Skip to content

feat(sdk): emitter affordance to record host-side projection failures - #71

Merged
MohammadHaroonAbuomar merged 1 commit into
mainfrom
mhabuomar/host-error-synthesis
Aug 7, 2026
Merged

feat(sdk): emitter affordance to record host-side projection failures#71
MohammadHaroonAbuomar merged 1 commit into
mainfrom
mhabuomar/host-error-synthesis

Conversation

@MohammadHaroonAbuomar

Copy link
Copy Markdown
Contributor

Closes #70.

What

When the HOST's own wire projection fails before a valid AgentContext exists for a point (e.g. a tool-call argument property getter throws during to-wire conversion at the chat seam), the host could only fail the run closed recordless — §11's reserved reasons cover interceptor/context failures the emitter can see, but a host-side projection fault happens before anything exists to emit.

This adds an emitter affordance that synthesizes and delivers the fail-closed record, in all five SDKs:

SDK API
Rust InterceptionEmitter::record_host_failure(point, HostFailure { detail, session_id, sequence, timestamp })
Python emitter.record_host_failure(point, detail, *, session_id=, sequence=, timestamp=)
TypeScript emitter.recordHostFailure(point, { detail, session_id, sequence, timestamp })
.NET emitter.RecordHostFailure(point, detail, sessionId, sequence, timestamp)
Go emitter.RecordHostFailure(point, HostFailure{Detail, SessionID, Sequence, Timestamp})

Record semantics

  • The record is the existing §10.3 rejection shape: payload-free projection of a deny host_error:context_invalid, null identities under the declared provider, decided_by: null, no per-interceptor summaries, interceptors_registered as registered.
  • No new reserved reason: host_error:context_invalid's cause already names "the host could not construct a schema-valid AgentContext"; spec/reserved-reasons.json is untouched (nothing for ACS's vendored copy to sync).
  • Payload-free discipline: detail is a type name/path only, recorded as the verdict message and truncated by the same §10.3 projection as every combined verdict.
  • Sequence integrity: the optional envelope facts carry the values the failed emission would have taken; the host SHOULD consume the next sequence number so records stay totally ordered (""/-1/absent when unknown). The record enters the same stream (sink, then buffer) as every emission.
  • Enforcement modes: synthesis records in both modes; in evaluate_only the mode member keeps the record from implying a block happened (§8) — the action failed on its own, not on a verdict.
  • All five bindings assemble the record through the core's finalize over a deliberately partial envelope basis (never §4-valid, so the rejection shape is forced), keeping cross-SDK behaviour pinned to one implementation. No record-shape or schema change; golden vectors unaffected.

Spec

  • §10.3 gains a "Host projection failure" paragraph: MUST fail closed in enforce, SHOULD record; detail is type/path only (§14); sequence-integrity guidance; evaluate_only does not imply enforcement.
  • §11's synthesis-site list adds §10.3.

Downstream

Unblocks microsoft/agent-framework#7564's recordless chat-seam projection-failure path and the same gap in the merged Python feature (adoption there is follow-up work; no agent-framework code is touched here).

Testing

Full local matrix mirroring CI: cargo fmt --check + clippy -D warnings + cargo test --locked --workspace --all-features (Rust); ruff format --check/ruff check + pytest 185 passed (Python); native build + zero binding drift + tsc + node --test 135 passed (TypeScript); dotnet format --verify-no-changes + -warnaserror build + 126 tests passed (.NET); gofmt/go vet/go test all packages ok (Go); scripts/check-version-consistency.py agrees at 0.1.0-alpha.5. Four new tests per SDK (rejection shape, unknown-envelope defaults, evaluate_only + sink delivery, projection truncation).

@MohammadHaroonAbuomar MohammadHaroonAbuomar added the spec:additive Additive normative change (optional fields, new vectors) label Aug 7, 2026
@MohammadHaroonAbuomar
MohammadHaroonAbuomar force-pushed the mhabuomar/host-error-synthesis branch 2 times, most recently from 4b76735 to d754349 Compare August 7, 2026 19:27
When the host's own to-wire projection fails before a valid
AgentContext exists (e.g. a tool-call argument property getter throws
during conversion at the chat seam), the host could only fail the run
closed recordless: §11's reserved reasons cover failures the emitter
can see, but a host-side projection fault happens before anything
exists to emit.

Add an emitter affordance — record_host_failure(point, ...) in Rust
and Python, recordHostFailure in TypeScript, RecordHostFailure in
.NET and Go — that synthesizes and delivers the fail-closed record:
a deny host_error:context_invalid in the §10.3 rejection shape (null
identities under the declared provider, decided_by null, no verdict
summaries) carrying a payload-free type-name/path detail as the
projected message and the envelope facts the host still knows
(session_id, sequence, timestamp; ""/-1/absent when unknown). The
record enters the same stream (sink, then buffer) as every emission.
In evaluate_only the record still gets produced and documents the
host fault without implying enforcement (§8).

All five bindings assemble the record through the core's finalize
over a deliberately partial envelope basis, so the shape is pinned to
one implementation. No new reserved reason (context_invalid's cause
already names "could not construct a schema-valid AgentContext") and
no record-shape or schema change; golden vectors unaffected.

Spec: §10.3 gains the "Host projection failure" host obligation
(MUST fail closed, SHOULD record; sequence-integrity and
data-minimization rules); §11 lists §10.3 as a synthesis site.

Closes #70

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>
@MohammadHaroonAbuomar
MohammadHaroonAbuomar force-pushed the mhabuomar/host-error-synthesis branch from d754349 to 25316d5 Compare August 7, 2026 19:32
@MohammadHaroonAbuomar
MohammadHaroonAbuomar merged commit ee5506d into main Aug 7, 2026
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

spec:additive Additive normative change (optional fields, new vectors)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SDK: no emitter affordance to synthesize a host_error record for host-side projection failures

1 participant