Governance Artifact — signed, control-mapped, verifiable evidence assembled from a real inline decision
2026-07-21
LOCKSTEP TRACEABILITY MATRIX --- api_endpoints: ["GET /v1/governance/artifacts/{request_id}"] sdk_methods_updated: ["regenerated via pnpm gen:contract (generated SDK trees)"] mcp_tools_updated: ["none yet (candidate br_get_governance_artifact — follow-up)"] ---
What We Built
GET /v1/governance/artifacts/{request_id} — Phase 2 / step 2b. It returns a Governance Artifact: a single, signed, exportable evidence object composed from a real inline decision — the audit-chain proof (event_hash/prev_hash/ tenant_seq/provenance check), the coverage label, the policy and grant context, the routed decision, and the framework controls the decision exercised, optionally HMAC-signed with the tenant's audit key.
Crucially it is derived on-read from the already-committed completion_audit
decision_lineagerows, via the exact same sharedassembleLineageWhythe
WHY route and br_why MCP tool use — so there is no new table and no hot-path write. The composition/control-projection/signing is a pure, injectable assembler (buildGovernanceArtifact), unit-tested offline.
Why It Matters
Credo AI's evidence is a pull-based document snapshot with no cryptographic verifiability. A Governance Artifact is a bound projection of an actual inline decision: it embeds the hash-chain proof and the enforcement point that satisfied each control, so an auditor can independently re-verify it and it cannot be fabricated after the fact. This is the unit of "evidence you don't assemble" — generated automatically because BR sits on the request path.
How It Works
GET /v1/governance/artifacts/req_abc
→ {
artifactId: "gart_…", // deterministic sha256(tenant:request)
binding: "bound", coverage: "captured",
chainProof: { eventHash, prevHash, tenantSeq, provenanceCheck },
controls: [ { framework: "SOC2", controlId: "CC7.2", enforcementPoint: "completion_audit hash chain", satisfiedBy: "verified.event_hash" }, … ],
signature: { alg: "hmac", keyVersion, hmac } | null
}
Control mapping is injected (defaultArtifactControls is a minimal SOC2-anchored seed tied to executing enforcement points — it never claims a control the decision didn't exercise). Phase 3 swaps in the full EU AI Act / NIST / ISO 42001 projection from compliance-mappings.ts. Signing degrades gracefully to an unsigned artifact when the tenant HMAC key isn't provisioned; the embedded chain proof is verifiable either way.
Competitive Edge
Self-verifying, control-mapped evidence emitted from the request path — a batch documentation/registry posture structurally cannot produce a cryptographically bound artifact.
Lockstep Checklist
- [x] API Routes:
defineCapabilityingovernance.ts, registered in_registry.ts(both blocks). - [x] TS/Py SDK: regenerated via
pnpm gen:contract;docs/openapi.yaml+llms-full.txt+routes.jsoncommitted. - [x] MCP Schemas: none yet —
br_get_governance_artifactis a clean follow-up (the assembler is already shared, so MCP == REST by construction). - [x] Behavior:
governance.behavior.jsonentry (SOC2-CC6+CC7). - [ ] Master Record: to update when the artifact list route + Phase 3 framework mapping land.
Verification & caveats
- Verified:
buildGovernanceArtifact+defaultArtifactControlsunit tests
(chain proof, deterministic id, signed/unsigned paths, canonical-body signing, control projection that never over-claims); _registry completeness gate; pnpm check + pnpm build green; full unit suite 9,126 passing.
- NOT verified here: the live DB read path (
assembleLineageWhyover real
Postgres) — no live database in this environment. It reuses the identical store calls the existing /v1/governance/lineage/{request_id} route already makes, so it is correct-by-reuse, but wants a staging run before GA.
- Follow-ups: the artifact _list_ route (
GET /v1/governance/artifacts,
needs a windowed request-id enumeration), an optional sampled materializer table, and the br_get_governance_artifact MCP tool.