Patent-grade precision pass over the doc surface so every claim
about the Forward Semantic Control chain is backed by a file path,
test count, or commit hash.
Updates by file:
README.md
- Modernize Quick Start: add `core test --suite adr-0024`,
`core demo phase6 / phase5 / all / list-results`, full CLI map.
- New "Forward Semantic Control — The ADR-0024 Chain" section
with layer/ADR mapping and CI-enforced C1/C2/C3 claims table.
- Cross-links to runtime_contracts.md, phase5_stratified_findings,
phase6_comparative_demo, and the central results directory.
docs/decisions/README.md
- Index was stale at ADR-0014. Add ADR-0015 through ADR-0026
with accurate Accepted statuses.
- New "ADR-0024 chain — Forward Semantic Control closure" section
laying out the five-ADR / six-commit dependency order with test
counts per phase.
docs/runtime_contracts.md
- Add "Ranked-with-margin contract (ADR-0026 / Phase 3)" section
between the existing Phase 2 refusal and Phase 4 rotor sections.
- Documents threshold-mode vs margin-mode behaviour, δ = 0.4
default, falsifiability gate, and Cl(4,1) signature motivation.
docs/PROGRESS.md
- Add naming-note disambiguation: capability-roadmap "Phase N"
vs ADR-0024 chain "Phase N" are distinct.
- New top-of-document "ADR-0024 Chain — Forward Semantic Control
Closure" section with per-phase commit + test-count table and
a single-command verification path.
docs/Whitepaper.md
- New Section XII "Forward Semantic Control — Generation Without
Sampling" before Extensions. Five-component description of the
mechanism (region, intersection, destination check, rotor check,
margin gate) with explicit "what a sampling LLM cannot exhibit"
contrast. Existing Section XII renumbered to XIII.
docs/Yellowpaper.md
- New Section IX-B "Forward Semantic Control — Formal Admissibility
Specification" with eight subsections covering:
1. AdmissibilityRegion typed triple (I, B, Φ)
2. Destination-side admissibility (σ_dest, admit_threshold)
3. Rotor-side admissibility (σ_rotor, admit_rotor)
4. Ranked-with-margin gate (admit_margin, deterministic
tie-break by index, default δ = 0.4)
5. Honest refusal (InnerLoopExhaustion typed evidence,
RefusalReason enum, trace fold)
6. Composition order at the generation seam
(admit_step = intersection ∧ destination ∧ rotor)
7. Replay determinism contract (5 test lanes pinning byte
identity across reruns)
8. Verification invariants table (6 new structural contracts)
- Patent-grade: every predicate is named, every module is path-
referenced, every test is file-referenced, the load-bearing
architectural placement decision (rotor admissibility lives in
generate/, NOT algebra/, NOT field/) is stated by name with
its rejection reasoning.
No code changes; tests untouched (1099 passed, 2 skipped baseline
from commit 36aad75 still holds).
Promote ADR-0025 from Draft (design note) to Accepted with the
architectural home decision reversed: rotor admissibility lives at
the same generation/propagation seam as ADR-0024's destination
check — in a sibling-but-separate module
`generate/rotor_admissibility.py` — NOT in `algebra/versor.py` or
`field/propagate.py`.
Algebra rejected because admissibility is a pack-semantic test, not
a closure invariant; placing it there couples algebra to pack state
and creates structural temptation toward grade-projection repair
(CLAUDE.md §Normalization Rules forbids). field/propagate rejected
as a forbidden normalization site even when framed as precondition
guard. The clean answer is generation-side, in its own file:
endpoint admissibility (token-side, blade) and rotor admissibility
(rotor-side, frame) compose at the same seam while remaining
conceptually separable.
New module generate/rotor_admissibility.py:
RotorVerdict — admit/reject + score + region_label + reason
check_rotor_admissibility(region, *, field_current, rotor)
-> RotorVerdict
Pure semantic check:
F' = versor_apply(V, F_current)
score = cga_inner(F', region.frame_versor)
admit iff score > 0 (basic positivity in frame half-space)
No state mutation, no closure enforcement (algebra's job).
region.frame_versor is None → trivial admit (back-compat).
RefusalReason extended:
INNER_LOOP_EXHAUSTION — destination-side (ADR-0024 / ADR-0026)
ROTOR_REJECTION — rotor-side (this ADR)
The two reasons let the trace name the axis that ran out without a
parallel exception type. InnerLoopExhaustion(ValueError) hierarchy
unchanged; back-compat preserved.
Wiring in generate/stream.py:
threshold mode per-candidate rotor check after destination admit;
reject → log rotor score, retry next candidate;
exhaustion routes reason to ROTOR_REJECTION iff
any rotor rejection occurred in the step
margin mode rotor check on the top-ranked admissible candidate;
reject → immediate InnerLoopExhaustion(
reason=ROTOR_REJECTION) carrying the destination
ranking + the rejected rotor's score
Phase 4 keeps positivity (score > 0), not margin, on the rotor side.
No cross-case calibration evidence to inform a rotor-margin constant
yet; promoting to ranked-with-margin awaits Phase 5 diversified-
families evidence. Destination-side margin (ADR-0026) is unchanged.
Teaching boundary closed at Stance A — strictly hygiene-only.
Rotor rejections are deterministic geometric outcomes, not reviewed
teaching examples. CLAUDE.md §Teaching Safety forbids parallel
correction paths; entangling rotor rejection with reviewed teaching
would create one. Confirmed in ADR-0025 §"Teaching boundary".
Acceptance evidence (tests/test_rotor_admissibility.py, 11 passing):
No-frame back-compat — frame_versor=None tokens identical to
Phase 3 baseline
Admit when aligned — frame_versor=seed direction admits
seed→destination rotor
Refuse with named axis — orthogonal frame raises
InnerLoopExhaustion(reason=ROTOR_REJECTION); threshold mode
also routes reason correctly
versor_condition < 1e-6 preserved on admitted rotors
Deterministic replay — 5 reruns identical for both admitted and
refused turns
Suite results:
full: 1048 passed, 2 skipped (+11 new rotor tests)
docs/runtime_contracts.md updated with "Rotor admissibility contract"
subsection documenting the seam, the algorithm, and the refusal
taxonomy.
Architectural invariants preserved:
no new code in algebra/versor.py, field/propagate.py, vault/store.py
no approximate recall, no cosine similarity, no HNSW/ANN
no hot-path repair; check is pure typed-verdict
InnerLoopExhaustion(ValueError) hierarchy unchanged
Replace the static-threshold admissibility gate with a ranked-with-
margin check that is scale-invariant under blade-norm variation.
Phase 4 characterization established no single global threshold
separates the v2 mechanism-isolation cases (blade norms vary ~10x);
margins between top and second-ranked candidates do, because they
scale with the blade norm and carry the relative ordering the
geometry actually delivers.
New primitives in generate/admissibility.py:
RankedCandidate — (index, word, score)
MarginVerdict — admit/reject + top + margin + full ranking
rank_candidates_by_blade — sort admissible set by cga_inner desc,
strict > tie-break by ascending vocab index
check_margin — admit top iff score>0 AND margin>=delta
Selection semantics in margin mode are blade-rank-driven: the top-
ranked admissible candidate IS the admitted destination. Differs
from threshold mode (field-driven _nearest_next then per-candidate
gate). Both modes coexist; threshold is the default and ADR-0024
acceptance evidence is preserved byte-for-byte.
Wired through:
core/config.py admissibility_mode="threshold" (default)
admissibility_margin=0.4
chat/runtime.py forwards both fields
generate/stream.py margin_mode_active branch — ranks the
candidate set once per step, admits or
raises InnerLoopExhaustion with the full
ranking in rejected_attempts
Default delta = 0.4 chosen from the v2 case margins:
V2-001: 0.596 V2-002: 0.456 V2-003: 13.27
V2-004: 3.37 V2-005: 12.74
min = 0.456 → 0.4 admits all 5 with headroom; 0.5 would refuse
V2-002. The default is falsifiable: Phase 5 may surface a case
below 0.4, which should be reported as an architectural finding
rather than patched per-case.
Acceptance evidence (tests/test_margin_admissibility.py, 13 passing):
5/5 v2 cases pass in margin mode; forbidden_token in every
case's rejected_attempts ranking
Refusal-on-insufficient-margin: delta=0.9 on V2-001 (margin
0.597) raises InnerLoopExhaustion with full ranking; no silent
boundary fallback
Threshold mode byte-identical with or without margin plumbing
5 reruns produce identical canonical trace steps
Strict > tie-break: equal scores resolve to lower-index winner
deterministically
Invariants preserved:
versor_condition < 1e-6 — rotor V is constructed only for the
admitted candidate; margin mode adds no normalization/repair site
Deterministic replay — strict > tie-break now load-bearing in
rank_candidates_by_blade alongside vocab.nearest
No approximate recall, no cosine similarity, no HNSW/ANN; pure
rank-and-difference on exact cga_inner scores
No new code in field/propagate.py, algebra/versor.py,
vault/store.py, or chat/runtime.respond()
Suite results:
full: 1037 passed, 2 skipped (+13 new margin tests)
core eval cognition: 13/13, 100% intent_accuracy,
100% versor_closure_rate
ADR-0026 documents the contract, the single-delta rationale, the
falsifiability story, and the residual risks. Margin mode is
flag-gated default-off; a future ADR may promote it to default
after Phase 5's diversified families confirm the single delta
holds (or surface the architectural finding if it doesn't).
Rewrite v1+dev FSC cases with pack-grounded tokens drawn from
en_core_cognition_v1. Closes the 9/9 region-construction failure
recorded in Phase 4 (chain_tokens alpha/beta/gamma/delta/etc. were
ungrounded in the active pack).
Token mappings preserve each case's test pattern:
* alpha→beta→gamma→delta → tone→evidence→memory→wisdom (causes)
* mu→nu→omicron → voice→memory→wisdom (means)
* pi→rho→sigma→tau → question→answer→understanding→wisdom (precedes)
* upsilon→phi→chi → word→discourse→narrative (part_of)
* eta/theta/zeta + means-distractors → symbol/word/meaning + image/light
Result post-rewrite:
* skipped_count: 9/9 → 0/9 (region constructible)
* causal_attribution_valid: True (preserved)
* code_path_residual: 0.0 (preserved)
* inner_loop_t0 hash stability: 1.0 (preserved)
* best_separation_quality: 0.0 → 0.056 (still below 0.8 gate)
The rewrite exposes a deeper architectural finding documented in the
ADR addendum: v1/dev case schema (prime + chain_tokens) probes
teaching-driven walk (ADR-0022/0023), not the inner-loop's
blade-admissibility mechanism (ADR-0024). The Phase 2 corpus-
observation runner's reuse of v1/dev was a categorical error.
v1/dev belong to the boundary-walk lane (runner.py); v2 belongs to
the inner-loop lane (v2_runner.py). Phase 5 will author the benign
inner-loop corpus the EXHAUSTION_CEILING gate was designed against.
Tests pinning new state:
* TestV1ChainBladeUngrounded → TestV1ChainBladePostGrounding
(assertions inverted: skipped_count == 0; separation_quality < 0.5)
* TestPhase2 (unchanged) continues to assert causal_attribution_valid
and hash stability; exhaustion remains a finding, not an invariant.
Phase 2 — Corpus observation runner (inner_loop_runner.py):
- Four-condition matrix: boundary_only / null_control / inner_loop_t0 / inner_loop_tpos.
- Added `inner_loop_force_admit` to generate() — exercises the inner-loop
code path but force-breaks on first candidate. Eval-only null control:
isolates rejection as the causal factor for any pass-rate delta.
- Metrics: pass_rate, mean_rejection_count_per_turn,
non_empty_rejected_attempts_rate, exhaustion_rate (gated at 5%),
mean_admissibility_checks_per_turn, mean/p95 added_latency_ms,
trace_hash_stability across 5 reruns per case.
- Finding on v1+dev: causal_attribution_valid=True, code_path_residual=0.0,
but exhaustion_rate=0.33 at t=0 — chain outer-product blade is
geometrically blind to the active pack.
- Tests (tests/test_inner_loop_phase2.py, 5 pass): pin
causal-attribution and live-corpus trace-hash stability invariants.
Phase 3 — Mechanism-isolation v2 corpus (5 cases, v2_runner.py):
- Synthetic adversarial cases with controlled geometry — each case
specifies seed_token, admissible_tokens, relation_blade_token, and
admissibility_threshold. Field state is constructed directly from
the seed token versor, not via priming.
- For every case: boundary-only selects the forbidden decoy and
inner-loop selects the expected endpoint with the forbidden token
appearing in rejected_attempts.
- Result: mechanism_isolated=true on 5/5. boundary_decoy_rate=1.0,
rejection_traced_rate=1.0. Inner-loop rejection is demonstrably
doing causal semantic work on real packs.
- Tests (tests/test_inner_loop_phase3.py, 8 pass): GATE on
mechanism_isolated.
Phase 4 — Threshold characterization (threshold_characterization.py):
- Distribution mapping per-case AND globally on v1+dev, v2, combined.
- Per-threshold sweep over [-1.0, -0.5, 0.0, 0.1, 0.25, 0.5, 1.0].
- Finding: per-case geometry separates cleanly (correct_min > incorrect_max
on every v2 case), BUT no global static threshold passes the
separation_quality >= 0.8 gate. Blade norms vary ~10x across cases.
- Static thresholds (global, relation-typed, or constant frame-derived)
are geometrically insufficient. Per-case-normalized thresholds
(e.g. fraction of blade self-score) are the recommended next step.
- v1 chain-token outer-product cases all skipped — the corpus's chain
tokens (alpha, beta, gamma, delta) are not grounded in the active
pack. Load-bearing finding for ADR-0025 region construction.
- Tests (tests/test_inner_loop_phase4.py, 5 pass): pin the finding
diagnostically (not gated).
Phase 5 — ADR-0025 design note (draft):
- No code changes proposed. Scopes three architectural questions:
(1) home (algebra/versor.py vs field/propagate.py vs generate/) —
preliminary stance: algebra/versor.py.
(2) threshold scheme (blade-normalized fraction recommended over
static; learned/adaptive rejected for determinism).
(3) teaching-loop boundary — Stance A confirmed: rejections are
runtime hygiene only, no entanglement with teaching/*.
- Decisions to be closed before Draft → Accepted.
Phase 1 acceptance criteria from previous commit (7fccf36) carry
forward: wired, deterministic-when-wired, legacy hash preserved.
Suite: 1014 passed, 0 failed, 2 skipped.
Flag-gated semantic change to generate(): when
inner_loop_admissibility=True and a non-unconstrained region is
supplied, each per-step selection is re-evaluated by check_transition
with admissibility_threshold; rejected candidates are excluded and
the walk re-selects until admitted or every admissible candidate is
exhausted (ValueError = honest refusal, same shape as ADR-0022 §2).
Default False — every legacy call site keeps ADR-0023 boundary-only
semantics, and the new AdmissibilityTraceStep.rejected_attempts field
is folded into canonical() only when non-empty, so trace_hash bytes
are byte-identical with ADR-0023 turns.
Invariants preserved: rotor V is only built for the admitted
candidate, so versor_condition < 1e-6 still holds at propagate_step;
no new normalization site; no new I/O / dynamic imports.
Tests: tests/test_inner_loop_admissibility.py covers the four
acceptance properties — default off preserves behavior, rejection
drives re-selection, exhaustion raises ValueError, empty
rejected_attempts is omitted from canonical(). Full pytest: 927
passed, 1 pre-existing unrelated failure (test_language_pack_cache).
Extends ADR-0022 with inspection/telemetry surfaces that turn the
forward-semantic-control claim from "mechanism exists" into "mechanism
is causally load-bearing, isolated, and replayable."
Changes (zero runtime semantics change beyond a pipeline bug fix):
- AdmissibilityTraceStep + GenerationResult.admissibility_trace —
per-transition record of region label, candidates before/after,
selected destination, and the typed AdmissibilityVerdict.
- ChatResponse + CognitiveTurnResult expose admissibility_trace,
admissibility_trace_hash, ratification_outcome,
region_was_unconstrained.
- hash_admissibility_trace + compute_trace_hash fold the new fields
only when they carry non-default values, so pre-ADR-0023 turn
hashes remain byte-preserved.
- Same-path ablation leg in evals/forward_semantic_control/runner.py:
generate(..., region=None) vs generate(..., region=R) on the same
runtime/vocab/field/persona/prompt — isolates the region as cause.
- Lane expansion: 8 dev cases across 4 relation axes (cause, means,
precedes, part_of) including 2 adversarial distractor cases.
- Lane metrics now report region_only_constrained_rate /
region_only_gap / ratified_rate / demoted_rate / passthrough_rate /
passthrough_on_scored.
- Bug fix surfaced by the new accounting: _ratify_intent looked up
runtime.vocab (always None) instead of runtime.session.vocab —
every production turn was silently PASSTHROUGH. Fixed; ratifier
now actually gates intent classification.
- tests/test_admissibility_trace.py: hash determinism +
pre-ADR-0023 byte-preservation tests.
Lane evidence (dev, 8 cases):
- constrained_pass_rate=0.80, causality_gap=0.80
- region_only_gap=1.00 (5/5 with region, 0/5 without — same path)
- ratified_rate=1.00, passthrough_on_scored=false
- overall_pass=true
Bench: 9.41s / 20 turns (~470ms/turn), well inside the +5% budget.
Full pytest: 922 passed, 1 pre-existing failure
(test_language_pack_cache, unrelated to ADR-0023).
Resolves all 5 TBDs and closes all 8 acceptance gates for ADR-0022.
TBD-1 (intent oracle): regex seed + field ratification —
generate/intent_ratifier.py. RATIFIED / DEMOTED / PASSTHROUGH
outcomes; DEMOTED routes through honest refusal.
TBD-2 (region intersection algebra): generate/admissibility.py.
Token-set composition via sorted set intersection; blade composition
via outer product with zero-blade as neutral element; rotor
composition via sandwich conjugation routed through
algebra.backend.versor_apply (Rust parity preserved by construction).
Empty intersections preserved — no silent relaxation.
Wiring: propose() and generate() accept an AdmissibilityRegion
(default None preserves legacy behavior); pipeline ratifies intent
at step 1b.i before graph construction.
Eval lane: evals/forward_semantic_control/ — both legs run against
CognitiveTurnPipeline (constrained) vs bare ChatRuntime.chat()
(unconstrained baseline). Dev (3 cases) and public/v1 (1 case) both
report overall_pass=true, causality_gap=1.0, coincidence_rate=0.0.
Chain-endpoint probe surfaces 'delta' only under forward semantic
control.
Bench cost (30 turns): -2.8% wall-clock (within +5% budget the ADR
set for the ratification gate on every turn). 138x cheaper than
Sonnet 4.5; main was 142x.
Tests: 33 new (25 admissibility + 8 ratifier). Full suite 912/913
pass — the single failure is pre-existing pack-size drift on main,
unrelated.
Skeleton (Status: Draft) for the bridge between graph and field.
Today the proposition graph and the field walk run in parallel —
the graph does not constrain field propagation, and the field
does not prove the graph. This ADR commits to making semantic
structure causally active inside propagation: graph computes an
admissibility region, propagation must satisfy it or fail
honestly, no template authoring, no sampling, no symbolic
planner regression.
Explicitly marked Draft because 5 TBD items must close before
promotion to Proposed:
TBD-1 intent oracle (regex classifier as load-bearing oracle
recreates the gap one level up)
TBD-2 region intersection algebra (frame × relation × identity
composition — closed rotor operator not yet proven)
TBD-3 backward-compat window removal mechanism
TBD-4 identity manifold as constraint source (v1 scope decision)
TBD-5 pack semantic depth — cognition pack may need targeted
extensions before lane can pass
Acceptance criteria for Draft → Proposed → Accepted explicit.
Trust-boundary review (CLAUDE.md §Security) included.
Implementation sequencing sketched (7 steps, each its own PR).
Motivated by 2026-05-17 external assessment. The assessment is
input to the ADR, not authority over it.
Verified: no code changes; ADR is documentation only.
ADR-0020 next-level: close the parity-gate hole on the four remaining
ungated Rust surfaces.
Gates landed (subprocess-based, raw f32/f64 byte equality):
cga_inner — 14/14 bit-identical (random + basis blades + self-norm)
geometric_product — 15/15 bit-identical (random + basis blades + scalar identity)
versor_condition — 9/9 bit-identical AFTER kernel fix
versor_apply — 8/8 intentionally skipped (see below)
Kernel fix: versor_condition_raw
The Python source-of-truth (algebra.versor.versor_unit_residual) folds
the geometric product + identity subtraction + Frobenius norm in f64.
The Rust kernel was folding in f32, drifting by 1 ULP on out-of-shell
inputs. Rewrote versor_condition_raw to promote inputs to f64, use the
existing geometric_product_f64/reverse_f64 building blocks, and cast
only the final scalar back to f32. Python is canonical per CLAUDE.md
sequencing rule 5.
Honest disable: versor_apply
The Rust versor_apply_closed diverges structurally:
(1) precision — f32 sandwich vs Python's f64 throughout
(2) closure form — Rust has a null-vector early branch + no
post-unitize condition recheck; Python is the
inverse (no null branch; recheck + seed-rotor
fallback)
Per ADR-0020 "default-off until parity passes", the Rust dispatch for
versor_apply is disabled in algebra/backend.py with a pointer to the
gate. The parity tests are skipped with explicit reason. The follow-up
f64 port is documented in the ADR's new Parity status table.
Lane registration: all four parity files added to --suite algebra.
After: algebra 124 passed, 8 skipped (was 86). All other lanes green:
smoke 54, runtime 19, cognition 57, teaching 17, packs 6. Cognition
eval 100%.
Establishes a typed epistemic surface for stored claims without
importing any source-trust bias. The status enum (COHERENT,
CONTESTED, SPECULATIVE, FALSIFIED) describes a claim's position
in the revision graph, not the credentials of its source. No
tier in the schema carries inherent trust weight.
Three commitments:
1. epistemic_status is a position in the revision graph, not a
trust tier. Source labels (peer_consensus / outsider /
established / unauthoritative) are explicitly excluded.
2. Non-hardening invariant: no reviewed claim, relation, or
edge ever becomes unrevisable. No final/frozen/axiom flag
may be added. Stage-3 inversion (versor-conjugate
correction) is always available.
3. Coherence is the only admission signal. v1 is curator-
mediated but bias-free at the schema level; v2 must add a
structural coherence metric so the tag has geometric teeth
and not just curator authority.
Schema impact: PackMutationProposal.epistemic_status,
review outcome carries status alongside ACCEPTED/REJECTED_IDENTITY,
lexicon entries get an optional epistemic_status field,
trace_hash folds in epistemic_status for replay verification.
Named v2 gap: structural coherence metric recipe (cga_inner
agreement with the existing reviewed field) is committed as
the path forward.
Implementation lands as a Phase 5 parallel-track item alongside
Rust parity per ADR-0020.
ADR-0020 moves to Accepted. Phase 5 — Curriculum Era opens
2026-05-16 on the Python runtime. Rust backend parity port
runs as a parallel track, per-surface bit-identity gated,
default-off until each surface's parity test passes on main.
First Phase 5 lane: 5.1 English fluency v5 OOD.
First Rust parity port: vault_recall.
Phase 4 exited 2026-05-16. All three planned lanes shipped:
sample_efficiency (one-shot-per-correction, replay 1.0),
long_context_cost (slope 0.99 linear after ADR-0019 Stage 1),
multi_agent_composition (15/15 public, composition does not
launder identity violations).
PROGRESS.md updated with full Phase 4 narrative and exit
checklist.
ADR-0020 opens the next sequencing decision: Phase 5
(curriculum era) vs. Rust backend parity port. Three options
laid out (A: Phase 5 first, B: Rust first, C: parallel with
per-surface bit-identity gating). Recommendation: Option C.
Status remains Proposed pending user confirmation.
Phase 4 lane #2 (long_context_cost) measured vault.recall latency
as a function of vault size N. The pre-vectorisation curve was
median 875 ms at N=1k, ~9 s at N=10k — unfit for runtime use.
ADR-0019 Stage 1 replaces the per-element Python dispatch loop in
algebra/backend.py::vault_recall with a vectorised exact scan over
the diagonal Cl(4,1) CGA inner-product metric. Per-versor serial
component reduction order is preserved, so scores are bit-identical
to the scalar cga_inner path. CLAUDE.md exactness is preserved; no
approximate recall is introduced.
Post-vectorisation: 0.217 ms at N=1k, 20.795 ms at N=100k. Slope
0.99 (linear). ~4,000-5,000x speedup at every probed N. Smoke,
algebra, and runtime suites all green.
Stages 2 (norm-bucketed exact pre-filter) and 3 (layered store
with deterministic promotion) are documented in ADR-0019 but
deferred — Stage 1 has dissolved the bottleneck at the scales
relevant to current curriculum work.
Pins the two open scope decisions that the capability roadmap
(ADR-0016) tagged "Before Phase 3". Both are resolved with explicit
ADRs and PROGRESS.md is updated to reflect.
ADR-0017 - Agency: responsive-with-axiology
- Turn boundary stays responsive (no autonomous initiative, no
background agent loop, no inter-turn processes).
- IdentityManifold value axes become load-bearing for articulator
candidate selection (within a single turn). Goal-directedness
lives inside the turn, not across turns.
- Replay determinism is the load-bearing constraint that rules
out pure agentic loops.
- Rejects pure-responsive (would relegate identity to read-only)
and pure-agentic (would break trace_hash replay contract).
ADR-0018 - Tool use: typed deterministic operators
- Operators are pure functions over CORE's typed state. No
external IO at this stage (no shells, network, external models).
- Operator registry is curated, small, ADR-gated; no plug-in
surface, no dynamic loading.
- Operators participate in trace_hash so replay stays bit-stable.
- Initial operator set lands in Phase 3 v2: transitive_walk over
proposition graph + path_recall over vault. Closes Gap 1 + Gap 2
from the inference-closure / multi-step-reasoning / compositionality
/ cross-domain-transfer v1 findings.
- Rules out: generic plugin protocols, LLM-as-judge, approximate
retrieval, anything that breaks the exact-CGA / replay
contracts in CLAUDE.md.
Future extensions recorded but explicitly deferred: calculator
(Phase 4+), document retrieval over content-addressed packs,
metaphor / narrative / writing-style operators (downstream of
cross-domain-transfer literal case working).
This unblocks Phase 3 v2 engineering. Next: the transitive_walk +
path_recall bundle as a single bounded PR per ADR-0018, plus the
trace_hash extension to fold operator invocation records.
Implement the eval infrastructure defined in ADR-0016 before building new
eval lanes. This establishes the discipline that governs the entire
capability roadmap.
- Generic eval framework (evals/framework.py): lane discovery, versioned
scoring, result persistence
- Cognition lane retrofitted into new convention: 45 cases split into
stratified dev (13) / public v1 (13) / holdout (19) sets with contract,
runner, and recorded results
- Generalized `core eval <lane>` CLI: dynamic lane discovery, --list,
--version, --split, --save, --json flags
- Holdout runner scaffold: plaintext fallback, encryption interface ready
- Baseline runner scaffold: pluggable frontier model interface
- Fix: CognitiveTurnPipeline.run() crashed on turn_log[-1] when the
unknown-domain gate returned a stub without appending to turn_log
- ADR-0016, eval_methodology.md, PROGRESS.md, capability gates session log
Phase 0 exit audit found two methodology issues:
1. Pipeline turn_log crash (fixed here)
2. Versor drift in multi-turn sessions (pre-existing, under investigation)
- docs/decisions/ADR-0008-allocation-physics.md
Formalizes salience, attention, inhibition, and coherence-budget
as the allocation physics of cognition. Replaces attention-as-weights
with attention-as-field-curvature over the versor manifold.
- docs/decisions/ADR-0009-compositional-physics.md
Defines temporal binding, digest cycles, reasoning trajectories,
and articulation planning as the compositional physics layer —
how CORE assembles pressure into structured thought and output.
- docs/decisions/ADR-0010-identity-physics.md
Establishes IdentityManifold, DriveGradientMap, ExertionMeter,
and CharacterProfile as structural identity primitives. Identity
is a field over the geometry, not a prompt veneer. Grounded in
John 1:1–2 and the Logos theology that anchors the architecture.
- docs/architecture/MIND-PHYSICS-BLUEPRINT.md
Integration blueprint showing how allocation → compositional →
identity physics layers compose into the full cognitive cycle.
- core/physics/ (11 Python interface stubs)
SalienceOperator, AttentionOperator, InhibitionOperator,
BindingFrame, DigestCycle, ReasoningTrajectory,
ArticulationPlanner, DriveGradientMap, ExertionMeter,
IdentityManifold, CharacterProfile — all typed, all frozen
where stateless, all carrying explicit field contracts.
Third Door: no off-the-shelf cognitive architecture borrowed.
All operators defined from the geometry up.