Conversation
- shift/install.sh wires the Stop hook into ~/.claude/settings.json idempotently (backup -> merge -> validate -> atomic move); never duplicates, updates the path on repo move, preserves existing hooks/settings. - shift/lib/install.cjs: pure mergeStopHook() (tested); install.sh is a thin shell. - shift/test/install.test.cjs: 7 tests (unit merge + live install.sh integration). - README (root): list shift in the Modules table + candor pointer. - shift/README: swap manual hook-wiring for the installer; resolve the hook-schema caveat (block/reason contract verified against the Claude Code hooks docs).
|
Merge-prep pushed (e172bb0).
Still draft pending the manual end-to-end smoke (PLAN Task 9) — the real |
A real `shift run` smoke confirmed headless `claude -p` honors the Stop-hook block and drives the queue warm (resolves the SPEC §9.2 open question). A pre-flight audit of the previously-untested runner path drove these fixes: - No false-green: classifyOutcome returns 'completed' only when the engine finalized (summary.md). A code-0 exit without finalize is 'incomplete' — the runner resumes if the queue advanced, else stops with a 'is the Stop hook wired?' diagnostic. `shift run` grades on summary.md, not the exit line. - Stale-reset guard: auto-resume stops cleanly when the cached reset time is already in the past (was a maxResumes-bounded busy-spin). - Per-spawn timeout (spawnTimeoutMinutes, default 30) kills a wedged claude so spawnSync can't hang the runner; launch failures + kills are surfaced. - Warn when a headless run uses a Bash-prompting permission mode. - Dropped a spurious audit suggestion (runner writing state.iterations) that would have double-counted the hook's bound tracking. 63 shift tests green (pure unit + hook/CLI/run-loop/install integration).
|
Hardening pushed (c7adfb8) — validated by a real smoke + audit. Ran a live A pre-flight adversarial audit of the previously-untested runner path then drove four fixes (each adversarially re-verified before commit; verdict: SHIP):
Dropped one spurious audit suggestion (making the runner write 63 |
|
Superseded by #2, which now targets |
Autonomous work-queue runner for Claude Code — built solid before merge (v1 + v2 + v3), plus the prior review fixes. 63 tests (
shift52,code-status-bar7, all green), zero dependencies.What it does
Pre-load bins of work (hand-written briefs and/or plugin plan folders), leave, and
shiftworks the queue autonomously until it's empty or a bound trips — surviving the 5-hour wall by waiting for the reset. You review the branch + summary at the end. Design:shift/SPEC.md,shift/PLAN.md.v1 — keep-going engine (Stop hook)
Marks each finished bin done, feeds back the next, finalizes on queue-empty / bound / kill switch. Bounds: time box + max iterations. Branch-only, no-push, decision log,
Needs you:flagging.v2 — all-day headless runner
shift runouter loop: spawn → let the engine grind → on a rate-limit wall, wait for the window to reset and resume; bounded by time, iterations, a usage cap, and a resume backstop.rate_limits) with config-overridable stderr patterns — no dependency on an exact exit code. Degrades gracefully when usage data is absent.v3 — per-bin verify gate
A bin counts as done only if
verify.commandpasses; failures re-feed it with the output up tomaxAttempts, then block it. Catches "looked done but wasn't."Review fixes (from the prior review)
usage-bar.cjs(was untested). 2. Hook resolves repo from the payloadcwd. 3. Summary surfaces loggedNeeds you:items. 4. Hardenedinstall.sh(temp→validate-JSON→move; piped local-file guard; Node check).Testing
runloop driven with injected effects (simulates a rate-limit→wait→resume→finalize cycle).bin/shift run(realclaudespawn) and a live rate-limit hit — flagged in SPEC §13.Operational note
Unattended runs that execute commands likely need
permissionMode: "dontAsk"(+permissions.allow) or"bypassPermissions";acceptEdits(default) only auto-approves edits. Documented inshift/README.md.Still a draft — review at your pace.