fix(outbox,toolbox): the class was every caller-supplied name, and containment was not unreachable
Session 146 fixed `--run-id` across the seven doors and called it a class. It was not: the class
is every caller-supplied value that reaches a file name, and `write_outbox` composes
`{run_id}-{approach_id}`. Measured 20.09 -- `--approach-id a/../../../ESCAPE` answered 0 and put
the artefacts three levels above the directory the caller named. Counted rather than assumed: 11
path compositions in `outbox.py`, 2 such values, both now through one `_checked_name`.
The ledger sentence that said containment was UNREACHABLE after the string rule was untrue, and
the approach-id escape is the disproof -- the removed check would have caught it. It is back, but
in `outbox._artefact_path`, where the composition is, not in the door. That is the difference
that makes it reachable: the string rule lives in the door, while `run.py` hands its own
`--run-id` straight to the writers and goes past it. Checked before the directory is created, so
a refusal leaves nothing behind, and it covers the next flag someone interpolates into a name.
The judge's exact call now answers 3 with 0 files outside. Suite 2291/0/5/5 (746 s), ruff clean,
mypy 0. Both gates re-run after `git add`: v1 exit 1 (0/3, 0/3, 3/8, no report, 3/8, NOT
MEASURED, 1/20), B exit 1 (15/17, 0/2, 15/15 over 516 files, 0/3, 4/5, NOT MEASURED) -- no row
moved, and row 3's denominator held because the probe grew in place rather than as a new file.
Also: the presentation deck said 1.1.0 was the current version in two places. 1.2.0 now stands in
every tracked place that claims the repo's version. No bump, no tag, no new capability.
[skip-docs]
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
8a6a09df05
commit
cec9b8fe50
5 changed files with 116 additions and 68 deletions
20
CHANGELOG.md
20
CHANGELOG.md
|
|
@ -32,12 +32,20 @@ at all, and this release gives each of them a command of its own.
|
|||
report share one module entry point without a subcommand that tells them apart.
|
||||
|
||||
### Security
|
||||
- A `--run-id` that carries a path is refused by all seven outbox doors before anything is written.
|
||||
Each writer composes `<out_dir>/<run_id>-<artefact>.json`; the directory was guarded and the run
|
||||
id was not, so `--outbox-dir <d>/inni --run-id ../../X` wrote two levels above the directory the
|
||||
caller named and answered `0`. Separators, a bare `.` or `..`, an absolute prefix, an embedded
|
||||
NUL and the empty string are now refused with exit `3`, the reason named, and no directory left
|
||||
behind. Fixed as a class, because the composition is identical in all seven.
|
||||
- A caller-supplied **name** that carries a path is refused by all seven outbox doors before
|
||||
anything is written. Each writer composes `<out_dir>/<name>-<artefact>.json`; the directory was
|
||||
guarded and the names were not, so `--outbox-dir <d>/inni --run-id ../../X` wrote two levels
|
||||
above the directory the caller named and answered `0`. Separators, a bare `.` or `..`, an
|
||||
absolute prefix, an embedded NUL and the empty string are now refused with exit `3`, the reason
|
||||
named, and no directory left behind. The class is every caller-supplied value that reaches a
|
||||
file name, not one flag: `write-outbox` composes `<run_id>-<approach_id>`, and
|
||||
`--approach-id a/../../../X` escaped the same way through the other half of that stem. Both go
|
||||
through one rule.
|
||||
- Containment as the last link: a composed artefact path that does not resolve **under** the
|
||||
output directory is refused, in `outbox` itself, where all eleven compositions are built and
|
||||
before the directory is created. The string rule above lives in the door, so this one covers the
|
||||
callers that never pass a door - the run path hands its own `--run-id` straight to these writers
|
||||
- and the next value someone interpolates into a file name.
|
||||
|
||||
### Fixed
|
||||
- `--stop-reason` being required is now guarded by a test rather than only by prose. The rule is
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue