Skip to content

feat(build/wrap-console): classify console.warn/error into halt events (PR 3 of 7)#54

Merged
anbangr merged 2 commits into
mainfrom
halt-events-wrap-console
May 19, 2026
Merged

feat(build/wrap-console): classify console.warn/error into halt events (PR 3 of 7)#54
anbangr merged 2 commits into
mainfrom
halt-events-wrap-console

Conversation

@anbangr

@anbangr anbangr commented May 19, 2026

Copy link
Copy Markdown
Owner

Summary

Third PR in the 7-PR halt-events rollout. Adds the wrapConsole shim that classifies every console.warn / console.error line in the orchestrator into a SOFT_HALT_WARN / SOFT_HALT_ERROR / SILENT_STATE_MUTATION halt event.

The orchestrator emits 281 console.warn/error calls today, only ~7 of which are caught by the explicit helpers in PRs 1+2. This PR catches the rest — the "soft halt" class invisible to structured detection.

What's new

New module: build/orchestrator/wrap-console.ts (147 lines)

  • classifyConsoleLine(level, msg) — pure function, maps a message to { kind, severity }.
  • installWrapConsole(ctx) — wraps console.warn / console.error globally. Returns an uninstall function.

Pattern table (matched in order):

  • /Re-processing the feature/i → SILENT_STATE_MUTATION (HIGH) — catches the polis hand-merged-feature class from any code path that prints it (also explicitly emitted at cli.ts:9548 in PR 2; matches dedupe via faultId).
  • /worktree cleanup failed/i → SOFT_HALT_WARN (LOW)
  • /PR check unsettled|PR not yet mergeable/i → SOFT_HALT_WARN (LOW)
  • /branch deletion failed/i → SOFT_HALT_WARN (LOW)
  • ^✗ (orchestrator's error sigil) → SOFT_HALT_ERROR (MEDIUM)
  • Unmatched warn → SOFT_HALT_WARN (LOW)
  • Unmatched error → SOFT_HALT_ERROR (MEDIUM)

Safety knobs:

  • GSTACK_HALT_EVENTS_OFF=1 short-circuits installation (debug escape hatch).
  • NODE_ENV=test + no explicit queueDir is a no-op (tests don't pollute the user's real queue).
  • Wrapper calls original console.warn / console.error FIRST, then attempts the emit. emit failures are swallowed silently — the shim never crashes the orchestrator.

cli.ts wiring (one site, in main() around line 9442):

  • Installed AFTER state loading (so helperCtxFor(state) is valid).
  • Installed AFTER mode dispatchers exit (drain-faults / mark-shipped / doctor / monitor all process.exit before this block — they don't get the shim, matching the "build mode only" intent).
  • Installed AFTER orphan-sweep warnings at line 9023-9027 (those print BEFORE state exists; installing earlier would queue them as halt events from startup noise).
  • Uninstalled FIRST in the outer finally (cleanup warnings hit the real console.warn, not the wrapped one).

Bisectable commits

  1. a0571513 — wrap-console module + 14 tests + MODULE_TEST_OWNERS registration.
  2. e3031fa6 — wire installWrapConsole(helperCtxFor(state)) into the orchestrator's main entry with try/finally uninstall.

Test plan

  • bun test build/orchestrator/__tests__/wrap-console.test.ts — 14 pass / 0 fail
  • bun test build/orchestrator/__tests__/coverage-matrix.test.ts — 4 pass / 0 fail
  • bun test build/orchestrator/__tests__/ — 1402 pass / 16 fail. Same 16 pre-existing failures as PR 2's baseline; zero new failures.
  • rg -n 'installWrapConsole\\(' build/orchestrator/cli.ts — 1 match (single install site).

Versioning

Fork-local skill work per CLAUDE.md ## Fork versioning rule. No top-level VERSION/CHANGELOG bump. No *.tmpl changed — no skill-frontmatter bump either.

Plan reference

  • Spec: ~/.claude/plans/i-want-the-idempotent-dream.md
  • Implementation plan: docs/superpowers/plans/2026-05-19-idempotent-dream-halt-events.md

PRs 4-7 remaining:

  • PR 4: state_jsonpath matcher + HAND_MERGED_FEATURE detector + E2E pin
  • PR 5: investigator dispatch + drain-faults extension + configure.cm investigator role
  • PR 6: end-of-build auto-drain + cost guardrails
  • PR 7: learn-fault-patterns sub-function in build/SKILL.md.tmpl

🤖 Generated with Claude Code

anbangr added 2 commits May 19, 2026 21:13
…RROR

Wraps console.warn / console.error and emits halt-events for each line
based on pattern classification. Patterns:
- "Re-processing the feature" → SILENT_STATE_MUTATION (HIGH)
- "worktree cleanup failed" → SOFT_HALT_WARN (LOW)
- "PR check unsettled" / "PR not yet mergeable" → SOFT_HALT_WARN (LOW)
- "branch deletion failed" → SOFT_HALT_WARN (LOW)
- "✗ " error sigil → SOFT_HALT_ERROR (MEDIUM)
- Unmatched → SOFT_HALT_WARN/ERROR at level-appropriate severity

Original console behavior preserved (wrapper calls original first).
Env-gated by GSTACK_HALT_EVENTS_OFF=1 and a NODE_ENV=test guard so
test runs don't spam the user's real queue.
Captures soft-halt class (console.warn / console.error lines) into the
halt-events queue. Installed only for the build run loop (not for
drain-faults, mark-shipped, doctor, monitor — those have separate
flows). Uninstall in finally so the shim is always removed on exit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant