Skip to content

v0.2.55.0 feat: a saved server history reads back as a Server replay, and two windows no longer overwrite each other's learning material (Cycle 0059 pt2) - #149

Merged
ryota-murakami merged 19 commits into
mainfrom
codex/cycle-0059-pt2
Oct 28, 2026
Merged

ryota-murakami merged 19 commits into
mainfrom
codex/cycle-0059-pt2

Conversation

@ryota-murakami

@ryota-murakami ryota-murakami commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor
{
  "schema_version": 1,
  "pr": 149,
  "head": "acd8d01f3882305856041c9e2a47b38459ac10fb",
  "version": "0.2.55.0",
  "base": "main",
  "gate": {
    "tests": {
      "pass": 8085,
      "fail": 0,
      "skip": 10
    },
    "test:package": {
      "pass": 1083,
      "fail": 0,
      "skip": 10
    }
  },
  "session_kind": "interactive",
  "pregate": "pass @4eabb3cef95d (6 checks, current for acd8d01f3882)",
  "issues": {
    "fixes": [],
    "refs": [],
    "flakes": []
  },
  "docs": {
    "status": "current",
    "scope": "AGENTS.md, CHANGELOG.md, PRODUCT_GOAL.md, README.md, extension/README.md, extension/skills/codebook/SKILL.md, the v9 PNG; base a16c28c4 to the candidate"
  },
  "review_loop": {
    "passes": 1,
    "blocking_found": 0,
    "deferred": 0,
    "noted": 0,
    "fixed": 0,
    "scope": "frozen",
    "dispatches": {
      "specialist": 6,
      "red-team": 1
    }
  }
}

Summary

A learner who explained their own Node server with /codebook cannot come back to that explanation once the server stops. Cycle 0059 (Issue 147) fixes that in three pull requests. The first (PR 148) laid the storage. This second one reads a saved server history back, so the third can record into it during the run and turn Save learning replay on for server runs.

A saved server history now shows in Saved studies as a Server replay, led by its learning title, request line and response status. It opens in the replay composition, with the recorded request, output and response in the Application pane, the executed source and the recorded debugger state at each stop, Source and debugger not recorded at this moment. between stops, and one transport. The chat reads it through codebook://node-history, with a lean events list whose pages stay pinned while a recording grows, a detail resource per entry and the three verdicts. Nothing in the product writes a server history yet, so learners cannot reach one in this version.

One change is reachable today. Two editor windows saving the chat's learning material for the same test replay used to be able to overwrite each other. Now the material is read, checked against its revision and written under the storage lock, so one save lands and the other gets the revision conflict.

Blast radius

The Server replay reuses the test replay's select, supersede and commit path through an adapter, so every test replay and browser replay runs through code this PR touched (the playback controller, the Application document, the Study pane, reader positions). That is safe because the existing replay suites pass with no edit to their files and branch on a profile that only server histories set (script ran: pnpm --dir extension test, 8095 tests, 0 failures; the five Reader DOM checks pass).

Test Coverage

CODE PATHS                                              USER FLOWS
[+] readServerHistoryResource.ts                        [+] Saved studies
  ├── [★★★] catalog row, three verdicts, capped lists     ├── [★★★] row: title, request line, status, Partial with +n more
  ├── [★★★] lean events, `through` pin, 16 pages          ├── [★★★] two replays of one route told apart
  ├── [★★★] detail stop/response, NOT_FOUND               ├── [★★★] other window recording shows Recording
  └── [★★★] INVALID_REFERENCE cursor                      └── [★★★] delete refused in server words
[+] assertNodeLearningCitations / material under lock   [+] Server replay
  ├── [★★★] concurrent saves, one wins (server + test)    ├── [★★★] open, no-stop history, damaged prefix, still recording refused
  ├── [★★★] cross-window save visible                     ├── [★★★] stops and events, seek and back, 4A at non-stop moments
  ├── [★★★] wrong citation → INVALID_REFERENCE + nearest  ├── [★★★] request/response regions per moment, server words
  └── [★★★] save racing a Trash move                      └── [★★★] understanding and playhead after reopen; no request sent
[+] replay model / presentation / adapter / words  [★★★] six dedicated files + workspace tests
[+] unreadable profile folder isolation            [★★ ] serverHistoryRoutingFindings
[+] interrupted and recording verdicts             [★★★] nodeServerHistoryInterrupted

COVERAGE: 28/28 paths tested (100%) | QUALITY: ★★★:26 ★★:2 | GAPS: 0

Tests: 13 new test files on the branch (counted before this audit)
Coverage: 100% value-weighted (100% including 0 weakly covered paths)
Test value: 0 tests written, 0 rejected by the authoring gate, 0 existing tests extended, 0 paths weakly covered (weak = ★, gate-failing or unrated).
Tests ran: tests count unavailable (receipt); the runner's own summary on the final tree reads 8095 tests, 8085 pass, 0 fail, 10 skipped.

Pre-Landing Review

One pass over the whole diff (6,846 lines): core checklist, six specialists (testing, maintainability, security, performance, simplification, state-machines), the red team, Codex's structured review (codex review --base origin/main), then the native adversarial pass and a Codex adversarial challenge. No critical finding; the pass converged with no edits. Eleven informational findings were answered Skip under the repository rule for feature cycles and are tracked on Issue 147 as pt3 tasks (each to be fixed with a test that fails without its fix). The most important of them are about the truth of a recorded moment and come from Codex reproductions. The request region decides "sent" from the whole journal, so a moment before the send mark already reads sent. An interrupted unsealed history shows only the generic no-seal reason. The timeline's end after the last event cannot be reached. No server history exists in the product before pt3, so none of them is reachable today.

REVIEW_LOOP: passes=1 blocking_found=0 deferred=0 noted=0 fixed=0 scope=frozen dispatches=7

Gate edits: 18 listed, 3 read, 0 findings — 0 kept, 0 restored, 0 open

Outside review: Codex structured review of the whole diff completed with P2 findings only, no P0 or P1. The Codex adversarial challenge completed with two P2 findings: the save route still parses content with the test-profile schema, so server citations cannot be saved through the tool until pt3 publishes it, and the unreachable timeline end. Both are on the pt3 list.

Local reviews before /ship (repository rule): CodeRabbit CLI 0.9.1 on the range (--committed --base-commit a16c28c4 -c .coderabbit.yaml, included reviews, no credits) completed with 2 findings (53 files); open-code-review-delegate reviewed 42 of 42 reviewable files (11 default exclusions, all new test files) with 2 medium and 8 low findings. All twelve were fixed before /ship, findings 1 to 10 with red-first tests. Hosted CodeRabbit is off for this repository (.coderabbit.yaml reviews.auto_review.enabled: false); nobody asked it to review this PR.

Review notes

Below the blocking floor (advisory, informational, test-gap or wording items); recorded here and not fixed in this PR.

  • INFORMATIONAL extension/src/utils/projectServerApplication.ts:65 request claim uses journal-wide send/withdraw flags, so a moment before the send mark shows Request sent by Codebook (reproduced by Codex) — MULTI-SOURCE CONFIRMED (core + codex)
  • INFORMATIONAL extension/src/utils/presentServerHistory.ts:41 an interrupted unsealed history shows only the generic no-seal reason and drops the evaluated capture reasons such as an unreached declared stop (reproduced by Codex)
  • INFORMATIONAL extension/src/utils/presentServerHistory.ts:18 wordServerCaptureReason re-implements wordNodeCaptureReason and drops its surrogate-safe length cut, so a long server reason is uncapped
  • INFORMATIONAL [ADVISORY] extension/src/utils/projectServerApplication.ts:188 indexServerOutput is unused outside tests
  • INFORMATIONAL extension/src/studyWorkspace.ts:13660 inReplayWords swaps wording by replaceAll('test replay','server replay') on inline sentences
  • INFORMATIONAL extension/src/studyWorkspace.ts:13563 serverReplayViews adds ~70 lines of projection/memo logic duplicating the test path in studyWorkspace.ts
  • INFORMATIONAL extension/src/studyWorkspace.ts:12232 as const on a profile literal
  • INFORMATIONAL extension/src/nodeTestHistoryStore.ts:1122 material save re-reads and parses the whole journal while holding the cross-window storage lock
  • INFORMATIONAL extension/src/nodeTestHistoryStore.ts:1122 test-profile material save under the storage lock can throw StorageLockHeldError, not mapped to a StudyError
  • INFORMATIONAL extension/src/service.ts:2201 explainNodeHistorySchema parses content with the test-profile schema first, so server-only citations are rejected before the server schema runs (publication is pt3)
  • INFORMATIONAL extension/src/studyWorkspace.ts:9726 close drains only the test store's reader-position writes; a server history's position write can outlive the close

Exploratory QA

Functional surface, probed through the repository's own test files with node --test on the compiled extension. The success path opens a saved server history as a Server replay, moves through stops and events, seeks and comes back, persists understanding and the playhead, and checks that no request is sent and no process is started: 17 of 17 passed. The riskiest edge is the MCP read contract an agent depends on: pinned pages while entries append, the lean list, detail and verdicts. It passed 7 of 7. Findings: none. Limits: no native editor check runs in pt2; the cycle's native trial N59 (VS Code and Cursor) runs on pt3.

Design Review

No design review ran in /ship (the change is behind the server replay screen, which learners cannot reach before pt3). The Server replay reuses the test replay layout with server words; the Reader DOM case in study-bootstrap-qa.mjs pins its words, accessible names, response states, clamping and the explanation arriving while open. N59 compares it with image region 2 on pt3.

Eval Results

No prompt-related files changed — evals skipped.

Scope Drift

Scope Check: CLEAN. Intent: Cycle 0059 pt2, the read path for saved server histories. Delivered: that, the cross-window material lock the plan requires for both profiles, the four pt1 review findings assigned to pt2, and shard timings for the new test files.

Plan Completion

Plan: the plan /autoplan approved for Cycle 0059 (Issue 147 body and its pinned comment), audited for the part this PR owns (tasks 6 read parts, 7 and 8, tests E5 and E6, the four pt1 findings assigned to pt2). Result: 30 items, 28 done, 1 changed, 1 partial, 0 not done.

  • Read resources: listing, lean events pinned by through, per-entry detail, three verdicts with capped lists, INVALID_REFERENCE citations
  • Cross-window material lock under the storage lock (E6: one conflict, shows everywhere, no resurrection after Trash)
  • Library row led by learning title with request line, status and first reason +n more (CHANGED: deletion refused in server words, matching test replays, which cannot be deleted from Saved studies either; recorded on Issue 147)
  • Replay model, Application pane, server replay screen decisions, UI adapter seam
  • pt1 findings: interrupted history reads capture-incomplete; writer state and request-sent tests; mask tests
  • PARTIAL: the incremental scan keeps unstored-source facts (tested; the auditor could not confirm the change's location from the diff alone; it is in nodeServerStorageDescriptor.ts)
  • Moved pt1 items: other-window delete refusal, 16-page events bound test
  • E5 replay model tests (sequences, same-time hits, late end, storage-only playhead, switch race, no request sent)
  • Task 7 and task 8 workspace tests; Reader DOM case in study-bootstrap-qa.mjs

Acceptance edits: baseline unavailable (plan is not tracked in this repository).

Verification Results

Executed in this ship: pnpm --dir extension test PASS (8095 tests, 0 failures), pnpm --dir extension test:package PASS (1093 tests, 0 failures), typecheck, lint, health:static, dupes, dead-code, format:check PASS, pre-gate preflight PASS (secrets scan: 6846 added lines clean), the five Reader DOM checks PASS (run by the implementer on the pre-fix tree and inside the gate below). Still to run before merge: required CI, the exact-HEAD gate pnpm --dir extension gate, and the local CodeRabbit CLI on the final range.

Documentation

Scope: the base-to-working-tree diff of codex/cycle-0059-pt2 (0.2.55.0), covering committed, staged and unstaged bytes. Reviewed CHANGELOG.md, README.md, extension/README.md, AGENTS.md, the bundled SKILL.md and VERSION.

Result: current. The CHANGELOG entry's user-visible behavior (two windows saving the same test replay's learning material get one saved revision and one revision conflict, and a save meeting the lock is refused with the lock's sentence) is stated in extension/README.md. The root README names 0.2.55.0 and the three-part plan. SKILL.md still correctly says server runs are not saved.

Debt: none found.

Test plan

  • pnpm --dir extension test (Node 24.22.1, LANG=en_US.UTF-8, macOS): 8095 tests, 8085 pass, 0 fail, 10 skipped
  • pnpm --dir extension test:package: 1093 tests, 1083 pass, 0 fail, 10 skipped
  • pnpm --dir extension typecheck, lint, health:static, dupes, dead-code, format:check: exit 0
  • gstack-pregate --stage preflight --allow-repo-commands: pass, 6 checks, secrets scan clean
  • Required CI on this head
  • Exact-HEAD gate pnpm --dir extension gate on this head
  • Local CodeRabbit CLI on the final range

Refs Issue 147 (Cycle 0059; this PR is part 2 of 3 and closes nothing).

🤖 Generated with Claude Code

ryota-murakami and others added 18 commits October 28, 2026 15:13
…plete, and a recording reports a source it could not store (Cycle 0059 pt2)

Also pins the writer's sealed, abandoned and seal-failed states, a second or early request-sent mark, and the request mask's undecodable name and composition.
…orage lock, cited by request, stop, output and response (Cycle 0059 pt2)

One learning-material codec per profile; two windows saving one revision get one success and one conflict, and a save racing a Trash move leaves no folder.
…uest line and status, and refuses to delete one in server words (Cycle 0059 pt2)
…ents as a lean pinned list with per-entry detail, and state the three verdicts (Cycle 0059 pt2)
…ication pane projects its request, response and output regions (Cycle 0059 pt2)
…heir participants and steps schemas, and the server Application view shares the output cut lines (Cycle 0059 pt2)
…pane's pinned refusal options stay as they were; record timings of the new test files (Cycle 0059 pt2)
…eplay's select, supersede and commit path, with the server catalog on the Study pane and the Application document (Cycle 0059 pt2)

A server history is read once into its replay model and presented as a test-shaped view of learner events; the Application pane gets its two fixed request and response regions, the debugger thread and the source placeholder say server, and a saved playhead on a storage-only entry restores the nearest earlier event.
…tes, clamped request path and the explanation arriving while it is open (Cycle 0059 pt2)
…trols and words its reasons, and a stop whose source was too large says why; a bidirectional control in a doc example is written as an escape (Cycle 0059 pt2)
…ing, so the shared section padding no longer makes them needlessly tall (Cycle 0059 pt2)
…chema, so no cast hides a wrong reference (Cycle 0059 pt2)
… replays, a server study's learning material is saved in the server store, and a test history's event-detail routes answer as unknown resources (Cycle 0059 pt2)
…use server words and never the test store; the request region shows no request before its entry; the response region shows only a no-response reason; the body cut note needs a real cut; the pane name strips controls; an unreadable profile keeps its earlier catalog (Cycle 0059 pt2)
…revision and one conflict; the root README names 0.2.55.0
Co-Authored-By: Claude <noreply@anthropic.com>
@ryota-murakami

Copy link
Copy Markdown
Contributor Author

Local CodeRabbit CLI on the final range (repository delivery rule; hosted CodeRabbit stays off)

  • Command: coderabbit review --agent --committed --base-commit a16c28c4 -c .coderabbit.yaml (CLI 0.9.1, included reviews, no credits).
  • Source cut: a16c28c4..acd8d01f, this PR's head. Completed; 63 files reviewed.
  • Result: 5 findings, none critical.
    • Minor, raised twice (extension/src/ui/studyHtml.ts:2627): when Saved studies holds only server histories, the waiting line reads "no replay" instead of "choose a replay".
    • Trivial: three duplicated test helpers (VERDICTS, modelOf, viewAt; the harness accessors) could move to shared test utilities.
  • Disposition: under the feature-cycle rule these are not fixed in this PR. They are tracked on Issue 147 for pt3 of this cycle, each with its fix and a test.

… the measured health stays under its CRAP bound
@ryota-murakami

Copy link
Copy Markdown
Contributor Author

Post-/ship fix: measured health (gate check 14 and the Fallow CI job)

The exact-HEAD gate on acd8d01f failed only at 14-health, and the Fallow CI job failed for the same reason. One new function in this PR was above the measured CRAP bound of 30: applyServerRegions in extension/src/utils/installNodeTestOutput.ts, at cyclomatic 13 and CRAP 49.5. It runs in the webview, so the Node suite's coverage barely reaches it.

The fix is 56997de3. It splits the function into one request-region update and one response-region update, with the same texts, the same hidden states and the same order. No baseline was re-saved.

The fix was verified locally:

  • typecheck, lint, health:static and format:check exit 0.
  • 46 focused server-replay, Study pane and Application tests pass.

Still running on the new head 56997de3: the gate, required CI, and the local CodeRabbit CLI on the fix range. The ship receipt in the body still names acd8d01f. The reviewed code is unchanged apart from this split.

@ryota-murakami
ryota-murakami merged commit 2b437b0 into main Oct 28, 2026
24 checks passed
@ryota-murakami
ryota-murakami deleted the codex/cycle-0059-pt2 branch October 28, 2026 09:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant