Skip to content

Commit 5ab2dd7

Browse files
conformance(signet): resolve all mapping markers per maintainer review
Incorporates @willamhou's review of #1, which resolved every [CONFIRM] / [FILL] marker in the original template with production-source-level detail (struct definitions, source-file line references, verifier-behaviour notes on `exp` and `nonce`, and correction of inferred mappings that did not match reality). FIELD-MAPPING.md: - All markers resolved. - signer.owner reclassified from inferred holder_binding mapping to informational metadata only (confirmed by maintainer: not a cryptographic identity; multi-level authority lives in Authorization). - exp reclassified from "soft hint" to hard verification gate (verify() rejects expired; verify_allow_expired() exists for forensic contexts); adapter drops or carries as informational. - nonce reclassified from inferred nullifier mapping to 128-bit OsRng freshness token; not a VOPRF artifact; adapter carries as Signet-specific extension or omits. - authorization struct expanded with full Rust definition provided by the maintainer: chain + chain_hash + root_pubkey; only chain_hash and root_pubkey enter signature scope. - policy (PolicyAttestation) struct expanded with full Rust definition: policy_hash/policy_name/matched_rules/decision/reason. Mapping to draft-02: policy_hash → policy_digest, policy_name → policy_id, decision → decision; matched_rules and reason mapped to a suggested attestation_evidence extension. - Decision enum confirmed as {allow, deny, require_approval}, all direct-match draft-02. DEVIATIONS.md: - Deviation 3 (chain linkage by ID vs hash) resolved per maintainer preference: Option 2 (additive parent_hash alongside parent_receipt_id) in an upcoming Signet point release. ADAPTER.md: - Fix wrong PolicyAttestation field names in the pseudocode (policy_name / policy_hash, not id / digest) per maintainer catch. - Expand Authorization mapping to reflect chain_hash + root_pubkey as the signature-scope fields. - Replace "Open questions for the Signet maintainer" with the answered section: co-signer via `signet sign --emit-draft02`; in-workspace signet-draft02-adapter crate; operator key accessible at adapter site; co-signer mode is the default. README.md (conformance/signet/): - Lead with maintainer-confirmed status. - List Signet-side follow-ups (parent_hash field, --emit-draft02 flag, signet-draft02-adapter crate) in flight. - Cross-link maintainer's parallel crosswalk at aeoess/agent-governance-vocabulary#37. IMPLEMENTATIONS.md: - Signet row moves from "Self-certification template staged" to "Self-certified (adapter crate pending)". - Add pointers to the agt-integration-profile review PR and the aeoess vocabulary crosswalk. Co-Authored-By: Will.hou <8574759+willamhou@users.noreply.github.com>
1 parent 3b2bfee commit 5ab2dd7

5 files changed

Lines changed: 74 additions & 67 deletions

File tree

IMPLEMENTATIONS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
| protect-mcp | [scopeblind/scopeblind-gateway](https://github.com/scopeblind/scopeblind-gateway) | Claimed | @tomjwxf | Claude Code hooks + MCP gateway. Operator-signed mode. |
77
| protect-mcp-adk | [scopeblind/protect-mcp-adk](https://github.com/scopeblind/protect-mcp-adk) | Claimed | @tomjwxf | Google ADK BasePlugin. Python. |
88
| aps-governance-hook | [aeoess/hermes-aps-delegation](https://github.com/aeoess/hermes-aps-delegation) (pending 0.1.0) | Claimed | @aeoess | Authority-chain-referenced mode with delegation_chain_root. |
9-
| Signet | [Prismer-AI/signet](https://github.com/Prismer-AI/signet) | Self-certification template staged | @willamhou | Conformance template pre-filled at [conformance/signet/](./conformance/signet/) for maintainer sign-off. Wire format shares JCS + Ed25519 with draft-02; four documented deltas (envelope shape, signature prefix, chain linkage by ID vs hash, key identifier) are adapter-addressable. Context: [microsoft/agent-governance-toolkit#1201](https://github.com/microsoft/agent-governance-toolkit/pull/1201). |
9+
| Signet | [Prismer-AI/signet](https://github.com/Prismer-AI/signet) | Self-certified (adapter crate pending) | @willamhou | Mapping confirmed by @willamhou in [agt-integration-profile#1](https://github.com/VeritasActa/agt-integration-profile/pull/1); conformance/signet/ captures the agreed field mapping and four documented wire-format deltas. Signet is adding `parent_hash` alongside `parent_receipt_id` and shipping a `--emit-draft02` flag plus an in-workspace `signet-draft02-adapter` crate in an upcoming point release. Cross-documentation at [aeoess/agent-governance-vocabulary#37](https://github.com/aeoess/agent-governance-vocabulary/pull/37). |
1010

1111
## How to add an implementation
1212

conformance/signet/ADAPTER.md

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Pseudocode for a thin shim that translates a Signet receipt (as emitted by `Prismer-AI/signet@main` at the date of this PR) into a draft-farley-acta-signed-receipts-02 envelope verifiable against `@veritasacta/verify`.
44

5-
**Status:** Sketch only. Production implementation is out of scope for this template. Provided so the Signet maintainer can evaluate whether the adapter path is thin enough to pursue, or whether native alignment (Path 3 on [microsoft/agent-governance-toolkit#1201](https://github.com/microsoft/agent-governance-toolkit/pull/1201)) is the better move.
5+
**Status:** Sketch. The Signet maintainer has confirmed the co-signer shape below and committed to shipping this as a `--emit-draft02` flag on `signet sign` (main repo), plus an in-workspace `signet-draft02-adapter` crate. Production implementation is scheduled on the Signet side; this file remains as the architectural reference. Open questions at the bottom are resolved.
66

77
## Input
88

@@ -50,17 +50,31 @@ def signet_to_draft02(signet_receipt: dict, operator_signer: Ed25519Signer) -> d
5050
# See DEVIATIONS.md section 3.
5151
payload["previousReceiptHash"] = resolve_prior_hash(action["parent_receipt_id"])
5252

53-
# Optional: map policy_attestation -> policy_digest/policy_id
53+
# Map PolicyAttestation -> policy_digest / policy_id / decision.
54+
# Signet's PolicyAttestation struct uses policy_name and policy_hash.
5455
if signet_receipt.get("policy"):
5556
policy = signet_receipt["policy"]
56-
payload["policy_id"] = policy.get("id")
57-
payload["policy_digest"] = policy.get("digest")
58-
59-
# Optional: map authorization -> holder_binding (AIP-0003)
57+
payload["policy_id"] = policy.get("policy_name")
58+
payload["policy_digest"] = policy.get("policy_hash")
59+
if policy.get("decision"):
60+
payload["decision"] = policy["decision"]
61+
# Suggested: attestation_evidence extension for richer fields
62+
if policy.get("matched_rules") or policy.get("reason"):
63+
payload["attestation_evidence"] = {
64+
"matched_rules": policy.get("matched_rules", []),
65+
"reason": policy.get("reason"),
66+
}
67+
68+
# Map Authorization -> holder_binding (AIP-0003).
69+
# Signet's Authorization struct: { chain, chain_hash, root_pubkey }.
70+
# Only chain_hash and root_pubkey enter the signed scope; full chain
71+
# is carried for storage and dropped at adapt time.
6072
if signet_receipt.get("authorization"):
73+
auth = signet_receipt["authorization"]
6174
payload["holder_binding"] = {
62-
"mode": "jwk_thumbprint", # Adjust based on Signet's auth shape
63-
"thumbprint": jwk_thumbprint(signet_receipt["authorization"]),
75+
"mode": "jwk_thumbprint",
76+
"thumbprint": jwk_thumbprint_of_ed25519_pubkey(auth["root_pubkey"]),
77+
"delegation_chain_hash": auth["chain_hash"],
6478
}
6579

6680
# Re-sign under draft-02 canonicalization (JCS RFC 8785, AIP-0001 ASCII-keys)
@@ -108,10 +122,14 @@ That is achievable but constrains Signet's field set (cannot include fields that
108122

109123
**Co-sign mode is the recommended default.** Transcode mode is a design conversation for Path 3 (native alignment), not for an adapter.
110124

111-
## Open questions for the Signet maintainer
125+
## Signet maintainer answers
126+
127+
Resolved in the review of [VeritasActa/agt-integration-profile#1](https://github.com/VeritasActa/agt-integration-profile/pull/1):
128+
129+
1. **Feature flag.** The co-signer emits as a `--emit-draft02` flag on `signet sign`. When set, both the Signet-native envelope and the draft-02 envelope are produced per operation. Lives in the main Signet repo (discoverable, tested in the main CI).
130+
131+
2. **In-workspace adapter crate.** A `signet-draft02-adapter` crate is welcome inside the Signet Cargo workspace. Timing depends on the conformance bar; maintainer will prioritise after field mapping is confirmed (confirmed by this PR).
112132

113-
1. Does a co-sign adapter make sense as a Signet feature flag (emit both Signet-native and draft-02 envelopes per operation), or as an out-of-tree tool?
114-
2. Would a Rust-native adapter (`signet-draft02-adapter` crate) be accepted upstream into the Signet workspace?
115-
3. Is the operator's private key accessible at the adapter site, or is co-signing constrained by key-custody boundaries?
133+
3. **Co-signer mode is the right default.** The operator private key is accessible at the adapter site, so the adapter can produce a draft-02 envelope that verifies under the operator's public key. No cross-custody complications at the adapter site.
116134

117-
The answers shape whether the adapter lives in the Signet repo, this repo, or as a third-party crate.
135+
The adapter therefore lives in the Signet main repo (not this repo, not third-party). This repo retains the architectural reference (this file) and the normative field mapping ([`FIELD-MAPPING.md`](./FIELD-MAPPING.md)).

conformance/signet/DEVIATIONS.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,9 @@ Four deltas that require adapter handling but do not affect semantic conformance
6060

6161
**Adapter direction (Signet -> draft-02):** Compute the SHA-256 of the canonicalized Signet prior receipt at adapter time and emit as `previousReceiptHash`. The adapter MUST have access to the prior receipt (or its hash) to emit this field.
6262

63-
**For Signet self-certification:** this is the most significant semantic delta. Two reasonable positions:
63+
**Maintainer preference (selected).** The Signet maintainer has chosen **Option 2**: add a `parent_hash` field alongside `parent_receipt_id`. Dual-mode, additive, low-effort. Both fields coexist on the wire. Signet-native verifiers continue to use `parent_receipt_id`; draft-02 verifiers use `parent_hash`.
6464

65-
1. **Declare partial conformance at T1 minus chain-linkage.** Signet receipts verify as individual signed artifacts but do not carry tamper-evident chain linkage in the draft-02 sense. An operator wanting tamper-evident chain linkage uses the adapter.
66-
2. **Add a `parent_hash` field alongside `parent_receipt_id`.** Dual-mode: Signet-native verifiers keep using IDs; draft-02 verifiers use the hash. Zero-cost additive change.
67-
68-
Maintainer preference welcome.
65+
**Signet-side implementation note.** This requires the signer to have access to the prior receipt's canonical bytes at sign time; the signer API needs a minor extension to accept (or compute) the parent hash. Scheduled for an upcoming Signet point release. Once shipped, this deviation collapses to "emit `parent_hash` on the wire, read it on the draft-02 side", and the adapter's chain-linkage step becomes zero-cost.
6966

7067
## 4. Key identifier: pubkey string vs JWK thumbprint
7168

@@ -91,7 +88,7 @@ Not a blocker for conformance; just a real constraint on what the adapter emits.
9188
|---|---|---|
9289
| Envelope shape | Structural | ~10 lines, boilerplate. |
9390
| Signature encoding | Cosmetic | ~5 lines, strip prefix + re-encode. |
94-
| Chain linkage (ID vs hash) | Semantic | Most significant. Either accept partial conformance or add a dual `parent_hash` field in Signet. |
91+
| Chain linkage (ID vs hash) | Semantic | Resolved. Signet is adding `parent_hash` alongside `parent_receipt_id` in an upcoming point release; dual-mode, zero-cost after the point release ships. |
9592
| Key identifier (pubkey vs thumbprint) | Policy | Adapter MUST NOT emit raw pubkey. External key discovery is the verification path. |
9693

9794
None of these deltas are structural blockers to conformance. All are adapter-addressable; two could be additionally softened by thin Signet-side extensions.

0 commit comments

Comments
 (0)