core/docs/decisions
Shay 6f67e9a616 feat(safety): ADR-0032 — SafetyCheck structural surface
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.
2026-05-17 20:25:22 -07:00
..
ADR-0001-vocab-layer-invariants.md docs: add ADR log and session decision record for 2026-05-12 2026-05-12 20:56:21 -07:00
ADR-0002-ingest-layer-design.md docs: add ADR log and session decision record for 2026-05-12 2026-05-12 20:56:21 -07:00
ADR-0003-coordinate-system-dissolution.md docs: add ADR log and session decision record for 2026-05-12 2026-05-12 20:56:21 -07:00
ADR-0004-rotor-as-operator-not-property.md docs: add ADR log and session decision record for 2026-05-12 2026-05-12 20:56:21 -07:00
ADR-0005-language-pack-contract.md docs(decisions): ADR-0005 language pack contract + session addendum [Batch 1] 2026-05-12 21:16:00 -07:00
ADR-0006-field-energy-operator.md ADR-0006: wire energy recomputation into propagate_step, add test_energy.py, mark ADR Implemented 2026-05-14 12:39:49 -07:00
ADR-0007-valence-layer.md docs: ADR-0006 field energy operator, ADR-0007 valence layer, session addendum 2026-05-12-b 2026-05-12 22:13:29 -07:00
ADR-0008-allocation-physics.md feat(physics): add mind-physics layer — ADR-0008/0009/0010, blueprint, and operator stubs 2026-05-12 23:20:58 -07:00
ADR-0009-compositional-physics.md feat(physics): add mind-physics layer — ADR-0008/0009/0010, blueprint, and operator stubs 2026-05-12 23:20:58 -07:00
ADR-0010-identity-physics.md feat(physics): add mind-physics layer — ADR-0008/0009/0010, blueprint, and operator stubs 2026-05-12 23:20:58 -07:00
ADR-0011-renderer.md chore: fix package name, add core/__init__.py, ADR-0011, session note 2026-05-13 2026-05-13 10:44:42 -07:00
ADR-0012-core-ingest-governance-layer.md docs: add ADR-0012, ADR-0013, ADR-0014, SESSION-2026-05-13 2026-05-13 11:24:10 -07:00
ADR-0013-sensorium-multimodal-protocol.md docs: add ADR-0012, ADR-0013, ADR-0014, SESSION-2026-05-13 2026-05-13 11:24:10 -07:00
ADR-0014-train-learning-loop.md docs: add ADR-0012, ADR-0013, ADR-0014, SESSION-2026-05-13 2026-05-13 11:24:10 -07:00
ADR-0015-language-packs-and-holonomy-resonance.md Document language pack manifold contract 2026-05-13 13:13:06 -07:00
ADR-0016-capability-roadmap.md feat(evals): Phase 0 — benchmark methodology lock-in and eval framework 2026-05-15 22:36:53 -07:00
ADR-0017-agency-scope.md docs(adr): resolve Agency + Tool-use scope decisions (ADR-0017, ADR-0018) 2026-05-16 14:51:42 -07:00
ADR-0018-tool-use-scope.md docs(adr): resolve Agency + Tool-use scope decisions (ADR-0017, ADR-0018) 2026-05-16 14:51:42 -07:00
ADR-0019-exact-vault-recall-acceleration.md feat(phase4): long-context-cost lane + ADR-0019 Stage 1 vault recall vectorisation 2026-05-16 16:39:30 -07:00
ADR-0020-phase5-rust-parity-sequencing.md perf(rust): versor_apply f64 parity port — 29x over Python, bit-identical 2026-05-16 20:43:01 -07:00
ADR-0021-epistemic-grade-policy.md docs(adr): ADR-0021 Epistemic Grade Policy — coherence is the only signal 2026-05-16 17:10:58 -07:00
ADR-0022-forward-semantic-control.md feat(adr-0022): Forward Semantic Control — Accepted 2026-05-17 12:10:20 -07:00
ADR-0023-forward-semantic-control-proof.md feat(adr-0023): Forward Semantic Control proof evidence — Accepted 2026-05-17 12:55:19 -07:00
ADR-0024-inner-loop-admissibility.md feat(adr-0024): Phase 1 addendum — retire v1/dev fixture rot 2026-05-17 14:43:34 -07:00
ADR-0025-rotor-frame-admissibility-design-note.md feat(adr-0025): Phase 4 — rotor / frame admissibility at the seam 2026-05-17 15:16:32 -07:00
ADR-0026-ranked-admissibility-with-margin.md feat(adr-0026): Phase 3 — ranked admissibility with margin 2026-05-17 15:03:03 -07:00
ADR-0027-identity-packs.md feat(identity-packs): ADR-0028 — pack-driven hedge & claim-strength shaping 2026-05-17 19:42:54 -07:00
ADR-0028-identity-surface-wiring.md feat(identity-packs): ADR-0028 — pack-driven hedge & claim-strength shaping 2026-05-17 19:42:54 -07:00
ADR-0029-safety-packs.md feat(safety): ADR-0029 — always-loaded, never-replaceable safety pack 2026-05-17 19:56:29 -07:00
ADR-0030-depth-language-hedge.md feat(surface): ADR-0030 — depth-language hedge wiring 2026-05-17 20:05:45 -07:00
ADR-0031-score-decomposition-surface.md feat(surface): ADR-0031 — score-decomposition surface (per-axis hedges) 2026-05-17 20:16:22 -07:00
ADR-0032-safety-check-surface.md feat(safety): ADR-0032 — SafetyCheck structural surface 2026-05-17 20:25:22 -07:00
README.md docs: ADR-0024 chain coverage across README, ADR index, contracts, papers 2026-05-17 16:28:54 -07:00
SESSION-2026-05-12-b.md docs: ADR-0006 field energy operator, ADR-0007 valence layer, session addendum 2026-05-12-b 2026-05-12 22:13:29 -07:00
SESSION-2026-05-12-language-packs-addendum.md docs(decisions): ADR-0005 language pack contract + session addendum [Batch 1] 2026-05-12 21:16:00 -07:00
SESSION-2026-05-12.md docs: add ADR log and session decision record for 2026-05-12 2026-05-12 20:56:21 -07:00
SESSION-2026-05-13.md docs: add ADR-0012, ADR-0013, ADR-0014, SESSION-2026-05-13 2026-05-13 11:24:10 -07:00

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:

  1. ADR-0022 — Forward Semantic Control. Establishes the AdmissibilityRegion data structure (allowed indices, relation blade, frame versor) and the contract that a region restricts the admissible token set at generation time.
  2. 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.
  3. 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 typed RefusalReason taxonomy.
  4. 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 in generate/rotor_admissibility.py — a sibling-but-separate module, not in algebra/versor.py (would couple algebra to pack state) and not in field/propagate.py (forbidden normalization site).
  5. 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