Rank 1 on the adopted docket, and the cheapest item on it: two ratified ADRs
whose records contradicted the code, plus the ADR-0252 obligation that Track
A's ratified NO-GO created. All four land in two files because they are two
files under one authority — splitting them would have bought two reviews of
the same document.
ADR-0146 (R-12a, option A) — the daemon it rejected, shipped.
The Shape-A rejection stands AS REASONING: a background daemon does require
process-supervision infrastructure that Shape B does not. That infrastructure
was subsequently built. chat/always_on_daemon.py implements the three items
"What is NOT in Scope" excludes, each mapped to where:
- cross-process file locking -> advisory fcntl.flock(LOCK_EX|LOCK_NB) at :82,
acquired BEFORE any signal or runtime setup so a second life fails fast
- signal handling -> SIGINT/SIGTERM graceful stop at :145
- daemon synchronization -> the load-time strict-identity guard; the flag is
forced at :48 and a different-identity checkpoint is refused, so a restart
is the same life or it is nothing
Shape B remains the persistence model and the CLI default; the daemon is an
additional shape layered on it, owned by this ADR. A new ADR for a shape that
shipped six weeks earlier adds a document without adding a decision.
The stale bullet gets an INLINE pointer, not only a trailing addendum. H-8's
mechanism is that an authoritative line converts "I should check" into "I
already checked" — the reader who stops at the excluded-scope list is exactly
the reader this gap is about, and they never scroll to the end.
ADR-0252 (R-12b, option A) — the "34 organs" basis footnote.
Footnote at the first use, marking the count as underived: the reproducible
figure is 18 resolve_promotable_* organs, ALL in generate/derivation/ and none
anywhere else, with exactly 32 modules in the package as the likely origin of
"34". The diagnosis, supersession plan and §4 conformance bar are unaffected —
none depends on the count. Option B (replace every "34" with "18") rejected: it
rewrites a ratified document's prose where a note at the point of use is all
that is owed.
ADR-0252 §5 — the verdict banner. NO-GO, ratified. Criterion pre-registered at
299c92be BEFORE the run, run at 797ebad5, artifact digest b3d9d275…, with the
mechanism stated in one measured sentence: the similarity quotient that
delivers attribute-invariance is the same quotient that annihilates structural
contrast. Scope held narrow on purpose — this refutes H1 for point-position
role encodings aligned under similarity, not every Cl(4,1) representation, and
not the symbolic lane. Also records N-8 (two prior GO verdicts on unmerged
branches, both unsound) and G-21.
ADR-0252 §6 — the amendment the NO-GO forces, and the load-bearing half.
§6 retired the surface organs "until the structure-mapper proves out" and named
no replacement for the NO-GO branch. Left alone that is a live instruction that
can never fire — an authoritative-looking dead instrument, the H-9 class
exactly. Amended: the organs are RETAINED, and that is the operative state
rather than a pause in a transition; the retirement condition is re-stated as a
demonstrated replacement passing the §5 criterion, which does not exist. The
"Build (gated on §5 GO)" bullet is marked NOT AUTHORIZED with the reason.
Retiring a working organ on the strength of a hypothesis ABOUT its replacement
is backwards; the hypothesis has now been tested.
Verification — every factual claim re-derived at ca5e614e rather than copied
from the packet: 18 organs, 0 outside generate/derivation/, exactly 32 modules
(tightening the draft's "~32"); lock, signals and identity guard each cited by
line; report digest read back from the artifact file.
Three things caught before landing, recorded because this commit is about
records being wrong.
1. The date. The addendum drafted "landed 2026-06-14". This container's clone
was SHALLOW — 168 commits, roots grafted at 2026-07-19 — so git log
reported 2026-07-20, which is the shallow boundary and not a fact. Neither
figure was verifiable until the clone was deepened to 2340 commits, which
confirmed the packet: 18e25580, 2026-06-14, the same commit introducing
both the lock and the signal handling. The addendum now cites the SHA. A
date that cannot be re-derived is testimony.
2. A wrong section reference — the amendment cited §9 for a sentence in §8.
3. A misquote — "the existing reader" for "the existing 34-organ reader".
Writing a misquote into a ratified document while amending that document for
accuracy would have been this ruling's own failure mode committed inside its
own fix. Both were found by re-reading the amendment against the source it
quotes, which is standing philosophy 7.
Records closed: H-8(a), H-8(b), G-15. Track A's outstanding obligation
discharged. H-8(c)/(d) remain open on R-3 and land with PR-5.
No runtime behavior. No test changes. Two ADR files and four register/plan
files.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wcw2pnMBwyvmNyQg4uPEt4
39 KiB
The Hindrance Audit
Assessor: Fable 5 (Phase 4) · Verified at: 8927c563 (2026-07-27)
Discipline: A hindrance is something present that works against the goal — a wrong solution for its underlying problem, a responsibility lodged in the wrong owner, a trade-off tuned instead of dissolved, or a record that misleads the next reasoner. Every entry carries evidence, a fitness verdict from the schema vocabulary, a proposed better home, and its deciding authority. Per standing rule: settled rulings are constraints — an entry may flag a ratified decision only on evidence, only for ruling, never as a unilateral recommendation to reverse. This audit decides nothing.
Ranked by leverage (cognitive/structural load removed ÷ effort), per the AGENTS.md protocol — not by ease.
Amended: 2026-07-27 at ed06dd64 (Opus 5, Phase 6) · re-verified 2026-07-28 at 797ebad5 (H-12's ten-file delta re-measured and unchanged; H-8d's wording corrected on re-verification — see the entry). H-12 added (the two smoke gates have diverged). H-8 gains a fourth instance, located inside the source rather than the documents. H-1 gains a note: its exposure is already pinned. Derivations in 50-execution-plan.md §0.
Amended again: 2026-07-28 at 8f0ccfe3 (Fable 5, external-assessment triage). Two external first-principles assessments were verified against code line-by-line; two of their observations survived and are entered as H-13 and H-14, H-8 gains a fifth instance (e), and six of their proposals were examined and cleared (see the closing section). Every rejected proposal failed on evidence one file-read away from its claims — the third recurrence of the N-1 scan-artifact class.
H-1 · License evidence counted on an independence assumption replay violates
Verdict: wrong-solution (the counting basis, not the gating) · Layers: M5
Evidence: Wilson lower-bound licensing (θ_SERVE=0.99, ADR-0175 lineage) assumes independent trials; a replay of the same sealed case is one trial observed again, not a new one. Measured consequence recorded in the prior arc: 21 of 25 ratified bands fall short of their floor when replays are deduplicated.
Why it hinders: the entire earned-license architecture — CORE's mechanism for deserving to serve — rests on the evidence count. An overstated count grants licenses the evidence doesn't support, which is precisely the failure the mechanism exists to prevent. The gate is right; the arithmetic feeding it is not.
Better home: distinct-evidence counting at the seal boundary (count distinct cases; a replay refreshes, never increments), declared in the ledger schema the way ADR-0263 Rule 5 declares absence policy — in the table, not the call site.
Note (Phase 6): the exposure is already pinned in-repo. tests/test_volume_honesty.py (ADR-0264 R9, in the local smoke gate) pins "21 of 25 bands do not clear θ_SERVE on distinct evidence" in both directions, measured 2026-07-25 at 6ada6f7a with every band at 720 committed decisions, and its own comment calls the inventory "an EXPOSURE INVENTORY, not an approved baseline." The audit source is docs/research/distinct-evidence-audit-2026-07-25.md. The open work is therefore applying the shortfall, not discovering it — and that pin moves in the same PR.
Authority: ADR amendment (0175/0263 lineage) + a re-count of the 25 bands, authorized by R-13. The re-count may demote licenses; that is the mechanism working.
H-2 · Decoration in the runtime constructor — objects built and never read
Verdict: decoration (fails the sabotage test) · Layers: M6/M3
Evidence: DriveGradientMap constructed at chat/runtime.py:716, read nowhere. InhibitionMask/InhibitionOperator exported by core/physics/__init__.py, constructed on no path. Deleting either changes no output.
Why it hinders: dead structure is not neutral — it is testimony. Both objects tell every reader that drive mapping and inhibition masking are live, and Phase 1 of this very assessment initially believed them. Decoration is how architecture lies without anyone lying.
Better home: deletion (mastery algorithm step 2: the best part is no part), with their intents preserved where they belong — drive in the CR-2 design (G-4), the mask's disposition in the CR-1 ADR (G-14). If a future mechanism needs them, re-adding a deleted class is cheap; un-believing a phantom is not.
Authority: mechanical PR + one line each in the CR-1/CR-2 decisions.
H-3 · The typed refusal is constructed, then discarded at the public boundary
Verdict: strained — truth built and unserved · Layers: M4
Evidence: InnerLoopExhaustion carries reason, region, and per-step rejected-attempt evidence; respond()/arespond() convert it to "" for the str contract, so a refusing turn serves the empty string with refusal_reason == "". The plumbing to materialise (CognitiveTurnResult.refusal_reason, compute_trace_hash fold) already landed; runtime_contracts.md names it a residual awaiting a future ADR.
Why it hinders: the honesty machinery is the product. A system whose refusals are richer than its answers, serving its refusals as nothing, undersells its own thesis on every hard turn.
Better home: materialise into ChatResponse.refusal_reason (and a minimal honest surface), per the contract's own anticipation.
Authority: small ADR — the chain already reserved the seam.
H-4 · Composer-arm precedence is ordered branches above a declarative resolver
Verdict: strained — a solved pattern not yet extended · Layers: M4
Evidence: core/cognition/surface_resolution.py (494 lines) resolves the pipeline seam by declared precedence, self-documenting, with an in-code falsifiable contract for its own regression. Upstream, the composer arms (deduction :1834, curriculum :1850, pack/narrative/example/relation :1871–:1936, determination, estimate, gate, hedge) remain ordered branches across chat/runtime.py, in a different package with a different owner — nothing structurally prevents arm N+1 from bypassing the resolver's disciplines.
Why it hinders: prospectively — each new serving capability adds an arm ahead of any declared order. With only deduction ON, the live complexity is modest; the time to dissolve the pattern is before the next three arms, not after.
Better home: extend the resolver's declared-precedence pattern upstream to arm selection — the Third Door here is half-built and proven to fit this codebase.
Authority: refactor ADR; low-risk while one arm is live.
H-5 · Underived constants at the semantic center of generation
Verdict: strained — Pillar I violation with an in-repo counterexample · Layers: M3/CR-1
Evidence: salience_top_k=16, inhibition_threshold=0.3 gate every token walk's candidate set; no recorded derivation exists for either. The contrast is instructive and in-repo: admissibility_margin δ=0.4 was derived from the minimum observed margin of a characterization corpus (0.456), declared falsifiable, and survived a 20-case stratified attempt — the standard exists two config lines away.
Why it hinders: "thresholds tuned for good-enough" at the exact point where the system decides what it may consider. Also the self-narrowing budget feedback (stream.py:637) — a real cognitive property nobody has named or justified.
Better home: the CR-1 ADR (G-14) with an empirical derivation in the δ=0.4 style.
Authority: ADR + a small characterization run.
H-6 · The half-forced flag pair gating the lived learning loop
Verdict: misplaced responsibility — a set decision made one flag at a time · Layers: M6/M5
Evidence: F-6 (05-phase3-findings.md): the daemon forces the consolidator, not the accruer; the loop's writer and its consumer are gated independently, and only the consumer is on.
Why it hinders: flags that must be coherent as a set are owned nowhere as a set. CONTINUOUS_LIFE_CONFIG_FLAGS is the right pattern (a named, documented flag profile) applied to the wrong subset.
Better home: the flag-default register (G-8) with named profiles (one-shot / eval / continuous-life), each profile ruled as a unit.
Authority: ruling on the accrual flag + the register PR.
H-7 · The production ingest boundary lacks the trust contract its sibling has
Verdict: strained — the standard exists and stops one layer short · Layers: M2
Evidence: formation declares six boundaries — content-addressed in/out, no floats in hashed payloads, no pickle, an audit record per rejection. ingest/gate.py, facing untrusted user text in production, has the versor gate and the AGENTS.md trust-boundary defaults, but no comparable declared table.
Why it hinders: asymmetric rigor invites the assumption that the un-tabled boundary is the less important one; it is the opposite.
Better home: an M2 trust-boundary table in runtime_contracts.md, formation-style; hardening PRs only where the table exposes real deltas.
Authority: documentation first; evidence decides whether code follows.
Status (2026-07-28): CLOSED — table written, and the measurement reframes the entry. docs/specs/runtime_contracts.md §"M2 trust-boundary table" measures ingest/gate.py against all six of formation's declared boundaries at edf6c2a4. The result is not "five of six missing":
| Already met | no floats in hashed payloads (_stable_digest hashes strings only); no pickle anywhere under ingest/ |
| Category differences — closed, not owed | content-addressing, self-sealing, and the source allow-list all presuppose a persisted artifact with citations. Formation validates artifacts it will store; the gate transforms text it will not. Writing these as obligations would have manufactured three gaps and sent someone to close them |
| REAL DELTA (one) | no audit record per rejection. The gate refuses with typed exceptions and records nothing about what it refused |
The surviving delta is not a containment hole — refusal is fail-closed and nothing unvalidated crosses. It costs forensics, and it is the same failure class as H-11: a guard that works correctly and leaves no trace of having worked. It also has a downstream consumer worth naming — a widening program (G-3) must be able to ask "what shapes is the boundary refusing, and how often?", which today it cannot. Hardening is a separate PR per this entry's own authority.
H-8 · The record contradicts the code at three load-bearing points
Verdict: wrong-solution as record-keeping — divergence that reasoners inherit · Layers: governance
Evidence: (a) ADR-0146 rejects the daemon shape and places "cross-process file locking, daemon synchronization, and signal handling" out of scope; chat/always_on_daemon.py ships all three (fcntl.flock single-instance lock, SIGINT/SIGTERM, load-time identity guard) and is unowned. (b) ADR-0252's headline "34 organs" has no reproducible basis (18 resolve_promotable_* entry organs at the ratification commit and at ed06dd64; ~32 modules). (c) architecture-assessment-verification-2026-07-25.md asserts accrual "is enabled by the production L10 process"; the flag set says otherwise. (d) — added Phase 6, and it is inside the code. core/config.py's docstring for accrue_realized_knowledge states "the production L10 process enables it alongside persist_session_state", and the docstring for consolidate_determinations states the same about "accrue_realized_knowledge + persist_session_state". CONTINUOUS_LIFE_CONFIG_FLAGS (chat/always_on_daemon.py:45-49) forces persist_session_state, consolidate_determinations, strict_identity_continuity, and not accrue_realized_knowledge — so the first docstring is false outright, and the second is false in its "alongside accrue_realized_knowledge" clause. (Stated precisely on the 07-28 re-verification: an earlier draft of this entry said the flag set "contains neither claim's subject," which is wrong — it does contain consolidate_determinations. The false clause, in both docstrings, is the one naming the accrual flag as co-enabled. A third comment, on persist_session_state:283, makes the same shape of claim and is true.)
Why it hinders: demonstrated, not hypothetical — this assessment's own Phase 0 inherited a stale-record error, and the 2026-07-25 doc (itself a corrective document) introduced one. Every divergence is a future wrong analysis. Instance (d) is the sharpest: it is one layer below the documents, where a reader checking the code against the docs would stop and believe.
(e) — added 2026-07-28 (external-assessment triage), and it is inside the code again. core/cognition/inductive_closure.py's docstring rule "Cycle: if path would revisit a node, skip" (:106) describes a check the implementation does not perform — it checks a == c and known-triple membership only (:189-193), which is sufficient: the fixed point is monotone over a finite triple set, so no path-based check is needed for termination, and adding one would refuse sound transitive derivations (a witness path that revisits a node still proves a true fact). Separately, path records only (a, b, c) even for derivations whose chain is longer (:198), so the provenance serialized into operator_invocation is incomplete for multi-step derivations. The remedy splits: the docstring correction is mechanical and belongs with the amendment batch; extending path to full provenance changes operator_invocation bytes and therefore trace_hash, so it is held to the trace-change bar and must not land silently.
Better home: five amendments — ADR-0146 addendum owning the daemon (drafted in 50-rulings.md R-12a); ADR-0252 basis footnote (drafted, R-12b); a correction note on the 07-25 doc; the two docstrings corrected or the flag added, per R-3; and the inductive-closure docstring correction (e), mechanical.
Status (2026-07-28): (a) CLOSED · (b) CLOSED · (e) CORRECTED · (c)+(d) open on R-3.
(a) and (b) closed by R-12, executed 2026-07-28. ADR-0146 gained an addendum owning the daemon: the Shape-A rejection stands as reasoning, the supervision infrastructure it said would be required was subsequently built, and the "What is NOT in Scope" concurrency bullet is superseded for the daemon path only — with an inline pointer at the stale bullet itself, because H-8's mechanism is precisely that readers do not scroll to the end. ADR-0252 gained the basis footnote at the first use of "34". Every claim in both was re-verified at ca5e614e before writing rather than copied from the packet: 18 resolve_promotable_* organs, 0 outside generate/derivation/, exactly 32 modules; the daemon's lock, signals and identity guard all present with line references; the daemon's landing date confirmed as 18e25580, 2026-06-14.
Two errors caught in the amendment text before it landed, recorded because this entry is about records being wrong: the draft cited §9 for a sentence that is in §8, and misquoted it as "the existing reader" when the ADR says "the existing 34-organ reader." Both were found by re-reading the amendment against the source it quotes. Writing a misquote into a ratified document while amending it for accuracy would have been this entry's own failure, committed inside its own fix.
Also caught, and it is the reason the date is trustworthy: the container's clone was shallow (168 commits, roots grafted at 2026-07-19), so git log reported the daemon as first appearing on 2026-07-20 — the shallow boundary, not a fact. The packet's 2026-06-14 was unverifiable either way until the clone was deepened to 2340 commits. A date that cannot be re-derived is testimony; it is now evidence, and cited by SHA rather than by date alone.
(e) CORRECTED. expand_relation_closure's docstring now states that termination is structural (monotone growth over a finite triple set) and that no path-revisit check is performed and none should be — one would refuse sound transitive derivations. It also records that path is the witnessing step rather than full ancestry, and that extending it would move operator_invocation and trace_hash, so it is deliberately not done.
(c) and (d) remain open, both on R-3 (ruled A — incomplete flag set), and both land with PR-5: the 07-25 doc's correction note, and the two core/config.py docstrings corrected as accrue_realized_knowledge joins the daemon profile.
Authority: docs PRs + ruling signatures (R-12 — discharged; R-3 for the docstrings).
H-9 · Dead instruments still standing as if live
Verdict: superseded-in-place (unratified) · Layers: MV/governance
Evidence: docs/gaps.md — 26/26 closed, no entry from any 2026-06+ arc; substrate-liveness-ratchet — v5, stale since ~2026-05-24, all OPEN items L10-chained; ~130 analysis docs with no aggregator. The system map — the best macro artifact — is local, gitignored, 48 days stale, and was wrong precisely where the project moved fastest; its phantom "L12" stratum exists nowhere else.
Why it hinders: an instrument that looks authoritative converts "I should check" into "I already checked." Phase 0's error was this mechanism operating on this assessment.
Better home: this register supersedes docs/gaps.md (marked historical); the ratchet's 7 OPEN items migrate here (G-5 absorbs their L10 dependency); the map stays a regeneratable local index per D5, with "L12" dropped; the assessment directory becomes the standing ruled record, verified_at-stamped.
Authority: ruling (one PR).
Status (2026-07-28): CLOSED — R-7 ruled A; PR-3 landed. docs/gaps.md and the substrate-liveness ratchet both carry historical banners naming this entry's own mechanism as the reason. The ratchet's seven OPEN items (W-003/005/007/008/009/017/018, all L10-chained) migrated into G-5 with their dependency chains. L12 had no in-repo generator — the map is local and gitignored — so the phantom is recorded as ruled rather than deleted, which is the honest form.
H-10 · The demotion that mispriced the paradigm experiment
Verdict: strained framing — a correct ruling casting an incorrect shadow · Layers: M3/governance
Evidence: GSM8K was demoted to diagnostic (correct — the flags-and-benchmarks reasoning stands). The §5 SME experiment lives in GSM8K's neighborhood (holdout_dev/v1, math structures), so it inherited the demotion's priority — but its verdict governs the comprehension paradigm for everything, per ADR-0252's own §4 conformance bar.
Why it hinders: the highest-leverage open item in the project (G-1) has been priced as math-lane housekeeping.
Better home: none needed — G-1's execution is the fix; this entry exists so the mispricing mechanism is named and not repeated.
Status (2026-07-28): confirmed and discharged. G-1 ran to a recorded NO-GO in hours, not an arc (docs/research/sme-experiment-verdict-797ebad5.md) — which is the mispricing demonstrated rather than asserted. The entry also understated itself: the experiment had already been run twice and returned GO both times, and both results sat unmerged on rnd/ branches while the highest-leverage item in the project was recorded as unstarted. The demotion's shadow fell not only on the priority but on the retrieval of work already done.
Authority: already covered by G-1's ruling.
H-11 · A silent-failure pinhole inside a typed layer
Verdict: strained (small, cheap, principled) · Layers: M3
Evidence: _accrue_in_turn's broad guard converts any exception in the read→realize→determine chain into a no-op accrual with no telemetry (F-10). Defensible as a backstop; invisible as a signal — in the one layer whose constitution is "failures are typed, never silent" (INV-34).
Better home: count the swallow (a telemetry field on IdleTickResult/turn accrual), not a behavior change.
Authority: mechanical PR.
Status (2026-07-28): CLOSED — PR-9 landed, across all three instances.
chat/runtime.py::_accrue_in_turn—_accrual_swallows/_last_accrual_error, read viaaccrual_swallow_telemetry()._last_turn_accrualstill becomesNone, so_maybe_surface_determinationreturns byte-identically: additive by construction, and pinned as such.core/cognition/pipeline.pylogos authority —logos_erroronCognitiveTurnResult. An emptylogos_decision_kindpreviously meant either "not consulted" or "raised"; those are now distinguishable.- The OOV geometric probe —
probe_error,neighbor_scan_errors, andgraph_anti_unify_error. This block exists to price the anti-unification roadmap, and a crashed probe used to serialize identically to one that ran and found nothing.
Every guard stays deliberately broad. Narrowing them to ImportError/OSError, as an external assessment proposed, converts a malformed decision object into a turn-spine crash — trading silent failure for served-surface failure, the worse trade. What changed is visibility, not tolerance.
tests/test_accrual_swallow_telemetry.py, 7 pins, the two behavioral ones observed red against a build with the fields present but the recording removed — so they discriminate rather than merely pass. Registered in both gates on creation (#136); local/CI delta unchanged at ten (local 25, CI 15, CI-only 0).
H-12 · The two smoke gates have diverged by ten files, and one comment says they cannot
Verdict: strained — a real asymmetry, smaller than it first looks · Layers: MV
Evidence: TEST_SUITES["smoke"] is 23 files; .github/workflows/smoke.yml is 8 path patterns expanding to 13. The ten local-only files are test_audit_ledger_r7, test_cli_runner_contract, test_pack_draft_serve_boundary, test_workbench_deduction_provenance, test_prior_surface_deduction_binding, test_negation_survives_articulation, test_adr_status_governance, test_adr_index, test_volume_honesty, test_curriculum_polarity.
State the counter-evidence first. AGENTS.md §CI/CD is explicit that .github/workflows/*.yml are "secondary observability only — never a substitute for local gates": the merge gate is the in-worktree run, and the in-worktree run is the superset. Eight of the ten files carry in-code comments saying they belong "on the pre-push gate" — which is exactly where they are. Under doctrine, nothing is unguarded, and any reading of this entry as "ten pins run nowhere" is wrong.
Why it hinders, precisely: (1) two independent places assert the parity — the audio block in core/cli_test.py says it is listed explicitly "so the local-first pre-push gate (AGENTS.md protocol) equals the CI gate rather than silently narrowing it," accurate about the six audio files and false as the statement about the suite a reader will take it for; and scripts/hooks/pre-push, the automation of the AGENTS.md protocol itself, describes its own step 1 as "the smoke suite — exact CI-gate parity" while running 23 files against CI's 13. A claim made twice inside the enforcement tooling is the strongest available evidence that the drift was never intended; (2) the real exposure is the push that skipped the local gate — from a cloud session, another machine, or an agent — for which CI is the only automatic check, and for which ADR-0265's denial pin, both ADR-governance pins, volume honesty, and curriculum polarity currently run nowhere before merge. Six of these files were promoted after real silent-regression incidents (#136, #113, the 2026-07-20..24 register-axis drift), so the failure mode they exist to catch is demonstrated, not hypothetical.
Better home: the gate-parity pin in G-7 — the drift is only invisible because nothing measures it. Measured parity cost: 429 tests in 46s on the Act runner's own hardware (ubuntu-latest:host = native macOS host).
Authority: R-14 sets the direction (raise CI, or lower local, or keep them different and correct the comment); the pin itself is mechanical.
AMENDED 2026-07-28 (N-9) — "the drift was never intended" is withdrawn. It was intended, deliberated, and recorded.
A third artifact settles what two comments only suggested. tests/test_cli_test_suites.py::test_cli_smoke_suite_covers_ci_smoke_gate has enforced smoke.yml ⊆ TEST_SUITES["smoke"] all along — which is why this entry's own measurement finds CI-only = 0 — and carries a comment headed "DELIBERATELY ONE-DIRECTIONAL — do not 'complete' this by also asserting local_paths <= ci_paths." Its history is 50fa287d (2026-07-25): the bidirectional assertion was added and reverted the same day, because AGENTS.md:280 makes GitHub Actions "billing-locked … dead signals — never chase them" and §277 makes the workflows "secondary observability only."
So: the local suite is the source and is free to be broader; the ten-file delta is the designed state, not drift. What this entry got right is narrower and still true — one in-code comment (core/cli_test.py's audio block) and scripts/hooks/pre-push's "exact CI-gate parity" line both assert an equality that does not hold and should be corrected to say what the pin says.
And the real gap this entry was circling is elsewhere: the parity pin lives in the fast suite, while the pre-push gate runs smoke + deductive. The pin guarding the gate does not run on the gate. That is the mechanical fix worth making, and it is ruling-free. (Status: promoted into smoke on 2026-07-28.)
On the number itself — "ten files" is not an invariant and should stop being quoted as one. Measured at 98a6e8b4+ the delta is 12 (local 27, CI 15), because this session added three pins to the local suite. Under the corrected reading that is the design working, not drift widening: the local suite is the source and grows as pins are written; smoke.yml is observability and is edited only when convenient. The invariant is CI-only == 0, and that one is pinned. Earlier entries in this directory quote 10 (and 24/14, 25/15) as measurements true on their date; none of them is a target.
H-13 · The speculative-marker cache un-marks a sibling proposal's material on promotion
Verdict: defect — honesty regression on a served marker · Layers: M4/M5
Evidence: _speculative_subjects is a flat token OrderedDict with no owner tracking (core/cognition/pipeline.py:161). A SPECULATIVE proposal seeds its subject plus every ≥4-char non-stopword token (:726-729); on COHERENT promotion, _forget_speculative_subject pops the subject and each token regardless of which proposal added it (:736-739, :1045-1055). Promoting "practical wisdom" therefore evicts the shared token "wisdom" while an independent "wisdom" proposal is still SPECULATIVE — and that proposal's material is then served without its marker.
Why it hinders: the marker is the honesty surface for unreviewed material, and the failure direction is served-unhedged — the direction this architecture treats as the expensive one. (Provenance: surfaced by an external assessment that described this seam with the direction inverted — it claimed under-eviction; the code over-evicts. The verification that caught the inversion is what confirmed the real bug.)
Better home: a reference-counted cache (token → count of live proposals; decrement on promotion, evict at zero), with the LRU cap retained as a size valve. Failing test first: promote one proposal, assert the sibling's marker survives — red before green.
Authority: mechanical PR + red-then-green test; flag at review whether ADR cover is wanted, since served-marker behavior changes (in the honest direction).
Status (2026-07-28): FIXED — on the second attempt, and the first attempt is the more useful record.
The value of _speculative_subjects is now the set of subjects claiming each token (OrderedDict[str, set[str]]). A token is evicted exactly when the subject that actually claimed it is reviewed. Token derivation moved from the call site into _speculative_index_tokens, because ownership is precisely what the call site cannot see.
The first fix was a reference count, and it did not work. It rested on "seeding and eviction walk the same source list, so counts balance." They do not: the call site's arms are mutually exclusive — a proposal is seeded when SPECULATIVE or released when COHERENT, never both — so a release never balances a claim the same proposal made, and a COHERENT proposal always releases claims it never held. Refcounting therefore only repaired the sub-case where both proposals had been taught speculatively; the common case (an unreviewed wisdom, then a separate correction about practical wisdom that passes review on its own turn) still stripped the marker. Demonstrated after the refcount landed: sibling marked? False.
The first attempt's tests passed because their helpers split tokens themselves, testing a call pattern production no longer used — a test written to the fix instead of to the defect. The replacement helpers call the cache exactly as pipeline.py §10b does, and the lead pin (test_coherent_proposal_does_not_unmark_an_unrelated_subject) was confirmed to fail against the refcount design before the claimant design landed. 13 pins pass, 8 of them the pre-existing lifecycle pins, unchanged.
Ratification note: this changes served surfaces — markers now appear on turns where they previously vanished. The direction is toward disclosure and it restores ADR-0021 §Articulation's stated intent rather than extending it, so it is offered as a defect fix; say if you want ADR cover before it goes further.
Suite membership resolved, not deferred (G-7's mechanism, live). tests/test_speculative_subject_lifecycle.py pinned this exact behavior while sitting in no curated suite — reachable only through full — which is why the regression was invisible. It is now registered in both TEST_SUITES["smoke"] and smoke.yml, per the #136 precedent that an unregistered pin runs nowhere. Registering it in both leaves the local/CI delta at exactly ten files (verified: local 24, CI 14, CI-only 0), so it is compatible with all three R-14 options and settles none of them. PR-4 still owns the standing ten.
H-14 · The cognitive spine's turn method is 759 lines, with back-stamp repairs as the symptom
Verdict: strained — structure debt on the highest-traffic path; H-4's sibling · Layers: M3/M4
Evidence: _run_turn spans core/cognition/pipeline.py:189-947 (759 lines) under a module docstring still describing a thin delegating wrapper ("delegates to ChatRuntime internals… clean plug-in surface"). Trace-hash inputs accumulate across the whole span, and two explicit back-stamp calls exist (finalize_turn_trace_hash ×2, finalize_turn_surface ×1) because those values cannot be computed atomically where first needed.
Why it hinders: prospectively, H-4's mechanism — each landing phase is added inline, and the contributor must manually audit every prior phase for trace determinism. The back-stamps are the measured symptom, not the disease.
Better home: staged decomposition — deterministic pre-turn context → the delegated runtime.chat() call → post-turn resolution → a stateful learn stage (the teach step mutates the teaching store and the speculative cache, so a pure-tripartite framing is wrong and would mislead its own implementer). Zero-delta bar: byte-identical trace on the live lanes, PR-10's discipline.
Authority: refactor ADR, sequenced with or after PR-10 (H-4); not before Wave 2.
Explicitly examined and cleared
For symmetry with the Candidate Register's "considered and not registered" — hindrance candidates this audit rejects:
-
The 18 derivation organs — condemned but ruled to keep serving (
superseded-in-placeby explicit ruling); their continued service is governance working, not failing. The hindrance was their unreproducible count (H-8b), not their existence. -
Off-serve quarantines (holographic vault, wave modules,
topological_reasoning) — capacity that exists and cannot be used by AST-pinned design; legitimate research containment with failing-when-violated enforcement. An exit criterion would be nice (M1 card); the quarantine itself is fit. -
Pure-Python-by-default algebra — measured as the correct posture: determinism is the product,
versor_conditionis 0.22% of turn time, and the urgency argument for Rust-by-default dissolved under measurement. The open parity question (blocked on network) is a question, not a hindrance. -
The five unreconciled articulations — dissolved by the taxonomy (D1), not a standing hindrance; the residue is one stale Draft banner (folded into H-8's amendment batch).
-
Flag-gated conservatism itself — seventeen dark flags is not inherently hindrance; unregistered darkness is (G-8). The posture may be exactly right; the register exists so that judgment can be made deliberately.
-
Six proposals from two external assessments (2026-07-28) — each verified against code and cleared, with the refuting file named: EpistemicState compression (the "unused" states are the vault's refuse-forcing states and the serving path's
UNVERIFIED_POSSIBLE—vault/store.py:99-103,chat/runtime.py:1329; ADR-0206 already partitions the taxonomy per-state incore/response_governance/policy.py:64-100); an EpistemicState×NormativeClearance product type (forbidding DECODED+SUPPRESSED at the type level erases the refusal's evidence — H-3's failure rebuilt as a type constraint; the coupling already exists as policy, where the legitimate combinations are decided); PID attestation onlived_life.json(a reboot-resumed life's writer PID is dead by definition, so the check refuses every legitimate resume, and PID reuse defeats attestation — the same pid-file pitfalls the lock's own comment derives against); path-based cycle skipping in the inductive closure (would refuse sound transitive derivations; see H-8e — the docstring, not the code, is the wrong side); a depth-enrichment session cache (the cost it targets is already@lru_cached at the pack layer,chat/pack_resolver.py:19; measure first — the 0.22% Rust precedent); a unified reasoning engine presented as refactor (changesoperator_invocationbytes →trace_hash, silently widens capability by letting compose see closure-derived triples, and reduces entailment to set membership one merge after ADR-0265 ratified denial representation — the underlying facts are real and are recorded as design considerations under H-4/H-14). Triage rule kept from this round: no external lead folds in without the one-more-file check — every rejected proposal above failed on a file its author did not open. -
Six architectural proposals from a third external assessment (2026-07-28), whose author states the method up front: "I have enough from the directory and CLAIMS.md to reason seriously." That is the method
AGENTS.mdprotocol rule 1 forbids, and the hedges mark where it broke — "almost certainly a nested conditional or a big dict," "likely doing both," "may be operating at a resolution." One folded in (G-23); five falsified by opening the file:conftest.pyis "almost certainly the most dangerous file in the repo"; suite-membership logic has accumulated in it. False. It holds two autouse engine-state isolation fixtures, a QUARANTINE nodeid registry, a SLOW_FILES/SLOW_TESTS registry,_is_slow, andpytest_collection_modifyitems— which stamps markers and never skips ("classification ONLY, never skipped here"). Zero suite membership, zero gate-tier assignment, zero conditional inclusion. The 12KB is two data tables with per-entry justifications: already the declared-table pattern the proposal asks for.cli_test.pymanages suite topology "through what is almost certainly a nested conditional or a big dict." A flat dict — 17 keys, all tuple values, zero conditionals in the module body. 463 lines, 171 of them comments (37%). The surviving half of the point — gate tier is a property of which suites the shell invokes, not of the suite — is real; but it is already declared and verified:test_suite_reachability.pydeclaresGATE_SUITESand asserts it againstpre-push/local-ci.shprecisely so the pin cannot go vacuous. The claim that this "makes pin 3's ratchet trivially implementable" describes a pin that shipped this arc.field/+algebra/+morphology/are a triad a caller must compose correctly or bypass the ratification contract; give them a singleserve(). Not a triad.algebra/has 72 non-test importers (a foundational library),field/15,morphology/3 — andmorphology/is 2 files, 97 lines total. Nodef serve(exists anywhere incore/,chat/orgenerate/; the blessed path isChatRuntime. Top-level directories look like peers regardless of size, which is the entire content of this proposal.- The epistemic grade space is richer than the serve layer consumes; collapse it. All 15
EpistemicStatemembers have non-test consumers (min 1, max 13). Nothing is unconsumed. Compression was already examined and cleared in the round above, on different evidence. - Give each of the 260+ ADRs a machine-readable
constraints:block. The count is 314, and the class already exists in the better direction:test_adr_status_governance.pyparsescore/config.py's bool flags with their cited ADR numbers and fails when a default-ON flag is governed by aProposedADR, with a non-vacuity guard. The proposal inverts this the wrong way — 314 ratified, immutable decision records each carrying live assertions is 314 new places that must be kept true, in the repository whose dominant defect class is records drifting from reality. Either the ADR is edited when code moves (breaking ratification) or the assertion goes stale (H-8, at 314×). Machine-readability belongs in the checker that reads the ADR, not in the ADR. - The unifying proposal — a root
contracts.tomlholding every declared relationship — is "the highest-leverage single change." The principle is already this repository's (ADR-0263 Rule 5: declared in the table, not the call site) and is implemented in the very file the assessment cites:core/epistemic_state.pydeclaresGroundingSourceas a closedLiteralplus a runtime-iterableGROUNDING_SOURCESfrozenset, single-sourced across the runtime, the lane validator, the Workbench API coercion, and a build-time enum-coverage test underworkbench-ui/— and its docstring records the bug that pattern caught (unregistereddeduction/curriculumlabels floored to"none", "recording a proved answer as ungrounded in a durable audit artifact"). Centralizing four tables with four different authorities and lifecycles into one file adds a fifth copy that must agree with four generators; it is a ratchet to guard ratchets (standing philosophy 2). Cleared as a proposal, kept as an observation: nobody can currently enumerate "which declared tables exist and what enforces each" — that is one page, folded into PR-5, not a new mechanism.
What it got right, and it is worth saying: proposal 1 pointed at the pack/domain seam. Every specific was wrong, and reading the code there anyway found G-23 — a real, load-bearing, one-directional check on the band whose license is next to be earned. Bad method, useful direction. The triage rule survives unchanged and earned a second demonstration: every rejected proposal above failed on a file its author did not open.