ADR-032 Building Block View (2026 Q2)¶
Status: Current-state building block view after Wave42 Canonical ADR: ADR-032 Companion docs: Overview, Quality Scenarios
This page captures the stable building blocks of the ADR-032 implementation line. It is the structural view of the current MCP policy/evidence stack on main.
Scope¶
This building-block view covers the MCP governance line only. It does not attempt to document every crate or every CLI path in the workspace.
Level 1: System Context¶
flowchart LR
Client["Agent / MCP Client"] --> Assay["Assay MCP Policy Stack"]
Auth["Transport Auth / Resource Server"] --> Assay
Approval["Approval Artifact Source"] --> Assay
Policy["Policy Bundles"] --> Assay
Assay --> Consumers["CLI / Replay / Evidence Consumers"] Context boundary¶
External to Assay:
- transport authentication
- token issuance
- approval UI / human workflow systems
- external incident systems
Owned by Assay:
- policy evaluation
- bounded runtime enforcement
- typed decision/evidence payloads
- replay/diff and consumer contracts
Level 2: Container View¶
flowchart TD
A["Policy Bundle"] --> B["Runtime PEP Hook"]
C["Context Envelope / PIP Inputs"] --> B
B --> D["PDP / Evaluator"]
D --> E["Typed Decision Model"]
E --> F["Bounded Enforcement Layer"]
F --> G["Evidence + Outcome Emission"]
G --> H["Replay / Diff Basis"]
G --> I["Consumer Read Layer"] Level 3: Building Blocks¶
1. Policy Bundle¶
Responsibility: - hold typed rules, obligations, compatibility expectations, and evaluator inputs
Owns: - decision contract inputs - obligation declarations - allow/deny semantics at policy level
Does not own: - transport auth - approval UX - policy backend migration strategy
2. Runtime PEP Hook¶
Responsibility: - intercept MCP runtime calls deterministically - gather context and hand off to policy evaluation
Owns: - pre-execution interception - runtime call envelope - handoff into evaluator and enforcement path
3. Context Envelope / PIP Inputs¶
Responsibility: - carry policy-relevant context into evaluation and downstream evidence
Stable fields include: - lane - principal - auth_context_summary - approval_state - other bounded runtime summaries
4. PDP / Evaluator¶
Responsibility: - produce typed decisions from policy + context
Owns: - rule matching - decision typing - bounded compatibility handling for legacy decision shapes
Does not own: - token issuance - transport negotiation - broad control-plane semantics
5. Typed Decision Model¶
Responsibility: - normalize runtime outcomes into a stable contract
Stable decision set: - allow - allow_with_obligations - deny - deny_with_alert
Compatibility path: - legacy AllowWithWarning remains a bounded compatibility layer
6. Bounded Enforcement Layer¶
Responsibility: - execute only the obligations and enforcement paths explicitly landed in the wave line
Current bounded executions: - log - alert - approval_required - restrict_scope - redact_args
7. Fail-Closed Selector¶
Responsibility: - choose deterministic deny/fallback behavior for fail-closed situations
Owns: - fail-closed typing - fail-closed reasons - separation from policy-origin deny
8. Evidence + Outcome Emitter¶
Responsibility: - emit decision events, obligation outcomes, normalized evidence, and additive compatibility fields
Owns: - decision event payloads - obligation fulfillment evidence - deny/evidence convergence fields
9. Replay / Diff Basis¶
Responsibility: - provide stable replay and comparison payloads across policy revisions and reader generations
Owns: - replay diff basis - deterministic diff buckets - compatibility normalization
10. Consumer Read Layer¶
Responsibility: - support deterministic downstream reads by CLI/reporting/replay consumers
Owns: - read precedence - compatibility markers - context completeness metadata for payload consumers
Responsibility Matrix¶
| Building block | Primary responsibility | Key bounded outputs |
|---|---|---|
| Policy bundle | policy contract | typed rules, obligations |
| Runtime PEP hook | interception | runtime call envelope |
| Context envelope | input completeness | lane/principal/auth/approval summaries |
| PDP / evaluator | decision | typed decision |
| Decision model | normalization | stable decision variants |
| Enforcement layer | bounded runtime action | approval/scope/redaction outcomes |
| Fail-closed selector | fallback semantics | typed fail-closed deny reason |
| Evidence emitter | audit contract | decision events, obligation outcomes |
| Replay / diff basis | comparison contract | deterministic replay basis |
| Consumer read layer | downstream robustness | compat fields, read precedence |
Separation Rules¶
Policy deny vs fail-closed deny vs enforcement deny¶
These must remain distinct in evidence and replay. That distinction is now a structural property of the stack, not a best-effort convention.
Runtime capability growth¶
Any new runtime capability must arrive as a new bounded wave. It should attach to an existing block or add a clearly named new block. It must not blur responsibilities between evaluator, enforcement, and evidence.
Auth boundary¶
Auth context is consumed, not issued. No building block here is allowed to become a hidden IdP or token broker.
Maintainer Guidance¶
If a change does not clearly fit one building block, stop and re-evaluate the scope. That is usually a sign the change belongs in a new bounded wave or needs an explicit architecture decision.