feat(toolbox): the judgement through the same door -- validate-proposal, verdict-key, capture-verdict
B's premise applied to the three steps that DECIDE a proposal: a proposal authored outside po -- by a human, or by an agent that is not po -- now meets the blocking deterministic gate, mints the learning key, and is captured as a Verdict, all without a chat client on the way. Three thin adapters, no second implementation. The reason is the one the first four doors were built on, but it bites harder here: the refusal SENTENCE is fed back verbatim into the next attempt by step 5, so a door that reworded it would break the repair loop while still looking correct. The probes assert the sentence, not a substring two stages share. One measurement decided a design detail. The IR writes whole magnitudes as JSON integers (30000), the run path carries the pydantic float, and verdicts._mint_id hashes the raw value -- so minting from the undeclared JSON would hand out a DIFFERENT verdict id than the debate does for the same proposal. The door therefore reads the proposal through SavingsProposal and feeds model_dump() to the public features_from_ir; the probe pins both forms and asserts they differ, so the shortcut cannot come back silently. A blocked proposal exits 3, carrying the verdict rather than an exception envelope. "You asked right and the answer is no" is the same fact whether a file was missing or a claim was infeasible, and a caller that only reads the exit code must not see a blocked proposal as a cleared one. Fasit outside the door in every arm: the base's own checked-in golden suite (written before the toolbox existed, so it cannot have been fitted to it), a cost baseline authored in the test, a method cap computed by hand from the fixture, and the public minting rule. Each refusal arm has an rc-0 control on an argv that would otherwise be accepted. STATED LIMIT: the input-grounding stage (P7, stage 0b) has no flag here. It falsifies a proposal against the rendered prompt the model received, and an outside caller has no such prompt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
c660bd2a82
commit
368367e1c5
4 changed files with 408 additions and 14 deletions
16
README.md
16
README.md
|
|
@ -100,10 +100,24 @@ uv run portfolio-optimiser-toolbox cost-baseline --bundle-dir <base> --project-i
|
|||
|
||||
# Admit (or refuse, by name) a declared pre-pass cut before it may shape a run
|
||||
uv run portfolio-optimiser-toolbox prepass-admit --payload <cut.json> --bundle-dir <base>
|
||||
|
||||
# Run the blocking deterministic gate on a proposal written OUTSIDE the framework.
|
||||
# Exit 3 carries the verdict: the verbatim refusal sentence and the stage that wrote it.
|
||||
uv run portfolio-optimiser-toolbox validate-proposal \
|
||||
--proposal shared/examples/bygg-energi-mikro/validator-input.json \
|
||||
--cost-baseline <project-prices.json>
|
||||
|
||||
# The learning key a verdict on that proposal will arrive under — without deciding anything
|
||||
uv run portfolio-optimiser-toolbox verdict-key --proposal <proposal.json>
|
||||
|
||||
# Mint an expert's judgement into the Verdict the store holds (stdout is the on-disk form)
|
||||
uv run portfolio-optimiser-toolbox capture-verdict --proposal <proposal.json> \
|
||||
--decision approved --rationale "why"
|
||||
```
|
||||
|
||||
Each subcommand calls the same function the run path calls — not a copy of it. That is what makes
|
||||
the answers you get here the answers the debate gets.
|
||||
the answers you get here the answers the debate gets: a proposal a human wrote meets the same
|
||||
stages, in the same order, with the same sentence, as one an agent produced.
|
||||
|
||||
Verify the install by running the whole suite from the clean clone:
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue