These notes define the intended seam between this repository and ATM-specific integration code.
- The primary ATM adapter seam is the public observer API exposed by
sc-composerand consumed directly or indirectly bysc-compose. - Typestate and other internal pipeline markers are library implementation details, not adapter extension points.
- Command lifecycle events are emitted by the CLI layer. The library emits composition-stage events only.
- ATM adapters own mailbox-aware configuration, path translation, and any host
policy projection needed to build a
ComposeRequest. sc-composerintentionally does not expose aComposerConfigobject for ATM to fill. Adapters construct request values directly.- Runtime-specific home resolution, spool paths, and ATM transport concerns stay outside this repository.
sc-composerandsc-composeintentionally replace equivalent crates that previously lived inagent-team-mail.- This is an intentional breaking change and migration step, not a temporary compatibility layer.
- The crate version is
1.0.0for the first standalone release from this repo. - The standalone release checklist lives in
docs/release-checklist.md; ATM cutover follows that published release.
An ATM adapter that uses the sc-compose CLI and will send or cache a rendered
template must supply the exact context it intends to use and run
validate --check-render --json. It must inspect the structured payload.state,
not infer success from human-readable output:
render_checkedpermits sending or caching the exact checked result.static_only,context_required,contract_invalid, andrender_invaliddeny sending or caching.
An ATM adapter that calls the sc-composer library directly has the same
Checked-Emission Caller Contract, but the library cannot enforce it through
the type of ComposeResult: compose() returns a public raw
ComposeResult::rendered_text string. The adapter must therefore:
- compose with the exact context intended for emission;
- call
check_rendered_outputon the complete finalrendered_text, using the persistedOutputFormatand the resolved template path. If the adapter also persists JSON mode or other render metadata, pass it throughcheck_rendered_output_with_metarather than replacing metadata after the check; - emit or cache only the resulting
CheckedOutputviaCheckedOutput::emit, and deny emission onOutputCheckError.
This caller contract is required even when the adapter is not using the CLI.
ComposeResult::rendered_text must never be treated as implicitly checked.
The library has no bundled compose_checked() convenience API yet; the
future Checked Library Composition API sprint owns evaluation of a
non-invasive helper that would bundle final text and its check report.
Plain validate is intentionally static-only and emits no rendered body.
Validation and checked-render responses contain diagnostics and a redacted
context summary; adapters must not require the complete prompt body merely to
decide whether a render is safe. A JSON parser failure uses the stable
ERR_RENDER_JSON_MALFORMED diagnostic and includes source location without
echoing variable values. Multi-pass failures identify the final render pass
that produced the rejected body.