Appearance
Execution Workflows
Wave-based execution, atomic commits, task lifecycle CRUD. Every commit produced here obeys ADR-0004: one task, one commit, subject prefix task(M<NNN>-S<NNN>-T<NNNN>):.
np:execute-phase <N> [--verify-work]
The execution entry point. Reads milestone N's slices (waves) and their tasks, dispatches each slice in order. Every task runs through the Nubosloop; a single-pass executor → commit-task is forbidden (ADR-0010).
--verify-work is an opt-in chain. When passed, the workflow runs /np:verify-work $PHASE automatically after every slice is committed and finalize-milestone has produced the slice summaries. It carries the same hard-fail contract as a manual /np:verify-work (exit 1 on any Fail SC). Without the flag the workflow stops after finalize-milestone and verify-work stays a separate manual step, which is the right default when the operator wants to inspect commits before running the verifier. The flag appears in the init payload as auto_verify: true.
For each slice in order:
- Dispatch every task of the slice in parallel. Each task is one independent Nubosloop instance.
- Wait until every task in the slice is committed OR is
stuckOR hitplan-checker. - If any task is
stuckor hitplan-checker, stop the wave and exit non-zero. Previously committed tasks remain committed. - Move to the next slice.
When workflow.worktree_isolation: true, each slice runs inside an isolated git worktree (created at slice-start, fast-forward-merged + removed at slice-end). On failure the worktree stays in place for inspection — clean up with /np:reset-slice. See ADR-0008 for the full mechanism.
Per-task Nubosloop (6 steps)
Per task, per round (default cap loop.maxRounds=3):
- Pre-flight cache lookup (Round 1) —
loop-run-round --phase preflightcheckslearnings.jsonfor a cached pattern; a hit short-circuits the Researcher-Schwarm. - Researcher-Schwarm (on cache miss or re-route) —
swarm.research.k=3parallelnp-researcherspawns. Each writes a schema-boundresearch/spawn-<i>.md(researcher-output schema, hard-gated post-write). The deterministicmergeConsensusproposes;np-researcher-reconciler(Stage 2, ADR-0018) reads all spawns plus the proposal, classifies reasoning-trace agreement, picks contested decisions, and writes the finalM<NNN>-RESEARCH.md. A disagreement hard-gate keyed onagreement_scoreandcontested_countraises an askuser prompt when the swarm has not converged. Layer-C requires k audit entries (k-of-k gate). - Executor (R1) or Build-Fixer (R≥2) — a single LLM spawn writes code in
files_modified. Build-Fixer takes prior critic findings plus verify output as input. - Mechanical Checks — the orchestrator runs the task's
verifycommand plus stack linters (phpstan,pint,tsc,eslint);loop-audit-tool-useaudits Rule 9 (search-tool invocation) per spawn. - Critic (verify-green) — one
np-critic(sonnet) spawns and audits all three axes (style, tests, acceptance) in a single structured JSON. Per the Verdict-Only Contract (ADR-0010 §L5), the critic writes the full findings JSON to<report_path>and emits a small envelope as its final message, which keeps parent-context tokens bounded. - Route —
loop-run-round --phase post-critics --critic-outputs-path <file>returnsnext_action ∈ {commit, executor, researcher, askuser, plan-checker, stuck}. Zero findings routes tocommit-task. Otherwise it spawns the routed destination, increments the round, and returns to Step 3.
Headless-Subprocess Mode (Cost Layer L6, opt-in) routes the critic and researcher spawns through a claude -p subprocess for true parent-context detach when the runtime's native Agent tool is too costly. Default spawn.headless.enabled=false. See ADR-0010 §L6 and Configuration → spawn.
Stuck escalation
Hitting loop.maxRounds triggers a four-option askuser dialog: continue +5 rounds, replan, mark stuck, manual fix. A next_action=plan-checker route (locked-decision-violation, infrastructure-mismatch) gets a three-option dialog: replan, stuck, manual-fix. The loop always pulls the operator into the decision rather than exiting silently.
bash
/np:execute-phase 1
# or, auto-chain into verify-work on success:
/np:execute-phase 1 --verify-worknp:verify-work <N>
Post-execution verification. Spawns np-verifier (tier=sonnet) which reads the milestone's ROADMAP + CONTEXT, every slice's PLAN + SUMMARY, every task's PLAN + SUMMARY, and the task commits.
Output: M<NNN>-VERIFICATION.md with one entry per success_criterion. Each entry carries a status of Pass, Fail, Defer, or Pending. Subjective criteria (UX, "feels", usability) are left at Pending with a needs_user_confirm flag set; the pass-2 askuser gate resolves those interactively. Any Fail makes the workflow exit non-zero.
bash
/np:verify-work 1np:validate-phase <N>
Nyquist coverage audit. Spawns np-nyquist-auditor (tier=haiku) which walks every requirement in milestone scope and scores it COVERED / UNDER_SAMPLED / UNCOVERED based on whether at least one test observes the requirement's behavior directly. Writes M<NNN>-VALIDATION.md.
np:add-tests <N>
Persists Pass-classified cases from M<NNN>-VERIFICATION.md into test/uat/m<nnn>-<slug>.test.cjs using node:test format. Sentinel-preserving: user-authored tests outside the // >>> np:add-tests begin / end markers survive regeneration.
np:commit-task <M-S-T>
Atomic per-task git commit. Routes through lib/git.cjs:
assertCommittablePaths(files_modified)— hard-fails when all declared paths are gitignored; warns on partial.git add -- <files_modified>(no-A, no.).git commit -m "task(<M-S-T>): <title>".- Deletes the task's checkpoint at
.nubos-pilot/checkpoints/<M-S-T>.jsonon success. - Flips the task frontmatter status to
done.
The executor calls it; the user does not invoke it directly. If you ever need to manually finalize a task, this is the only safe way.
Since commit-task routes through lib/tasks.cjs::setTaskStatus, it also re-renders the slice's TODO.md rollup. The same is true for /np:skip, /np:park, /np:unpark, and /np:undo-task — every task-status transition keeps the slice TODO view live.
np:checkpoint
Per-task crash-safety pointer CRUD. Subcommands:
start <M-S-T>— write initial checkpoint withpendingstatus.transition <M-S-T> <new-status>—pending→in-progress→verifying→pre-commit.touch <M-S-T>— heartbeat update.show <M-S-T>— print the checkpoint JSON.
The executor uses transition exclusively. Direct Read/Write on the JSON is forbidden, because the wrapper enforces invariants.
np:pause-work
Stamps STATE.session.stopped_at and writes STATE.resume_file for an explicit handoff. Use this when stepping away mid-task; /np:resume-work will pick up cleanly later.
pause-work also captures a session snapshot to .nubos-pilot/state/session-snapshot.json (gitignored): current milestone and task, the last 10 task commits, every still-open / read handoff, and the live checkpoint ids. The snapshot is a best-effort write. Failures don't block the pause; the JSON payload returns snapshot_path and snapshot_error so the workflow can surface either.
np:resume-work
Classifies the current session state as one of:
- resume — explicit pause, resume_file present, continue from there.
- orphan — checkpoints exist but no pause was logged; the agent likely crashed.
- clean — no checkpoints, nothing in flight; start fresh.
Use after re-opening the host CLI on a project that was mid-execution.
Session-snapshot block. When .nubos-pilot/state/session-snapshot.json exists from a prior /np:pause-work, the JSON payload also includes a session_snapshot block with the captured milestone, task, last-5-commits, and open handoffs. The orchestrator surfaces this so operators (and re-spawned executors) re-enter with continuity context and do not have to re-read every milestone artifact to remember where they were.
Worktree awareness. When workflow.worktree_isolation is enabled, the JSON payload also includes:
worktree_isolation: true(always, so callers can branch)worktree: { slice_full_id, branch, path }(when the current task's slice has an active worktree; this is where the orchestrator shouldcdbefore re-spawning the executor)stale_worktrees[](any worktrees whose branch does NOT match the current task's slice: orphans from prior crashes, candidates for manual cleanup)
np:undo <N | M<NNN>-S<NNN>>
Revert every task commit of a milestone or slice via git revert --no-edit, with no history rewrite. Newest-first so dependency chains unwind cleanly. Every affected task's frontmatter is reset to pending so the next /np:execute-phase picks them up again.
bash
/np:undo 1 # revert every task of milestone M001
/np:undo M001-S002 # revert every task of slice M001-S002np:undo-task <M-S-T>
Single-task variant. Reverts exactly one task's commit via git revert --no-edit, resets the task frontmatter status to pending.
bash
/np:undo-task M001-S001-T0003np:reset-slice [<M-S-T>]
Crash-recovery. Discards the in-flight task (named in STATE.current_task or passed explicitly): restores files_modified from HEAD via git restore, deletes the checkpoint, clears STATE.current_task. It does not commit or revert. Use this when execution crashed before the commit landed; use /np:undo-task instead when the commit already exists.
When workflow.worktree_isolation is on, reset-slice also removes the slice's worktree and deletes the np/<mid>-<sid> branch (unless --keep-worktree is passed). See ADR-0008.
np:skip / np:park / np:unpark
Lightweight task lifecycle CRUD:
/np:skip <M-S-T>— markstatus: skipped. Use for tasks made obsolete mid-milestone./np:park <M-S-T>— markstatus: parked. Use for tasks blocked on something external./np:unpark <M-S-T>— return a parked task topending.
All three update task frontmatter, route through setTaskStatus, and therefore also re-render the owning slice's TODO.md rollup. None of them produce a git commit on their own.
