feat(s33): wave executor with per-project snapshot and deterministic merge barrier

Replaces run_portfolio's sequential loop with a wave loop over _waves(ids, k):
each wave takes a per-project snapshot of the shared store, runs the wave under
one asyncio.gather in a single event loop, then crosses a merge barrier that
folds each project's NEW verdicts back in wave-submission order. Step 2's
contract goes GREEN; runs stays in project_ids order because gather resolves in
argument order, not completion order.

TWO PLAN CORRECTIONS, both found by the RED-first test rather than by reading:

1. The plan specified sorting the merged verdicts on `project_id`. Measured, that
   produces a deterministic order which is the WRONG one: lexicographic gives
   BRU/FV42/RV13 while the sequential pass gives FV42/RV13/BRU. It satisfies
   "deterministic" while breaking "identical to concurrency=1" — and the second is
   the actual contract. The merge preserves submission order instead.

2. The plan named the barrier's sort as the load-bearing seam. It is not — with
   per-project snapshots the wave list is never reordered by completion, so a
   sorted() there would re-sort an already-ordered list and read as a guard while
   guarding nothing. The SNAPSHOT is the half that carries the load. Rather than
   ship a decorative sort, both halves were measured (scratchpad-restore, never
   git checkout):

     detach _wave_snapshot  -> RED (store lands in completion order)
     detach merge ordering  -> RED (reversed wave order diverges)

   Both restored byte-identical (sha 42b01d46).

The snapshot carries `retriever` across deliberately: dropping it would silently
downgrade a caller-owned store's S3.1 semantic-retrieval opt-in mid-pass.

Also strengthens the scripted-client consolidation guard, which the probe broke by
being a legitimate third _inner_get_response def-site. It pinned a literal count
of 2 — the wrong shape: it failed on any new legitimate subclass while still
passing if someone pasted a duplicated body into an already-listed file. It now
pins the property (registered sites, scripted-lineage overrides must delegate via
super(), foreign-lineage doubles must genuinely be foreign). Verified load-bearing:
removing both delegation sites turns it RED.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LQapztREtC2mkr5oU811pr
This commit is contained in:
Kjell Tore Guttormsen 2026-07-31 15:56:13 +02:00
commit 756b1d5b5c
3 changed files with 207 additions and 51 deletions

View file

@ -9,6 +9,7 @@ five ``def _inner_get_response`` sites (four scripted + test_step5's own-lineage
from __future__ import annotations
import re
from pathlib import Path
_ROOT = Path(__file__).resolve().parents[1]
@ -18,9 +19,35 @@ def _py_files(base: str) -> list[Path]:
return sorted((_ROOT / base).rglob("*.py"))
# Files permitted to define ``_inner_get_response``. The invariant this guard protects is that the
# scripted BODY is not duplicated — not that the def-site count is frozen. Adding a file here is a
# deliberate act: a new entry must either be the canonical, or a thin override that DELEGATES to it
# (which ``test_delegating_overrides_call_super`` below then enforces mechanically).
_CANONICAL_SITE = "src/portfolio_optimiser/simulation.py"
# Overrides in the SCRIPTED lineage — they subclass ``ScriptedChatClient``, so a body of their own
# would be a copy of the canonical. They must delegate.
_DELEGATING_OVERRIDES = [
# S3.3 ordering probe: yields to the event loop N times, then delegates. It cannot live in the
# reply-selector seam, which the canonical calls synchronously and so can never await.
"tests/test_portfolio_concurrent_loadbearing.py",
]
# Doubles in a DIFFERENT lineage (``spikes._harness.FakeChatClient``). There is no canonical
# scripted body above them to delegate to, so the delegation rule does not apply — but the
# separation is asserted rather than assumed, so a file cannot be parked here to dodge the rule.
_FOREIGN_LINEAGE = ["tests/test_step5_refine_loadbearing.py"]
def test_inner_get_response_collapsed_to_two_sites() -> None:
"""The four scripted clients collapse to ONE canonical ``_inner_get_response`` (simulation.py);
test_step5's own-lineage double is the only other def. So exactly 2 def-sites remain — NOT 5."""
"""The four scripted clients collapse to ONE canonical ``_inner_get_response``
(``simulation.py``). Every other def-site must be a registered, DELEGATING override never a
fourth copy of the body.
The guard originally pinned a literal count of 2. That made it fail on any new legitimate
subclass while still passing if someone pasted a duplicated body into an already-listed file
a count is the wrong shape for the invariant. The list below plus
``test_delegating_overrides_call_super`` pin the property itself."""
sites = [
p.relative_to(_ROOT).as_posix()
for base in ("src", "tests")
@ -28,10 +55,43 @@ def test_inner_get_response_collapsed_to_two_sites() -> None:
if p.name != Path(__file__).name # this guard file references the pattern in prose
and "def _inner_get_response" in p.read_text(encoding="utf-8")
]
assert sorted(sites) == [
"src/portfolio_optimiser/simulation.py",
"tests/test_step5_refine_loadbearing.py",
], f"expected the four scripted bodies collapsed to one canonical + test_step5's, got: {sites}"
expected = sorted([_CANONICAL_SITE, *_DELEGATING_OVERRIDES, *_FOREIGN_LINEAGE])
assert sorted(sites) == expected, (
f"unregistered ``_inner_get_response`` def-site — the scripted body must not be copied. "
f"Expected {expected}, got: {sites}"
)
def test_foreign_lineage_doubles_are_genuinely_foreign() -> None:
"""A file listed as foreign lineage must NOT subclass the scripted canonical.
Without this, ``_FOREIGN_LINEAGE`` would be an escape hatch: any scripted-lineage subclass
could be moved into that list to skip the delegation rule below."""
for site in _FOREIGN_LINEAGE:
text = (_ROOT / site).read_text(encoding="utf-8")
assert "ScriptedChatClient" not in text, (
f"{site} is registered as foreign lineage but references ``ScriptedChatClient`` — if it "
"is in the scripted lineage it belongs in _DELEGATING_OVERRIDES and must delegate"
)
def test_delegating_overrides_call_super() -> None:
"""Every scripted-lineage override actually DELEGATES to the canonical rather than
reimplementing it.
This is the strength the literal count never had: without it, a file already on the list could
grow a full copy of the scripted body and the consolidation would be cosmetic again."""
for site in _DELEGATING_OVERRIDES:
text = (_ROOT / site).read_text(encoding="utf-8")
# Match the delegation ITSELF — ``super()._inner_get_response`` or the explicit
# ``super(Cls, self)._inner_get_response`` form a nested function needs. Searching for
# "super(" and "_inner_get_response" independently would pass on any file that merely
# calls ``super().__init__`` near a def, which is accidental-green, not a guard.
assert re.search(r"super\([^)]*\)\._inner_get_response", text), (
f"{site} defines ``_inner_get_response`` but never delegates to the canonical via "
"``super()._inner_get_response`` — that is a duplicated body, which is exactly what "
"this guard exists to prevent"
)
def test_no_src_imports_tests() -> None: