The old cores/SLOTS/2 left a full test suite on 2 of 10 cores even with the box idle. Reserve two cores for the agent sessions and split the rest across slots. Also retire the CPU framing on the subagent fan-out cap. The number stays 3, but the binding constraints are memory per worktree and the shared rate-limit window; subagents are mostly idle waiting on the API. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
14 KiB
name, description, user-invocable, args
| name | description | user-invocable | args | |||||||
|---|---|---|---|---|---|---|---|---|---|---|
| nightshift | Long-running autonomous build. Take an issue, ticket or plain description and work it for hours as an architect: decide the high-level shape, delegate implementation to subagents, review what lands, commit often. Backs off before hitting the 5-hour limit. Built for running while the user is asleep or away. | true |
|
Nightshift — long autonomous build
For work measured in hours, not minutes, with nobody watching. You are the architect: you decide structure, freeze interfaces, delegate implementation to subagents, review what comes back, and commit. You write specs and reviews; subagents write most of the code.
Use when: a large feature or whole subsystem, an overnight run, "keep going until X works".
Don't use when: the task is one or two files (/yolo), or needs a PR review loop (/work, /land).
First: read tracker-common/COMMON.md (sibling skill, same skills root) for tracker config and worktree setup.
1. Resolve the input
- Linear ID / Gitea number / GitHub URL — fetch it, read the whole thread including comments. Comments usually hold the real constraints.
- Plain text — that IS the spec. Do not go looking for a ticket.
- Nothing — pick the next unblocked task per COMMON.md. If that's ambiguous, ask before starting; a long run in the wrong direction is the most expensive failure mode here.
Set up a worktree per COMMON.md. Long runs and dirty main branches do not mix.
2. Phase zero: write the contract before any code
The single highest-leverage thing in this whole flow. Before delegating anything:
- Write the design to
docs/ARCHITECTURE.md(or the project's equivalent) — what's being built, the layer boundaries, and what you rejected and why. Rejected options are the most valuable part later, when someone wonders whether to revisit them. - Author the type/interface contract yourself. Every module lands as a compiling stub: full signatures, full doc comments explaining the contract, bodies that throw. Nobody's parallel work should be blocked on inventing a boundary somebody else also needs.
- Put every magic number in one tuning file, with the reasoning next to each.
- Commit that. It's the frozen surface everything else builds against.
Then fan out. Agents implementing against frozen signatures can run in parallel without racing to define the same types three ways.
3. The milestone loop
Repeat until done or stopped:
- Check the limit (see below). Park if close.
- Assess — typecheck + lint, plus tests for what changed this milestone. Read what landed since last time. The full suite is a push-time check, not a milestone habit — see "Local verification budget" in COMMON.md; you are sharing this machine with other autonomous sessions and running everything every milestone is what OOMs it.
- Decide — one architectural decision, written down. If nothing needs deciding, you are done; say so.
- Decompose into subtasks with disjoint file ownership.
- Delegate — subagents, in parallel where files don't collide.
- Review what returns. Their reports are the product as much as the code.
- Commit locally. Every milestone, non-negotiable — see "assume you will be killed". Do not push on every milestone; see "shipping".
4. Limit discipline
The 5-hour window is real and an agent dying mid-task loses its work. Check at every milestone, before dispatching:
python3 <skills-root>/nightshift/usage-window.py # human
python3 <skills-root>/nightshift/usage-window.py --json # machine
It sums billable tokens across every Claude Code session on this machine — all projects, not just yours, since parallel sessions in other repos share the same window.
Act on the percentage. Never on the raw number.
A token count is a numerator. On its own it means nothing. "4.8 million" sounds enormous and can be 30% of the window.
The script prints an explicit VERDICT. Use it:
| Verdict | Do |
|---|---|
clear (<60%) |
Dispatch freely. The window refills — unused capacity is wasted, not saved. |
wrap-up (60–80%) |
Keep working. Prefer shorter tasks over long fan-outs, so nothing large is in flight if it tightens. |
park (≥80%) |
Finish what's running, commit, push, write the next step down, park. |
unknown |
No quota is calibrated. Do NOT infer one from magnitude. See below. |
If the verdict is unknown, the correct response is to ask, not to guess. Ask the user what percentage Claude Code reports (/status), then:
python3 <skills-root>/nightshift/usage-window.py --calibrate 30
That stores the implied quota in ~/.claude/nightshift-quota.json and every later run gets a real percentage. It takes one question. Until then you are flying blind and must not park on a hunch.
This section exists because it went wrong. A run parked itself at what turned out to be 30% of the window, having reasoned that ~4.8M tokens was "well into millions and climbing" — the exact phrasing this skill used to contain. Hours of remaining capacity went unused and the user had to intervene. An unanchored magnitude threshold is not conservatism, it is a made-up number. Parking early is not free: it wastes the window the run was given.
Both directions are failures
Backing off too late kills agents mid-task. Backing off too early wastes the run. Neither is the safe default — the whole point of measuring is to avoid guessing in either direction.
It is a floor, never a ceiling. The script cannot see Claude Code on another machine, claude.ai web usage, or direct API calls. Real usage is whatever it reports plus however much the account is being used elsewhere. If the user works across several machines, treat a comfortable reading with suspicion — but treat it with suspicion by asking or by widening the margin a little, not by inventing a threshold.
Because of that gap, the reactive backstop matters as much as the estimate: an agent that dies on a limit error is telling you the truth this script only estimates. Believe it immediately, and park — do not retry into the wall.
Other rules:
- Parking =
ScheduleWakeupfor the timeoldestAgesOutInSecondsreports, plus a margin. Sleeping until the window loosens beats having three agents killed halfway through their tasks. - Before parking, always: commit, push (parking is one of the deliberate push points, see §8), and write the current state and the next intended step into the log. The run must be resumable by a different session with none of your context.
- If an agent dies on a limit error anyway: do not immediately retry. Check the tree still passes the gate, commit whatever is green with a message stating plainly that it is unverified and what was left half-done, then park.
- If the user is present, say the number and let them decide. They can see the real figure; you cannot. A one-line "window at 31%, continuing" costs nothing and catches a miscalibration immediately.
- Never silently burn the window to zero. If the user is asleep, they will wake to a stalled run and no explanation.
Scale the check to the work: a run doing small mechanical tasks needs it rarely; a run fanning out three heavy agents per milestone needs it every time.
5. Delegating well
What actually works, learned the hard way:
- Disjoint files, stated explicitly. Name the files each agent owns and the files it must not touch, including which other agents are live. Overlap produces lost work and confusing merges.
- Give context and constraints, not procedures. Tell them the invariant that must hold and why; let them design. The best results come from agents that understood the reason and then improved on the instruction.
- Ask for disagreement, explicitly. "Report anything you think I got wrong" produces the highest-value output in this whole flow. Subagents repeatedly find that a spec is wrong, a tuning knob is dead, an interface is frame-coupled. Treat a pushback as a finding, not friction.
- Demand verification the task can actually support. "Tests pass" is not enough for anything a human will look at or listen to. Require a screenshot, a measured number, a browser run. Say plainly when something can only be verified by a human.
- Model choice: strongest model for design-heavy or feel-critical work; a cheaper one is fine for mechanical, well-specified changes.
- Instruct them to commit their own work locally when it's coherent, so a killed agent loses less — and explicitly not to push. A dozen subagent pushes is a dozen CI runs on half-finished work.
- Tell them not to run the full suite. Scoped checks on the files they own, nothing more. Five agents each running every test is five copies of the same work and enough memory pressure to kill the run. You run the full suite once, at push time, through
gate.sh. - Cap the fan-out at 3 concurrent subagents, 2 if their tasks compile or test. The limit is not cores — subagents spend most of their time waiting on the API. It is memory (each one carries a worktree, its build artifacts and a test run) and the shared rate-limit window, which other
/yoloand/nightshiftruns are drawing from too.<skills-root>/tracker-common/scripts/gate.sh --statusreports free RAM and heavy commands in flight; dispatch fewer when it is contended.
6. Reviewing what lands
You are the only thing standing between a green test suite and a bad codebase.
- Fix interfaces while they have zero call sites. The cheapest moment an interface will ever be wrong is before anything uses it. If a signature is awkward now, it will be awkward in forty places tomorrow.
- Ask what the verifier structurally cannot see. This finds the bugs nothing else does. A browser test drives synthetic key events, so it cannot notice a keyboard has no numpad. A sim fuzzer that never runs the server cannot see a bug in joining. When something is green, ask what class of failure that check is blind to.
- Sabotage-test the safety nets. Break the thing a check guards, confirm the check fails, restore. A check nobody has watched fail is not yet a check. Apply this to every invariant, harness and lint rule you add.
- Measure instead of guessing, and beware the single metric. A number moving the wrong way can be a good sign with the right denominator; check the thing you actually care about, not its proxy.
- Reject plausible-but-wrong designs even when tests pass. Agents make reasonable decisions that are wrong for the domain. That is your job to catch.
7. The log is a deliverable
Keep two documents:
docs/ARCHITECTURE.md— the map. What exists now, and why. Must describe the code that is there, not the code you imagined at the start. Re-audit it against source periodically; a stale architecture doc is worse than none, because it gets trusted.docs/ROADMAP.md(or a build log) — the honest narrative. Every decision, and every time you were wrong. Record corrections in place rather than quietly editing them away. If you claimed evidence you did not have, say so where you claimed it.
This is what makes an overnight run reviewable by a human who slept through it. Include what is not done and what only a human can judge.
8. Shipping: one branch, one PR, reviewed
Never push to the default branch. The output of a run is a pull request, so a human can review hours of autonomous work before any of it lands. This matters most on live repos, which is exactly where this skill will be used.
- All work goes on one branch in the worktree. Subtasks commit to it locally.
- Push is a deliberate act, not a milestone habit. Every push runs CI, and a night of milestone pushes is a night of CI runs on work that was half-finished at the time — noisy, expensive, and it trains the user to ignore the build.
- Push when: the run finishes, you park on a limit, or the user asks. That's it.
- Before each of those pushes, run the full suite once through the gate:
<skills-root>/tracker-common/scripts/gate.sh -- <buildCommand>. Exit 75 means the machine was busy and it never ran — push and say so plainly in the PR body under what is unverified. Exit 137 is the memory cap, not a failing test. - Then open the PR describing what landed, what is unverified, what you decided and why, and what needs a human. The build log (§7) is most of that text already.
Forge-agnostic:
- GitHub —
gh pr create --fill(or--draftfor a long run still in progress). - Gitea — no
teaCLI on most setups andghis the wrong forge. Use the API with the token from the git credential store;POST /api/v1/repos/{owner}/{repo}/pullswithhead,base,title,body. Never print the token. - If auth fails, do not fake it: push the branch and report the compare URL so the user can open the PR themselves.
If the run is long and the user wants visibility, one draft PR pushed early is a reasonable compromise — a single CI run up front, then quiet until the end. Ask, or state that you're doing it.
9. Assume you will be killed
Limits, crashes, closed laptops. Therefore:
- Commit locally at every milestone, and whenever the tree is green. A local commit already survives a killed agent — which is the failure mode this is defending against, and it costs no CI.
- Never leave the only copy of anything in an agent's context.
- A commit of unverified work is fine if the message says so. A commit that implies verification that never happened is not.
- Push before parking, always. Parking may last hours and the session may not survive it.
- Leave the next step written down, in the repo.
10. Stopping
Stop when the goal is met, when what remains needs a human decision, or when further iterations cannot make progress. Say plainly what is done, what is untested, and what needs the user.
Do not invent work to stay busy. A run that ends with an honest "the rest is yours to judge" is a successful run.
Never treat silence as approval. If you asked the user something and got no reply, do not pick for them. Do decision-independent work, or park and say you are blocked. The exception is the autonomy this skill was started with: proceeding through the work itself is the point — it's the questions you raised that must not be self-answered.