feat(toolbox): the seven outbox writers get their own door -- row 1 moves 8 -> 15 of 17
Every one of the run path's seven `outbox.write_*` steps was reachable only through `run.main`, and every path through that builds a chat client. The steps need no model: they take already-rendered data and put it on disk in a byte-deterministic form. Seven subcommands, seven thin adapters. The outbox directory is always the caller's to name -- never a default, never the repository's own, because a step that wrote into a folder the framework also reads as an inbox would bypass the Step-8 promotion gate. `write-outbox` is the one that is not purely mechanical: `outbox.write_outbox` branches on the outcome TYPE, so a door that took the outcome as an argument would let anyone author an outbox of claims and hand it to Step 8 as results. The door DERIVES it through `validate_proposal` -- the run path's own composition -- and a blocked proposal exits 3 with the artefacts still written, since that is where the rejection is recorded. `verdict_id` stays an argument: `verdict-key` already owns that minting. `--stop-reason` is required rather than defaulted to the empty string, inheriting the core writer's measured reason: "the run finished" and "we never found out" must not be the same value. Eight probes, each a subprocess with the subcommand in argv, each asserting on the FILE the command wrote. The ground truth is composed in the test -- the payload it wrote and counted itself, and the byte form the contract requires -- never `outbox._dump`, which would have measured the module against itself. The refusal arm carries its rc-0 control. Measured, own run of the B gate: row 1 8 of 17 -> 15 of 17, exit 1 unchanged, no other row moved. 0 chat-client names reachable from the toolbox (known-positive control: 24 in run.py). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
1111924000
commit
6375ce5af3
5 changed files with 691 additions and 30 deletions
|
|
@ -263,11 +263,14 @@
|
|||
"scope": "run_project"
|
||||
},
|
||||
"entry": {
|
||||
"kind": "console-script",
|
||||
"module": "run.py",
|
||||
"scope": "main"
|
||||
"kind": "subcommand",
|
||||
"module": "toolbox.py",
|
||||
"scope": "main",
|
||||
"command": "write-run-config"
|
||||
},
|
||||
"probe": []
|
||||
"probe": [
|
||||
"tests/test_toolbox_outbox_doors.py::test_write_run_config_from_outside_is_the_byte_deterministic_artefact"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "coverage",
|
||||
|
|
@ -279,11 +282,14 @@
|
|||
"scope": "run_project"
|
||||
},
|
||||
"entry": {
|
||||
"kind": "console-script",
|
||||
"module": "run.py",
|
||||
"scope": "main"
|
||||
"kind": "subcommand",
|
||||
"module": "toolbox.py",
|
||||
"scope": "main",
|
||||
"command": "write-coverage"
|
||||
},
|
||||
"probe": []
|
||||
"probe": [
|
||||
"tests/test_toolbox_outbox_doors.py::test_write_coverage_from_outside_keeps_every_row_and_the_stop_reason"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "utboks",
|
||||
|
|
@ -295,11 +301,14 @@
|
|||
"scope": "run_project"
|
||||
},
|
||||
"entry": {
|
||||
"kind": "console-script",
|
||||
"module": "run.py",
|
||||
"scope": "main"
|
||||
"kind": "subcommand",
|
||||
"module": "toolbox.py",
|
||||
"scope": "main",
|
||||
"command": "write-outbox"
|
||||
},
|
||||
"probe": []
|
||||
"probe": [
|
||||
"tests/test_toolbox_outbox_doors.py::test_write_outbox_from_outside_writes_the_pair_the_run_path_writes"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "rundebinding",
|
||||
|
|
@ -365,11 +374,14 @@
|
|||
"scope": "run_project"
|
||||
},
|
||||
"entry": {
|
||||
"kind": "console-script",
|
||||
"module": "run.py",
|
||||
"scope": "main"
|
||||
"kind": "subcommand",
|
||||
"module": "toolbox.py",
|
||||
"scope": "main",
|
||||
"command": "write-prepass"
|
||||
},
|
||||
"probe": []
|
||||
"probe": [
|
||||
"tests/test_toolbox_outbox_doors.py::test_write_prepass_from_outside_records_the_cut_the_run_was_given"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "parse-feil",
|
||||
|
|
@ -381,11 +393,14 @@
|
|||
"scope": "run_project"
|
||||
},
|
||||
"entry": {
|
||||
"kind": "console-script",
|
||||
"module": "run.py",
|
||||
"scope": "main"
|
||||
"kind": "subcommand",
|
||||
"module": "toolbox.py",
|
||||
"scope": "main",
|
||||
"command": "write-parse-failures"
|
||||
},
|
||||
"probe": []
|
||||
"probe": [
|
||||
"tests/test_toolbox_outbox_doors.py::test_write_parse_failures_from_outside_keeps_every_reply_that_did_not_parse"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "forslagsvurderinger",
|
||||
|
|
@ -397,11 +412,14 @@
|
|||
"scope": "run_project"
|
||||
},
|
||||
"entry": {
|
||||
"kind": "console-script",
|
||||
"module": "run.py",
|
||||
"scope": "main"
|
||||
"kind": "subcommand",
|
||||
"module": "toolbox.py",
|
||||
"scope": "main",
|
||||
"command": "write-proposal-reviews"
|
||||
},
|
||||
"probe": []
|
||||
"probe": [
|
||||
"tests/test_toolbox_outbox_doors.py::test_write_proposal_reviews_from_outside_states_an_empty_review_list"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "debatt-verktøy",
|
||||
|
|
@ -413,11 +431,14 @@
|
|||
"scope": "run_project"
|
||||
},
|
||||
"entry": {
|
||||
"kind": "console-script",
|
||||
"module": "run.py",
|
||||
"scope": "main"
|
||||
"kind": "subcommand",
|
||||
"module": "toolbox.py",
|
||||
"scope": "main",
|
||||
"command": "write-debate-tools"
|
||||
},
|
||||
"probe": []
|
||||
"probe": [
|
||||
"tests/test_toolbox_outbox_doors.py::test_write_debate_tools_from_outside_writes_an_empty_trace_as_a_statement"
|
||||
]
|
||||
}
|
||||
],
|
||||
"roles": {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue