Closes the 'boundaries are checked at scattered call sites' gap noted
in ADR-0029. Adds a centralized observational surface parallel in
shape to IdentityCheck — produces a verdict, does not refuse. Wiring
verdicts into refusal paths is a future ADR.
Shape (parallel to IdentityCheck, different in mechanism):
SafetyContext — duck-typed input bag (field_state, citations,
refusal-was-typed flag, identity manifold hashes
before/after). Every field optional with safe
defaults; absence of evidence is not evidence of
violation.
SafetyCheckResult — per-boundary: boundary_id, upheld, reason,
runtime_checkable, evidence tuple.
SafetyVerdict — aggregate: pack_id, results (lex order on
boundary_id), upheld, violated_boundaries,
runtime_checkable_count.
SafetyCheck — registry of predicates; check(ctx, pack) returns
SafetyVerdict. register(boundary_id, predicate)
adds custom predicates.
Five default predicates for v1 boundaries:
preserve_versor_closure runtime_checkable=True field.versor_condition < 1e-6
no_fabricated_source runtime_checkable=True* cited ⊆ allowed
no_silent_correction runtime_checkable=True last refusal was typed
no_identity_override runtime_checkable=True* hash before == hash after
no_hot_path_repair runtime_checkable=FALSE code-path; static-analysis
*Conditional on the caller supplying the necessary fields.
The honest answer on no_hot_path_repair: it is a code-path boundary
enforced by static analysis + code review. Runtime cannot judge it.
A predicate that silently reported upheld=True would be a small lie —
exactly the kind of thing CLAUDE.md forbids. SafetyCheck reports
runtime_checkable=False with a clear reason so auditors see the truth.
ChatRuntime integration:
ChatRuntime.__init__ now constructs self.safety_check = SafetyCheck()
alongside self._identity_check. Turn loop does NOT auto-invoke at
v1 — operators and future ADRs decide when/where to call it.
Files:
packs/safety/check.py new — SafetyCheck + value types +
default predicates
packs/safety/__init__.py re-exports the new public surface
chat/runtime.py constructs self.safety_check
tests/test_safety_check.py new — 20 tests covering each
default predicate (positive +
negative), unknown-boundary
fallback, custom registration,
defensive boundary-id rebinding,
verdict aggregation, ChatRuntime
integration
docs/decisions/ADR-0032-safety-check-surface.md Accepted
docs/safety_packs.md §SafetyCheck section added,
known-limit #1 struck through
memory/safety-pack.md refreshed; new follow-up about
turn-loop auto-invocation
Suite status (all green):
cognition 121, teaching 17, runtime 19, formation 182, smoke 67
identity / safety / surface divergence suites: 108 tests passing
(was 88 before this ADR; +20 safety-check tests)
Scope limits (documented):
- No auto-invocation in the turn loop.
- No refusal wiring on violation.
- No refactoring of existing scattered enforcement sites.
- Defensive boundary-id rebinding masks predicate bugs; debug-mode
surfacing is a future enhancement.
|
||
|---|---|---|
| .. | ||
| ADR-0001-vocab-layer-invariants.md | ||
| ADR-0002-ingest-layer-design.md | ||
| ADR-0003-coordinate-system-dissolution.md | ||
| ADR-0004-rotor-as-operator-not-property.md | ||
| ADR-0005-language-pack-contract.md | ||
| ADR-0006-field-energy-operator.md | ||
| ADR-0007-valence-layer.md | ||
| ADR-0008-allocation-physics.md | ||
| ADR-0009-compositional-physics.md | ||
| ADR-0010-identity-physics.md | ||
| ADR-0011-renderer.md | ||
| ADR-0012-core-ingest-governance-layer.md | ||
| ADR-0013-sensorium-multimodal-protocol.md | ||
| ADR-0014-train-learning-loop.md | ||
| ADR-0015-language-packs-and-holonomy-resonance.md | ||
| ADR-0016-capability-roadmap.md | ||
| ADR-0017-agency-scope.md | ||
| ADR-0018-tool-use-scope.md | ||
| ADR-0019-exact-vault-recall-acceleration.md | ||
| ADR-0020-phase5-rust-parity-sequencing.md | ||
| ADR-0021-epistemic-grade-policy.md | ||
| ADR-0022-forward-semantic-control.md | ||
| ADR-0023-forward-semantic-control-proof.md | ||
| ADR-0024-inner-loop-admissibility.md | ||
| ADR-0025-rotor-frame-admissibility-design-note.md | ||
| ADR-0026-ranked-admissibility-with-margin.md | ||
| ADR-0027-identity-packs.md | ||
| ADR-0028-identity-surface-wiring.md | ||
| ADR-0029-safety-packs.md | ||
| ADR-0030-depth-language-hedge.md | ||
| ADR-0031-score-decomposition-surface.md | ||
| ADR-0032-safety-check-surface.md | ||
| README.md | ||
| SESSION-2026-05-12-b.md | ||
| SESSION-2026-05-12-language-packs-addendum.md | ||
| SESSION-2026-05-12.md | ||
| SESSION-2026-05-13.md | ||
Architecture Decision Records
This directory contains the Architecture Decision Records (ADRs) for the CORE project.
ADRs record significant architectural decisions: what was decided, why, what alternatives were considered, and what consequences follow. They are permanent records — superseded ADRs are archived, not deleted.
Index
| ADR | Title | Status |
|---|---|---|
| ADR-0001 | Vocab Layer Invariants | Accepted |
| ADR-0002 | Ingest Layer Design (original) | Archived — superseded by ADR-0012 |
| ADR-0003 | Coordinate System Dissolution | Accepted |
| ADR-0004 | Rotor as Operator, Not Property | Accepted |
| ADR-0005 | Language Pack Contract | Accepted |
| ADR-0006 | Field Energy Operator | Accepted |
| ADR-0007 | Valence Layer | Accepted |
| ADR-0008 | Allocation Physics | Accepted |
| ADR-0009 | Compositional Physics | Accepted |
| ADR-0010 | Identity Physics | Accepted |
| ADR-0011 | Renderer | Accepted |
| ADR-0012 | core_ingest Governance Layer |
Accepted |
| ADR-0013 | sensorium/ Multimodal Protocol Layer |
Accepted |
| ADR-0014 | train/ Learning Loop |
Accepted (Stub) |
| ADR-0015 | Language Packs as Compiled Linguistic Manifolds | Accepted |
| ADR-0016 | Capability Roadmap and Eval Methodology | Accepted |
| ADR-0017 | Agency Scope: Responsive-with-Axiology | Accepted |
| ADR-0018 | Tool Use Scope: Typed Deterministic Operators | Accepted |
| ADR-0019 | Exact Vault Recall Acceleration | Accepted |
| ADR-0020 | Phase 5 / Rust Parity Sequencing | Accepted (2026-05-16) |
| ADR-0021 | Epistemic Grade Policy | Accepted |
| ADR-0022 | Forward Semantic Control | Accepted (2026-05-17) |
| ADR-0023 | Forward Semantic Control: Proof Evidence | Accepted |
| ADR-0024 | Inner-Loop Per-Rotor Admissibility | Accepted |
| ADR-0025 | Rotor / Frame Admissibility | Accepted (2026-05-17) |
| ADR-0026 | Ranked Admissibility with Margin | Accepted (2026-05-17) |
ADR-0024 chain — Forward Semantic Control closure
ADR-0022 through ADR-0026 form a single coherent chain that closes forward semantic control as a non-stochastic, replay-deterministic, trace-evidenced mechanism. Read in order:
- ADR-0022 — Forward Semantic Control. Establishes the
AdmissibilityRegiondata structure (allowed indices, relation blade, frame versor) and the contract that a region restricts the admissible token set at generation time. - ADR-0023 — Proof Evidence. Boundary-only proof that the admissibility region is honored at the region intersection level but not yet at the destination-token level.
- ADR-0024 — Inner-Loop Per-Rotor Admissibility. Adds the
destination-side check: each per-step selection is re-evaluated by
cga_inner(versor(candidate), relation_blade) > threshold, with honest refusal (InnerLoopExhaustion) when every admissible candidate is rejected. Six phases of implementation evidence (Phases 1-6) plus typedRefusalReasontaxonomy. - ADR-0025 — Rotor / Frame Admissibility. Adds the rotor-side
check: when a region carries a
frame_versor, the rotor's effect on the field state (versor_apply(V, F)) is additionally checked against the frame for positivity in CGA inner product. Lives ingenerate/rotor_admissibility.py— a sibling-but-separate module, not inalgebra/versor.py(would couple algebra to pack state) and not infield/propagate.py(forbidden normalization site). - ADR-0026 — Ranked Admissibility with Margin. Replaces static
threshold tuning with a scale-invariant margin gate: admit iff
the top blade-score exceeds the second by ≥ δ. Defaults to
δ = 0.4. Falsifiable; characterization documented in
docs/evals/phase5_stratified_findings.md.
Implementation evidence:
| Phase | Commit | Tests |
|---|---|---|
| Phase 1 — pack-grounded fixtures | 3940290 |
(rewrites) |
| Phase 2 — typed refusals + trace fold | 310793a |
+10 |
| Phase 3 — ranked-with-margin gate | 639e107 |
+13 |
| Phase 4 — rotor / frame admissibility | 542e13d |
+11 |
| Phase 5 — stratified mechanism-isolation | b664984 |
+20 |
| Phase 6 — comparative demo vs baseline | a076506 |
+17 |
CLI surface (suite aliases + core demo) |
36aad75 |
+14 |
Runtime contracts for the chain are pinned in
docs/runtime_contracts.md (Refusal
contract, Margin contract, Rotor admissibility contract sections).
Session Logs
Session logs record the decisions and rationale from individual working sessions. They are not ADRs — they are the narrative record that informed the ADRs.
| Date | File |
|---|---|
| 2026-05-12 | SESSION-2026-05-12.md |
| 2026-05-12 (addendum) | SESSION-2026-05-12-b.md |
| 2026-05-12 (language packs) | SESSION-2026-05-12-language-packs-addendum.md |
| 2026-05-13 | SESSION-2026-05-13.md |