LearnNewsExamplesServices
Frontmatter
id13110
titleMemoize the endurance comparator parse (blank-line incremental)
stateClosed
labels
enhancementaitesting
assigneesneo-opus-vega
createdAtJun 13, 2026, 6:56 PM
updatedAtJun 13, 2026, 8:49 PM
githubUrlhttps://github.com/neomjs/neo/issues/13110
authorneo-opus-vega
commentsCount0
parentIssue13032
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 13, 2026, 8:49 PM

Memoize the endurance comparator parse (blank-line incremental)

Closed v13.1.0/archive-v13-1-0-chunk-2 enhancementaitesting
neo-opus-vega
neo-opus-vega commented on Jun 13, 2026, 6:56 PM

Context

The Harness Endurance Benchmark machinery (#13066, splitting #13076) shipped Subject B — the main-thread comparator — with a full re-parse of the growing source each tick. The #13032 thread flagged this as the open naive-vs-best-practice fairness fork. This leaf resolves it to best practice: the comparator now memoizes its parse, so the cross-subject lag delta isolates the worker-topology variable rather than conflating it with parse strategy. Carved out as a sub so it can Resolve cleanly while #13032 stays open for load-calibration → the verdict.

Release classification: post-release (harness benchmark fairness; non-blocking for v13).

The Problem

A full re-parse per streamed append is O(n²) over a session AND folds Neo's off-thread parser-memoization benefit INTO the measured delta. A falsifier must isolate ONLY the variable under test — where the work runs (main thread vs worker) — or its public claim is contestable. The comparator must memoize its parse the way a competent main-thread streaming renderer would.

The Architectural Reality

  • ai/examples/harnessEndurance/comparator/comparator.mjs — drove applyBlocks(parseMarkdownBlocks(accumulated)) each tick (render was already tail-incremental; parse was not).
  • ai/examples/harnessEndurance/comparator/markdownBlocks.mjs — pure parseMarkdownBlocks(source) → string[].
  • Block boundaries: a blank line is the only boundary a forward-only stream can never un-merge (a partial list item re-merges with the next once it arrives), so settling must be blank-line-granular, not per-block — block-granularity settling corrupts a streamed list.

The Fix

  • markdownBlocks.mjs: add createIncrementalBlocks() — a stateful, delta-fed memoizer that settles blocks before the last blank line once and re-parses only the open region per delta. parseMarkdownBlocks output stays byte-identical (back-compat).
  • comparator.mjs: drive via blocks.push(text) (the delta), dropping the accumulated full re-parse.
  • Unit spec: every-prefix equivalence (incremental === full parse), list-stream regression guard, blank-line settling, empty-delta tolerance.

Acceptance Criteria

  • The comparator memoizes its parse: settled blocks parsed once; only the open region re-parses per delta (bounded by blank-line cadence, not transcript length).
  • parseMarkdownBlocks output is byte-identical to the pre-change implementation (existing specs unchanged + pass).
  • Streaming equivalence proven: incremental output === full re-parse at every prefix (unit test).
  • List-stream regression guarded (a streamed - a / - b stays one <ul>).
  • Benchmark e2e still drives both subjects + the cross-subject delta runner (no harness regression).

Out of Scope

  • Load-calibration, the conclusive cross-subject verdict, and published numbers/methodology — remain #13032.
  • The keystroke→echo / frame-time / task-queue metric layers — remain #13032.
  • Subject A (Neo) changes — none.

Related

  • Parent: #13032 (Harness Endurance Benchmark)
  • Machinery this builds on: #13066 (PR) / #13076 (sub) — the LoadProfile + both subjects + runner
  • Concept: ADR 0020 (learn/agentos/decisions/0020-agent-harness-concept.md)

Live latest-open sweep: checked latest 30 open issues at 2026-06-13; no comparator/memoization/incremental leaf exists. A2A in-flight sweep: no [lane-claim] on this scope (own #13032 sub).

Origin Session ID: 4cc428e3-cf36-4324-8646-1b96cb23fa4a Retrieval Hint: "harness endurance comparator incremental parse memoize blank-line createIncrementalBlocks Subject B fairness"