Commit graph

2 commits

Author SHA1 Message Date
82d46148e2 test(loadbearing): measure the last 8 all-negative tests instead of assuming them
Point 2 of the vacuity sweep is now MEASURED, not paired-by-reading. Every
one of the 8 got a mutation that detaches the seam it claims to guard, run
through a harness that asserts the anchor is unique before mutating, restores
in `finally`, and sha256-verifies the restore.

Six were value-proven — the negative itself went RED under its detach:
  hitl :260  load_routing invents a default        -> RED
  hitl :298  route_pending hardcodes a fallback    -> RED
  step7 :145 the is_dir() guard deleted            -> RED
  step7 :171 the §4.2 vocabulary filter deleted    -> RED
  step7 :253 the id grammar off the model          -> RED
  prov  :111 sdk_version becomes required          -> RED

Two did not, and both are fixed here.

hitl :197 — the guard it appeared to prove is DEAD. Deleting the `is_dir()`
early-out from load_outbox_proposals leaves all 711 tests green: the tolerance
comes from `Path.glob`, which yields nothing on a missing directory and never
raises. The contrast is the finding: load_inbox carries an identically-shaped
guard that IS load-bearing, because it walks with `Path.iterdir`, which DOES
raise (measured both ways). Same guard, opposite verdict, and the difference
is the stdlib call behind it — the point-3 lesson one level out, where the
default being pinned belongs to the standard library rather than the SDK.
The stdlib baseline is now anchored explicitly, so a Python that makes glob
raise turns this red instead of quietly promoting a dead line to a seam.
What the test always did prove is kept and stated: replacing the early-out
with a raise turns it red, so it does hold tolerance.

portfolio :175 — the negative asserted over an unheld population. Measured, it
is real today (6 prompts), so the test is not vacuous now; nothing in it says
so, and a run_portfolio that stopped prompting would leave it green while
proving nothing. A positive control now runs first. Value-proven: green before,
red after the same mutation (iterate no projects), and it is that assertion
which fails, not an import.

The sibling repo sent the same rule from the other stack this week, arrived at
independently via its B4 empty-negative: on a negative assert, prove FIRST that
the event happened.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qr6TwWrHDHeukHy3bL4hgb
2026-08-09 10:08:12 +02:00
9bae4fb563 feat(portfolio): K3 — portfolio learning loop (shared verdict store, parity row 5) [skip-docs]
A single VerdictStore threaded through run_portfolio: a verdict available when
project k composes survives into project k+1's fold (method-spec §5 cross-project
threading). The optional verdict_dir is the portfolio-level expert inbox, read
before each fold (role split §3 Step 7 — the portfolio never writes a run's own
verdict back; §1/§6 — no self-contamination, only expert/seed verdicts cross).
compose_run_context gains an optional passed-in store (None = fresh; every
existing caller composes exactly as before).

Load-bearing (tests/test_portfolio_learning_loadbearing.py), 2 detach proofs +
control + §4.2 idempotency:
- cross-project threading: project 1's bundle seed survives into project 2's
  prompt via the shared store; detach (compose ignores the passed-in store,
  always fresh) -> red.
- portfolio inbox fold: a verdict_dir marker reaches the project's fold; detach
  (drop the run_portfolio merge) -> red; control (no verdict_dir) -> marker absent.
- double-merge idempotency: a verdict merged before every project folds exactly
  once (first-write-wins on id).

437->442 green, golden byte-exact, full gate clean (ruff + format + mypy strict).
run_s10.py and runs/ byte-untouched. README synced (test count, portfolio block,
load-bearing list). K2 re-entrancy test stays green — the shared store threads
verdict fold lines only, never bundle context markers.

[skip-docs]: no invariant changed (CLAUDE.md untouched); the run_portfolio and
compose_run_context docstrings + README carry the doc need.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RiTwaKLesgcwXx2mDviqpt
2026-07-23 22:08:02 +02:00