feat(row6): a proposal whose approach declared no requirement is unsupported

Stress round 6 validated three falsification arms, and every validated
approach rested only on run-level declarations nobody can attribute to one
approach. declare_requirement now takes a required approach_id (a mandate
id or own-proposal; an unknown id is refused naming the valid ones), and a
ValidatedProposal whose approach has neither a mandate requirement nor a
declaration under its own id becomes validator.Unsupported - a Rejection
subclass carrying the validator's own ruling, reported as `unsupported` in
coverage, the outcome artefact, the settlement and the judge, and never
counted or summed. The rule is active whenever the debate held the
declaration tool, the micro base included; the road and pre-pass paths are
untouched. Declaration quality is not judged, so the rule can be satisfied
by declaring any document the run read.

The v1 gate's row 6 probes pass; its artefact half reads IKKE MÅLT because
stress round 6 predates approach-addressed declarations, and IKKE MÅLT is
never green - it fails the exit code.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-17 16:40:54 +02:00
commit 938a1ca30e
23 changed files with 718 additions and 115 deletions

View file

@ -70,7 +70,7 @@ def test_c1_a_declaration_after_one_document_is_refused_with_the_denominator() -
opened.append(ToolCall(name="read_file", bundle_id="tunnel-hauglia", path=path))
answer = tools["declare_requirement"].func(
bundle_id="tunnel-hauglia", path=path, ref="Krav 1.1—1"
approach_id="a1", bundle_id="tunnel-hauglia", path=path, ref="Krav 1.1—1"
)
assert answer["refusal"] == "RequirementNotRead"
@ -93,7 +93,7 @@ def test_c1_the_same_declaration_after_three_documents_is_accepted() -> None:
opened.append(ToolCall(name="read_file", bundle_id="tunnel-hauglia", path=name))
answer = tools["declare_requirement"].func(
bundle_id="tunnel-hauglia", path=files[0], ref="Krav 1.1—1"
approach_id="a1", bundle_id="tunnel-hauglia", path=files[0], ref="Krav 1.1—1"
)
assert answer["declared"] is True
@ -109,7 +109,7 @@ def test_c1_the_same_path_read_three_times_is_still_one_document() -> None:
opened.append(ToolCall(name="read_file", bundle_id="tunnel-hauglia", path=path))
answer = tools["declare_requirement"].func(
bundle_id="tunnel-hauglia", path=path, ref="Krav 1.1—1"
approach_id="a1", bundle_id="tunnel-hauglia", path=path, ref="Krav 1.1—1"
)
assert answer["refusal"] == "RequirementNotRead"
@ -135,7 +135,9 @@ def test_c1_a_small_base_stays_declarable(tmp_path: Path) -> None:
for name in ("a.md", "b.md"):
opened.append(ToolCall(name="read_file", bundle_id="mini", path=name))
answer = tools["declare_requirement"].func(bundle_id="mini", path="a.md", ref="1")
answer = tools["declare_requirement"].func(
approach_id="a1", bundle_id="mini", path="a.md", ref="1"
)
assert answer["declared"] is True
assert len(declared) == 1
@ -151,7 +153,7 @@ def test_c1_the_never_opened_refusal_still_fires_first() -> None:
opened.append(ToolCall(name="read_file", bundle_id="tunnel-hauglia", path=name))
answer = tools["declare_requirement"].func(
bundle_id="tunnel-hauglia", path=files[4], ref="Krav 1.1—1"
approach_id="a1", bundle_id="tunnel-hauglia", path=files[4], ref="Krav 1.1—1"
)
assert answer["refusal"] == "RequirementNotRead"