9.1 KiB
| name | description |
|---|---|
| lights-out | Use when the user is going to bed, going away, or wants unattended overnight coding work; says "lights out", "run this overnight", "keep working while I sleep", or names gnhf; asks to check on, steer, or stop a running overnight job; asks "how did last night's run go", says "good morning", or wants a morning review of an agent run; or gives review findings on the results of an overnight run. |
Lights Out
Overview
Lights Out delegates a long-running coding objective to gnhf, which loops a coding agent until a
natural-language stop condition is met. Scout prepares and supervises the run; gnhf executes it.
Core rule: you orchestrate, gnhf implements. Do not hand-edit files inside a scope a live gnhf worker owns. If the work needs correcting, launch a new bounded run rather than taking over.
Second rule: a stop condition being met is not acceptance. "Stopped" only means the worker stopped. Compare the result against the user's actual request and your own fresh verification.
Why a wrapper instead of running gnhf directly
The Scout session that starts a night run is usually gone before it ends — the app gets closed, the machine is left alone. So anything that must happen at exit cannot live in the conversation.
| Tier | Runs as | Guaranteed | Responsibility |
|---|---|---|---|
| Finalize | PowerShell, inside the detached worker | Always | Capture commits, diff, end-state, re-run verification, write the vault note |
| Judgment | You, on demand | When asked | Assess quality, decide merge vs follow-up, fill in the Assessment section |
| Push | One-shot automation | Opt-in | Morning Teams digest |
Never promise the user a summary that depends on this session still being alive.
Scripts
Always go through these. Never invoke gnhf directly — the preflight is the entire point.
$LO = "$env:USERPROFILE\.scout\m-skills\lights-out\scripts"
| Script | Use |
|---|---|
$LO\start-run.ps1 |
Preflight, launch detached, register the run |
$LO\check-run.ps1 |
Reconstruct state: polling, morning review, "what happened" |
State registry: ~\.scout\lights-out\runs.json. This is the handoff file. A brand-new session
with no memory of the launch conversation finds every run here. Read it before saying you don't know
about a run.
gnhf is vendored
The skill ships its own pinned copy of gnhf at vendor\node_modules\gnhf\, so it does not depend on
a global npm install -g gnhf and cannot be broken by someone uninstalling or upgrading one.
Resolution order:
$env:LIGHTS_OUT_GNHF— explicit override (used by the test suite)- the vendored copy, run as
node vendor\node_modules\gnhf\dist\cli.mjs gnhfon PATH — fallback only
Only node needs to be on PATH. Every run records which one it used (gnhfKind, gnhfVersion) in
the registry and the vault note, so a behavior change after an upgrade is traceable.
To update the pinned copy:
npm install gnhf --prefix "$env:USERPROFILE\.scout\m-skills\lights-out\vendor"
pwsh -NoProfile -File "$env:USERPROFILE\.scout\m-skills\lights-out\scripts\test\e2e.ps1"
Re-run the suite after upgrading — it asserts the flags the wrapper passes still exist.
Launch
Gather these before launching. Ask for anything missing rather than guessing:
- Repo path — must be a git repo with a clean tree.
- Objective — one concrete outcome.
- Stop condition — observable. "Looks good" is not one; "
npm testexits 0 and no files outsidesrc/utilschanged" is. - Verification command — how success is checked. Must actually exist on this machine.
- Agent — default
copilot. Others:claude,codex,cursor,opencode,rovodev,pi,acp:<target>. - Mode — Hands-Off or Companion (below).
& "$LO\start-run.ps1" `
-RepoPath 'D:\Repos\myapp' `
-Prompt '<worker prompt — see references\prompts.md>' `
-Title 'Short Title For The Vault Folder' `
-StopWhen '<observable condition>' `
-VerifyCommand 'npm test' `
-Agent copilot `
-MaxIterations 40 `
-Mode hands-off
Returns JSON. If ok is false, report the problems list to the user and stop. Do not try to
work around a failed preflight — each check maps to a way the night silently dies:
| Check | What it prevents |
|---|---|
| gnhf unresolvable | Vendored copy deleted and no global install — nothing to run |
| Empty prompt | gnhf blocks forever reading stdin with no TTY |
| Dirty working tree | gnhf refuses to start |
Already on a gnhf/* branch |
Triggers an interactive overwrite prompt that hard-fails without a TTY |
| Agent CLI missing | Run dies on iteration 1 at 2am |
| Verify command not on PATH | The classic: docs say pnpm, machine only has npm |
Pass -Worktree to run alongside other work, -CurrentBranch to commit on the current branch, and
-Push to push after each successful iteration.
Modes
Hands-Off — bounded task, clear verification, user is asleep. Launch, report the run id, stop. Intervene only for hard failure or destructive behavior.
Companion — uncertain, exploratory, or design-heavy work; the user is around and wants steering.
Default to Companion when the user asks to iterate until satisfied, supplies review findings, or
asks for supervision. Poll with check-run.ps1 between iterations.
Steer
In Companion mode, judge each poll:
| Signal | Action |
|---|---|
| Real blocker found | Stop; relaunch with blocker-specific instructions |
| Good partial slice | Let it run, or tighten the next stop condition |
| Skipped requested research | Relaunch with research as the explicit first deliverable |
| Touching unrelated files | Stop and review before continuing |
| Claims success, verification disagrees | Review now; relaunch only with an evidence-based stop condition |
| User says not good enough | Relaunch with that finding as the sole bounded correction |
Steering means a new bounded run, not editing the files yourself.
Morning Review
Triggered by "good morning", "how did it go", or any post-run check-in. Never answer from memory and never ask the user what to review. Reconstruct:
& "$LO\check-run.ps1" -Since 2
Then:
- If
statusisrunning, say so first — it is still working; report progress, don't judge it. - If
statusisorphaned, the worker died without finalizing (reboot, kill, power loss). Say that plainly; the vault note will be missing and artifacts may be partial. - Read
vaultNote,notesTail, and the commits. Treat gnhf's notes as claims, not evidence. - Run independent verification yourself — the recorded
verifyExitCodeAfteris a starting point, not a substitute for looking at the diff. - Compare against the stop condition and what the user originally asked for.
- Decide: Mergeable, Needs follow-up run, or Do not merge.
Then write the judgment back into the vault note (below). Do not merge unless explicitly authorized.
Writing the assessment back
The wrapper leaves ## Assessment as a stub. Complete it:
- Open the
vaultNotepath fromcheck-run.ps1. - Replace the Assessment section with your findings and verdict.
- Set
status: activein frontmatter, swap thestatus/drafttag forstatus/active, bumpupdated:. - Leave every other file in the folder untouched — they are raw artifacts (vault rule 4).
Findings
When the user says "that's not right", "scope drift", "you missed X", or "why did it stop":
- Treat the run as Companion from now on.
- Convert each finding into one observable correction, preserving the user's wording and scope.
- Relaunch on the same repo with a bounded prompt (see
references\prompts.md). - Review again. Repeat until no blocking findings remain or a real blocker surfaces.
Optional morning digest
Only if the user wants a phone ping. Offer it at launch; never create it silently. Use a one-shot automation so it auto-disables and does not accumulate:
m_create_automation(
name: "Lights Out digest — <run id>",
schedule: "every day at 7am", // the next morning
oneShot: true,
teamsNotify: "always",
prompt: "Run the lights-out Morning Review for run <run id>: execute
$env:USERPROFILE\\.scout\\m-skills\\lights-out\\scripts\\check-run.ps1 -Id <run id>,
assess the result, write the assessment back into the vault note, and send a short digest."
)
The digest is a convenience. The artifacts land on disk with or without it.
Safety
- Never run destructive git commands to tidy a gnhf branch. The branch is the night's work.
- Never present a worker's success summary as verified fact.
- If the user is away, produce branches and a report — not merges, not pushes to shared branches, unless they explicitly authorized it beforehand.
- A run left on
status: runningwith a dead worker isorphaned, not successful. Say so. - Stop conditions must be observable. Rewrite vague ones before launching.
References
references\prompts.md— worker, steering, and findings prompt templates.references\cli.md— gnhf flags and agent roster (a cache;gnhf --helpis the source of truth).