From 09277299707a11716cdc154cd9db545c651d179f Mon Sep 17 00:00:00 2001 From: Warren <28354219+jayminwest@users.noreply.github.com> Date: Wed, 10 Jun 2026 09:32:23 +0000 Subject: [PATCH 1/2] Release v0.8.6 --- CHANGELOG.md | 17 +++++++++++++++++ docs/openapi.yaml | 2 +- package.json | 2 +- src/index.ts | 2 +- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b85fda1..75e1bc45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.8.6] — 2026-06-10 + +Comment-only documentation cleanup plus a validation error-message +harmonization from the nightwatch patrol (plan pl-69e1). + +### Fixed + +- **Stale `latent` NOTE** in `src/runs/analytics/insights.ts` removed + after the feature it described landed. +- **Stale `Postgres schema not yet wired` comments** repointed after the + dialect-aware `openDatabase` landed. +- **`four dedicated mutators` miscount** in `src/plot-client/types.ts` + corrected. +- **Validation error phrasing harmonized** across handlers — the + `expected one of` vs `must be one of ...; got` variants now use a + single consistent format. + ## [0.8.5] — 2026-06-09 Comment-only documentation cleanup from the nightwatch patrol (plan diff --git a/docs/openapi.yaml b/docs/openapi.yaml index f6006ed1..b3637781 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -3,7 +3,7 @@ openapi: 3.1.0 info: title: warren HTTP API - version: 0.8.5 + version: 0.8.6 description: >- Auto-generated from `src/server/handlers/index.ts`'s `ROUTE_TABLE`. Run `bun run gen:openapi` to refresh; CI fails if this schema drifts from the handler module. Request/response bodies are diff --git a/package.json b/package.json index 5d0c8789..18bf5a9e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@os-eco/warren-cli", - "version": "0.8.5", + "version": "0.8.6", "description": "Self-hostable control plane for ephemeral cloud agents — spawn sandboxed agents at your GitHub repos, watch them work live, steer them, get a branch back", "type": "module", "bin": { diff --git a/src/index.ts b/src/index.ts index 99db4d11..528f7b62 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,4 +4,4 @@ * `Client` class is deferred to V2 (SPEC §8.3). */ -export const VERSION = "0.8.5"; +export const VERSION = "0.8.6"; From d9f1880d841485119aa4f6a488ef7f3cc3bcae07 Mon Sep 17 00:00:00 2001 From: warren Date: Wed, 10 Jun 2026 09:34:42 +0000 Subject: [PATCH 2/2] chore(warren): seeds state --- .seeds/issues.jsonl | 4 ++-- .seeds/plans.jsonl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.seeds/issues.jsonl b/.seeds/issues.jsonl index 55d9d6cc..035a64c9 100644 --- a/.seeds/issues.jsonl +++ b/.seeds/issues.jsonl @@ -634,9 +634,9 @@ {"id":"warren-9358","title":"Fix src/runs/burrow_config.ts -> src/runs/burrow-config.ts filename in planner.ts comment","status":"closed","type":"task","priority":3,"plan_step_index":2,"description":"\nStep 3 of plan pl-7580.\n\nParent seed: warren-a056 — nightwatch patrol: 2026-06-09\nPlan template: refactor\nPlan approach: Each step is an independent, comment-only fix touching a small set of files; there are no real dependencies between the four fix steps, so they can land in any order as separate PRs. The final Release step is ordered last and blocked by…\n\nRun `sd plan show pl-7580` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n","createdAt":"2026-06-09T09:08:52.347Z","updatedAt":"2026-06-09T09:24:12.449Z","labels":["nightwatch"],"plan_id":"pl-7580","blocks":["warren-f48a","warren-a056"],"closedAt":"2026-06-09T09:24:12.449Z"} {"id":"warren-9d72","title":"Update comments referencing the retired brainstorm/interactive flow","status":"closed","type":"task","priority":3,"plan_step_index":3,"description":"\nStep 4 of plan pl-7580.\n\nParent seed: warren-a056 — nightwatch patrol: 2026-06-09\nPlan template: refactor\nPlan approach: Each step is an independent, comment-only fix touching a small set of files; there are no real dependencies between the four fix steps, so they can land in any order as separate PRs. The final Release step is ordered last and blocked by…\n\nRun `sd plan show pl-7580` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n","createdAt":"2026-06-09T09:08:52.347Z","updatedAt":"2026-06-09T09:31:01.193Z","labels":["nightwatch"],"plan_id":"pl-7580","blocks":["warren-f48a","warren-a056"],"extensions":{"role":"pi","lastRunId":"run_2cwz2pp100m2","lastRunAt":"2026-06-09T09:25:40.442Z"},"closedAt":"2026-06-09T09:31:01.193Z"} {"id":"warren-f48a","title":"Release: run /release per .claude/commands/release.md","status":"closed","type":"task","priority":3,"plan_step_index":4,"description":"\nStep 5 of plan pl-7580.\n\nParent seed: warren-a056 — nightwatch patrol: 2026-06-09\nPlan template: refactor\nPlan approach: Each step is an independent, comment-only fix touching a small set of files; there are no real dependencies between the four fix steps, so they can land in any order as separate PRs. The final Release step is ordered last and blocked by…\n\nRun `sd plan show pl-7580` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n","createdAt":"2026-06-09T09:08:52.347Z","updatedAt":"2026-06-09T09:36:51.283Z","labels":["nightwatch"],"plan_id":"pl-7580","blocks":["warren-a056"],"closedAt":"2026-06-09T09:36:51.283Z"} -{"id":"warren-678a","title":"nightwatch patrol: 2026-06-10","status":"open","type":"task","priority":3,"createdAt":"2026-06-10T09:06:15.162Z","updatedAt":"2026-06-10T09:27:40.120Z","labels":["patrol","nightwatch"],"plan_id":"pl-69e1","blockedBy":["warren-32ce"]} +{"id":"warren-678a","title":"nightwatch patrol: 2026-06-10","status":"open","type":"task","priority":3,"createdAt":"2026-06-10T09:06:15.162Z","updatedAt":"2026-06-10T09:34:42.125Z","labels":["patrol","nightwatch"],"plan_id":"pl-69e1"} {"id":"warren-66ec","title":"Fix stale 'latent' NOTE in src/runs/analytics/insights.ts","status":"closed","type":"task","priority":3,"plan_step_index":0,"description":"\nStep 1 of plan pl-69e1.\n\nParent seed: warren-678a — nightwatch patrol: 2026-06-10\nPlan template: refactor\nPlan approach: One step per finding, ordered independents-first. Steps 1-3 are pure comment fixes (zero test impact). Step 4 harmonizes validation error-message phrasing across handler call sites and must update the exact-string assertions in the…\n\nRun `sd plan show pl-69e1` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n","createdAt":"2026-06-10T09:07:02.542Z","updatedAt":"2026-06-10T09:11:42.011Z","labels":["nightwatch"],"plan_id":"pl-69e1","blocks":["warren-32ce","warren-678a"],"extensions":{"role":"pi","lastRunId":"run_bpfbhg6e0ef1","lastRunAt":"2026-06-10T09:08:42.254Z"},"closedAt":"2026-06-10T09:11:42.011Z"} {"id":"warren-4674","title":"Repoint stale 'Postgres schema not yet wired' comments after dialect-aware openDatabase landed","status":"closed","type":"task","priority":3,"plan_step_index":1,"description":"\nStep 2 of plan pl-69e1.\n\nParent seed: warren-678a — nightwatch patrol: 2026-06-10\nPlan template: refactor\nPlan approach: One step per finding, ordered independents-first. Steps 1-3 are pure comment fixes (zero test impact). Step 4 harmonizes validation error-message phrasing across handler call sites and must update the exact-string assertions in the…\n\nRun `sd plan show pl-69e1` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n","createdAt":"2026-06-10T09:07:02.542Z","updatedAt":"2026-06-10T09:15:55.789Z","labels":["nightwatch"],"plan_id":"pl-69e1","blocks":["warren-32ce","warren-678a"],"closedAt":"2026-06-10T09:15:55.789Z"} {"id":"warren-5453","title":"Fix 'four dedicated mutators' miscount in src/plot-client/types.ts","status":"closed","type":"task","priority":3,"plan_step_index":2,"description":"\nStep 3 of plan pl-69e1.\n\nParent seed: warren-678a — nightwatch patrol: 2026-06-10\nPlan template: refactor\nPlan approach: One step per finding, ordered independents-first. Steps 1-3 are pure comment fixes (zero test impact). Step 4 harmonizes validation error-message phrasing across handler call sites and must update the exact-string assertions in the…\n\nRun `sd plan show pl-69e1` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n","createdAt":"2026-06-10T09:07:02.542Z","updatedAt":"2026-06-10T09:20:20.917Z","labels":["nightwatch"],"plan_id":"pl-69e1","blocks":["warren-32ce","warren-678a"],"closedAt":"2026-06-10T09:20:20.917Z"} {"id":"warren-cda9","title":"Harmonize 'expected one of' vs 'must be one of ...; got' validation error phrasing across handlers","status":"closed","type":"task","priority":3,"plan_step_index":3,"description":"\nStep 4 of plan pl-69e1.\n\nParent seed: warren-678a — nightwatch patrol: 2026-06-10\nPlan template: refactor\nPlan approach: One step per finding, ordered independents-first. Steps 1-3 are pure comment fixes (zero test impact). Step 4 harmonizes validation error-message phrasing across handler call sites and must update the exact-string assertions in the…\n\nRun `sd plan show pl-69e1` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n","createdAt":"2026-06-10T09:07:02.542Z","updatedAt":"2026-06-10T09:27:40.120Z","labels":["nightwatch"],"plan_id":"pl-69e1","blocks":["warren-32ce","warren-678a"],"closedAt":"2026-06-10T09:27:40.120Z"} -{"id":"warren-32ce","title":"Release: run /release per .claude/commands/release.md","status":"open","type":"task","priority":3,"plan_step_index":4,"description":"\nStep 5 of plan pl-69e1.\n\nParent seed: warren-678a — nightwatch patrol: 2026-06-10\nPlan template: refactor\nPlan approach: One step per finding, ordered independents-first. Steps 1-3 are pure comment fixes (zero test impact). Step 4 harmonizes validation error-message phrasing across handler call sites and must update the exact-string assertions in the…\n\nRun `sd plan show pl-69e1` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n","createdAt":"2026-06-10T09:07:02.542Z","updatedAt":"2026-06-10T09:27:40.120Z","labels":["nightwatch"],"plan_id":"pl-69e1","blocks":["warren-678a"]} +{"id":"warren-32ce","title":"Release: run /release per .claude/commands/release.md","status":"closed","type":"task","priority":3,"plan_step_index":4,"description":"\nStep 5 of plan pl-69e1.\n\nParent seed: warren-678a — nightwatch patrol: 2026-06-10\nPlan template: refactor\nPlan approach: One step per finding, ordered independents-first. Steps 1-3 are pure comment fixes (zero test impact). Step 4 harmonizes validation error-message phrasing across handler call sites and must update the exact-string assertions in the…\n\nRun `sd plan show pl-69e1` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n","createdAt":"2026-06-10T09:07:02.542Z","updatedAt":"2026-06-10T09:34:42.125Z","labels":["nightwatch"],"plan_id":"pl-69e1","blocks":["warren-678a"],"closedAt":"2026-06-10T09:34:42.125Z"} diff --git a/.seeds/plans.jsonl b/.seeds/plans.jsonl index dd511256..c3d56b21 100644 --- a/.seeds/plans.jsonl +++ b/.seeds/plans.jsonl @@ -51,4 +51,4 @@ {"id":"pl-ca7d","seed":"warren-12f3","template":"refactor","status":"done","revision":1,"sections":{"context":"Code patrol of the warren repo. Quality gates are green (bun test 2626 pass, typecheck clean, lint clean), so findings are subtle: a stale routing prefix that no route serves, three count/cross-reference doc comments that contradict the code they describe, a one-directional sync test that let the stale prefix slip through, and one Biome info-level lint nit. Each is small, internal, and single-PR sized. No public API, dependency, or architecture changes.","behavior_invariant":"All HTTP routing, auth gating, SPA-fallback behavior, preview proxy referer routing, and CLI/server spawn behavior must remain byte-for-byte identical. These are dead-entry, comment, test-assertion, and lint-key changes only. The full `bun test` suite (2626 pass / 16 skip) must stay green and `bun run lint`/`bun run typecheck` must stay clean after every step. No route's reachability or auth requirement changes — `/brainstorm` is already unserved, so removing it from the local mirror list is a no-op at runtime.","approach":"Land each independent doc/dead-code fix as its own small PR first, then tighten the sync test that should have caught the stale prefix (ordered after the prefix removal so the new reverse-direction assertion passes). Verify with the existing test suite plus lint/typecheck after each change.","steps":[{"title":"Remove stale /brainstorm prefix from preview proxy mirror list","type":"task","priority":3,"blocks":[5,6],"labels":["nightwatch"],"description":"src/preview/proxy/route-match.ts:32 — WARREN_API_PATH_PREFIXES contains \"/brainstorm\", but no route serves it: the brainstorm dispatcher was retired (see the header comment in src/server/handlers/plots/workbench.ts) and API_PREFIXES in src/server/handlers/index.ts (lines 387-401) has no /brainstorm entry. The route-match.ts doc comment (lines 22-30) claims this list 'Mirrors src/server/handlers/index.ts::API_PREFIXES', yet the two lists diverge precisely on this stale entry. Fix: delete the \"/brainstorm\" line so WARREN_API_PATH_PREFIXES matches API_PREFIXES exactly. Runtime impact is nil (no client routes there); this removes dead routing config and restores the documented mirror invariant. Confirm src/preview/proxy/route-match.test.ts still passes."},{"title":"Fix isApiPath doc comment count drift (five -> actual)","type":"task","priority":3,"blocks":[6],"labels":["nightwatch"],"description":"src/server/handlers/index.ts:404-406 — the isApiPath doc comment says 'Cheap prefix scan — five entries, no allocations on the hot path.' but API_PREFIXES (lines 387-401) has 14 entries. Documentation drift: update the wording so it no longer states a wrong count (either drop the specific number or state the correct one). No code change."},{"title":"Harmonize the three defaultSpawn cross-reference comments","type":"task","priority":3,"blocks":[6],"labels":["nightwatch"],"description":"defaultSpawn is intentionally triplicated across src/cli/output.ts (~line 51), src/server/main/utils.ts (~lines 15-17), and src/server/handlers/index.ts (~lines 104-108). The cross-reference comments are inconsistent: utils.ts names both other copies, output.ts names only utils.ts (omits handlers/index.ts), and handlers/index.ts names neither. Fix: make all three comments reference the other two copies and restate that the duplication is deliberate (neither surface imports the other). Comment-only change; do not deduplicate (that would be an architecture change out of patrol scope)."},{"title":"Resolve Biome useLiteralKeys info in gc.test.ts","type":"task","priority":3,"blocks":[6],"labels":["nightwatch"],"description":"src/runs/reap/gc.test.ts:238 — Biome flags lint/complexity/useLiteralKeys: `(obj as { msg?: string })[\"msg\"]` should use dot access `.msg`. Currently info-level (does not fail --error-on-warnings) but is a flagged inconsistency vs the rest of the codebase, which uses dot access. Fix: change `[\"msg\"]` to `.msg`. Re-run `bun run lint` to confirm the info is gone and `bun test src/runs/reap/gc.test.ts` stays green."},{"title":"Tighten warren-api-prefixes-stay-in-sync test to catch stale extras","type":"task","priority":3,"blocks":[6],"labels":["nightwatch"],"description":"src/preview/proxy/route-match.test.ts:113-132 — the 'warren-api-prefixes-stay-in-sync' test only asserts one direction (every observed API prefix is in the local WARREN_API_PATH_PREFIXES list). It never asserts the reverse, which is exactly how the stale '/brainstorm' entry went undetected. After step 1 removes /brainstorm, add a reverse assertion: every entry in the local list must correspond to an observed prefix derived from API_ROUTE_PATTERNS (or to API_PREFIXES) — so a future stale extra fails CI. Keep the existing forward assertion. Must be ordered after step 1; running it before the removal would fail. Confirm the suite passes."},{"title":"Release: run /release per .claude/commands/release.md","type":"task","priority":3,"blocks":[],"labels":["nightwatch"],"description":"Final step. Run /release per .claude/commands/release.md (patch bump: keep package.json version and src/index.ts VERSION in sync, update CHANGELOG.md). Blocked by all preceding patrol-fix steps so the release captures the full set."}],"acceptance":["bun test stays green (2626 pass / 16 skip, 0 fail) after every step.","bun run lint and bun run typecheck stay clean; the gc.test.ts useLiteralKeys info no longer appears.","WARREN_API_PATH_PREFIXES equals API_PREFIXES (no /brainstorm), and the sync test now fails if a stale local extra is reintroduced.","No doc comment states a wrong entry count or an incomplete cross-reference for defaultSpawn.","No runtime routing, auth, or spawn behavior changes — diff is limited to the named comments, the dead prefix line, the test assertion, and the lint key."]},"children":["warren-7c2e","warren-a31c","warren-103b","warren-3a79","warren-abaa","warren-2471"],"createdAt":"2026-06-07T09:04:39.579Z","updatedAt":"2026-06-07T09:33:42.385Z","name":"nightwatch patrol 2026-06-07: prefix/doc-drift cleanup"} {"id":"pl-de53","seed":"warren-203d","template":"bug","status":"done","revision":1,"sections":{"context":"Leveret conversations whose anchoring run dies before producing any events render as a blank chat with zero operator-visible signal. Observed on conv_4v2b2rewmq6r: both run_yyrcrhw4et4f and its rewake run_vj66cemfx7q4 failed never_started ('agent pi-chat is not registered' burrow-side), yet the conversation stayed 'active' and the split-view chat was empty even though GET /conversations/:id returns the persisted user message (msg seq 1). Operators are left staring at an empty pane with no clue the run failed, no transcript, and no error. This is a pure UI surfacing bug — the data is already on the wire (the persisted transcript and the failed run row); the conversation detail page just never reads it.","reproduction":"1. Open a Leveret conversation whose anchoring run terminated as state=failed with failureReason=never_started (e.g. burrow rejects the runtime / 'agent X is not registered'). 2. Navigate to /leveret/:id (ConversationDetail). Observed: the left 'Conversation' Card renders the Chat surface empty ('No messages yet.') because Chat only consumes useEventStream(runId) and the failed run emitted zero events; no error banner appears even though anchoringRun.data.state === 'failed'. Expected: (a) the persisted transcript returned by GET /conversations/:id (conversation.data.messages, including the seq-1 user message) renders regardless of run state, and (b) a danger banner names the terminal failure (e.g. 'Anchoring run failed — never_started').","root_cause":"src/ui/src/components/Chat.tsx derives its message list solely from useEventStream(runId, follow) — it maps streamed RunEvents (kinds user_message / agent_message) into bubbles and has no notion of the persisted transcript. When the anchoring run is terminal-failed (e.g. never_started), the event stream is empty, so messages.length === 0 and the surface shows 'No messages yet.'. Separately, src/ui/src/pages/ConversationDetail.tsx already fetches the anchoring run (anchoringRun query) and computes isAnchoringRunTerminal, but it never distinguishes state==='failed' from a clean 'succeeded' completion and renders no error affordance — and it discards conversation.data.messages entirely, passing only runId to .","approach":"UI-only fix, no wire/API changes. (1) Teach Chat to accept the already-fetched persisted transcript and render it merged with the live stream, so messages show regardless of run state. (2) In ConversationDetail, feed conversation.data.messages into Chat and add a danger Alert banner when the anchoring run is terminal-failed. Reuse the existing shared Alert component (variant='danger', as RunDetail.tsx already does for failureReason) for consistency. Keep the change to two source files plus one new Chat regression test — no API signatures, deps, or architecture touched.","steps":[{"title":"Add persisted-transcript merge to Chat.tsx","type":"task","priority":1,"blocks":[2,4,5],"labels":["bugwatch"]},{"title":"Pass conversation transcript into Chat from ConversationDetail","type":"task","priority":1,"blocks":[3,5],"labels":["bugwatch"]},{"title":"Render terminal-failed banner in ConversationDetail","type":"task","priority":1,"blocks":[5],"labels":["bugwatch"]},{"title":"Add Chat regression test for transcript render with empty stream","type":"task","priority":2,"blocks":[5],"labels":["bugwatch"]},{"title":"Release: run /release per .claude/commands/release.md","type":"task","priority":2,"blocks":[],"labels":["bugwatch"]}],"acceptance":["src/ui/src/components/Chat.tsx accepts a persisted transcript (e.g. a `transcript?: readonly MessageRow[]` prop) and maps rows to ChatMessage (role user->user, assistant->agent; system/tool rows omitted or rendered distinctly), merging them with live stream events and deduping by (kind, content) so an active conversation does not double-render user turns that appear in both the transcript and the event stream.","When the live event stream is empty (e.g. a never_started anchoring run), Chat still renders the persisted transcript bubbles instead of the 'No messages yet.' empty state.","src/ui/src/pages/ConversationDetail.tsx passes conversation.data?.messages into the instance so the seq-1 user message renders on a failed conversation.","ConversationDetail renders a danger Alert (reusing src/ui/src/components/ui/alert.tsx, mirroring RunDetail.tsx) above the chat when the anchoring run is terminal with state==='failed', surfacing anchoringRun.data.failureReason (e.g. 'never_started'). No banner shows for a clean state==='succeeded' completion.","A new Chat regression test (src/ui/src/components/Chat.test.tsx) asserts: (a) transcript rows render when the event stream yields no message events, and (b) a transcript row matching a streamed event is not duplicated.","bun run lint, bun run typecheck, and bun test pass; bun run check:all is green (no bundle-size, file-size, or coverage ratchet regressions)."]},"children":["warren-9929","warren-1785","warren-e810","warren-0732","warren-0db3"],"createdAt":"2026-06-07T12:04:30.130Z","updatedAt":"2026-06-07T12:43:15.515Z","name":"Surface anchoring-run failure on the conversation surface"} {"id":"pl-7580","seed":"warren-a056","template":"refactor","status":"done","revision":1,"sections":{"context":"Code patrol of the warren repo on 2026-06-09. All quality gates are green: bun test (2632 pass / 16 skip / 0 fail), bun run typecheck clean, bun run lint clean (661 files), and the full check:all family (file-sizes, debt-markers, duplicates, gen:docs:check, gen:openapi:check, validate:agents-md) all pass. Findings are therefore subtle and all fall in the documentation-drift category: source-comment file-path pointers that no longer resolve after several module splits/renames, one snake_case-vs-kebab filename typo in a comment, and a cluster of comments that still describe the brainstorm/interactive flow retired in PR #277. A static reference-extraction pass (grep every `src/...ts(x)` path mentioned in non-test comments, then check existence) surfaced the dead pointers; each is a one-line comment edit landing as a tiny PR. No public API, dependency, behavior, or architecture changes.","behavior_invariant":"These are comment-only edits. No runtime code, type, control flow, route, or wire shape changes. The full `bun test` suite (2632 pass / 16 skip) must stay green and `bun run lint` / `bun run typecheck` must stay clean after every step. `bun run validate:agents-md`, `gen:docs:check`, and `gen:openapi:check` must remain green. Do not rename any files, move any code, or change any identifiers — only correct the prose/path references inside doc comments so they point at code that actually exists.","approach":"Each step is an independent, comment-only fix touching a small set of files; there are no real dependencies between the four fix steps, so they can land in any order as separate PRs. The final Release step is ordered last and blocked by all four. Verify each step by re-running `bun run lint && bun run typecheck && bun test` (comment edits must not perturb any of them) and by grepping that the corrected path now resolves to an existing file.","steps":[{"title":"Repoint stale src/preview/launch.ts and src/preview/proxy.ts comment references after the launch/ + proxy/ splits","type":"task","priority":3,"blocks":[5],"labels":["nightwatch"],"description":"`src/preview/launch.ts` was split into the `src/preview/launch/` directory and `src/preview/proxy.ts` into `src/preview/proxy/`, but three doc comments still point at the now-nonexistent single-file paths:\n\n - `src/warren-config/schema.ts:319` — `// ... See \\`src/preview/launch.ts\\`.` The launch logic now lives under `src/preview/launch/` (the setup pre-step is in `src/preview/launch/setup.ts`). Repoint to `src/preview/launch/setup.ts` (or `src/preview/launch/`).\n - `src/ui/src/api/client.ts:363` — `// Mirrors server-side \\`formatPreviewUrl\\` (\\`src/preview/launch.ts\\`)`. `formatPreviewUrl` now lives in `src/preview/launch/url.ts`. Repoint to `src/preview/launch/url.ts`.\n - `src/server/types.ts:468` — `/** Host-match preview proxy preamble. See \\`src/preview/proxy.ts\\`. */`. Repoint to `src/preview/proxy/` (the handler preamble lives in `src/preview/proxy/index.ts`).\n\nFix: update each path string so it resolves to an existing file. Comment-only; no code change. Verify each corrected path exists with `ls`."},{"title":"Repoint stale src/runs/reap.ts comment references after the reap/ split","type":"task","priority":3,"blocks":[5],"labels":["nightwatch"],"description":"`src/runs/reap.ts` was split into the `src/runs/reap/` directory, but two doc comments still cite the old single-file path:\n\n - `src/preview/launch/index.ts:8` — `// ... orchestration ... lives in \\`src/runs/reap.ts\\`; this module ...`. Repoint to `src/runs/reap/` (the preview orchestration call site is in the reap pipeline under `src/runs/reap/`).\n - `src/projects/refresh.ts:421` — `// Matches the \\`mergePlotEventsFile\\` strategy in \\`src/runs/reap.ts\\`.` The `mergePlotEventsFile` function now lives in `src/runs/reap/plot-merge.ts`. Repoint to `src/runs/reap/plot-merge.ts`.\n\nFix: update each path string so it resolves to an existing file. Comment-only; no code change. Verify with `ls` and `grep -n mergePlotEventsFile src/runs/reap/plot-merge.ts`."},{"title":"Fix src/runs/burrow_config.ts -> src/runs/burrow-config.ts filename in planner.ts comment","type":"task","priority":3,"blocks":[5],"labels":["nightwatch"],"description":"`src/registry/builtins/planner.ts:22` references the sandbox-policy module as `src/runs/burrow_config.ts` (snake_case), but the actual file is `src/runs/burrow-config.ts` (kebab-case, per the repo's kebab-case filename convention). The snake_case path does not resolve.\n\nFix: change `src/runs/burrow_config.ts` to `src/runs/burrow-config.ts` in the planner.ts header comment. Comment-only; no code change. Verify `ls src/runs/burrow-config.ts` resolves and that no other non-test comment still uses the underscored form (`grep -rn 'runs/burrow_config.ts' src`)."},{"title":"Update comments referencing the retired brainstorm/interactive flow","type":"task","priority":3,"blocks":[5],"labels":["nightwatch"],"description":"PR #277 (`Retire mode=interactive/brainstorm`) removed the interactive-turn primitive, the `POST /brainstorm` surface, `src/runs/interactive.ts`, `src/runs/reap/interactive.ts`, and the `src/registry/builtins/brainstorm.ts` built-in. Several doc comments still point at those deleted files / describe the retired flow as if current:\n\n - `src/plots/formalize.ts:19` — cites `src/runs/interactive.ts` for `agent_message` capture (file deleted).\n - `src/plots/formalize.ts:22` — `The brainstorm agent (\\`src/registry/builtins/brainstorm.ts\\`)` (built-in retired; current builtins are bugwatch/claude-code/leveret/nightwatch/pi/planner/pr-fixer/sapling — no brainstorm.ts).\n - `src/ui/src/pages/plot-detail/interactive-panel.tsx:33` — cites `src/runs/reap/interactive.ts` for reap-side `agent_message` capture (file deleted; the reap-side interactive `appendAgentMessage` path was retired with #277).\n - `src/ui/src/pages/plot-detail/interactive-panel.tsx:63` — cites `src/runs/interactive.ts` for respawn-per-turn (file deleted).\n\nFix: update each comment to describe the current state — either repoint to where the equivalent logic now lives (the conversation/leveret path) or drop the dead `src/...` pointer and the retired-flow rationale. Keep this strictly comment-only: do NOT alter `INTERACTIVE_AGENT_NAMES` or any runtime behavior in this step (the planner prompt's `**brainstorm**` wording in `src/registry/builtins/planner.ts` is a separate concern — leave it). Confirm the four edited comments no longer reference any nonexistent `src/...` path, and that lint/typecheck/test stay green."},{"title":"Release: run /release per .claude/commands/release.md","type":"task","priority":3,"blocks":[],"labels":["nightwatch"],"description":"Final step, blocked by all preceding patrol fixes. Run the release flow per `.claude/commands/release.md`: patch-bump the version in both `package.json` and `src/index.ts` (they must agree or the release workflow fails), move the [Unreleased] CHANGELOG.md entries (the four documentation-drift comment fixes from this patrol) into a new dated version section, and commit. Verify `bun run check:all` is green before releasing."}],"acceptance":["Every `src/...ts(x)` path referenced in a non-test source comment resolves to an existing file (re-run the reference-extraction grep used to find these; no MISSING lines for real warren paths).","No non-test comment references the retired files src/runs/interactive.ts, src/runs/reap/interactive.ts, or src/registry/builtins/brainstorm.ts.","bun run lint, bun run typecheck, and bun test all stay green (2632 pass / 16 skip / 0 fail) after each step.","bun run validate:agents-md, gen:docs:check, and gen:openapi:check remain green.","No runtime code, types, routes, wire shapes, or identifiers changed — git diff for the fix steps shows comment-only edits.","Release step patch-bumps package.json and src/index.ts in lockstep and updates CHANGELOG.md."]},"children":["warren-43e6","warren-bfe2","warren-9358","warren-9d72","warren-f48a"],"createdAt":"2026-06-09T09:08:52.347Z","updatedAt":"2026-06-09T09:36:51.283Z","name":"nightwatch patrol: 2026-06-09"} -{"id":"pl-69e1","seed":"warren-678a","template":"refactor","status":"approved","revision":1,"sections":{"context":"Code-patrol scan of the warren repo on 2026-06-10. Quality gates are green (bun test 2632 pass, biome lint clean, tsc clean, file-size/debt-marker/gen:docs/gen:openapi guards all ok). The scan surfaced no logic bugs, type-safety holes, dead code, or security issues, but it did find documentation that now contradicts the code it describes (comment drift from features that have since landed) plus one cross-call-site error-message-style inconsistency. These are comment/string-only fixes that keep the codebase's heavily-documented modules honest — the same class of drift earlier nightwatch patrols (pl-7580) cleaned up. Each finding is independent and lands as its own small PR.","behavior_invariant":"No runtime behavior changes. All edits are to doc comments or to user-facing validation error strings (with their corresponding test assertions updated in lockstep). The public API surface, route table, HTTP status codes, JSON wire shapes, and exported signatures stay byte-for-byte identical. `bun run check:all` (tests + lint + typecheck + file-size + debt-marker + gen:docs:check + gen:openapi:check) stays green after every step.","approach":"One step per finding, ordered independents-first. Steps 1-3 are pure comment fixes (zero test impact). Step 4 harmonizes validation error-message phrasing across handler call sites and must update the exact-string assertions in the adjacent *.test.ts files in the same PR. There are no real dependencies among the four fix steps, so they may land in any order as separate PRs; each blocks only the final Release step, which is ordered last.","steps":[{"title":"Fix stale 'latent' NOTE in src/runs/analytics/insights.ts","type":"task","priority":3,"labels":["nightwatch"],"blocks":[5],"description":"src/runs/analytics/insights.ts lines ~26-32 carry a NOTE claiming the `steering-anomaly` / `pause-anomaly` callouts are latent: 'no production code currently does so — the `GET /analytics/behavior` handler calls `buildInsights` without `steering`, so these two kinds never appear in the live endpoint's response today.' This contradicts the code: src/server/handlers/runs/analytics.ts:209-213 now builds `steering` via `buildSteeringSignals(steeringRows, rows.length)` and calls `buildInsights({ metrics, mining, steering })`, so both callouts are live. Rewrite the NOTE to describe the current wiring (the handler fetches steering/pause events via `EventsRepo.listSteeringAndPauseEventsForRuns`, builds a SteeringSignals bundle, and passes it through) and drop the 'latent / no production caller' framing. Comment-only change; no tests affected."},{"title":"Repoint stale 'Postgres schema not yet wired' comments after dialect-aware openDatabase landed","type":"task","priority":3,"labels":["nightwatch"],"blocks":[5],"description":"The dialect-aware `openDatabase` (warren-a66e, the 'step 3' those comments forward-reference) has landed: src/db/client.ts:124-131 routes a postgres URL to `openPostgres`, which calls `drizzlePg(pool, { schema: pgSchema })` (line ~185), so the Postgres schema IS now wired into the runtime for the postgres dialect. Update the stale header comments that still claim otherwise: (a) src/db/schema/postgres.ts lines ~19-22 ('This schema is not yet wired into `openDatabase` ... Until then this file is build-only and exercised by the drift test.'); (b) src/db/schema/columns.ts lines ~14-15 ('Step 3 (warren-a66e) adds dialect-aware `openDatabase`; until then, the Postgres tables exist but are unused at runtime.'). While here, sanity-check the related framing in src/db/schema.ts lines ~13-16 ('lit up by step 3' / 'until then the SQLite objects ARE the runtime') and adjust the 'until then' clause to reflect that postgres is now a selectable runtime dialect. Comment-only change; the drift test still guards parity, no test edits expected."},{"title":"Fix 'four dedicated mutators' miscount in src/plot-client/types.ts","type":"task","priority":3,"labels":["nightwatch"],"blocks":[5],"description":"src/plot-client/types.ts, the doc comment on `AgentAllowedEventType` (lines ~39-46), reads: 'The four dedicated mutators (`editIntent`, `setStatus`, `detach`, plus `question_answered` appends) live only on `UserPlotHandle`'. That miscounts: there are THREE dedicated mutators (editIntent, setStatus, detach) plus one shared append path (question_answered) — not four mutators. This contradicts the sibling file src/plot-client/handle.ts lines ~8-13, which correctly states 'the first three because their dedicated mutators (`editIntent`, `setStatus`, `detach`) ... and the fourth because `append`'s generic parameter excludes it.' Reword the types.ts comment to say 'three dedicated mutators (`editIntent`, `setStatus`, `detach`) plus the shared `question_answered` append path' so the two files agree. Comment-only change."},{"title":"Harmonize 'expected one of' vs 'must be one of ...; got' validation error phrasing across handlers","type":"task","priority":3,"labels":["nightwatch"],"blocks":[5],"description":"Enum-validation error messages use two divergent styles across handler call sites for the same kind of failure. The 'must be one of ; got ''' form is used in src/server/handlers/burrows.ts:33,42, src/server/handlers/plan-runs.ts:56, and src/server/handlers/plots/attachments.ts:250 (merge_method). The 'expected one of ' form (no offending-value suffix) is used in src/server/handlers/plots/list.ts:50, src/server/handlers/plots/status.ts:68, and src/server/handlers/plots/attachments.ts:102. Standardize on the more informative ' must be one of ; got ''' form (it echoes the rejected value) for these enum-membership rejections, leaving the field-key 'is not recognized; expected one of ...' messages in plots/intent.ts and plots/list.ts alone (different failure: unrecognized key, not bad enum value). Update the exact-string assertions in the adjacent test files (plots/list.test.ts, plots/status.test.ts, plots/attachments.test.ts) in the same PR so the suite stays green. Scope is wording-only on already-thrown ValidationErrors — no status codes, error `code` values, or control flow change."},{"title":"Release: run /release per .claude/commands/release.md","type":"task","priority":3,"labels":["nightwatch"],"blocks":[],"description":"Final step. After all preceding fix steps have merged, run /release per .claude/commands/release.md to cut the release that ships these comment + error-message consistency fixes."}],"acceptance":["bun run check:all passes after each step (tests, lint, typecheck, file-size, debt-marker, gen:docs:check, gen:openapi:check all green).","src/runs/analytics/insights.ts no longer claims the steering-anomaly/pause-anomaly callouts are latent or that no production caller passes `steering`; the NOTE matches the GET /analytics/behavior wiring in src/server/handlers/runs/analytics.ts.","No comment in src/db/schema/postgres.ts, src/db/schema/columns.ts, or src/db/schema.ts asserts the Postgres schema is unwired/build-only now that openDatabase resolves the postgres dialect to drizzlePg(pgSchema).","src/plot-client/types.ts and src/plot-client/handle.ts agree: three dedicated mutators plus the shared question_answered append path (no 'four dedicated mutators' claim).","Enum-membership validation errors in burrows/plan-runs/plots handlers share the ' must be one of ; got ''' phrasing, with their test assertions updated to match; HTTP status codes and error `code` strings are unchanged.","No source logic, route table, OpenAPI schema, or exported signature changed — diffs are limited to comments, error-message strings, and the matching test assertions."]},"children":["warren-66ec","warren-4674","warren-5453","warren-cda9","warren-32ce"],"createdAt":"2026-06-10T09:07:02.542Z","updatedAt":"2026-06-10T09:07:02.542Z","name":"nightwatch patrol 2026-06-10: doc-drift + error-message consistency"} +{"id":"pl-69e1","seed":"warren-678a","template":"refactor","status":"done","revision":1,"sections":{"context":"Code-patrol scan of the warren repo on 2026-06-10. Quality gates are green (bun test 2632 pass, biome lint clean, tsc clean, file-size/debt-marker/gen:docs/gen:openapi guards all ok). The scan surfaced no logic bugs, type-safety holes, dead code, or security issues, but it did find documentation that now contradicts the code it describes (comment drift from features that have since landed) plus one cross-call-site error-message-style inconsistency. These are comment/string-only fixes that keep the codebase's heavily-documented modules honest — the same class of drift earlier nightwatch patrols (pl-7580) cleaned up. Each finding is independent and lands as its own small PR.","behavior_invariant":"No runtime behavior changes. All edits are to doc comments or to user-facing validation error strings (with their corresponding test assertions updated in lockstep). The public API surface, route table, HTTP status codes, JSON wire shapes, and exported signatures stay byte-for-byte identical. `bun run check:all` (tests + lint + typecheck + file-size + debt-marker + gen:docs:check + gen:openapi:check) stays green after every step.","approach":"One step per finding, ordered independents-first. Steps 1-3 are pure comment fixes (zero test impact). Step 4 harmonizes validation error-message phrasing across handler call sites and must update the exact-string assertions in the adjacent *.test.ts files in the same PR. There are no real dependencies among the four fix steps, so they may land in any order as separate PRs; each blocks only the final Release step, which is ordered last.","steps":[{"title":"Fix stale 'latent' NOTE in src/runs/analytics/insights.ts","type":"task","priority":3,"labels":["nightwatch"],"blocks":[5],"description":"src/runs/analytics/insights.ts lines ~26-32 carry a NOTE claiming the `steering-anomaly` / `pause-anomaly` callouts are latent: 'no production code currently does so — the `GET /analytics/behavior` handler calls `buildInsights` without `steering`, so these two kinds never appear in the live endpoint's response today.' This contradicts the code: src/server/handlers/runs/analytics.ts:209-213 now builds `steering` via `buildSteeringSignals(steeringRows, rows.length)` and calls `buildInsights({ metrics, mining, steering })`, so both callouts are live. Rewrite the NOTE to describe the current wiring (the handler fetches steering/pause events via `EventsRepo.listSteeringAndPauseEventsForRuns`, builds a SteeringSignals bundle, and passes it through) and drop the 'latent / no production caller' framing. Comment-only change; no tests affected."},{"title":"Repoint stale 'Postgres schema not yet wired' comments after dialect-aware openDatabase landed","type":"task","priority":3,"labels":["nightwatch"],"blocks":[5],"description":"The dialect-aware `openDatabase` (warren-a66e, the 'step 3' those comments forward-reference) has landed: src/db/client.ts:124-131 routes a postgres URL to `openPostgres`, which calls `drizzlePg(pool, { schema: pgSchema })` (line ~185), so the Postgres schema IS now wired into the runtime for the postgres dialect. Update the stale header comments that still claim otherwise: (a) src/db/schema/postgres.ts lines ~19-22 ('This schema is not yet wired into `openDatabase` ... Until then this file is build-only and exercised by the drift test.'); (b) src/db/schema/columns.ts lines ~14-15 ('Step 3 (warren-a66e) adds dialect-aware `openDatabase`; until then, the Postgres tables exist but are unused at runtime.'). While here, sanity-check the related framing in src/db/schema.ts lines ~13-16 ('lit up by step 3' / 'until then the SQLite objects ARE the runtime') and adjust the 'until then' clause to reflect that postgres is now a selectable runtime dialect. Comment-only change; the drift test still guards parity, no test edits expected."},{"title":"Fix 'four dedicated mutators' miscount in src/plot-client/types.ts","type":"task","priority":3,"labels":["nightwatch"],"blocks":[5],"description":"src/plot-client/types.ts, the doc comment on `AgentAllowedEventType` (lines ~39-46), reads: 'The four dedicated mutators (`editIntent`, `setStatus`, `detach`, plus `question_answered` appends) live only on `UserPlotHandle`'. That miscounts: there are THREE dedicated mutators (editIntent, setStatus, detach) plus one shared append path (question_answered) — not four mutators. This contradicts the sibling file src/plot-client/handle.ts lines ~8-13, which correctly states 'the first three because their dedicated mutators (`editIntent`, `setStatus`, `detach`) ... and the fourth because `append`'s generic parameter excludes it.' Reword the types.ts comment to say 'three dedicated mutators (`editIntent`, `setStatus`, `detach`) plus the shared `question_answered` append path' so the two files agree. Comment-only change."},{"title":"Harmonize 'expected one of' vs 'must be one of ...; got' validation error phrasing across handlers","type":"task","priority":3,"labels":["nightwatch"],"blocks":[5],"description":"Enum-validation error messages use two divergent styles across handler call sites for the same kind of failure. The 'must be one of ; got ''' form is used in src/server/handlers/burrows.ts:33,42, src/server/handlers/plan-runs.ts:56, and src/server/handlers/plots/attachments.ts:250 (merge_method). The 'expected one of ' form (no offending-value suffix) is used in src/server/handlers/plots/list.ts:50, src/server/handlers/plots/status.ts:68, and src/server/handlers/plots/attachments.ts:102. Standardize on the more informative ' must be one of ; got ''' form (it echoes the rejected value) for these enum-membership rejections, leaving the field-key 'is not recognized; expected one of ...' messages in plots/intent.ts and plots/list.ts alone (different failure: unrecognized key, not bad enum value). Update the exact-string assertions in the adjacent test files (plots/list.test.ts, plots/status.test.ts, plots/attachments.test.ts) in the same PR so the suite stays green. Scope is wording-only on already-thrown ValidationErrors — no status codes, error `code` values, or control flow change."},{"title":"Release: run /release per .claude/commands/release.md","type":"task","priority":3,"labels":["nightwatch"],"blocks":[],"description":"Final step. After all preceding fix steps have merged, run /release per .claude/commands/release.md to cut the release that ships these comment + error-message consistency fixes."}],"acceptance":["bun run check:all passes after each step (tests, lint, typecheck, file-size, debt-marker, gen:docs:check, gen:openapi:check all green).","src/runs/analytics/insights.ts no longer claims the steering-anomaly/pause-anomaly callouts are latent or that no production caller passes `steering`; the NOTE matches the GET /analytics/behavior wiring in src/server/handlers/runs/analytics.ts.","No comment in src/db/schema/postgres.ts, src/db/schema/columns.ts, or src/db/schema.ts asserts the Postgres schema is unwired/build-only now that openDatabase resolves the postgres dialect to drizzlePg(pgSchema).","src/plot-client/types.ts and src/plot-client/handle.ts agree: three dedicated mutators plus the shared question_answered append path (no 'four dedicated mutators' claim).","Enum-membership validation errors in burrows/plan-runs/plots handlers share the ' must be one of ; got ''' phrasing, with their test assertions updated to match; HTTP status codes and error `code` strings are unchanged.","No source logic, route table, OpenAPI schema, or exported signature changed — diffs are limited to comments, error-message strings, and the matching test assertions."]},"children":["warren-66ec","warren-4674","warren-5453","warren-cda9","warren-32ce"],"createdAt":"2026-06-10T09:07:02.542Z","updatedAt":"2026-06-10T09:34:42.125Z","name":"nightwatch patrol 2026-06-10: doc-drift + error-message consistency"}