Repository navigation
v0.2.51.0 feat: the chat explains a repository's own Node HTTP server live, paused in its route handler (Cycle 0057 pt2) - #141
Merged
Conversation
…ecovery, profile, run view and environment hooks (Issue #139) The shared contract the pt2 parts build on (tasks 9–12): - errors.ts: the 13 new codes of task 11 (PORT_UNAVAILABLE, LISTENER_NOT_OWNED, PORT_OWNER_UNKNOWN, RUN_NOT_READY, REQUEST_ALREADY_SENT, REQUEST_NOT_CONFIRMED, NO_PAUSE, LEARNER_PAUSED, SERVER_EXITED, SERVER_NOT_LISTENING, REQUEST_FAILED, REQUEST_TIMEOUT, PAUSE_HOLD_EXPIRED), each with the fix first, its recovery class, side effects, a retry bound and its codebook://help/node-server anchor. - constants.ts: NODE_SERVER_PROFILE and NODE_SERVER_ACTION. - runtime.ts: NodeServerState (the ten states), NodeServerView with its stops, pause, held pause, request, response, failures and in-memory captures, the NodeServerRuntime interface, and the environment's createNodeServerRun and confirmStateChangingRequest hooks (D1, D6, D9, D14 in the Issue's pt2 expectation notes). No caller yet.
… sender and orphan records (Issue #139)
…equest sender, orphan records) into pt2 (Issue #139)
…, state and events through the service (Issue #139)
…ost and real-process tests (Issue #139)
…ams) into pt2 (Issue #139)
… real readiness, listener, peer, request and orphan-record utilities (Issue #139) Integration of parts U and R: ownedNodeServerRun.process.test.ts drops its test-local stand-ins and runs the fixture server through waitForServerReadiness, verifyListenerOwnership (lsof), readListeningPortsOfProcess, readConnectionServerPid (lsof), sendDeclaredRequest and the orphan record functions over an in-memory store; the loop test also asserts the running server's orphan record and its removal at stop. Evidence level 3 (a direct inspector client stands in for pwa-node). 4/4 pass.
…rror channel, confirmation modal and status item (Issue #139)
…elp and status item) into pt2 (Issue #139)
…n, its machine utilities and the window's orphan records (Issue #139) Integration of parts U, R and S: - environment.ts createNodeServerRun: the configured external Node with its version (resolveExternalNode), lazily the VS Code-backed run (createOwnedNodeServerRun) with the product dependencies and U's readiness, listener, connection, request and orphan-record utilities (createNodeServerRunUtilities) bound to the window's workspaceState (an in-memory store when a host gives none); the node-test and node-server factories share one prerequisite and workspace check. - extension.ts: activation hands workspaceState to reapNodeServerOrphans once, with NODE_SERVER_SHUTDOWN_GRACE_MS (TD-7). - The event whitelist keeps the fields the run emits: learner-paused kind and declaredStopIndex, learner-resumed declaredStopIndex, response location, and ready, stop-hit-at-start, pause, capture-budget-exhausted, port-held-by-other, attached and stopped; its text limits move to constants.ts. - nextActions names the continuation continue-server, as the other profiles do. Test changes, each for the integration: nodeServerStatus expects the environment's run factory (S's part had none); nodeServerEvents records the shapes the run emits; nodeServerState expects continue-server. New tests: lifecycle event whitelist and activation reaping (red first on the pre-integration files), resolveExternalNode.
…ofile; the root README names Cycle 0057's delivery (Issue #139) extension/README.md 'Explain a Node HTTP server': what the chat declares, the environment (the server's own .env plus the allowlist, NODE_ENV unset, codebook.nodeExecutable for a newer Node), the one request and its confirmation for POST/PUT/PATCH/DELETE, your own pauses stay yours, what the run reports (responses, REQUEST_FAILED/REQUEST_TIMEOUT never resent, PAUSE_HOLD_EXPIRED), the status bar texts beside 'Learning replay is not available for server runs yet', and the limits. Root README: the delivered version and Cycle 0057's three pull requests.
… lists it (owner rule of 2026-10-27, Issue #139) The Space's VS Code 1.142.0 Copilot picker listed GPT-6.1 Terra (and GPT-6.1 Sol, no GPT-6.1 Luna) on 2026-10-28 JST, so the owner's 2026-10-27 rule moves VS Code trials from GPT6 Luna to GPT-6.1 Terra; each trial still searches the picker and takes GPT-6.1 Luna if it appears.
…han sweep, redact-then-cut response body, bounded content type (Issue #139)
…te path, one oversized event no longer ends the journal, the deadline ends a finished server run normally, and the confirmation modal is joined (Issue #139)
…tside the window, failed continue, unclassified pauses, path hiding, notice handling, peer holders, fact keys) (Issue #139)
…Pid, CodeRabbit r1) into pt2 (Issue #139)
…tsLoopbackConnection (Issue #139) The pre-gate's stray-file check read probeLoopbackPort.ts as a scratch file name. The utility is renamed with its single function; its three callers follow. No behaviour change (28/28 tests of its callers pass).
… the secret scan's assignment pattern; two intentional waits are marked (Issue #139) The Stage 1 pre-gate's secret scan read nine added lines as secret-named assignments with high-entropy values: idempotency keys in tests ('changed-hash', 'run-${index}', ...), isDebugSessionOfRun's 'session' parameter and the debugger's 'token: ++this.nextToken'. The keys become plain words or String(index), the parameter debugSession, and the stop number is taken into 'sequence' first; behaviour is unchanged (250/250 affected tests). The two sleep-then-assert waits in waitForServerReadiness.test.ts are part of their scenarios (a late server start; an abort inside the poll pause) and carry gstack-timing-ok reasons.
…ld; event-type and reaper-poll limits live in constants.ts (CodeRabbit r2, Issue #139) Local CodeRabbit CLI r2 on the pt2 range (5 findings, 2 duplicates): - extension/README.md names that the 300 s pause hold covers a pause of yours as well as a declared stop (PAUSE_HOLD_EXPIRED never resumes it). - EVENT_TYPE_LIMIT_CHARS (128) replaces the literal in the node-server journal and in the node-test journal of service.ts; NODE_SERVER_GROUP_EXIT_POLL_MS (50) in the orphan reaper. - ownedNodeServerRun.process.test.ts reuses tests/utils/freeLoopbackPort. No behaviour change in code.
…d P08 and P07 clones on the Mac, and skipped in CI with its reason (AC 2(c), Issue #139) ownedNodeServerRun.pinnedClones.test.ts runs the real run (CDP debugger stand-in, the real readiness/listener/peer/request/orphan utilities) against switch-time 4f68953 and nsx 502545c7 from CODEBOOK_NODE_SERVER_CLONES (JSON); without it every test skips with "pinned clones and their databases are local-only". Each test checks the clone revision, hits the declared .ts stop with the recorded local, observes the response and frees the group and the port: - switch-time GET /api/healthz: app.ts:54, c.req.path, 200 {"status":"ok"} - switch-time POST /api/auth/sign-in/email (unknown e-mail): db/client.ts:254, values ["nobody@example.com"], 401 INVALID_EMAIL_OR_PASSWORD - nsx GET /api/health, MySQL up: server/routes/health.ts:60, _req.path, 200 - nsx GET /api/health, MySQL stopped by the test and restored: 503 Local run on the Mac (Node 26.10.0 for the targets): 4/4 pass, ~31 s; without the variable 4 skipped. Test support: tests/utils/realNodeServerDependencies.ts (shared with the fixture process test, which now imports it) and generatedPositionOfOriginal.ts (inline source-map lookup). Changed test helper: cdpNodeServerDebugger.ts now binds a .ts stop through the script's inline source map (V8's beforeScriptWithSourceMapExecution instrumentation pause for ESM, scriptParsed for CommonJS), as Part A bound them; the fixture process test still passes 4/4.
…kills a server paused in the request first; each run asks in its own dialog (Issue #139) /ship Step 11, Codex structured review P1 x3 (gate FAIL, fixed under the recommended option): - A stop admitted while the connected peer is verified aborts the request's own signal, so nothing is written; the call answers RUN_NOT_READY. - D14 kill-first also covers a stop the editor reported but whose stack is still being read (NodeServerDebugger.hasUnreportedPause) and a declared stop, or any pause inside the request, that arrives after the stop was admitted. - The window-wide confirmation modal is keyed by the run id and the whole declared request, so a modal an earlier run left open never sends this run's request. Red first: the seven new tests failed on cdc2736.
…, and paused stops, sent requests and dialogs read what is true (Issue #139) /ship pt2 last review round (Step 9 pass 3 capped, Step 11 round 2); every finding fixed under the owner's ship review limit: - D14 v2: a Stop while the declared request is under way ends the group with SIGKILL before the debugger lets go, so a stop the handler reaches during the detach is never resumed (Codex adversarial P1). - The sender counts a request handed to the socket as written when an abort comes after end(), so a Stop never reports "nothing was sent" for bytes that may be on the wire; the node-server.request event is journaled only once the request was written, never for a refused peer. - The VS Code debugger clears a pause on the adapter's accepted resume or a continued event, per thread, not on the request: a rejected Continue keeps the pause current and its unreported stop counted, and a stop resumed while its stack was read is never reported. Only the bound session's stops queued for the run count as unreported (the entry pause and child sessions do not). - Open confirmation dialogs are kept per run and request, so a retry joins its own dialog after another run asked; each names its run. - LISTENER_NOT_OWNED and PORT_OWNER_UNKNOWN recovery covers a refusal at the request (the run still reads ready). - Tests for the kill-first cells, a Stop after the first byte and the content type in the dialog key. Red first: 11 new tests failed on 8257e53.
…overage audit's tests (/ship Step 7, Issue #139)
…rofile checks before the first byte, how a Stop ends the server, and when NODE_SERVER_SOURCE_REFUSED comes (Issue #139)
Co-Authored-By: Claude <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the
|
…, a port the system refuses, an unreadable port and Codebook's own run (gate: pnpm health CRAP on refusalText, Issue #139)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #139 (Cycle 0057, a feature cycle: second of its three pull requests, per Owner decision O1). pt1 (#140) laid the launch parts and the redaction contract; this PR offers the
node-serverprofile through MCP; pt3 adds the bundled skill's server route and the native trial N57 in both editors. Issue #139 stays open for pt3.Summary
A learner who asks how a project's API handles a request could only get a source reading or a browser-page explanation: Codebook ran browser apps and tests, not servers. Now the chat can start the repository's own Node HTTP server under the editor's debugger, send one declared request, pause in the route handler's actual TypeScript source and explain with the live values the learner also sees in the Variables view, then report the response it observed and stop the server.
node [--import <the repository's tsx>] <entry>, passes only an allowlisted environment and never sets the port.debugger;, exception or Pause button is never resumed by Codebook.codebook://help/errorsandcodebook://help/node-server.Blast radius
The profile adds code paths beside the existing
repository-browserandnode-testprofiles; it shares only the service's admission, receipt and status machinery, whose existing browser and test replay suites pass unchanged in the full lane (7,801 tests, 0 fail, run). MCP stays 1.8 (additions only), stored learner data and saved replays are untouched, and the bundled skill stays 1.0.50.Test Coverage
Every new mechanism has host tests (fake editor, DAP, process table, listener tool and clock) and the run loop has real-process tests against a test-only fixture server, with the test's own debugger client standing in for
pwa-node(evidence level 3). The state × call table generates the refusal tests for all ten states and four calls.Tests: 514 → 515 files (+1 new from the coverage audit; every implementation commit carries its own tests)
Coverage: 87% value-weighted (97% including 3 weakly covered paths)
Test value: 6 tests written, 7 rejected by the authoring gate, 0 existing tests extended, 3 paths weakly covered (weak = ★, gate-failing or unrated).
createNodeServerRunUtilities,createMemoryOrphanStore,nodeServerRunDependencies(wiring, covered only indirectly through the environment and real-process tests).Tests ran: tests count unavailable (receipt; the runner summary of the final run reads 7,801 tests, 7,791 pass, 0 fail, 10 skipped)
Pre-Landing Review
Step 9 ran three passes under
review_scope frozenand did not converge (converged:false). Pass 1 (full diff, 6 specialists and a red team) found 13 informational findings, carried as pt3 tasks under the feature-cycle rule. Step 11's first round (native adversarial, Codex adversarial, Codex structured) returned three Codex P1 findings; pass 2 fixed them (8257e534). Pass 3 reviewed that fix and was capped with four untested kill-first state cells and five informational notes. Under the owner's ship review limit every last-round finding (pass 3 and Step 11's second round, including Codex adversarial's P1 that led to D14 v2) was fixed in0f008416; no Critical or Major defect stays open, so no Issue records one.REVIEW_LOOP: passes=3 blocking_found=7 deferred=0 noted=12 fixed=3 scope=frozen
Gate edits: 43 listed, 4 read, 0 findings (4 hunks kept with reasons)
extension/src/extension.ts: the Output line writer catches a disposed channel; the line is also in the run's events.extension/src/ownedNodeServerRun.ts: each catch names its owner (the response promise, a retryable stop, or a recorded orphan record).extension/src/service.ts: the confirmation modal fails closed (no Send, nothing sent) and the release paths report their errors.extension/src/tests/fixtures/node-server/server.ts: the test-only fixture gained routes; nothing was relaxed.Outside review: Codex structured round 1 FAIL (three P1, fixed); round 2 PASS (VERDICT clean, four P2 fixed). Codex adversarial round 1 unavailable (timed out at 540 s; missing coverage), round 2 completed (one P1, fixed).
Review notes
Recorded and fixed after the cap (last round) or carried to pt3 (earlier rounds):
end()reported "nothing was sent"; unreported stops kept for the entry pause and child sessions; a rejected learner Continue clearing a pause; a stale stack token; the request event journaled before the ownership check; the ownership refusals' recovery at request time; one dialog slot.runningTimeLimit's untested cells.Exploratory QA
b40af1e7, the Mac, pinned clones with their databases): 4/4 pass. switch-timeGET /api/healthzpaused atapp.ts:54, 200{"status":"ok"}; sign-in of an unknown user paused atdb/client.ts:254with the e-mail value, 401INVALID_EMAIL_OR_PASSWORD; nsxGET /api/healthpaused athealth.ts:60, 200 with the database up and 503 with it down. Skipped in CI with the reasonpinned clones and their databases are local-only.f697fa1e…cff9e, 0.2.51). The last run asked a new natural question (sign-in with an unregistered e-mail): the chat declared the run on its first attempt, the native dialog named the POST and the run, the learner chose Send, the server paused atapp.ts:65(stop 1 of 2) anddb/client.ts:254(stop 2 of 2, the SQL parameter readable), and the chat explained both stops. After the long pause the app's own 25 s request deadline answered 500; the chat reported that as observed, sent nothing more, stopped the server (port freed, no process left) and labeled its 401 explanation as source-derived.Design Review
No frontend files changed — design review skipped (the status bar text and the native dialog are editor-owned surfaces).
Eval Results
No prompt-related files changed — evals skipped.
Plan Completion
pt2 scope of #139 (O1): tasks 9–12 delivered (run, MCP lifecycle and the state × call table, recovery text and help, status item), N57 step 0 done, task 14's pt2 docs done (CHANGELOG 0.2.51.0, the packaged README section, the root README status). D14 v2 recorded on the Issue before its code. Remaining for pt3: task 13 (skill route), task 15 (N57 in both editors) and the carried findings above.
Issues
Refs #139
Verification Results
Step 8.1 obligations: 9 PASS, 0 FAIL, 0 BLOCKED, 0 NOT RUN.
b40af1e7; the later commits change docs, version lines and tests only).c6641821): PASS.3f1473fb(tree542ef587, clean before and after): 15/15 exit 0.pnpm test7,808 tests, 7,798 pass, 0 fail, 10 skipped; Reader DOM 288 + 55 + 12 + 8 + 26 cases, all pass;pnpm test:package1,081 tests, 1,071 pass, 0 fail, 10 skipped;pnpm healthexit 0 (86 A); context-restore test 9/9./shipand fixed before merge: the first gate run onc6641821failed onlypnpm health:refusalTextinassertNodeServerPortFree.tsscored CRAP 72 with no test reaching it.3f1473fbadds seven tests (every refusal wording, the occupant named or not, Codebook's own run running or stopping); no product code changed.3f1473fb: 23 pass, 2 skipped (hosted CodeRabbit, off by owner decision O6; the main-only split-files job).origin/main..c6641821(round 3) and onorigin/main..3f1473fb(round 4), outcome completed: six minor findings in five subjects, no critical (the help'sNODE_SERVER_SOURCE_REFUSEDrow, the wall-time backstop's message, the CHANGELOG smoke's revisions, the invalid-UTF-8 note at the end of a body, and the README's 10 s stop deadline). Under the feature-cycle rule they are carried to pt3 as Issue tasks.TODOS
No TODO items completed in this PR (the repository keeps no TODOS.md; carried work lives in Issue #139).
Documentation
Scope: The audit covered committed, unstaged and selected content against base 4ff53d2: AGENTS.md, README.md, CHANGELOG.md (0.2.51.0), extension/README.md, plus PRODUCT_GOAL.md, the bundled skill and the v9 PNG, which have no diff against the base. Read-only mode, so I made no edits.
Result: The CHANGELOG 0.2.51.0 entry matches the new README section "## Explain a Node HTTP server". Every user-visible behavior the entry names has a sentence in the packaged README:
codebook.nodeExecutableLISTENER_NOT_OWNEDcheckREQUEST_FAILED,REQUEST_TIMEOUTandPAUSE_HOLD_EXPIREDcodebook_statusThe README recovery-table row for
NODE_SERVER_SOURCE_REFUSEDmatches errors.ts and the throw sites in resolveNodeServerLaunch.ts and resolveNodeServerStops.ts. All three cover the same cases: a missing or outside-the-repositorypackageRoot,entry, stop file or the repository's owntsx. The row's recovery (correct the path or install dependencies, then declare again) is consistent with the errors.ts recovery text. The top-level README "Implementation status" paragraph and the AGENTS.md VS Code model line (GPT-6.1 Terra) are consistent with the CHANGELOG and with the extension version 0.2.51.Debt: None. The skill's server route is the planned pt3 work.
Test plan
gstack-evidence run --label tests -- 'cd extension && corepack pnpm test 2>&1'onc6641821: 7,801 tests, 7,791 pass, 0 fail, 10 skipped (the gate reran the suite on3f1473fb: 7,808 tests, 0 fail)pnpm --dir extension format:check,lint,health:static,dupes,dead-codeafter the last fixes: exit 0CODEBOOK_NODE_SERVER_CLONES=<clones JSON> node --test dist/tests/ownedNodeServerRun.pinnedClones.test.jsonb40af1e7: 4/4 passgstack-pregate --stage preflight --allow-repo-commands: warn (11 medium non-credential findings, all benign test or doc examples)3f1473fb: 15/15 exit 03f1473fb: 23 pass, 2 skippedorigin/main..3f1473fb: completed, minor findings carried to pt3🤖 Generated with Claude Code