Skip to main content

Interpreter output

In the context of Courier interpreters, the term output refers to the named results returned by an interpreter as part of its contract, not to standard output or standard error streams.

Interpreter output consists of structured data returned into the job context and explicitly referenced artifacts produced during execution. These outputs are the authoritative results that users, automation, and downstream job steps rely on.

Standard output (stdout) and standard error (stderr) are always captured by Courier, but they’re diagnostic streams, not contractual output. They may be unstructured and are intended for human inspection and troubleshooting only.

This distinction is critical. Users should never be required to parse stdout or stderr to determine outcomes, extract results, or drive workflow behavior.

Structured output is the contract

Structured output is the primary and contractual result of an interpreter invocation.

Every interpreter must return structured output that clearly communicates:

  • What action was attempted
  • What outcome occurred
  • What data or artifacts were produced
  • Whether follow-on action is appropriate

Structured output is returned as named values in the job context and as explicit artifact references. These outputs are intended for downstream consumption by other job steps, automation systems, and user interfaces.

While interpreters may emit information to stdout and stderr, those streams are non-contractual and must not be required for interpreting results.

Outcome-oriented results

Interpreter output must be outcome-oriented, not execution-oriented.

Outputs should describe what happened rather than how it happened. Users shouldn’t need to know how many commands were run, which APIs were called, or what intermediate steps occurred.

Effective output:

  • Uses domain-relevant terminology
  • Clearly distinguishes success, partial success, failure, and no-op outcomes
  • Avoids leaking engine-specific error formats
  • Normalizes results across environments where possible

If execution fails, the structured output must clearly indicate failure and provide meaningful context without relying on raw engine logs as the primary signal.

Designing for composition

Interpreter output must be designed to support composition across job steps.

Outputs should:

  • Use stable, well-defined field names and data types
  • Separate summary results from detailed data
  • Expose values likely to be consumed by subsequent steps
  • Avoid encoding meaning solely in human-readable strings

When outputs are designed for composition, users can build higher-level workflows without brittle parsing, hidden coupling, or implicit assumptions.

Artifacts and references

When interpreters produce large, complex, or binary results, they should return them as artifacts rather than embedding them directly in structured output.

Artifacts may include:

  • Compliance or audit reports
  • Bundled diagnostics
  • Generated configuration or evidence
  • Output intended for long-term retention

Structured output must reference artifacts explicitly and describe their purpose and format. Artifacts are first-class outputs and should be treated as part of the interpreter’s contract.

Errors, partial success, and clarity

Interpreter output must clearly communicate execution state.

Valid outcomes include:

  • Full success
  • Partial success
  • Failure
  • No-op or already-in-desired-state results

Ambiguous outcomes force users to infer meaning from logs or exit codes and undermine trust in automation. Structured output must make outcome semantics explicit.

Where partial success is possible, output should identify which elements succeeded, which didn’t, and what corrective action may be required.

Relationship to output rules

Courier provides output rules that allow users to transform or extract value from unstructured output downstream.

These rules exist to support flexibility and integration with legacy tools. However, interpreter output design must never depend on output rules to be usable or complete.

Structured output returned by the interpreter remains the authoritative source of truth. Output rules are an enhancement mechanism, not a substitute for well-designed contracts.

Interpreters should always aim to return meaningful, structured data directly into the job context.

Stability and evolution of output

Interpreter output is part of the interpreter contract and must follow the same stability rules as command input.

As a result:

  • Output fields must not change meaning
  • Fields must not be removed without deprecation
  • New fields should be additive and optional
  • Breaking changes require new commands or versions

Users build automation, reporting, and governance workflows against interpreter output. Treat output design with the same care and discipline as input design.

Downstream usage and integration

Interpreter output is valuable as part of a larger workflow. Structured output and artifacts are expected to be consumed by downstream systems, including reporting pipelines, governance tooling, audit systems, and external integrations.

Artifacts produced by an interpreter, including those bundled as evidence, must therefore adhere to known names, formats, and semantic contracts. Consumers should be able to ingest artifacts based on their declared purpose and contract, not by inspecting file contents or relying on interpreter-specific conventions.

To support reliable downstream usage:

  • Artifacts must be explicitly named and described in structured output
  • Artifact purpose and format must be stable and documented
  • Evidence bundles should follow consistent structure across executions
  • Downstream systems must not be required to infer meaning from filenames, directory layout, or unstructured metadata

Interpreters should assume that artifacts may be consumed independently of the job that produced them. As such, artifacts should be self-describing enough to support ingestion, correlation, and reporting without requiring access to execution logs or interpreter internals.

By treating artifacts as contract-bound outputs rather than incidental byproducts, Courier enables consistent integration with reporting, compliance, and governance systems while reducing custom glue code and fragile ingestion logic.

Thank you for your feedback!

×