Commit graph

583 commits

Author SHA1 Message Date
Shay
5feedcebd9 feat(persistence): Shape B+ Phase C — SessionContext.snapshot/restore (full lived state)
Composes the FieldState (A) and VaultStore (B) codecs with new codecs for
SessionGraph/TurnNode, ReferentRegistry/ReferentEntry, Proposition, and
DialogueTurn into SessionContext.snapshot()/restore() — the complete lived
session state that must survive reboot for resume-as-same-life.

- session/graph.py: TurnNode + SessionGraph to_dict/from_dict (versors bit-exact).
- session/referents.py: ReferentEntry + ReferentRegistry, preserving the
  _slots<->_history object aliasing via slot->history-index (update_turn_versor
  relies on `is` identity).
- generate/proposition.py + generate/dialogue.py: Proposition + DialogueTurn
  codecs (relation_norm is derived in __post_init__, not persisted).
- vault/store.py: complete the metadata codec — vault metadata can hold a
  Proposition ({"kind":"proposition",...} from generate/proposition.py), tagged
  on encode and reconstructed on decode (lazy import, cycle-free). This closes a
  gap Phase B assumed away ("metadata is primitives only"); surfaced by the
  Phase C JSON-safe integration test.
- session/context.py: snapshot()/restore(). vocab/persona are NOT serialized
  (shared, supplied at restore); restore() mutates self by design (a load).

Exit gate: a real 4-turn session, snapshotted and restored into a fresh context,
is field-equal — field bit-exact, vault recall identical, graph/referents/
dialogue preserved (incl. the referent aliasing). 9 new tests; INV-02 +
session-coherence regression green (68 passed).

Part of the A->E Shape B+ scope (Phase C).
2026-06-05 12:13:46 -07:00
Shay
c0aebf142c feat(persistence): Shape B+ Phase B — VaultStore (de)serialize, exact recall preserved
Adds VaultStore.to_dict/from_dict on top of Phase A's array codec. Persists the
versors (bit-exact via the codec), metadata, store_count, reproject_interval,
and max_entries; rebuilds the derived _exact_index on load and leaves the lazy
_matrix_cache None.

Bright line (vault/store.py is a CLAUDE.md forbidden normalization site): the
load path performs NO reprojection / normalization / repair — it restores the
exact persisted bytes (already null-projected at their last live reproject
boundary) and rebuilds only the pure index. Proven by a test asserting the
restored versors are BIT-IDENTICAL to the originals (a reproject would change
them via null_project) and that exact CGA recall — including the score==inf
exact-match short-circuit — is identical after a save/load cycle.

5 new tests + INV-02 (normalize-not-called-outside-gate) + all vault tests pass
(116 passed). Part of the A->E Shape B+ scope (Phase B).
2026-06-05 11:49:58 -07:00
Shay
21e2ccb508 feat(persistence): Shape B+ Phase A — bit-exact array codec + FieldState (de)serialize
Foundation for L10 resume-as-same-life persistence. Adds:
- core/array_codec.py: a leaf (numpy+base64) codec encoding arrays as
  {dtype, shape, b64(raw bytes)} — BIT-EXACT, never decimal. Float round-trips
  lose zero precision, so a restored versor keeps versor_condition < 1e-6 and a
  replayed turn keeps its trace_hash. dtype carries byte order; float32 is never
  conflated with float64.
- field/state.py: FieldState.to_dict/from_dict. Multivector arrays (F, holonomy)
  go through the byte codec; energy/valence round-trip exactly via JSON-safe
  helpers (lazy physics imports keep field/ cycle-free).

Exit gate (the scope's #1 risk, de-risked first): bit-exact round-trip AND
closure preserved — versor_condition(restored.F) == versor_condition(fs.F)
exactly. 10 codec/FieldState tests + 55 architectural-invariant/runtime tests
pass. Purely additive; no existing behavior changed.

Part of docs/analysis/L10-shapeBplus-persistence-scope-2026-06-05.md (Phase A).
2026-06-05 11:38:58 -07:00
Shay
23bc28caf9 feat(evals): L10 continuity spike — falsifiable long-horizon soak lane
Build evals/l10_continuity/, the empirical gate between the two L10 targets
(T-resume: provable same-life resume; T-experience: continuous experiencing
field-life). Drives the REAL turn loop (ChatRuntime + CognitiveTurnPipeline)
over a deterministic in-vocab corpus, with reboot and orphan-crash legs, and
evaluates falsifiable predicates over recorded evidence. Additive only; no
existing file touched; read-only over the runtime; no serving-path import.

Predicates (each with a *_holds real-soak test AND a *_bites mutation test, per
the CLAUDE.md schema-as-proof discipline):
- P1 closure: versor_condition < 1e-6 every turn (green guard).
- P2a determinism: two independent runtimes -> byte-identical trace_hash.
- P2b reboot transparency (the diagnostic): a reboot never alters pre-reboot
  turns (hard guard); post-reboot transparency is MEASURED and today FALSE --
  the mechanical proof that Shape B (ADR-0146) discards the lived field/vault,
  i.e. "many lives sharing a checkpoint". A pinned test flips if persistence is
  ever added, forcing a doc update so the gap can't close silently.
- P3 bounded resources: vault grows linear-bounded/monotonic (RSS recorded).
- P4 crash recovery: two recoveries from one checkpoint converge (determinism)
  + commit-point/ARIES force boundary (recovered turn_count == committed) +
  atomic-write survives mid-os.replace kill (ADR-0156).
- P5b anchor stability (T-experience crux): field anchors without COLLAPSE
  (dist_to_anchor not -> 0) or FREEZE (turn_movement not -> 0); the long-horizon
  test of the sanctioned _session_anchor_pull (alpha=0.05). Thresholds measured.
- P5c coherence: surfaces stay non-empty and not collapsed to one output, over
  more than one corpus cycle.
- P5a recall precision@k: recorded as not_covered (needs a held-out probe set).

report.py assembles the panel into a structured report with a hardware-stable
deterministic_digest (trace_hash sequence + verdicts; excludes RSS/wall-clock)
as the freeze handle. Run: python -m evals.l10_continuity [n_turns] [reboot_turn].

24 tests pass; adversarially reviewed across 4 lenses (bite-discipline,
invariant/trust-boundary, honesty/determinism, correctness) before landing.
2026-06-05 11:14:17 -07:00
Shay
b1f35b1d6c
Merge pull request #565 from AssetOverflow/feat/l10-stream-forbidden-site-cleanup 2026-06-05 09:14:41 -07:00
Shay
8c394b8818 refactor(generate): remove redundant forbidden-site _close_final_state; rename "Drift fix 2"
generate/stream.py is a CLAUDE.md-forbidden normalization site, yet _close_final_state
re-closed the walk's final state with unitize_versor. The walk is built entirely from
versor_apply / Spin-manifold rotors (persona voicing, recall transitions, propagate_step),
so versor_condition < 1e-6 holds on the output BY CONSTRUCTION — the final unitize was a
true no-op (measured: final_state versor_condition = 2.98e-17 WITH and WITHOUT it).

- Remove _close_final_state + its unitize_versor import; GenerationResult.final_state=current.
- Reframe the "Drift fix 2" comment -> "recall-confidence weighting" (a selection policy,
  not normalization; mislabeled per the L10 Decision 0 bright line).
- Test-first: add test_generated_final_state_satisfies_versor_condition_by_construction
  (exercises voicing + seeded-vault recall); green before AND after removal.

Brings stream.py into forbidden-sites compliance.
2026-06-05 08:17:17 -07:00
Shay
54707f53a0
Merge pull request #564 from AssetOverflow/feat/l10-anchoring-doctrine
L10 Decision 0: sanction session semantic anchoring (CLAUDE.md) + rename anchor pull
2026-06-05 08:08:39 -07:00
Shay
81ea72482f refactor(field): rule the session anchoring family as sanctioned semantic anchoring (L10 Decision 0)
L10 scoping Decision 0 ruled the session/context.py "drift fix" family as
sanctioned SEMANTIC anchoring, not forbidden drift-repair:
- closure (versor_condition<1e-6) is owned by the sanctioned algebra/versor.py
  sandwich closure and holds BY CONSTRUCTION (measured: 100k-step field walk,
  max versor_condition ~6e-13, flat, with AND without the anchor pull);
- the family preserves the invariant by construction (rotor_power /
  word_transition_rotor / versor_apply on the Spin manifold, no post-hoc
  unitize) and expresses the session concept-attractor model.

CLAUDE.md: add session/context.py semantic anchoring to sanctioned normalization
sites behind a two-clause guard, plus a bright-line paragraph (semantic anchoring
vs drift repair; closure owned solely by algebra/versor.py; no "drift fix" naming).

Rename _anchor_pull -> _session_anchor_pull; reframe the "Drift fix 1/3" /
"conjugate correction against slow angular drift" docs as semantic anchoring
(no behavior change). Update test_session_coherence.py to the new name.

Out of scope (flagged for separate review): generate/stream.py "Drift fix 2"
sits in a forbidden normalization site.

Verified: 15 targeted tests green; INV-02 normalization invariant unaffected.
2026-06-05 07:48:46 -07:00
Shay
0b19e08306 feat(engine-state): schema-version migration discipline (L10 step-2)
Versioned additive-optional migration (L10 scoping step-2 ruling): a checkpoint
schema bump is a recorded lineage transition, not death-and-rebirth.

- engine_state.load_manifest() now REFUSES (IncompatibleEngineStateError) a
  checkpoint whose schema_version > this build's _SCHEMA_VERSION, and tolerates
  <= current (older/equal read any missing newer fields via additive-optional
  defaults). Never silently mis-loads newer state.
- chat.runtime._load_engine_state() loads the manifest FIRST so the version
  refusal gates before any recognizers/candidates are read.
- DerivedRecognizer.from_json documents the additive-optional convention
  (new fields .get-defaulted + omitted-when-default), mirroring DiscoveryCandidate.

Tests (TDD): refuses newer schema_version; tolerates older. Prerequisite for the
L10 continuity spike's P2 byte-identity gate (it may now assume a fixed schema
within a run, with version bumps handled explicitly).
2026-06-05 07:48:46 -07:00
Shay
3911db66a3 test: lock ADR-0146 engine-state byte-stability + discovery store path
The ADR-0146 round-trip tests proved object-equality but not byte-stability,
and the only non-empty discovery test bypassed EngineStateStore. Mutation
testing confirmed object-equality has teeth (a dropped field is caught) while
the store's non-empty discovery round-trip, save->load->save idempotence, and
cross-instance byte-determinism were untested.

Adds 4 locking tests (mutation-verified to fail under a lossy from_dict):
- recognizers_save_load_save_is_idempotent
- recognizers_save_is_deterministic_across_instances
- discovery_store_round_trips_nonempty_candidate
- discovery_store_save_load_save_is_idempotent

Deliberately not golden-format pins: a deterministic format change is harmless
for a content hash, and pinning would make every legitimate schema bump a
death-and-rebirth event. Prerequisite for any cross-reboot EngineIdentity
content-hash (ADR-0146 / L10).
2026-06-05 07:19:20 -07:00
Shay
d47741f5df
Merge pull request #562 from AssetOverflow/feat/cga-incidence-primitives
algebra: incidence algebra — graded_wedge, dual, meet + honest outer_product
2026-06-04 21:52:20 -07:00
Shay
de645055ea feat(algebra): incidence algebra — graded_wedge, dual, meet + honest outer_product
Adds the correct grade-raising "wire" the field substrate was missing — so cga_inner
can operate on RELATIONS among entities (lines/planes/incidence), not just pairwise
point distance. Built only from existing Cl(4,1) primitives (geometric_product,
grade_project) + the pseudoscalar; no normalization, no approximation, versor_condition
path untouched (flats are null-cone wedges, not unit versors).

- outer_product: DOCSTRING-ONLY honesty fix (behavior byte-identical, every caller
  unchanged). It is the commutator 0.5*(XY-YX) = the wedge ONLY for grade-1 vectors;
  for higher grades it is the Lie bracket, NOT the wedge, and does NOT build a k-blade
  by repetition. Existing callers consume it as an opaque cga_inner-reduced feature
  (none read it by grade), so the relabel is safe. Points to graded_wedge for the real
  exterior product.
- graded_wedge(X,Y) = <XY>_{grade(X)+grade(Y)} — the true wedge; agrees with
  outer_product on grade-1, differs above (pinned by test). Builds lines/planes.
- is_incident(point, flat): EXACT zero-test (point^flat == 0, no float tolerance to
  admit — near-incident is refused, per wrong=0). Exact at scale in f64.
- dual(X) = X*I5^{-1} (I5^2=-1 confirmed); involutive up to sign.
- meet(A,B) = dual(dual(A)^dual(B)): correct for spanning operands (two planes -> their
  line, incidence verified). HONEST ENVELOPE: degenerates for non-spanning operands
  (coplanar lines) — returns the ZERO multivector (detectable, documented, tested),
  never a silent wrong value. The general coplanar intersection needs the join-relative
  meet, deliberately NOT faked here.

Green: smoke 87, algebra 82, incidence 8, outer_product consumers + invariants 109;
zero regressions (outer_product behavior unchanged).
2026-06-04 21:43:35 -07:00
Shay
5f274b75b7 feat(deductive): binary relations + multi-variable grounding (finite propositional)
Extends evals/deductive_logic/grounding.py from unary predicates / single-var rules to
binary relations + multi-variable universal rules, still by FINITE PROPOSITIONAL
grounding into the regime the ROBDD engine + the independent truth-table oracle both
decide. wrong==0 stays structural. This is the real capability step a RuleTaker/
ProofWriter-style mirror needs (the unary fragment alone is trivial).

- atom_n lowers pred(a,b) -> pred__a__b; arity-1 is byte-identical to the old atom, so
  the live unary panel lowers unchanged (proven by an exact-string back-compat test).
- multi-variable universal rules ground over n^k assignments — transitivity now decides.
- range-restriction: a rule with a head variable unbound in the body refuses (unsafe_rule)
  — it grounds soundly but is outside the clean regime real benchmarks use.
- typed refusals: arity>=3/functions, explicit quantifiers, variable-free rules, bounds.

Honest ceilings (documented in docs/analysis/relational-grounding-extension-2026-06-04.md):
- THE binding constraint is the GOLD, not the grammar: the truth-table oracle is
  O(2^atoms), so grounding refuses above MAX_GROUND_ATOMS=20 => binary problems cap at
  ~4 entities/predicate. A real lift needs a 2nd genuinely-independent sub-enumeration
  oracle (not built).
- OPEN-WORLD only: RuleTaker/ProofWriter's main splits are closed-world + NAF; a future
  adapter MUST refuse CWA/NAF (mapping CWA "False"->"refuted" is a wrong=0 breach).
- arity <= 2, function-free.

Validated: held-out differential fuzz (400 random binary problems, oracle-golded) = 0
engine/oracle mismatches; unary back-compat byte-identical; INV-25b reproducibility green;
deductive lane wrong=0 16/16; smoke 87.
2026-06-04 20:17:33 -07:00
Shay
5c77c9eece feat(field-wedge): ablation verdict — field is decoration on additive (C3) (Phase W.2)
The falsifiable experiment's measurements #2 (ablation) and #3 (diversity). Builds the
competent, code-disjoint SYMBOLIC reader (the control arm AND the C3 capability path)
and the ablation instrument that runs both readers through the real
verify_tier2_agreement gate.

VERDICT: C3 — the field is decoration on this domain (a sanctioned, honest negative):
- field_wrong_commits = []  (wrong=0 holds; the per-step drift guard refuses bad ints)
- field_caught_symbolic_errors = []  (the field caught ZERO symbolic errors)
- per-class diversity = 0 everywhere (both readers agree and are both correct)
- the only admitted-set change is the field LOSING coverage at the precision ceiling.

Insight: on forward-substitutable relations, geometric translation IS arithmetic
addition, so there is no metric over-determination for the field to exploit — field and
symbol are common-mode (Knight-Leveson), not a genuine second derivation. This is the
deductive finding's twin: logic was combinatorial (field can't earn it), additive is
arithmetically trivial (field adds nothing). The field needs metric-nontrivial AND
arithmetically-hard structure to earn a reasoning role — dedicated research, not
near-term. Field-as-reasoner is NOT earned; no field vote enters any serving path; the
field stays a servant. Capability path = symbolic (C3), not shipped here.

- generate/relational_symbolic_reader.py: competent independent reader (pure int).
- evals/relational_metric/ablation.py: the reusable decoration instrument.
- docs/analysis/field-wedge-ablation-result-2026-06-04.md: the recorded verdict.

All prior artifacts STAY (field reader = real wrong=0 read demo + 3rd panel domain).
Green: full wedge suite 104; 53 architectural invariants.
2026-06-04 19:44:22 -07:00
Shay
145d797196 feat(field-wedge): geometric field reader — relational-metric lane wrong=0 (Phase W.1)
Measurement #1 of the field-reasoner falsifiable experiment: does the CL(4,1) field,
given an honest metric encoding, read forward-substitutable quantitative-relational
problems from TEXT with wrong==0? It does — 14/15 correct, 0 wrong, 1 refused
(precision ceiling), scored against an independent arithmetic oracle.

- generate/relational_field_reader.py: reads problem text into conformal points on
  the e1 number line; additive/part-whole relations are conformal TRANSLATOR versors
  (versor_apply(T_delta, embed[x]) == embed[x+delta], exact); the answer reads back
  by projective dehomogenization. Refusal-first: fences multiplicative/ratio (the
  sign/orientation-blind cases), the precision ceiling, non-forward-substitutable
  references, negatives. A per-step exactness self-check turns any f64 translator
  drift into a refusal (precision_drift) — it NEVER commits a wrong integer. Its
  parser is an independent reimplementation importing no generate.derivation/math_*.
- evals/relational_metric/: independent arithmetic oracle (computes gold from the
  STRUCTURE, shares no code with the reader), 15-case fixture, and a runner that
  enforces gold integrity + wrong==0.
- INV-25: relational_metric registered in INDEPENDENT_GOLD_LANES (oracle proven
  code-disjoint from the field reader and the algebra engine). The independently
  golded panel is now three domains: deductive, dimensional, relational-metric.

Green: smoke 87, 53 architectural invariants, 16 new tests; deductive + dimensional
lanes unperturbed (wrong=0).
2026-06-04 19:34:43 -07:00
Shay
568face63e feat(reasoning): field-wedge foundation — f64 embedding, lineage firewall, INV-27
Phase 0 of the field-reasoner wedge — net hardening regardless of the
experiment's outcome.

- algebra/cga.py: embed_point gains a dtype kwarg (f32 default byte-unchanged;
  cl41.geometric_product already preserves f64) + read_scalar_e1 projective
  dehomogenization read-back (weight-invariant; correct for dilations, where a
  raw distance-from-origin is wrong) + EMBED_EXACT_MAX pinned magnitude ceiling.
  f32 silently collapsed integer coordinates past ~1e4.
- core/reasoning/evidence.py: verify_tier2_agreement now keys independence on a
  reader_lineage pathway token (refuses SAME_READER_LINEAGE), replacing the
  label-only len(set(signatures))<2 check a single reader could satisfy by
  relabeling. reader_lineage is excluded from canonical serialization, so the
  entailment trace_hash is unchanged.
- tests INV-27: transitive reader-disjointness over TIER2_READER_PATHWAYS makes
  the lineage check load-bearing (distinct lineage => proven import-disjoint
  pathway). The two seeded readers share zero transitive first-party modules.

Green: smoke 87, algebra 82, cognition 121, 53 architectural invariants,
reasoning/deductive/r1 50; 16 new f64-exactness tests; zero regressions.
2026-06-04 19:22:16 -07:00
Shay
4c6290f773
Merge pull request #557 from AssetOverflow/feat/dimensional-reasoning-domain
Dimensional-reasoning lane — 3rd diversity-panel domain
2026-06-04 16:48:55 -07:00
Shay
96c1d4bcee feat: dimensional-reasoning lane — 3rd diversity-panel domain
The first non-GSM8K consumer of the binding-graph interlingua's unit algebra as a
load-bearing reasoner: given two units and an operation, decide the result's
dimension. SUT = generate.binding_graph.units; gold = evals/dimensional/oracle.py,
a genuinely INDEPENDENT dimensional reasoner (own unit->base-exponent table, own
exponent arithmetic, own canonical-string renderer; shares no code with the SUT).

12 cases (area / speed / wage / mass-density / dimensionless / 2 refused) gated by
SUT == oracle == gold (wrong=0). Registered in INV-25's INDEPENDENT_GOLD_LANES,
proving the independent-gold discipline generalizes to a SECOND oracle.

This is the 3rd structurally-distinct golded domain (logic / grounding / dimensional)
— the anti-overfit >=2-domain panel is now real, and the interlingua is load-bearing
beyond GSM8K.
2026-06-04 16:38:56 -07:00
Shay
3e2a52870d feat: Phase 2 — finite-entity grounding compiler + Phase 1.5 finding
The first comprehension->structure compiler: evals/deductive_logic/grounding.py
lowers a typed finite-entity problem (finite entities + unary predicates +
single-variable universal rules) into the propositional regime the ADR-0206
entailment operator decides, refusal-first with a closed typed reason vocabulary
(unsafe_symbol / unknown_entity / unsupported_predicate_arity / unsupported_
quantifier / malformed_case / empty_case) and collision-safe atom slugging.

finite_entity/v1/cases.jsonl: 8 cases with INDEPENDENT (oracle-derived) gold
(4 entailed, 2 unknown, 1 refuted, 1 refused) — chained rules, conjunctive
bodies, negative heads, inconsistent premises. 20 tests gate engine==oracle==gold.

This is the second diversity-panel domain (distinct comprehension, same checkable
substrate) — the universal-structure thesis validated on a different problem shape,
with the anti-overfit >=2-domain discipline now live.

Phase 1.5 finding recorded: a clean geometric/algebraic propositional decoder
agrees 716/716 with the oracle but is O(2^n) (enumeration-class), so logic is the
wrong first domain for field-as-reasoner; the wedge redirects to quantitative-
relational structure where the field is the natural non-redundant decoder.
2026-06-04 16:32:03 -07:00
Shay
8d620d6257 feat: Phase 1 — canonize binding-graph interlingua + INV-26 neutrality
Declares SemanticSymbolicBindingGraph the universal problem-structure interlingua
(the corpus callosum where the geometric field and symbolic ROBDD decodings meet
and must agree). INV-26 enforces that neutrality structurally: 26a no binding-graph
module imports field/algebra/eval/vault/chat/core/sensorium; 26b the core imports
no domain reader (only allowlisted bridges adapter/question_target may); 26c proven
non-vacuous (flags pipeline.py's field import + the adapter's domain import).

Amends the plan doc with the structurally-diverse checkable panel (logic/grounding/
dimensional/execution/constraint, each with independent gold) and the 'a capability
change must move >=2 structurally-distinct domains or it is suspected overfitting'
rule, woven in from Phase 2 — the anti-overfit instrument the train_sample breach
proved we need.

Validated: architectural invariants 49 + binding_graph model = 118 passed.
2026-06-04 16:20:12 -07:00
Shay
a447dce5d1 feat: ratify independent-gold invariant (INV-25) + SHA-pin deductive lane
INV-25 makes the GSM8K lesson structural: no capability claim is valid unless
its gold is computed by a procedure sharing no code with the system under test.
Three meaningfully-failing checks (proven able to fail): 25a oracle imports no
SUT module (AST); 25b every committed deductive gold is reproduced by the
independent oracle AND matched by the engine; 25c an unsound engine disagrees
on committed cases.

SHA-pin the deductive lane (deductive_logic_v1, dev+holdout+external 716/716,
wrong=0, refused=0) via a deterministic --report writer + run_as_module (the
lane dir's local generate.py shadows the package in script mode) + CLAIMS regen.

Fix drift the review surfaced: contract.md + pivot doc claimed an 8,000/7,340
fuzz and an 'external mirror' -> corrected to the real gated 3,000-case fuzz
(2,796 definite) and 'hand-authored, NOT a published-benchmark mirror'; pivot
doc GSM8K holdout 0->5 (all 5 are R1 reconstruction; composer scored 0).

Validated: smoke 78, deductive 23, proof 29, invariants 44, lane-sha+claims 9.
2026-06-04 15:56:28 -07:00
Shay
134a91c48a feat: add tier2 reasoning evidence spine 2026-06-04 14:12:18 -07:00
Shay
7155f5ab34 feat: add gsm8k r1 reconstruction 2026-06-04 13:25:11 -07:00
Shay
3389cc68c3 feat: add deductive proof evidence gates 2026-06-04 08:37:51 -07:00
Shay
48827f281a feat: sound+complete propositional entailment operator + deductive-logic lane
The first SIZEABLE, honestly-verified reasoning capability — built on CORE's
own terrain (exact, verifiable, deterministic), not GSM8K's stochastic terrain.

THE OPERATOR (generate/proof_chain/entail.py, ADR-0206):
- evaluate_entailment(premises, query) -> entailed | refuted | unknown | refused.
- The multi-hop inference operator evals/symbolic_logic/gaps.md said did not exist
  ("no operator that takes A->B, B->C and returns A->C") and ADR-0205 deferred.
- Built on the ADR-0201 ROBDD canonicalizer: premises |= Q iff (AND P) -> Q is a
  tautology. SOUND AND COMPLETE for propositional logic, not single-step.
- wrong=0 is structural: an exact tautology check refuses (LogicError) on
  malformed / out-of-decidable-regime (quantified/predicate) input, never guesses.

THE HONEST METRIC (evals/deductive_logic/):
- holdout v1 (500 cases): 500 correct / 0 WRONG, incl. 227 non-trivial deductions
  (117 entailed + 110 refuted). dev (200): 200/0.
- Gold from an INDEPENDENT truth-table oracle (oracle.py) sharing zero code with
  the engine. 8,000-case fuzz across two independent decision procedures:
  0 disagreements. This is the soundness evidence the GSM8K composer could never
  produce (it could not separate its 2 right from its 87 wrong answers).
- contract.md states the load-bearing honesty boundary: PROPOSITIONAL ONLY, and
  given-formulas (NL->logic grounding is a separate later layer, kept out of scope
  so we do not re-step on the GSM8K natural-language rake).

TESTS (17, all green): classic inference shapes (MP, multi-hop chain, modus
tollens, disjunctive/hypothetical syllogism, conjunctive rules, genuine unknown),
refusal boundary (inconsistent / quantified / predicate / malformed), and a
deterministic engine-vs-oracle fuzz cross-check.

Pure new module — does NOT touch serving. Smoke 73 passed; invariants 40 passed.
2026-06-04 07:47:01 -07:00
Shay
d81084ffe3 feat(eval): held-out dev lane — the honest iteration metric (real capability = 0)
The 2026-06-04 sealed-breach post-mortem proved the 50-case train_sample has ZERO
predictive validity (its 4 "correct" are overfit; they hid a 5-wrong sealed breach).
This adds the instrument we never had: 500 real GSM8K cases CORE was NOT built on —
the train split minus the 50 train_sample, deterministic sha256(question) sort.

Same scorer as train_sample + the sealed lane, so the three are directly comparable:
  train_sample(50): 4/0/46   holdout_dev(500): 0/0/500   sealed test(1319): 0/0/1319

Real GSM8K capability is 0%. The 4 train "correct" generalize to NOT ONE of 500
held-out cases. wrong=0 holds (refuses, never confabulates).

- evals/gsm8k_math/holdout_dev/v1/: cases.jsonl (500), runner, report (0/0/500), README.
- tests/test_holdout_dev_lane.py: floor (wrong==0, forever) + baseline snapshot (0/500).

Discipline: iterate here (open, large enough to resist trivial overfit); the sealed
test stays the final arbiter. wrong=0 is the floor; correct rising is the goal;
"refuse everything" is the FAILING baseline to beat, not a pass. Non-serving (eval only).
2026-06-04 02:30:42 -07:00
Shay
763c46d2f4 fix(gsm8k): disable unsound serving bridges — restore sealed wrong=0 (0/5 -> 0/0)
The FIRST real sealed measurement (operator-decrypted 1,319 held-out GSM8K)
found `0 correct / 5 WRONG` — a wrong=0 breach hidden for weeks because the
working metric was the 50-case train sample the bridges were tuned to. Bisection
isolated it to the product_bridge serving promotion (ADR-0195).

- generate/math_candidate_graph.py: REMOVE both serving promotion bridges
  (product_bridge + goal_residual/ADR-0207 §5 step 2). Serving = main-graph-only.
  Restores sealed 0/0/1319 (verified by bisect: disabling product_bridge -> 0 wrong).
  Production modules remain in generate/derivation/; only serving promotion is
  unwired, until a gate is proven wrong=0 on the SEALED set (never the train sample).
- Honest numbers everywhere: train_sample 7/43/0 -> 4/46/0 (the bridges' "correct"
  was train-overfit). report.json + coverage probe regenerated. 7 ADR test lanes
  de-pinned from the inflated count. corpus: cv-0005 (R4) reverts to refuse; cv-0020
  (a "baseline control" that solved ONLY via product_bridge) reclassified.
- docs/claims_ledger.md: dated wrong=0-breach-and-remediation note + the rule:
  the train_sample number had ZERO predictive validity for the exam; never the score.
- docs/analysis/gsm8k-lift-program-strategy: the program to actually move the 1,319.

NOTE the exit gate stays `correct>=10 AND wrong==0` — refusing-everything is an
explicit FAIL, not a wrong=0 pass; serving still commits (main graph). Verified:
broad regression 848 passed, smoke 73 passed.
2026-06-04 01:55:05 -07:00
Shay
7160e5e77f
Merge pull request #544 from AssetOverflow/feat/r4-goal-residual
feat(r4): cv-0005 goal-residual to serving — train_sample 6/44/0 → 7/43/0 (ADR-0207 §5 step 2)
2026-06-03 22:29:21 -07:00
Shay
ad9cf57069 feat(r4): flip cv-0005 to serving — train_sample 6/44/0 -> 7/43/0 (ADR-0207 §5 step 2)
Wires the R4 goal-residual production to serving via
resolve_promotable_goal_residual (math_candidate_graph.py, mirroring
product_bridge). cv-0005 / train_sample 0037 now solves on serving as
goal - Σprogress = 10 - 3 - 4 = 3. First Phase-5b composition lift on serving.

wrong=0 preserved on every runnable surface:
- train_sample 6/44/0 -> 7/43/0 (0037 added; 6 prior correct intact; wrong=0).
- Fires on 2/455 visible GSM8K cases, both correct, ZERO wrong.
- Gain-goal divergence firewall proves it reads the GOAL, not a possession.
- smoke 73, math+invariants 53, derivation/pool/practice 341, corpus, all green.

Lockstep updates (the ratified metric move, 6/44/0 -> 7/43/0):
- report.json; 7 ADR test lanes that pinned 6/44/0; corpus cv-0005 baseline
  fields + snapshot (4/18 -> 5/17) + contract; plan-doc cv-0018 control fix.

⚠ SEALED MEASUREMENT REQUIRED — NOT DONE. The sealed 1,319 (encrypted, not
CI-reproducible) is the real bar (ADR-0207 §6) and was NOT re-measured. The
operator/CI must decrypt+run it and confirm sealed wrong==0; if wrong>0, revert
the resolve_promotable_goal_residual block (isolated). See
docs/handoff/sealed-measurement-obligation-2026-06-04.md.
2026-06-03 22:20:12 -07:00
Shay
b4fb9df8e7 feat(sensorium): fail-closed efferent gate for actuating decode (ADR-0198 §3)
DefaultEfferentGate is a capability/shape pre-filter only; it does not
lower decoded actions into safety/ethics pack verdicts (ADR-0198 §3 /
§1.2 Gap B). ModalityRegistry.decode/decode_batch now refuse fail-closed
any emission through a gate whose enforces_action_verdicts is False,
unless an explicit allow_unverified_efferent sandbox opt-in is set.

A real motor decoder thus cannot emit through the capability-only gate;
the §3 verdict-lowering gate must be built and installed first. No
production caller of the decode path exists today, so this closes the
latent hazard before a motor decoder makes it load-bearing. Adds two
falsifiable tests (fail-closed refusal; verdict-enforcing gate allowed).
Disjoint from the GSM8K serving path.
2026-06-03 22:03:35 -07:00
Shay
94d8137ad1 feat(r4): goal-residual production — ADR-0207 §5 step 2 (sealed lane)
First composition lift-target built end-to-end: cv-0005 (train_sample 0037)
now resolves in the sealed pool as goal - Σprogress = 10 - 3 - 4 = 3.

- generate/derivation/goal_residual.py: new R4 production. Reads a GOAL anchor
  (goal-intent lexeme) + a residual question, subtracts each same-referent
  progress quantity (progress reduces the residual regardless of world-polarity).
  Gated by the unchanged self-verification gate.
- wrong=0 firewall (test_reads_goal_not_possession): on a gain goal the
  goal-residual (20-5-6=9) DIVERGES from possession-accumulation (20+5+6=31);
  the production gives 9 and is all-subtract -> it reads the goal, not the
  possession. This is the coincidental-correctness trap cv-0005 alone hides
  (10-3-4 == 10-(3+4)).
- pool.py: goal_residual added to pooled_candidates (sealed). Verified: fires on
  exactly one train_sample case (0037, correct), zero new pool wrong-commits
  (the 8 are pre-existing, gated off serving by product_bridge).

Does NOT move the serving metric: train_sample stays 6/44/0 byte-identical
(serving = candidate-graph; product_bridge promotes only pure products, never a
subtract chain). The serving promotion gate for goal-residual is the next,
separately-gated step (needs the sealed 1,319 verdict). Smoke 73, math 4,
derivation/pool/practice 196, corpus, completeness-guard all green.
2026-06-03 21:50:59 -07:00
Shay
9cabeeb40d Add sensorium eval and governance runway 2026-06-03 20:53:05 -07:00
Shay
d9fc7f9e56
Merge pull request #540 from AssetOverflow/codex/vision-eval-environment-sensorimotor
[codex] Add vision evidence and sensorimotor contracts
2026-06-03 20:41:10 -07:00
Shay
2d2b096784 Add vision evidence and sensorimotor contracts 2026-06-03 20:27:46 -07:00
Shay
d0d305f86a
Merge pull request #538 from AssetOverflow/master-workbench-state-implementation
feat: CORE Workbench W3 Ratification Corridor
2026-06-03 20:26:26 -07:00
Shay
6d1f6bba0c feat: implement CORE Workbench W3 Ratification Corridor 2026-06-03 20:13:36 -07:00
Shay
fc01be715c
Merge pull request #537 from AssetOverflow/codex/sensorium-compiler-vision
[codex] Add sensorium compiler law and tile vision
2026-06-03 20:09:31 -07:00
Shay
282679bd85 Add sensorium compiler law and tile vision 2026-06-03 19:58:36 -07:00
Shay
94bf1be1bc docs: ratify ADR-0207 — GSM8K comprehension/composition substrate
Consolidating ratification of the GSM8K design of record. Ratify the built
comprehension/derivation substrate, freeze the serving regex recognizer/
injector path to lexemes + refusal-only, pin Phase 5b execution to
WIRING -> COMPOSITION -> LEXICON.

- ADR-0207: new consolidating decision (Accepted, ratified 2026-06-03).
  Supersedes ADR-0163 §Phase B-E + ADR-0136 regex sentence-template
  prescriptions. Freeze + wrong=0 gates (22-case corpus + sealed 1,319).
- ADR-0164/0165/0174/0178/0179: -> Accepted (ratified by ADR-0207,
  2026-06-03). 0164 keeps its implementation clause (Phase 1+2 shipped;
  remainder per §5) so Accepted != fully built.
- composition_validation/v1: 20 -> 22 cases (2nd R4/R5 positives,
  dataset-sourced golds), +contract invariants 6-7, +dataset-gold test.
  Baseline 4/18/0; 47 passed.
- docs/analysis: extraction-richness audit (read-only) reconciling
  ADR-0179 to the tree (EX-1/2/4/5/6 landed; EX-3 deferred).

Non-serving (evals/docs/tests only). train_sample 6/44/0 unchanged;
no-ref <N> times hazard stays refused. GB3b/0136 untouched.
2026-06-03 19:42:47 -07:00
Shay
c89adc6547 test(gsm8k): executable invariants for composition validation corpus
The composition_validation/v1 corpus shipped as data + a prose contract
with no executing test -- decoration until a test can fail (CLAUDE.md,
Schema-Defined Proof Obligations). Add the load-bearing gate:

- forever-invariants: wrong=0 firewall (admit => ==gold; null-gold =>
  refuse), baseline-control regression net, permanent-refusal permanence,
  and frozen baseline-field/tree match for the non-positive rows.
- current snapshot: aggregate 4 solve / 16 refuse / 0 wrong -- the single
  assertion a Phase 5b slice updates when it flips a positive.

Future positives (5b-* gates) are checked by the firewall only, so a
refuse->solve flip at 5b stays green without rewriting frozen rows.

Verified: 44 passed; falsified (corrupting a control's gold fails the
firewall + control + snapshot tests); completeness guard still 21 passed.
2026-06-03 18:40:37 -07:00
Shay
e1bcdf6286 Harden no-reference n-times comparative guard 2026-06-03 15:22:42 -07:00
Shay
d5872a2e96 feat(adr-0206): response-governance bridge scaffold (STRICT-only, inert)
Adds the first consumer of CORE's two built epistemic substrates — the
decode-state taxonomy (core/epistemic_state.py) and the risk-reward
reliability gate (core/reliability_gate/, ADR-0175) — beginning to close
the LABEL-ONLY consumption gap they sat behind.

Ships the scaffold only:
- core/response_governance/policy.py — ReachLevel (STRICT < APPROXIMATE <
  EXTRAPOLATE < CREATIVE), ReachPolicy, govern_response (STRICT-only stub),
  shape_surface (STRICT = identity transform; higher levels real but
  unreachable in production), and the 9/5/1 EpistemicState partition.
- chat/runtime.py — cognition-path seam: the response surface now flows
  through shape_surface(govern_response(...)). STRICT = identity, so the
  path is byte-identical to pre-bridge. reach_level carried on ChatResponse.
- core/physics/identity.py — reach_level on TurnEvent (default "strict").

wrong==0 untouched: select_self_verified is NOT touched (ADR-0206 §5);
reach_level is NOT added to the telemetry JSONL dict, so pinned lane SHAs
stay byte-identical. Widening, SITUATE/FEED-BACK, the math-serving seam,
and the EVIDENCED reconcile are deferred to their own PRs.

Tests (tests/test_response_governance.py): STRICT-only contract over all
states x license x stakes, STRICT identity, live-wiring proof (forces
APPROXIMATE -> policy-sensitive surface), total+disjoint taxonomy
partition. Each fails loudly under the violation it guards.
2026-06-03 10:39:12 -07:00
Shay
4c095c3621
Merge pull request #529 from AssetOverflow/codex/mp-corpus-fixture
[codex] Add modus ponens oracle corpus
2026-06-03 09:32:57 -07:00
Shay
010e713d1b test(adr-0167): decouple self-teaching e2e from the evolving train_sample reader
The thesis demo ratified the unknown word 'sees' in train_sample case 0040 and
asserted the refusal moved. The reader has since advanced past that barrier —
case 0040 now first-refuses at quantity_extraction@s0 and never reaches 'sees',
and no train_sample case cleanly first-refuses at an unknown word anymore. So
the fixture was stale, not the machinery (which is unit-tested in
test_math_lexical_ratification.py + 9 others).

Repoint to a reader-stable synthetic statement ('Sam zorps 5 apples and
quibbles 3 oranges...'): 'zorps' first-refuses at lexicon_entry, gets ratified
as a drain_token and resolves, and the second unknown verb 'quibbles' keeps the
statement refused (wrong=0). Removed the now-dead RATIFICATION_TARGET_* consts.
2026-06-03 02:11:41 -07:00
Shay
1fe57643e1 test: update to evolved contracts (propose-from-exemplars corpora; pronoun guard)
- propose-from-exemplars: --all now proposes 6 exemplar corpora (the ME-1..ME-5
  matcher waves added currency_amount, discrete_count_statement,
  multiplicative_aggregation). All pending. Updated the pinned set + renamed
  the test off 'three_corpora'.

- adr_0163_d2 pronoun: the design moved from hard-refusing a bare pronoun
  subject at extraction to admitting it tagged requires_pronoun_resolution=True,
  with the candidate-graph (math_candidate_graph.py:704/723) refusing to commit
  unless it resolves. Verified end-to-end: 'He has 5 apples. How many...' still
  returns answer=None. Pin the defensive flag (its absence re-opens the ADR-0174
  wrong=0 hazard) instead of the obsolete None return.
2026-06-03 02:02:58 -07:00
Shay
6ea52f8af0 test(adr-0157): patch get_git_revision (the seam load_manifest actually calls)
A refactor split the revision helper into public get_git_revision() with
_git_revision() as a backward-compat alias, and pointed load_manifest() at
get_git_revision(). The revision-mismatch tests still patched _git_revision,
so the patch was a no-op and load_manifest read the real HEAD SHA — emitting
(or suppressing) warnings against the wrong 'current' revision. Patch the
function load_manifest calls. Feature unchanged; only the test seam was stale.
(The reboot path in chat/runtime.py still uses _git_revision, tested by
test_adr_0158 — left as-is.)
2026-06-03 01:59:05 -07:00
Shay
6d62ac2f24 test(telemetry): isolate engine_state so emission-count tests are order-independent
The telemetry tests built ChatRuntime(config=RuntimeConfig()) against the
default (shared) engine_state/ store. In a full-suite run, earlier runtime
tests persist a checkpoint there, so these tests restored ambient state and
emitted an extra 'reboot' telemetry event (restored_turn_count=NNNN), breaking
the 'one line per turn' counts (assert 3 == 2). They passed alone, failed
after siblings — a classic order-dependent isolation bug, not a telemetry
regression.

Build with no_load_state=True so each test exercises clean per-turn emission.
No telemetry test asserts the reboot/restore path, so none lose coverage.
(engine_state/ data files are already gitignored per ADR-0146.)
2026-06-03 01:56:05 -07:00
Shay
0d05d3a1b3 fix(refusal-taxonomy): parse new refusal-reason format; reconcile to reader gains
build_refusal_taxonomy_cases._STATEMENT_RE only matched the old 'no admissible
candidate for ...' shape, so post-#359 'recognizer matched but produced no
injection ... (category=X)' refusals were silently dropped (44 refusals -> 12
extracted). Extend it to both shapes (same gap fixed in rescan_v4 before that
layer was retired).

The lane mirrored 50 cases from the all-refused era; the reader now admits 6,
so it covers the 44 refused. Regenerated the cases fixture + committed
report.json and updated the count pins (50 -> 44).

Removed the perverse categorized_rate >= 0.95 floor: the exact histogram is
already pinned by test_committed_report_matches_categorizer, and the rate
drifts DOWN as the reader graduates categorized refusals — it fought reader
progress. Replaced with a sanity floor.

adr_0126: the unparseable 'contemplates' input still refuses (wrong=0); only
the reason wording changed (#359). Accept either non-admission phrasing.
2026-06-03 01:49:41 -07:00
Shay
78001d6f78 chore: deprecate orphaned rescan_v4 archaeology layer
The rescan_v2/v3/v4 chain has zero runtime consumers (nothing in core/,
generate/, teaching/, chat/ imports it). v2/v3 are frozen disk-snapshot
tests; v4 alone re-ran the LIVE reader and asserted a barrier-shift count +
admission set, so it broke on every legitimate reader improvement (it was 8
of the red tests). Its only real invariant (wrong=0) is guarded directly by
the serving runner and test_runtime_wrong_zero_preserved.

No ADR doc references the v4 layer (only S2/S3-post-rescan exist). Remove the
brittle live test plus the now-orphaned generator and its two artifacts.
Keep the frozen, tested v2/v3 layer as the historical record.

Net: -8 brittle tests, removes a maintenance-only archaeology surface rather
than greening it.
2026-06-03 01:38:49 -07:00
Shay
eed293c31c test: update enumeration pins to current system state (no behavior change)
- recognizer_registry: ratified registry grew past round-1 (later ratification
  rounds); assert the Phase C three remain present (subset) rather than pinning
  exactly 3.
- brief_11b: 0021 joined the pre_frame_filler set as the verb-class auditor
  evolved; it refuses, rows[0]=pre_frame_filler, and post-skip still refuses
  (zero-lift verified). Canary 0050 untouched; wrong=0 unaffected (audit-only).
- cli_test_suites: assert the packs invocation against the live _TEST_SUITES
  definition instead of a hardcoded file list (suite grew).
2026-06-03 01:27:40 -07:00