Skip to main content

Summary

This document defines how Courier interpreters should be designed, implemented, and evaluated to ensure they’re safe, predictable, and usable over time. Interpreters aren’t scripts, wrappers, or tools. They’re intent-driven contracts that users trust as building blocks for operational workflows.

This final section summarizes the core principles and provides a practical checklist for design and review.

Interpreter design checklist

Use the following checklist when designing or reviewing an interpreter:

Intent and scope

  • Does the interpreter express a single, clear intent?
  • Is each command responsible for exactly one outcome?
  • Is the interpreter’s purpose obvious without understanding the underlying engine?

Contract quality

  • Are command inputs readable, explicit, and intent-focused?
  • Are invalid states prevented or clearly rejected?
  • Does the contract avoid exposing engine-specific flags or mechanics?
  • If advanced or CLI-aligned options are exposed, are they explicitly opt-in and structured to guide correct usage?

Validation and UX

  • Can the contract be validated through a known structured specification?
  • Does the specification provide sufficient metadata to support UI-driven input?
  • Are validation errors clear, human-readable, and actionable?
  • Are users protected from needing to understand JSON or serialization formats when using a UI?

Execution and safety

  • Does the interpreter manage its process lifecycle responsibly?
  • Are child processes cleaned up on termination whenever possible?
  • Are retries and re-execution safe or explicitly documented when they’re not?

Output and composition

  • Does the interpreter return structured output as named job context values or artifacts?
  • Are stdout and stderr used only for diagnostics?
  • Is output designed for downstream composition and integration?
  • Are artifacts named, documented, and consumable through known contracts?

Failure semantics

  • Are success, failure, and partial success clearly distinguished?
  • Are outcomes explicit without requiring log inspection?
  • Is non-determinism documented and signaled when present?

Stability and Evolution

  • Are contract changes additive and backward-compatible?
  • Are new behaviors introduced through new commands or versions?
  • Is output treated as a stable, long-lived contract?

Review questions

When reviewing an interpreter design or implementation, ask:

  • Would a user understand what this interpreter does without knowing the engine?
  • Can this contract remain stable even if the engine changes significantly?
  • Does the interpreter guide users toward safe and supported behavior?
  • Are constraints intentional and beneficial, or are they missing?
  • Could this interpreter be composed safely into larger workflows?
  • Are escape hatches clearly labeled and genuinely necessary?

If any of these questions are difficult to answer, the contract likely needs refinement.

Essential points

The most important principles are as follows:

  • Interpreters express intent, not mechanics.
  • Contracts are promises to users and must be treated as long-lived APIs.
  • Constraint is a feature, not a limitation.
  • Structured output is the interface; logs are diagnostics.
  • If users must understand the engine, the interpreter has failed.

Courier interpreters succeed when users can trust them as stable, composable capabilities—regardless of how the underlying systems evolve.

Thank you for your feedback!

×