From 16f40314fd7fc88fa5cd451981915be60e722bcf Mon Sep 17 00:00:00 2001 From: Edward Langley Date: Fri, 9 Oct 2026 22:23:59 -0700 Subject: [PATCH] docs(context): act on the adversarial review of the repo-map split - AGENTS.md: "Three files" is now "These files"; the table lists five. - Digests 43 and 45 regain the traps the review found missing. - protocol.md and formula-and-io.md cite file-inventory.md for the Wasm appendix and the inventory, which moved there. Co-Authored-By: Claude Sonnet 5.5 --- AGENTS.md | 2 +- context/code/formula-and-io.md | 2 +- context/code/protocol.md | 2 +- context/repo-map.md | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 845b1507..8f0431f9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -151,7 +151,7 @@ that costs to get right. Everything in it was learned by getting it wrong first. ### Who owns what -Three files are **orchestrator-only**, and the rule exists because they are +These files are **orchestrator-only**, and the rule exists because they are guaranteed conflicts — every agent has a reason to touch them and they merge badly: diff --git a/context/code/formula-and-io.md b/context/code/formula-and-io.md index 9a8b88ad..7c7da5d8 100644 --- a/context/code/formula-and-io.md +++ b/context/code/formula-and-io.md @@ -24,7 +24,7 @@ over `unescape_pipe_body`. Before improvise-i2m5 there were **three** copies and they had drifted, over the keyword rule below. **`improvise-io` no longer has one** — its -`persistence/quoting.rs` is deleted. `context/repo-map.md`'s file inventory +`persistence/quoting.rs` is deleted. `context/file-inventory.md` kept claiming io "still has its own unguarded copy" long after the deletion — it was corrected in wave 1, but any *other* doc or comment still saying so is wrong, and that is the shape this particular fact goes stale in. diff --git a/context/code/protocol.md b/context/code/protocol.md index 30f4ec7d..e9b8bd2c 100644 --- a/context/code/protocol.md +++ b/context/code/protocol.md @@ -902,7 +902,7 @@ The feature is on for **every workspace crate with a normal dependency on serde_json** (improvise-dz8c). Each crate's own manifest names it, because each build is made from one crate alone: the `wasm` CI job and `wasm-pack` invoke per crate, and feature unification cannot reach across separate invocations -(`context/repo-map.md`, `## Wasm`). Enabling it in one crate and relying on the +(`context/file-inventory.md`, appendix "Wasm"). Enabling it in one crate and relying on the others to inherit it works in `cargo test` and nowhere else. **Why "can parse" and not "parses a frame".** The first version of the rule diff --git a/context/repo-map.md b/context/repo-map.md index b967a21f..7a64ddf9 100644 --- a/context/repo-map.md +++ b/context/repo-map.md @@ -205,9 +205,9 @@ the incidents and the ticket ids.** Read the long form of every gotcha your diff 40. **A batch's basis is three tiers** (`document_generation`, `layout_version`, `record_versions`); the unit is the record; lower tiers are *observed*, not read off the effect. 41. **`Storage` is not a VFS;** SQLite was declined on measurement (a second serialization is a second grammar). 42. **Browser render decisions are made in Rust** (`RenderModel`: `editable` from the `CellId` variant, selection reconciled with offsets, `flatten_cat_tree`). `improvise_protocol::frame` is the one envelope pair for both deployments. -43. **A batch carries its basis, and the server publishes it** (`Projection::Basis`). `Basis` has no `Default` or public constructor; `Checked`/`CheckedBatch` make "ignoring the basis" unrepresentable; `Rejection` keeps `RecordGone` / `RecordMoved` / `RecordUnstated` apart. Anti-staleness, not security. +43. **A batch carries its basis, and the server publishes it** (`Projection::Basis`). `Basis` has no `Default` or public constructor; `Checked`/`CheckedBatch` make "ignoring the basis" unrepresentable; `Rejection` keeps `RecordGone` / `RecordMoved` / `RecordUnstated` apart. Anti-staleness, not security. The check is a property of the session door (`apply_command` does not check), and only two of the three tiers hoist per frame — the record tier is asked per command (`records_named`) against the frame's basis. Read gotcha 43 before touching it. 44. **The TUI grid draws from `GridCache`**, which frames it too (`AxisFrame`; width rule `header_level_widths`). Use the one-pass accessors, not per-position scans. `RecordHash` is document-scoped, `AggregateHash` layout-scoped. -45. **One session loop (`Host`), two transports.** Saving is a request frame (`ClientFrame::Save`); dirtiness is raised from the `EffectKind`, observed for data. `impl Storage for Rc` lives in `improvise-io`. `harness/` runs `OpfsFs` for real; Safari is unseen. +45. **One session loop (`Host`), two transports.** Saving is a request frame (`ClientFrame::Save`); dirtiness is *declared* for `WholeWorkbook` and *observed* for `CellData`/`LayoutGeometry` (`MarkDirty` is gone). `impl Storage for Rc` lives in `improvise-io`. `harness/` runs `OpfsFs` for real; Safari is unseen. 46. **The page picks a peer:** `?ws=` → socket, else a module `Worker`. `#status` composes two facts; the first-frame watchdog is per-peer-agnostic. The demo model is built so every cell is a `Record`. 47. **Keys become commands in the browser;** the server must not know the keymap. `GridExtent`, `set_viewport`, `Commands(Vec)`, `resolve::NEEDS_THE_HOST` and the five client rules (`projected_at`, `opened`, `refused_here`, `Step::Declined`, `notify`). 48. **The browser JS is partly executed** (`harness/tests/shell.spec.js`); changes to `web/*.js` belong there. Serialize frames on one tail promise; disarm, don't pre-empt, a watchdog. Evidence headings may be module-qualified (and must be when the leaf collides).