opencode-swarm 7.114.7 → 7.114.9
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/.opencode/skills/ci-fix-monitor/SKILL.md +8 -13
- package/.opencode/skills/commit-pr/SKILL.md +4 -0
- package/.opencode/skills/engineering-conventions/SKILL.md +33 -0
- package/.opencode/skills/execute/SKILL.md +2 -0
- package/.opencode/skills/swarm-ci-monitor/SKILL.md +5 -0
- package/.opencode/skills/swarm-pr-feedback/SKILL.md +2 -0
- package/.opencode/skills/writing-tests/SKILL.md +2 -0
- package/README.md +16 -14
- package/dist/agents/template.d.ts +40 -20
- package/dist/cli/{curator-qshyr2tc.js → curator-5xt89z05.js} +7 -7
- package/dist/cli/{curator-llm-factory-2xgznxyw.js → curator-llm-factory-pnhvf3s3.js} +7 -7
- package/dist/cli/{evidence-summary-service-8g594znj.js → evidence-summary-service-fehwj116.js} +1 -1
- package/dist/cli/{guardrail-explain-4t8fnysh.js → guardrail-explain-7aztgtyh.js} +8 -8
- package/dist/cli/{hive-promoter-5ngbmnrw.js → hive-promoter-q899q2m6.js} +7 -7
- package/dist/cli/{index-z01r5483.js → index-54sevh81.js} +8 -8
- package/dist/cli/{index-7stsmndb.js → index-6f6y2rbp.js} +3 -3
- package/dist/cli/{index-kjbfry6m.js → index-8f2270hc.js} +1 -1
- package/dist/cli/{index-gmjrwz34.js → index-m9m7p49w.js} +1 -1
- package/dist/cli/{index-qrnhvhmg.js → index-n18yy0z1.js} +26 -2
- package/dist/cli/{index-91qesget.js → index-rk6qhyng.js} +2 -2
- package/dist/cli/{index-6ctejje2.js → index-typ408f4.js} +710 -630
- package/dist/cli/{index-vjvdvjd3.js → index-x12hvfpf.js} +3 -3
- package/dist/cli/{index-f6y341yk.js → index-yrrqs4b0.js} +82 -21
- package/dist/cli/index.d.ts +34 -0
- package/dist/cli/index.js +105 -28
- package/dist/cli/{knowledge-escalator-qn7ew687.js → knowledge-escalator-5gwp1ar8.js} +3 -3
- package/dist/cli/{knowledge-events-k2xsz5bh.js → knowledge-events-m304swh6.js} +1 -1
- package/dist/cli/{knowledge-store-ksa1dr2z.js → knowledge-store-9babt8rd.js} +1 -1
- package/dist/cli/{knowledge-validator-2knz0d2t.js → knowledge-validator-t9sym59g.js} +4 -2
- package/dist/cli/{skill-generator-w6qd9mde.js → skill-generator-tav44xpm.js} +4 -4
- package/dist/commands/ci-monitor.d.ts +18 -0
- package/dist/commands/registry.d.ts +8 -0
- package/dist/config/skill-mirrors.d.ts +22 -1
- package/dist/hooks/adversarial-detector.d.ts +6 -0
- package/dist/hooks/delegation-gate.d.ts +19 -0
- package/dist/hooks/guardrails/index.d.ts +2 -2
- package/dist/hooks/knowledge-validator.d.ts +22 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +194 -169
- package/dist/plan/ledger.d.ts +83 -20
- package/dist/types/delegation.d.ts +24 -0
- package/package.json +1 -1
- package/dist/graph/graph-builder.d.ts +0 -39
- package/dist/graph/graph-query.d.ts +0 -42
- package/dist/graph/graph-store.d.ts +0 -27
- package/dist/graph/import-extractor.d.ts +0 -44
- package/dist/graph/index.d.ts +0 -16
- package/dist/graph/symbol-extractor.d.ts +0 -17
- package/dist/graph/types.d.ts +0 -84
- package/dist/sandbox/win32/restricted-token-executor.d.ts +0 -9
|
@@ -5,21 +5,8 @@ description: >
|
|
|
5
5
|
Monitor CI on a PR, diagnose failures, fix them, and re-push until green.
|
|
6
6
|
Covers reading CI logs, classifying failure types (check-title, package-check,
|
|
7
7
|
test failures, lint), determining the correct fix, and re-pushing.
|
|
8
|
-
triggers:
|
|
9
|
-
- ci check failure
|
|
10
|
-
- fix ci
|
|
11
|
-
- monitor ci
|
|
12
|
-
generated_from_knowledge: []
|
|
13
|
-
source_knowledge_ids: []
|
|
14
|
-
generated_at: 2026-07-02T02:35:49.945Z
|
|
15
|
-
confidence: 0.60
|
|
16
|
-
status: active
|
|
17
|
-
version: 6
|
|
18
|
-
skill_origin: generated
|
|
19
8
|
---
|
|
20
9
|
|
|
21
|
-
<!-- generated by opencode-swarm skill-generator. Do not edit by hand; edits will be preserved on regeneration only with controlled update mode. -->
|
|
22
|
-
|
|
23
10
|
# CI Fix & Monitor Protocol
|
|
24
11
|
|
|
25
12
|
Activates when the user asks to monitor CI, fix CI failures, or resolve red
|
|
@@ -201,3 +188,11 @@ the stall state to the user rather than waiting indefinitely.
|
|
|
201
188
|
Do NOT declare victory until ALL required checks pass. A check in `skipped`
|
|
202
189
|
state is acceptable only if the same check was skipped on the base branch
|
|
203
190
|
(i.e. the workflow gates on a path filter). Confirm this explicitly.
|
|
191
|
+
|
|
192
|
+
## Standalone retry bound
|
|
193
|
+
|
|
194
|
+
When this skill is invoked directly (not composed via `swarm-ci-monitor`'s
|
|
195
|
+
own 5-iteration counter), cap fix-push cycles at 5 iterations. If the PR is
|
|
196
|
+
still not green after 5 fix-push cycles, stop and escalate to the user with
|
|
197
|
+
the last failing check and a short log excerpt rather than looping
|
|
198
|
+
indefinitely.
|
|
@@ -79,6 +79,8 @@ git status --short
|
|
|
79
79
|
|
|
80
80
|
On Windows, prefer temporary save branches over `git stash`. If you must stash, use `git stash push --include-untracked` and verify the stash contents.
|
|
81
81
|
|
|
82
|
+
If this changeset edited any SKILL.md file's wording, also run `file:.swarm/bundled-skills/skill-edit-validation/SKILL.md`'s content-assertion sweep before committing, to catch stale test assertions.
|
|
83
|
+
|
|
82
84
|
## Step 1 - Commit and PR titles
|
|
83
85
|
|
|
84
86
|
Use `<type>(<scope>): <description>` exactly.
|
|
@@ -549,6 +551,8 @@ checks to rerun. Re-check before claiming final green or merge-readiness.
|
|
|
549
551
|
|
|
550
552
|
### Merge queue (current-base validation)
|
|
551
553
|
|
|
554
|
+
Read `file:.swarm/bundled-skills/merge-queue-readiness/SKILL.md` for the full pre-queue merge-group CI simulation protocol.
|
|
555
|
+
|
|
552
556
|
When `main` has a GitHub **merge queue** enabled, do not rebase or force-push a PR
|
|
553
557
|
*solely because `main` advanced*. Once required checks and review are green, add the
|
|
554
558
|
PR to the merge queue; GitHub re-runs the required workflows against the queued
|
|
@@ -52,6 +52,39 @@ The OpenCode `test_runner` tool is for **targeted agent validation** with explic
|
|
|
52
52
|
- For repo validation, run the shell commands in `contributing.md` / `TESTING.md` directly (per-file isolation loops + tier orchestration).
|
|
53
53
|
- `scope: 'all'` is gated behind the `SWARM_ALLOW_FULL_SUITE=1` env var (intended for opt-in CI mirrors only); there is no `allow_full_suite` arg. Default to `files: [...]` instead.
|
|
54
54
|
|
|
55
|
+
## Agent prompt strings — escaping pitfalls
|
|
56
|
+
|
|
57
|
+
Agent prompts in `src/agents/*.ts` are large TypeScript template literals. They frequently contain characters that have special meaning inside template literals and cause silent parse errors if unescaped:
|
|
58
|
+
|
|
59
|
+
| Character | Inside template literal | Correct escape |
|
|
60
|
+
|-----------|------------------------|----------------|
|
|
61
|
+
| Backtick `` ` `` | Terminates the literal | `` \` `` (single backslash — renders as `` ` `` in output) |
|
|
62
|
+
| `${` | Starts an interpolation | `\${` (single backslash) |
|
|
63
|
+
| Literal backslash `\` | Consumed by escape processing | `\\` (double backslash renders as `\` in output) |
|
|
64
|
+
|
|
65
|
+
**The most common failure pattern:** A coder adds an inline code example containing backticks to an agent prompt string. The unescaped backtick silently terminates the template literal, producing a `SyntaxError: Unexpected identifier` or `Unexpected token` at the character *after* the backtick — which appears unrelated to the actual cause.
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
// WRONG — unescaped backtick terminates the template literal
|
|
69
|
+
const PROMPT = `
|
|
70
|
+
Use `bun:test` for all tests. // ← bare backtick before "bun" closes the literal
|
|
71
|
+
`;
|
|
72
|
+
|
|
73
|
+
// CORRECT — single backslash before each backtick; renders as Use `bun:test` in output
|
|
74
|
+
const PROMPT = `
|
|
75
|
+
Use \`bun:test\` for all tests.
|
|
76
|
+
`;
|
|
77
|
+
|
|
78
|
+
// OVER-ESCAPED (also wrong) — triple backslash produces literal \` in the rendered prompt
|
|
79
|
+
const PROMPT = `
|
|
80
|
+
Use \\\`bun:test\\\` for all tests. // renders as: Use \`bun:test\` (backslashes visible)
|
|
81
|
+
`;
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Detection:** If `bun run build` or `bun --smol test` reports a parse error at a line number that seems far from any recent change, search the surrounding lines for an unescaped backtick inside a template literal.
|
|
85
|
+
|
|
86
|
+
**Prevention:** After adding any inline code example to an agent prompt, run `bun run build` immediately — the TypeScript compiler catches unescaped backticks as a syntax error before any tests run.
|
|
87
|
+
|
|
55
88
|
## The invariant-audit gate (PR-time)
|
|
56
89
|
|
|
57
90
|
Every PR that touches a relevant area must include an `## Invariant audit` section in its description. The format is in `AGENTS.md` ("Invariant audit required in PRs"). The `commit-pr` skill enforces this gate before push/PR — load it before committing.
|
|
@@ -111,6 +111,8 @@ Treating pre_check_batch as a substitute for the active swarm's reviewer agent i
|
|
|
111
111
|
|
|
112
112
|
When `council_mode` is OFF, the standard Stage B flow (steps 5j-5l: reviewer + test_engineer) runs as normal.
|
|
113
113
|
|
|
114
|
+
For set-dispatch reviewer/test_engineer verdict rows that must be attributed to plan tasks, read `file:.swarm/bundled-skills/gate-attribution/SKILL.md`. Before re-dispatching a coder for a task that already has a lane (any prior dispatch status), read `file:.swarm/bundled-skills/worktree-retry-cleanup/SKILL.md`.
|
|
115
|
+
|
|
114
116
|
5j. the active swarm's reviewer agent - General review. REJECTED before the configured QA retry limit → coder retry. REJECTED at the configured QA retry limit → escalate.
|
|
115
117
|
→ REQUIRED: Print "reviewer: [APPROVED | REJECTED — reason]"
|
|
116
118
|
5k. Security gate: if change matches TIER 3 criteria OR content contains SECURITY_KEYWORDS OR secretscan has ANY findings OR sast_scan has ANY findings at or above threshold → MUST delegate the active swarm's reviewer agent security-only review. REJECTED before the configured QA retry limit → coder retry. REJECTED at the configured QA retry limit → escalate to user.
|
|
@@ -241,6 +241,11 @@ already ran once in this invocation.
|
|
|
241
241
|
directly per Step 5 as an "un-approval" terminal, do not loop back to
|
|
242
242
|
Step 2.
|
|
243
243
|
|
|
244
|
+
Optional pre-queue simulation: `file:.swarm/bundled-skills/merge-queue-readiness/SKILL.md`
|
|
245
|
+
covers running `/swarm ci-simulate` before entering a merge queue. It is a
|
|
246
|
+
fast local signal, not a substitute for this step's live re-checks above —
|
|
247
|
+
run it in addition to, never instead of, Step 3.
|
|
248
|
+
|
|
244
249
|
## Step 4 — Merge
|
|
245
250
|
|
|
246
251
|
### 4a. Execute the merge
|
|
@@ -239,6 +239,8 @@ branches or prior work sessions.
|
|
|
239
239
|
|
|
240
240
|
## Batch Collection (mandatory before any fix)
|
|
241
241
|
|
|
242
|
+
Read `file:.swarm/bundled-skills/ci-failure-batching/SKILL.md` for the full batch collection and fix protocol before proceeding.
|
|
243
|
+
|
|
242
244
|
Issue #1746: 8+ push cycles where 3–4 would have sufficed with batching.
|
|
243
245
|
The anti-pattern: iterating check-by-check, proposing a fix for one failure,
|
|
244
246
|
pushing, waiting for CI, then discovering the next failure. Each cycle costs
|
|
@@ -617,6 +617,8 @@ authority checks:
|
|
|
617
617
|
|
|
618
618
|
`scripts/check-test-file-cap.sh` enforces the **500-line cap** per test file (FR-006) as a **diff-scoped ratchet**: new test files over 500 lines and existing over-cap files that grew fail the quality gate and block PR merge. Pre-existing over-cap files not touched by the PR are non-blocking. Escape hatch: `TEST_CAP_ENFORCE=0` soft-warns (use only for a deliberate growth PR).
|
|
619
619
|
|
|
620
|
+
For the full splitting protocol (describe-block extraction, shared helper management, pure-function extraction, mock isolation verification, cascading-split detection), read `file:.swarm/bundled-skills/test-file-split/SKILL.md`.
|
|
621
|
+
|
|
620
622
|
### Checking file length
|
|
621
623
|
|
|
622
624
|
```bash
|
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ Most AI coding tools let one model write code and ask that same model whether th
|
|
|
39
39
|
- 🔄 **Phase completion gates** — completion-verify and drift verifier gates enforced before phase completion
|
|
40
40
|
- 🔁 **Resumable sessions** — all state saved to `.swarm/`; pick up any project any day
|
|
41
41
|
- 🖥️ **PR Monitor** — GitHub PR subscription and background polling via `gh` CLI; delivers real-time CI, review, and merge status updates via the AutomationEventBus (FR-001, opt-in via `pr_monitor.enabled: true`). Subscribe with `/swarm pr subscribe <pr-url|owner/repo#N|N>`; unsubscribe with `/swarm pr unsubscribe <pr-url|owner/repo#N|N>`; check status with `/swarm pr status`. Enable `auto_pr_feedback: true` in `pr_monitor` config to inject `[MODE: PR_FEEDBACK pr="URL"]` on CI failures and merge conflicts automatically.
|
|
42
|
-
- 🌐 **
|
|
42
|
+
- 🌐 **13 full language profiles** (TypeScript, JavaScript, Python, Go, Rust, Java, Kotlin, C/C++, C#, Ruby, Swift, Dart, PHP) with **tree-sitter parse validation across 20 grammars** (adds CSS, Bash, PowerShell, INI, Regex — and `.tsx` / `.c` aliases) — extending: see [docs/adding-a-language.md](docs/adding-a-language.md)
|
|
43
43
|
- 🛡️ **Built-in security** — SAST, secrets scanning, dependency audit per task
|
|
44
44
|
- 🔒 **Scope enforcement** — Validates write targets against declared scope with cross-process persistence, TTL expiry, and scope-aware destructive command blocking. **Handles both single-string and array-based path arguments** (`files[]`, `paths[]`, `targetFiles[]`) to prevent scope bypass via multi-file tool calls.
|
|
45
45
|
- 📝 **Shell write detection** — Static analysis of POSIX/PowerShell/cmd commands to detect file writes (redirects, builtins, in-place editors, network downloads, archive extraction, git destructive ops) before execution
|
|
@@ -550,14 +550,14 @@ These quality gates run locally. No Docker is required. Config-gated features su
|
|
|
550
550
|
|
|
551
551
|
### Context Budget Guard
|
|
552
552
|
|
|
553
|
-
The Context Budget Guard monitors how
|
|
553
|
+
The Context Budget Guard monitors how full the model's context window is getting across the whole conversation. It helps prevent context overflow before it becomes a problem.
|
|
554
554
|
|
|
555
555
|
### Default Behavior
|
|
556
556
|
|
|
557
557
|
- **Enabled automatically** — No setup required. Swarm starts tracking context usage right away.
|
|
558
|
-
- **What it measures** —
|
|
559
|
-
- **Warning threshold (0.7 ratio)** — When
|
|
560
|
-
- **Critical threshold (0.9 ratio)** — When
|
|
558
|
+
- **What it measures** — The estimated total tokens across **all** messages in the conversation (every text part of every message — your prompts, the model's responses, and injected content alike), divided by the model's context window. The window comes from `context_budget.model_limits` (default `128000`), resolved per model/provider. It does **not** measure only swarm-injected content, and it does **not** read `max_injection_tokens`.
|
|
559
|
+
- **Warning threshold (0.7 ratio)** — When total conversation tokens reach 70% of the model context window (e.g. ~89,600 of 128,000), the architect receives a one-time advisory warning. This is informational — execution continues normally.
|
|
560
|
+
- **Critical threshold (0.9 ratio)** — When total conversation tokens reach 90% of the model context window (e.g. ~115,200 of 128,000), the architect receives a critical alert with a recommendation to run `/swarm handoff`. This is also one-time only.
|
|
561
561
|
- **Non-nagging** — Alerts fire once per session, not repeatedly. You won't be pestered every turn.
|
|
562
562
|
- **Who sees warnings** — Only the architect receives these warnings. Other agents are unaware of the budget.
|
|
563
563
|
|
|
@@ -588,17 +588,18 @@ Swarm includes an intelligent skill propagation system that tracks, validates, a
|
|
|
588
588
|
|
|
589
589
|
```json
|
|
590
590
|
{
|
|
591
|
-
"
|
|
591
|
+
"skillPropagation": {
|
|
592
592
|
"enabled": true,
|
|
593
593
|
"enforce": false,
|
|
594
|
-
"
|
|
595
|
-
"threshold": 0.5,
|
|
596
|
-
"max_recommendations": 5
|
|
597
|
-
}
|
|
594
|
+
"audiences": []
|
|
598
595
|
}
|
|
599
596
|
}
|
|
600
597
|
```
|
|
601
598
|
|
|
599
|
+
- **`enabled`** (boolean, default `true`) — turns skill-propagation scoring, recommendations, and warnings on or off. The mandatory explicit-skill-reference integrity check still runs even when this is `false`.
|
|
600
|
+
- **`enforce`** (boolean, default `false`) — when `true`, blocks delegations that omit the `SKILLS:` field instead of only warning.
|
|
601
|
+
- **`audiences`** (string array, default `[]`, max 16 entries, de-duplicated) — extra audience tokens to broaden which skills are considered in scope for this project, in addition to the active runner's own audience. Each entry must be a lowercase domain token matching `^[a-z0-9]+(?:[._-][a-z0-9]+)*$`; the reserved value `swarm-plugin` and any `runner:*` prefix are rejected.
|
|
602
|
+
|
|
602
603
|
**Skill routing file format** (`.opencode/skill-routing.yaml`):
|
|
603
604
|
|
|
604
605
|
```yaml
|
|
@@ -695,9 +696,9 @@ Every candidate passes a 3-gate pipeline before entering quarantine:
|
|
|
695
696
|
| Key | Type | Default | Description |
|
|
696
697
|
|-----|------|---------|-------------|
|
|
697
698
|
| `context_budget.enabled` | boolean | `true` | Enable or disable the context budget guard entirely |
|
|
698
|
-
| `context_budget.max_injection_tokens` | number | `4000` |
|
|
699
|
-
| `context_budget.warn_threshold` | number | `0.7` | Ratio (0.0-1.0) of `
|
|
700
|
-
| `context_budget.critical_threshold` | number | `0.9` | Ratio (0.0-1.0) of `
|
|
699
|
+
| `context_budget.max_injection_tokens` | number | `4000` | Separate per-turn cap on system-enhancer injection. It is NOT the guard's budget — the guard measures total conversation tokens against `model_limits`, not this value |
|
|
700
|
+
| `context_budget.warn_threshold` | number | `0.7` | Ratio (0.0-1.0) of the model context window (`model_limits`, default `128000`) at which total conversation tokens trigger a warning advisory |
|
|
701
|
+
| `context_budget.critical_threshold` | number | `0.9` | Ratio (0.0-1.0) of the model context window (`model_limits`, default `128000`) at which total conversation tokens trigger a critical alert with handoff recommendation |
|
|
701
702
|
| `context_budget.enforce` | boolean | `true` | When true, enforces budget limits and may trigger handoffs |
|
|
702
703
|
| `context_budget.prune_target` | number | `0.7` | Ratio (0.0-1.0) of context to preserve when pruning occurs |
|
|
703
704
|
| `context_budget.preserve_last_n_turns` | number | `4` | Number of recent turns to preserve when pruning |
|
|
@@ -847,7 +848,7 @@ Swarm uses file locking to protect shared state files from concurrent write corr
|
|
|
847
848
|
|
|
848
849
|
### Locking Implementation
|
|
849
850
|
|
|
850
|
-
- **Library**: `proper-lockfile` with
|
|
851
|
+
- **Library**: `proper-lockfile` with automatic retries (F-09): 5 retries with exponential backoff (10ms→500ms, factor 2); a held lock is treated as stale after `LOCK_TIMEOUT_MS` (5 minutes)
|
|
851
852
|
- **Scope**: Each tool acquires an exclusive lock on the target file before writing
|
|
852
853
|
- **Agents**: Lock is tagged with the current agent name and task context for diagnostics
|
|
853
854
|
|
|
@@ -1114,6 +1115,7 @@ Control how tool outputs are summarized for LLM context.
|
|
|
1114
1115
|
| `/swarm issue <issue-url\|owner/repo#N\|N> [--plan] [--trace] [--no-repro]` | Ingest a GitHub issue for localization and resolution |
|
|
1115
1116
|
| `/swarm pr-review <pr-url\|owner/repo#N\|N> [--council] [instructions...]` | Structured deep PR review with parallel lanes, reviewer confirmation, and critic challenge |
|
|
1116
1117
|
| `/swarm pr-feedback [<pr-url\|owner/repo#N\|N>] [instructions...]` | Ingest and close known PR feedback (review comments, CI failures, conflicts) without a fresh review |
|
|
1118
|
+
| `/swarm ci-monitor <pr-url\|owner/repo#N\|N>` | Drive an already-reviewed, approved PR to green and merged (monitor CI, fix, merge; max 5 fix cycles) |
|
|
1117
1119
|
| `/swarm pr subscribe <pr-url\|owner/repo#N\|N>` | Subscribe current session to PR monitoring (session-scoped); requires `pr_monitor.enabled: true` |
|
|
1118
1120
|
| `/swarm pr unsubscribe <pr-url\|owner/repo#N\|N>` | Remove session's subscription to a PR |
|
|
1119
1121
|
| `/swarm pr status` | List active PR subscriptions for current session with relative timestamps (the `bunx opencode-swarm run pr status` CLI has no session context, so it lists subscriptions across all sessions) |
|
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Agent prompt template
|
|
2
|
+
* Agent prompt template helpers.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* a `ProjectContext` resolved at session-init time
|
|
6
|
-
*
|
|
7
|
-
* `
|
|
8
|
-
* leaks
|
|
4
|
+
* `{{KEY}}` placeholders in agent prompt strings are substituted with values
|
|
5
|
+
* from a `ProjectContext` resolved at session-init time by the hand-rolled
|
|
6
|
+
* `.replace()` chains in `src/agents/index.ts` (Chain B) and
|
|
7
|
+
* `src/agents/architect.ts` (Chain A). `assertNoUnresolvedPlaceholders` is the
|
|
8
|
+
* post-substitution safety net that guarantees a typo never leaks a raw
|
|
9
|
+
* `{{KEY}}` to the model — it runs over each agent's FINAL prompt inside the
|
|
10
|
+
* `createSwarmAgents` loop (`src/agents/index.ts`), after every substitution
|
|
11
|
+
* chain has run, before the agents are returned.
|
|
9
12
|
*
|
|
10
|
-
*
|
|
11
|
-
* `
|
|
12
|
-
*
|
|
13
|
-
*
|
|
13
|
+
* Invariant 1 (fail-open): the assertion itself throws (unit tests depend on
|
|
14
|
+
* it), but its production call site in `createSwarmAgents` wraps it in a
|
|
15
|
+
* try/catch that downgrades a leftover placeholder to a deferred warning and
|
|
16
|
+
* registers the agent anyway — a user-authored custom prompt may legitimately
|
|
17
|
+
* contain a literal `{{UPPER_KEY}}` in prose, and plugin init must never abort.
|
|
18
|
+
* Built-in-prompt regressions stay caught in CI by a test that drains the
|
|
19
|
+
* warning buffer after `getAgentConfigs()` over the default prompts.
|
|
20
|
+
*
|
|
21
|
+
* Phase 4b of language-agnostic plugin work.
|
|
14
22
|
*/
|
|
15
23
|
/**
|
|
16
24
|
* Variables available for substitution into agent prompts. Every prompt's
|
|
17
|
-
* `{{KEY}}` placeholders must be a key of this interface
|
|
18
|
-
*
|
|
19
|
-
* `buildProjectContext` in `src/index.ts`.
|
|
25
|
+
* `{{KEY}}` placeholders must be a key of this interface. New variables go
|
|
26
|
+
* here AND in `buildProjectContext` in `src/index.ts`.
|
|
20
27
|
*/
|
|
21
28
|
export interface ProjectContext {
|
|
22
29
|
PROJECT_LANGUAGE: string;
|
|
@@ -68,15 +75,28 @@ export declare function emptyProjectContext(): ProjectContext;
|
|
|
68
75
|
*/
|
|
69
76
|
export declare function escapeForTemplate(s: string): string;
|
|
70
77
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
78
|
+
* Post-substitution safety net for the hand-rolled `.replace()` chains that
|
|
79
|
+
* assemble each agent's FINAL system prompt (Chain A in
|
|
80
|
+
* `src/agents/architect.ts` and Chain B in `src/agents/index.ts`). Neither
|
|
81
|
+
* chain validated for leftover placeholders, so a renamed, mistyped, or
|
|
82
|
+
* newly-added `{{KEY}}` could leak raw template text straight to the model
|
|
83
|
+
* with no error. This asserts — over the fully-substituted prompt — that no
|
|
84
|
+
* `{{KEY}}` survived, applied at the reachable production call site (see
|
|
85
|
+
* `src/agents/index.ts`, immediately before `getAgentConfigs`).
|
|
86
|
+
*
|
|
87
|
+
* The scan uses the character class `[A-Z_]+`. It MUST NOT be broadened to
|
|
88
|
+
* `[^}]+`, `.*?`, or similar: `src/agents/architect.ts` contains a literal
|
|
89
|
+
* `` `{{...}}` `` in instructional prose (teaching the architect what an
|
|
90
|
+
* unresolved field looks like). The dots in `...` are not in `[A-Z_]`, so this
|
|
91
|
+
* guard never matches that prose. A broader class WOULD match it and
|
|
92
|
+
* false-throw during agent init. The trailing `g` flag only enumerates every
|
|
93
|
+
* offender for the error message; it does not widen what counts as a
|
|
94
|
+
* placeholder.
|
|
73
95
|
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* should pre-compute a string variable in `buildProjectContext` and
|
|
77
|
-
* substitute it as a single placeholder.
|
|
96
|
+
* @throws if any `{{KEY}}` placeholder remains, naming the offending key(s)
|
|
97
|
+
* and the agent whose prompt they were found in.
|
|
78
98
|
*/
|
|
79
|
-
export declare function
|
|
99
|
+
export declare function assertNoUnresolvedPlaceholders(prompt: string, agentName: string): void;
|
|
80
100
|
/**
|
|
81
101
|
* Convert an array of constraint strings into a bulleted block ready for
|
|
82
102
|
* inclusion in an agent prompt via `{{CODER_CONSTRAINTS}}` etc.
|
|
@@ -14,20 +14,20 @@ import {
|
|
|
14
14
|
runCuratorInit,
|
|
15
15
|
runCuratorPhase,
|
|
16
16
|
writeCuratorSummary
|
|
17
|
-
} from "./index-
|
|
17
|
+
} from "./index-typ408f4.js";
|
|
18
18
|
import"./index-yfedche9.js";
|
|
19
19
|
import"./index-c8s9a3zh.js";
|
|
20
20
|
import"./index-9bsmzfk3.js";
|
|
21
21
|
import"./index-a45jq4b7.js";
|
|
22
|
-
import"./index-
|
|
22
|
+
import"./index-yrrqs4b0.js";
|
|
23
23
|
import"./index-scww5b77.js";
|
|
24
24
|
import"./index-ga4ta3cr.js";
|
|
25
25
|
import"./index-80jkseqw.js";
|
|
26
|
-
import"./index-
|
|
27
|
-
import"./index-
|
|
28
|
-
import"./index-
|
|
29
|
-
import"./index-
|
|
30
|
-
import"./index-
|
|
26
|
+
import"./index-x12hvfpf.js";
|
|
27
|
+
import"./index-n18yy0z1.js";
|
|
28
|
+
import"./index-6f6y2rbp.js";
|
|
29
|
+
import"./index-8f2270hc.js";
|
|
30
|
+
import"./index-rk6qhyng.js";
|
|
31
31
|
import"./index-bfwt3abw.js";
|
|
32
32
|
import"./index-g40r5d08.js";
|
|
33
33
|
import"./index-vxv732ex.js";
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
createCuratorLLMDelegate
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-typ408f4.js";
|
|
5
5
|
import"./index-yfedche9.js";
|
|
6
6
|
import"./index-c8s9a3zh.js";
|
|
7
7
|
import"./index-9bsmzfk3.js";
|
|
8
8
|
import"./index-a45jq4b7.js";
|
|
9
|
-
import"./index-
|
|
9
|
+
import"./index-yrrqs4b0.js";
|
|
10
10
|
import"./index-scww5b77.js";
|
|
11
11
|
import"./index-ga4ta3cr.js";
|
|
12
12
|
import"./index-80jkseqw.js";
|
|
13
|
-
import"./index-
|
|
14
|
-
import"./index-
|
|
15
|
-
import"./index-
|
|
16
|
-
import"./index-
|
|
17
|
-
import"./index-
|
|
13
|
+
import"./index-x12hvfpf.js";
|
|
14
|
+
import"./index-n18yy0z1.js";
|
|
15
|
+
import"./index-6f6y2rbp.js";
|
|
16
|
+
import"./index-8f2270hc.js";
|
|
17
|
+
import"./index-rk6qhyng.js";
|
|
18
18
|
import"./index-bfwt3abw.js";
|
|
19
19
|
import"./index-g40r5d08.js";
|
|
20
20
|
import"./index-vxv732ex.js";
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
handleGuardrailExplain
|
|
4
|
-
} from "./index-
|
|
5
|
-
import"./index-
|
|
4
|
+
} from "./index-m9m7p49w.js";
|
|
5
|
+
import"./index-typ408f4.js";
|
|
6
6
|
import"./index-yfedche9.js";
|
|
7
7
|
import"./index-c8s9a3zh.js";
|
|
8
8
|
import"./index-9bsmzfk3.js";
|
|
9
9
|
import"./index-a45jq4b7.js";
|
|
10
|
-
import"./index-
|
|
10
|
+
import"./index-yrrqs4b0.js";
|
|
11
11
|
import"./index-scww5b77.js";
|
|
12
12
|
import"./index-ga4ta3cr.js";
|
|
13
13
|
import"./index-80jkseqw.js";
|
|
14
|
-
import"./index-
|
|
15
|
-
import"./index-
|
|
16
|
-
import"./index-
|
|
17
|
-
import"./index-
|
|
18
|
-
import"./index-
|
|
14
|
+
import"./index-x12hvfpf.js";
|
|
15
|
+
import"./index-n18yy0z1.js";
|
|
16
|
+
import"./index-6f6y2rbp.js";
|
|
17
|
+
import"./index-8f2270hc.js";
|
|
18
|
+
import"./index-rk6qhyng.js";
|
|
19
19
|
import"./index-bfwt3abw.js";
|
|
20
20
|
import"./index-g40r5d08.js";
|
|
21
21
|
import"./index-vxv732ex.js";
|
|
@@ -6,20 +6,20 @@ import {
|
|
|
6
6
|
isHiveEligible,
|
|
7
7
|
promoteFromSwarm,
|
|
8
8
|
promoteToHive
|
|
9
|
-
} from "./index-
|
|
9
|
+
} from "./index-typ408f4.js";
|
|
10
10
|
import"./index-yfedche9.js";
|
|
11
11
|
import"./index-c8s9a3zh.js";
|
|
12
12
|
import"./index-9bsmzfk3.js";
|
|
13
13
|
import"./index-a45jq4b7.js";
|
|
14
|
-
import"./index-
|
|
14
|
+
import"./index-yrrqs4b0.js";
|
|
15
15
|
import"./index-scww5b77.js";
|
|
16
16
|
import"./index-ga4ta3cr.js";
|
|
17
17
|
import"./index-80jkseqw.js";
|
|
18
|
-
import"./index-
|
|
19
|
-
import"./index-
|
|
20
|
-
import"./index-
|
|
21
|
-
import"./index-
|
|
22
|
-
import"./index-
|
|
18
|
+
import"./index-x12hvfpf.js";
|
|
19
|
+
import"./index-n18yy0z1.js";
|
|
20
|
+
import"./index-6f6y2rbp.js";
|
|
21
|
+
import"./index-8f2270hc.js";
|
|
22
|
+
import"./index-rk6qhyng.js";
|
|
23
23
|
import"./index-bfwt3abw.js";
|
|
24
24
|
import"./index-g40r5d08.js";
|
|
25
25
|
import"./index-vxv732ex.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
handleGuardrailExplain
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-m9m7p49w.js";
|
|
5
5
|
import {
|
|
6
6
|
handleGuardrailLog
|
|
7
7
|
} from "./index-7jmrbp68.js";
|
|
@@ -81,7 +81,7 @@ import {
|
|
|
81
81
|
handleWriteRetroCommand,
|
|
82
82
|
normalizeSwarmCommandInput,
|
|
83
83
|
resolveCommand
|
|
84
|
-
} from "./index-
|
|
84
|
+
} from "./index-typ408f4.js";
|
|
85
85
|
import"./index-yfedche9.js";
|
|
86
86
|
import"./index-c8s9a3zh.js";
|
|
87
87
|
import"./index-9bsmzfk3.js";
|
|
@@ -90,15 +90,15 @@ import {
|
|
|
90
90
|
ORCHESTRATOR_NAME,
|
|
91
91
|
stripKnownSwarmPrefix
|
|
92
92
|
} from "./index-a45jq4b7.js";
|
|
93
|
-
import"./index-
|
|
93
|
+
import"./index-yrrqs4b0.js";
|
|
94
94
|
import"./index-scww5b77.js";
|
|
95
95
|
import"./index-ga4ta3cr.js";
|
|
96
96
|
import"./index-80jkseqw.js";
|
|
97
|
-
import"./index-
|
|
98
|
-
import"./index-
|
|
99
|
-
import"./index-
|
|
100
|
-
import"./index-
|
|
101
|
-
import"./index-
|
|
97
|
+
import"./index-x12hvfpf.js";
|
|
98
|
+
import"./index-n18yy0z1.js";
|
|
99
|
+
import"./index-6f6y2rbp.js";
|
|
100
|
+
import"./index-8f2270hc.js";
|
|
101
|
+
import"./index-rk6qhyng.js";
|
|
102
102
|
import"./index-bfwt3abw.js";
|
|
103
103
|
import"./index-g40r5d08.js";
|
|
104
104
|
import"./index-vxv732ex.js";
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
countEntryViolationsInWindow,
|
|
5
5
|
readKnowledgeEvents,
|
|
6
6
|
recordKnowledgeEvent
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-8f2270hc.js";
|
|
8
8
|
import {
|
|
9
9
|
jaccardBigram,
|
|
10
10
|
readKnowledge,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
resolveSwarmKnowledgePath,
|
|
13
13
|
transactKnowledge,
|
|
14
14
|
wordBigrams
|
|
15
|
-
} from "./index-
|
|
15
|
+
} from "./index-rk6qhyng.js";
|
|
16
16
|
import {
|
|
17
17
|
isActiveStatus
|
|
18
18
|
} from "./index-bfwt3abw.js";
|
|
@@ -188,7 +188,7 @@ async function maybeQuarantineOnContradiction(directory, entryId, threshold, win
|
|
|
188
188
|
alreadyInactive: true
|
|
189
189
|
};
|
|
190
190
|
}
|
|
191
|
-
const { quarantineEntry } = await import("./knowledge-validator-
|
|
191
|
+
const { quarantineEntry } = await import("./knowledge-validator-t9sym59g.js");
|
|
192
192
|
await quarantineEntry(directory, entryId, `repeat_contradiction: ${count} contradicted events in ${windowDays}d`, "auto");
|
|
193
193
|
return { quarantined: true, entryId, contradictionsInWindow: count };
|
|
194
194
|
} catch {
|
|
@@ -594,7 +594,7 @@ async function applyKnowledgeVerdictFeedback(directory, options) {
|
|
|
594
594
|
deltas.push({ id, delta });
|
|
595
595
|
}
|
|
596
596
|
if (deltas.length > 0) {
|
|
597
|
-
const { bumpKnowledgeConfidenceBatch } = await import("./knowledge-store-
|
|
597
|
+
const { bumpKnowledgeConfidenceBatch } = await import("./knowledge-store-9babt8rd.js");
|
|
598
598
|
await bumpKnowledgeConfidenceBatch(directory, deltas, options?.floorOptions);
|
|
599
599
|
}
|
|
600
600
|
return {
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
resolveSwarmKnowledgePath,
|
|
7
7
|
resolveSwarmRejectedPath,
|
|
8
8
|
transactKnowledge
|
|
9
|
-
} from "./index-
|
|
9
|
+
} from "./index-rk6qhyng.js";
|
|
10
10
|
import {
|
|
11
11
|
resolveKnowledgeStoreDir
|
|
12
12
|
} from "./index-g40r5d08.js";
|
|
@@ -75,6 +75,25 @@ var INJECTION_PATTERNS = [
|
|
|
75
75
|
/\bconstructor\[/,
|
|
76
76
|
/\.prototype\[/
|
|
77
77
|
];
|
|
78
|
+
function scanContentSafety(text) {
|
|
79
|
+
if (typeof text !== "string" || text.length === 0)
|
|
80
|
+
return null;
|
|
81
|
+
const normalized = text.normalize("NFKC").replace(INVISIBLE_FORMAT_CHARS, " ").replace(/\s+/g, " ").toLowerCase();
|
|
82
|
+
for (const pattern of DANGEROUS_COMMAND_ERROR_PATTERNS) {
|
|
83
|
+
if (pattern.test(normalized))
|
|
84
|
+
return "dangerous command pattern detected";
|
|
85
|
+
}
|
|
86
|
+
for (const pattern of SECURITY_DEGRADING_PATTERNS) {
|
|
87
|
+
if (pattern.test(normalized)) {
|
|
88
|
+
return "security-degrading instruction detected";
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
for (const pattern of INJECTION_PATTERNS) {
|
|
92
|
+
if (pattern.test(text))
|
|
93
|
+
return "injection pattern detected";
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
78
97
|
var VALID_CATEGORIES = new Set([
|
|
79
98
|
"process",
|
|
80
99
|
"architecture",
|
|
@@ -412,6 +431,11 @@ function validateActionableFields(fields) {
|
|
|
412
431
|
errors.push(`${name} contains invalid string`);
|
|
413
432
|
return;
|
|
414
433
|
}
|
|
434
|
+
const unsafe = scanContentSafety(item);
|
|
435
|
+
if (unsafe) {
|
|
436
|
+
errors.push(`${name} contains unsafe content: ${unsafe}`);
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
415
439
|
}
|
|
416
440
|
}
|
|
417
441
|
function checkNameList(name, list) {
|
|
@@ -758,4 +782,4 @@ var _internals = {
|
|
|
758
782
|
hasSignificantOverlap
|
|
759
783
|
};
|
|
760
784
|
|
|
761
|
-
export { DANGEROUS_COMMAND_ERROR_PATTERNS, DANGEROUS_COMMAND_WARNING_PATTERNS, DANGEROUS_COMMAND_PATTERNS, SECURITY_DEGRADING_PATTERNS, INVISIBLE_FORMAT_CHARS, INJECTION_PATTERNS, validateLesson, ACTIONABLE_STRING_MAX, ACTIONABLE_LIST_MAX, RETIRED_SKILL_HISTORY_MAX, ALLOWED_SKILL_PATH_PREFIXES, validateSkillPath, validateSkillCandidatePath, validateActionableFields, validateActionability, resolveUnactionablePath, appendUnactionable, auditEntryHealth, quarantineEntry, restoreEntry, unarchiveEntry, _internals };
|
|
785
|
+
export { DANGEROUS_COMMAND_ERROR_PATTERNS, DANGEROUS_COMMAND_WARNING_PATTERNS, DANGEROUS_COMMAND_PATTERNS, SECURITY_DEGRADING_PATTERNS, INVISIBLE_FORMAT_CHARS, INJECTION_PATTERNS, scanContentSafety, validateLesson, ACTIONABLE_STRING_MAX, ACTIONABLE_LIST_MAX, RETIRED_SKILL_HISTORY_MAX, ALLOWED_SKILL_PATH_PREFIXES, validateSkillPath, validateSkillCandidatePath, validateActionableFields, validateActionability, resolveUnactionablePath, appendUnactionable, auditEntryHealth, quarantineEntry, restoreEntry, unarchiveEntry, _internals };
|
|
@@ -595,7 +595,7 @@ async function applyConfidenceFloorAction(directory, touched, options) {
|
|
|
595
595
|
const recovered = touched.filter((e) => e.confidence > CONFIDENCE_FLOOR + FLOOR_EPSILON && e.confidence_floor_demoted);
|
|
596
596
|
if (atFloor.length === 0 && recovered.length === 0)
|
|
597
597
|
return;
|
|
598
|
-
const { readKnowledgeCounterRollups, effectiveRetrievalOutcomes } = await import("./knowledge-events-
|
|
598
|
+
const { readKnowledgeCounterRollups, effectiveRetrievalOutcomes } = await import("./knowledge-events-m304swh6.js");
|
|
599
599
|
const rollups = await readKnowledgeCounterRollups(directory);
|
|
600
600
|
const flagIds = new Set;
|
|
601
601
|
for (const e of atFloor) {
|
|
@@ -662,7 +662,7 @@ async function applyConfidenceFloorAction(directory, touched, options) {
|
|
|
662
662
|
});
|
|
663
663
|
}
|
|
664
664
|
if (action === "quarantine" && toQuarantine.length > 0) {
|
|
665
|
-
const { quarantineEntry } = await import("./knowledge-validator-
|
|
665
|
+
const { quarantineEntry } = await import("./knowledge-validator-t9sym59g.js");
|
|
666
666
|
for (const { id } of toQuarantine) {
|
|
667
667
|
await quarantineEntry(directory, id, "confidence_floor_negative_outcome", "auto").catch((err) => {
|
|
668
668
|
log("[knowledge-store] confidence-floor quarantine failed (best-effort):", err instanceof Error ? err.message : String(err));
|