Appearance
Agents
Subagents do the work in nubos-pilot. Workflows orchestrate; agents read, write, and reason. Every agent is a single Markdown file with a fixed frontmatter contract and a free-form body.
The frontmatter contract (D-09)
yaml
---
name: <filename-stem> # required, must equal the filename
description: <one-line summary> # required
tier: haiku | sonnet | opus # required
tools: Read, Write, Bash, Grep # required
color: <ui-hint> # optional
---Validation lives in lib/agents.cjs.validateAgentFrontmatter() and runs four gates in strict order:
- REQUIRED — every required field non-empty.
- FORBIDDEN — no field in
{model, model_profile, hooks}may appear. - TIER_ENUM —
tiermust be one of the three allowed values. - Name match — frontmatter
namemust equal the filename stem.
The first violation throws a NubosPilotError with a stable code, and the remaining gates short-circuit. There is no caching: loadAgent() re-reads the file on every call, so author edits are picked up immediately.
See the full reference for error codes, finding categories, and rationale.
Why no model / model_profile field?
Concrete model selection is tier-based. Embedding a literal model id in agent frontmatter has three drawbacks: it breaks portability across runtimes (Claude Code, Codex, Gemini and OpenCode all differ), it bypasses the Tier × Profile resolver in np-tools.cjs resolve-model, and it couples agent definitions to model-name churn that the resolver was built to absorb.
The resolver is consulted by the workflow at spawn time. The agent file itself never names a model.
Why no hooks field?
Hooks are runtime-specific syntax. Claude Code's hook format differs from Codex's and from Gemini's. The portable agent contract stays uniform by deferring lifecycle wiring to the runtime adapter layer in lib/runtime/.
Tier enum
| Tier | Used for |
|---|---|
| opus | Goal-backward decomposition, adversarial review, decision-fidelity (planner, plan-checker) |
| sonnet | Wide-context synthesis, execution, verification (executor, verifier, researcher, codebase-documenter) |
| haiku | Bounded checks, classifications, audits (nyquist-auditor) |
Model resolution
The concrete model ID is resolved at spawn time by np-tools.cjs resolve-model <agent-or-tier> --profile <profile>. Set model_profile in .nubos-pilot/config.json (default: frontier). Workflows consult the resolver inline so changing the profile takes effect on next spawn with zero redeploy.
Full Tier × Profile matrix in Agent Frontmatter Schema § Model resolution.
Spawn flow
A workflow spawns an agent through whatever mechanism the host runtime exposes (Claude's Task tool, Codex equivalents, …). The orchestrator hands the agent:
- a
<files_to_read>block enumerating every input path, - the relevant
M<NNN>-CONTEXT.mddecisions (D-01..D-NN), - task-specific parameters via the agent's prompt body.
mermaid
sequenceDiagram
participant U as User
participant W as Workflow<br/>(np:plan-phase)
participant T as np-tools.cjs
participant A as Agent<br/>(np-planner)
participant S as Project-State
U->>W: /np:plan-phase 1
W->>T: init plan-milestone
T-->>W: payload (files_to_read, context)
W->>A: spawn (tier=opus, prompt with payload)
A->>S: Read inputs
A->>S: Write S<NNN>-PLAN.md, ROADMAP, …
A-->>W: done
W->>T: scaffold-all-tasks
T->>S: Write T<NNNN>-PLAN.md per task
W-->>U: plan readyAgents are forbidden from spawning other agents. The orchestration graph is one level deep by design: no fan-out chains, no recursive agent trees.
The agent catalog
agents/ holds 16 Markdown files: 13 spawnable subagents plus 3 Critic audit-surface modules (np-critic-style, np-critic-tests, np-critic-acceptance, each marked module: true). The modules are not spawnable; the np-critic agent loads them with Read during its read step. See the catalog for the full list with tier, tools and spawn-source.
Agent skills
Beyond the body prompt, an agent can load additional skill files at spawn time. The map lives in config.json under agent_skills:
json
{
"agent_skills": {
"np-researcher": ["nubos-research-skill"],
"np-executor": ["nubos-rails-skill"]
}
}Workflows that spawn the agent embed the resolved skill list into the spawn prompt; the agent loads each skill before performing the task. Skills are runtime-managed: the host CLI resolves the string to a concrete skill file. By default an agent loads no extra skills. Full reference in Configuration § Agent skills.
Mandatory initial read
Every agent body opens with this guard:
CRITICAL: Mandatory Initial Read If the prompt contains a
<files_to_read>block, you MUST use theReadtool to load every file listed there before performing any other actions.
This guard is what makes orchestrator-supplied context reach the agent. An agent that skips the step reasons from prior assumptions, and the verifier catches it.
