Commit graph

5 commits

Author SHA1 Message Date
1041687d31 test(experience): the id was pinned, the keying was not - and the two paths disagree
S3.2 measured with scripts/mutation_harness.py, denominator tests/ (963), every
run sha256-restored. The mirroring question answerable offline: is today's
boundary - "the id comes from the FILE, the keying comes from the BUNDLE" -
load-bearing in both halves?

The id half is pinned on both sides (re-minting RED, dropping the mint fallback
RED). The keying half is green-but-dead: empty features and the gated C3.2 fix's
own shape each left all 963 green. Nothing observed what a seeded verdict is
keyed on. One rationale clause too: requiring BOTH learning fields, whose
either-or form emits a marker naming the absent field as None (honesty, §1).

New beyond C-F5: the sibling's drift form DOES exist here. A verdict is keyed in
exactly two places by different rules - the bundle seed (bundle-wide) and the
file/inbox path (per-verdict) - so the same verdict id lands in the same
first-write-wins slot with a keying decided by LOAD ORDER. And promote writes no
candidate features at all, which is why the fix's shape is a no-op against every
fixture in the repo and had to be measured against one carrying the fields.

Pinned by tests/test_experience_keying_loadbearing.py (11 tests, 963 -> 974,
strict superset, 0 node ids lost). No src/ change: C-F5 is GATED on D-A pkt. 4,
and these tests exist so the gated work must arrive as a visible red test and a
decision. Two behaviour-preserving mutations carry their own controls (a third
VerdictRecord site; hoisting the projection read into the loop). Dated under the
D7 frame: work after 2026-08-09, never independent convergence.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 23:40:07 +02:00
544655b4c8 test(validator): the gate was pinned in its arithmetic, not in its decision [mutation-ok]
[mutation-ok] rationale: no mutation is pinned in code. `src/` is byte-identical
to HEAD (git diff HEAD -- src/ is empty; `if False` occurs 0 times under src/).
The three matches the guard found are PROSE in the docs note and the test file's
docstring, quoting the detach mutation that was run and restored. Every harness
run in this session verified its restore by sha256 from disk.

S2.7 is the D7 mirroring queue's topmost unmeasured candidate. The MAF sibling
tightened its validator in two halves -- (a) a structural block on
`claimed > nominal_feasible`, (b) an IR invariant `low <= unit_cost <= high`.
Both halves are GATED here on D-A pkt. 1 + a commons pull, and the defect they
answer is confirmed on our side as C-F2. So neither is built. The question this
answers is the one that is answerable offline: is today's boundary -- "the ONE
numeric gate is p90" -- load-bearing?

One rule, structurally: a claim is numerically bounded in exactly two places in
src, each with its own spec role (ir.py:50 §7.1, validator.py:68 §3 Step 4).
The sibling's drift shape does not exist here.

But the coverage splits cleanly across the rule. Measured with
scripts/mutation_harness.py, denominator tests/ (all 955), each run
sha256-restored: everything the gate COMPUTES is red, because the golden
fixture freezes it -- policy cap, band branch, band endpoint order, MC seed,
p90 cut point, nominal_feasible. Everything the gate DECIDES WITH is
green-but-dead -- bound to p10, bound to nominal_feasible, and loosening the
comparison each left all 955 green. The golden freezes what the validator
produces, so it cannot help with the one thing it does not observe: which bound
the gate reads. Swapping p90 for nominal_feasible IS the gated S2.7 half (a),
and it would have landed with the suite green, before D-A was decided.

Closed by tests/test_validator_gate_loadbearing.py (8 tests, 955 -> 963). Each
clause is green before and red after exactly its own mutation, with the golden
figures green in BOTH runs -- which shows mechanically that the mutation moved
the decision, not the arithmetic. The two IR tests are pinned with --red-at
against the invariant's own message, since they die in a helper. The AST
population control was proved against a BEHAVIOUR-PRESERVING mutation (the gate
widened to a logically equivalent conjunction) with all three behavioural
controls green: a new gate site is invisible to any behavioural test, which is
why it is there.

Two things the measurement gave in addition. Under the containment mutation the
golden test stayed green, confirming mechanically that half (b) is
golden-compatible when D-A lands. And the IR carries no ORDER on band endpoints
either -- strictly more than C-F2 names: (1.40, 0.70) is accepted, and while
random.uniform still draws from [0.70, 1.40], it walks the seeded stream
backwards, which is a different p90 (120456.91 against 121057.09).

Honest limit: pinning that a claim above nominal_feasible validates today is not
an endorsement of it. C-F2 calls that a MAJOR spec-level defect and the fix is
gated, not declined. These tests make the gated work arrive as a visible red
test and a decision, never as a silent swap. No src change, no spec text
touched, the fasit untouched.

Dated under the D7 frame: work AFTER 2026-08-09, not independent convergence.

Co-Authored-By: Claude <claude-opus-5>
2026-09-07 00:07:19 +02:00
607f017537 test(okf): the one unquoting rule was pinned at its edge, not in its three clauses
D7 mirroring candidate (a)/(i) `unquote_scalar`, measured. The sibling grew that
function after a duplicated conversion had drifted; our counterpart
`okf._strip_matching_quotes` is genuinely ONE rule -- one definition, one call
site, and `unquote` appears in 0 of 76 .py files under src+tests (positive
control: the same query finds `parse_frontmatter`). So the drift shape is absent.

But the rule was covered only at its edge. Detaching it outright is red; each of
its three clauses was green-but-dead against the whole 950-test suite -- weakening
the length guard, dropping the matching requirement, and widening the quote set
with a symmetric delimiter all left the suite green. Same class as the
_STRUCTURE_MARKERS hole: named and edge-covered is not covered.

tests/test_okf_unquote_loadbearing.py closes the three clauses (950 -> 955). Each
clause test is green before and red after exactly its own mutation, with the
population control green in both, clause 3 pinned on its line via --red-at.

A measuring trap, measured: the first clause-3 mutation added '[' to the quote
set and the suite stayed green -- which reads as "not covered" but is a NO-OP,
since '[' can never satisfy the matching clause. Flow-form values are protected
by the matching clause, not the quote set. The harness cannot distinguish a
behaviour-preserving mutation from an undetected seam; both surface as "stayed
GREEN". A mutation must be shown to change behaviour before its green is read as
a hole.

No flow decoding is added here -- that is the sibling's B4 work, and these tests
pin today's boundary so it cannot land silently on this side.

Co-Authored-By: Claude <claude-opus-5>
2026-08-31 23:31:17 +02:00
56164f5f07 test(sdk): the server knows its own name, and the tool never hears it
B4 asked whether this side gets server identity for free in tool names.
It does not. create_sdk_mcp_server emits the bare name; mcp__ appears in
0 of the package's 24 files, with create_sdk_mcp_server itself as the
positive control that the query can find. Identity lives on the config
and on Server.name, disjoint from anything the tool list carries.

The prefix does exist -- 178 times, inside the CLI bundled with the SDK.
But that was read off the artifact, not observed in a run, and observing
it would cost the one live query() this repo does not spend. So the
finding is scoped to the seam we can actually hang a recorder on, and
the note says so rather than claiming the wider thing.

Value-proved, not asserted: mutating the SDK to namespace at construction
time turns 3 of the 4 tests red, and the one that stays green is the
population control, which should. The SDK file was restored byte-identical.

Same answer as the MAF sibling, arrived at after 2026-08-09 -- so it is
recorded as a measurement, not as independent convergence.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 08:33:07 +02:00
98516f1b8c docs(state): three points that were state, not current state-of-play
STATE.md measured 149 lines against a ~120 cap (operator decision 2026-08-18).
The negative findings, the D7 mirroring queue and the D-A gates are settled
records, not the state-of-play the next session needs at the top of the file, so
they move here and STATE keeps ONE pointer per point on the `fil § Overskrift`
form — a grep-able paragraph anchor, never a line number. Nothing is deleted:
state moves, it does not disappear.

The negative-findings list carries a correction rather than a copy. Its
`ingest_spec` entry was measured against the §12-anchored guard; session 32
found the hole that enumeration did not cover, so the entry is annotated with
what its scope actually was. A negative finding has a scope, and the scope is
the query that was run.

STATE 149 -> 134 (move plus compression of the closed points and the log; the
remaining gap over ~120 is stated to the operator rather than closed by deleting
live state). `docs/` publishes on the next `open` push — that push is not taken
here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FQBdZYCWHLKNH8tLiZsXFq
2026-08-18 17:58:29 +02:00