feat(navigation,validator): read_dir names the rung that reads a document, and a run can require its anchoring
F3 and F4, the two findings the S7 acid test (session 98) reported and left. The order required both descriptions to be treated as PREMISES. One held; the other was felled before anything was built on it. F3 -- premise FELLED, asymmetry real. The order read arm C's two refused calls as "the path names a document that EXISTS". Measured against the base that ran: its root holds 27 directories named del-ii-bilag-N-... and 12 documents named inbox-del-ii-bilag-N-....md, and the requested path matches NEITHER -- it is the directory naming convention applied to a document whose real name carries an inbox- prefix. So the two live rounds were the UNKNOWN-path class, and this delivery does NOT recover them (gated). What IS real: read_file on a directory has named read_dir since session 95, while read_dir on a document named neither the rung nor the path. okf.DocumentPathRefused closes that one direction -- a ValueError, a SIBLING of BundlePathNotFound rather than a subclass, built from context_files (never files) and through the same in_dimension predicate the listing uses, quoting the document's REAL name so what it hands back resolves. F4 -- premise HELD, option (c) felled by measurement. All four live artefacts stamped cost_baseline_anchored: False and each arm invented its cost codes. derive_cost_baseline refuses against the delivered base: K2's price schedule is a pandoc SIMPLE table with ONE column header, so making --derive-cost-baseline reachable there would mean inventing a rule for an unmeasured form -- MAJOR-4's own honesty limit. Chose (b) over (a): --require-cost-baseline / run_project(require_cost_baseline=...), OPT-IN and never default, so every bundle without a cost-baseline.json runs unchanged. The gate sits where both branches have bound baseline and ABOVE the dry-run cut, so it fires on the free trip too and, on the paid one, before the first model call. Three CLI refusals by name, each with an rc-0 control. 12 mutations, all red against the WHOLE suite. Green control 1493/5 -> 1511/5 (+18 node-ids, 0 removed); golden demo-transcript.stdout BYTE-UNCHANGED (shasum -a 1 of the CONTENT = ea8c534773acdbe41ae68f2c55724d69aaf8be4f). No paid run: both findings measured offline. Measurement: docs/2026-09-08-f3-f4-nekten-og-forankringen.md Order: 20260908T020419Z-5837110336-from-portfolio-optimiser Co-Authored-By: Claude <Opus 5>
This commit is contained in:
parent
76b939b3b8
commit
9232f94041
8 changed files with 759 additions and 2 deletions
14
README.md
14
README.md
|
|
@ -626,6 +626,20 @@ when the seam is detached, so the loop cannot silently degrade into theater.
|
|||
--derive-cost-baseline
|
||||
```
|
||||
|
||||
- **Requiring the run to be anchored** — `--require-cost-baseline` (opt-in, requires
|
||||
`--bundle-dir`). Without a baseline the validator's stage 0 is skipped, and the run says so on
|
||||
stdout — but it still finishes and still stamps `validator_decision: validated` over cost lines
|
||||
nothing tied to the project. Measured on a live tender run, every arm invented its codes. This
|
||||
flag turns that visibility into a refusal: no baseline, no run, and the refusal fires before the
|
||||
first model call, on `--live-dry-run` as well. It stays opt-in because a bundle that ships no
|
||||
`cost-baseline.json` is legitimately un-anchored — combine it with `--derive-cost-baseline` when
|
||||
the base carries a priced schedule.
|
||||
|
||||
```bash
|
||||
uv run python -m portfolio_optimiser.run PROSJEKT-1 --docs-dir <bundle> --bundle-dir <bundle> \
|
||||
--derive-cost-baseline --require-cost-baseline
|
||||
```
|
||||
|
||||
|
||||
`--explore` is refused together with `--mandate` — they are two sources of one mandate, and
|
||||
merging would silently overwrite what you wrote. To seed an exploration with a domain expert's
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue