0.5.0
The wire vocabulary grew for the first time since the HITL merge — two additive constructs, designed in the open on typescript-sdk#16 with guuey as the first consumer, and signed off against their production surfaces before this cut. Everything is additive: streams that don’t use the new vocabulary are byte-identical to draft.1.
Grant modes — scope-qualified consent (§7)
Real permission systems answer “yes” with a scope: always, this chat only, just once. hitl.ask (and its persisted AgPausedAsk record) can now declare grantModes — the accept variants the asker offers — and the answer echoes exactly one as AgHitlAnswer.grantModeId. The design is strictly asker-declared: ids are opaque, AgJSON hard-codes nobody’s mode set, and declining stays the universal affordance outside the declaration (a renderer can always show refusal without consulting it). Anchored on the Claude Agent SDK’s PermissionUpdate.destination scopes and the OpenAI Agents alwaysApprove/alwaysReject options; frameworks with binary confirmation (ADK) simply don’t declare, which is the valid absent case.
Enforcement ships with the shape: grantModeId on a non-resolved answer rejects at parse, and the new validateHitlAnswer(ask, answer) checks the cross-object contract (required-iff-declared, echo-must-be-declared, plus the pre-existing requestState byte-echo rule) against the fold’s own paused-ask record. Clients advertise support via the hitl.grantModes capability flag.
The notice role — a first-class home for transcript annotations (§3)
AgRole gains "notice": a persisted, non-conversational transcript row for host banners, adapter annotations, and framework notices — with noticeSource: host | adapter | framework naming the layer that injected it. A notice is never replayed to the model, never merges into assistant content, and never renders as agent-authored. The admission test is deliberately narrow (persisted + user-facing + non-conversational); ephemeral status chatter stays in vendor carries.
The Claude normalizer ships the first producer: SDKInformationalMessage frames (transcript notices, halt explanations) are promoted from their vendor-extension carry to full notice messages — and now carry tool_use_id, which the old route dropped.
Wire version
AGJSON_VERSION is now 1.0.0-draft.2. Draft.1 inputs remain accepted (same major); consumers pinning 0.4.x should bump to parse streams that use the new vocabulary.