From dff48f66f7cb2cdf74f23998caa368073629eab3 Mon Sep 17 00:00:00 2001 From: Warren <28354219+jayminwest@users.noreply.github.com> Date: Fri, 12 Jun 2026 09:22:52 +0000 Subject: [PATCH 1/2] Release v0.8.8: harmonize truthy boolean env-var parsers (pl-a04a) --- CHANGELOG.md | 20 ++++++++++++++++++++ docs/openapi.yaml | 2 +- package.json | 2 +- src/index.ts | 2 +- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a938300f..3ea5d029 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.8.8] — 2026-06-12 + +Truthy boolean env-var parser harmonization from the nightwatch patrol +(plan pl-a04a). + +### Fixed + +- **Divergent truthy env-var parsers harmonized** on the canonical + `1`/`true`/`yes`/`on` token set (trimmed, case-insensitive), symmetric + with the existing falsy `0`/`false`/`no`/`off` opt-out set. + `parseTrueEnv` (`src/server/main/utils.ts`) now also accepts `on`, and + the inline parsers for `WARREN_WORKER_PROBE_DISABLED` + (`src/server/probe.ts`) and `WARREN_DISABLE_UI` (`src/server/config.ts`) + route through the same logic, so case variants and the `yes`/`on` + spellings are honored uniformly instead of being silently ignored. +- **Supervisor `parseBoolEnv`** (`src/supervisor/main.ts`) for + `WARREN_BURROW_NO_AUTH` now trims, lowercases, and accepts + `1`/`true`/`yes`/`on`, while preserving the fail-safe default (absent + or empty keeps auth on). + ## [0.8.7] — 2026-06-11 Doc-drift and validation error-message consistency fixes from the diff --git a/docs/openapi.yaml b/docs/openapi.yaml index 9d3f2a29..9a2fb771 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.7 + version: 0.8.8 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 44781784..70360671 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@os-eco/warren-cli", - "version": "0.8.7", + "version": "0.8.8", "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 e6acf154..ae93e693 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.7"; +export const VERSION = "0.8.8"; From 233f40f302e1f32604fadcfa2c82f6f119721dc2 Mon Sep 17 00:00:00 2001 From: warren Date: Fri, 12 Jun 2026 09:23:59 +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 6e1c99a2..05146063 100644 --- a/.seeds/issues.jsonl +++ b/.seeds/issues.jsonl @@ -677,7 +677,7 @@ {"id":"warren-879c","title":"Add '; got ' suffix to ?sort/?dir validation errors in runs/lifecycle.ts","status":"closed","type":"task","priority":3,"plan_step_index":1,"description":"\nStep 2 of plan pl-9796.\n\nParent seed: warren-027f — nightwatch patrol: 2026-06-11\nPlan template: refactor\nPlan approach: Two independent, mechanical edits, each landing as its own PR, followed by the standard release step. Neither edit changes a public API signature, adds dependencies, or reorganizes modules. Order is irrelevant between the two fixes (no…\n\nRun `sd plan show pl-9796` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n","createdAt":"2026-06-11T09:05:59.371Z","updatedAt":"2026-06-11T09:17:50.956Z","labels":["nightwatch"],"plan_id":"pl-9796","blocks":["warren-e338","warren-027f"],"closedAt":"2026-06-11T09:17:50.956Z"} {"id":"warren-e338","title":"Release: run /release per .claude/commands/release.md","status":"closed","type":"task","priority":3,"plan_step_index":2,"description":"\nStep 3 of plan pl-9796.\n\nParent seed: warren-027f — nightwatch patrol: 2026-06-11\nPlan template: refactor\nPlan approach: Two independent, mechanical edits, each landing as its own PR, followed by the standard release step. Neither edit changes a public API signature, adds dependencies, or reorganizes modules. Order is irrelevant between the two fixes (no…\n\nRun `sd plan show pl-9796` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n","createdAt":"2026-06-11T09:05:59.371Z","updatedAt":"2026-06-11T09:23:51.640Z","labels":["nightwatch"],"plan_id":"pl-9796","blocks":["warren-027f"],"closedAt":"2026-06-11T09:23:51.640Z"} {"id":"warren-ea20","title":"Article IX ratification record: PR #337 (audit population founding — docs/CONSTITUTION.md, .canopy/ auditor prompts, .warren/triggers.yaml audit entries, auto-merge guard) was explicitly human-reviewed and human-merged by the operator on 2026-06-12 after LGTM in working session; auto-merge was disabled for the PR. This seed is the sign-off evidence gatewatch's Article IX check looks for.","status":"closed","type":"task","priority":4,"createdAt":"2026-06-12T05:27:28.391Z","updatedAt":"2026-06-12T05:27:28.449Z","labels":["audit","ratification"],"closedAt":"2026-06-12T05:27:28.449Z","closeReason":"Record-only seed: ratification evidence for gatewatch Article IX verification of PR #337"} -{"id":"warren-6702","title":"nightwatch patrol: 2026-06-12","status":"open","type":"task","priority":3,"createdAt":"2026-06-12T09:05:48.630Z","updatedAt":"2026-06-12T09:18:37.114Z","labels":["patrol","nightwatch"],"plan_id":"pl-a04a","blockedBy":["warren-1b53"]} +{"id":"warren-6702","title":"nightwatch patrol: 2026-06-12","status":"open","type":"task","priority":3,"createdAt":"2026-06-12T09:05:48.630Z","updatedAt":"2026-06-12T09:23:59.362Z","labels":["patrol","nightwatch"],"plan_id":"pl-a04a"} {"id":"warren-c27f","title":"Harmonize app-side truthy env parsers on 1/true/yes/on (case-insensitive)","status":"closed","type":"task","priority":3,"plan_step_index":0,"description":"\nStep 1 of plan pl-a04a.\n\nParent seed: warren-6702 — nightwatch patrol: 2026-06-12\nPlan template: refactor\nPlan approach: Converge all default-OFF truthy env parsers on a single accepted token set — `1`, `true`, `yes`, `on` — compared after `.trim().toLowerCase()`, matching the existing `isTruthy` in eviction/config.ts and reap/gc.ts and symmetric with the…\n\nRun `sd plan show pl-a04a` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n","createdAt":"2026-06-12T09:06:24.600Z","updatedAt":"2026-06-12T09:13:41.840Z","labels":["nightwatch"],"plan_id":"pl-a04a","blocks":["warren-1b53","warren-6702"],"extensions":{"role":"pi","lastRunId":"run_49mm93ht0kaa","lastRunAt":"2026-06-12T09:08:19.385Z"},"closedAt":"2026-06-12T09:13:41.840Z"} {"id":"warren-83ae","title":"Harmonize supervisor parseBoolEnv for WARREN_BURROW_NO_AUTH","status":"closed","type":"task","priority":3,"plan_step_index":1,"description":"\nStep 2 of plan pl-a04a.\n\nParent seed: warren-6702 — nightwatch patrol: 2026-06-12\nPlan template: refactor\nPlan approach: Converge all default-OFF truthy env parsers on a single accepted token set — `1`, `true`, `yes`, `on` — compared after `.trim().toLowerCase()`, matching the existing `isTruthy` in eviction/config.ts and reap/gc.ts and symmetric with the…\n\nRun `sd plan show pl-a04a` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n","createdAt":"2026-06-12T09:06:24.600Z","updatedAt":"2026-06-12T09:18:37.114Z","labels":["nightwatch"],"plan_id":"pl-a04a","blocks":["warren-1b53","warren-6702"],"extensions":{"role":"pi","lastRunId":"run_bgdstkfzgs2f","lastRunAt":"2026-06-12T09:15:09.897Z"},"closedAt":"2026-06-12T09:18:37.114Z"} -{"id":"warren-1b53","title":"Release: run /release per .claude/commands/release.md","status":"open","type":"task","priority":3,"plan_step_index":2,"description":"\nStep 3 of plan pl-a04a.\n\nParent seed: warren-6702 — nightwatch patrol: 2026-06-12\nPlan template: refactor\nPlan approach: Converge all default-OFF truthy env parsers on a single accepted token set — `1`, `true`, `yes`, `on` — compared after `.trim().toLowerCase()`, matching the existing `isTruthy` in eviction/config.ts and reap/gc.ts and symmetric with the…\n\nRun `sd plan show pl-a04a` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n","createdAt":"2026-06-12T09:06:24.600Z","updatedAt":"2026-06-12T09:18:37.114Z","labels":["nightwatch"],"plan_id":"pl-a04a","blocks":["warren-6702"]} +{"id":"warren-1b53","title":"Release: run /release per .claude/commands/release.md","status":"closed","type":"task","priority":3,"plan_step_index":2,"description":"\nStep 3 of plan pl-a04a.\n\nParent seed: warren-6702 — nightwatch patrol: 2026-06-12\nPlan template: refactor\nPlan approach: Converge all default-OFF truthy env parsers on a single accepted token set — `1`, `true`, `yes`, `on` — compared after `.trim().toLowerCase()`, matching the existing `isTruthy` in eviction/config.ts and reap/gc.ts and symmetric with the…\n\nRun `sd plan show pl-a04a` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n","createdAt":"2026-06-12T09:06:24.600Z","updatedAt":"2026-06-12T09:23:59.362Z","labels":["nightwatch"],"plan_id":"pl-a04a","blocks":["warren-6702"],"closedAt":"2026-06-12T09:23:59.362Z"} diff --git a/.seeds/plans.jsonl b/.seeds/plans.jsonl index af903a36..c033418e 100644 --- a/.seeds/plans.jsonl +++ b/.seeds/plans.jsonl @@ -58,4 +58,4 @@ {"id":"pl-1ec1","seed":"warren-58dc","template":"feature","status":"approved","revision":1,"sections":{"context":"The operator runs agents at the root of ~/Projects/kota-monorepo (many intertwined projects, one git repo) more often than inside individual projects. Investigation (2026-06-10) found warren supports this today with zero code changes: a project is one repo, burrow materializes workspaces as git worktrees of warren's host clone, agents run at repo root, and one branch/one PR per run is the natural monorepo shape. Opt-in features light up from root-level .seeds/, .mulch/, .plot/, .warren/. The rough edges are coarseness, not blockers: feature detection probes the clone root only (src/projects/refresh.ts:73-81), there is no sparse/partial-clone support (full checkout per concurrent run), one preview config and one pr-template for the whole repo, and git-hooks arming reads only the root package.json. True multi-repo burrow workspaces were sized at several weeks across burrow SPEC + dispatch + reap + plan-run PR gating and deliberately deferred; ROADMAP R-20 Colonies covers cross-repo policy grouping without joint workspaces.","approach":"Onboard kota-monorepo as a single warren project now and validate the full loop (dispatch, plan-run, PR) against it, then land the cheap coarseness fixes only as pain is proven: partial clone + sparse-checkout first if checkout time/disk bites, and an R-20 colonies decision spike for the genuinely separate os-eco repos. Explicitly do not build multi-repo workspaces in this arc.","alternatives":[{"name":"True multi-repo burrow workspaces (N clones per sandbox)","rejected_because":"Deferred: several weeks across the most failure-sensitive paths (burrow SPEC, dispatch, reap, plan-run PR gating), and the monorepo path removes the primary motivation"},{"name":"Splitting kota-monorepo packages into separate warren projects","rejected_because":"The projects are closely intertwined and the operator's working habit is monorepo-root runs"}],"steps":[{"title":"Onboard kota-monorepo: add as a warren project, place .warren/config.yaml (defaultRole, defaultPrompt, runBranchPrefix) plus .seeds/.mulch/.plot/ at the repo root, dispatch a smoke run and a small plan-run end-to-end, and record the validated setup + any friction as mulch records","type":"task","priority":2,"blocks":[2]},{"title":"Measure and decide on sparse/partial clone: capture clone + per-run worktree checkout time and disk for kota-monorepo under concurrent runs; if it bites, implement --filter=blob:none on warren's clone (src/projects/clone.ts, refresh.ts) and a per-project sparsePaths burrow applies after worktree add (burrow src/provider/local/workspace.ts + sandbox binds); if it does not bite, close with the measurements recorded","type":"task","priority":3,"blocks":[]},{"title":"R-20 Colonies decision spike for os-eco's separate repos: evaluate the ROADMAP sketch (colonies/colony_members tables, shared scheduling, aggregate dashboard, colony-level agents) against actual cross-repo needs observed after the monorepo + plan-run CLI workflows settle; outcome is a go/no-go note on the roadmap item, not code","type":"task","priority":4,"blocks":[]}],"risks":["kota-monorepo's on-disk size is unverified — if very large, full checkouts per concurrent run could hurt before step 2's measurements land","Root-level .seeds/ means all packages share one issue queue and one PR stream; acceptable by design but per-package scoping pressure may emerge","Sparse-checkout in burrow touches the sandbox bind set and worktree lifecycle — needs burrow-side review against ../burrow/SPEC.md before implementation"],"acceptance":["kota-monorepo is a registered warren project and a plan-run executed against it end-to-end (dispatch, child PRs, merge-gated advancement)","A documented measurement of clone/checkout cost exists with an explicit go/no-go on sparse support","R-20 has a recorded decision note","Any code changes pass bun run check:all (and burrow's gates if sparse lands)"]},"children":["warren-b32d","warren-4c45","warren-2fa8"],"createdAt":"2026-06-11T04:45:11.903Z","updatedAt":"2026-06-11T04:45:11.903Z","name":"Monorepo onboarding (kota-monorepo)"} {"id":"pl-cf2a","seed":"warren-16d2","template":"feature","status":"approved","revision":1,"sections":{"context":"warren is the os-eco reference L5 repo and originated the check:ci-parity gate, but its check:all is a 12-gate && chain using verbose names (check:file-sizes, check:debt-markers, check:duplicates, validate:agents-md) that diverge from the canonical terse vocabulary frozen in docs/check-all-standard.md (os-eco-9048) and shipped as the portable runner in templates/l5-toolkit/scripts (os-eco-5db7). warren has no quiet runner (it chains with &&) and no `verify` alias. Conforming warren makes the reference repo match the standard it anchors. Depends on root tracker pl-760e steps 1-2.","approach":"Rename warren's verbose gate keys to canonical, swap the && chain for the byte-identical quiet runner, and refactor warren's existing check-ci-parity.ts to import the shared GATES manifest. Keep warren's repo-specific conditional gates (check:bundle-size, gen:docs:check, gen:openapi:check) under their canonical names, slotted before check:coverage with check:ci-parity last.","steps":[{"title":"Rename warren's verbose package.json gate keys to the canonical terse names: check:file-sizes -> check:size, check:debt-markers -> check:debt, check:duplicates -> check:dups, validate:agents-md -> check:agents (keep check:deps, check:coverage, check:bundle-size, gen:docs:check, gen:openapi:check as-is). Update every reference to the old keys in CLAUDE.md, .github/workflows/ci.yml, .github/workflows/ci-postgres.yml, and any scripts; retain each old key as a one-cycle deprecated alias only if an external consumer needs it. Do not yet touch check:all.","type":"task","priority":2,"blocks":[2]},{"title":"Replace warren's && -chain check:all with the canonical scripts/check-all.ts quiet runner copied byte-identical from templates/l5-toolkit/scripts/check-all.ts. Define warren's exported GATES manifest in the standard's order: lint, typecheck, check:agents, check:dups, check:deps, check:size, check:debt, check:bundle-size, gen:docs:check, gen:openapi:check, check:coverage, check:ci-parity (last). Set package.json check:all to `bun scripts/check-all.ts`, add `verify`: `bun run check:all`, and add scripts/check-all.test.ts. Confirm the quiet-output contract (one aligned line per gate, signatures-only on failure).","type":"task","priority":2,"blocks":[3]},{"title":"Refactor warren's existing scripts/check-ci-parity.ts to import the GATES array from scripts/check-all.ts as the single source of truth (replacing its own ROOT_GATES/local derivation), and confirm it scans BOTH .github/workflows/ci.yml and ci-postgres.yml. Run `bun run check:all` and `bun run verify` green end-to-end, confirm check:ci-parity passes with the new manifest, and update CLAUDE.md's Quality Gates section to describe the runner + verify alias.","type":"task","priority":2,"blocks":[]}],"acceptance":["warren package.json uses canonical terse gate names; no verbose key remains except optional documented one-cycle aliases.","check:all is `bun scripts/check-all.ts` with a byte-identical runner and a GATES manifest in the standard's order; verify aliases check:all.","scripts/check-ci-parity.ts imports GATES from check-all.ts and passes against ci.yml + ci-postgres.yml.","`bun run check:all` runs green with the quiet-output contract."]},"children":["warren-c123","warren-0628","warren-3a0f"],"createdAt":"2026-06-12T04:53:28.716Z","updatedAt":"2026-06-12T04:53:28.716Z","name":"Adopt canonical check:all standard (warren)"} {"id":"pl-9796","seed":"warren-027f","template":"refactor","status":"done","revision":1,"sections":{"context":"Nightwatch patrol of 2026-06-11. Quality gates are green (bun test: 2632 pass / 0 fail, bun run lint, bun run typecheck all clean). Two small, in-scope quality issues surfaced during the scan: (1) a doc-comment table count in the SQLite schema header has drifted from the actual schema, and (2) two query-param validation errors in the runs list handler omit the standard '; got ' suffix that every other enumerated/literal validation error in src/server/handlers carries. Both are low-risk, single-PR fixes that improve doc accuracy and error-message consistency without touching behavior.","behavior_invariant":"No runtime behavior changes. The SQLite/Postgres physical schema (table names, columns, FKs, indexes) stays byte-identical — only a header doc comment changes. For the validation-message fix, the same inputs that throw ValidationError today must still throw ValidationError (same 400 status, same field), and the same valid inputs must still pass; only the human-readable error string gains the '; got ' suffix to match sibling messages. All existing tests must continue to pass; any test asserting the exact error strings for ?sort / ?dir is updated in lockstep.","approach":"Two independent, mechanical edits, each landing as its own PR, followed by the standard release step. Neither edit changes a public API signature, adds dependencies, or reorganizes modules. Order is irrelevant between the two fixes (no shared files), so they run in parallel; the release step is gated on both.","steps":[{"title":"Fix 'Seven tables' doc drift in src/db/schema/sqlite.ts header","type":"task","priority":3,"labels":["nightwatch"],"blocks":[3]},{"title":"Add '; got ' suffix to ?sort/?dir validation errors in runs/lifecycle.ts","type":"task","priority":3,"labels":["nightwatch"],"blocks":[3]},{"title":"Release: run /release per .claude/commands/release.md","type":"task","priority":3,"labels":["nightwatch"],"blocks":[]}],"acceptance":["src/db/schema/sqlite.ts header comment names the correct table count (12) and lists the tables actually defined in the file (agents, projects, runs, events, triggers, workers, burrows, planRuns, planRunChildren, plots, conversations, messages); no schema definitions changed; src/db/schema/drift.test.ts still passes.","src/server/handlers/runs/lifecycle.ts:19 and :26 throw ValidationError messages ending in \"; got ''\" (using the rejected raw value), matching the ?limit/?offset messages directly below them and the conversations ?status message; behavior (status code, which inputs are rejected) is unchanged.","Full quality suite is green: bun test, bun run lint, bun run typecheck all pass; any test asserting the old ?sort/?dir strings is updated to match.","Release step completes per .claude/commands/release.md after both fixes merge."]},"children":["warren-897b","warren-879c","warren-e338"],"createdAt":"2026-06-11T09:05:59.371Z","updatedAt":"2026-06-11T09:23:51.640Z","name":"nightwatch patrol 2026-06-11: doc-drift + validation-message consistency"} -{"id":"pl-a04a","seed":"warren-6702","template":"refactor","status":"approved","revision":1,"sections":{"context":"Patrol scan of 2026-06-12 found one coherent cross-call-site inconsistency: warren parses \"is this env flag truthy\" (default-off flags) at least five different ways with divergent accepted-token sets and case handling, so the same conceptual flag behaves differently depending on which subsystem reads it.\n\nDefault-OFF (truthy) parsers, today:\n- src/server/probe.ts:75 — inline `disabledRaw === \"1\" || disabledRaw === \"true\"` for WARREN_WORKER_PROBE_DISABLED. Case-sensitive, no trim, accepts only 1/true. `=TRUE`, `=Yes`, `=on` are silently ignored.\n- src/server/config.ts:128 — inline `disabled === \"1\" || disabled === \"true\"` for WARREN_DISABLE_UI. Case-sensitive, accepts only 1/true (the doc comment at config.ts:20 even says \"'1'/'true' to disable\"), so `=on`/`=yes`/`=TRUE` are ignored.\n- src/supervisor/main.ts:382 `parseBoolEnv` — `raw === \"1\" || raw.toLowerCase() === \"true\"` for WARREN_BURROW_NO_AUTH (controls burrow `--no-auth`). Lowercases only `true`, accepts 1/true, not yes/on.\n- src/server/main/utils.ts:80 `parseTrueEnv` — trim+lowercase, accepts 1/true/yes (NOT on). Used by detector/poller/idle flags.\n- src/preview/eviction/config.ts:74 and src/runs/reap/gc.ts:107 `isTruthy` (byte-identical) — trim+lowercase, accepts 1/true/yes/on.\n\nBy contrast the default-ON (falsy/opt-out) parsers already agree on one set — `0/false/no/off` — across src/triggers/config.ts:63, src/plan-runs/config.ts:77, and src/runs/pr.ts:387. The truthy side should reach the same internal consistency. The canonical target token set is `1/true/yes/on`, trimmed and case-insensitive (the broadest existing behavior, symmetric with the falsy `0/false/no/off`).\n\nThis is a correctness/consistency finding, not new behavior: an operator setting WARREN_WORKER_PROBE_DISABLED=on or WARREN_DISABLE_UI=TRUE today gets surprising no-ops. No public API signature changes; no new module is required (parseTrueEnv already exists as the reference implementation).","behavior_invariant":"Every truthy env-var parse keeps its existing default (absent or empty value => false) and keeps accepting the values it accepts today: `1` and `true` must remain truthy at every call site. The HTTP query-param boolean parser `parseBoolean` in src/server/handlers/index.ts (which intentionally rejects unknown values rather than coercing) is OUT of scope and must NOT change. The default-ON opt-out parsers (triggers/config.ts, plan-runs/config.ts, runs/pr.ts) must NOT change. No route, response shape, or public function signature changes. The only observable difference is that previously-ignored truthy spellings (case variants, surrounding whitespace, and the `yes`/`on` tokens) are now honored uniformly.","approach":"Converge all default-OFF truthy env parsers on a single accepted token set — `1`, `true`, `yes`, `on` — compared after `.trim().toLowerCase()`, matching the existing `isTruthy` in eviction/config.ts and reap/gc.ts and symmetric with the falsy `0/false/no/off` set. Use the already-exported `parseTrueEnv` (src/server/main/utils.ts) as the canonical reference: extend it to also accept `on`, then route the divergent inline parsers through the same token logic. Keep changes minimal and local — do not introduce a new shared module or change any signatures; where a call site cannot cleanly import the canonical helper (e.g. the supervisor, which crosses the warren↔burrow boundary), harmonize its inline token set in place. Split the supervisor change into its own step because WARREN_BURROW_NO_AUTH gates burrow's `--no-auth` and lives across the warren↔burrow boundary that AGENTS.md flags for extra review.","steps":[{"title":"Harmonize app-side truthy env parsers on 1/true/yes/on (case-insensitive)","type":"task","priority":3,"blocks":[3],"labels":["nightwatch"]},{"title":"Harmonize supervisor parseBoolEnv for WARREN_BURROW_NO_AUTH","type":"task","priority":3,"blocks":[3],"labels":["nightwatch"]},{"title":"Release: run /release per .claude/commands/release.md","type":"task","priority":3,"blocks":[],"labels":["nightwatch"]}],"acceptance":["Step 1 — src/server/probe.ts (WARREN_WORKER_PROBE_DISABLED) and src/server/config.ts (WARREN_DISABLE_UI) trim+lowercase their raw value and accept 1/true/yes/on; src/server/main/utils.ts parseTrueEnv also accepts `on` so it, isTruthy (eviction/config.ts, reap/gc.ts), probe.ts and config.ts all recognize the same four tokens. The WARREN_DISABLE_UI doc comment in src/server/config.ts:20 is updated to list the accepted set. New/updated unit tests assert each parser treats `On`, `YES`, ` true `, and `1` as true and `0`/empty/undefined/`off` as false.","Step 2 — src/supervisor/main.ts parseBoolEnv trims, lowercases, and accepts 1/true/yes/on; an added test asserts WARREN_BURROW_NO_AUTH variants (`On`, `YES`, ` true `) enable no-auth while absent/empty/`0`/`false` keep auth on (fail-safe default preserved).","Regression: `1` and `true` remain truthy everywhere they were before; the opt-out parsers (triggers/config.ts, plan-runs/config.ts, runs/pr.ts) and the HTTP query parseBoolean are unchanged.","bun test, bun run lint, and bun run typecheck all pass; bun run check:all is green."]},"children":["warren-c27f","warren-83ae","warren-1b53"],"createdAt":"2026-06-12T09:06:24.600Z","updatedAt":"2026-06-12T09:06:24.600Z","name":"Harmonize truthy boolean env-var parsers"} +{"id":"pl-a04a","seed":"warren-6702","template":"refactor","status":"done","revision":1,"sections":{"context":"Patrol scan of 2026-06-12 found one coherent cross-call-site inconsistency: warren parses \"is this env flag truthy\" (default-off flags) at least five different ways with divergent accepted-token sets and case handling, so the same conceptual flag behaves differently depending on which subsystem reads it.\n\nDefault-OFF (truthy) parsers, today:\n- src/server/probe.ts:75 — inline `disabledRaw === \"1\" || disabledRaw === \"true\"` for WARREN_WORKER_PROBE_DISABLED. Case-sensitive, no trim, accepts only 1/true. `=TRUE`, `=Yes`, `=on` are silently ignored.\n- src/server/config.ts:128 — inline `disabled === \"1\" || disabled === \"true\"` for WARREN_DISABLE_UI. Case-sensitive, accepts only 1/true (the doc comment at config.ts:20 even says \"'1'/'true' to disable\"), so `=on`/`=yes`/`=TRUE` are ignored.\n- src/supervisor/main.ts:382 `parseBoolEnv` — `raw === \"1\" || raw.toLowerCase() === \"true\"` for WARREN_BURROW_NO_AUTH (controls burrow `--no-auth`). Lowercases only `true`, accepts 1/true, not yes/on.\n- src/server/main/utils.ts:80 `parseTrueEnv` — trim+lowercase, accepts 1/true/yes (NOT on). Used by detector/poller/idle flags.\n- src/preview/eviction/config.ts:74 and src/runs/reap/gc.ts:107 `isTruthy` (byte-identical) — trim+lowercase, accepts 1/true/yes/on.\n\nBy contrast the default-ON (falsy/opt-out) parsers already agree on one set — `0/false/no/off` — across src/triggers/config.ts:63, src/plan-runs/config.ts:77, and src/runs/pr.ts:387. The truthy side should reach the same internal consistency. The canonical target token set is `1/true/yes/on`, trimmed and case-insensitive (the broadest existing behavior, symmetric with the falsy `0/false/no/off`).\n\nThis is a correctness/consistency finding, not new behavior: an operator setting WARREN_WORKER_PROBE_DISABLED=on or WARREN_DISABLE_UI=TRUE today gets surprising no-ops. No public API signature changes; no new module is required (parseTrueEnv already exists as the reference implementation).","behavior_invariant":"Every truthy env-var parse keeps its existing default (absent or empty value => false) and keeps accepting the values it accepts today: `1` and `true` must remain truthy at every call site. The HTTP query-param boolean parser `parseBoolean` in src/server/handlers/index.ts (which intentionally rejects unknown values rather than coercing) is OUT of scope and must NOT change. The default-ON opt-out parsers (triggers/config.ts, plan-runs/config.ts, runs/pr.ts) must NOT change. No route, response shape, or public function signature changes. The only observable difference is that previously-ignored truthy spellings (case variants, surrounding whitespace, and the `yes`/`on` tokens) are now honored uniformly.","approach":"Converge all default-OFF truthy env parsers on a single accepted token set — `1`, `true`, `yes`, `on` — compared after `.trim().toLowerCase()`, matching the existing `isTruthy` in eviction/config.ts and reap/gc.ts and symmetric with the falsy `0/false/no/off` set. Use the already-exported `parseTrueEnv` (src/server/main/utils.ts) as the canonical reference: extend it to also accept `on`, then route the divergent inline parsers through the same token logic. Keep changes minimal and local — do not introduce a new shared module or change any signatures; where a call site cannot cleanly import the canonical helper (e.g. the supervisor, which crosses the warren↔burrow boundary), harmonize its inline token set in place. Split the supervisor change into its own step because WARREN_BURROW_NO_AUTH gates burrow's `--no-auth` and lives across the warren↔burrow boundary that AGENTS.md flags for extra review.","steps":[{"title":"Harmonize app-side truthy env parsers on 1/true/yes/on (case-insensitive)","type":"task","priority":3,"blocks":[3],"labels":["nightwatch"]},{"title":"Harmonize supervisor parseBoolEnv for WARREN_BURROW_NO_AUTH","type":"task","priority":3,"blocks":[3],"labels":["nightwatch"]},{"title":"Release: run /release per .claude/commands/release.md","type":"task","priority":3,"blocks":[],"labels":["nightwatch"]}],"acceptance":["Step 1 — src/server/probe.ts (WARREN_WORKER_PROBE_DISABLED) and src/server/config.ts (WARREN_DISABLE_UI) trim+lowercase their raw value and accept 1/true/yes/on; src/server/main/utils.ts parseTrueEnv also accepts `on` so it, isTruthy (eviction/config.ts, reap/gc.ts), probe.ts and config.ts all recognize the same four tokens. The WARREN_DISABLE_UI doc comment in src/server/config.ts:20 is updated to list the accepted set. New/updated unit tests assert each parser treats `On`, `YES`, ` true `, and `1` as true and `0`/empty/undefined/`off` as false.","Step 2 — src/supervisor/main.ts parseBoolEnv trims, lowercases, and accepts 1/true/yes/on; an added test asserts WARREN_BURROW_NO_AUTH variants (`On`, `YES`, ` true `) enable no-auth while absent/empty/`0`/`false` keep auth on (fail-safe default preserved).","Regression: `1` and `true` remain truthy everywhere they were before; the opt-out parsers (triggers/config.ts, plan-runs/config.ts, runs/pr.ts) and the HTTP query parseBoolean are unchanged.","bun test, bun run lint, and bun run typecheck all pass; bun run check:all is green."]},"children":["warren-c27f","warren-83ae","warren-1b53"],"createdAt":"2026-06-12T09:06:24.600Z","updatedAt":"2026-06-12T09:23:59.362Z","name":"Harmonize truthy boolean env-var parsers"}