feat(p22): declare_requirement answers with a COMPARISON, not a confirmation

P19 DEL A made a direction name the requirement that binds it; P20/A1 made the reply carry the
DOCUMENT's own title and number instead of echoing the caller's arguments. Re-measured at the head
of this session against the six round-5 debate traces: requirement_hit is 0 of 20 approach rows and
0 of 12 declarations -- the third round in a row at zero. P21/C1 made the runs LOOK first and it
worked on its own terms (distinct documents before a declaration went 1,1,1,2,5,13 -> 3,3,5,7,11,12)
and the hit did not move. The runs were made to read MORE, not righter.

The reply now compares: it names the directions the run was commissioned to pursue and says which
of their words appear in the declared document's own title and number, or that none do.

A REPORT, never a gate -- the declaration is recorded either way, because a requirement can bind a
measure without sharing a word with the name someone gave it, which is exactly how the alternative
rule the C1 measurement rejected failed one rung over. The words compared are the DOCUMENT's, never
`ref`: a comparison against the caller's own argument can only ever agree. Matching is generous in
both directions, and that failure direction is chosen -- a false "no overlap" pushes a model away
from a declaration that was right, a false "overlap" merely keeps the report quiet.

MEASURED BEFORE IT WAS BUILT, offline against the six traces as the order required (no paid calls
in DEL B): the rule speaks on 10 of 12 declarations and stays quiet on 2. A rule that spoke on 12
of 12, or on 0 of 12, could not tell the two classes apart.

`labels` defaults to empty, so every call site written before today is byte-identical and the three
keys are ABSENT rather than empty -- "there was nothing to compare against" and "we compared and
found nothing" are different facts. RUN-level, as the declaration itself is (P19 A4).

Also re-measured: the order cited requirement_hit as "0 of 12". The field is per APPROACH (0 of 20);
12 is the number of DECLARATIONS (7 distinct, 0 hits). Both zero, so the conclusion stands, but they
are two populations.

Load-bearing MEASURED (tests/test_requirement_comparison_loadbearing.py, 8 arms), eight mutations
all red against the WHOLE suite + green control 1881/5 (from 1873/5, superset, 0 removed) and
golden demo-transcript.stdout BYTE-UNCHANGED (shasum -a 1 of the CONTENT =
ea8c534773acdbe41ae68f2c55724d69aaf8be4f): B1 detach the run.py wiring (1 red, that arm alone) -
B2 always report an overlap (5) - B3 never report one (2) - B4 compare against the caller's ref
(1, that arm alone) - B5 make it a gate (5) - B6 emit the keys with no directions (2, one an OLDER
independent witness) - B7 exact token equality instead of substring (1) - B8 drop the minimum word
length (3).

Honesty limits, stated: no LIVE model has read the comparison yet (DEL D is the measurement); the
report cannot say a requirement IS right, only that it shares no word with the direction; and
finding 4 (`named` 1/20) is this same matter from the other side, so DEL D measures it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-16 00:04:47 +02:00
commit 9072359606
5 changed files with 360 additions and 1 deletions

View file

@ -3011,6 +3011,49 @@ Python ≥3.10. MAF (`agent-framework-core` 1.16.0, `-orchestrations` 1.1.1 —
uttalt:** ingen betalt kjoering bekrefter ennaa at nekten endrer utfallet levende (DEL D er
maalingen); vinduet er aldri naadd av noe maalt, saa avkortnings-grenen er oevd kun syntetisk; og
skjemaet naar fortsatt ikke prompten, saa foerste forsoek gjetter som foer.
- **`declare_requirement` svarer med en SAMMENLIGNING, ikke en bekreftelse (P22 DEL B, 16.09):**
P19 DEL A gjorde at en retning MAA navngi kravet som binder den, og P20/A1 lot svaret baere
DOKUMENTETS egen tittel og nummer i stedet for aa ekko kallerens argumenter. MAALT paa nytt ved
starten av oekt 126 mot de seks runde-5-sporene: `requirement_hit` er **0 av 20** approach-rader
og **0 av 12** erklaeringer — tredje runde paa rad paa null. P21/C1 fikk kjoeringene til aa SE
seg om, og virket paa sine egne premisser (distinkte dokumenter foer en erklaering
`1·1·1·2·5·13``3·3·5·7·11·12`), men treffet rikket seg ikke: kjoeringene ble faatt til aa lese
MER, ikke RIKTIGERE. **Ordrens egen denominator var upresis, og det er maalt:** feltet
`requirement_hit` er per APPROACH (0 av 20), mens 12 er antallet ERKLAERINGER (7 distinkte, 0
treff) — begge null, saa konklusjonen staar, men de er to populasjoner.
`_label_overlap` er den ene sammenligningen: hvilke ord fra kommisjonens retninger som finnes i
det ERKLAERTE DOKUMENTETS egen tittel og nummer. **En RAPPORT, aldri en gate** — erklaeringen
registreres uansett (M B5 → 5 roede): et krav kan binde et tiltak uten aa dele ett ord med navnet
noen ga det, hvilket er NOEYAKTIG slik den alternative regelen P21/C1 maalte og forkastet feilet,
ett trinn over. **Ordene som sammenlignes er DOKUMENTETS, aldri `ref`** — kallerens eget argument
ekkoet tilbake, og en sammenligning mot kallerens input kan bare vaere enig (M B4 → 1 roed, den
armen ALENE; P20/A1s regel anvendt paa halvdelen P20 ikke naadde). **Sjenerøs i BEGGE retninger**
(delstreng hver vei, saa `rundkjoring` moeter `Rundkjoringer` og `senkekostnader` moeter `senke`),
og feilretningen er VALGT: rapporten sier ett av to, og bare ett av dem kan gjoere skade — en
falsk «ingen overlapp» skyver en modell BORT fra en erklaering som var riktig, mens en falsk
«overlapp» bare gjoer rapporten stille. Delstreng feiler mot stille (P18s `filter` valgte samme
retning av samme grunn; M B7 → 1 roed, M B2 → 5, M B3 → 2). `_LABEL_WORD_MIN = 4`, ellers deler
hver label «for»/«med»/«til» med et halvt korpus (M B8 → 3 roede).
**MAALT FOER DEN BLE BYGGET**, offline mot de seks sporene slik ordren krevde (ingen betalte kall
i DEL B): regelen TALER paa **10 av 12** erklaeringer og tier paa 2 (begge fv412, paa
`materialer`). En regel som talte paa 12 av 12 — eller paa 0 av 12 — kunne ikke skilt de to
klassene, samme proeve P21/C1s terskel maatte bestaa. **`labels` DEFAULTER til tom**, saa hvert
kallsted skrevet foer i dag er BYTE-IDENTISK og de tre noeklene UTELATES (fravaerende, ikke tomme:
«det fantes ingenting aa sammenligne mot» og «vi sammenlignet og fant ingenting» er ulike fakta,
og bare ett av dem er sant der; M B6 → 2 roede, hvorav ett ELDRE uavhengig vitne i
`test_binding_requirement`). Utforskningen mynter sine egne retninger, saa den HAR ingen ved
erklaerings-tid. **RUN-nivaa, som erklaeringen selv (P19 A4):** debatten erklaerer ÉN gang per
kjoering, saa svaret navngir HVER retning kjoeringen baerer i stedet for aa velge én den ikke kan
tilskrive. Wiringen i `run.py` maales ATFERDSMESSIG — en kilde-assert er en lint (oekt 77s funn),
saa armen driver den EKTE debatten med et steg-manus som erklaerer og leser sammenligningen ut av
verktoeyets eget svar (M B1 → 1 roed, den armen ALENE). Load-bearing MAALT
(`tests/test_requirement_comparison_loadbearing.py`, 8 armer), **aatte mutasjoner alle roede mot
HELE suiten** + groenn kontroll **1881/5** (fra 1873/5, supersett, 0 fjernet) og golden
BYTE-UENDRET (`shasum -a 1` av INNHOLDET = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`).
**AErlighets-grenser, uttalt:** ingen LEVENDE modell har lest sammenligningen
(structured-output-grensens klasse) — DEL D er maalingen; rapporten kan ikke si at et krav ER
riktig, bare at det ikke deler ett ord med retningen; og funn 4 (`named` 1/20) er denne saken
sett fra den andre siden, saa den maales av DEL D og ikke av en egen soem.
- **STATE.md er local-only** (gitignored). Voyage session-state er efemert; STATE.md er kanonisk kontinuitet.
- Prosess: Voyage-plugin (`/trekbrief → /trekplan → /trekexecute → /trekreview`) per større fase.