Design Philosophy

Why Software
Should Explain Itself

Good operational software should not require a detective every time it does something important.

Most software explains itself only after something goes wrong. We read logs, reconstruct timelines, compare metrics, and infer intent from side effects.

That works, but it is reactive. By the time someone is digging through logs, the software has already failed to communicate clearly.

A process that knows what it is doing should be able to say so while it runs.

This is the design philosophy behind OpenTrace: applications should report meaningful work in their own terms. Not every function call. Not every debug line. Just the milestones, progress, decisions, measurements, and exceptions that help people understand the operation.

Logs are evidence, not explanation

Logs are useful. They tell developers that a request failed, a timeout occurred, or an exception was thrown.

But a message such as:

HTTP request failed: 503

does not explain what that means for the work being done.

A more useful operational message might be:

Supplier product collection delayed.
Supplier service unavailable when the scheduled run began.
No refreshed dataset has been published.
Next retry scheduled for 09:30.

The technical detail still exists for the developer. But the event is now connected to the process it affects.

That distinction matters.

Logs describe what the software observed. Explanation describes what the software was trying to achieve, where it is in that process, and what the consequence may be.

One process, different responsibilities

The same event means different things to different people.

A developer may see an HTTP 503 response.

An operator may see a failed scheduled run.

A manager may see a customer waiting for yesterday's report.

These are not separate problems. They are different views of the same operation.

The problem is that most software exposes only the technical view and leaves people to translate it through messages, meetings, screenshots, and assumptions.

Software should help create a shared operational picture.

It should make clear:

  • what is happening;
  • what has completed;
  • what is blocked;
  • what has changed;
  • whether an expected outcome is now at risk;
  • what should happen next.

Translate software into business-process state

Most systems exist to complete some business process.

A scraper collects product data. An import moves data between systems. A reconciliation job checks records. A reporting process produces something a customer is waiting for.

The implementation may involve APIs, queues, containers, retries, databases, and scheduled workers. But the people depending on it usually want simpler answers:

Has it started?
Is it progressing?
Is the expected data present?
Can the result be published?
Is the customer deliverable at risk?

Software should expose state in those terms.

For example:

Validation started for weekly price collection.
31,240 of approximately 48,000 products processed.
312 records rejected due to invalid pricing structure.
Collection remains on track for the 08:00 reporting deadline.

That gives a developer something to investigate, an operator something to monitor, and management a clearer view of delivery risk.

Facts, policy, and action

Software should report facts clearly:

  • a worker started;
  • a supplier was unavailable;
  • a retry was attempted;
  • only 72% of expected data was collected;
  • the last successful dataset is 26 hours old.

But software cannot always decide what those facts mean.

Is 72% enough to publish? Is 26-hour-old data acceptable? Should the customer be notified? Does a partial result need approval?

Those are operational and business decisions.

This is where policy belongs.

A business may define that:

  • reports can publish above a completeness threshold;
  • data older than a set age is marked at risk;
  • a delayed run requires customer communication after a deadline;
  • certain failures require approval before publication;
  • supplier issues should escalate after a defined number of retries.

These policies give the business hooks into the software without requiring it to change code or improvise during an incident.

The software provides the facts. Operations applies the process. Management defines the expectations. Developers fix the underlying cause.

Explanation is not noise

The goal is not to publish every internal detail.

Too much telemetry becomes another investigation problem. The useful layer is the operational narrative: the information someone would need to understand the work without reconstructing it from raw evidence.

A good signal should answer a practical question:

What is happening?
What changed?
What is blocked?
What decision was made?
What is the customer impact?
What should happen next?

That is why domain language matters.

“Supplier service unavailable” is more useful than “HTTP 503.”

“Skipped empty file” is more useful than “array length zero.”

“Report delayed because expected input was not received” is more useful than “dependency timeout.”

Make the obvious visible

The software often already knows the important facts.

It knows when it started, what input it received, how much work it has completed, when a dependency failed, when it retried, and whether it produced the expected result.

Too often, that information stays trapped inside the process until someone asks for it.

OpenTrace is one attempt to make those small explanations easy to publish. It gives applications a way to report progress, milestones, expectations, notes, metrics, and decisions in language that connects technical activity to business process.

The best operational software does not wait to be interrogated.

It makes important work visible before people need to ask.