…t#3083)
Port Python agent-mesh approval_protocol subpackage to the TypeScript SDK,
bringing require_approval chain execution on par with the Python reference
from microsoft#3076 (ADR-0030):
- approval-protocol/digest.ts: RFC 8785 JCS canonicalization (UTF-16 key
sort, format integers without decimal) + SHA-256 action digests with
"sha256:" prefix. Deterministic across key insertion order.
- approval-protocol/binding.ts: ActionBinding + ActionTarget, bindingDigest
binds the exact operation/agent/target/parameters so an approval for one
binding can never authorize a different action.
- approval-protocol/models.ts: PolicyDecisionRecord, ApprovalRequest,
ApprovalChainEntry (with seal/verifyDigest for hash-linked integrity),
ApprovalResolution; utcnow(), inputDigest(), presentedCanonical().
- approval-protocol/store.ts: ApprovalStore interface +
InMemoryApprovalStore; consume() is atomic and returns true exactly once.
- approval-protocol/coordinator.ts: ApprovalCoordinator with openRequest,
submitEntry (authority-checked, idempotent by chainEntryId, advisory
entries never satisfy a stage), validateForExecution (pre-execution
revalidation: digest/version/chain-integrity checks, one-time consume,
fail-closed on any unexpected error), and _maybeResolve (single deny
terminates immediately; all required stages must allow).
- 31 new tests covering the JCS serializer, binding digest, coordinator
lifecycle, chain integrity, consume-once, expiry, digest mismatches,
unpermitted identity, advisory vote behavior, and idempotent resubmission.
Semantic contract matches the Python reference. Node.js is single-threaded
so InMemoryApprovalStore needs no mutex (parity with Python's RLock is not
needed in this runtime).
Closes microsoft#3083
Signed-off-by: Varun Nuthalapati <nuthalapativarun@gmail.com>
Description
Adds TypeScript parity for the action-bound approval protocol (ADR-0030), as tracked in #3083.
The Python reference implementation landed in #3076 (routing
require_approvalthrough theApprovalCoordinator) plus the underlyingapproval_protocolsubpackage. This PR brings the same approval-chain execution layer to the TypeScript SDK. One PR per SDK per the pattern established in prior parity efforts.What this adds (
agent-governance-typescript/src/approval-protocol/):digest.ts— RFC 8785 JCS canonicalization (object keys sorted by UTF-16 code unit, integers without decimal point) +sha256Jcsfor action digests. Deterministic across key insertion order.binding.ts—ActionBinding/ActionTarget/bindingDigest. An approval for one binding can never authorize a different action: change a parameter, the target, the tool schema version, or the acting agent, and the digest changes.models.ts—PolicyDecisionRecord,ApprovalRequest,ApprovalChainEntry(withsealEntry/verifyEntryDigestfor hash-linked chain integrity),ApprovalResolution;inputDigest,presentedCanonical.store.ts—ApprovalStoreinterface +InMemoryApprovalStore.consume()is atomic (one-time-use guard, ADR-0030 section 6).coordinator.ts—ApprovalCoordinatorwith three public methods:openRequest: binds arequire_approvaldecision to a durable, TTL-bounded requestsubmitEntry: authority-checked (by identity or role), idempotent bychainEntryId, advisory (llm_advisory) entries never satisfy a stage, single deny terminates immediatelyvalidateForExecution: pre-execution revalidation — checks action digest, policy version, chain version, chain integrity, expiry, and consume-once; fails closed on any unexpected errorAll symbols re-exported from
src/index.ts.Semantic contract matches the Python reference precisely. Node.js is single-threaded so
InMemoryApprovalStoredoes not need a mutex (threading.RLockis not needed in this runtime — idiomatic adaptation per @imran-siddique's guidance).Type of Change
New feature — language parity
Package(s) Affected
agent-governance-typescriptChecklist
npm test— 31 new tests, 591 total, all green)npm run lint)npm run build)-s)Attribution & Prior Art
Python reference implementation:
agent-governance-python/agent-mesh/src/agentmesh/governance/approval_protocol/(coordinator + models + binding + digest + store). Python wiring intogovern()landed in #3076 by @carloshvp. TypeScript port mirrors the Python semantics; no new design.AI Assistance
I can explain every change. Tests were run locally. Not autonomously submitted.
IP, Patents, and Licensing
All new code is original and placed under the MIT License, consistent with the existing SDK. No third-party libraries added.
Related Issues
Closes #3083