The latency wall is document-lifetime, not one sitting

Review found the mitigation attached to the last landing reading the wrong
code path. EditorSession::open does start with an empty applied log, but that
is the score-only probe constructor. The savable-document path is Ruling B's:
reopen is full replay, stored envelopes load as a committed partition, and
materialization reduces committed plus session operations together. Nothing
resets the depth this bench varies until the checkpoint and pruning machinery
assigned to T4b can write a new canonical_base.

So consequence (e) is withdrawn rather than corrected in place. The ~4,500-edit
wall is a budget on a document's whole accumulated history, and there is no
session reset to lean on -- neither as reassurance about the number nor as
support for the sequencing argument, which rests on paint dominance and does
not need it. T4b's trigger is correspondingly firmer than it read yesterday.

Also: two comments still described the gated core portion as reduce plus
engrave, from before envelope construction was added as a third stage. The
sum they document has included it since the last landing.

Verified in an isolated worktree at HEAD rather than in the working tree,
which still carries the genesis tranche's in-flight work: fmt clean, clippy 0
with and without golden-gate, gate OK with every verdict unchanged (the edits
are documentation only).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RSX4zSLgKvtiXaPjnMqLGz
This commit is contained in:
Levi Neuwirth 2026-07-28 16:27:59 -04:00
parent 986c9cc5a1
commit 4a4988ce88
2 changed files with 27 additions and 20 deletions

View File

@ -81,13 +81,15 @@
//! depth; `engrave`, `scene-build`, and `paint` track score content. Reading //! depth; `engrave`, `scene-build`, and `paint` track score content. Reading
//! paint's dip at 10,000 as a scaling win would be a mistake. //! paint's dip at 10,000 as a scaling win would be a mistake.
//! //!
//! **Depth is per session, not per document.** `EditorSession::open` starts //! **Depth is document-lifetime, not per session.** The score-only
//! with an empty `applied` log (`editor-core/src/lib.rs`), so reopening a saved //! `EditorSession::open` does start with an empty `applied` log, but that is
//! score resets the depth this bench varies: the reduced score becomes the new //! the probe path, not the savable-document path: under Ruling B
//! pristine base. The wall below is therefore a budget on **one sitting**, not //! (`spec/PLAN_EDITOR_APP.md`) reopen is **full replay** — stored envelopes
//! on a document's lifetime — which is what keeps a four-figure number from //! load as a committed partition and materialization reduces committed +
//! being catastrophic. It is still reachable: note entry mints one operation //! session operations together. Nothing resets the depth this bench varies
//! per note. //! until the checkpoint/pruning machinery assigned to T4b exists to write a
//! new `canonical_base`. So the wall below is a budget on a **document's
//! whole edit history**, and note entry mints one operation per note.
//! //!
//! **The honest limitation:** no orchestral-scale score fixture exists in the //! **The honest limitation:** no orchestral-scale score fixture exists in the
//! testkit (the largest are three staves × ten measures), so the engrave and //! testkit (the largest are three staves × ten measures), so the engrave and
@ -146,8 +148,8 @@ struct ScalePoint {
criterion_time: Option<Duration>, criterion_time: Option<Duration>,
} }
/// THE STAGE TABLE. Budget: the core's portion (reduce + engrave) within /// THE STAGE TABLE. Budget: the core's portion (envelope construction +
/// 16.7 ms, `req:perf:single-system-edit-latency`. /// reduce + engrave) within 16.7 ms, `req:perf:single-system-edit-latency`.
/// ///
/// Measured, dev profile, 2026-07-28, `--features golden-gate`, on a /// Measured, dev profile, 2026-07-28, `--features golden-gate`, on a
/// **session-shaped log** (see the module note — the first published table used /// **session-shaped log** (see the module note — the first published table used
@ -175,7 +177,7 @@ struct ScalePoint {
/// logs of equal length are not equal work.) /// logs of equal length are not equal work.)
/// 2. **The frame budget breaks between 3,000 and 5,000 edits** — 9.11 ms /// 2. **The frame budget breaks between 3,000 and 5,000 edits** — 9.11 ms
/// (55%), 12.99 ms at 4,000 (78%), then 17.84 ms (107%). Call the wall /// (55%), 12.99 ms at 4,000 (78%), then 17.84 ms (107%). Call the wall
/// ~4,500 in one sitting, on a dev box rather than the reference hardware /// ~4,500 edits of document history, on a dev box rather than the reference hardware
/// profile and at median rather than the requirement's p99, so treat it as /// profile and at median rather than the requirement's p99, so treat it as
/// an order of magnitude rather than a threshold. /// an order of magnitude rather than a threshold.
/// 3. **`engrave` is flat and small** — 260327 µs at every depth, because the /// 3. **`engrave` is flat and small** — 260327 µs at every depth, because the
@ -553,7 +555,8 @@ fn criterion_measurements(criterion: &mut Criterion, quick: bool) {
group.finish(); group.finish();
} }
/// The budget-gate side. Gates the **core's portion** (reduce + engrave) against /// The budget-gate side. Gates the **core's portion** (envelope construction +
/// reduce + engrave — all three the requirement names) against
/// `req:perf:single-system-edit-latency`; prints the product-layer stages as /// `req:perf:single-system-edit-latency`; prints the product-layer stages as
/// attributed measurements with no budget attached. /// attributed measurements with no budget attached.
fn budget_gate(quick: bool) -> Vec<budget::GateReport> { fn budget_gate(quick: bool) -> Vec<budget::GateReport> {

View File

@ -565,15 +565,19 @@ spike decides it, bounded by these recorded criteria:
work plus ~130 µs of SVG serialization**, so a direct-IR canvas avoids work plus ~130 µs of SVG serialization**, so a direct-IR canvas avoids
2.34 ms at depth 100 = **83% of the full per-edit pipeline, 99.8% of the 2.34 ms at depth 100 = **83% of the full per-edit pipeline, 99.8% of the
render path alone** (both denominators stated; an unqualified "98%" was render path alone** (both denominators stated; an unqualified "98%" was
supported by neither); (e) **depth is per session, not per document** supported by neither); (e) **the measured depth is document-lifetime, not
`EditorSession::open` starts with an empty applied log — so the wall is a per session** — **Ruling B** (below) makes reopen *full replay*: stored
budget on one sitting, though note entry mints one operation per note. envelopes load as a committed partition and materialization reduces
**Sequencing: T4 before T4b still stands** — the canvas removes what committed + session operations together. Nothing resets the depth until the
dominates a session's first ~1,000 edits and is the architecture later checkpoint/pruning machinery assigned to **T4b** can write a new
tranches build on — **but the two are no longer comfortably separated**, and `canonical_base`. There is no session-reset mitigation to lean on, and note
T4b's trigger is ~4,500 edits in a sitting rather than the ~10,000 this entry mints one operation per note. **Sequencing: T4 before T4b still
bench's first, context-free version reported. The bench watches for it as an stands** — the canvas removes what dominates a document's first ~1,000
`Xfail` row at depth 5,000. edits and is the architecture later tranches build on — **but the two are
no longer comfortably separated**, and T4b's trigger is ~4,500 edits of
accumulated history rather than the ~10,000 this bench's first,
context-free version reported. The bench watches for it as an `Xfail` row
at depth 5,000.
3. **Text pipeline (hard criterion):** shaping, font fallback, bidi/complex 3. **Text pipeline (hard criterion):** shaping, font fallback, bidi/complex
scripts, and metrics consistent between interactive canvas, SVG/PDF scripts, and metrics consistent between interactive canvas, SVG/PDF
export, hit testing, and the accessibility tree. A stack with no credible export, hit testing, and the accessibility tree. A stack with no credible