// 02 · Workflow
Drive the cycle.
Each skill, in depth.
// Under construction
This chapter is still being rewritten.
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
The same loop, drawn out — the web app holds the OP, your codebase is where the agent works, and the skills move data and progress between them:
┌────────────────────────────────────────────────────────┐
│ Mission HQ: Naholo web app │
│ │
│ [Ideation: Drop intel as logs or notes] │
└────────────────────────────────────────────────────────┘
│ /infil ^ /sitrep ^ /exfil
v (pull OP data) │ (push OP data) │ (push + close)
┌────────────────────────────────────────────────────────┐
│ Battlefield: Your codebase │
│ │
│ /warno (write architecture decisions) │
│ ↓ │
│ [Review architecture decisions] │
│ ↓ │
│ /opord (cut into single-commit tasks) │
│ ↓ │
│ [Review specs] │
│ ↓ │
│ /splash (ship one task) ◂┐ │
│ ↓ │ [Repeat] │
│ [Review diff] │ (/opord if revising tasks) │
│ └────────────────┘ │
└────────────────────────────────────────────────────────┘
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/infilwhen no op is in flight./raid— fresh-OP shortcut. Collapses/warno+/opordfor 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 phase — infil, 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 infilled 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 infilled 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./fobderives 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 infilled, /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 infilled 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 infilled directory — .naholo/local/infilled/ inside the repo for team mode (naholo init), or ~/.naholo/covert-ops/{codename}/infilled/ for covert mode (naholo covert init, where each project gets its own codename folder under your home dir). Only one OP can be infilled at a time, so passing {N} while another OP is in flight errors — /exfil the current one first.
What lands on disk:
OPERATION.mdwith## SITUATIONseeded from the OP’s logs and notes.## WARNING ORDERand## OPERATION ORDERare absent — owned by/warnoand/opordrespectively.TASKS.md— empty until/opordwrites 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.
A fresh /infil {N} posts an entry log to the OP server-side once the fetch lands — the bookend to /exfil’s summary log, so the feed shows when the op was picked up.
/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. A refresh posts no log — only the fresh pull leaves an entry.
/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
/opordfrom 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 records what you decide to change as a pinned RECON note. Don’t burn a /warno ... or /opord ... figuring out what you want; work it out in recon first.
/recon needs an arg (a question or a change request) and aborts without one. Each turn is one of two things:
- A question — answered concisely (200 words max), reading files on demand, and writes nothing. Asking it to elaborate or go deeper spends those 200 words better rather than lifting the cap; for a longer answer, explicitly raise the answer limit, which resets when the recon phase ends.
- A change request — when you ask to change the plan or the code, the agent writes a
notes/RECONn.mdnote drafting the change, then hands off. With no op infilled, a change request instead points you at/fobto create + infil.
A RECON note is a task section for OPERATION.md instead of the codebase, numbered per OP (RECON1, RECON2, ...). Three sections:
## Intent— the pain and what you want.## Scheme— optional; the detailed how, skipped when the FRAGMENTARY ORDER already says everything.## FRAGMENTARY ORDER— an(Add)/(Delete)list of the change (no edit verb: a change is a(Delete)of the old, struck through as~~...~~, plus an(Add)of the new), routed against the op’s current state: it folds into the last finished task (a revision/splash N), lands as an/opordchange to the task list, or needs both a/warnoand an/opordchange when it cuts against the WARNO.
The note is the review surface: you read it, then fire the routed skill (/splash N, /opord, or /warno + /opord). /recon stamps a recon line in TIMELINE when it writes, and makes no other change and no server sync.
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.
/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.
/frago — revise both orders at once
/frago runs /warno then /opord with the same prompt, so a revision touching both the WARNO and the task list lands in one call. It needs both ## WARNING ORDER and ## OPERATION ORDER to already exist; when only one is affected, run /warno or /opord alone.
/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
/splashuses to know the task is done. - Method of Engagement — optional. Prose plus an ASCII artifact (control-flow diagram, wireframe, signature diff) when the change is shape-y enough to need one; omitted when the task has nothing to sketch.
- Target Description — mandatory. An action list of atomic steps (
Add/Edit/Move/Delete/Run/Manual) that/splashwalks when shipping the task.
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.
Tasks are also ordered root-first, not leaf-first. Composing work runs contract → root → leaves: the interface or schema settles first, then the root — the page or endpoint — ships as a running skeleton with placeholders standing in for the pieces not built yet, then each leaf lands onto that skeleton in its own later /splash. You review a real (if half-baked) page from the first ship and watch each widget slot into place, catching a wrong turn early instead of waiting for a pile of disconnected components to assemble in the final task.
/opord also lands a phase. Mid-cycle plan revisions — insert a task, split one in two, drop an unstarted one, retitle, rewrite a Target Description action list — happen by re-invoking /opord ... (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
/warnoand/opordfor 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 + Method of Engagement + Target Description, 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 Target Description 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.
/splashcontinues 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 Target Description 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 infilled 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 infilled 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 ... 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).