opencode-swarm 6.48.0 → 6.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -30,7 +30,7 @@ Most AI coding tools let one model write code and ask that same model whether th
30
30
  - 🔒 **Gated pipeline** — code never ships without reviewer + test engineer approval (bypassed in turbo mode)
31
31
  - 🔄 **Phase completion gates** — completion-verify and drift verifier gates enforced before phase completion (bypassed in turbo mode)
32
32
  - 🔁 **Resumable sessions** — all state saved to `.swarm/`; pick up any project any day
33
- - 🌐 **11 languages** — TypeScript, Python, Go, Rust, Java, Kotlin, C#, C/C++, Swift, Dart, Ruby
33
+ - 🌐 **12 languages** — TypeScript, Python, Go, Rust, Java, Kotlin, C#, C/C++, Swift, Dart, Ruby, PHP
34
34
  - 🛡️ **Built-in security** — SAST, secrets scanning, dependency audit per task
35
35
  - 🆓 **Free tier** — works with OpenCode Zen's free model roster
36
36
  - ⚙️ **Fully configurable** — override any agent's model, disable agents, tune guardrails
@@ -69,16 +69,26 @@ All project state lives in `.swarm/`:
69
69
 
70
70
  ```text
71
71
  .swarm/
72
- ├── plan.md # Project roadmap with phases and tasks
73
- ├── plan.json # Structured plan data
74
- ├── context.md # Technical decisions and SME guidance
75
- ├── events.jsonl # Event stream for diagnostics
76
- ├── evidence/ # Review/test evidence bundles per task
77
- ├── telemetry.jsonl # Session observability events (JSONL)
78
- ├── curator-summary.json # Curator system state (if enabled)
79
- └── drift-report-phase-N.json # Plan-vs-reality drift reports
72
+ ├── plan.md # Projected plan (generated from ledger)
73
+ ├── plan.json # Projected plan data (generated from ledger)
74
+ ├── plan-ledger.jsonl # Durable append-only ledger authoritative source of truth (v6.44)
75
+ ├── SWARM_PLAN.md # Export checkpoint artifact written on save_plan / phase_complete / close
76
+ ├── SWARM_PLAN.json # Export checkpoint artifact (importable via importCheckpoint)
77
+ ├── context.md # Technical decisions and SME guidance
78
+ ├── spec.md # Feature specification (written by /swarm specify)
79
+ ├── close-summary.md # Written by /swarm close with project summary
80
+ ├── close-lessons.md # Optional: explicit session lessons for /swarm close to curate
81
+ ├── doc-manifest.json # Documentation index built by doc_scan tool
82
+ ├── events.jsonl # Event stream for diagnostics
83
+ ├── evidence/ # Review/test evidence bundles per task
84
+ ├── telemetry.jsonl # Session observability events (JSONL)
85
+ ├── curator-summary.json # Curator system state
86
+ ├── curator-briefing.md # Curator init briefing injected at session start
87
+ └── drift-report-phase-N.json # Plan-vs-reality drift reports (Curator)
80
88
  ```
81
89
 
90
+ > **Plan durability (v6.44):** `plan-ledger.jsonl` is the authoritative source of truth for plan state. `plan.json` and `plan.md` are projections derived from the ledger — if they are missing or stale, `loadPlan()` auto-rebuilds them from the ledger. `SWARM_PLAN.md` / `SWARM_PLAN.json` are export-only checkpoint artifacts written automatically — use `SWARM_PLAN.json` to restore if both `plan.json` and the ledger are lost.
91
+
82
92
  Swarm is resumable by design. If `.swarm/` already exists, the architect goes straight into **RESUME** → **EXECUTE** instead of repeating discovery.
83
93
 
84
94
  ---
@@ -312,6 +322,7 @@ When a task requires multiple coder attempts (e.g., reviewer rejections), Swarm
312
322
  | `/swarm diagnose` | Health check for swarm state, including config parsing, grammar files, checkpoint manifest, events stream integrity, and steering directive staleness |
313
323
  | `/swarm evidence 2.1` | Show review/test results for a specific task |
314
324
  | `/swarm history` | What's been completed so far |
325
+ | `/swarm close [--prune-branches]` | Idempotent session close-out: writes retrospectives, curates lessons (reads `.swarm/close-lessons.md` if present), archives evidence, resets `context.md`, cleans config-backup files, optionally prunes merged branches |
315
326
  | `/swarm reset --confirm` | Start over (clears all swarm state) |
316
327
 
317
328
  ---
@@ -336,9 +347,9 @@ Agent roles (see [Agent Categories](#agent-categories) for classification refere
336
347
  | `architect` | Coordinates the workflow, writes plans, enforces gates | Always |
337
348
  | `explorer` | Scans the codebase and gathers context | Before planning, after phase wrap |
338
349
  | `sme` | Provides domain guidance | During planning / consultation |
339
- | `critic` | Reviews the plan before execution | Before coding starts |
340
- | `critic_sounding_board` | Pre-escalation pushback before user contact | When architect hits impasse |
341
- | `critic_drift_verifier` | Phase completion verifier (implementation matches plan) | Before phase_complete |
350
+ | `critic` | Reviews the plan before execution and blocks coding until approved | Before coding starts (CRITIC-GATE mode) |
351
+ | `critic_sounding_board` | Pre-escalation pushback — the architect consults this before contacting the user; returns UNNECESSARY / REPHRASE / APPROVED / RESOLVE | When architect hits an impasse |
352
+ | `critic_drift_verifier` | **Phase-close drift detector**: verifies that the completed implementation still matches the original plan spec. Returns APPROVED or NEEDS_REVISION. When NEEDS_REVISION is returned, the phase is **blocked** — the architect must address deviations before calling `phase_complete`. After receiving the verdict, the architect calls `write_drift_evidence` to record the gate result. Bypassed in turbo mode. | Before `phase_complete` (PHASE-WRAP mode) |
342
353
  | `coder` | Implements one task at a time | During execution |
343
354
  | `reviewer` | Reviews correctness and security | After each task |
344
355
  | `test_engineer` | Writes and runs tests | After each task |
@@ -405,6 +416,9 @@ MODE: EXECUTE (per task)
405
416
  ├── 5j. @test_engineer (verification tests + coverage ≥70%)
406
417
  ├── 5k. @test_engineer (adversarial tests)
407
418
  ├── 5l. architect regression sweep (scope:"graph" to find cross-task test regressions)
419
+ ├── 5l-ter. test drift detection (conditional — fires when changes involve command behaviour,
420
+ │ parsing/routing logic, user-visible output, public contracts, assertion-heavy areas,
421
+ │ or helper lifecycle changes; validates tests still align with current behaviour)
408
422
  ├── 5m. ⛔ Pre-commit checklist (all 4 items required, no override)
409
423
  └── 5n. Task marked complete, evidence written
410
424
  ```
@@ -419,12 +433,12 @@ The architect moves through these modes automatically:
419
433
  |---|---|
420
434
  | `RESUME` | Existing `.swarm/` state was found, so Swarm continues where it left off |
421
435
  | `CLARIFY` | Swarm asks for missing information it cannot infer |
422
- | `DISCOVER` | Explorer scans the codebase |
436
+ | `DISCOVER` | Explorer scans the codebase; co-change dark matter analysis runs automatically to detect hidden file couplings (v6.41) |
423
437
  | `CONSULT` | SME agents provide domain guidance |
424
438
  | `PLAN` | Architect writes or updates the phased plan (includes CODEBASE REALITY CHECK on brownfield projects) |
425
439
  | `CRITIC-GATE` | Critic reviews the plan before execution |
426
440
  | `EXECUTE` | Tasks are implemented one at a time through the QA pipeline |
427
- | `PHASE-WRAP` | A phase closes out, docs are updated, retrospective is written, and phase completion gates are enforced |
441
+ | `PHASE-WRAP` | A phase closes out, including: explorer rescan, docs update, `context.md` update, `write_retro`, evidence check, `sbom_generate`, **`@critic_drift_verifier` delegation** (drift check — blocking gate), `write_drift_evidence` call with verdict, mandatory gate evidence verification (`completion-verify.json` + `drift-verifier.json` both required), then `phase_complete` |
428
442
 
429
443
  > **CODEBASE REALITY CHECK (v6.29.2):** Before any planning, the Architect dispatches Explorer to verify the current state of every referenced item. Produces a CODEBASE REALITY REPORT with statuses: NOT STARTED, PARTIALLY DONE, ALREADY COMPLETE, or ASSUMPTION INCORRECT. This prevents planning against stale assumptions. Skipped for greenfield projects with no existing codebase references.
430
444
 
@@ -491,6 +505,8 @@ Every completed task writes structured evidence to `.swarm/evidence/`:
491
505
  | diff | Files changed, additions/deletions |
492
506
  | retrospective | Phase metrics, lessons learned, error taxonomy classification (injected into next phase) |
493
507
  | secretscan | Secret scan results: findings count, files scanned, skipped files (v6.33) |
508
+ | completion-verify | Deterministic gate: verifies plan task identifiers exist in source files (written automatically by `completion-verify` tool; required before `phase_complete`) |
509
+ | drift-verifier | Phase-close drift gate: `critic_drift_verifier` verdict (APPROVED/NEEDS_REVISION) and summary (written by architect via `write_drift_evidence`; required before `phase_complete`) |
494
510
 
495
511
  ### telemetry.jsonl: Session Observability
496
512
 
@@ -832,7 +848,7 @@ To disable entirely, set `context_budget.enabled: false` in your swarm config.
832
848
 
833
849
  | Tool | What It Does |
834
850
  |------|-------------|
835
- | syntax_check | Tree-sitter validation across 11 languages |
851
+ | syntax_check | Tree-sitter validation across 12 languages |
836
852
  | placeholder_scan | Catches TODOs, FIXMEs, stubs, placeholder text |
837
853
  | sast_scan | Offline security analysis, 63+ rules, 9 languages |
838
854
  | sbom_generate | CycloneDX dependency tracking, 8 ecosystems |
@@ -1119,6 +1135,7 @@ Control how tool outputs are summarized for LLM context.
1119
1135
  | `/swarm benchmark` | Performance benchmarks |
1120
1136
  | `/swarm retrieve [id]` | Retrieve auto-summarized tool outputs (supports offset/limit pagination) |
1121
1137
  | `/swarm reset --confirm` | Clear swarm state files |
1138
+ | `/swarm reset-session` | Clear session state files in `.swarm/session/` (preserves plan and context) |
1122
1139
  | `/swarm preflight` | Run phase preflight checks |
1123
1140
  | `/swarm config doctor [--fix]` | Config validation with optional auto-fix |
1124
1141
  | `/swarm doctor tools` | Tool registration coherence and binary readiness check |
@@ -1126,6 +1143,18 @@ Control how tool outputs are summarized for LLM context.
1126
1143
  | `/swarm specify [description]` | Generate or import a feature specification |
1127
1144
  | `/swarm clarify [topic]` | Clarify and refine an existing feature specification |
1128
1145
  | `/swarm analyze` | Analyze spec.md vs plan.md for requirement coverage gaps |
1146
+ | `/swarm close [--prune-branches]` | Idempotent session close-out: retrospectives, lesson curation, evidence archive, context.md reset, config-backup cleanup, optional branch pruning |
1147
+ | `/swarm write-retro` | Write a phase retrospective manually |
1148
+ | `/swarm handoff` | Generate a handoff summary for context-budget-critical sessions |
1149
+ | `/swarm simulate` | Simulate plan execution without writing code |
1150
+ | `/swarm promote` | Promote swarm-scoped knowledge to hive (global) knowledge |
1151
+ | `/swarm evidence summary` | Generate a summary across all evidence bundles with completion ratio and blockers |
1152
+ | `/swarm knowledge` | List knowledge entries |
1153
+ | `/swarm knowledge migrate` | Migrate knowledge entries to the current format |
1154
+ | `/swarm knowledge quarantine [id]` | Move a knowledge entry to quarantine |
1155
+ | `/swarm knowledge restore [id]` | Restore a quarantined knowledge entry |
1156
+ | `/swarm turbo` | Enable turbo mode for the current session (bypasses QA gates) |
1157
+ | `/swarm checkpoint` | Save a git checkpoint for the current state |
1129
1158
 
1130
1159
  </details>
1131
1160
 
@@ -1139,11 +1168,11 @@ Swarm limits which tools each agent can access based on their role. This prevent
1139
1168
 
1140
1169
  | Agent | Tools | Count | Rationale |
1141
1170
  |-------|-------|:---:|-----------|
1142
- | **architect** | All 23 tools | 23 | Orchestrator needs full visibility |
1143
- | **reviewer** | diff, imports, lint, pkg_audit, pre_check_batch, secretscan, symbols, complexity_hotspots, retrieve_summary, extract_code_blocks, test_runner | 11 | Security-focused QA |
1144
- | **coder** | diff, imports, lint, symbols, extract_code_blocks, retrieve_summary | 6 | Write-focused, minimal read tools |
1145
- | **test_engineer** | test_runner, diff, symbols, extract_code_blocks, retrieve_summary, imports, complexity_hotspots, pkg_audit | 8 | Testing and verification |
1146
- | **explorer** | complexity_hotspots, detect_domains, extract_code_blocks, gitingest, imports, retrieve_summary, schema_drift, symbols, todo_extract | 9 | Discovery and analysis |
1171
+ | **architect** | All registered tools | | Orchestrator needs full visibility |
1172
+ | **reviewer** | diff, imports, lint, pkg_audit, pre_check_batch, secretscan, symbols, complexity_hotspots, retrieve_summary, extract_code_blocks, test_runner, suggest_patch, batch_symbols | 13 | Security-focused QA |
1173
+ | **coder** | diff, imports, lint, symbols, extract_code_blocks, retrieve_summary, search | 7 | Write-focused, minimal read tools |
1174
+ | **test_engineer** | test_runner, diff, symbols, extract_code_blocks, retrieve_summary, imports, complexity_hotspots, pkg_audit, search | 9 | Testing and verification |
1175
+ | **explorer** | complexity_hotspots, detect_domains, extract_code_blocks, gitingest, imports, retrieve_summary, schema_drift, symbols, todo_extract, search, batch_symbols | 11 | Discovery and analysis |
1147
1176
  | **sme** | complexity_hotspots, detect_domains, extract_code_blocks, imports, retrieve_summary, schema_drift, symbols | 7 | Domain expertise research |
1148
1177
  | **critic** | complexity_hotspots, detect_domains, imports, retrieve_summary, symbols | 5 | Plan review, minimal toolset |
1149
1178
  | **docs** | detect_domains, doc_extract, doc_scan, extract_code_blocks, gitingest, imports, retrieve_summary, schema_drift, symbols, todo_extract | 10 | Documentation synthesis and discovery |
@@ -1203,8 +1232,10 @@ The following tools can be assigned to agents via overrides:
1203
1232
 
1204
1233
  | Tool | Purpose |
1205
1234
  |------|---------|
1235
+ | `batch_symbols` | Extract exported symbols from multiple files in a single call; per-file error isolation; 75–98% call reduction vs sequential (v6.45); registered for architect, explorer, reviewer |
1206
1236
  | `checkpoint` | Save/restore git checkpoints |
1207
1237
  | `check_gate_status` | Read-only query of task gate status |
1238
+ | `co_change_analyzer` | Scan git history for files that co-change frequently; generates dark matter architecture knowledge entries during DISCOVER mode (v6.41); architect-only |
1208
1239
  | `complexity_hotspots` | Identify high-risk code areas |
1209
1240
  | `declare_scope` | Pre-declare the file scope for the next coder delegation (architect-only); violations trigger warnings |
1210
1241
  | `detect_domains` | Detect SME domains from text |
@@ -1220,14 +1251,17 @@ The following tools can be assigned to agents via overrides:
1220
1251
  | `pkg_audit` | Security audit of dependencies |
1221
1252
  | `pre_check_batch` | Parallel pre-checks (lint, secrets, SAST, quality) |
1222
1253
  | `retrieve_summary` | Retrieve summarized tool outputs |
1254
+ | `save_plan` | Persist plan to `.swarm/plan.json`, `plan.md`, and ledger; also writes `SWARM_PLAN.md` / `SWARM_PLAN.json` checkpoint artifacts; requires explicit `working_directory` parameter |
1223
1255
  | `schema_drift` | Detect OpenAPI/schema drift |
1256
+ | `search` | Workspace-scoped ripgrep-style structured text search; literal and regex modes, glob filtering, result limits (v6.45); registered for architect, coder, reviewer, explorer, test_engineer |
1224
1257
  | `secretscan` | Scan for secrets in code |
1258
+ | `suggest_patch` | Generate contextual diff hunks without modifying files; read-only patch suggestions for reviewer→coder handoff (v6.45); registered for reviewer and architect |
1225
1259
  | `symbols` | Extract exported symbols |
1226
1260
  | `test_runner` | Run project tests |
1227
1261
  | `update_task_status` | Mark plan tasks as pending/in_progress/completed/blocked; track phase progress; acquires lock on `plan.json` before writing |
1228
1262
  | `todo_extract` | Extract TODO/FIXME comments |
1229
1263
  | `write_retro` | Document phase retrospectives via the phase_complete workflow; capture lessons learned |
1230
- | `write_drift_evidence` | Write drift verification evidence after critic_drift_verifier completes |
1264
+ | `write_drift_evidence` | Write drift verification evidence after critic_drift_verifier completes; architect calls this after receiving the verifier’s verdict — the critic does not write files directly |
1231
1265
 
1232
1266
  ---
1233
1267
 
@@ -1236,8 +1270,34 @@ The following tools can be assigned to agents via overrides:
1236
1270
 
1237
1271
  > For the complete version history, see [CHANGELOG.md](CHANGELOG.md) or [docs/releases/](docs/releases/).
1238
1272
 
1239
- ### v6.41.0 — Drift Evidence Tool
1273
+ ### v6.47.0 — `/swarm close` Full Session Close-Out
1274
+
1275
+ - **`/swarm close` expanded**: Now performs complete close-out: resets `context.md`, deletes stale `config-backup-*.json` files, supports plan-free sessions (PR reviews, investigations), and accepts `--prune-branches` to delete local branches whose remote tracking ref is `gone` (merged/deleted upstream).
1276
+ - **Lesson injection**: If `.swarm/close-lessons.md` exists when `/swarm close` runs, the architect’s explicit lessons are curated into the knowledge base before the file is deleted.
1277
+
1278
+ ### v6.45.0 — New Search, Patch, and Batch Tools
1279
+
1280
+ - **`search` tool**: Workspace-scoped ripgrep-style structured search with literal/regex modes and glob filtering. Registered for architect, coder, reviewer, explorer, test_engineer.
1281
+ - **`suggest_patch` tool**: Reviewer-safe context-anchored patch suggestion. Generates diff hunks without writing files. Registered for reviewer and architect.
1282
+ - **`batch_symbols` tool**: Batched symbol extraction from multiple files in one call; per-file error isolation; 75–98% call reduction vs sequential single-file calls. Registered for architect, explorer, reviewer.
1283
+ - **Step 5l-ter**: Test drift detection step added to the EXECUTE pipeline. Fires conditionally when changes involve command behaviour, parsing/routing logic, user-visible output, public contracts, assertion-heavy areas, or helper lifecycle changes.
1284
+
1285
+ ### v6.44.0 — Durable Plan Ledger
1286
+
1287
+ - **`plan-ledger.jsonl`**: Append-only JSONL ledger is now the authoritative source of truth for plan state. `plan.json` and `plan.md` are projections derived from the ledger. `loadPlan()` auto-rebuilds projections from the ledger on hash mismatch.
1288
+ - **Checkpoint artifacts**: `writeCheckpoint()` writes `SWARM_PLAN.md` and `SWARM_PLAN.json` at the project root on every `save_plan`, `phase_complete`, and `/swarm close`. Use `SWARM_PLAN.json` to restore after data loss.
1289
+ - **Auto-generated tool lists**: Architect prompt `YOUR TOOLS` and `Available Tools` sections are now generated from `AGENT_TOOL_MAP.architect` — no more hand-maintained lists that drift.
1290
+ - See [docs/plan-durability.md](docs/plan-durability.md) for migration notes.
1240
1291
 
1292
+ ### v6.42.0 — Curator LLM Delegation Wired
1293
+
1294
+ - **Curator now performs real LLM analysis**: Previously the LLM delegation was scaffolded but never connected — every call fell through to data-only mode. All three call sites now invoke the Explorer agent with curator-specific system prompts.
1295
+ - **`curator.enabled` now defaults to `true`**: The curator falls back gracefully to data-only mode when no SDK client is available (e.g., in unit tests). If you relied on the previous `false` default, set `"curator": { "enabled": false }` explicitly.
1296
+
1297
+ ### v6.41.0 — Dark Matter Detection + `/swarm close` + Drift Evidence Tool
1298
+
1299
+ - **Dark matter detection pipeline**: During DISCOVER mode, automatically scans git history for files that frequently co-change. Results are stored as `architecture` knowledge entries and the architect is guided to consider co-change partners when declaring scope. Silently skips repos with fewer than 20 commits or no git history.
1300
+ - **`/swarm close` command**: New idempotent close command. Writes retrospectives for in-progress phases, curates session lessons via the knowledge pipeline, archives evidence, marks phases/tasks as `closed`, writes `.swarm/close-summary.md`, and cleans state.
1241
1301
  - **`write_drift_evidence` tool**: New architect tool for persisting drift verification evidence after critic_drift_verifier delegation
1242
1302
  - Accepts phase number, verdict (APPROVED/NEEDS_REVISION), and summary
1243
1303
  - Normalizes verdict automatically (APPROVED → approved, NEEDS_REVISION → rejected)
@@ -1291,7 +1351,7 @@ The following tools can be assigned to agents via overrides:
1291
1351
 
1292
1352
  This release adds the optional Curator system for phase-level intelligence and fixes session snapshot persistence for task workflow states.
1293
1353
 
1294
- - **Curator system**: New optional background analysis system (`curator.enabled = false` by default). After each phase, collects events, checks compliance, and writes drift reports to `.swarm/drift-report-phase-N.json`. Three integration points: init on first phase, phase analysis after each phase, and drift injection into architect context at phase start.
1354
+ - **Curator system**: Background analysis system (`curator.enabled = false` by default in v6.22; **changed to `true` in v6.42**). After each phase, collects events, checks compliance, and writes drift reports to `.swarm/drift-report-phase-N.json`. Three integration points: init on first phase, phase analysis after each phase, and drift injection into architect context at phase start.
1295
1355
  - **Drift reports**: `runCriticDriftCheck` compares planned vs. actual decisions and writes structured drift reports with alignment scores (`ALIGNED` / `MINOR_DRIFT` / `MAJOR_DRIFT` / `OFF_SPEC`). Latest drift summary is prepended to the architect's knowledge context each phase.
1296
1356
  - **Issue #81 fix — taskWorkflowStates persistence**: Session snapshots now correctly serialize and restore the per-task state machine. Invalid state values are filtered to `idle` on deserialization. `reconcileTaskStatesFromPlan` seeds task states from `plan.json` on snapshot load (completed → `tests_run`, in-progress → `coder_delegated`).
1297
1357
 
@@ -1423,7 +1483,7 @@ bun test
1423
1483
 
1424
1484
  ## Supported Languages
1425
1485
 
1426
- OpenCode Swarm v6.16+ ships with language profiles for 11 languages across three quality tiers. All tools use graceful degradation — if a binary is not on PATH, the tool skips with a soft warning rather than a hard failure.
1486
+ OpenCode Swarm v6.46+ ships with language profiles for 12 languages across three quality tiers. All tools use graceful degradation — if a binary is not on PATH, the tool skips with a soft warning rather than a hard failure.
1427
1487
 
1428
1488
  | Language | Tier | Syntax | Build | Test | Lint | Audit | SAST |
1429
1489
  |---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
@@ -1438,6 +1498,9 @@ OpenCode Swarm v6.16+ ships with language profiles for 11 languages across three
1438
1498
  | Swift | 2 | ✅ | ✅ swift build | ✅ swift test | ✅ swiftlint | — | 🔶 Semgrep exp. |
1439
1499
  | Dart / Flutter | 3 | ✅ | ✅ dart pub | ✅ dart test | ✅ dart analyze | ✅ dart pub outdated | — |
1440
1500
  | Ruby | 3 | ✅ | — | ✅ RSpec / minitest | ✅ RuboCop | ✅ bundle-audit | 🔶 Semgrep exp. |
1501
+ | PHP / Laravel | 3 | ✅ | ✅ Composer install | ✅ PHPUnit / Pest / artisan test | ✅ Pint / PHP-CS-Fixer | ✅ composer audit | ✅ 10+ native rules |
1502
+
1503
+ > **PHP + Laravel baseline**: PHP v6.49+ ships with deterministic Laravel project detection (multi-signal: `artisan` file, `laravel/framework` dependency, `config/app.php`). When detected, commands are automatically overridden to `php artisan test`, Pint formatting, and PHPStan static analysis. Laravel-specific SAST rules cover SQL injection via raw queries, mass-assignment vulnerabilities, and destructive migrations without rollback. `.blade.php` files are included in all scanning pipelines.
1441
1504
 
1442
1505
  **Tier definitions:**
1443
1506
  - **Tier 1** — Full pipeline: all tools integrated and tested end-to-end.
@@ -1450,9 +1513,11 @@ OpenCode Swarm v6.16+ ships with language profiles for 11 languages across three
1450
1513
 
1451
1514
  ## Curator
1452
1515
 
1453
- The Curator is an optional background analysis system that runs after each phase. It is **disabled by default** (`curator.enabled = false`) and never blocks execution — all Curator operations are wrapped in try/catch.
1516
+ The Curator is a background analysis system that runs after each phase. It is **enabled by default** as of v6.42 (`curator.enabled = true`) and never blocks execution — all Curator operations are wrapped in try/catch. It falls back gracefully to data-only mode when no SDK client is available.
1517
+
1518
+ Since v6.42, the Curator performs real LLM analysis by delegating to the Explorer agent with curator-specific prompts. Before v6.42, the LLM delegation was scaffolded but never wired.
1454
1519
 
1455
- To enable, set `"curator": { "enabled": true }` in your config. When enabled, it writes `.swarm/curator-summary.json` and `.swarm/drift-report-phase-N.json` files.
1520
+ To disable, set `"curator": { "enabled": false }` in your config. When enabled, it writes `.swarm/curator-summary.json`, `.swarm/curator-briefing.md`, and `.swarm/drift-report-phase-N.json` files.
1456
1521
 
1457
1522
  ### What the Curator Does
1458
1523
 
@@ -1470,7 +1535,7 @@ Add a `curator` block to `.opencode/opencode-swarm.json`:
1470
1535
  ```json
1471
1536
  {
1472
1537
  "curator": {
1473
- "enabled": false,
1538
+ "enabled": true,
1474
1539
  "init_enabled": true,
1475
1540
  "phase_enabled": true,
1476
1541
  "max_summary_tokens": 2000,
@@ -1484,7 +1549,7 @@ Add a `curator` block to `.opencode/opencode-swarm.json`:
1484
1549
 
1485
1550
  | Field | Default | Description |
1486
1551
  |-------|---------|-------------|
1487
- | `enabled` | `false` | Master switch. Set to `true` to activate the Curator pipeline. |
1552
+ | `enabled` | `true` | Master switch. Set to `false` to disable the Curator pipeline. |
1488
1553
  | `init_enabled` | `true` | Initialize curator summary on first phase (requires `enabled: true`). |
1489
1554
  | `phase_enabled` | `true` | Run phase analysis and knowledge updates after each phase. |
1490
1555
  | `max_summary_tokens` | `2000` | Maximum token budget for curator knowledge summaries. |
@@ -1533,6 +1598,7 @@ Run `/swarm reset --confirm`.
1533
1598
  - [Getting Started](docs/getting-started.md)
1534
1599
  - [Architecture Deep Dive](docs/architecture.md)
1535
1600
  - [Design Rationale](docs/design-rationale.md)
1601
+ - [Plan Durability & Ledger](docs/plan-durability.md)
1536
1602
  - [Installation Guide](docs/installation.md)
1537
1603
  - [Linux + Docker Desktop Install Guide](docs/installation-linux-docker.md)
1538
1604
  - [LLM Operator Installation Guide](docs/installation-llm-operator.md)
@@ -1,5 +1,5 @@
1
1
  import type { AgentDefinition } from './architect';
2
- export declare const CURATOR_INIT_PROMPT = "## IDENTITY\nYou are Explorer in CURATOR_INIT mode. You consolidate prior session knowledge into an architect briefing.\nDO NOT use the Task tool to delegate. You ARE the agent that does the work.\n\nINPUT FORMAT:\nTASK: CURATOR_INIT\nPRIOR_SUMMARY: [JSON or \"none\"]\nKNOWLEDGE_ENTRIES: [JSON array of high-confidence entries]\nPROJECT_CONTEXT: [context.md excerpt]\n\nACTIONS:\n- Read the prior summary to understand session history\n- Cross-reference knowledge entries against project context\n- Identify contradictions (knowledge says X, project state shows Y)\n- Produce a concise briefing for the architect\n\nRULES:\n- Output under 2000 chars\n- No code modifications\n- Flag contradictions explicitly with CONTRADICTION: prefix\n- If no prior summary exists, state \"First session \u2014 no prior context\"\n\nOUTPUT FORMAT:\nBRIEFING:\n[concise summary of prior session state, key decisions, active blockers]\n\nCONTRADICTIONS:\n- [entry_id]: [description] (or \"None detected\")\n\nKNOWLEDGE_STATS:\n- Entries reviewed: [N]\n- Prior phases covered: [N]\n";
3
- export declare const CURATOR_PHASE_PROMPT = "## IDENTITY\nYou are Explorer in CURATOR_PHASE mode. You consolidate a completed phase into a digest.\nDO NOT use the Task tool to delegate. You ARE the agent that does the work.\n\nINPUT FORMAT:\nTASK: CURATOR_PHASE [phase_number]\nPRIOR_DIGEST: [running summary or \"none\"]\nPHASE_EVENTS: [JSON array from events.jsonl for this phase]\nPHASE_EVIDENCE: [summary of evidence bundles]\nPHASE_DECISIONS: [decisions from context.md]\nAGENTS_DISPATCHED: [list]\nAGENTS_EXPECTED: [list from config]\n\nACTIONS:\n- Extend the prior digest with this phase's outcomes (do NOT regenerate from scratch)\n- Identify workflow deviations: missing reviewer, missing retro, skipped test_engineer\n- Recommend knowledge updates: entries to promote, archive, or flag as contradicted\n- Summarize key decisions and blockers resolved\n\nRULES:\n- Output under 2000 chars\n- No code modifications\n- Compliance observations are READ-ONLY \u2014 report, do not enforce\n- Extend the digest, never replace it\n\nOUTPUT FORMAT:\nPHASE_DIGEST:\nphase: [N]\nsummary: [what was accomplished]\nagents_used: [list]\ntasks_completed: [N]/[total]\nkey_decisions: [list]\nblockers_resolved: [list]\n\nCOMPLIANCE:\n- [type]: [description] (or \"No deviations observed\")\n\nKNOWLEDGE_UPDATES:\n- [action] new: [reason] (or \"No recommendations\")\nNOTE: Always use \"new\" as the token \u2014 existing entry IDs (UUID v4) are not available in this context. Any non-UUID token is treated as \"new\" by the parser. Only \"promote new:\" creates a new entry; \"archive new:\" and \"flag_contradiction new:\" are silently skipped because those actions require an existing entry to operate on.\n\nEXTENDED_DIGEST:\n[the full running digest with this phase appended]\n";
2
+ export declare const CURATOR_INIT_PROMPT = "## IDENTITY\nYou are Explorer in CURATOR_INIT mode. You consolidate prior session knowledge into an architect briefing.\nDO NOT use the Task tool to delegate. You ARE the agent that does the work.\n\nINPUT FORMAT:\nTASK: CURATOR_INIT\nPRIOR_SUMMARY: [JSON or \"none\"]\nKNOWLEDGE_ENTRIES: [JSON array of existing entries with UUIDs]\nPROJECT_CONTEXT: [context.md excerpt]\n\nACTIONS:\n- Read the prior summary to understand session history\n- Cross-reference knowledge entries against project context\n- Identify contradictions (knowledge says X, project state shows Y)\n- Recommend rewrites for verbose or stale lessons\n- Produce a concise briefing for the architect\n\nRULES:\n- Output under 2000 chars\n- No code modifications\n- Flag contradictions explicitly with CONTRADICTION: prefix\n- If no prior summary exists, state \"First session \u2014 no prior context\"\n\nOUTPUT FORMAT:\nBRIEFING:\n[concise summary of prior session state, key decisions, active blockers]\n\nCONTRADICTIONS:\n- [entry_id]: [description] (or \"None detected\")\n\nKNOWLEDGE_UPDATES:\n- promote <uuid>: <reason> (boost confidence, mark hive_eligible)\n- archive <uuid>: <reason> (mark as archived \u2014 no longer injected)\n- rewrite <uuid>: <new lesson text> (replace verbose/stale lesson with tighter version, max 280 chars)\n- flag_contradiction <uuid>: <reason> (tag as contradicted)\n- promote new: <new lesson text> (add a brand-new entry)\nUse the UUID from KNOWLEDGE_ENTRIES when archiving, rewriting, or flagging an existing entry. Use \"new\" only when recommending a brand-new entry.\n\nKNOWLEDGE_STATS:\n- Entries reviewed: [N]\n- Prior phases covered: [N]\n";
3
+ export declare const CURATOR_PHASE_PROMPT = "## IDENTITY\nYou are Explorer in CURATOR_PHASE mode. You consolidate a completed phase into a digest.\nDO NOT use the Task tool to delegate. You ARE the agent that does the work.\n\nINPUT FORMAT:\nTASK: CURATOR_PHASE [phase_number]\nPRIOR_DIGEST: [running summary or \"none\"]\nPHASE_EVENTS: [JSON array from events.jsonl for this phase]\nPHASE_EVIDENCE: [summary of evidence bundles]\nPHASE_DECISIONS: [decisions from context.md]\nAGENTS_DISPATCHED: [list]\nAGENTS_EXPECTED: [list from config]\nKNOWLEDGE_ENTRIES: [JSON array of existing entries with UUIDs]\n\nACTIONS:\n- Extend the prior digest with this phase's outcomes (do NOT regenerate from scratch)\n- Identify workflow deviations: missing reviewer, missing retro, skipped test_engineer\n- Recommend knowledge updates: entries to promote, archive, rewrite, or flag as contradicted\n- Summarize key decisions and blockers resolved\n\nRULES:\n- Output under 2000 chars\n- No code modifications\n- Compliance observations are READ-ONLY \u2014 report, do not enforce\n- Extend the digest, never replace it\n\nOUTPUT FORMAT:\nPHASE_DIGEST:\nphase: [N]\nsummary: [what was accomplished]\nagents_used: [list]\ntasks_completed: [N]/[total]\nkey_decisions: [list]\nblockers_resolved: [list]\n\nCOMPLIANCE:\n- [type]: [description] (or \"No deviations observed\")\n\nKNOWLEDGE_UPDATES:\n- promote <uuid>: <reason> (boost confidence, mark hive_eligible)\n- archive <uuid>: <reason> (mark as archived \u2014 no longer injected)\n- rewrite <uuid>: <new lesson text> (replace verbose/stale lesson with tighter version, max 280 chars)\n- flag_contradiction <uuid>: <reason> (tag as contradicted)\n- promote new: <new lesson text> (add a brand-new entry)\nUse the UUID from KNOWLEDGE_ENTRIES when archiving, rewriting, or flagging an existing entry. Use \"new\" only when recommending a brand-new entry.\n\nEXTENDED_DIGEST:\n[the full running digest with this phase appended]\n";
4
4
  export declare function createExplorerAgent(model: string, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
5
5
  export declare function createExplorerCuratorAgent(model: string, mode: 'CURATOR_INIT' | 'CURATOR_PHASE', customAppendPrompt?: string): AgentDefinition;
@@ -8,7 +8,7 @@
8
8
  export interface PlanSyncWorkerOptions {
9
9
  /** Directory containing .swarm folder (defaults to cwd) */
10
10
  directory?: string;
11
- /** Debounce delay in ms (default: 300ms) */
11
+ /** Debounce delay in ms (default: 500ms) */
12
12
  debounceMs?: number;
13
13
  /** Polling interval in ms when fs.watch fails (default: 2000ms) */
14
14
  pollIntervalMs?: number;
package/dist/cli/index.js CHANGED
@@ -16517,25 +16517,33 @@ async function loadPlan(directory) {
16517
16517
  if (await ledgerExists(directory)) {
16518
16518
  const planHash = computePlanHash(validated);
16519
16519
  const ledgerHash = await getLatestLedgerHash(directory);
16520
- if (ledgerHash !== "" && planHash !== ledgerHash) {
16521
- const currentPlanId = `${validated.swarm}-${validated.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
16522
- const ledgerEvents = await readLedgerEvents(directory);
16523
- const firstEvent = ledgerEvents.length > 0 ? ledgerEvents[0] : null;
16524
- if (firstEvent && firstEvent.plan_id !== currentPlanId) {
16525
- warn(`[loadPlan] Ledger identity mismatch (ledger: ${firstEvent.plan_id}, plan: ${currentPlanId}) \u2014 skipping ledger rebuild (migration detected). Use /swarm reset-session to reinitialize the ledger.`);
16526
- } else {
16527
- warn("[loadPlan] plan.json is stale (hash mismatch with ledger) \u2014 rebuilding from ledger. If this recurs, run /swarm reset-session to clear stale session state.");
16528
- try {
16529
- const rebuilt = await replayFromLedger(directory);
16530
- if (rebuilt) {
16531
- await rebuildPlan(directory, rebuilt);
16532
- warn("[loadPlan] Rebuilt plan from ledger. Checkpoint available at SWARM_PLAN.md if it exists.");
16533
- return rebuilt;
16520
+ const resolvedWorkspace = path8.resolve(directory);
16521
+ if (!startupLedgerCheckedWorkspaces.has(resolvedWorkspace)) {
16522
+ startupLedgerCheckedWorkspaces.add(resolvedWorkspace);
16523
+ if (ledgerHash !== "" && planHash !== ledgerHash) {
16524
+ const currentPlanId = `${validated.swarm}-${validated.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
16525
+ const ledgerEvents = await readLedgerEvents(directory);
16526
+ const firstEvent = ledgerEvents.length > 0 ? ledgerEvents[0] : null;
16527
+ if (firstEvent && firstEvent.plan_id !== currentPlanId) {
16528
+ warn(`[loadPlan] Ledger identity mismatch (ledger: ${firstEvent.plan_id}, plan: ${currentPlanId}) \u2014 skipping ledger rebuild (migration detected). Use /swarm reset-session to reinitialize the ledger.`);
16529
+ } else {
16530
+ warn("[loadPlan] plan.json is stale (hash mismatch with ledger) \u2014 rebuilding from ledger. If this recurs, run /swarm reset-session to clear stale session state.");
16531
+ try {
16532
+ const rebuilt = await replayFromLedger(directory);
16533
+ if (rebuilt) {
16534
+ await rebuildPlan(directory, rebuilt);
16535
+ warn("[loadPlan] Rebuilt plan from ledger. Checkpoint available at SWARM_PLAN.md if it exists.");
16536
+ return rebuilt;
16537
+ }
16538
+ } catch (replayError) {
16539
+ warn(`[loadPlan] Ledger replay failed during hash-mismatch rebuild: ${replayError instanceof Error ? replayError.message : String(replayError)}. Returning stale plan.json. To recover: check SWARM_PLAN.md for a checkpoint, or run /swarm reset-session.`);
16534
16540
  }
16535
- } catch (replayError) {
16536
- warn(`[loadPlan] Ledger replay failed during hash-mismatch rebuild: ${replayError instanceof Error ? replayError.message : String(replayError)}. Returning stale plan.json. To recover: check SWARM_PLAN.md for a checkpoint, or run /swarm reset-session.`);
16537
16541
  }
16538
16542
  }
16543
+ } else if (ledgerHash !== "" && planHash !== ledgerHash) {
16544
+ if (process.env.DEBUG_SWARM) {
16545
+ console.warn(`[loadPlan] Ledger hash mismatch during active session for ${resolvedWorkspace} \u2014 skipping rebuild (startup check already performed).`);
16546
+ }
16539
16547
  }
16540
16548
  }
16541
16549
  return validated;
@@ -17028,11 +17036,13 @@ function migrateLegacyPlan(planContent, swarmId) {
17028
17036
  };
17029
17037
  return plan;
17030
17038
  }
17039
+ var startupLedgerCheckedWorkspaces;
17031
17040
  var init_manager2 = __esm(() => {
17032
17041
  init_plan_schema();
17033
17042
  init_utils2();
17034
17043
  init_utils();
17035
17044
  init_ledger();
17045
+ startupLedgerCheckedWorkspaces = new Set;
17036
17046
  });
17037
17047
 
17038
17048
  // src/services/config-doctor.ts
@@ -18665,6 +18675,8 @@ var KnowledgeConfigSchema = exports_external.object({
18665
18675
  hive_max_entries: exports_external.number().min(1).max(1e5).default(200),
18666
18676
  auto_promote_days: exports_external.number().min(1).max(3650).default(90),
18667
18677
  max_inject_count: exports_external.number().min(0).max(50).default(5),
18678
+ inject_char_budget: exports_external.number().min(200).max(1e4).default(2000),
18679
+ max_lesson_display_chars: exports_external.number().min(40).max(280).default(120),
18668
18680
  dedup_threshold: exports_external.number().min(0).max(1).default(0.6),
18669
18681
  scope_filter: exports_external.array(exports_external.string()).default(["global"]),
18670
18682
  hive_enabled: exports_external.boolean().default(true),
@@ -35627,37 +35639,80 @@ LANGUAGE_REGISTRY.register({
35627
35639
  id: "php",
35628
35640
  displayName: "PHP",
35629
35641
  tier: 3,
35630
- extensions: [".php", ".phtml"],
35642
+ extensions: [".php", ".phtml", ".blade.php"],
35631
35643
  treeSitter: { grammarId: "php", wasmFile: "tree-sitter-php.wasm" },
35632
35644
  build: {
35633
35645
  detectFiles: ["composer.json"],
35634
- commands: []
35646
+ commands: [
35647
+ {
35648
+ name: "Composer Install",
35649
+ cmd: "composer install --no-interaction --prefer-dist",
35650
+ detectFile: "composer.json",
35651
+ priority: 1
35652
+ }
35653
+ ]
35635
35654
  },
35636
35655
  test: {
35637
- detectFiles: ["phpunit.xml", "phpunit.xml.dist"],
35656
+ detectFiles: ["Pest.php", "phpunit.xml", "phpunit.xml.dist"],
35638
35657
  frameworks: [
35658
+ {
35659
+ name: "Pest",
35660
+ detect: "Pest.php",
35661
+ cmd: "vendor/bin/pest",
35662
+ priority: 1
35663
+ },
35639
35664
  {
35640
35665
  name: "PHPUnit",
35641
35666
  detect: "phpunit.xml",
35642
35667
  cmd: "vendor/bin/phpunit",
35643
- priority: 1
35668
+ priority: 3
35669
+ },
35670
+ {
35671
+ name: "PHPUnit",
35672
+ detect: "phpunit.xml.dist",
35673
+ cmd: "vendor/bin/phpunit",
35674
+ priority: 4
35644
35675
  }
35645
35676
  ]
35646
35677
  },
35647
35678
  lint: {
35648
- detectFiles: [".php-cs-fixer.php", "phpcs.xml"],
35679
+ detectFiles: [
35680
+ "phpstan.neon",
35681
+ "phpstan.neon.dist",
35682
+ "pint.json",
35683
+ ".php-cs-fixer.php",
35684
+ "phpcs.xml"
35685
+ ],
35649
35686
  linters: [
35687
+ {
35688
+ name: "PHPStan",
35689
+ detect: "phpstan.neon",
35690
+ cmd: "vendor/bin/phpstan analyse",
35691
+ priority: 1
35692
+ },
35693
+ {
35694
+ name: "PHPStan",
35695
+ detect: "phpstan.neon.dist",
35696
+ cmd: "vendor/bin/phpstan analyse",
35697
+ priority: 2
35698
+ },
35699
+ {
35700
+ name: "Pint",
35701
+ detect: "pint.json",
35702
+ cmd: "vendor/bin/pint --test",
35703
+ priority: 3
35704
+ },
35650
35705
  {
35651
35706
  name: "PHP-CS-Fixer",
35652
35707
  detect: ".php-cs-fixer.php",
35653
35708
  cmd: "vendor/bin/php-cs-fixer fix --dry-run --diff",
35654
- priority: 1
35709
+ priority: 4
35655
35710
  }
35656
35711
  ]
35657
35712
  },
35658
35713
  audit: {
35659
35714
  detectFiles: ["composer.lock"],
35660
- command: "composer audit --format=json",
35715
+ command: "composer audit --locked --format=json",
35661
35716
  outputFormat: "json"
35662
35717
  },
35663
35718
  sast: { nativeRuleSet: "php", semgrepSupport: "ga" },
@@ -35666,13 +35721,25 @@ LANGUAGE_REGISTRY.register({
35666
35721
  "Follow PSR-12 coding standards",
35667
35722
  "Use strict types declaration: declare(strict_types=1)",
35668
35723
  "Prefer type hints and return type declarations on all functions",
35669
- "Use dependency injection over static methods and singletons"
35724
+ "Use dependency injection over static methods and singletons",
35725
+ "Prefer named constructors and value objects over primitive obsession"
35670
35726
  ],
35671
35727
  reviewerChecklist: [
35672
35728
  "Verify no user input reaches SQL queries without parameterised binding",
35673
35729
  "Check for XSS \u2014 all output must be escaped with htmlspecialchars()",
35674
35730
  "Confirm no eval(), exec(), or shell_exec() with user-controlled input",
35675
- "Validate proper error handling \u2014 no bare catch blocks that swallow errors"
35731
+ "Validate proper error handling \u2014 no bare catch blocks that swallow errors",
35732
+ "Challenge any PHP/Laravel documentation or README claim that exceeds what is implemented and CI-verified in v6.49.0 (composer build, PHPUnit/Pest/artisan test, Pint/PHP-CS-Fixer lint, PHPStan static analysis, composer audit, Laravel detection, Blade scanning, 3 Laravel SAST rules). If a PR adds docs claiming broader support, verify it is backed by tests."
35733
+ ],
35734
+ testConstraints: [
35735
+ "Prefer feature tests for HTTP, middleware, and authentication flows \u2014 use Laravel RefreshDatabase or DatabaseTransactions traits",
35736
+ "Use unit tests for isolated business logic classes that do not require the full Laravel application container",
35737
+ "Pest and PHPUnit coexist in many Laravel repos \u2014 php artisan test runs both; do not assume PHPUnit-only",
35738
+ "Use .env.testing for test environment configuration; run php artisan config:clear when environment changes affect tests",
35739
+ "For database tests, prefer RefreshDatabase over manual setUp/tearDown to avoid state leakage between tests",
35740
+ "Run php artisan config:clear and php artisan cache:clear before running tests if environment variables changed",
35741
+ "Use separate .env.testing file for test-specific configuration; never rely on .env for CI test runs",
35742
+ "For parallel testing with php artisan test --parallel, ensure database connections use separate databases per worker (APP_ENV=testing + test database suffix pattern)"
35676
35743
  ]
35677
35744
  }
35678
35745
  });
@@ -35813,6 +35880,17 @@ var ECOSYSTEMS = [
35813
35880
  { command: "make", priority: 1 },
35814
35881
  { command: "cmake -B build && cmake --build build", priority: 2 }
35815
35882
  ]
35883
+ },
35884
+ {
35885
+ ecosystem: "php-composer",
35886
+ buildFiles: ["composer.json"],
35887
+ toolchainCommands: ["composer"],
35888
+ commands: [
35889
+ {
35890
+ command: "composer install --no-interaction --prefer-dist",
35891
+ priority: 1
35892
+ }
35893
+ ]
35816
35894
  }
35817
35895
  ];
35818
35896
  var PROFILE_TO_ECOSYSTEM_NAMES = {
@@ -35826,7 +35904,8 @@ var PROFILE_TO_ECOSYSTEM_NAMES = {
35826
35904
  cpp: ["cpp"],
35827
35905
  swift: ["swift"],
35828
35906
  dart: ["dart"],
35829
- ruby: []
35907
+ ruby: [],
35908
+ php: ["php-composer"]
35830
35909
  };
35831
35910
  var toolchainCache = new Map;
35832
35911
  function isCommandAvailable(command) {
@@ -415,6 +415,8 @@ export declare const KnowledgeConfigSchema: z.ZodObject<{
415
415
  hive_max_entries: z.ZodDefault<z.ZodNumber>;
416
416
  auto_promote_days: z.ZodDefault<z.ZodNumber>;
417
417
  max_inject_count: z.ZodDefault<z.ZodNumber>;
418
+ inject_char_budget: z.ZodDefault<z.ZodNumber>;
419
+ max_lesson_display_chars: z.ZodDefault<z.ZodNumber>;
418
420
  dedup_threshold: z.ZodDefault<z.ZodNumber>;
419
421
  scope_filter: z.ZodDefault<z.ZodArray<z.ZodString>>;
420
422
  hive_enabled: z.ZodDefault<z.ZodBoolean>;
@@ -778,6 +780,8 @@ export declare const PluginConfigSchema: z.ZodObject<{
778
780
  hive_max_entries: z.ZodDefault<z.ZodNumber>;
779
781
  auto_promote_days: z.ZodDefault<z.ZodNumber>;
780
782
  max_inject_count: z.ZodDefault<z.ZodNumber>;
783
+ inject_char_budget: z.ZodDefault<z.ZodNumber>;
784
+ max_lesson_display_chars: z.ZodDefault<z.ZodNumber>;
781
785
  dedup_threshold: z.ZodDefault<z.ZodNumber>;
782
786
  scope_filter: z.ZodDefault<z.ZodArray<z.ZodString>>;
783
787
  hive_enabled: z.ZodDefault<z.ZodBoolean>;
@@ -36,7 +36,7 @@ export interface ComplianceObservation {
36
36
  severity: 'info' | 'warning';
37
37
  }
38
38
  export interface KnowledgeRecommendation {
39
- action: 'promote' | 'archive' | 'flag_contradiction';
39
+ action: 'promote' | 'archive' | 'flag_contradiction' | 'rewrite';
40
40
  entry_id?: string;
41
41
  lesson: string;
42
42
  reason: string;
@@ -65,6 +65,10 @@ export interface KnowledgeConfig {
65
65
  auto_promote_days: number;
66
66
  /** Maximum knowledge entries to inject per architect message. Default: 5 */
67
67
  max_inject_count: number;
68
+ /** Maximum total chars for the entire injection block. Default: 2000 */
69
+ inject_char_budget?: number;
70
+ /** Maximum display chars per lesson at injection time. Default: 120 */
71
+ max_lesson_display_chars?: number;
68
72
  /** Jaccard bigram similarity threshold for deduplication. Default: 0.6 */
69
73
  dedup_threshold: number;
70
74
  /** Scope filters to apply when reading knowledge. Default: ['global'] */