opencode-swarm 7.132.2 → 7.133.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 +4 -1
- package/dist/agents/agent-output-schema.d.ts +74 -0
- package/dist/agents/critic.d.ts +2 -1
- package/dist/agents/reviewer.d.ts +1 -1
- package/dist/background/completion-observer.d.ts +2 -0
- package/dist/background/pending-delegations.d.ts +39 -1
- package/dist/background/stage-b-gates.d.ts +2 -0
- package/dist/cli/{config-doctor-bp5spb79.js → config-doctor-8nbdwnn6.js} +2 -2
- package/dist/cli/{core-wg3re04e.js → core-egwpry19.js} +2 -2
- package/dist/cli/{curation-policy-7zp2m9gv.js → curation-policy-gae3xm5d.js} +2 -2
- package/dist/cli/{curator-h067mrcc.js → curator-e88bm4mg.js} +17 -18
- package/dist/cli/{curator-llm-factory-605d08hf.js → curator-llm-factory-1a7esr69.js} +17 -18
- package/dist/cli/{evidence-summary-service-jfagmvrh.js → evidence-summary-service-nhsmsap8.js} +3 -3
- package/dist/cli/{guardrail-explain-s7vzm6z7.js → guardrail-explain-zgja2b9m.js} +18 -19
- package/dist/cli/{guardrail-log-aa112fxv.js → guardrail-log-fjgyx76r.js} +3 -3
- package/dist/cli/{hive-promoter-nv0m5rzk.js → hive-promoter-2b04e0wh.js} +17 -18
- package/dist/cli/{index-9cf1yr67.js → index-0vd91yb8.js} +3 -3
- package/dist/cli/{index-w9cb5zwh.js → index-17zjp67y.js} +1 -1
- package/dist/cli/{index-djwemsjn.js → index-66zght9d.js} +1 -1
- package/dist/cli/{index-6ccynjv3.js → index-7ftthvqt.js} +2 -2
- package/dist/cli/{index-jgfcp9bh.js → index-bz08438z.js} +1 -1
- package/dist/cli/{index-mwkwyej1.js → index-cpest8sa.js} +5 -5
- package/dist/cli/{index-y5qp59rc.js → index-hfpw5m0e.js} +9 -3
- package/dist/cli/{index-3s9rfnqq.js → index-j5pnah1w.js} +4 -4
- package/dist/cli/{index-jj4earrh.js → index-kc1m6vpr.js} +2 -2
- package/dist/cli/{index-8d3m0ge3.js → index-mhcge2ry.js} +34 -23
- package/dist/cli/{index-yvv1wt2h.js → index-mmvaf4t6.js} +1 -1
- package/dist/cli/{index-f6480ee6.js → index-mwqfyjja.js} +37751 -33949
- package/dist/cli/{index-fgcmxjp7.js → index-sp7tm8t7.js} +1 -1
- package/dist/cli/{index-k4tmx21m.js → index-sw82jvf2.js} +2 -2
- package/dist/cli/{index-630badhp.js → index-tj2mkfb3.js} +149 -6
- package/dist/cli/{index-rt5jgktq.js → index-wz36r0fk.js} +1 -1
- package/dist/cli/{index-bvp2v7k1.js → index-wzb4dv5s.js} +263 -16
- package/dist/cli/index.js +21 -20
- package/dist/cli/{knowledge-escalator-j0nceas7.js → knowledge-escalator-hzkw1ban.js} +3 -3
- package/dist/cli/{knowledge-events-gpqc62jr.js → knowledge-events-pbycdhqd.js} +1 -1
- package/dist/cli/{knowledge-store-ggxr3ww5.js → knowledge-store-45jawb2p.js} +1 -1
- package/dist/cli/{knowledge-validator-007smap6.js → knowledge-validator-ge576f8n.js} +4 -4
- package/dist/cli/pending-delegations-kxy8mdqg.js +75 -0
- package/dist/cli/{scan-cursor-wz4bff7a.js → scan-cursor-kvw872be.js} +2 -2
- package/dist/cli/{schema-023gwne7.js → schema-a2zm2m3r.js} +6 -2
- package/dist/cli/{scope-persistence-dm5bab50.js → scope-persistence-5qypzxxm.js} +1 -1
- package/dist/cli/{skill-generator-rtsg1m7x.js → skill-generator-ch79hvxh.js} +5 -5
- package/dist/commands/command-dispatch.d.ts +7 -0
- package/dist/commands/index.d.ts +7 -0
- package/dist/commands/registry.d.ts +16 -0
- package/dist/commands/review.d.ts +21 -0
- package/dist/config/agent-names.d.ts +3 -3
- package/dist/config/evidence-schema.d.ts +47 -47
- package/dist/config/index.d.ts +2 -2
- package/dist/config/schema.d.ts +58 -6
- package/dist/consensus/contracts.d.ts +3 -3
- package/dist/evaluation/contracts.d.ts +1 -1
- package/dist/evaluation/ephemeral-agent-dispatcher.d.ts +64 -0
- package/dist/evaluation/model-dispatcher.d.ts +11 -5
- package/dist/evaluation/public-api.d.ts +1 -1
- package/dist/hooks/auto-review.d.ts +30 -65
- package/dist/hooks/delegation-gate.d.ts +1 -1
- package/dist/hooks/guardrails/tool-before.d.ts +8 -0
- package/dist/hooks/review-receipt-collector.d.ts +53 -10
- package/dist/hooks/review-receipt-scope.d.ts +74 -0
- package/dist/hooks/review-receipt.d.ts +104 -10
- package/dist/hooks/reviewer-scope-file-fingerprint.d.ts +21 -0
- package/dist/hooks/reviewer-scope-lifecycle.d.ts +19 -0
- package/dist/hooks/task-result-classifier.d.ts +6 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +660 -607
- package/dist/memory/schema.d.ts +5 -5
- package/dist/review/contracts.d.ts +29 -0
- package/dist/review/diff-source.d.ts +134 -0
- package/dist/review/engine.d.ts +60 -0
- package/dist/review/evidence.d.ts +88 -0
- package/dist/review/finding-validator.d.ts +77 -0
- package/dist/review/phase-runner.d.ts +37 -0
- package/dist/review/runtime.d.ts +32 -0
- package/dist/scope/scope-binding.d.ts +9 -0
- package/dist/services/config-doctor.d.ts +12 -0
- package/dist/state.d.ts +179 -0
- package/dist/tools/dispatch-lanes.d.ts +2 -0
- package/dist/tools/lean-turbo-review.d.ts +4 -1
- package/dist/tools/lean-turbo-run-phase.d.ts +3 -1
- package/dist/tools/phase-complete/gates/final-review-gate.d.ts +18 -0
- package/dist/tools/phase-complete/gates/index.d.ts +1 -0
- package/dist/tools/phase-complete/gates/types.d.ts +10 -0
- package/dist/tools/phase-complete.d.ts +13 -1
- package/dist/tools/plugin-registration.d.ts +3 -1
- package/dist/tools/swarm-command.d.ts +4 -1
- package/dist/tools/tool-metadata.d.ts +22 -22
- package/dist/turbo/lean/integration.d.ts +18 -2
- package/dist/turbo/lean/reviewer.d.ts +19 -3
- package/dist/turbo/lean/runner.d.ts +1 -1
- package/package.json +1 -1
- package/dist/cli/index-y2pfmd0z.js +0 -259
- package/dist/cli/pending-delegations-37t4xecr.js +0 -34
- package/dist/cli/{curator-drift-y1wm4atk.js → curator-drift-ea0p8nh1.js} +2 -2
- package/dist/cli/{index-4ff0x4cg.js → index-74tptrss.js} +0 -0
- package/dist/cli/{index-03zyn94g.js → index-r260ybay.js} +4 -4
|
@@ -68,9 +68,9 @@ export declare const ConsensusMineRequestSchema: z.ZodObject<{
|
|
|
68
68
|
declare const ConsensusProposedTargetSchema: z.ZodEnum<{
|
|
69
69
|
tooling: "tooling";
|
|
70
70
|
none: "none";
|
|
71
|
+
orchestration: "orchestration";
|
|
71
72
|
prompt: "prompt";
|
|
72
73
|
skill: "skill";
|
|
73
|
-
orchestration: "orchestration";
|
|
74
74
|
}>;
|
|
75
75
|
export type ConsensusProposedTarget = z.infer<typeof ConsensusProposedTargetSchema>;
|
|
76
76
|
/**
|
|
@@ -151,9 +151,9 @@ export declare const ConsensusAttributeV1Schema: z.ZodObject<{
|
|
|
151
151
|
proposedTarget: z.ZodEnum<{
|
|
152
152
|
tooling: "tooling";
|
|
153
153
|
none: "none";
|
|
154
|
+
orchestration: "orchestration";
|
|
154
155
|
prompt: "prompt";
|
|
155
156
|
skill: "skill";
|
|
156
|
-
orchestration: "orchestration";
|
|
157
157
|
}>;
|
|
158
158
|
}, z.core.$strict>;
|
|
159
159
|
/**
|
|
@@ -390,9 +390,9 @@ export declare const ConsensusReportV1Schema: z.ZodObject<{
|
|
|
390
390
|
proposedTarget: z.ZodEnum<{
|
|
391
391
|
tooling: "tooling";
|
|
392
392
|
none: "none";
|
|
393
|
+
orchestration: "orchestration";
|
|
393
394
|
prompt: "prompt";
|
|
394
395
|
skill: "skill";
|
|
395
|
-
orchestration: "orchestration";
|
|
396
396
|
}>;
|
|
397
397
|
}, z.core.$strict>>;
|
|
398
398
|
proposals: z.ZodArray<z.ZodObject<{
|
|
@@ -278,9 +278,9 @@ export declare const PromotionDecisionV1Schema: z.ZodObject<{
|
|
|
278
278
|
runId: z.ZodString;
|
|
279
279
|
decidedAt: z.ZodISODateTime;
|
|
280
280
|
status: z.ZodEnum<{
|
|
281
|
+
reject: "reject";
|
|
281
282
|
inconclusive: "inconclusive";
|
|
282
283
|
accept: "accept";
|
|
283
|
-
reject: "reject";
|
|
284
284
|
}>;
|
|
285
285
|
reasons: z.ZodArray<z.ZodString>;
|
|
286
286
|
baseline: z.ZodObject<{
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { OpencodeClient } from '@opencode-ai/sdk';
|
|
2
|
+
import type { DelegationCostFields } from '../services/cost-accounting.js';
|
|
3
|
+
import { log } from '../utils/logger.js';
|
|
4
|
+
import type { ModelOverride } from '../utils/model-dispatch-fallback.js';
|
|
5
|
+
export declare const DEFAULT_EPHEMERAL_TIMEOUT_MS = 120000;
|
|
6
|
+
export declare const DEFAULT_EPHEMERAL_CLEANUP_TIMEOUT_MS = 500;
|
|
7
|
+
export declare const DEFAULT_EPHEMERAL_PROMPT_BYTE_LIMIT: number;
|
|
8
|
+
export declare const MAX_EPHEMERAL_PROMPT_BYTE_LIMIT: number;
|
|
9
|
+
export declare const DEFAULT_EPHEMERAL_RESPONSE_BYTE_LIMIT: number;
|
|
10
|
+
export type ReadOnlyToolDenials = Readonly<Record<string, false>>;
|
|
11
|
+
/**
|
|
12
|
+
* Fail-closed tool policy for isolated review/evaluation agents.
|
|
13
|
+
*
|
|
14
|
+
* OpenCode merges this request map with the selected agent's configured tools,
|
|
15
|
+
* so omitting a registered plugin tool leaves it enabled. Deny every canonical
|
|
16
|
+
* plugin tool (including deceptively mutable tools such as lint and recursive
|
|
17
|
+
* tools such as swarm_command) plus built-in mutation/dispatch escape hatches.
|
|
18
|
+
* Upstream read-only discovery tools remain available.
|
|
19
|
+
*/
|
|
20
|
+
export declare const DEFAULT_READ_ONLY_TOOLS: ReadOnlyToolDenials;
|
|
21
|
+
export type EphemeralAgentDispatchRequest = {
|
|
22
|
+
client: OpencodeClient;
|
|
23
|
+
directory: string;
|
|
24
|
+
parentSessionId?: string;
|
|
25
|
+
/** Already-resolved OpenCode agent name. Agent lookup belongs to the caller. */
|
|
26
|
+
agentName: string;
|
|
27
|
+
model?: ModelOverride;
|
|
28
|
+
/** Optional system prompt for this isolated session. */
|
|
29
|
+
system?: string;
|
|
30
|
+
prompt: string;
|
|
31
|
+
/** Explicit false-only tool map. The primitive never grants tools implicitly. */
|
|
32
|
+
readOnlyTools: ReadOnlyToolDenials;
|
|
33
|
+
title?: string;
|
|
34
|
+
timeoutMs: number;
|
|
35
|
+
cleanupTimeoutMs?: number;
|
|
36
|
+
promptByteLimit?: number;
|
|
37
|
+
responseByteLimit?: number;
|
|
38
|
+
abortSignal?: AbortSignal;
|
|
39
|
+
};
|
|
40
|
+
export type EphemeralAgentDispatchResult = {
|
|
41
|
+
status: 'completed' | 'timeout' | 'cancelled' | 'error';
|
|
42
|
+
agentName: string;
|
|
43
|
+
modelId?: string;
|
|
44
|
+
text: string;
|
|
45
|
+
error?: string;
|
|
46
|
+
durationMs: number;
|
|
47
|
+
promptBytes: number;
|
|
48
|
+
responseBytes: number;
|
|
49
|
+
costFields?: DelegationCostFields;
|
|
50
|
+
};
|
|
51
|
+
export declare function boundedDeleteEphemeralSession(client: OpencodeClient, sessionId: string, timeoutMs?: number): Promise<void>;
|
|
52
|
+
export declare const _internals: {
|
|
53
|
+
boundedDelete: typeof boundedDeleteEphemeralSession;
|
|
54
|
+
log: typeof log;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Dispatch one read-only agent in a fresh, parent-bound session.
|
|
58
|
+
*
|
|
59
|
+
* This is deliberately policy-free: callers resolve the agent and model, provide
|
|
60
|
+
* the replacement system prompt, and own retry/fallback policy. The primitive
|
|
61
|
+
* owns only bounded session creation/prompting, transcript caps, accounting, and
|
|
62
|
+
* awaited best-effort cleanup.
|
|
63
|
+
*/
|
|
64
|
+
export declare function dispatchEphemeralAgent(request: EphemeralAgentDispatchRequest): Promise<EphemeralAgentDispatchResult>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Agent, OpencodeClient } from '@opencode-ai/sdk';
|
|
2
|
-
import {
|
|
2
|
+
import type { DelegationCostFields } from '../services/cost-accounting.js';
|
|
3
|
+
import { _internals as ephemeralDispatcherInternals } from './ephemeral-agent-dispatcher.js';
|
|
3
4
|
export type EvaluationModelDispatchRequest = {
|
|
4
5
|
directory: string;
|
|
5
6
|
agentName: string;
|
|
@@ -18,13 +19,18 @@ export type EvaluationModelDispatchResult = {
|
|
|
18
19
|
text: string;
|
|
19
20
|
durationMs: number;
|
|
20
21
|
error?: string;
|
|
22
|
+
promptBytes?: number;
|
|
23
|
+
responseBytes?: number;
|
|
24
|
+
costFields?: DelegationCostFields;
|
|
21
25
|
};
|
|
22
26
|
export type EvaluationModelDispatcher = (request: EvaluationModelDispatchRequest) => Promise<EvaluationModelDispatchResult>;
|
|
23
27
|
export declare function resolveEvaluationAgentName(agents: readonly Pick<Agent, 'name'>[], logicalName: string, preferredSwarm?: string): string;
|
|
24
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Compatibility proxy for the existing evaluation test seam. The shared
|
|
30
|
+
* primitive remains the single owner of cleanup and logging behavior.
|
|
31
|
+
*/
|
|
25
32
|
export declare const _internals: {
|
|
26
|
-
boundedDelete: typeof boundedDelete;
|
|
27
|
-
log: typeof log;
|
|
33
|
+
boundedDelete: typeof ephemeralDispatcherInternals.boundedDelete;
|
|
34
|
+
log: typeof ephemeralDispatcherInternals.log;
|
|
28
35
|
};
|
|
29
36
|
export declare function createEvaluationModelDispatcher(client: OpencodeClient): EvaluationModelDispatcher;
|
|
30
|
-
export {};
|
|
@@ -31,7 +31,7 @@ export declare const evaluationV1: ((options: EvaluateCandidateV1Options) => Pro
|
|
|
31
31
|
decisionId: string;
|
|
32
32
|
runId: string;
|
|
33
33
|
decidedAt: string;
|
|
34
|
-
status: "
|
|
34
|
+
status: "reject" | "inconclusive" | "accept";
|
|
35
35
|
reasons: string[];
|
|
36
36
|
baseline: {
|
|
37
37
|
baselineRunId: string;
|
|
@@ -1,90 +1,55 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Automatic task-completion review hook.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* the same "second model reviews the work in a clean context" pattern used
|
|
9
|
-
* by Claude Code's auto-review and Codex's review model. The reviewer agent
|
|
10
|
-
* carries its own configured model (`agents.reviewer.model`), so the review
|
|
11
|
-
* model is independently configurable from the coder/architect models.
|
|
12
|
-
*
|
|
13
|
-
* The pass is ADVISORY and fully fail-open:
|
|
14
|
-
* - fire-and-forget from `tool.execute.after` (never blocks the tool)
|
|
15
|
-
* - verdicts are persisted as durable review receipts
|
|
16
|
-
* (`.swarm/review-receipts/`, scope-fingerprinted over the diff) and an
|
|
17
|
-
* `auto_review` event is appended to `.swarm/events.jsonl`
|
|
18
|
-
* - a REJECTED or unparseable verdict injects a `[AUTO-REVIEW]` advisory
|
|
19
|
-
* into the architect's next prompt; APPROVED stays silent
|
|
20
|
-
*
|
|
21
|
-
* Bounds (AGENTS.md invariants 3 and 8): the diff subprocess uses execFile
|
|
22
|
-
* with cwd/timeout/maxBuffer and ignored stdin; dispatches are guarded by a
|
|
23
|
-
* per-session in-flight set plus a 60s cooldown in a bounded FIFO map.
|
|
24
|
-
*
|
|
25
|
-
* #1896 / #1905: on a transient/quota dispatch error the reviewer fails over to
|
|
26
|
-
* a configured `fallback_models` entry via the shared `dispatchWithModelFallback`
|
|
27
|
-
* helper, instead of immediately writing a `verdict: 'error'` event (a quota
|
|
28
|
-
* blip previously dropped the review pass with no recovery). The SDK error
|
|
29
|
-
* envelope is preserved in the thrown message so the classifier sees the quota
|
|
30
|
-
* token on the dominant SDK error shape.
|
|
4
|
+
* Phase/plan review is owned by the phase_complete tool body so it can await a
|
|
5
|
+
* durable artifact before the evidence-only gate runs. This hook therefore owns
|
|
6
|
+
* only task-completion review, remains fire-and-forget, and delegates every
|
|
7
|
+
* model/diff/persistence decision to the shared review engine.
|
|
31
8
|
*/
|
|
32
9
|
import { type AutoReviewConfig } from '../config/schema.js';
|
|
33
|
-
import {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
export type ExecutionDiffResult = {
|
|
37
|
-
status: 'ok';
|
|
38
|
-
diff: string;
|
|
39
|
-
} | {
|
|
40
|
-
status: 'clean';
|
|
41
|
-
} | {
|
|
42
|
-
status: 'error';
|
|
43
|
-
reason: string;
|
|
44
|
-
};
|
|
45
|
-
/**
|
|
46
|
-
* Collect the execution diff for review: `git diff HEAD` (tracked changes)
|
|
47
|
-
* plus a porcelain summary of untracked files. Distinguishes a clean working
|
|
48
|
-
* tree from collection failures (git missing, timeout, diff exceeding the
|
|
49
|
-
* 2× maxBuffer cap) so events report honestly. Output is truncated to
|
|
50
|
-
* `maxBytes`.
|
|
51
|
-
*/
|
|
52
|
-
declare function computeExecutionDiff(directory: string, maxBytes: number): Promise<ExecutionDiffResult>;
|
|
53
|
-
declare function dispatchReviewer(directory: string, prompt: string, agentName: string, timeoutMs: number, parentSessionId: string, model?: ModelOverride): Promise<string>;
|
|
10
|
+
import type { ReviewModelDispatcher } from '../review/contracts.js';
|
|
11
|
+
import { type ReviewEngineResult, runReviewEngine } from '../review/engine.js';
|
|
12
|
+
import { type ReviewAgentModelRegistry } from '../review/runtime.js';
|
|
54
13
|
export interface AutoReviewRunInput {
|
|
55
14
|
directory: string;
|
|
56
15
|
sessionID: string;
|
|
57
|
-
trigger: 'task_completion'
|
|
16
|
+
trigger: 'task_completion';
|
|
58
17
|
taskId?: string;
|
|
59
|
-
|
|
60
|
-
|
|
18
|
+
config: AutoReviewConfig;
|
|
19
|
+
dispatcher?: ReviewModelDispatcher;
|
|
20
|
+
generatedAgentNames?: Iterable<string>;
|
|
21
|
+
activeAgentName?: string;
|
|
22
|
+
agentModelRegistry?: ReviewAgentModelRegistry;
|
|
61
23
|
injectAdvisory: (sessionId: string, message: string) => void;
|
|
62
24
|
}
|
|
63
|
-
|
|
64
|
-
* Execute one auto-review pass: collect diff → dispatch reviewer over an
|
|
65
|
-
* ephemeral session → persist receipt + event → advisory on REJECTED or
|
|
66
|
-
* unparseable output. Fully fail-open; never throws.
|
|
67
|
-
*/
|
|
68
|
-
export declare function runAutoReview(input: AutoReviewRunInput): Promise<void>;
|
|
25
|
+
export declare function runAutoReview(input: AutoReviewRunInput): Promise<ReviewEngineResult | undefined>;
|
|
69
26
|
export interface AutoReviewHookOptions {
|
|
70
27
|
config: AutoReviewConfig;
|
|
71
28
|
directory: string;
|
|
29
|
+
dispatcher?: ReviewModelDispatcher;
|
|
30
|
+
generatedAgentNames?: Iterable<string>;
|
|
31
|
+
agentModelRegistry?: ReviewAgentModelRegistry;
|
|
32
|
+
getActiveAgentName?: (sessionID: string) => string | undefined;
|
|
72
33
|
injectAdvisory: (sessionId: string, message: string) => void;
|
|
73
34
|
}
|
|
35
|
+
export interface AutoReviewToolAfterContext {
|
|
36
|
+
/**
|
|
37
|
+
* Arguments recovered from the callID snapshot. The OpenCode SDK's
|
|
38
|
+
* `tool.execute.after` output does not carry the original tool arguments.
|
|
39
|
+
*/
|
|
40
|
+
args: Record<string, unknown> | null;
|
|
41
|
+
}
|
|
74
42
|
export declare function createAutoReviewHook(options: AutoReviewHookOptions): {
|
|
75
43
|
toolAfter: (input: {
|
|
76
44
|
tool: string;
|
|
77
45
|
sessionID: string;
|
|
78
46
|
callID?: string;
|
|
79
|
-
},
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}) => Promise<void>;
|
|
47
|
+
}, context: AutoReviewToolAfterContext) => Promise<void>;
|
|
48
|
+
/** Instance-local test/lifecycle seam; never affects another plugin instance. */
|
|
49
|
+
resetTracking: () => void;
|
|
83
50
|
};
|
|
84
51
|
export declare const _internals: {
|
|
85
|
-
|
|
86
|
-
dispatchReviewer: typeof dispatchReviewer;
|
|
52
|
+
runReviewEngine: typeof runReviewEngine;
|
|
87
53
|
runAutoReview: typeof runAutoReview;
|
|
88
54
|
now: () => number;
|
|
89
55
|
};
|
|
90
|
-
export {};
|
|
@@ -268,7 +268,7 @@ interface MessageWithParts {
|
|
|
268
268
|
* approval. Does not throw — returns `false` for any failure (fail-closed).
|
|
269
269
|
*/
|
|
270
270
|
export declare function isPlanCriticApproved(directory: string): Promise<boolean>;
|
|
271
|
-
declare function resolveDelegatedPlanTaskId(args: Record<string, unknown>, knownPlanTaskIds?: ReadonlySet<string>): string | null;
|
|
271
|
+
export declare function resolveDelegatedPlanTaskId(args: Record<string, unknown>, knownPlanTaskIds?: ReadonlySet<string>): string | null;
|
|
272
272
|
/**
|
|
273
273
|
* Builds a cause-specific diagnostic for `prepareCoderScope`'s SCOPE_NOT_DECLARED
|
|
274
274
|
* throw when `resolveDelegatedPlanTaskId` returns null. Re-runs extraction with
|
|
@@ -37,6 +37,14 @@ export interface ToolBeforeContext {
|
|
|
37
37
|
* trusted roots when exempting `git worktree remove --force` (issue #1708).
|
|
38
38
|
*/
|
|
39
39
|
worktreeBaseDirOverrides?: string[];
|
|
40
|
+
/** Hold exact child-write provenance until the matching after-hook succeeds. */
|
|
41
|
+
rememberReviewerScopeWrite?: (input: {
|
|
42
|
+
callID: string;
|
|
43
|
+
parentSessionID: string;
|
|
44
|
+
taskId: string;
|
|
45
|
+
coderCallID: string;
|
|
46
|
+
file: string;
|
|
47
|
+
}) => void;
|
|
40
48
|
}
|
|
41
49
|
/**
|
|
42
50
|
* Creates a toolBefore handler with the given shared context.
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Parses the mandated reviewer OUTPUT FORMAT (`VERDICT:` / `RISK:` /
|
|
5
5
|
* `ISSUES:` / `FIXES:`) from a returning reviewer Task delegation and
|
|
6
6
|
* persists it as a durable review receipt under `.swarm/review-receipts/`
|
|
7
|
-
* via the existing receipt store
|
|
8
|
-
*
|
|
7
|
+
* via the existing receipt store. Scope is derived from guardrails-observed
|
|
8
|
+
* modified files and their current content, never architect-authored prose.
|
|
9
9
|
*
|
|
10
10
|
* Before this collector, reviewer verdicts existed only as free text inside
|
|
11
11
|
* the architect's context — re-reviews and drift verification had no durable
|
|
@@ -15,7 +15,14 @@
|
|
|
15
15
|
*
|
|
16
16
|
* Fail-open: parsing or persistence failures never block tool execution.
|
|
17
17
|
*/
|
|
18
|
-
|
|
18
|
+
import { type ReviewFinding } from '../agents/agent-output-schema.js';
|
|
19
|
+
import { type AutoReviewConfig } from '../config/schema.js';
|
|
20
|
+
import type { ReviewModelDispatcher } from '../review/contracts.js';
|
|
21
|
+
import { type FindingValidationScheduler } from '../review/finding-validator.js';
|
|
22
|
+
import { type ReviewAgentModelRegistry } from '../review/runtime.js';
|
|
23
|
+
import { persistReviewReceipt, type ReviewFindingSeverity, updateReviewReceiptValidations } from './review-receipt.js';
|
|
24
|
+
import { buildReviewerTaskScope, resolveReviewerTaskScope } from './review-receipt-scope.js';
|
|
25
|
+
export type ParsedReviewSeverity = ReviewFindingSeverity;
|
|
19
26
|
export interface ParsedReviewIssue {
|
|
20
27
|
/** Raw issue line (trimmed, bullet stripped) */
|
|
21
28
|
text: string;
|
|
@@ -23,6 +30,8 @@ export interface ParsedReviewIssue {
|
|
|
23
30
|
severity: ParsedReviewSeverity;
|
|
24
31
|
/** `path:line` reference when one appears in the line */
|
|
25
32
|
location?: string;
|
|
33
|
+
/** Machine-readable source finding, when structured output parsed. */
|
|
34
|
+
finding?: ReviewFinding;
|
|
26
35
|
}
|
|
27
36
|
export interface ParsedReviewerOutput {
|
|
28
37
|
verdict: 'approved' | 'rejected';
|
|
@@ -32,30 +41,64 @@ export interface ParsedReviewerOutput {
|
|
|
32
41
|
issues: ParsedReviewIssue[];
|
|
33
42
|
/** Required-change lines from the FIXES section */
|
|
34
43
|
fixes: string[];
|
|
44
|
+
outputMode: 'structured' | 'legacy';
|
|
45
|
+
overallConfidence?: number;
|
|
46
|
+
structuredFindings?: ReviewFinding[];
|
|
35
47
|
}
|
|
36
48
|
/**
|
|
37
49
|
* Parse the reviewer agent's mandated output block. Returns null when no
|
|
38
|
-
* unambiguous line-anchored `VERDICT: APPROVED|REJECTED` is present
|
|
39
|
-
* including
|
|
40
|
-
*
|
|
50
|
+
* single unambiguous line-anchored `VERDICT: APPROVED|REJECTED` is present,
|
|
51
|
+
* including missing, duplicate, or contradictory verdict lines. A structured
|
|
52
|
+
* verdict must match that single legacy line so ambiguous output fails toward
|
|
53
|
+
* "no machine-readable verdict", never toward approval.
|
|
41
54
|
*/
|
|
42
|
-
export declare function parseReviewerOutput(text: string
|
|
55
|
+
export declare function parseReviewerOutput(text: string, options?: {
|
|
56
|
+
structured?: boolean;
|
|
57
|
+
}): ParsedReviewerOutput | null;
|
|
43
58
|
export interface ReviewerReceiptInput {
|
|
44
59
|
tool: unknown;
|
|
45
60
|
args?: unknown;
|
|
46
61
|
sessionID?: unknown;
|
|
62
|
+
callID?: unknown;
|
|
47
63
|
}
|
|
48
64
|
export interface ReviewerReceiptOutput {
|
|
49
65
|
output?: unknown;
|
|
66
|
+
state?: unknown;
|
|
67
|
+
status?: unknown;
|
|
68
|
+
error?: unknown;
|
|
69
|
+
errors?: unknown;
|
|
70
|
+
metadata?: unknown;
|
|
71
|
+
result?: unknown;
|
|
50
72
|
}
|
|
51
73
|
export interface ReviewerReceiptTranscriptInput {
|
|
52
74
|
targetAgent?: string;
|
|
53
|
-
prompt
|
|
75
|
+
prompt?: string;
|
|
54
76
|
transcript: string;
|
|
55
77
|
sessionID?: string;
|
|
56
78
|
sessionId?: string;
|
|
79
|
+
taskId?: string;
|
|
80
|
+
reviewerCallID?: string;
|
|
81
|
+
/** Production collectors consume the exact claimed coder generation. */
|
|
82
|
+
consumeHandoff?: boolean;
|
|
57
83
|
}
|
|
58
|
-
export
|
|
84
|
+
export interface ReviewerReceiptValidationOptions {
|
|
85
|
+
dispatcher?: ReviewModelDispatcher;
|
|
86
|
+
config?: AutoReviewConfig;
|
|
87
|
+
generatedAgentNames?: Iterable<string>;
|
|
88
|
+
agentModelRegistry?: ReviewAgentModelRegistry;
|
|
89
|
+
injectAdvisory?: (sessionID: string, message: string) => void;
|
|
90
|
+
/** Shared only within the owning plugin instance. */
|
|
91
|
+
validationScheduler?: FindingValidationScheduler;
|
|
92
|
+
}
|
|
93
|
+
/** Test seam for the otherwise process-global telemetry sink. */
|
|
94
|
+
export declare const _internals: {
|
|
95
|
+
delegationEnd: (sessionId: string, agentName: string, taskId: string, result: string, costFields?: Partial<import("../services/cost-accounting.js").DelegationCostFields>) => void;
|
|
96
|
+
resolveReviewerTaskScope: typeof resolveReviewerTaskScope;
|
|
97
|
+
buildReviewerTaskScope: typeof buildReviewerTaskScope;
|
|
98
|
+
persistReviewReceipt: typeof persistReviewReceipt;
|
|
99
|
+
updateReviewReceiptValidations: typeof updateReviewReceiptValidations;
|
|
100
|
+
};
|
|
101
|
+
export declare function collectReviewerReceiptFromTranscript(directory: string, input: ReviewerReceiptTranscriptInput, validationOptions?: ReviewerReceiptValidationOptions): Promise<string | null>;
|
|
59
102
|
/**
|
|
60
103
|
* `tool.execute.after` collector. When a reviewer Task returns, parse its
|
|
61
104
|
* verdict block and persist a durable review receipt. No-op for non-reviewer
|
|
@@ -63,4 +106,4 @@ export declare function collectReviewerReceiptFromTranscript(directory: string,
|
|
|
63
106
|
*
|
|
64
107
|
* Returns the persisted receipt path (for tests/telemetry) or null.
|
|
65
108
|
*/
|
|
66
|
-
export declare function collectReviewerReceiptAfter(directory: string, input: ReviewerReceiptInput, output: ReviewerReceiptOutput): Promise<string | null>;
|
|
109
|
+
export declare function collectReviewerReceiptAfter(directory: string, input: ReviewerReceiptInput, output: ReviewerReceiptOutput, validationOptions?: ReviewerReceiptValidationOptions): Promise<string | null>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical scope construction for Stage-B reviewer receipts.
|
|
3
|
+
*
|
|
4
|
+
* The architect-authored reviewer prompt is not authoritative scope: it can
|
|
5
|
+
* omit files that the coder actually changed. Guardrails records every
|
|
6
|
+
* write-tool target in `modifiedFilesThisCoderTask`, so receipts fingerprint a
|
|
7
|
+
* bounded manifest of repository HEAD, those paths, and their current byte
|
|
8
|
+
* content instead. A base change therefore invalidates the receipt even when
|
|
9
|
+
* the working-file bytes happen to remain identical.
|
|
10
|
+
*
|
|
11
|
+
* Any missing session state, unsafe path, symlink/reparse point, concurrent
|
|
12
|
+
* mutation, or size overflow fails toward no receipt. A durable receipt must
|
|
13
|
+
* never claim a scope the harness could not reconstruct exactly.
|
|
14
|
+
*/
|
|
15
|
+
import * as child_process from 'node:child_process';
|
|
16
|
+
import * as fs from 'node:fs';
|
|
17
|
+
export declare const REVIEWER_TASK_SCOPE_DESCRIPTION = "reviewer-task-files-v1";
|
|
18
|
+
export interface ReviewerTaskScope {
|
|
19
|
+
content: string;
|
|
20
|
+
description: typeof REVIEWER_TASK_SCOPE_DESCRIPTION;
|
|
21
|
+
files: string[];
|
|
22
|
+
headSha: string;
|
|
23
|
+
taskId?: string;
|
|
24
|
+
coderCallID?: string;
|
|
25
|
+
generation?: number;
|
|
26
|
+
sessionIncarnation?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface ReviewerTaskScopeProvenance {
|
|
29
|
+
taskId: string;
|
|
30
|
+
coderCallID: string;
|
|
31
|
+
generation: number;
|
|
32
|
+
sessionIncarnation: string;
|
|
33
|
+
}
|
|
34
|
+
export interface ResolveReviewerTaskScopeOptions {
|
|
35
|
+
/** Consume the completed coder's one-shot scope instead of the live list. */
|
|
36
|
+
consumeHandoff?: boolean;
|
|
37
|
+
/** Exact task expected by the returning reviewer/background record. */
|
|
38
|
+
expectedTaskId?: string;
|
|
39
|
+
/** Exact reviewer Task call that claimed the generation. */
|
|
40
|
+
reviewerCallID?: string;
|
|
41
|
+
/** Injectable clock used only for deterministic expiry tests. */
|
|
42
|
+
now?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Resolve the exact known plan task carried by reviewer/coder Task arguments.
|
|
46
|
+
*
|
|
47
|
+
* This deliberately reuses delegation-gate's canonical extractor so lifecycle
|
|
48
|
+
* identity cannot drift from scope authorization. It checks all supported Task
|
|
49
|
+
* text fields, prefers an unambiguous TASK line, rejects ambiguity, and filters
|
|
50
|
+
* numeric-dot tokens against the current plan.
|
|
51
|
+
*/
|
|
52
|
+
export declare function resolveReviewerScopeTaskId(directory: string, args: unknown): Promise<string | null>;
|
|
53
|
+
/**
|
|
54
|
+
* Test-only dependency-injection seam. Keeping the spawn binding local avoids
|
|
55
|
+
* process-global `mock.module()` pollution while allowing tests to prove that
|
|
56
|
+
* the production call really creates a child with ignored stdin.
|
|
57
|
+
*/
|
|
58
|
+
export declare const _internals: {
|
|
59
|
+
spawn: typeof child_process.spawn;
|
|
60
|
+
realpath: typeof fs.promises.realpath;
|
|
61
|
+
lstatBigInt: (path: fs.PathLike) => Promise<fs.BigIntStats>;
|
|
62
|
+
open: typeof fs.promises.open;
|
|
63
|
+
fileHandleStatBigInt: (handle: fs.promises.FileHandle) => Promise<fs.BigIntStats>;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Build the exact scope fingerprint input for a guardrails-observed file list.
|
|
67
|
+
*/
|
|
68
|
+
export declare function buildReviewerTaskScope(directory: string, modifiedFiles: readonly string[], maxBytes?: number, provenance?: ReviewerTaskScopeProvenance): Promise<ReviewerTaskScope | null>;
|
|
69
|
+
/**
|
|
70
|
+
* Resolve scope only from the architect session's guardrails-owned task state.
|
|
71
|
+
* Receipt collection consumes the completed coder handoff exactly once; direct
|
|
72
|
+
* callers retain the legacy live-list view for diagnostics and drift probes.
|
|
73
|
+
*/
|
|
74
|
+
export declare function resolveReviewerTaskScope(directory: string, sessionID: string, maxBytes?: number, options?: ResolveReviewerTaskScopeOptions): Promise<ReviewerTaskScope | null>;
|