opencode-swarm 7.114.9 → 7.116.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 +3 -1
- package/dist/cli/{config-doctor-jy3mdh9t.js → config-doctor-htzxe394.js} +2 -2
- package/dist/cli/{curator-5xt89z05.js → curator-7s5yw6hw.js} +18 -17
- package/dist/cli/{curator-llm-factory-pnhvf3s3.js → curator-llm-factory-x96dr0zf.js} +18 -17
- package/dist/cli/{dispatch-mczsxy5s.js → dispatch-07jgc3hn.js} +1 -1
- package/dist/cli/{evidence-summary-service-fehwj116.js → evidence-summary-service-ef6kgtev.js} +5 -5
- package/dist/cli/{gate-evidence-vkpqt300.js → gate-evidence-thqt0beq.js} +4 -4
- package/dist/cli/{guardrail-explain-7aztgtyh.js → guardrail-explain-kwqfkwch.js} +19 -18
- package/dist/cli/{guardrail-log-84wnx273.js → guardrail-log-dzbqcgz9.js} +3 -3
- package/dist/cli/{hive-promoter-q899q2m6.js → hive-promoter-rkkx40qv.js} +18 -17
- package/dist/cli/{index-54sevh81.js → index-3b8n3dbd.js} +30 -22
- package/dist/cli/{index-8f2270hc.js → index-3yh67t1h.js} +3 -3
- package/dist/cli/{index-4sckv7y6.js → index-42cx6g2h.js} +9 -4
- package/dist/cli/index-4905hd2m.js +19 -0
- package/dist/cli/{index-4h2ea8h5.js → index-81vzywh3.js} +2 -2
- package/dist/cli/{index-6f6y2rbp.js → index-8bvh0qfa.js} +3 -3
- package/dist/cli/{index-yfedche9.js → index-8j5d3ytd.js} +1 -1
- package/dist/cli/{index-80jkseqw.js → index-a6f8b0vn.js} +1 -1
- package/dist/cli/{index-0p660a87.js → index-bbsaxnj5.js} +1 -1
- package/dist/cli/{index-yrrqs4b0.js → index-cnrhj56z.js} +1160 -47
- package/dist/cli/{index-n18yy0z1.js → index-jyetmzcn.js} +3 -3
- package/dist/cli/{index-rk6qhyng.js → index-k5ey429j.js} +4 -4
- package/dist/cli/{index-7jmrbp68.js → index-m43zgtjn.js} +1 -1
- package/dist/cli/{index-9bsmzfk3.js → index-m7hc7nn7.js} +5 -1
- package/dist/cli/{index-typ408f4.js → index-me46ffm2.js} +6811 -1947
- package/dist/cli/{index-ga4ta3cr.js → index-nprawcc0.js} +7 -1
- package/dist/cli/{index-a45jq4b7.js → index-nvc0nsvg.js} +6 -1
- package/dist/cli/{index-pa6t33pt.js → index-q2rrv0cy.js} +11 -0
- package/dist/cli/{index-g40r5d08.js → index-qgeeyy75.js} +1 -1
- package/dist/cli/{index-x12hvfpf.js → index-s385axt1.js} +3 -3
- package/dist/cli/{index-m9m7p49w.js → index-tvgvb5pa.js} +2 -2
- package/dist/cli/index.js +18 -17
- package/dist/cli/{knowledge-escalator-5gwp1ar8.js → knowledge-escalator-0bq62d34.js} +7 -7
- package/dist/cli/{knowledge-events-m304swh6.js → knowledge-events-cwwky393.js} +5 -5
- package/dist/cli/{knowledge-store-9babt8rd.js → knowledge-store-q8x4h82m.js} +5 -5
- package/dist/cli/{knowledge-validator-t9sym59g.js → knowledge-validator-zr0djm02.js} +6 -6
- package/dist/cli/{pending-delegations-ddbkbgxy.js → pending-delegations-rr9x47rd.js} +2 -2
- package/dist/cli/{pr-subscriptions-vwv7zm2p.js → pr-subscriptions-cny2jz2d.js} +3 -3
- package/dist/cli/runtime-ykafcwc6.js +3397 -0
- package/dist/cli/{schema-aymfdrsb.js → schema-bqn7g3ez.js} +3 -1
- package/dist/cli/{skill-generator-tav44xpm.js → skill-generator-mz267btk.js} +8 -8
- package/dist/cli/{telemetry-jny76r83.js → telemetry-qh78ymq4.js} +1 -1
- package/dist/commands/archive.d.ts +4 -4
- package/dist/commands/command-dispatch.d.ts +2 -0
- package/dist/commands/gate-audit.d.ts +28 -0
- package/dist/commands/gate-stats.d.ts +1 -0
- package/dist/commands/index.d.ts +4 -0
- package/dist/commands/registry.d.ts +19 -2
- package/dist/config/index.d.ts +2 -2
- package/dist/config/plan-schema.d.ts +7 -7
- package/dist/config/schema.d.ts +9 -0
- package/dist/evaluation/contracts.d.ts +545 -0
- package/dist/evaluation/disposable-worktree.d.ts +38 -0
- package/dist/evaluation/fixtures.d.ts +8 -0
- package/dist/evaluation/gate-audit.d.ts +32 -0
- package/dist/evaluation/gate-ground-truth.d.ts +43 -0
- package/dist/evaluation/gate-stats.d.ts +47 -0
- package/dist/evaluation/hashing.d.ts +34 -0
- package/dist/evaluation/index.d.ts +17 -0
- package/dist/evaluation/model-dispatcher.d.ts +30 -0
- package/dist/evaluation/public-api.d.ts +87 -0
- package/dist/evaluation/retention.d.ts +56 -0
- package/dist/evaluation/runner.d.ts +48 -0
- package/dist/evaluation/statistics.d.ts +9 -0
- package/dist/evaluation/store.d.ts +26 -0
- package/dist/evidence/manager.d.ts +18 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +497 -450
- package/dist/mutation/engine.d.ts +29 -5
- package/dist/telemetry.d.ts +11 -1
- package/dist/tools/apply-patch.d.ts +21 -0
- package/dist/tools/plugin-registration.d.ts +2 -1
- package/dist/tools/sast-scan.d.ts +9 -0
- package/dist/tools/swarm-command.d.ts +2 -1
- package/dist/tools/update-task-status.d.ts +16 -4
- package/dist/utils/external-tool-runner.d.ts +2 -1
- package/dist/utils/fuzzy-match.d.ts +115 -0
- package/dist/utils/sequence-matcher.d.ts +83 -0
- package/evaluation-fixtures/tier1/boundary-error/environment/baseline.ts +3 -0
- package/evaluation-fixtures/tier1/boundary-error/environment/defect.test.ts +3 -0
- package/evaluation-fixtures/tier1/boundary-error/environment/defect.ts +3 -0
- package/evaluation-fixtures/tier1/boundary-error/instruction.md +1 -0
- package/evaluation-fixtures/tier1/boundary-error/manifest.json +1 -0
- package/evaluation-fixtures/tier1/branch-swap/environment/baseline.ts +3 -0
- package/evaluation-fixtures/tier1/branch-swap/environment/defect.test.ts +3 -0
- package/evaluation-fixtures/tier1/branch-swap/environment/defect.ts +3 -0
- package/evaluation-fixtures/tier1/branch-swap/instruction.md +1 -0
- package/evaluation-fixtures/tier1/branch-swap/manifest.json +1 -0
- package/evaluation-fixtures/tier1/curated-off-by-one/environment/baseline.ts +3 -0
- package/evaluation-fixtures/tier1/curated-off-by-one/environment/defect.test.ts +3 -0
- package/evaluation-fixtures/tier1/curated-off-by-one/environment/defect.ts +3 -0
- package/evaluation-fixtures/tier1/curated-off-by-one/instruction.md +1 -0
- package/evaluation-fixtures/tier1/curated-off-by-one/manifest.json +1 -0
- package/evaluation-fixtures/tier1/guard-removal/environment/baseline.ts +3 -0
- package/evaluation-fixtures/tier1/guard-removal/environment/defect.test.ts +3 -0
- package/evaluation-fixtures/tier1/guard-removal/environment/defect.ts +3 -0
- package/evaluation-fixtures/tier1/guard-removal/instruction.md +1 -0
- package/evaluation-fixtures/tier1/guard-removal/manifest.json +1 -0
- package/evaluation-fixtures/tier1/injection-prone-string/environment/baseline.ts +3 -0
- package/evaluation-fixtures/tier1/injection-prone-string/environment/defect.test.ts +3 -0
- package/evaluation-fixtures/tier1/injection-prone-string/environment/defect.ts +3 -0
- package/evaluation-fixtures/tier1/injection-prone-string/instruction.md +1 -0
- package/evaluation-fixtures/tier1/injection-prone-string/manifest.json +1 -0
- package/evaluation-fixtures/tier1/missing-auth-check/environment/baseline.ts +4 -0
- package/evaluation-fixtures/tier1/missing-auth-check/environment/defect.test.ts +3 -0
- package/evaluation-fixtures/tier1/missing-auth-check/environment/defect.ts +3 -0
- package/evaluation-fixtures/tier1/missing-auth-check/instruction.md +1 -0
- package/evaluation-fixtures/tier1/missing-auth-check/manifest.json +1 -0
- package/evaluation-fixtures/tier1/missing-await/environment/baseline.ts +7 -0
- package/evaluation-fixtures/tier1/missing-await/environment/defect.test.ts +3 -0
- package/evaluation-fixtures/tier1/missing-await/environment/defect.ts +4 -0
- package/evaluation-fixtures/tier1/missing-await/instruction.md +1 -0
- package/evaluation-fixtures/tier1/missing-await/manifest.json +1 -0
- package/evaluation-fixtures/tier1/mutation-off-by-one/environment/baseline.ts +3 -0
- package/evaluation-fixtures/tier1/mutation-off-by-one/environment/defect.test.ts +3 -0
- package/evaluation-fixtures/tier1/mutation-off-by-one/environment/defect.ts +3 -0
- package/evaluation-fixtures/tier1/mutation-off-by-one/instruction.md +1 -0
- package/evaluation-fixtures/tier1/mutation-off-by-one/manifest.json +1 -0
- package/evaluation-fixtures/tier1/null-substitution/environment/baseline.ts +3 -0
- package/evaluation-fixtures/tier1/null-substitution/environment/defect.test.ts +3 -0
- package/evaluation-fixtures/tier1/null-substitution/environment/defect.ts +3 -0
- package/evaluation-fixtures/tier1/null-substitution/instruction.md +1 -0
- package/evaluation-fixtures/tier1/null-substitution/manifest.json +1 -0
- package/evaluation-fixtures/tier1/operator-swap/environment/baseline.ts +3 -0
- package/evaluation-fixtures/tier1/operator-swap/environment/defect.test.ts +3 -0
- package/evaluation-fixtures/tier1/operator-swap/environment/defect.ts +3 -0
- package/evaluation-fixtures/tier1/operator-swap/instruction.md +1 -0
- package/evaluation-fixtures/tier1/operator-swap/manifest.json +1 -0
- package/evaluation-fixtures/tier1/side-effect-deletion/environment/baseline.ts +4 -0
- package/evaluation-fixtures/tier1/side-effect-deletion/environment/defect.test.ts +3 -0
- package/evaluation-fixtures/tier1/side-effect-deletion/environment/defect.ts +3 -0
- package/evaluation-fixtures/tier1/side-effect-deletion/instruction.md +1 -0
- package/evaluation-fixtures/tier1/side-effect-deletion/manifest.json +1 -0
- package/evaluation-fixtures/tier1/swallowed-error/environment/baseline.ts +3 -0
- package/evaluation-fixtures/tier1/swallowed-error/environment/defect.test.ts +3 -0
- package/evaluation-fixtures/tier1/swallowed-error/environment/defect.ts +3 -0
- package/evaluation-fixtures/tier1/swallowed-error/instruction.md +1 -0
- package/evaluation-fixtures/tier1/swallowed-error/manifest.json +1 -0
- package/package.json +2 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
|
-
|
|
3
|
-
export type MutationOutcome = 'killed' | 'survived' | 'timeout' | 'error' | 'equivalent' | 'skipped';
|
|
2
|
+
import { resolveExecutableFromPath, runExternalTool } from '../utils/external-tool-runner.js';
|
|
3
|
+
export type MutationOutcome = 'killed' | 'survived' | 'timeout' | 'cancelled' | 'error' | 'equivalent' | 'skipped';
|
|
4
4
|
/**
|
|
5
5
|
* Known test runner executables permitted as the first element of testCommand.
|
|
6
6
|
* Validated as the basename (without extension) to support platform-specific
|
|
@@ -35,6 +35,7 @@ export interface MutationReport {
|
|
|
35
35
|
killed: number;
|
|
36
36
|
survived: number;
|
|
37
37
|
timeout: number;
|
|
38
|
+
cancelled: number;
|
|
38
39
|
equivalent: number;
|
|
39
40
|
skipped: number;
|
|
40
41
|
errors: number;
|
|
@@ -55,13 +56,36 @@ export interface MutationReport {
|
|
|
55
56
|
timestamp: string;
|
|
56
57
|
}
|
|
57
58
|
export declare const MAX_MUTATIONS_PER_FUNCTION = 10;
|
|
59
|
+
type LegacySpawnSyncFn = typeof spawnSync;
|
|
60
|
+
export type MutationCommandResult = {
|
|
61
|
+
status: 'completed' | 'timeout' | 'cancelled' | 'spawn-error';
|
|
62
|
+
exitCode: number | null;
|
|
63
|
+
stdout: string;
|
|
64
|
+
stderr: string;
|
|
65
|
+
message?: string;
|
|
66
|
+
};
|
|
67
|
+
export type MutationCommandRunner = (args: {
|
|
68
|
+
executable: string;
|
|
69
|
+
args: string[];
|
|
70
|
+
cwd: string;
|
|
71
|
+
timeoutMs: number;
|
|
72
|
+
abortSignal?: AbortSignal;
|
|
73
|
+
}) => Promise<MutationCommandResult>;
|
|
74
|
+
export type MutationExecutionOptions = {
|
|
75
|
+
abortSignal?: AbortSignal;
|
|
76
|
+
runner?: MutationCommandRunner;
|
|
77
|
+
};
|
|
78
|
+
export declare const runMutationCommand: MutationCommandRunner;
|
|
58
79
|
export declare const _internals: {
|
|
59
80
|
executeMutation: typeof executeMutation;
|
|
60
81
|
computeReport: typeof computeReport;
|
|
61
82
|
executeMutationSuite: typeof executeMutationSuite;
|
|
62
|
-
spawnSync:
|
|
83
|
+
spawnSync: LegacySpawnSyncFn;
|
|
84
|
+
runCommand: MutationCommandRunner;
|
|
85
|
+
runExternalTool: typeof runExternalTool;
|
|
86
|
+
resolveExecutableFromPath: typeof resolveExecutableFromPath;
|
|
63
87
|
};
|
|
64
|
-
export declare function executeMutation(patch: MutationPatch, testCommand: string[], testFiles: string[], workingDir: string): Promise<MutationResult>;
|
|
88
|
+
export declare function executeMutation(patch: MutationPatch, testCommand: string[], testFiles: string[], workingDir: string, options?: MutationExecutionOptions): Promise<MutationResult>;
|
|
65
89
|
export declare function computeReport(results: MutationResult[], durationMs: number, budgetMs?: number): MutationReport;
|
|
66
|
-
export declare function executeMutationSuite(patches: MutationPatch[], testCommand: string[], testFiles: string[], workingDir: string, budgetMs?: number, onProgress?: (completed: number, total: number, result: MutationResult) => void, sourceFiles?: Map<string, string
|
|
90
|
+
export declare function executeMutationSuite(patches: MutationPatch[], testCommand: string[], testFiles: string[], workingDir: string, budgetMs?: number, onProgress?: (completed: number, total: number, result: MutationResult) => void, sourceFiles?: Map<string, string>, options?: MutationExecutionOptions): Promise<MutationReport>;
|
|
67
91
|
export {};
|
package/dist/telemetry.d.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import type { DelegationCostFields } from './services/cost-accounting.js';
|
|
2
|
-
export type TelemetryEvent = 'session_started' | 'session_ended' | 'agent_activated' | 'delegation_begin' | 'delegation_end' | 'task_state_changed' | 'gate_passed' | 'gate_failed' | 'gate_parse_error' | 'phase_changed' | 'budget_updated' | 'model_fallback' | 'hard_limit_hit' | 'revision_limit_hit' | 'loop_detected' | 'scope_violation' | 'qa_skip_violation' | 'heartbeat' | 'turbo_mode_changed' | 'auto_oversight_escalation' | 'environment_detected' | 'evidence_lock_acquired' | 'evidence_lock_contended' | 'evidence_lock_stale_recovered' | 'plan_ledger_cas_retry' | 'plan_md_write_failed' | 'snapshot_failed' | 'prm_pattern_detected' | 'prm_course_correction_injected' | 'prm_escalation_triggered' | 'prm_hard_stop';
|
|
2
|
+
export type TelemetryEvent = 'session_started' | 'session_ended' | 'agent_activated' | 'delegation_begin' | 'delegation_end' | 'task_state_changed' | 'gate_passed' | 'gate_failed' | 'gate_parse_error' | 'reviewer_gate_decision' | 'phase_changed' | 'budget_updated' | 'model_fallback' | 'hard_limit_hit' | 'revision_limit_hit' | 'loop_detected' | 'scope_violation' | 'qa_skip_violation' | 'heartbeat' | 'turbo_mode_changed' | 'auto_oversight_escalation' | 'environment_detected' | 'evidence_lock_acquired' | 'evidence_lock_contended' | 'evidence_lock_stale_recovered' | 'plan_ledger_cas_retry' | 'plan_md_write_failed' | 'snapshot_failed' | 'prm_pattern_detected' | 'prm_course_correction_injected' | 'prm_escalation_triggered' | 'prm_hard_stop';
|
|
3
|
+
/** Stable classification for how a reviewer-gate decision was established. */
|
|
4
|
+
export type ReviewerGateEvidenceKind = 'genuine' | 'fallback' | 'data_quality' | 'block';
|
|
5
|
+
/**
|
|
6
|
+
* Stable reason codes for reviewer-gate decision telemetry.
|
|
7
|
+
*
|
|
8
|
+
* These values are persisted in telemetry.jsonl and consumed by offline gate
|
|
9
|
+
* analytics, so additions are allowed but existing values must not be renamed.
|
|
10
|
+
*/
|
|
11
|
+
export type ReviewerGateReasonCode = 'lean_turbo_completed_lane' | 'standard_turbo_non_tier3' | 'durable_evidence_complete' | 'workflow_state_complete' | 'stage_b_parallel_complete' | 'no_active_sessions' | 'zero_valid_sessions' | 'restart_recovery_complete' | 'scoped_delegation_complete' | 'unscoped_delegation_complete' | 'corrupt_evidence' | 'required_gates_missing' | 'inspection_error';
|
|
3
12
|
export type TelemetryListener = (event: TelemetryEvent, data: Record<string, unknown>) => void;
|
|
4
13
|
/**
|
|
5
14
|
* Number of emits between rotation checks. 50 keeps the overhead at one
|
|
@@ -48,6 +57,7 @@ export declare const telemetry: {
|
|
|
48
57
|
gatePassed(sessionId: string, gate: string, taskId: string): void;
|
|
49
58
|
gateParseError(taskId: string, error: Error): void;
|
|
50
59
|
gateFailed(sessionId: string, gate: string, taskId: string, reason: string): void;
|
|
60
|
+
reviewerGateDecision(sessionId: string, taskId: string, blocked: boolean, reasonCode: ReviewerGateReasonCode, evidenceKind: ReviewerGateEvidenceKind): void;
|
|
51
61
|
phaseChanged(sessionId: string, oldPhase: number, newPhase: number): void;
|
|
52
62
|
budgetUpdated(sessionId: string, budgetPct: number, agentName: string): void;
|
|
53
63
|
modelFallback(sessionId: string, agentName: string, fromModel: string, toModel: string, reason: string): void;
|
|
@@ -7,6 +7,17 @@
|
|
|
7
7
|
* Pure TypeScript, no shell/git/external binaries, standard node:fs sync I/O.
|
|
8
8
|
*/
|
|
9
9
|
import type { ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
10
|
+
import { loadPluginConfigWithMeta } from '../config';
|
|
11
|
+
/**
|
|
12
|
+
* DI seam for hermetic config-load substitution in tests (AGENTS.md invariant 7).
|
|
13
|
+
* Mirrors the pattern at `src/tools/context-status.ts:81-88`. Tests override
|
|
14
|
+
* `_internals.loadPluginConfigWithMeta` and restore it in `afterEach` instead
|
|
15
|
+
* of writing real config files or using `mock.module` (which leaks across
|
|
16
|
+
* test files in Bun's shared runner).
|
|
17
|
+
*/
|
|
18
|
+
export declare const _internals: {
|
|
19
|
+
loadPluginConfigWithMeta: typeof loadPluginConfigWithMeta;
|
|
20
|
+
};
|
|
10
21
|
/** Per-file error detail in the structured output. */
|
|
11
22
|
export interface ApplyPatchFileError {
|
|
12
23
|
hunkIndex: number;
|
|
@@ -45,6 +56,16 @@ export interface ApplyPatchArgs {
|
|
|
45
56
|
allowCreates?: boolean;
|
|
46
57
|
allowDeletes?: boolean;
|
|
47
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Opt-in fuzzy-matching options threaded from `execute` → `processFileDiff`
|
|
61
|
+
* → `applyHunks`. Both flags default false (exact-match-only, B3 decision).
|
|
62
|
+
*/
|
|
63
|
+
export interface ApplyHunksOptions {
|
|
64
|
+
/** Enable fuzzy fallback (strategies 1-8) on exact-match failure. */
|
|
65
|
+
fuzzyMatch: boolean;
|
|
66
|
+
/** Additionally enable strategy 9 (context_aware). Only effective with fuzzyMatch. */
|
|
67
|
+
fuzzyMatchContextAware: boolean;
|
|
68
|
+
}
|
|
48
69
|
/**
|
|
49
70
|
* Swarm unified-diff patch tool (formerly registered as apply_patch).
|
|
50
71
|
* Renamed to swarm_apply_patch so it no longer shadows the native opencode
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import type { ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
12
12
|
import type { AgentDefinition } from '../agents/index.js';
|
|
13
13
|
import type { PluginConfig } from '../config/index.js';
|
|
14
|
+
import type { EvaluationModelDispatcher } from '../evaluation/model-dispatcher.js';
|
|
14
15
|
/**
|
|
15
16
|
* Construct the plugin tool object: one handler per manifest entry, with
|
|
16
17
|
* `swarm_command` overridden by its dependency-injected instance.
|
|
@@ -21,4 +22,4 @@ import type { PluginConfig } from '../config/index.js';
|
|
|
21
22
|
*
|
|
22
23
|
* Knowledge tools are conditionally excluded when config.knowledge.enabled = false.
|
|
23
24
|
*/
|
|
24
|
-
export declare function buildPluginToolObject(agents: Record<string, AgentDefinition>, config?: PluginConfig): Record<string, ToolDefinition>;
|
|
25
|
+
export declare function buildPluginToolObject(agents: Record<string, AgentDefinition>, config?: PluginConfig, evaluationModelDispatcher?: EvaluationModelDispatcher): Record<string, ToolDefinition>;
|
|
@@ -5,9 +5,16 @@
|
|
|
5
5
|
import type { ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
6
6
|
import type { PluginConfig } from '../config';
|
|
7
7
|
import type { EvidenceVerdict } from '../config/evidence-schema';
|
|
8
|
+
import { isSemgrepAvailable, runSemgrep } from '../sast/semgrep';
|
|
8
9
|
export interface SastScanInput {
|
|
9
10
|
/** List of files to scan */
|
|
10
11
|
changed_files: string[];
|
|
12
|
+
/**
|
|
13
|
+
* Restrict execution to built-in Tier A rules. This is used by isolated,
|
|
14
|
+
* reproducible evaluation runs where PATH discovery and Semgrep execution
|
|
15
|
+
* (including remote `--config=auto`) are forbidden.
|
|
16
|
+
*/
|
|
17
|
+
offline_only?: boolean;
|
|
11
18
|
/** Minimum severity that causes failure (default: 'medium') */
|
|
12
19
|
severity_threshold?: 'low' | 'medium' | 'high' | 'critical';
|
|
13
20
|
/**
|
|
@@ -94,4 +101,6 @@ export declare const sast_scan: ToolDefinition;
|
|
|
94
101
|
export declare const _internals: {
|
|
95
102
|
sastScan: typeof sastScan;
|
|
96
103
|
sast_scan: typeof sast_scan;
|
|
104
|
+
isSemgrepAvailable: typeof isSemgrepAvailable;
|
|
105
|
+
runSemgrep: typeof runSemgrep;
|
|
97
106
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AgentDefinition } from '../agents/index.js';
|
|
2
|
+
import type { EvaluationModelDispatcher } from '../evaluation/model-dispatcher.js';
|
|
2
3
|
import { createSwarmTool } from './create-tool.js';
|
|
3
|
-
export declare function createSwarmCommandTool(agents: Record<string, AgentDefinition
|
|
4
|
+
export declare function createSwarmCommandTool(agents: Record<string, AgentDefinition>, evaluationModelDispatcher?: EvaluationModelDispatcher): ReturnType<typeof createSwarmTool>;
|
|
4
5
|
export declare const swarm_command: ReturnType<typeof createSwarmTool>;
|
|
@@ -3,8 +3,12 @@
|
|
|
3
3
|
* Allows agents to mark tasks as pending, in_progress, completed, or blocked.
|
|
4
4
|
*/
|
|
5
5
|
import type { ToolContext, ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
6
|
+
import { readTaskEvidenceRaw } from '../gate-evidence.js';
|
|
6
7
|
import { tryAcquireLock } from '../parallel/file-locks.js';
|
|
7
8
|
import { loadPlan, updateTaskStatus } from '../plan/manager';
|
|
9
|
+
import { hasActiveLeanTurbo, hasActiveTurboMode } from '../state';
|
|
10
|
+
import { type ReviewerGateEvidenceKind, type ReviewerGateReasonCode } from '../telemetry.js';
|
|
11
|
+
import { verifyLeanTurboTaskCompletion } from '../turbo/lean/task-completion';
|
|
8
12
|
import { resolveWorkingDirectory } from './resolve-working-directory';
|
|
9
13
|
/**
|
|
10
14
|
* Internal seams for test injection.
|
|
@@ -12,10 +16,16 @@ import { resolveWorkingDirectory } from './resolve-working-directory';
|
|
|
12
16
|
* module-scope vi.mock, which leaks across files in Bun's shared test runner.
|
|
13
17
|
*/
|
|
14
18
|
export declare const _internals: {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
tryAcquireLock: typeof tryAcquireLock;
|
|
20
|
+
updateTaskStatus: typeof updateTaskStatus;
|
|
21
|
+
resolveWorkingDirectory: typeof resolveWorkingDirectory;
|
|
22
|
+
loadPlan: typeof loadPlan;
|
|
23
|
+
readTaskEvidenceRaw: typeof readTaskEvidenceRaw;
|
|
24
|
+
hasActiveLeanTurbo: typeof hasActiveLeanTurbo;
|
|
25
|
+
hasActiveTurboMode: typeof hasActiveTurboMode;
|
|
26
|
+
verifyLeanTurboTaskCompletion: typeof verifyLeanTurboTaskCompletion;
|
|
27
|
+
hasPassedDurableGateEvidence: typeof hasPassedDurableGateEvidence;
|
|
28
|
+
emitReviewerGateDecision: (sessionId: string, taskId: string, blocked: boolean, reasonCode: ReviewerGateReasonCode, evidenceKind: ReviewerGateEvidenceKind) => void;
|
|
19
29
|
};
|
|
20
30
|
/**
|
|
21
31
|
* Arguments for the update_task_status tool
|
|
@@ -58,6 +68,7 @@ export interface ReviewerGateResult {
|
|
|
58
68
|
blocked: boolean;
|
|
59
69
|
reason: string;
|
|
60
70
|
}
|
|
71
|
+
declare function hasPassedDurableGateEvidence(workingDirectory: string, taskId: string): boolean;
|
|
61
72
|
/**
|
|
62
73
|
* Check if a task has passed required QA gates using the state machine.
|
|
63
74
|
* Requires the task to be in 'tests_run' or 'complete' state, which means
|
|
@@ -138,3 +149,4 @@ export declare function executeUpdateTaskStatus(args: UpdateTaskStatusArgs, fall
|
|
|
138
149
|
* Tool definition for update_task_status
|
|
139
150
|
*/
|
|
140
151
|
export declare const update_task_status: ToolDefinition;
|
|
152
|
+
export {};
|
|
@@ -7,9 +7,10 @@ export interface ExternalToolRunOptions {
|
|
|
7
7
|
maxStdoutBytes: number;
|
|
8
8
|
maxStderrBytes: number;
|
|
9
9
|
env?: Record<string, string | undefined>;
|
|
10
|
+
abortSignal?: AbortSignal;
|
|
10
11
|
}
|
|
11
12
|
export interface ExternalToolRunResult {
|
|
12
|
-
status: 'completed' | 'timeout' | 'spawn-error';
|
|
13
|
+
status: 'completed' | 'timeout' | 'cancelled' | 'spawn-error';
|
|
13
14
|
exitCode: number | null;
|
|
14
15
|
stdout: string;
|
|
15
16
|
stderr: string;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fuzzy text-matching engine — faithful TypeScript port of hermes-agent's
|
|
3
|
+
* `tools/fuzzy_match.py` (issue #1718).
|
|
4
|
+
*
|
|
5
|
+
* Implements a 9-strategy matching chain that finds and replaces text,
|
|
6
|
+
* tolerating the whitespace, indentation, escape-sequence, and Unicode
|
|
7
|
+
* drift common in LLM-generated patches. Integrated into `apply-patch`
|
|
8
|
+
* as an **opt-in fallback** (default off) gated by the `apply_patch.fuzzy_match`
|
|
9
|
+
* and `apply_patch.fuzzy_match_context_aware` config flags.
|
|
10
|
+
*
|
|
11
|
+
* Porting conventions:
|
|
12
|
+
* - Operates on **UTF-16 code units** consistently (`s[i]`, `s.length`).
|
|
13
|
+
* Matches `src/utils/sequence-matcher.ts`. Round-trip safe.
|
|
14
|
+
* - Per-line stripping uses JS `String.prototype.trim()`, which strips the
|
|
15
|
+
* Unicode WhiteSpace + LineTerminator set. Coincides with Python
|
|
16
|
+
* `str.strip()` for the ASCII/BMP content in the test suite; minor
|
|
17
|
+
* divergence on exotic whitespace categories is acceptable.
|
|
18
|
+
* - Strategy 9 (`contextAware`) is opt-in via the `includeContextAware`
|
|
19
|
+
* option to `fuzzyFindAndReplace`. It is the loosest, most-false-positive-
|
|
20
|
+
* prone strategy and is separately gated in apply-patch by
|
|
21
|
+
* `apply_patch.fuzzy_match_context_aware`.
|
|
22
|
+
*/
|
|
23
|
+
/** A `[start, end)` character span in the content string. */
|
|
24
|
+
type Span = [number, number];
|
|
25
|
+
/** Result of {@link fuzzyFindAndReplace}. */
|
|
26
|
+
export interface FuzzyResult {
|
|
27
|
+
/** Modified content on success; original content on failure. */
|
|
28
|
+
content: string;
|
|
29
|
+
/** Number of replacements made (0 on failure). */
|
|
30
|
+
matchCount: number;
|
|
31
|
+
/** Name of the strategy that matched, or `null` on failure. */
|
|
32
|
+
strategy: string | null;
|
|
33
|
+
/** `null` on success; an error description on failure. */
|
|
34
|
+
error: string | null;
|
|
35
|
+
}
|
|
36
|
+
/** Options for {@link fuzzyFindAndReplace}. */
|
|
37
|
+
export interface FuzzyOptions {
|
|
38
|
+
/**
|
|
39
|
+
* When true (default at the utility level), the `context_aware` strategy
|
|
40
|
+
* (9) is included in the chain. Strategy 9 is the loosest/most-false-
|
|
41
|
+
* positive-prone strategy (requires 50% of lines to reach 0.80 per-line
|
|
42
|
+
* similarity) and has quadratic cost, so it is bounded by an internal
|
|
43
|
+
* cell-count cap.
|
|
44
|
+
*
|
|
45
|
+
* **Default divergence (intentional):** the utility defaults this to
|
|
46
|
+
* `true` so the byte-faithful ported hermes test suite passes unmodified
|
|
47
|
+
* (strategy 9 is a legitimate part of the matching chain and some test
|
|
48
|
+
* cases depend on it). The `apply-patch` integration — the only consumer
|
|
49
|
+
* today — explicitly passes `false` unless the separate
|
|
50
|
+
* `apply_patch.fuzzy_match_context_aware` config flag is set, honoring
|
|
51
|
+
* issue #1718's Non-Goal "do not port strategy 9 as default-on" at the
|
|
52
|
+
* integration layer. New callers should pass `false` unless they
|
|
53
|
+
* specifically want strategy 9.
|
|
54
|
+
*/
|
|
55
|
+
includeContextAware?: boolean;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Maps Unicode typographic characters to their ASCII equivalents.
|
|
59
|
+
* Some replacements EXPAND a single code point into multiple ASCII chars
|
|
60
|
+
* (em-dash → "--", ellipsis → "..."); the position-remap helpers handle the
|
|
61
|
+
* resulting offset divergence.
|
|
62
|
+
*/
|
|
63
|
+
export declare const UNICODE_MAP: Record<string, string>;
|
|
64
|
+
/** Normalize Unicode typographic characters to ASCII equivalents. */
|
|
65
|
+
export declare function unicodeNormalize(text: string): string;
|
|
66
|
+
/**
|
|
67
|
+
* Find and replace text using a chain of increasingly fuzzy strategies.
|
|
68
|
+
*
|
|
69
|
+
* Strategies are tried in order; the first that yields matches wins. On a
|
|
70
|
+
* unique match (or when `replaceAll` is true), the replacement is applied.
|
|
71
|
+
* On failure, returns the original content with an error description.
|
|
72
|
+
*
|
|
73
|
+
* Guards (ported verbatim from hermes):
|
|
74
|
+
* - Ambiguity: `>1 match && !replaceAll` → fail with a helpful message.
|
|
75
|
+
* - Escape-drift: `\'`/`\"` present in both old+new but absent from the
|
|
76
|
+
* matched file region → block (transport serialization artifact).
|
|
77
|
+
* - Selective unescape: `\t`/`\r` in new_string → real bytes only when the
|
|
78
|
+
* matched file region contains the corresponding control char. `\n` excluded.
|
|
79
|
+
* - Unicode preservation: under strategy 7, unchanged spans keep the file's
|
|
80
|
+
* original Unicode characters rather than the ASCII-normalized equivalents.
|
|
81
|
+
*/
|
|
82
|
+
export declare function fuzzyFindAndReplace(content: string, oldString: string, newString: string, replaceAll?: boolean, options?: FuzzyOptions): FuzzyResult;
|
|
83
|
+
/** Strategy 1: exact string match, non-overlapping. */
|
|
84
|
+
export declare function strategyExact(content: string, pattern: string): Span[];
|
|
85
|
+
/** Strategy 2: per-line `.trim()` + block equality. */
|
|
86
|
+
export declare function strategyLineTrimmed(content: string, pattern: string): Span[];
|
|
87
|
+
/** Strategy 3: collapse `[ \t]+` → single space, preserve newlines. */
|
|
88
|
+
export declare function strategyWhitespaceNormalized(content: string, pattern: string): Span[];
|
|
89
|
+
/** Strategy 4: strip all leading whitespace per line (lstrip). */
|
|
90
|
+
export declare function strategyIndentationFlexible(content: string, pattern: string): Span[];
|
|
91
|
+
/** Strategy 5: unescape `\n`/`\t`/`\r` literals → bytes, then exact match. */
|
|
92
|
+
export declare function strategyEscapeNormalized(content: string, pattern: string): Span[];
|
|
93
|
+
/** Strategy 6: trim only first and last lines, sliding window. */
|
|
94
|
+
export declare function strategyTrimmedBoundary(content: string, pattern: string): Span[];
|
|
95
|
+
/** Strategy 7: Unicode normalization (smart quotes, em/en dash, ellipsis, NBSP). */
|
|
96
|
+
export declare function strategyUnicodeNormalized(content: string, pattern: string): Span[];
|
|
97
|
+
/** Strategy 8: anchor on first+last lines, similarity for the middle. */
|
|
98
|
+
export declare function strategyBlockAnchor(content: string, pattern: string): Span[];
|
|
99
|
+
export declare function strategyContextAware(content: string, pattern: string): Span[];
|
|
100
|
+
/**
|
|
101
|
+
* Find lines in `content` most similar to `oldString` for "did you mean?" feedback.
|
|
102
|
+
*
|
|
103
|
+
* Returns a formatted string showing the closest matching lines with context
|
|
104
|
+
* and line numbers, or `''` if no useful match is found.
|
|
105
|
+
*/
|
|
106
|
+
export declare function findClosestLines(oldString: string, content: string, contextLines?: number, maxResults?: number): string;
|
|
107
|
+
/**
|
|
108
|
+
* Return a "Did you mean..." snippet for plain no-match errors.
|
|
109
|
+
*
|
|
110
|
+
* Gated so the hint only fires for actual "old_string not found" failures.
|
|
111
|
+
* Ambiguous-match, escape-drift, and identical-strings errors all have
|
|
112
|
+
* `matchCount === 0` but a did-you-mean snippet would be misleading.
|
|
113
|
+
*/
|
|
114
|
+
export declare function formatNoMatchHint(error: string | null, matchCount: number, oldString: string, content: string): string;
|
|
115
|
+
export {};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Faithful TypeScript port of CPython's `difflib.SequenceMatcher`.
|
|
3
|
+
*
|
|
4
|
+
* Implements the Ratcliff/Obershelp pattern-matching algorithm with the
|
|
5
|
+
* "popular element" (autojunk) guard, so that `.ratio()` produces values
|
|
6
|
+
* identical to CPython 3.x for the BMP character content used by the
|
|
7
|
+
* fuzzy-match strategies. The thresholds in `src/utils/fuzzy-match.ts`
|
|
8
|
+
* (0.50 / 0.70 / 0.80) were tuned against CPython's exact `2*M/T` ratio
|
|
9
|
+
* formula, so substituting a Levenshtein-based library would silently
|
|
10
|
+
* break those thresholds.
|
|
11
|
+
*
|
|
12
|
+
* Porting notes:
|
|
13
|
+
* - Operates on **UTF-16 code units** (`s[i]`, `s.length`, `s.charCodeAt(i)`)
|
|
14
|
+
* consistently throughout. CPython operates on Unicode code points; for
|
|
15
|
+
* ASCII/BMP content the two coincide. Astral-plane characters (emoji)
|
|
16
|
+
* consume two UTF-16 units, so ratios for emoji-heavy input may differ
|
|
17
|
+
* marginally from CPython. This is acceptable for the fuzzy-match use
|
|
18
|
+
* case (source-code patches) and is round-trip-safe — no index mixing,
|
|
19
|
+
* no file corruption.
|
|
20
|
+
* - `autojunk` defaults to `true`, matching CPython. When `b.length >= 200`
|
|
21
|
+
* and an element appears more than 1% of the time in `b`, it is treated
|
|
22
|
+
* as "popular" and excluded as an anchor candidate in `find_longest_match`.
|
|
23
|
+
* This is essential for ratio fidelity on real file sections.
|
|
24
|
+
*/
|
|
25
|
+
export interface Match {
|
|
26
|
+
/** Start index in sequence `a`. */
|
|
27
|
+
a: number;
|
|
28
|
+
/** Start index in sequence `b`. */
|
|
29
|
+
b: number;
|
|
30
|
+
/** Length of the matching block. */
|
|
31
|
+
size: number;
|
|
32
|
+
}
|
|
33
|
+
export type OpcodeTag = 'equal' | 'replace' | 'delete' | 'insert';
|
|
34
|
+
export interface Opcode {
|
|
35
|
+
tag: OpcodeTag;
|
|
36
|
+
i1: number;
|
|
37
|
+
i2: number;
|
|
38
|
+
j1: number;
|
|
39
|
+
j2: number;
|
|
40
|
+
}
|
|
41
|
+
/** A predicate that marks a character as "junk" (never a sync point). */
|
|
42
|
+
export type IsJunk = ((ch: string) => boolean) | null;
|
|
43
|
+
/**
|
|
44
|
+
* Difflib-compatible sequence matcher. Construct with two strings, then
|
|
45
|
+
* call `.ratio()`, `.get_matching_blocks()`, or `.get_opcodes()`.
|
|
46
|
+
*/
|
|
47
|
+
export declare class SequenceMatcher {
|
|
48
|
+
private a;
|
|
49
|
+
private b;
|
|
50
|
+
private isJunk;
|
|
51
|
+
private autoJunk;
|
|
52
|
+
private b2j;
|
|
53
|
+
private popularSet;
|
|
54
|
+
private matchingBlocks;
|
|
55
|
+
constructor(isJunk: IsJunk, a: string, b: string, autoJunk?: boolean);
|
|
56
|
+
/** Allow changing the input sequences (mirrors CPython `set_seqs`/`set_seq2`). */
|
|
57
|
+
setSeqs(a: string, b: string): void;
|
|
58
|
+
/** Precompute the `b` index map and the popular-element set. */
|
|
59
|
+
private chainB;
|
|
60
|
+
/**
|
|
61
|
+
* Find the longest matching block in `a[alo:ahi]` and `b[blo:bhi]`.
|
|
62
|
+
*
|
|
63
|
+
* Returns `{ a, b, size }` where `size` is maximal; ties are broken by
|
|
64
|
+
* smallest `a`, then smallest `b` (CPython canonical tiebreak).
|
|
65
|
+
*
|
|
66
|
+
* A "match" means `a[i] === b[j]` and the run extends as far as possible.
|
|
67
|
+
* Elements in the popular set are only used as anchor candidates when no
|
|
68
|
+
* non-popular match exists (CPython behavior: popular elements are
|
|
69
|
+
* excluded from `b2j`, so they only match opportunistically via the
|
|
70
|
+
* extending run after a non-popular anchor).
|
|
71
|
+
*/
|
|
72
|
+
findLongestMatch(alo: number, ahi: number, blo: number, bhi: number): Match;
|
|
73
|
+
/** Recursively compute the list of matching blocks (descending order). */
|
|
74
|
+
getMatchingBlocks(): Match[];
|
|
75
|
+
/**
|
|
76
|
+
* Return a float in [0, 1]: `2*M / T`, where `M` is the total matched
|
|
77
|
+
* characters and `T` is the sum of the two sequence lengths.
|
|
78
|
+
* Returns `1.0` when both sequences are empty (matches CPython).
|
|
79
|
+
*/
|
|
80
|
+
ratio(): number;
|
|
81
|
+
/** Compute the opcodes describing how to turn `a` into `b`. */
|
|
82
|
+
getOpcodes(): Opcode[];
|
|
83
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Inspect the upper-bound validation in `environment/defect.ts` and identify the invalid value it permits.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"v":1,"id":"boundary-error","source":"curated","split":"train","category":"boundary-error","protected":true,"instructionPath":"instruction.md","environment":{"kind":"fixture","path":"environment"},"scorer":{"kind":"builtin","argv":["tier1-defect"],"timeoutMs":30000,"scoreRange":[0,1]},"provenance":{"origin":"opencode-swarm#1820","license":"MIT"},"contentHash":"ac9cd9f603d86640900fe3af16e7373a322eb5deff009b72bdf4239df13661b8"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Inspect `environment/defect.ts` for swapped conditional branches and report the incorrect results.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"v":1,"id":"branch-swap","source":"curated","split":"train","category":"branch-swap","protected":false,"instructionPath":"instruction.md","environment":{"kind":"fixture","path":"environment"},"scorer":{"kind":"builtin","argv":["tier1-defect"],"timeoutMs":30000,"scoreRange":[0,1]},"provenance":{"origin":"opencode-swarm#1820","license":"MIT"},"contentHash":"f9b09fb7fa980fd94e1603a0e26e1ef43cd30a1d91211a195933913847943f23"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Review the pagination boundary in `environment/defect.ts` and identify the page that is skipped.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"v":1,"id":"curated-off-by-one","source":"curated","split":"train","category":"curated-off-by-one","protected":true,"instructionPath":"instruction.md","environment":{"kind":"fixture","path":"environment"},"scorer":{"kind":"builtin","argv":["tier1-defect"],"timeoutMs":30000,"scoreRange":[0,1]},"provenance":{"origin":"opencode-swarm#1820","license":"MIT"},"contentHash":"2894129b530e0624dc1739ee7910839d261728a8655474b0103b8c98a7ea9f81"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Find the removed input guard in `environment/defect.ts` and state which input now fails.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"v":1,"id":"guard-removal","source":"curated","split":"train","category":"guard-removal","protected":true,"instructionPath":"instruction.md","environment":{"kind":"fixture","path":"environment"},"scorer":{"kind":"builtin","argv":["tier1-defect"],"timeoutMs":30000,"scoreRange":[0,1]},"provenance":{"origin":"opencode-swarm#1820","license":"MIT"},"contentHash":"7943c549ab0c9ce6503ca8df45a9430ae0a431094b4e358be43da1cfb63a1f7d"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Find the injection-prone command construction in `environment/defect.ts` and identify the unsafe input boundary.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"v":1,"id":"injection-prone-string","source":"curated","split":"train","category":"injection-prone-string","protected":true,"instructionPath":"instruction.md","environment":{"kind":"fixture","path":"environment"},"scorer":{"kind":"builtin","argv":["tier1-defect"],"timeoutMs":30000,"scoreRange":[0,1]},"provenance":{"origin":"opencode-swarm#1820","license":"MIT"},"contentHash":"0f45604dbdd251aaec2af3f82afeec10b2242b16a88d86087994918796a657f4"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Review `environment/defect.ts` for a missing authorization check and state who can perform the protected action.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"v":1,"id":"missing-auth-check","source":"curated","split":"train","category":"missing-auth-check","protected":true,"instructionPath":"instruction.md","environment":{"kind":"fixture","path":"environment"},"scorer":{"kind":"builtin","argv":["tier1-defect"],"timeoutMs":30000,"scoreRange":[0,1]},"provenance":{"origin":"opencode-swarm#1820","license":"MIT"},"contentHash":"9b6d8ff362df8aad25d3c579b10e0fa202e923a0565cf5d18d4c4d1da75af482"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Find the missing await in `environment/defect.ts` and explain the ordering failure.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"v":1,"id":"missing-await","source":"curated","split":"train","category":"missing-await","protected":true,"instructionPath":"instruction.md","environment":{"kind":"fixture","path":"environment"},"scorer":{"kind":"builtin","argv":["tier1-defect"],"timeoutMs":30000,"scoreRange":[0,1]},"provenance":{"origin":"opencode-swarm#1820","license":"MIT"},"contentHash":"d444592ce7d955882de61601bfe414be54c616f6c441ea735450e6716bc837fd"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Find the boundary defect in `environment/defect.ts`. Report whether the implementation is safe and explain the exact failing case.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"v":1,"id":"mutation-off-by-one","source":"curated","split":"train","category":"mutation-off-by-one","protected":true,"instructionPath":"instruction.md","environment":{"kind":"fixture","path":"environment"},"scorer":{"kind":"builtin","argv":["tier1-defect"],"timeoutMs":30000,"scoreRange":[0,1]},"provenance":{"origin":"opencode-swarm#1820","license":"MIT"},"contentHash":"9cec6a89ff87b1b85691313a2430916e3ebf393d532644b3f82faa10fe0203cd"}
|