Skip to content

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

Typeinteger
Default3
Range[1, 100] (clamped)
Sourcelib/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

Typeinteger
Default3
Range[1, 5] (clamped)
Sourcelib/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

Typenumber ∈ [0, 1]
Default0.9
Sourcelib/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

Typeinteger
Default3
Sourcelib/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

Typenumber ∈ [0, 1]
Default0.5
Sourcelib/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

Typeinteger
Default2
Sourcelib/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}

Typeone of "haiku" / "sonnet" / "opus"
Defaultstyle_tier: "haiku", tests_tier: "sonnet", acceptance_tier: "sonnet"
Sourcelib/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"
Sourcelib/knowledge-adapter.cjs::_readAdapterConfig

Selects the cache adapter for matchExistingLearning:

  • "local"lib/knowledge-adapter.cjs routes to lib/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

Typeboolean
Defaulttrue
Sourcelib/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

KeyRead byEffect
loop.maxRoundslib/nubosloop.cjs::evaluateLoopWhen round >= maxRounds and findings remain → stuck
swarm.research.klib/researcher-swarm.cjs::buildSpawnSpecsNumber of parallel researcher spawns
swarm.research.thresholdlib/learnings.cjs::matchExistingLearningJaccard cutoff for cache hit
swarm.research.minOccurrencelib/learnings.cjs::matchExistingLearningMin occurrences for cache hit
swarm.critic.*np-tools.cjs resolve-model (per critic axis)Resolves each axis tier to a model
swarm.knowledge_adapterlib/knowledge-adapter.cjs::getAdapterRoutes match / log to the local store
auto_log_learninglib/nubosloop.cjs::autoLogLearningEnables / 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.