Address files by workspace path and return numbered text from read and edit

Draft
VA
18h ago
+4807-2577

Path-only read and edit replace the model-facing FileRef contract that blocked live finding F5. The shared executor derives stale-edit authority from successful durable tool results, and the line-window reader hashes and validates the full file while retaining only the selected lines.

Problem

Models cannot invent authenticated volume/generation/hash references. Reads and edits exposed those internal references, and the former observation reconstruction repeatedly reloaded every preceding result. A selected large line could also allocate before its budget was admitted.

Design

  • read accepts {path, offset?, limit?} and renders numbered text. edit accepts {path, old_string, new_string, replace_all?}. Internal canonical results retain the exact FileRef; model projections expose text.
  • Path reads pass through the single owner-bound authorization/resolution path. Edits compare the latest successfully observed version and publish with an exact-generation fence. Failed calls never advance authority.
  • Each turn exclusively owns its observation fold. Calls borrow it mutably and continue from its journal cursor; a resumed turn reconstructs it from durable records. There is no shared fold lock or replace/take window.
  • Selected-window growth claims storage, allocation and copy work on the original ledger before growing the buffer. One streaming scanner validates UTF-8 across chunk boundaries and hashes the complete file.

Deletions

Removed model-facing FileRef/byte-range arguments, e2e reference seeding, repeated observation reconstruction, and the fold mutex. Net diff against the current merge base: +4,791/-2,575 lines (+2,216), including regenerated contracts, fixtures and tests.

Decisions

  • Successful ToolCompleted records are the sole observed-version authority. A new turn has its own fold; a restart reconstructs it from the journal.
  • The new executor::tests::observed fixture now binds an admitted task context. Tool authority alone did not enter the production observation path. Successful fixture runs must also return their expected final answer.
  • Main-baseline failures in bundle::tests, core::authority::effect_root_tests and the recorded baseline/flake list belong to main-green. They are not counted as #895 regressions and are not rerun by the focused gate.
  • No new concurrency primitive replaces the deleted mutex. Exclusive ownership makes concurrent replacement of a turn's fold impossible.
  • A private publication descriptor authenticates its original immutable payload. The shared metadata selector uses the SDK unchanged-payload check; a raw editor or shell overwrite falls back to a new descriptor without invalidating historical pinned reads.
  • An initial lazy checkout read promotes only the requested path. It preserves unrelated source files as lazy and does not republish an already authored path.
  • Typed model-visible refusals remain a merge prerequisite through #899; no second error-settlement path is introduced here.

Guarantee

  1. Class: B/E (stale or lost observed authority), F/H (unadmitted allocation and repeated history work), K (model-facing identity and split UTF-8). The shared authorization path, exact publication fence, turn-owned cursor fold, preclaimed growth, and text-only tool schemas remove the duplicate paths that caused these defects.
  2. Proof: exact journal payload-load assertions cover 0/50/100 calls and repeated folds; resetting the production fold restores the redundant work and violates the same count. Reopen and failed-read controls preserve successful-result authority. Shrinking window/UTF-8 properties compare the production scanner with an independent whole-input oracle. A production append mutant allocates before admission and is detected by the denial oracle; a discarded-carry mutant fails the UTF-8 oracle. The line_window fuzz target and checked-in malformed/truncated/split corpus passed 200,000 runs in 3 seconds on Linux GNU. The added GraphCoder subprocess plus HTTP Responses scenario exercises read/edit/read, physical checkout publication and reopen; it passed at 1b8f2f5b6 in 1.354s. New shrinking SDK-transaction and lazy-source properties cover stale metadata, path pinning and repeated reads, with production mutations that restore both defects.
  3. Entry points: default read/write/edit/patch result projections; owner-bound project and mounted-volume path resolution; ordinary and resumed stock-tool dispatch/reconciliation; complete-file hash/range checking; line-window buffer growth; the real CLI and HTTP provider path. Existing scenario assertions are retained.
  4. Gaps: READ-errors remains blocked on integration with #899's typed model-visible refusals. This is a merge prerequisite, not a follow-up. The PR remains draft while that gap is open. The PR's own proof does not wait for the separately owned DST suite.

Validation

  • Previously reviewed focused suites: units/properties 20/20 (0.045s), default tools 17/17 (0.078s), portable integration 7/7 (0.099s), read scenarios 24/24 (1.106s), edit scenarios 23/23 (1.295s), bash 14/14 (0.702s), diff 9/9 (0.200s), oracles 2/2 (0.192s).
  • Production line_window fuzz: 200,000 runs, 3s, Linux GNU. Scanner implementation unchanged since that run.
  • At 8ac379cae: Windows GNU harness --lib --tests passed in 5m02s. The lib run exposed the new observation fixture's missing task context and one complete-UTF-8 fixture expectation; both are fixed here. Known main failures are excluded using Q:/lanes/main-gate/1a4eff552.log and Q:/lanes/flakes.txt.
  • Observation regressions: 3/3 passed (0.158s), including exact payload-load counts and the production reset control. Earlier Windows GNU harness and GraphCoder checks passed; these do not substitute for the current-head check.
  • The stock path probe exposed an initial lazy source read returning NotFound before any edit. Signed head 1b8f2f5b6 fixes requested-path promotion and includes its shrinking property and production negative control. The current-head focused Linux gate passed: 23 tests, each suite below 2.1s; Windows GNU harness and GraphCoder checks passed in 6m26s and 3m01s. No broad baseline suites are rerun.

The live CLI/provider tier would have caught F5 before merge; prior tool tests supplied authenticated references internally and bypassed the model-facing contract. The new real CLI/HTTP scenario uses only path/text arguments.
Current-head gate: buildbox job 1792327583915-1751131, rc=0. Stock path tools 2.016s; source pinning 1.396s; omitted-promotion control 0.092s; publication identity 0.008s; reads 9/9 in 0.009s; ranges 8/8 in 0.895s; native overwrite 0.258s; real CLI/HTTP path tools 1.354s. Known main-baseline failures were not rerun.