Appearance
Swarm + Loop Configuration
.nubos-pilot/config.json keys that control the Nubosloop and the Researcher-Schwarm. All keys are optional; documented defaults below apply when the key is absent.
Full schema
json
{
"loop": {
"maxRounds": 3
},
"swarm": {
"research": {
"k": 3,
"threshold": 0.9,
"minOccurrence": 3,
"min_agreement_score": 0.5,
"max_contested": 2
},
"critic": {
"style_tier": "haiku",
"tests_tier": "sonnet",
"acceptance_tier": "sonnet"
},
"knowledge_adapter": "local"
},
"auto_log_learning": true
}Per-key reference
loop.maxRounds
| Type | integer |
| Default | 3 |
| Range | [1, 100] (clamped) |
| Source | lib/nubosloop.cjs::resolveLoopOpts (clamp constant HARD_MAX_ROUNDS_BOUND = 100) |
Maximum number of Build → Critic round-trips per task before the loop transitions to stuck. maxRounds = 1 disables iteration. Three rounds resolve most cases; values above 5 raise token cost without much gain in convergence, so a higher cap is mainly for the operator's "+5 rounds" stuck-dialog choice rather than a static config value.
swarm.research.k
| Type | integer |
| Default | 3 |
| Range | [1, 5] (clamped) |
| Source | lib/researcher-swarm.cjs::resolveSwarmOpts |
Number of parallel np-researcher spawns per /np:research-phase (or /np:plan-phase --research). k = 1 degrades to legacy single-spawn behaviour. k = 3 (default) is the lowest count where majority voting filters out a single hallucinating spawn. k = 5 gives stronger consensus at higher token cost.
swarm.research.threshold
| Type | number ∈ [0, 1] |
| Default | 0.9 |
| Source | lib/researcher-swarm.cjs::resolveSwarmOpts |
Jaccard similarity threshold for the cache-bypass at the Pre-flight step. 0.9 requires near-identical token sets between the milestone goal plus requirements and a stored learning's pattern. Lower the threshold (e.g. 0.7) to be more aggressive about reusing cached patterns; raise it (e.g. 0.95) to be more conservative.
swarm.research.minOccurrence
| Type | integer |
| Default | 3 |
| Source | lib/learnings.cjs DEFAULT_MIN_OCCURRENCE |
Minimum occurrence count of a stored learning before it qualifies as a cache-bypass hit. 3 requires the pattern to have been confirmed in three distinct tasks. Lower it cautiously — single-occurrence cache hits are likely to skip valuable research.
swarm.research.min_agreement_score
| Type | number ∈ [0, 1] |
| Default | 0.5 |
| Source | lib/researcher-reconciler.cjs::DEFAULTS, ADR-0018 Step 5.7 |
Disagreement-gate floor for the reconciler-reported agreement_score (frontmatter field on the final M<NNN>-RESEARCH.md). 0.5 requires that at least half the decisions reached consensus; below this the workflow blocks via askuser with three options (re-spawn with sharper query / continue with reconciler picks / manual review). Raise to 0.7 to demand stronger convergence; lower to 0.3 if you accept high-divergence research and prefer to manually triage.
CLI override per invocation: node .nubos-pilot/bin/np-tools.cjs researcher-reconcile gate <N> --min-agreement-score 0.6.
swarm.research.max_contested
| Type | integer |
| Default | 2 |
| Source | lib/researcher-reconciler.cjs::DEFAULTS, ADR-0018 Step 5.7 |
Disagreement-gate ceiling for contested_count. A "contested decision" is one only a single spawn proposed (no Mehrheit). Above this count the swarm is split enough that automatic continuation is unsafe, so askuser fires. Lower to 1 for strict-convergence projects; raise to 4 to tolerate divergent research with manual triage.
CLI override per invocation: node .nubos-pilot/bin/np-tools.cjs researcher-reconcile gate <N> --max-contested 4.
swarm.critic.{style_tier,tests_tier,acceptance_tier}
| Type | one of "haiku" / "sonnet" / "opus" |
| Default | style_tier: "haiku", tests_tier: "sonnet", acceptance_tier: "sonnet" |
| Source | lib/config-defaults.cjs DEFAULT_SWARM_CRITIC; resolved by np-tools.cjs resolve-model |
The Claude tier for each critic axis. Style work is mechanical, so haiku is cost-optimal. Tests and acceptance verification need deeper semantic understanding, hence sonnet.
Under the Single-Critic Revision (ADR-0010 §2026-05-05) a single np-critic spawn covers all three axes in one structured verdict, and the three tier keys still drive resolve-model per axis. Promote acceptance_tier to "opus" for milestones where acceptance criteria are subtle. The tier resolves through the standard resolve-model pipeline, so the model profile (frontier / quality / balanced / budget / inherit) still applies.
swarm.knowledge_adapter
| Type | "local" |
| Default | "local" |
| Source | lib/knowledge-adapter.cjs::_readAdapterConfig |
Selects the cache adapter for matchExistingLearning:
"local"—lib/knowledge-adapter.cjsroutes tolib/learnings.cjs. Storage at.nubos-pilot/knowledge/learnings.json. Similarity: Jaccard. This is the only adapter shipped.
lib/knowledge-adapter.cjs keeps the adapter seam so more adapters can be added without touching the swarm logic. Unsupported values fall back to "local" silently.
auto_log_learning
| Type | boolean |
| Default | true |
| Source | lib/nubosloop.cjs::_readAutoLogLearning |
When true, every successful task commit triggers lib/nubosloop.cjs::autoLogLearning, which persists the merged Researcher-Schwarm consensus and the executor's final diff to the cache adapter. Future similar tasks will hit the cache and bypass the swarm.
Set to false if you want full control over what enters the cache (e.g. during sensitive prototyping).
Where each key takes effect
| Key | Read by | Effect |
|---|---|---|
loop.maxRounds | lib/nubosloop.cjs::evaluateLoop | When round >= maxRounds and findings remain → stuck |
swarm.research.k | lib/researcher-swarm.cjs::buildSpawnSpecs | Number of parallel researcher spawns |
swarm.research.threshold | lib/learnings.cjs::matchExistingLearning | Jaccard cutoff for cache hit |
swarm.research.minOccurrence | lib/learnings.cjs::matchExistingLearning | Min occurrences for cache hit |
swarm.critic.* | np-tools.cjs resolve-model (per critic axis) | Resolves each axis tier to a model |
swarm.knowledge_adapter | lib/knowledge-adapter.cjs::getAdapter | Routes match / log to the local store |
auto_log_learning | lib/nubosloop.cjs::autoLogLearning | Enables / disables persistence on commit |
Example: high-throughput pattern (cache-aggressive)
json
{
"loop": { "maxRounds": 3 },
"swarm": {
"research": { "k": 3, "threshold": 0.7, "minOccurrence": 1 },
"knowledge_adapter": "local"
},
"auto_log_learning": true
}Lower threshold + lower minOccurrence = the swarm bypasses aggressively. Use this once the project has accumulated a sizeable learnings corpus.
Example: conservative pattern (no auto-log, full swarm)
json
{
"loop": { "maxRounds": 5 },
"swarm": {
"research": { "k": 5, "threshold": 0.95, "minOccurrence": 5 }
},
"auto_log_learning": false
}Larger k, stricter cache, no auto-log. Use for prototyping when you don't trust the cache yet.
Related
- Nubosloop — the runtime that consumes these settings.
- Researcher-Schwarm — the spawn-and-merge that consumes the
swarm.research.*keys. - ADR-0010 and ADR-0011 for the underlying rationale.
