opencode-swarm 6.33.1 → 6.33.2
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 +59 -7
- package/dist/cli/index.js +73 -10
- package/dist/config/evidence-schema.d.ts +79 -0
- package/dist/config/schema.d.ts +6 -0
- package/dist/evidence/manager.d.ts +8 -4
- package/dist/hooks/delegation-gate.getEvidenceTaskId.test.d.ts +20 -0
- package/dist/index.js +811 -258
- package/dist/model-fallback.adversarial.test.d.ts +22 -0
- package/dist/model-fallback.test.d.ts +12 -0
- package/dist/session/snapshot-writer.d.ts +8 -0
- package/dist/state.d.ts +8 -0
- package/dist/tools/doc-scan.d.ts +38 -0
- package/dist/tools/index.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -252,6 +252,55 @@ For production use, mix providers to maximize quality across writing vs. reviewi
|
|
|
252
252
|
| MiniMax | `minimax-coding-plan/<model>` | `minimax-coding-plan/MiniMax-M2.5` |
|
|
253
253
|
| Kimi | `kimi-for-coding/<model>` | `kimi-for-coding/k2p5` |
|
|
254
254
|
|
|
255
|
+
### Model Fallback (v6.33)
|
|
256
|
+
|
|
257
|
+
When a transient model error occurs (rate limit, 429, 503, timeout, overloaded, model not found), Swarm can automatically switch to a fallback model.
|
|
258
|
+
|
|
259
|
+
**Configuration:**
|
|
260
|
+
|
|
261
|
+
```json
|
|
262
|
+
{
|
|
263
|
+
"agents": {
|
|
264
|
+
"coder": {
|
|
265
|
+
"model": "anthropic/claude-opus-4-6",
|
|
266
|
+
"fallback_models": [
|
|
267
|
+
"anthropic/claude-sonnet-4-5",
|
|
268
|
+
"opencode/gpt-5-nano"
|
|
269
|
+
]
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
- **`fallback_models`** — Optional array of up to 3 fallback model identifiers. When the primary model fails with a transient error, Swarm injects a `MODEL FALLBACK` advisory and the next retry uses the next fallback model in the list.
|
|
276
|
+
- **Advisory injection** — When a transient error is detected, a `MODEL FALLBACK` advisory is injected into the architect's context: *"Transient model error detected (attempt N). The agent model may be rate-limited, overloaded, or temporarily unavailable. Consider retrying with a fallback model or waiting before retrying."*
|
|
277
|
+
- **Exhaustion guard** — After exhausting all fallbacks (`modelFallbackExhausted = true`), further transient errors do not spam additional advisories.
|
|
278
|
+
- **Reset on success** — Both `model_fallback_index` and `modelFallbackExhausted` reset to 0/false on the next successful tool execution.
|
|
279
|
+
|
|
280
|
+
### Bounded Coder Revisions (v6.33)
|
|
281
|
+
|
|
282
|
+
When a task requires multiple coder attempts (e.g., reviewer rejections), Swarm tracks how many times the coder has been re-delegated for the same task and warns when limits are approached.
|
|
283
|
+
|
|
284
|
+
**Configuration:**
|
|
285
|
+
|
|
286
|
+
```json
|
|
287
|
+
{
|
|
288
|
+
"guardrails": {
|
|
289
|
+
"max_coder_revisions": 5
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
| Parameter | Type | Default | Description |
|
|
295
|
+
|-----------|------|---------|-------------|
|
|
296
|
+
| `max_coder_revisions` | integer | `5` | Maximum coder re-delegations per task before advisory warning (1–20) |
|
|
297
|
+
|
|
298
|
+
**Behavior:**
|
|
299
|
+
- **`coderRevisions` counter** — Incremented each time the coder delegation completes for the same task (reset on new task)
|
|
300
|
+
- **`revisionLimitHit` flag** — Set when `coderRevisions >= max_coder_revisions`
|
|
301
|
+
- **Advisory injection** — When the limit is hit, a `CODER REVISION LIMIT` advisory is injected: *"Agent has been revised N times (max: M) for task X. Escalate to user or consider a fundamentally different approach."*
|
|
302
|
+
- **Persistence** — Both `coderRevisions` and `revisionLimitHit` are serialized/deserialized in session snapshots
|
|
303
|
+
|
|
255
304
|
## Useful Commands
|
|
256
305
|
|
|
257
306
|
| Command | What It Does |
|
|
@@ -419,7 +468,8 @@ Every completed task writes structured evidence to `.swarm/evidence/`:
|
|
|
419
468
|
| review | Verdict, risk level, specific issues |
|
|
420
469
|
| test | Pass/fail counts, coverage %, failure messages |
|
|
421
470
|
| diff | Files changed, additions/deletions |
|
|
422
|
-
| retrospective | Phase metrics, lessons learned (injected into next phase) |
|
|
471
|
+
| retrospective | Phase metrics, lessons learned, error taxonomy classification (injected into next phase) |
|
|
472
|
+
| secretscan | Secret scan results: findings count, files scanned, skipped files (v6.33) |
|
|
423
473
|
|
|
424
474
|
</details>
|
|
425
475
|
|
|
@@ -659,11 +709,11 @@ Config file location: `~/.config/opencode/opencode-swarm.json` (global) or `.ope
|
|
|
659
709
|
{
|
|
660
710
|
"agents": {
|
|
661
711
|
"architect": { "model": "anthropic/claude-opus-4-6" },
|
|
662
|
-
"coder": { "model": "minimax-coding-plan/MiniMax-M2.5" },
|
|
712
|
+
"coder": { "model": "minimax-coding-plan/MiniMax-M2.5", "fallback_models": ["minimax-coding-plan/MiniMax-M2.1"] },
|
|
663
713
|
"explorer": { "model": "minimax-coding-plan/MiniMax-M2.1" },
|
|
664
714
|
"sme": { "model": "kimi-for-coding/k2p5" },
|
|
665
715
|
"critic": { "model": "zai-coding-plan/glm-5" },
|
|
666
|
-
"reviewer": { "model": "zai-coding-plan/glm-5" },
|
|
716
|
+
"reviewer": { "model": "zai-coding-plan/glm-5", "fallback_models": ["opencode/big-pickle"] },
|
|
667
717
|
"test_engineer": { "model": "minimax-coding-plan/MiniMax-M2.5" },
|
|
668
718
|
"docs": { "model": "zai-coding-plan/glm-4.7-flash" },
|
|
669
719
|
"designer": { "model": "kimi-for-coding/k2p5" }
|
|
@@ -857,14 +907,14 @@ Swarm limits which tools each agent can access based on their role. This prevent
|
|
|
857
907
|
|
|
858
908
|
| Agent | Tools | Count | Rationale |
|
|
859
909
|
|-------|-------|:---:|-----------|
|
|
860
|
-
| **architect** | All
|
|
910
|
+
| **architect** | All 23 tools | 23 | Orchestrator needs full visibility |
|
|
861
911
|
| **reviewer** | diff, imports, lint, pkg_audit, pre_check_batch, secretscan, symbols, complexity_hotspots, retrieve_summary, extract_code_blocks, test_runner | 11 | Security-focused QA |
|
|
862
912
|
| **coder** | diff, imports, lint, symbols, extract_code_blocks, retrieve_summary | 6 | Write-focused, minimal read tools |
|
|
863
913
|
| **test_engineer** | test_runner, diff, symbols, extract_code_blocks, retrieve_summary, imports, complexity_hotspots, pkg_audit | 8 | Testing and verification |
|
|
864
914
|
| **explorer** | complexity_hotspots, detect_domains, extract_code_blocks, gitingest, imports, retrieve_summary, schema_drift, symbols, todo_extract | 9 | Discovery and analysis |
|
|
865
915
|
| **sme** | complexity_hotspots, detect_domains, extract_code_blocks, imports, retrieve_summary, schema_drift, symbols | 7 | Domain expertise research |
|
|
866
916
|
| **critic** | complexity_hotspots, detect_domains, imports, retrieve_summary, symbols | 5 | Plan review, minimal toolset |
|
|
867
|
-
| **docs** | detect_domains, extract_code_blocks, gitingest, imports, retrieve_summary, schema_drift, symbols, todo_extract |
|
|
917
|
+
| **docs** | detect_domains, doc_extract, doc_scan, extract_code_blocks, gitingest, imports, retrieve_summary, schema_drift, symbols, todo_extract | 10 | Documentation synthesis and discovery |
|
|
868
918
|
| **designer** | extract_code_blocks, retrieve_summary, symbols | 3 | UI-focused, minimal toolset |
|
|
869
919
|
|
|
870
920
|
### Configuration
|
|
@@ -924,13 +974,17 @@ The following tools can be assigned to agents via overrides:
|
|
|
924
974
|
| `checkpoint` | Save/restore git checkpoints |
|
|
925
975
|
| `check_gate_status` | Read-only query of task gate status |
|
|
926
976
|
| `complexity_hotspots` | Identify high-risk code areas |
|
|
977
|
+
| `declare_scope` | Pre-declare the file scope for the next coder delegation (architect-only); violations trigger warnings |
|
|
927
978
|
| `detect_domains` | Detect SME domains from text |
|
|
928
979
|
| `diff` | Analyze git diffs and changes |
|
|
980
|
+
| `doc_extract` | Extract actionable constraints from project documentation relevant to current task (Jaccard bigram scoring + dedup) |
|
|
981
|
+
| `doc_scan` | Scan project documentation and build index manifest at `.swarm/doc-manifest.json` (mtime-based caching) |
|
|
929
982
|
| `evidence_check` | Verify task evidence |
|
|
930
983
|
| `extract_code_blocks` | Extract code from markdown |
|
|
931
984
|
| `gitingest` | Ingest external repositories |
|
|
932
985
|
| `imports` | Analyze import relationships |
|
|
933
986
|
| `lint` | Run project linters |
|
|
987
|
+
| `phase_complete` | Enforces phase completion, verifies required agents, logs events, resets state |
|
|
934
988
|
| `pkg_audit` | Security audit of dependencies |
|
|
935
989
|
| `pre_check_batch` | Parallel pre-checks (lint, secrets, SAST, quality) |
|
|
936
990
|
| `retrieve_summary` | Retrieve summarized tool outputs |
|
|
@@ -941,8 +995,6 @@ The following tools can be assigned to agents via overrides:
|
|
|
941
995
|
| `update_task_status` | Mark plan tasks as pending/in_progress/completed/blocked; track phase progress |
|
|
942
996
|
| `todo_extract` | Extract TODO/FIXME comments |
|
|
943
997
|
| `write_retro` | Document phase retrospectives via the phase_complete workflow; capture lessons learned |
|
|
944
|
-
| `phase_complete` | Enforces phase completion, verifies required agents, logs events, resets state |
|
|
945
|
-
| `declare_scope` | Pre-declare the file scope for the next coder delegation (architect-only); violations trigger warnings |
|
|
946
998
|
|
|
947
999
|
---
|
|
948
1000
|
|
package/dist/cli/index.js
CHANGED
|
@@ -13940,7 +13940,7 @@ function deepMerge(base, override) {
|
|
|
13940
13940
|
var MAX_MERGE_DEPTH = 10;
|
|
13941
13941
|
|
|
13942
13942
|
// src/config/evidence-schema.ts
|
|
13943
|
-
var EVIDENCE_MAX_JSON_BYTES, EVIDENCE_MAX_PATCH_BYTES, EVIDENCE_MAX_TASK_BYTES, EvidenceTypeSchema, EvidenceVerdictSchema, BaseEvidenceSchema, ReviewEvidenceSchema, TestEvidenceSchema, DiffEvidenceSchema, ApprovalEvidenceSchema, NoteEvidenceSchema, RetrospectiveEvidenceSchema, SyntaxEvidenceSchema, PlaceholderEvidenceSchema, SastEvidenceSchema, SbomEvidenceSchema, BuildEvidenceSchema, QualityBudgetEvidenceSchema, EvidenceSchema, EvidenceBundleSchema;
|
|
13943
|
+
var EVIDENCE_MAX_JSON_BYTES, EVIDENCE_MAX_PATCH_BYTES, EVIDENCE_MAX_TASK_BYTES, EvidenceTypeSchema, EvidenceVerdictSchema, BaseEvidenceSchema, ReviewEvidenceSchema, TestEvidenceSchema, DiffEvidenceSchema, ApprovalEvidenceSchema, NoteEvidenceSchema, RetrospectiveEvidenceSchema, SyntaxEvidenceSchema, PlaceholderEvidenceSchema, SastEvidenceSchema, SbomEvidenceSchema, BuildEvidenceSchema, QualityBudgetEvidenceSchema, SecretscanEvidenceSchema, EvidenceSchema, EvidenceBundleSchema;
|
|
13944
13944
|
var init_evidence_schema = __esm(() => {
|
|
13945
13945
|
init_zod();
|
|
13946
13946
|
EVIDENCE_MAX_JSON_BYTES = 500 * 1024;
|
|
@@ -13958,7 +13958,8 @@ var init_evidence_schema = __esm(() => {
|
|
|
13958
13958
|
"sast",
|
|
13959
13959
|
"sbom",
|
|
13960
13960
|
"build",
|
|
13961
|
-
"quality_budget"
|
|
13961
|
+
"quality_budget",
|
|
13962
|
+
"secretscan"
|
|
13962
13963
|
]);
|
|
13963
13964
|
EvidenceVerdictSchema = exports_external.enum([
|
|
13964
13965
|
"pass",
|
|
@@ -14039,7 +14040,14 @@ var init_evidence_schema = __esm(() => {
|
|
|
14039
14040
|
approach: exports_external.string().min(1),
|
|
14040
14041
|
result: exports_external.enum(["success", "failure", "partial"]),
|
|
14041
14042
|
abandoned_reason: exports_external.string().optional()
|
|
14042
|
-
})).max(10).default([])
|
|
14043
|
+
})).max(10).default([]),
|
|
14044
|
+
error_taxonomy: exports_external.array(exports_external.enum([
|
|
14045
|
+
"planning_error",
|
|
14046
|
+
"interface_mismatch",
|
|
14047
|
+
"logic_error",
|
|
14048
|
+
"scope_creep",
|
|
14049
|
+
"gate_evasion"
|
|
14050
|
+
])).default([])
|
|
14043
14051
|
});
|
|
14044
14052
|
SyntaxEvidenceSchema = BaseEvidenceSchema.extend({
|
|
14045
14053
|
type: exports_external.literal("syntax"),
|
|
@@ -14150,6 +14158,13 @@ var init_evidence_schema = __esm(() => {
|
|
|
14150
14158
|
})).default([]),
|
|
14151
14159
|
files_analyzed: exports_external.array(exports_external.string())
|
|
14152
14160
|
});
|
|
14161
|
+
SecretscanEvidenceSchema = BaseEvidenceSchema.extend({
|
|
14162
|
+
type: exports_external.literal("secretscan"),
|
|
14163
|
+
findings_count: exports_external.number().int().min(0).default(0),
|
|
14164
|
+
scan_directory: exports_external.string().optional(),
|
|
14165
|
+
files_scanned: exports_external.number().int().min(0).default(0),
|
|
14166
|
+
skipped_files: exports_external.number().int().min(0).default(0)
|
|
14167
|
+
});
|
|
14153
14168
|
EvidenceSchema = exports_external.discriminatedUnion("type", [
|
|
14154
14169
|
ReviewEvidenceSchema,
|
|
14155
14170
|
TestEvidenceSchema,
|
|
@@ -14162,7 +14177,8 @@ var init_evidence_schema = __esm(() => {
|
|
|
14162
14177
|
SastEvidenceSchema,
|
|
14163
14178
|
SbomEvidenceSchema,
|
|
14164
14179
|
BuildEvidenceSchema,
|
|
14165
|
-
QualityBudgetEvidenceSchema
|
|
14180
|
+
QualityBudgetEvidenceSchema,
|
|
14181
|
+
SecretscanEvidenceSchema
|
|
14166
14182
|
]);
|
|
14167
14183
|
EvidenceBundleSchema = exports_external.object({
|
|
14168
14184
|
schema_version: exports_external.literal("1.0.0"),
|
|
@@ -14517,11 +14533,12 @@ var init_manager = __esm(() => {
|
|
|
14517
14533
|
"sast",
|
|
14518
14534
|
"sbom",
|
|
14519
14535
|
"build",
|
|
14520
|
-
"quality_budget"
|
|
14536
|
+
"quality_budget",
|
|
14537
|
+
"secretscan"
|
|
14521
14538
|
];
|
|
14522
14539
|
TASK_ID_REGEX = /^\d+\.\d+(\.\d+)*$/;
|
|
14523
14540
|
RETRO_TASK_ID_REGEX = /^retro-\d+$/;
|
|
14524
|
-
INTERNAL_TOOL_ID_REGEX = /^(?:sast_scan|quality_budget|syntax_check|placeholder_scan|sbom_generate|build)$/;
|
|
14541
|
+
INTERNAL_TOOL_ID_REGEX = /^(?:sast_scan|quality_budget|syntax_check|placeholder_scan|sbom_generate|build|secretscan)$/;
|
|
14525
14542
|
LEGACY_TASK_COMPLEXITY_MAP = {
|
|
14526
14543
|
low: "simple",
|
|
14527
14544
|
medium: "moderate",
|
|
@@ -17723,7 +17740,8 @@ for (const [agentName, tools] of Object.entries(AGENT_TOOL_MAP)) {
|
|
|
17723
17740
|
var AgentOverrideConfigSchema = exports_external.object({
|
|
17724
17741
|
model: exports_external.string().optional(),
|
|
17725
17742
|
temperature: exports_external.number().min(0).max(2).optional(),
|
|
17726
|
-
disabled: exports_external.boolean().optional()
|
|
17743
|
+
disabled: exports_external.boolean().optional(),
|
|
17744
|
+
fallback_models: exports_external.array(exports_external.string()).max(3).optional()
|
|
17727
17745
|
});
|
|
17728
17746
|
var SwarmConfigSchema = exports_external.object({
|
|
17729
17747
|
name: exports_external.string().optional(),
|
|
@@ -18064,6 +18082,7 @@ var GuardrailsConfigSchema = exports_external.object({
|
|
|
18064
18082
|
warning_threshold: exports_external.number().min(0.1).max(0.9).default(0.75),
|
|
18065
18083
|
idle_timeout_minutes: exports_external.number().min(5).max(240).default(60),
|
|
18066
18084
|
no_op_warning_threshold: exports_external.number().min(1).max(100).default(15),
|
|
18085
|
+
max_coder_revisions: exports_external.number().int().min(1).max(20).default(5),
|
|
18067
18086
|
qa_gates: exports_external.object({
|
|
18068
18087
|
required_tools: exports_external.array(exports_external.string().min(1)).default([
|
|
18069
18088
|
"diff",
|
|
@@ -33996,7 +34015,11 @@ function serializeAgentSession(s) {
|
|
|
33996
34015
|
taskWorkflowStates: Object.fromEntries(s.taskWorkflowStates ?? new Map),
|
|
33997
34016
|
...s.scopeViolationDetected !== undefined && {
|
|
33998
34017
|
scopeViolationDetected: s.scopeViolationDetected
|
|
33999
|
-
}
|
|
34018
|
+
},
|
|
34019
|
+
model_fallback_index: s.model_fallback_index ?? 0,
|
|
34020
|
+
modelFallbackExhausted: s.modelFallbackExhausted ?? false,
|
|
34021
|
+
coderRevisions: s.coderRevisions ?? 0,
|
|
34022
|
+
revisionLimitHit: s.revisionLimitHit ?? false
|
|
34000
34023
|
};
|
|
34001
34024
|
}
|
|
34002
34025
|
async function writeSnapshot(directory, state) {
|
|
@@ -34020,7 +34043,9 @@ async function writeSnapshot(directory, state) {
|
|
|
34020
34043
|
await Bun.write(tempPath, content);
|
|
34021
34044
|
renameSync4(tempPath, resolvedPath);
|
|
34022
34045
|
} catch (error93) {
|
|
34023
|
-
|
|
34046
|
+
if (process.env.DEBUG_SWARM) {
|
|
34047
|
+
console.warn("[snapshot-writer] write failed:", error93 instanceof Error ? error93.message : String(error93));
|
|
34048
|
+
}
|
|
34024
34049
|
}
|
|
34025
34050
|
}
|
|
34026
34051
|
async function flushPendingSnapshot(directory) {
|
|
@@ -40040,8 +40065,46 @@ async function executeWriteRetro(args, directory) {
|
|
|
40040
40065
|
top_rejection_reasons: args.top_rejection_reasons ?? [],
|
|
40041
40066
|
lessons_learned: (args.lessons_learned ?? []).slice(0, 5),
|
|
40042
40067
|
user_directives: [],
|
|
40043
|
-
approaches_tried: []
|
|
40068
|
+
approaches_tried: [],
|
|
40069
|
+
error_taxonomy: []
|
|
40044
40070
|
};
|
|
40071
|
+
const taxonomy = [];
|
|
40072
|
+
try {
|
|
40073
|
+
for (const taskSuffix of ["1", "2", "3", "4", "5"]) {
|
|
40074
|
+
const phaseTaskId = `${phase}.${taskSuffix}`;
|
|
40075
|
+
const result = await loadEvidence(directory, phaseTaskId);
|
|
40076
|
+
if (result.status !== "found")
|
|
40077
|
+
continue;
|
|
40078
|
+
const bundle = result.bundle;
|
|
40079
|
+
for (const entry of bundle.entries) {
|
|
40080
|
+
const e = entry;
|
|
40081
|
+
if (e.type === "review" && e.verdict === "fail") {
|
|
40082
|
+
const reasonParts = [];
|
|
40083
|
+
if (typeof e.summary === "string")
|
|
40084
|
+
reasonParts.push(e.summary);
|
|
40085
|
+
if (Array.isArray(e.issues)) {
|
|
40086
|
+
for (const iss of e.issues) {
|
|
40087
|
+
if (typeof iss.message === "string")
|
|
40088
|
+
reasonParts.push(iss.message);
|
|
40089
|
+
}
|
|
40090
|
+
}
|
|
40091
|
+
const reason = reasonParts.join(" ");
|
|
40092
|
+
if (/signature|type|contract|interface/i.test(reason)) {
|
|
40093
|
+
taxonomy.push("interface_mismatch");
|
|
40094
|
+
} else {
|
|
40095
|
+
taxonomy.push("logic_error");
|
|
40096
|
+
}
|
|
40097
|
+
} else if (e.type === "test" && e.verdict === "fail") {
|
|
40098
|
+
taxonomy.push("logic_error");
|
|
40099
|
+
} else if (e.agent === "scope_guard" && e.verdict === "fail") {
|
|
40100
|
+
taxonomy.push("scope_creep");
|
|
40101
|
+
} else if (e.agent === "loop_detector" && e.verdict === "fail") {
|
|
40102
|
+
taxonomy.push("gate_evasion");
|
|
40103
|
+
}
|
|
40104
|
+
}
|
|
40105
|
+
}
|
|
40106
|
+
} catch {}
|
|
40107
|
+
retroEntry.error_taxonomy = [...new Set(taxonomy)];
|
|
40045
40108
|
try {
|
|
40046
40109
|
await saveEvidence(directory, taskId, retroEntry);
|
|
40047
40110
|
return JSON.stringify({
|
|
@@ -4,6 +4,7 @@ export declare const EVIDENCE_MAX_PATCH_BYTES: number;
|
|
|
4
4
|
export declare const EVIDENCE_MAX_TASK_BYTES: number;
|
|
5
5
|
export declare const EvidenceTypeSchema: z.ZodEnum<{
|
|
6
6
|
diff: "diff";
|
|
7
|
+
secretscan: "secretscan";
|
|
7
8
|
quality_budget: "quality_budget";
|
|
8
9
|
placeholder: "placeholder";
|
|
9
10
|
test: "test";
|
|
@@ -29,6 +30,7 @@ export declare const BaseEvidenceSchema: z.ZodObject<{
|
|
|
29
30
|
task_id: z.ZodString;
|
|
30
31
|
type: z.ZodEnum<{
|
|
31
32
|
diff: "diff";
|
|
33
|
+
secretscan: "secretscan";
|
|
32
34
|
quality_budget: "quality_budget";
|
|
33
35
|
placeholder: "placeholder";
|
|
34
36
|
test: "test";
|
|
@@ -217,6 +219,13 @@ export declare const RetrospectiveEvidenceSchema: z.ZodObject<{
|
|
|
217
219
|
}>;
|
|
218
220
|
abandoned_reason: z.ZodOptional<z.ZodString>;
|
|
219
221
|
}, z.core.$strip>>>;
|
|
222
|
+
error_taxonomy: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
223
|
+
planning_error: "planning_error";
|
|
224
|
+
interface_mismatch: "interface_mismatch";
|
|
225
|
+
logic_error: "logic_error";
|
|
226
|
+
scope_creep: "scope_creep";
|
|
227
|
+
gate_evasion: "gate_evasion";
|
|
228
|
+
}>>>;
|
|
220
229
|
}, z.core.$strip>;
|
|
221
230
|
export type RetrospectiveEvidence = z.infer<typeof RetrospectiveEvidenceSchema>;
|
|
222
231
|
export declare const SyntaxEvidenceSchema: z.ZodObject<{
|
|
@@ -434,6 +443,26 @@ export declare const QualityBudgetEvidenceSchema: z.ZodObject<{
|
|
|
434
443
|
files_analyzed: z.ZodArray<z.ZodString>;
|
|
435
444
|
}, z.core.$strip>;
|
|
436
445
|
export type QualityBudgetEvidence = z.infer<typeof QualityBudgetEvidenceSchema>;
|
|
446
|
+
export declare const SecretscanEvidenceSchema: z.ZodObject<{
|
|
447
|
+
task_id: z.ZodString;
|
|
448
|
+
timestamp: z.ZodString;
|
|
449
|
+
agent: z.ZodString;
|
|
450
|
+
verdict: z.ZodEnum<{
|
|
451
|
+
pass: "pass";
|
|
452
|
+
fail: "fail";
|
|
453
|
+
approved: "approved";
|
|
454
|
+
rejected: "rejected";
|
|
455
|
+
info: "info";
|
|
456
|
+
}>;
|
|
457
|
+
summary: z.ZodString;
|
|
458
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
459
|
+
type: z.ZodLiteral<"secretscan">;
|
|
460
|
+
findings_count: z.ZodDefault<z.ZodNumber>;
|
|
461
|
+
scan_directory: z.ZodOptional<z.ZodString>;
|
|
462
|
+
files_scanned: z.ZodDefault<z.ZodNumber>;
|
|
463
|
+
skipped_files: z.ZodDefault<z.ZodNumber>;
|
|
464
|
+
}, z.core.$strip>;
|
|
465
|
+
export type SecretscanEvidence = z.infer<typeof SecretscanEvidenceSchema>;
|
|
437
466
|
export declare const EvidenceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
438
467
|
task_id: z.ZodString;
|
|
439
468
|
timestamp: z.ZodString;
|
|
@@ -587,6 +616,13 @@ export declare const EvidenceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
587
616
|
}>;
|
|
588
617
|
abandoned_reason: z.ZodOptional<z.ZodString>;
|
|
589
618
|
}, z.core.$strip>>>;
|
|
619
|
+
error_taxonomy: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
620
|
+
planning_error: "planning_error";
|
|
621
|
+
interface_mismatch: "interface_mismatch";
|
|
622
|
+
logic_error: "logic_error";
|
|
623
|
+
scope_creep: "scope_creep";
|
|
624
|
+
gate_evasion: "gate_evasion";
|
|
625
|
+
}>>>;
|
|
590
626
|
}, z.core.$strip>, z.ZodObject<{
|
|
591
627
|
task_id: z.ZodString;
|
|
592
628
|
timestamp: z.ZodString;
|
|
@@ -790,6 +826,24 @@ export declare const EvidenceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
790
826
|
files: z.ZodArray<z.ZodString>;
|
|
791
827
|
}, z.core.$strip>>>;
|
|
792
828
|
files_analyzed: z.ZodArray<z.ZodString>;
|
|
829
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
830
|
+
task_id: z.ZodString;
|
|
831
|
+
timestamp: z.ZodString;
|
|
832
|
+
agent: z.ZodString;
|
|
833
|
+
verdict: z.ZodEnum<{
|
|
834
|
+
pass: "pass";
|
|
835
|
+
fail: "fail";
|
|
836
|
+
approved: "approved";
|
|
837
|
+
rejected: "rejected";
|
|
838
|
+
info: "info";
|
|
839
|
+
}>;
|
|
840
|
+
summary: z.ZodString;
|
|
841
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
842
|
+
type: z.ZodLiteral<"secretscan">;
|
|
843
|
+
findings_count: z.ZodDefault<z.ZodNumber>;
|
|
844
|
+
scan_directory: z.ZodOptional<z.ZodString>;
|
|
845
|
+
files_scanned: z.ZodDefault<z.ZodNumber>;
|
|
846
|
+
skipped_files: z.ZodDefault<z.ZodNumber>;
|
|
793
847
|
}, z.core.$strip>], "type">;
|
|
794
848
|
export type Evidence = z.infer<typeof EvidenceSchema>;
|
|
795
849
|
export declare const EvidenceBundleSchema: z.ZodObject<{
|
|
@@ -948,6 +1002,13 @@ export declare const EvidenceBundleSchema: z.ZodObject<{
|
|
|
948
1002
|
}>;
|
|
949
1003
|
abandoned_reason: z.ZodOptional<z.ZodString>;
|
|
950
1004
|
}, z.core.$strip>>>;
|
|
1005
|
+
error_taxonomy: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
1006
|
+
planning_error: "planning_error";
|
|
1007
|
+
interface_mismatch: "interface_mismatch";
|
|
1008
|
+
logic_error: "logic_error";
|
|
1009
|
+
scope_creep: "scope_creep";
|
|
1010
|
+
gate_evasion: "gate_evasion";
|
|
1011
|
+
}>>>;
|
|
951
1012
|
}, z.core.$strip>, z.ZodObject<{
|
|
952
1013
|
task_id: z.ZodString;
|
|
953
1014
|
timestamp: z.ZodString;
|
|
@@ -1151,6 +1212,24 @@ export declare const EvidenceBundleSchema: z.ZodObject<{
|
|
|
1151
1212
|
files: z.ZodArray<z.ZodString>;
|
|
1152
1213
|
}, z.core.$strip>>>;
|
|
1153
1214
|
files_analyzed: z.ZodArray<z.ZodString>;
|
|
1215
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1216
|
+
task_id: z.ZodString;
|
|
1217
|
+
timestamp: z.ZodString;
|
|
1218
|
+
agent: z.ZodString;
|
|
1219
|
+
verdict: z.ZodEnum<{
|
|
1220
|
+
pass: "pass";
|
|
1221
|
+
fail: "fail";
|
|
1222
|
+
approved: "approved";
|
|
1223
|
+
rejected: "rejected";
|
|
1224
|
+
info: "info";
|
|
1225
|
+
}>;
|
|
1226
|
+
summary: z.ZodString;
|
|
1227
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
1228
|
+
type: z.ZodLiteral<"secretscan">;
|
|
1229
|
+
findings_count: z.ZodDefault<z.ZodNumber>;
|
|
1230
|
+
scan_directory: z.ZodOptional<z.ZodString>;
|
|
1231
|
+
files_scanned: z.ZodDefault<z.ZodNumber>;
|
|
1232
|
+
skipped_files: z.ZodDefault<z.ZodNumber>;
|
|
1154
1233
|
}, z.core.$strip>], "type">>>;
|
|
1155
1234
|
created_at: z.ZodString;
|
|
1156
1235
|
updated_at: z.ZodString;
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export declare const AgentOverrideConfigSchema: z.ZodObject<{
|
|
|
18
18
|
model: z.ZodOptional<z.ZodString>;
|
|
19
19
|
temperature: z.ZodOptional<z.ZodNumber>;
|
|
20
20
|
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
21
|
+
fallback_models: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
21
22
|
}, z.core.$strip>;
|
|
22
23
|
export type AgentOverrideConfig = z.infer<typeof AgentOverrideConfigSchema>;
|
|
23
24
|
export declare const SwarmConfigSchema: z.ZodObject<{
|
|
@@ -26,6 +27,7 @@ export declare const SwarmConfigSchema: z.ZodObject<{
|
|
|
26
27
|
model: z.ZodOptional<z.ZodString>;
|
|
27
28
|
temperature: z.ZodOptional<z.ZodNumber>;
|
|
28
29
|
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
30
|
+
fallback_models: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
29
31
|
}, z.core.$strip>>>;
|
|
30
32
|
}, z.core.$strip>;
|
|
31
33
|
export type SwarmConfig = z.infer<typeof SwarmConfigSchema>;
|
|
@@ -314,6 +316,7 @@ export declare const GuardrailsConfigSchema: z.ZodObject<{
|
|
|
314
316
|
warning_threshold: z.ZodDefault<z.ZodNumber>;
|
|
315
317
|
idle_timeout_minutes: z.ZodDefault<z.ZodNumber>;
|
|
316
318
|
no_op_warning_threshold: z.ZodDefault<z.ZodNumber>;
|
|
319
|
+
max_coder_revisions: z.ZodDefault<z.ZodNumber>;
|
|
317
320
|
qa_gates: z.ZodOptional<z.ZodObject<{
|
|
318
321
|
required_tools: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
319
322
|
require_reviewer_test_engineer: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -468,6 +471,7 @@ export declare const PluginConfigSchema: z.ZodObject<{
|
|
|
468
471
|
model: z.ZodOptional<z.ZodString>;
|
|
469
472
|
temperature: z.ZodOptional<z.ZodNumber>;
|
|
470
473
|
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
474
|
+
fallback_models: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
471
475
|
}, z.core.$strip>>>;
|
|
472
476
|
swarms: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
473
477
|
name: z.ZodOptional<z.ZodString>;
|
|
@@ -475,6 +479,7 @@ export declare const PluginConfigSchema: z.ZodObject<{
|
|
|
475
479
|
model: z.ZodOptional<z.ZodString>;
|
|
476
480
|
temperature: z.ZodOptional<z.ZodNumber>;
|
|
477
481
|
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
482
|
+
fallback_models: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
478
483
|
}, z.core.$strip>>>;
|
|
479
484
|
}, z.core.$strip>>>;
|
|
480
485
|
max_iterations: z.ZodDefault<z.ZodNumber>;
|
|
@@ -592,6 +597,7 @@ export declare const PluginConfigSchema: z.ZodObject<{
|
|
|
592
597
|
warning_threshold: z.ZodDefault<z.ZodNumber>;
|
|
593
598
|
idle_timeout_minutes: z.ZodDefault<z.ZodNumber>;
|
|
594
599
|
no_op_warning_threshold: z.ZodDefault<z.ZodNumber>;
|
|
600
|
+
max_coder_revisions: z.ZodDefault<z.ZodNumber>;
|
|
595
601
|
qa_gates: z.ZodOptional<z.ZodObject<{
|
|
596
602
|
required_tools: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
597
603
|
require_reviewer_test_engineer: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type BuildEvidence, type Evidence, type EvidenceBundle, type PlaceholderEvidence, type QualityBudgetEvidence, type SastEvidence, type SbomEvidence, type SyntaxEvidence } from '../config/evidence-schema';
|
|
1
|
+
import { type BuildEvidence, type Evidence, type EvidenceBundle, type PlaceholderEvidence, type QualityBudgetEvidence, type SastEvidence, type SbomEvidence, type SecretscanEvidence, type SyntaxEvidence } from '../config/evidence-schema';
|
|
2
2
|
/**
|
|
3
3
|
* Discriminated union returned by loadEvidence.
|
|
4
4
|
* - 'found': file exists and passed Zod schema validation
|
|
@@ -15,9 +15,9 @@ export type LoadEvidenceResult = {
|
|
|
15
15
|
errors: string[];
|
|
16
16
|
};
|
|
17
17
|
/**
|
|
18
|
-
* All valid evidence types (
|
|
18
|
+
* All valid evidence types (13 total)
|
|
19
19
|
*/
|
|
20
|
-
export declare const VALID_EVIDENCE_TYPES: readonly ["review", "test", "diff", "approval", "note", "retrospective", "syntax", "placeholder", "sast", "sbom", "build", "quality_budget"];
|
|
20
|
+
export declare const VALID_EVIDENCE_TYPES: readonly ["review", "test", "diff", "approval", "note", "retrospective", "syntax", "placeholder", "sast", "sbom", "build", "quality_budget", "secretscan"];
|
|
21
21
|
/**
|
|
22
22
|
* Check if a string is a valid evidence type.
|
|
23
23
|
* Returns true if the type is recognized, false otherwise.
|
|
@@ -32,12 +32,16 @@ export declare function isSastEvidence(evidence: Evidence): evidence is SastEvid
|
|
|
32
32
|
export declare function isSbomEvidence(evidence: Evidence): evidence is SbomEvidence;
|
|
33
33
|
export declare function isBuildEvidence(evidence: Evidence): evidence is BuildEvidence;
|
|
34
34
|
export declare function isQualityBudgetEvidence(evidence: Evidence): evidence is QualityBudgetEvidence;
|
|
35
|
+
/**
|
|
36
|
+
* Type guard for secretscan evidence
|
|
37
|
+
*/
|
|
38
|
+
export declare function isSecretscanEvidence(evidence: Evidence): evidence is SecretscanEvidence;
|
|
35
39
|
/**
|
|
36
40
|
* Validate and sanitize task ID.
|
|
37
41
|
* Accepts three formats:
|
|
38
42
|
* 1. Canonical N.M or N.M.P numeric format (matches TASK_ID_REGEX)
|
|
39
43
|
* 2. Retrospective format: retro-<number> (matches RETRO_TASK_ID_REGEX)
|
|
40
|
-
* 3. Internal automated-tool format: specific tool IDs (sast_scan, quality_budget, syntax_check, placeholder_scan, sbom_generate, build)
|
|
44
|
+
* 3. Internal automated-tool format: specific tool IDs (sast_scan, quality_budget, syntax_check, placeholder_scan, sbom_generate, build, secretscan)
|
|
41
45
|
* Rejects: .., ../, null bytes, control characters, empty string, other non-numeric IDs
|
|
42
46
|
* @throws Error with descriptive message on failure
|
|
43
47
|
*/
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* delegation-gate.getEvidenceTaskId.test.ts
|
|
3
|
+
*
|
|
4
|
+
* Verification tests for the async conversion of getEvidenceTaskId.
|
|
5
|
+
* Tests the function behavior by recreating its logic in isolation since
|
|
6
|
+
* the function is private (not exported) and depends on fs.promises.
|
|
7
|
+
*
|
|
8
|
+
* Covers:
|
|
9
|
+
* 1. Function returns a Promise (is async)
|
|
10
|
+
* 2. Function resolves to correct task ID when currentTaskId is set
|
|
11
|
+
* 3. Function resolves to correct task ID when lastCoderDelegationTaskId is set
|
|
12
|
+
* 4. Function falls back to taskWorkflowStates when above are null
|
|
13
|
+
* 5. Function returns null when plan.json doesn't exist (ENOENT)
|
|
14
|
+
* 6. Function returns null when plan.json has no in_progress tasks
|
|
15
|
+
* 7. Function returns null when session has direct task_id (early return path via currentTaskId)
|
|
16
|
+
* 8. Path traversal is blocked (security hardening)
|
|
17
|
+
* 9. Malformed JSON returns null
|
|
18
|
+
* 10. Empty/invalid directory returns null
|
|
19
|
+
*/
|
|
20
|
+
export {};
|