// 04 · Workflow

Drive the cycle.

Each skill, in depth.

The cycle in Quick Start was the round-trip view. This chapter goes deeper: what each skill does on disk, what knobs it accepts, and the phase model that ties them together. The precise contracts — argument tables, file owners, MCP tools — live in Logistics.

The cycle at a glance

The core pipeline:

/infil/warno/opord/splash (loop) → /exfil

Side branches that plug into it:

  • /fob — always-safe op-creator. Drop a title + optional first log; spins up the OP server-side and chains /infil when no op is in flight.
  • /raid — fresh-OP shortcut. Collapses /warno + /opord for small OPs where architecture review is overkill.
  • /chop/chopchop / /nochop — OP-splitting. Carve one OP into two when scope has ballooned.
  • /recon — read-only side branch. Research the OP, talk through tradeoffs, and hand off to the next skill without touching disk.

Every skill in the pipeline ships you into a phaseinfil, warno, opord, splash, recon, chop. The phase name is the “where are we” signal: after /warno you’re in the warno phase, and small follow-up edits (a single Constraint tweak, a Concept of Operations rewrite) belong to that phase without needing to re-type /warno from scratch. Each skill enforces its own scope — if you ask for opord-shaped work in the warno phase, the agent routes you to /opord instead of doing it silently.

/sitrep is a sync, not a phase — it pushes local progress and posts a log without ending the current phase. /exfil ends the cycle entirely: sync, optional close, delete local infiled dir.

/fob — drop an idea, get an op

/fob is another front door of the cycle when the OP does not exist on the server yet. Pass a one-line title and an optional first log, and /fob creates the operation server-side, posts the log when content is non-empty, and chains /infil <n> so the session lands infiled and ready for /warno or /raid.

Arg shapes:

  • /fob title-only — title on the first line, no content. Creates the op, posts no log.
  • /fob\n<content lines> — empty first line, content after. /fob derives the title from the content, posts it as the first log.
  • /fob title\n<content lines> — title + log together.
/fob Fix hydration error # <- will become title

# ↓the contents below will be stored as a log
Here's the error message.

```
Compiling /field-manual ...
 GET /field-manual 200 in 7.2s (next.js: 7.0s, application-code: 281ms)
 GET /field-manual/quick-start 200 in 2.2s (next.js: 2.1s, application-code: 72ms)
[browser] In HTML, <p> cannot be a descendant of <p>.
```

When an op is already infiled, /fob still creates the new op + log server-side — dropping an idea should never cost you your in-flight work — but it skips the /infil chain so the local infiled directory stays exactly as it was. The output names the new op number; switch to it later with /exfil then /infil <n> when you are ready.

/fob does not research the codebase. It is a one-shot launcher whose job is to register the idea and (when the slot is free) drop you into the infil phase. Compare with /raid: /raid runs after /infil to collapse /warno + /opord for small OPs. The max-velocity path for a fresh small idea is /fob then /raid "...".

/infil — pull the op local

/infil {N} fetches operation {N} from the server into the infiled directory — .naholo/local/infiled/ inside the repo for team mode (naholo init), or ~/.naholo/covert-ops/{codename}/infiled/ for covert mode (naholo covert init, where each project gets its own codename folder under your home dir). Only one OP can be infiled at a time, so passing {N} while another OP is in flight errors — /exfil the current one first.

What lands on disk:

  • OPERATION.md with ## SITUATION seeded from the OP’s logs and notes. ## WARNING ORDER and ## OPERATION ORDER are absent — owned by /warno and /opord respectively.
  • TASKS.md — empty until /opord writes the task list.
  • notes/*.md — any free-form notes already on the OP.
  • LOGS.yml — server-side log snapshot for reference.
  • .base/ — 3-way merge baseline owned by the sync commands.

/infil with no args is a refresh: 3-way merges the server state into your local copy without clobbering edits. Use this when a teammate added a note or a log on the same OP mid-cycle.

/warno — write the WARNO

/warno is the direction-setting phase. It appends ## WARNING ORDER to OPERATION.md with three subsections:

  • Concept of Operations — two or three sentences naming the chosen approach. The “what” and the “why.”
  • Constraints — one bullet per architectural decision. The “how,” expanded one decision at a time.
  • Target Reference Points — a curated list of files / folders / globs a fresh session needs to read. For agents, not users — TRP keeps a future /opord from re-walking the codebase from scratch.

/warno lands you in the warno phase. Inside the phase, WARNO tweaks don’t need a fresh /warno invocation — just chat the change or hand-edit OPERATION.md; the agent applies the edit and fires a TIMELINE bullet.

The bar before you leave the warno phase: every Constraint is clear to you, not just the agent. If a Constraint is fuzzy, resolve it — elaborate it into something concrete, or drop it if it does not earn its slot. If something nags at you that the agent has not filed, spit it out and let the agent capture it as a new Constraint. Iterating in the warno phase is cheap; shipping a half-understood WARNO is not.

Stay at the architecture and concept level. TASKS and shipped diffs are where details get reviewed — if you bury detail in Constraints, you kill momentum without adding signal. A few load-bearing key decisions are unavoidable, but resist piling them on.

If CONOPS or the Constraint list keep growing past the size you can hold in your head, that is the signal the OP is doing the work of two. Stop adding Constraints and run /chop "..." to draft a split.

/recon — talk it out before you fire a prompt

Half-cooked prompts make bad revisions. /recon is the talk-it-out side branch — the agent answers questions, pulls files on demand, and the conversation shapes the freeform args you’ll fire next. Don’t burn a /warno "..." or /opord "..." figuring out what you want; figure it out in recon first.

/recon runs in one of two branches based on whether an op is infiled:

  • Infiled — the agent reads OPERATION.md + TIMELINE.md up front and answers with the loaded OP as context. The conversation shapes the freeform args for the next phase-changing skill (/warno "...", /opord "...", /splash N "...").
  • No infiled op — the agent skips the OP context load and answers from the codebase alone, reading files on demand. If your question describes work you would want to track as an operation (a fix, a feature, a refactor), the agent points you at /fob "<title>\n<content>" to create + infil. /fob follows the same handoff rule as the other phase-changing skills (see below).

Reach for it when:

  • A Constraint in the WARNO sounds fishy or unsure after /warno — talk through the decision before keeping it, dropping it, or revising it.
  • You want to revise a TASK or a shipped change but the prompt is not obvious — work out what to ask before you ask.
  • You want to think out loud about a piece of the codebase before deciding whether it deserves its own OP.
  • Any other moment your intent is unclear and you want to think out loud against the loaded OP context (or against the codebase, with no op infiled).

When the discussion lands the prompt, tell the agent to run the next skill — /warno "...", /opord "...", /splash N "...", or /fob "..." on the no-op branch — and it picks up where the conversation left off. /recon itself writes nothing: no OPERATION.md edits, no TASKS.md edits, no TIMELINE bullets, no server syncs.

The recon phase ends when a phase-changing skill (/infil / /warno / /opord / /splash / /chop / /chopchop / /nochop) or /exfil runs; /sitrep is sync-only and leaves recon intact.

The handoff has two modes. Name the skill (run opord, do a /warno to swap Constraint 2, fire /splash 4) and the agent invokes it for you with whatever args the conversation has shaped — slash prefix and backticks are optional. Describe phase-shaped work without naming the skill (rewrite the WARNO to X, swap TASK 4 to handle nulls) and the agent pushes back once: it names the right slash command, drafts the freeform args from your description, and stops — you re-fire (with edits) or confirm. Recon’s contract is that nothing lands on disk until the explicit invocation happens.

/raid — fresh-OP shortcut

/raid collapses /warno + /opord into a single invocation for fresh OPs where architecture review would be overkill. It writes ## WARNING ORDER with a real Concept of Operations and real Target Reference Points, marks the Constraints subsection _N/A_, then chains /opord to cut ## OPERATION ORDER and mirror TASKS.md. One handoff, two skills.

Reach for it on small OPs whose architecture is obvious — bug fixes, doc updates, single-file features, anything where Constraints would be filler. If the OP genuinely has architectural decisions worth surfacing, run /warno instead and let the Constraints list earn its slot.

/raid aborts if ## WARNING ORDER or ## OPERATION ORDER already exists — the paths for revisions stay with /warno and /opord. Freeform args after /raid are forwarded to the chained /opord. The session lands in the opord phase when done; ship tasks with /splash.

/opord — cut the WARNO into tasks

/opord is the detail-cutting phase. It reads the populated WARNO and writes ## OPERATION ORDER: one ### TASK N — Title section per task. Each task carries:

  • Intent — one or two sentences naming the success criterion /splash uses to know the task is done.
  • Scheme of Maneuver — an action list of atomic steps (Add / Edit / Move / Delete / Run / Manual) that /splash walks when shipping the task, optionally preceded by an ASCII artifact (control-flow diagram, wireframe, signature diff) when the change is shape-y enough to need one.

Tasks are sized for one /splash: a single cohesive change a reviewer can read as one diff. If a task title needs “and” or a comma, split it.

/opord also lands a phase. Mid-cycle plan revisions — insert a task, split one in two, drop an unstarted one, retitle, rewrite a SOM action list — happen by re-invoking /opord "freeform" (or hand-editing OPERATION ORDER + TASKS.md). Already-shipped tasks (those with an #### After-Action Report heading) are treated as immutable by default: the agent will not edit, renumber, or drop them on its own. The recommended path for a follow-up is a fresh TASK via /opord so the change gets its own review window. If you genuinely need to rewrite a shipped task — restoring a deleted file, undoing a botched ship — revert the change by hand and tell the agent to overwrite the AAR. The default keeps history honest; the override is yours when you need it.

If a revision you ask for would contradict a current Constraint, the agent pushes back with a drafted /warno "..." prompt — the WARNO revision it thinks the change needs. From there:

  • Draft looks right. Tell the agent “run /warno and /opord for me.” It revises the WARNO, then re-cuts the affected tasks under the new Constraints. One handoff, two skills.
  • Draft needs tweaks. Copy the prompt, edit it, and run /warno "..." yourself. After the WARNO settles, follow up with /opord "..." so OPERATION ORDER re-aligns with the new direction.

The chain is WARNO first, then OPORD.

/splash — ship one task

/splash implements exactly one task per invocation. It reads the task’s Intent + Scheme of Maneuver, writes the code, runs the project’s format + typecheck checks, then appends an #### After-Action Report to the same task section. The checkbox flips in TASKS.md, the skill stops, and you review the AAR before deciding to ship the next task.

/splash defaults to the first unchecked task in TASKS.md. To target a specific task — including one you just inserted via /opord — pass the integer: /splash 5. Freeform args after the integer are implementation context: /splash 5 "use the existing helper in src/utils/foo.ts". The canonical shape is /splash N "prompt", but the agent also takes casual prompts — /splash revise the previous task, rename that helper — and picks the right TASK from context.

How Manual: steps work

While /splash is running the SOM action list, Manual: {action} items break the loop and pause the skill. These are user-owned steps the agent will not execute on its own — database migrations, secrets to paste, browser verifications, anything the agent should not run itself. On each one, /splash asks for a confirmation, with three paths out:

  • Done. You ran the step. /splash continues with the next action-list item.
  • Defer. You are skipping for now. The step lands verbatim in the AAR Notes as a Deferred manual step: ... line so nothing is silently dropped.
  • Report back. Something did not go cleanly — paste the error, describe what happened, share the step’s output. Pick the Other option on the confirmation, or just dismiss the prompt and reply directly. The agent reads the report and decides the next move: retry, route to a follow-up, or fold the failure into the AAR.

Done and Defer both ship the splash — the difference is only whether the step is recorded as a deferral. Report back hands control back to the agent to assess what happened first.

After Action Report(AAR)

The AAR is the plan-vs-shipped record: the SOM action list was the plan, the AAR says what diverged and why. Written at end of splash, appended to the task section under a #### After-Action Report heading, with two labels.

Deviations — anything different from the planned action list. Two sources:

  • Agent-initiated. Mid-splash improvisation. Compile errors or test failures surface gaps in the plan — the agent adjusts to hit the task’s Intent and records the change with a brief reason.
  • User-initiated. A revision splash redirected scope (see Adjust fire below for the full revision flow).

Notes — follow-ups, deferred Manual: steps, risks worth flagging. Omitted when there is nothing to surface.

Adjust fire

Every splash lands somewhere. Review the AAR + the diff. If it landed off-target, branch by size:

  • Minor. You are still in the splash phase. Either chat the change — “rename that helper,” “the AAR missed a step” — and the agent fixes the code and refreshes the AAR. Or re-run /splash N "tweak: ..." — re-running on a shipped task is a revision splash that overwrites the AAR body in place under the same heading. The original Intent / SoM stay untouched; those are /opord’s planning record, immutable from a splash.
  • Major. Re-invoke /opord "..." to insert a new TASK and ship the rework as its own splash. A new TASK gets a new review window; the original AAR stays as the historical record.

The bar: would a reviewer want this change as its own diff? Yes → new TASK. No → chat it in-phase.

/sitrep — checkpoint sync

/sitrep is the mid-cycle push. It syncs the current state of local tasks and notes to the server, posts a short summary log, and leaves the local infiled directory intact for continued work. Optional freeform args become extra context for the summary log.

/sitrep does not end the current phase, so you can keep iterating after a checkpoint. Use it during long ops or multi-day work where teammates need visibility before /exfil.

/exfil — close + clean up

/exfil ends the cycle. It runs the same sync as /sitrep, posts a summary log, optionally closes the operation server-side, and deletes the local infiled directory. Run when the OP is done or paused indefinitely and you want to free the single-infil slot for another OP.

/exfil decides whether to close the OP from TASKS.md: every task done → close; anything still open → pause and ask. Override the default with a freeform hint — /exfil "close" closes even with unfinished tasks, /exfil "don't close" keeps the OP open server-side even when every task shipped.

OP-splitting side branch — the chop family

When scope has ballooned and the current OP is doing the work of two, split it. CHOP — Change of Operational Control, the military term for transferring a unit between commanders — is a proposal/apply flow.

/chop "freeform" drafts the split at notes/CHOP.md: a side-by-side brief with a # CURRENT OP block (what stays) and a # NEW OP block (what gets carved off). The freeform argument is required — it is the topic, Constraints, or new-OP title you want carved. Once the draft lands, you are in the chop phase: chat any revision and the agent edits CHOP.md in place. Re-invoke /chop "..." when a fresh session needs to re-enter the phase.

/chopchop applies: spawns the new OP server-side seeded with the carved SITUATION + WARNING ORDER + OPERATION ORDER (including AARs for shipped tasks that were carried over), prunes the same scope from the parent’s OPERATION.md + TASKS.md, and deletes CHOP.md both locally and server-side.

/nochop discards: deletes CHOP.md everywhere; neither OP is touched.

While CHOP.md exists, /warno / /opord / /splash each surface a “CHOP pending” gate before running — their edits would desync the proposal, so you have to decide whether to revise CHOP after (proceed) or resolve CHOP first (cancel and pick /chopchop / /nochop / /chop).