Skip to content
Nauro

Guides

Agents and skills

Nauro ships four bundled workflow roles for Claude Code and Codex, plus four skills. The planner classifies doctrine risk and drafts decision writes, the executor implements and commits locally, the reviewer audits the diff, and the tech-lead checks direction. Every decision add, update, and supersede requires explicit user approval before an agent calls propose_decision.

Overview: subagents vs skills

Nauro bundles two distinct artifact types. Workflow agents are rendered as Claude Code Markdown under ~/.claude/agents/<name>.md and Codex TOML under ~/.codex/agents/<name>.toml. Cursor has no subagent format.

Skills are SKILL.md files materialized under ~/.claude/skills/<name>/ for Claude Code and ~/.agents/skills/<name>/ for Codex; Cursor receives repo-local rules.

  • There are exactly four bundled workflow roles, defined by AGENT_NAMES = ("nauro-planner", "nauro-executor", "nauro-reviewer", "nauro-tech-lead") in agents/__init__.py. The same canonical instruction bodies render for Claude Code and Codex.
  • There are exactly four bundled skills, named in skills/__init__.py (SkillName and SKILL_DESCRIPTIONS): nauro-adopt, nauro-ship-task, nauro-context, nauro-loop. nauro-adopt is always installed (SKILL_NAMES); the other three are opt-in (OPT_IN_SKILL_NAMES).
  • Claude Code definitions use model: inherit and declare a restricted tools: allowlist. The Codex renderer carries the same description and instruction body into TOML and marks the planner, reviewer, and tech-lead read-only.
  • The subagents are essential because they call Nauro's MCP decision tools by design (check_decision, get_decision, propose_decision, and others). The personal-subagent path (@planner / @executor / @reviewer without the nauro- prefix) is explicitly not a substitute, because it does not wire the doctrine gates.
python
# agents/__init__.py
AGENT_NAMES: tuple[str, ...] = (
    "nauro-planner",
    "nauro-executor",
    "nauro-reviewer",
    "nauro-tech-lead",
)

# cli/commands/setup.py
SKILL_NAMES: tuple[str, ...] = ("nauro-adopt",)
OPT_IN_SKILL_NAMES: tuple[str, ...] = ("nauro-ship-task", "nauro-context", "nauro-loop")

Source: packages/nauro/src/nauro/agents/__init__.py (AGENT_NAMES, render_agent); packages/nauro/src/nauro/skills/__init__.py (SKILL_DESCRIPTIONS, SkillName, render_skill); packages/nauro/src/nauro/cli/commands/setup.py (SKILL_NAMES, OPT_IN_SKILL_NAMES).

@nauro-planner: classify doctrine risk and write the plan

The planner plans changes; it does not edit files. It classifies doctrine risk GREEN/AMBER/RED via Nauro, writes a structured plan, and drafts decision additions, updates, or supersedes for explicit user approval before any write.

It returns a plan; it does not edit files. Bash is for read-only investigation only (git log, grep, ls, gh view), never for writes.

  • Before any tool calls it restates the intent in one sentence and asks if the paraphrase reveals ambiguity. Step 1 is doctrine triage: it calls check_decision with the proposed approach and classifies the response.
  • GREEN: no related decisions, or clearly off-topic ones (spot-check the top one or two via get_decision).
  • AMBER: adjacent decisions that touch the same surface area, name the same dependency, or share keywords but do not directly contradict (get_decision on every one; spot-check adjacent areas via search_decisions).
  • RED: at least one active decision directly contradicts, OR the proposal would supersede an active decision (get_decision on every one, read in full).
  • The verdict goes in the plan as a one-line header before "Why": the verdict word plus the comma-separated decision numbers it touches, so the reader sees the doctrine cost upfront.
  • On RED it drafts the supersede by default (title, rationale, what is being replaced, what is being rejected) at the top of the plan. It may refuse to draft only under all four "decision-spam" criteria: the related decision was filed within the last 7 days, at confidence: high, the proposal restates an alternative explicitly named-and-rejected in that decision's rejected field, and the proposal carries no new evidence. The user can override the refusal by asking for the draft anyway.
  • The plan follows the PR-template shape: DOCTRINE verdict line / Why / Approach / What changes / What's deferred / Test plan. When AMBER or RED, 2-3 alternatives with concrete tradeoffs are mandatory and the user picks before commit; when GREEN, alternatives are at the planner's discretion.
  • It never files in the planning run. It returns the complete add, update, or supersede draft plus the related-decision assessment. A later invocation may call propose_decision only when it carries explicit approval for that exact draft and surfaced overlaps. A changed draft needs fresh approval.
  • Fail-safe: if check_decision is unreachable it must NOT infer a verdict from git log or first-principles and call it GREEN. It stamps the header DOCTRINE: PROVISIONAL — check_decision unreachable and hands the decision to proceed back to the parent.
  • It will not read credential or token files (~/.claude/.credentials.json, .env, *.pem, key caches) during investigation; they are never needed for a plan.
agents/nauro-planner.md
# Verbatim @nauro-planner frontmatter, with the
# "Use proactively..." sentence elided as "...":
---
name: nauro-planner
description: Use to plan a non-trivial change before any code is written.
  Classifies doctrine risk (GREEN/AMBER/RED) via Nauro, writes a structured
  plan, and drafts decision additions, updates, or supersedes for explicit
  user approval before any write. ... Returns a plan; does not edit files.
tools: Read, Grep, Glob, WebSearch, WebFetch, Bash,
  mcp__claude_ai_Nauro__check_decision, mcp__claude_ai_Nauro__propose_decision,
  mcp__claude_ai_Nauro__get_decision, mcp__claude_ai_Nauro__search_decisions,
  mcp__claude_ai_Nauro__list_decisions, mcp__claude_ai_Nauro__list_projects,
  mcp__nauro__check_decision, ... mcp__nauro__list_projects
model: inherit
---
plan header
# The doctrine-verdict header the planner emits (derived from
# the plan shape in nauro-planner.md Step 4)
DOCTRINE: AMBER — informed by decisions 42, 57

Why: ...
Approach: ...  (2-3 alternatives with tradeoffs, mandatory on AMBER/RED)
What changes: ...
What's deferred: ...
Test plan: ...

Source: packages/nauro/src/nauro/agents/nauro-planner.md (frontmatter, "Required steps before returning", "Hard rules").

@nauro-executor: implement, test, commit locally (never push)

The executor implements an already-approved plan. It has full edit/write/test access: its tools: are Read, Write, Edit, Grep, Glob, Bash, NotebookEdit, WebSearch, WebFetch, TodoWrite, plus the read-only Nauro MCP tools (check_decision, get_decision, search_decisions, list_decisions under both prefixes).

It does not invent scope, refactor outside the plan, or add unrequested features.

  • Test-first discipline: for a new function, command, or behavior it writes a failing test first, then implements to green. This is skipped for pure refactors, bug-fix-is-the-repro cases, and one-line changes.
  • Local completion only. It explicitly does NOT git push, does NOT run gh pr create, and does NOT mark the task complete. It runs lint (ruff format + ruff check, checking the project Makefile for the canonical command), runs the relevant test suite, keeps cross-package dependency pins in sync (regenerate every affected manifest in the same commit), commits (default one commit per PR, subject under 72 chars, imperative voice, body with a Why paragraph and a decision-reference footer if any), and drafts the PR description in the project's template shape (Why / Approach / What changed / What to review / Deferred / Test plan).
  • It never files emergent decisions itself: it has no user channel mid-run and propose_decision commits on Tier 1 clean, so inline filing would install binding doctrine with no human gate. Instead it names the choice and rationale in its handoff, flagged as an emergent decision, for the parent to gate and route to whoever owns the filing (the planner, or @nauro-tech-lead for a doctrine move).
  • On a reviewer block it fixes only what was flagged, re-runs lint and tests, and signals ready for re-review: no scope expansion.
  • Handoff to the parent: branch name plus commit SHAs (subject lines only), lint/test results, the full drafted PR body (ready to paste into gh pr create --body), and the explicit instruction to invoke @nauro-reviewer on the local diff and not push until the reviewer approves and the user confirms.
  • Code conventions enforced: no personal /Users/<name>/... paths anywhere (even on private repos), no internal labels or dated milestones in public-facing diffs, default to no comments, prefer startswith / find / slicing over regex in this Python codebase, assert exact exit codes (== N, not != 0), and colocate package-internal tests.
agents/nauro-executor.md
# Verbatim "What you do NOT do at this stage"
## What you do NOT do at this stage

- `git push` to any remote
- `gh pr create` or any PR-opening command
- Mark the task complete to the user

These happen only after the reviewer approves and the user confirms.

Source: packages/nauro/src/nauro/agents/nauro-executor.md (Scope discipline, Test-first, Surfacing emergent decisions, Code conventions, Local completion, "What you do NOT do at this stage", "When you finish").

@nauro-reviewer: two-pass audit (real bugs, then policy)

The reviewer is read-only. It reviews a diff against the PR template and project conventions; it reads, never writes, commits, or pushes.

Bash is for read-only commands (git diff, git log, gh pr view, gh pr diff, grep).

  • Two modes. Mode A (local pre-push, the default in the planner -> executor -> reviewer cycle) reads the drafted PR body from its prompt and the local diff (git diff origin/main...HEAD, or against the actual base branch). Mode B (remote PR audit) uses gh pr view / gh pr diff. Both dimensions and the return format are the same across modes.
  • Pass 1, code review for real bugs only. A finding qualifies only if all six criteria hold: it meaningfully impacts accuracy, performance, security, or maintainability; is discrete and actionable; was introduced in this PR; is provably affected; is clearly not an intentional author choice; and the fix does not demand more rigor than the codebase shows. It explicitly prefers zero findings to weak findings. Bug shapes scanned include boundary/None handling, bare or swallowed exceptions, test weakening (broadened matchers, removed cases, pytest.raises removed, != replacing ==), caller mismatches, resource leaks, hardcoded values, stale comments, and concurrency hazards.
  • Pass 2, policy enforcement. Hard rules BLOCK: required PR sections present (Why, Approach, What changed, What to review, What's deferred, Test plan; missing Why, Approach, or Test plan always blocks); every referenced decision resolves via get_decision; no personal paths; no internal labels in public repos; no raw template tokens (<!-- protocol:... -->) in distribution artifacts; cross-package dependency pins in sync.
  • Soft flags report but do not block: dramatic copy, AI cadence (em-dash contrast pairs, "X, not just Y" parallelism) in user-facing copy, example-as-claim, explicit negation framings, casual code comments, scope creep, speculative infrastructure.
  • It returns a structured VERDICT: APPROVE | BLOCK | APPROVE WITH NITS. Any qualifying code finding is a BLOCK; any hard-rule failure is a BLOCK; soft flags alone are APPROVE WITH NITS. In Mode A it appends a routing line telling the parent to surface for push confirmation (on approve) or hand failures back to the executor (on block), capped at 2 fix iterations before surfacing to the user.
reviewer return format
VERDICT: APPROVE | BLOCK | APPROVE WITH NITS

Code findings (real bugs introduced in this PR):
- <file:line range>: <one-paragraph issue body; state trigger conditions explicitly>
(omit this block entirely if no code findings)

Hard-rule failures (if any):
- <rule>: <where in diff/PR>

Decision references checked:
- <decision reference>: resolved | UNRESOLVED

Soft flags:
- <location>: <issue> -> <suggested phrasing>

Summary: <one-line take>

Source: packages/nauro/src/nauro/agents/nauro-reviewer.md (two modes, six criteria, hard rules, soft flags, return format).

@nauro-tech-lead: set direction and file decisions (human-gated)

The tech-lead sets and maintains project direction and has write authority on Nauro doctrine. @nauro-planner, @nauro-executor, and @nauro-reviewer defer to it on architectural direction, but the human keeps the final override: every add, update, and supersede passes through explicit user approval before it calls propose_decision.

The kernel commits immediately on Tier 1 clean; there is no separate confirm step.

  • The approval channel depends on invocation. Standalone (a human called it directly): it presents the complete draft through AskUserQuestion (options Approve and file / Reject / Modify draft) and files only on approval. Inside the /nauro-ship-task chain: the parent owns the gate, so it returns any add, update, or supersede draft marked "awaiting user approval" and does not file in-run. After approval the parent re-invokes the tech-lead to file the exact draft.
  • Three modes. Mode A (direction-setting pre-work consult): check_decision + get_decision on every result, return GREEN/AMBER/RED. Mode B (post-session audit): the caller provides a Claude Code session ID; the transcript lives at ~/.claude/projects/<encoded-cwd>/<session-id>.jsonl (encoded-cwd is the absolute cwd with each / replaced by -), filtered with jq/grep against the raw JSONL (never loading the whole file), drafts decisions made implicitly, and may call update_state. Mode C (PR/diff doctrine audit): default ref git diff origin/main...HEAD, surfaces doctrine drift and applies the same approval channel to any write.
  • What it files vs surfaces: add (genuinely new ground, commits on Tier 1 clean; surface any similar_decisions), update (rationale-only append; the server consumes only rationale, while title / confidence / decision_type / reversibility / files_affected / rejected are rejected at the boundary, so use supersede for any of those), supersede (replace a contradicted or subsumed decision). It FLAGS via flag_question for open tensions and SURFACES (no file, no flag) for borderline "we decided X" moments, two active decisions that appear to contradict (meta-doctrine), or cases where redirect-versus-supersede are both defensible.
  • It stays in the doctrine lane and explicitly does not replicate the reviewer's bug-finding pass; the reviewer can APPROVE a clean diff the tech-lead later flags for drift.
  • RED is overridable inline by the human ("override RED on the cited decision, proceed"): the override surfaces in the transcript and does not require a supersede to be filed. update_state is replace-semantics (it wipes state_current.md to history) and used sparingly. Agent-side disagreement (planner or executor pushing back without human input) is not an override.
agents/nauro-tech-lead.md
# Approval channel for every decision write
Draft the complete add, update, or supersede payload and include the related
decisions and assessment from check_decision. Present it via AskUserQuestion
when standalone, or return it to the parent when invoked in a chain. Call
propose_decision only after explicit approval of that exact draft. The kernel
commits immediately on Tier 1 clean, with no second confirm step.

Source: packages/nauro/src/nauro/agents/nauro-tech-lead.md (frontmatter, three modes, "What you file vs what you surface", "When you outrank other agents", Hard rules).

/nauro-adopt: seed the project store from a repo

The adopt skill runs after nauro adopt has wired MCP and installed the skill.

After restarting the agent, invoke it as /nauro-adopt in Claude Code or $nauro-adopt in Codex. Cursor uses the installed repo rule.

Its job is to seed the Nauro store via MCP write tools: docs supply rationale; code, config, tests, manifests, and git history supply evidence; and the user supplies the "why" via targeted probes when only evidence is present.

  • Two surface modes. Filesystem-capable surfaces (Claude Code, Cursor, Codex CLI) run Steps 1-11 in full. Chat surfaces (Claude.ai, Perplexity) have no shell: they operate only on content the user pastes (Step 3b), only against an already-adopted project, and skip the code-evidence path (Step 4) and Step 6b probes, jumping from Step 3b to Step 5.
  • Already-adopted guard (Step 2): reads <repo>/.nauro/config.json (extract id and name), with a worktree fallback (compare git rev-parse --git-dir vs --git-common-dir) and a registry fallback (~/.nauro/registry.json, schema v2, where the dict key under projects IS the project id). The resolved id must be passed as project_id on every MCP call; auto-resolve routes to the default project, which may not be the one being seeded.
  • Triage buckets (Step 6): documented decision (6a, needs explicit acceptance plus rationale in a source doc, or cross-doc stitching with both halves cited and both being docs); code-evidenced fact needing rationale (6b, filesystem only, one targeted probe per observation); stack inventory (6c, folded into the Step 8 update_state delta, never a decision); open question (Step 9 via flag_question); or ignore (Step 10).
  • Rapid cited seed (Step 0): on filesystem surfaces, complete classified proposals can be shown in one batch. A batch confirm is explicit approval for each unchanged proposal selected. If the Step 7 recheck changes its operation, payload, related decisions, or assessment, the revised proposal needs fresh approval. There is no blanket second gate for unchanged confirmed cards.
  • Write loop (Step 7) per candidate: check_decision -> get_decision -> classify add/update/supersede/skip -> present the complete proposal and overlaps for approval -> propose_decision with the operation-specific signature. Earlier keep replies select candidates but do not approve a write. confidence defaults to medium; high only when a source explicitly says "accepted" or "approved".
  • Refusal contract (Step 10): never infer rationale from prose, never invent rejected alternatives, never treat demo prose, stack inventory, or code as a decision. Code evidence is "what", not "why"; it only becomes a decision once the user or a doc supplies rationale. No code-only dependency decisions.
python
# Operation-specific propose_decision signatures the write loop uses
# (adopt_body.md, Step 7)

# add (new ground)
propose_decision(project_id=..., title=..., rationale=...,
                 operation="add", rejected=..., confidence=...)

# update (rationale-only; server rejects every other field at the boundary)
propose_decision(project_id=..., rationale=...,
                 operation="update", affected_decision_id=...)

# supersede (replace / change metadata; pass the full new body)
propose_decision(project_id=..., title=..., rationale=...,
                 operation="supersede", affected_decision_id=...,
                 rejected=..., confidence=...)

Source: packages/nauro/src/nauro/skills/adopt_body.md (Surface modes, Steps 1-11, refusal contract); packages/nauro/src/nauro/cli/commands/adopt.py (surface-specific closing message).

/nauro-ship-task: orchestrate the four subagents into one gated chain

The ship-task skill orchestrates a non-trivial code change end-to-end through planner -> executor -> reviewer -> tech-lead -> user-confirm -> push, with Nauro doctrine gates at every architectural choice. After the surface-specific dispatch capability is established, the normal chain runs without per-step prompting and pauses at its two explicit GATEs.

  • Prerequisite: the bundled workflow agents must be installed via nauro adopt --with-subagents (or nauro setup all --with-subagents); if missing, the chain cannot run and stops. Claude Code dispatches the named @nauro-* agents.
  • Codex dispatch capability check: before planning or mutation, the skill verifies all four TOML definitions and inspects the dispatcher for agent_type or an equivalent custom-agent selector. A matching task_name alone is not proof of custom-agent dispatch. If the selector is unavailable, the skill explains the weaker instruction-level Codex fallback and asks for explicit approval before doing any work. A decline or missing definition stops the chain.
  • Pre-step: if the planner returns RED with a supersede draft, the chain pauses before the executor sees anything; a RED the user does not resolve never reaches code. Only on explicit user approval (or an explicit "override RED on the cited decision, proceed") does the chain continue.
  • GATE 1 (plan approval) always fires when propose_decision is in play; there is no low-stakes auto-proceed when doctrine writes are pending (stricter than the personal /ship-task skill). It also gates on high-stakes triggers: auth/credentials/secrets/tokens/signing/encryption; data-model/schema/storage-format/on-disk-or-database-layout changes; public-surface add/remove/rename (CLI commands, public functions, MCP tools, API endpoints, env vars, config keys); the nauro <-> nauro-core contract (or anything mcp-server consumes from nauro-core); dependency add/remove/major-version-bump; decisions with reversibility hard or moderate; or 2-3 genuinely architectural alternatives. With no doctrine writes and no high-stakes triggers it auto-proceeds with a one-paragraph summary.
  • Step 6 (doctrine pass): after the reviewer returns APPROVE or APPROVE WITH NITS, @nauro-tech-lead runs in Mode C on the same local diff. GREEN proceeds; AMBER surfaces constraints at the push gate; RED pauses (redirect or supersede first; no push past RED without explicit human override). The reviewer's bug pass and the tech-lead's doctrine pass are deliberately separate concerns.
  • GATE 2 (push confirmation) surfaces, in order: a one-paragraph summary (branch, commit hash, file count plus line delta, test result, reviewer and tech-lead verdicts, any decisions filed); then the drafted PR body verbatim in a fenced block; then asks "Push and open PR?" There is no push without an explicit yes/go/push. Skipping the verbatim body is a chain failure. On approval it pushes and runs gh pr create --body "...", paraphrasing doctrine moves in the Approach section rather than citing raw decision numbers.
  • If a propose_decision is pending but the Nauro MCP server is disconnected, that is a hard pause: code and its decision must land together; no push-now-file-later split.
shell
$ # install the bundled workflow agents and opt-in skills
$ nauro adopt --with-skills --with-subagents
$ # or, for an already-adopted repo / all surfaces:
$ nauro setup all --with-skills --with-subagents

$ # then, after restarting the agent:
$ # Claude Code: /nauro-ship-task add a --dry-run flag to sync
$ # Codex: $nauro-ship-task add a --dry-run flag to sync

Source: packages/nauro/src/nauro/skills/ship_task_body.md (Prerequisites, Pre-step, Steps 1-8, Rules); packages/nauro/src/nauro/cli/commands/setup.py (SHIP_TASK_NEEDS_SUBAGENTS_NOTICE, SUBAGENTS_CONNECTOR_NAME_NOTICE); packages/nauro/src/nauro/cli/commands/adopt.py (--with-subagents / --with-skills).

/nauro-context: share, find, or resume with a durable brief

The context skill writes a durable shared brief into the project store so other agents, a later session or a parallel one, can discover and pull it on demand; finds and reads a brief another agent left; or captures a resume brief so your next session can reconstruct the in-flight state. It composes only existing MCP tools (get_context, get_raw_file, flag_question) alongside the agent's own filesystem write and the nauro status shell command, and never files a decision. The earlier standalone /nauro-handoff skill is retired; its capture-and-resume flow is now this skill's Resume mode, and the legacy handoffs/ directory is never written to.

It is a real bundled skill (skills/context_body.md, in OPT_IN_SKILL_NAMES) installed via nauro adopt --with-skills. A brief is free-form working context that is not yet a decision: a migration's half-finished state, a research synthesis, an investigation's findings, the in-flight state your next session must reconstruct. Decisions are the formal record; briefs hold the working state between them.

  • Mode is read from the invoking prompt. Author runs when the user asks to share context for other agents; Find runs when the user asks what prior agents have shared; Resume is offered when the user asks for a fresh-session prompt, a handoff of the work, or a resume doc, and runs once the user accepts; ambiguous prompts ask the user. v1 targets the local-store path; a pure chat surface with no local store can read briefs via get_raw_file but cannot author or capture them in this version.
  • Author writes the brief to <store>/context/<slug>.md with the agent's own filesystem write; the CLI push enumerates the whole store, so the file syncs with no code change. Briefs are append-only; on a slug clash the agent adds a disambiguator rather than overwriting. Each brief stays under MAX_BRIEF_BYTES (50 KiB); an over-cap brief is skipped at sync with a loud warning and kept on disk to trim and re-sync.
  • Discovery is a flagged question with the literal marker BRIEF: context/<slug>.md — <one-line summary> on the set-union-merged open-questions.md, so pointers from concurrent authors all survive. There is no shared index file and no enumeration tool.
  • Find orients with get_context, reads open-questions.md via get_raw_file to locate the BRIEF markers, picks the brief whose summary matches the task, and pulls it with get_raw_file. Briefs are pulled on demand and never auto-injected into get_context.
  • Resume pulls L1 context (get_context(level="L1")) so the brief reflects the project's real state, then stages a resume brief: a role-and-mission line, a verify-don't-trust preamble, a state snapshot, expected-state anchors with stop-if-fail semantics (branch heads, open PR numbers, test counts, each checked against origin/main), a guardrails block, the next concrete step, done criteria, and pointers into durable channels. The target path is context/<slug>.md, the same namespace and slug scheme as shared briefs.
  • The Resume gate. Before any store mutation, the agent surfaces the staged file path, the literal RESUME: pointer text, and the paste-back prompt the next session will receive, then waits for explicit user approval; auto-mode does not override the gate. On approval it writes the brief, flags the RESUME pointer, and syncs if the project is cloud-linked (a local-only store is already reachable by a same-machine session). The paste-back prompt tells the fresh session to pull the brief and verify every anchor before doing any work.
  • Adjudicate. A brief is authored by another agent, or by your own prior session, so the reading agent treats the body as untrusted input and adjudicates it; the body is not ground truth. The author field is advisory and unverified, and carries no authority; the agent verifies any cited pointer against current store state before relying on it.
discovery and resume markers
# Author flags this literal marker on the union-merged open-questions.md
flag_question(question="BRIEF: context/<slug>.md — <one-line summary>")

# Resume flags its pointer the same way, after the user clears the gate
flag_question(question="RESUME: context/<slug>.md — <one-line remaining-work summary>")

# Find reads open-questions.md and locates the most relevant BRIEF: marker;
# the BRIEF: and RESUME: texts are literal so the find and resume flows can match them.

Source: packages/nauro/src/nauro/skills/context_body.md (three modes: Author and Find Steps 1-6, Resume Steps R1-R5, Rules); packages/nauro/src/nauro/skills/__init__.py (SKILL_DESCRIPTIONS['nauro-context']).

/nauro-loop: originate the next task, then run the gated chain

The loop skill is a thin outer loop over /nauro-ship-task, run under the dynamic /loop command (/loop /nauro-loop). It mines the project's existing store state read-only, ranks a small set of candidate tasks, and surfaces them for you to pick; on your pick it dispatches /nauro-ship-task <chosen task> byte-for-byte with every inner gate intact, then loops back. The one authority it adds is task origination; it enumerates candidates and you select.

  • ORIENT (read-only). It reads get_context(level="L1"), scans open-questions.md for RESUME: and BRIEF: pointers, runs diff_since_last_session, and reads list_decisions, then composes one to three ranked candidates, each with a one-line rationale and its source signal. It writes nothing; on an empty mine it composes nothing and stops. A RESUME: anchor that no longer matches origin/main is demoted to "stale, surface" and reported, never ranked as live work.
  • SELECT (mandatory gate). Candidates surface through AskUserQuestion with their rationale and provenance; you pick one or reject them all. There is no auto-pick path, not even for a single ranked candidate. check_decision output, when shown, is a raw related-decision list, never a verdict or recommendation.
  • CHAIN. Your chosen candidate becomes the verbatim input to /nauro-ship-task, dispatched with all of its gates intact: the RED-supersede pause, plan approval, AMBER surfacing, the RED tech-lead pause, push confirmation, and the doctrine-disconnect hard-pause. Under the loop the chain's low-stakes auto-proceed at the plan gate is closed, so every plan blocks for explicit approval.
  • No store-write authority. The loop never files a decision, never pushes, and never runs gh. Every filing, PR, and push happens inside the dispatched chain after you clear the relevant chain gate. A standing "keep going" directive does not override the SELECT gate or any inner chain gate.
  • Bounded and fail-closed. One gate is open at a time, since a held gate takes a lock; a gate-callback timeout halts rather than counting as approval; a chain that self-halts or fails loud routes to you for a decision. The loop stops on an empty mine or at a hard per-session ceiling on completed chains and idle re-orient cycles.
  • Substrate. It runs only under the dynamic /loop command, which can pause for the SELECT gate. Cron, scheduled wakeups, and cloud routines are out of scope, since an unattended run cannot pause for the sign-off the gates require.

Source: packages/nauro/src/nauro/skills/loop_body.md (ORIENT, SELECT, CHAIN, INTEGRATE, RE-ORIENT, Gate H, Rules); packages/nauro/src/nauro/skills/__init__.py (SKILL_DESCRIPTIONS['nauro-loop']); packages/nauro/src/nauro/cli/commands/setup.py (OPT_IN_SKILL_NAMES).

Installation: --with-subagents and --with-skills

  • Complete workflow. Run nauro adopt --with-skills --with-subagents in a new repo adoption, or nauro setup all --with-skills --with-subagents in an adopted project. Plain nauro adopt wires MCP and installs only the core nauro-adopt skill.
  • Workflow agents install opt-in. --with-subagents materializes four nauro-*.md files into ~/.claude/agents/ for Claude Code and four nauro-*.toml files into ~/.codex/agents/ for Codex. Cursor has no subagent format.
  • Skills. nauro-adopt is always installed (into ~/.claude/skills/nauro-adopt/SKILL.md, ~/.agents/skills/nauro-adopt/SKILL.md for Codex, and <repo>/.cursor/rules/nauro-adopt.mdc for Cursor). --with-skills additionally installs the opt-in set (nauro-ship-task, nauro-context, nauro-loop). The two flags are independent so subagents and skills can be adopted on separate cadences.
  • Nauro-owned files refresh safely. If an installed Nauro skill or agent definition differs from the current bundle, setup refreshes it and stashes the prior content in a sibling .bak. --force-overwrite skips the backup. Byte-equal files are unchanged, and files outside Nauro's owned names are never touched.
  • Two install-time notices. If --with-skills is passed without --with-subagents, the CLI warns that nauro-ship-task needs the bundled workflow agents. It also tells Claude Code cloud users to name the remote connector exactly Nauro so the Claude definitions' mcp__claude_ai_Nauro__* tools resolve.
  • Running nauro adopt --with-subagents / --with-skills / --force-overwrite against an already-adopted repo routes to _install_into_adopted_repo, which materializes the artifacts without re-registering the project or rewriting .nauro/config.json. After install the user must restart the agent so it picks up the new files.
  • Verify before restart. Run nauro status to diagnose MCP, Codex hooks, skills, workflow agents, and AGENTS.md. Run nauro doctor separately to check store integrity. Then start a fresh agent session and make a Nauro MCP call.
install-time help and notices
nauro adopt --with-skills --with-subagents
nauro status
nauro doctor

# Restart, then:
# Claude Code: /nauro-adopt
# Codex: $nauro-adopt

Source: packages/nauro/src/nauro/cli/commands/adopt.py (install flags, _install_into_adopted_repo, closing message); packages/nauro/src/nauro/cli/commands/setup.py (setup flags and notices); packages/nauro/src/nauro/cli/integrations/agents.py (materialize_agents); packages/nauro/src/nauro/cli/integrations/skills.py; packages/nauro/src/nauro/agents/__init__.py (render_agent).

Key facts

  • Exactly four bundled workflow agents: nauro-planner, nauro-executor, nauro-reviewer, nauro-tech-lead (AGENT_NAMES in agents/__init__.py). Claude Code Markdown uses model: inherit; Codex TOML omits a model field and renders name, description, optional sandbox_mode, and developer_instructions.
  • Exactly four bundled skills: nauro-adopt (always installed, SKILL_NAMES), nauro-ship-task, nauro-context, and nauro-loop (opt-in, OPT_IN_SKILL_NAMES).
  • Doctrine verdicts are GREEN / AMBER / RED. The planner classifies via check_decision; RED means an active decision directly contradicts the proposal OR the proposal would supersede an active decision.
  • Workflow agents install into ~/.claude/agents/<name>.md for Claude Code and ~/.codex/agents/<name>.toml for Codex via --with-subagents. Cursor has no subagent format.
  • Claude Code skills install into ~/.claude/skills/<name>/SKILL.md; Codex into ~/.agents/skills/<name>/SKILL.md; Cursor into <repo>/.cursor/rules/<name>.mdc.
  • propose_decision operations: add, update, supersede. On update the server consumes only rationale; title / confidence / decision_type / reversibility / files_affected / rejected are rejected at the boundary.
  • confidence values seen: medium (default) and high (only when a source explicitly says "accepted" or "approved"). reversibility values referenced: hard, moderate.
  • The executor never pushes, never runs gh pr create, and never files decisions itself; it commits locally and hands off. Push and propose_decision happen only with explicit user approval.
  • Reviewer verdicts: APPROVE | BLOCK | APPROVE WITH NITS. A qualifying code finding or any hard-rule failure is a BLOCK; soft flags alone are APPROVE WITH NITS.
  • The tech-lead gates every add, update, and supersede through AskUserQuestion when standalone; in the ship-task chain it returns complete drafts "awaiting user approval" and is re-invoked to file after approval. The kernel commits on Tier 1 clean with no separate confirm step.
  • Required PR sections enforced by the reviewer: Why, Approach, What changed, What to review, What's deferred, Test plan.
  • /nauro-context Resume mode flags the literal marker RESUME: context/<slug>.md — <summary> in append-only open-questions.md after a user-approved gate; briefs, shared and resume alike, accumulate append-only under <store>/context/.
  • /nauro-loop runs under /loop /nauro-loop, originates one to three candidate tasks from a read-only store mine, and dispatches the chosen one to /nauro-ship-task after a mandatory AskUserQuestion pick; it files nothing, pushes nothing, and stops on an empty mine or a per-session ceiling.
  • update_state is REPLACE semantics with a roughly 5000-character cap; it wipes state_current.md to history.
  • ship-task gates always when propose_decision is in play (no low-stakes auto-proceed), plus on high-stakes triggers (auth/secrets, data model/schema/storage, public surface, the nauro <-> nauro-core contract, dependency add/remove/major-bump, reversibility hard/moderate, 2-3 architectural alternatives).
  • Claude Code agent definitions list Nauro MCP tools under mcp__claude_ai_Nauro__* (cloud connector, which must be named exactly Nauro) and mcp__nauro__* (local stdio). Codex does not share the connector-name constraint.
  • render_agent returns the canonical Markdown body for claude_code, translates it into custom-agent TOML for codex, and raises NotImplementedError only for cursor.
  • Complete workflow: nauro adopt --with-skills --with-subagents. After installation, run nauro status, use nauro doctor for store integrity, restart, then invoke /nauro-adopt in Claude Code or $nauro-adopt in Codex.
  • On reinstall, a differing Nauro-owned skill or agent definition is refreshed from the bundle and its prior content is saved to a sibling .bak unless --force-overwrite is passed. Byte-equal files are left unchanged; unrelated user files are not touched.