Skip to content

feat: APS governance hook driver (v2 envelope)#1

Open
aeoess wants to merge 1 commit intoScopeBlind:mainfrom
aeoess:aps-governance-hook-driver
Open

feat: APS governance hook driver (v2 envelope)#1
aeoess wants to merge 1 commit intoScopeBlind:mainfrom
aeoess:aps-governance-hook-driver

Conversation

@aeoess
Copy link
Copy Markdown
Contributor

@aeoess aeoess commented Apr 17, 2026

Summary

Implements the aps-governance-hook conformance driver required by spec.md. Fills the placeholder at implementations/aps-governance-hook/run.sh with a Python driver that reads fixtures/inputs/*.json, evaluates each against fixtures/policy/autoresearch-safe.cedar via the official Cedar engine, and emits v2 structured-envelope receipts signed with Ed25519 using the fixture seed.

Conformance result

$ bash conformance/verify.sh receipts/aps-governance-hook

=== Check 1: schema conformance (v1 flat OR v2 envelope) ===
PASS: schema ok: 001-allow-read.json
PASS: schema ok: 002-allow-bash-git.json
PASS: schema ok: 003-deny-bash-destructive.json
PASS: schema ok: 004-allow-write.json

=== Check 2: @veritasacta/verify signatures ===
PASS: all signatures verify (exit 0)

=== Check 3: chain order + parent-hash linkage ===
PASS: chain order + linkage

─────────────────────────────────────────────
  6 passed, 0 failed
─────────────────────────────────────────────

All four decisions match expected/chain.jsonl:

seq tool decision expected
1 Read allow allow
2 Bash (git) allow allow
3 Bash (rm -rf) deny deny
4 Write allow allow

Design notes

  • Cedar engine: uses cedarpy, the official Python binding around the Rust cedar-policy crate — not a re-implementation. The driver does not evaluate the policy itself; it builds the request and reads back decision.
  • Policy text shim: the shared policy uses the older Cedar idiom context.X in [strings]. Cedar 4.x strict types reject that (in's LHS must be an entity). The driver rewrites, for evaluation only, context.X in [list][list].contains(context.X) via a targeted regex. Semantics are unchanged; the on-disk fixture policy is untouched, and policy_digest is computed over the original bytes.
  • Canonicalization: JCS-lite (sort_keys=True, separators=(",", ":")). Sufficient for the field types these receipts carry (strings, integers, booleans, plain objects, ASCII-only keys). Documented in-line so a future contributor can lift to a full JCS library if fractional numbers ever appear in the payload.
  • Signed bytes: the driver signs the full envelope body minus signature, which is what @veritasacta/verify reconstructs before calling Ed25519. public_key is embedded inside payload so the verifier's auto-key-lookup path succeeds without --key.
  • Chain genesis: payload.prev_hash = "sha256:0000…0" (cryptographic chain convention) and top-level parent_receipt_hash = null (so conformance/verify.sh's check 3 accepts genesis as null/empty per its current wording). Subsequent receipts chain by SHA-256 of the full JCS-canonical envelope, consistent across both fields.
  • Skip semantics: exits 77 when cedarpy or cryptography are missing, matching the protect-mcp pattern. Install with pip install cedarpy cryptography.

Files

  • implementations/aps-governance-hook/run.sh — driver (was placeholder, now ~200 lines)
  • receipts/aps-governance-hook/*.json — regenerated at run time; not committed (matches protect-mcp and sb-runtime)

Test plan

  • pip install cedarpy cryptography
  • bash implementations/aps-governance-hook/run.sh prints aps-governance-hook: 4 receipts in … and exits 0
  • bash conformance/verify.sh receipts/aps-governance-hook — all 6 checks pass, exit 0
  • Decisions in produced receipts match expected/chain.jsonl
  • Running without cedarpy or cryptography exits 77 with a skip message (matches protect-mcp)

🤖 Generated with Claude Code

Implements the APS driver that reads fixtures/inputs/*.json in sequence,
evaluates each against fixtures/policy/autoresearch-safe.cedar using the
official Cedar Rust engine (via cedarpy Python bindings — not a
re-implementation), and emits v2 structured-envelope receipts signed with
Ed25519 using the fixture seed.

Conformance against conformance/verify.sh:
  Check 1 (schema v1-flat OR v2-envelope): PASS (4/4)
  Check 2 (@veritasacta/verify signatures): PASS
  Check 3 (chain order + parent-hash linkage): PASS

Dependencies: python3, cedarpy, cryptography. Driver exits 77 when any
are missing, matching the protect-mcp driver's skip-gracefully pattern.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant