opencode-swarm 7.144.2 → 7.144.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.opencode/skills/swarm-pr-review/SKILL.md +3 -1
- package/.opencode/skills/swarm-pr-review/references/lane-output-recoverability.md +124 -0
- package/.opencode/skills/swarm-pr-review/references/prompt-templates.md +2 -0
- package/README.md +3 -1
- package/dist/background/pending-delegations.d.ts +34 -0
- package/dist/cli/{config-doctor-7dfvxwjb.js → config-doctor-rw9zrjk6.js} +3 -3
- package/dist/cli/{core-dwmwdc4y.js → core-zjx9aqaf.js} +3 -3
- package/dist/cli/{curation-policy-pkb2eeb1.js → curation-policy-0wbrh11c.js} +5 -5
- package/dist/cli/curator-drift-2jbjv03a.js +1 -1
- package/dist/cli/{curator-w213v33y.js → curator-g54a7wv0.js} +33 -33
- package/dist/cli/{curator-llm-factory-rrs1q4hg.js → curator-llm-factory-xgb4pxmm.js} +33 -33
- package/dist/cli/{evidence-summary-service-t7n2h1he.js → evidence-summary-service-fnr5y54e.js} +14 -14
- package/dist/cli/{gate-evidence-xvxn603y.js → gate-evidence-2xt1x07r.js} +7 -7
- package/dist/cli/{guardrail-explain-v1mwsnkq.js → guardrail-explain-6wcgr9tz.js} +34 -34
- package/dist/cli/{guardrail-log-dn03dpz2.js → guardrail-log-5w4b9zrw.js} +4 -4
- package/dist/cli/{hive-promoter-asjtj7ga.js → hive-promoter-x63ehffd.js} +35 -35
- package/dist/cli/{index-ckrasab9.js → index-03pv47h2.js} +9 -9
- package/dist/cli/{index-4q9vfav6.js → index-1csyxv0f.js} +1 -1
- package/dist/cli/{index-s2rcz51a.js → index-1jsmmx7y.js} +66 -34
- package/dist/cli/{index-jsfghpy2.js → index-2m7mavaz.js} +2 -2
- package/dist/cli/{index-p3tnmkvc.js → index-4w5qdbk7.js} +12 -12
- package/dist/cli/{index-dhh2j2nd.js → index-8j0va7jp.js} +2 -2
- package/dist/cli/{index-y95nwsge.js → index-9qq7c18c.js} +1 -1
- package/dist/cli/{index-qpt8ahph.js → index-az8etqpp.js} +12 -12
- package/dist/cli/{index-gdd4jt6b.js → index-bt9aa01f.js} +1 -1
- package/dist/cli/{index-333kvewd.js → index-btmsqv7p.js} +4 -4
- package/dist/cli/{index-d55crzd4.js → index-cz25e8xp.js} +7 -7
- package/dist/cli/{index-g2ajae1z.js → index-d12jd5mn.js} +2 -2
- package/dist/cli/{index-tq5s07ta.js → index-dty5qgk2.js} +1 -1
- package/dist/cli/{index-k31en0ja.js → index-f9vvg5xb.js} +3 -3
- package/dist/cli/{index-k92cagmt.js → index-fqcjragy.js} +2 -2
- package/dist/cli/{index-jb4tchvy.js → index-h98t1m88.js} +2 -2
- package/dist/cli/{index-4fda8kkw.js → index-jabkn643.js} +30 -5
- package/dist/cli/{index-erfnw81g.js → index-mazgg5s2.js} +1 -1
- package/dist/cli/{index-m6wv2qdr.js → index-nckg4gxb.js} +2 -2
- package/dist/cli/{index-tg9fn2dy.js → index-p7cm3gtj.js} +38 -36
- package/dist/cli/{index-dg2w0wr4.js → index-psvxq93b.js} +3 -3
- package/dist/cli/{index-zr370283.js → index-pw83zgny.js} +3 -3
- package/dist/cli/{index-nretd4qn.js → index-q4ed1jk7.js} +1539 -963
- package/dist/cli/{index-hqvt3mhk.js → index-q67jb94n.js} +1 -1
- package/dist/cli/{index-whezv7vc.js → index-v3y3qg48.js} +1 -1
- package/dist/cli/{index-av0f6mm0.js → index-x6tp0hfr.js} +9 -9
- package/dist/cli/{index-h3z64mhz.js → index-y8j8ehc8.js} +2 -2
- package/dist/cli/{index-ne8cfgw5.js → index-yts89pqg.js} +4 -4
- package/dist/cli/{index-w7x7qxz2.js → index-ywn7vtxp.js} +1 -1
- package/dist/cli/{index-g1c5fgaw.js → index-z6v7kwpa.js} +4 -4
- package/dist/cli/{index-7ca3a6gj.js → index-zb0xcz9t.js} +10 -10
- package/dist/cli/index.js +34 -34
- package/dist/cli/{knowledge-escalator-cg19dhe5.js → knowledge-escalator-ypg14d5r.js} +13 -13
- package/dist/cli/{knowledge-events-yzvysaqd.js → knowledge-events-nkrym4wb.js} +11 -11
- package/dist/cli/{knowledge-link-fn5j3r4q.js → knowledge-link-e4qgqmpx.js} +4 -4
- package/dist/cli/{knowledge-store-6f77xpmm.js → knowledge-store-vh3nhtg2.js} +6 -6
- package/dist/cli/{knowledge-validator-4b28zdxa.js → knowledge-validator-jrxvexv6.js} +8 -8
- package/dist/cli/{pending-delegations-thy8g30k.js → pending-delegations-pw79c8ds.js} +3 -3
- package/dist/cli/{pr-subscriptions-jyav582d.js → pr-subscriptions-fk628bhc.js} +3 -3
- package/dist/cli/{runner-pde6b5sx.js → runner-b02sz2vx.js} +5 -5
- package/dist/cli/{scan-cursor-nqbb1xt6.js → scan-cursor-fp7w5jmc.js} +7 -7
- package/dist/cli/{schema-jj2pb6zp.js → schema-rptwqbm4.js} +2 -2
- package/dist/cli/{scope-persistence-63nasq0z.js → scope-persistence-0bkaxawa.js} +7 -7
- package/dist/cli/{skill-generator-nsymtdqm.js → skill-generator-nh8b4gjv.js} +16 -16
- package/dist/cli/{telemetry-xyfb5vm8.js → telemetry-cybx6cfz.js} +1 -1
- package/dist/cli/{worktree-collision-ownership-j6d33p49.js → worktree-collision-ownership-hqd9ypsz.js} +6 -6
- package/dist/cli/{worktree-isolation-g54kxw6x.js → worktree-isolation-canf3rj8.js} +33 -33
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/recover.d.ts +17 -0
- package/dist/commands/registry.d.ts +10 -2
- package/dist/commands/reset-session.d.ts +2 -0
- package/dist/hooks/context-budget.d.ts +4 -0
- package/dist/hooks/context-usage.d.ts +48 -0
- package/dist/hooks/pr-workflow-gate.d.ts +160 -4
- package/dist/index.js +556 -550
- package/dist/observability/catalog.d.ts +8 -6
- package/dist/sast/semgrep.d.ts +3 -2
- package/dist/telemetry.d.ts +17 -1
- package/dist/tools/context-status.d.ts +9 -3
- package/dist/tools/dispatch-lanes.d.ts +27 -2
- package/dist/tools/pre-check-batch.d.ts +9 -0
- package/dist/tools/sast-scan.d.ts +3 -0
- package/dist/workflow/coder-settlement.d.ts +74 -0
- package/package.json +1 -1
|
@@ -20,60 +20,60 @@ import {
|
|
|
20
20
|
sanitizeWorktreeTaskId,
|
|
21
21
|
standardWorktreeByCallID,
|
|
22
22
|
standardWorktreeSerializationSessions
|
|
23
|
-
} from "./index-
|
|
24
|
-
import"./index-
|
|
25
|
-
import"./index-
|
|
26
|
-
import"./index-
|
|
23
|
+
} from "./index-q4ed1jk7.js";
|
|
24
|
+
import"./index-d12jd5mn.js";
|
|
25
|
+
import"./index-h98t1m88.js";
|
|
26
|
+
import"./index-az8etqpp.js";
|
|
27
27
|
import"./index-134d35c1.js";
|
|
28
28
|
import"./index-b6e016tv.js";
|
|
29
|
-
import"./index-
|
|
30
|
-
import"./index-
|
|
29
|
+
import"./index-1csyxv0f.js";
|
|
30
|
+
import"./index-fqcjragy.js";
|
|
31
31
|
import"./index-y8552snf.js";
|
|
32
|
-
import"./index-
|
|
32
|
+
import"./index-nckg4gxb.js";
|
|
33
33
|
import"./index-70ha9e09.js";
|
|
34
34
|
import"./index-c8s9a3zh.js";
|
|
35
35
|
import"./index-9ss2m4rs.js";
|
|
36
|
-
import"./index-d55crzd4.js";
|
|
37
36
|
import"./index-74hpm6sh.js";
|
|
38
|
-
import"./index-
|
|
39
|
-
import"./index-
|
|
40
|
-
import"./index-
|
|
41
|
-
import"./index-
|
|
42
|
-
import"./index-
|
|
43
|
-
import"./index-
|
|
37
|
+
import"./index-bt9aa01f.js";
|
|
38
|
+
import"./index-zb0xcz9t.js";
|
|
39
|
+
import"./index-x6tp0hfr.js";
|
|
40
|
+
import"./index-yts89pqg.js";
|
|
41
|
+
import"./index-dty5qgk2.js";
|
|
42
|
+
import"./index-rtry5xyf.js";
|
|
44
43
|
import"./index-zsrtt42s.js";
|
|
44
|
+
import"./index-jabkn643.js";
|
|
45
45
|
import"./index-k3cxyk66.js";
|
|
46
|
-
import"./index-
|
|
47
|
-
import"./index-
|
|
48
|
-
import"./index-
|
|
49
|
-
import"./index-
|
|
46
|
+
import"./index-cz25e8xp.js";
|
|
47
|
+
import"./index-8j0va7jp.js";
|
|
48
|
+
import"./index-pw83zgny.js";
|
|
49
|
+
import"./index-z6v7kwpa.js";
|
|
50
|
+
import"./index-556ja8an.js";
|
|
50
51
|
import"./index-7sy3aa9m.js";
|
|
51
52
|
import"./index-wx8zdh4a.js";
|
|
52
|
-
import"./index-
|
|
53
|
+
import"./index-8fwhhayc.js";
|
|
54
|
+
import"./index-q1exe2b3.js";
|
|
55
|
+
import"./index-03pv47h2.js";
|
|
56
|
+
import"./index-4w5qdbk7.js";
|
|
53
57
|
import {
|
|
54
58
|
resolveWorktreeIsolationConfig
|
|
55
|
-
} from "./index-
|
|
59
|
+
} from "./index-psvxq93b.js";
|
|
56
60
|
import"./index-gprxjmm7.js";
|
|
57
61
|
import"./index-n832052r.js";
|
|
58
|
-
import"./index-y95nwsge.js";
|
|
59
|
-
import"./index-h3z64mhz.js";
|
|
60
62
|
import"./index-rn0eq85g.js";
|
|
61
|
-
import"./index-4rhhvd1a.js";
|
|
62
|
-
import"./index-whezv7vc.js";
|
|
63
63
|
import"./index-z6xqpmqg.js";
|
|
64
|
+
import"./index-9qq7c18c.js";
|
|
65
|
+
import"./index-y8j8ehc8.js";
|
|
66
|
+
import"./index-4rhhvd1a.js";
|
|
67
|
+
import"./index-v3y3qg48.js";
|
|
64
68
|
import"./index-zjygnfay.js";
|
|
65
|
-
import"./index-ne8cfgw5.js";
|
|
66
|
-
import"./index-tq5s07ta.js";
|
|
67
|
-
import"./index-rtry5xyf.js";
|
|
68
|
-
import"./index-ckrasab9.js";
|
|
69
69
|
import"./index-ae75rja9.js";
|
|
70
|
-
import"./index-
|
|
71
|
-
import"./index-
|
|
72
|
-
import"./index-bk5tah7q.js";
|
|
70
|
+
import"./index-ywn7vtxp.js";
|
|
71
|
+
import"./index-mazgg5s2.js";
|
|
73
72
|
import"./index-ed5ykebp.js";
|
|
74
|
-
import"./index-
|
|
73
|
+
import"./index-bk5tah7q.js";
|
|
74
|
+
import"./index-f9vvg5xb.js";
|
|
75
|
+
import"./index-1jsmmx7y.js";
|
|
75
76
|
import"./index-7g4c7s5r.js";
|
|
76
|
-
import"./index-s2rcz51a.js";
|
|
77
77
|
import"./index-bpmtbmy9.js";
|
|
78
78
|
import"./index-4nt52yr9.js";
|
|
79
79
|
import"./index-zgwm4ryv.js";
|
package/dist/commands/index.d.ts
CHANGED
|
@@ -46,6 +46,7 @@ export { handlePlanCommand } from './plan';
|
|
|
46
46
|
export { handlePreflightCommand } from './preflight';
|
|
47
47
|
export { handlePromoteCommand } from './promote';
|
|
48
48
|
export { handleQaGatesCommand } from './qa-gates';
|
|
49
|
+
export { handleRecoverCommand } from './recover';
|
|
49
50
|
export { handleHelpCommand } from './registry';
|
|
50
51
|
export type { CommandContext, CommandEntry, RegisteredCommand, } from './registry.js';
|
|
51
52
|
export { COMMAND_REGISTRY, resolveCommand, VALID_COMMANDS, } from './registry.js';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handles the /swarm recover command (issue #2268).
|
|
3
|
+
*
|
|
4
|
+
* The user-facing invoker for coder-settlement recovery. The wedge class this
|
|
5
|
+
* exists for: a DISPATCHED settlement WAL whose completion (toolAfter) never
|
|
6
|
+
* arrived — every dispatch retry is refused with CODER_SETTLEMENT_IN_PROGRESS
|
|
7
|
+
* / CODER_DISPATCH_IN_PROGRESS and internal sinks (update_task_status, /swarm
|
|
8
|
+
* close) are paused too. Safe mode recovers settlements whose owning process
|
|
9
|
+
* is gone; --force additionally releases ownership keys still held by THIS
|
|
10
|
+
* process (an operator assertion that no dispatch is genuinely in flight —
|
|
11
|
+
* a still-running dispatch's late completion will then fail settlement with
|
|
12
|
+
* CODER_SETTLEMENT_IDEMPOTENCY_CONFLICT, which is safe to ignore).
|
|
13
|
+
*
|
|
14
|
+
* Human-only by policy: agents already self-heal dead-owner settlements via
|
|
15
|
+
* update_task_status, and --force must stay an operator decision.
|
|
16
|
+
*/
|
|
17
|
+
export declare function handleRecoverCommand(directory: string, args: string[]): Promise<string>;
|
|
@@ -619,7 +619,7 @@ export declare const COMMAND_REGISTRY: {
|
|
|
619
619
|
readonly handler: (ctx: CommandContext) => Promise<string>;
|
|
620
620
|
readonly description: "Clear a stuck PR_REVIEW/PR_FEEDBACK mechanical gate and stop the auto-resume loop [mode] [reason]";
|
|
621
621
|
readonly args: "[PR_REVIEW|PR_FEEDBACK] [reason...]";
|
|
622
|
-
readonly details: "Human-only escape hatch for an unrecoverable PR_REVIEW or PR_FEEDBACK mechanical gate. When the architect cannot reach complete_pr_workflow — for example a compound `git fetch && git checkout` was rejected as read-only shell syntax, the PR head cannot be fetched, or the working tree is on the wrong branch — running this clears the durable gate state for the current session and stops the auto-resume loop without depending on the trapped model. The agent itself cannot run this command; it must call the abort_pr_workflow tool (or ask you to run this command). Both paths funnel into the same fail-closed abortPrWorkflow hook, which refuses while the workflow is armed for publication or while PR workflow lanes are still in flight. When checkout preparation preserved a stash, the result instructs the caller to run prepare_pr_workflow_checkout operation=restore after the clear. An audit event is appended to .swarm/events.jsonl.";
|
|
622
|
+
readonly details: "Human-only escape hatch for an unrecoverable PR_REVIEW or PR_FEEDBACK mechanical gate. When the architect cannot reach complete_pr_workflow — for example a compound `git fetch && git checkout` was rejected as read-only shell syntax, the PR head cannot be fetched, or the working tree is on the wrong branch — running this clears the durable gate state for the current session and stops the auto-resume loop without depending on the trapped model. The agent itself cannot run this command; it must call the abort_pr_workflow tool (or ask you to run this command). Both paths funnel into the same fail-closed abortPrWorkflow hook, which refuses while the workflow is armed for publication or while PR workflow lanes are still in flight. This human-only force path has exactly one exception to that second refusal (issue #2251): when the ONLY lanes still blocking are ones past the 30-minute staleness horizon that the liveness probe reports as still running — a lane nothing will ever settle on a schedule — it clears the gate anyway, names exactly which lanes it overrode, and finalizes their delegation records so the session can start a new PR workflow. Those sessions are NOT stopped and their output is NOT collected. A lane with a fresh updatedAt still blocks even under force, and any delegation record that still keeps the session blocked is named in the warning. When checkout preparation preserved a stash, the result instructs the caller to run prepare_pr_workflow_checkout operation=restore after the clear. An audit event is appended to .swarm/events.jsonl.";
|
|
623
623
|
readonly category: "utility";
|
|
624
624
|
readonly toolPolicy: "restricted";
|
|
625
625
|
};
|
|
@@ -825,11 +825,19 @@ export declare const COMMAND_REGISTRY: {
|
|
|
825
825
|
readonly 'reset-session': {
|
|
826
826
|
readonly handler: (ctx: CommandContext) => Promise<string>;
|
|
827
827
|
readonly description: "Clear session state while preserving plan, evidence, and knowledge";
|
|
828
|
-
readonly details: "Deletes only .swarm/session/state.json and any other session files. Clears in-memory agent sessions, delegation chains, and active-agent mappings. Preserves plan, evidence, and knowledge for cross-session continuity. Before deleting, auto-backs up the session files it removes to .swarm/reset-backups/<timestamp>/ (newest 5 kept).";
|
|
828
|
+
readonly details: "Deletes only .swarm/session/state.json and any other session files. Clears in-memory agent sessions, delegation chains, and active-agent mappings. Preserves plan, evidence, and knowledge for cross-session continuity. Also recovers stale coder settlements, releasing in-flight ownership held by this process, so dispatches cannot stay wedged on CODER_DISPATCH_IN_PROGRESS (issue #2268). Before deleting, auto-backs up the session files it removes to .swarm/reset-backups/<timestamp>/ (newest 5 kept).";
|
|
829
829
|
readonly args: "";
|
|
830
830
|
readonly category: "utility";
|
|
831
831
|
readonly toolPolicy: "restricted";
|
|
832
832
|
};
|
|
833
|
+
readonly recover: {
|
|
834
|
+
readonly handler: (ctx: CommandContext) => Promise<string>;
|
|
835
|
+
readonly description: "Recover wedged coder settlements [task_id] [--force]";
|
|
836
|
+
readonly details: "Settles stale coder-settlement WALs in .swarm/coder-settlements/ — the CODER_DISPATCH_IN_PROGRESS wedge where a dispatch's completion never fired (issue #2268). Safe mode recovers settlements whose owner process is gone. --force also releases ownership keys held by this process: use only when no dispatch is genuinely running (a late completion then reports CODER_SETTLEMENT_IDEMPOTENCY_CONFLICT, safe to ignore). Never interrupts another live OpenCode process. Human-only.";
|
|
837
|
+
readonly args: "[task_id] [--force]";
|
|
838
|
+
readonly category: "utility";
|
|
839
|
+
readonly toolPolicy: "human-only";
|
|
840
|
+
};
|
|
833
841
|
readonly rollback: {
|
|
834
842
|
readonly handler: (ctx: CommandContext) => Promise<string>;
|
|
835
843
|
readonly description: "Restore swarm state or project files to a checkpoint";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { recoverStaleCoderSettlements } from '../workflow/coder-settlement.js';
|
|
1
2
|
import { type OrphanCleanupResult } from '../worktree/merge';
|
|
2
3
|
import { type ResetBackupResult } from './reset-backup';
|
|
3
4
|
/**
|
|
@@ -9,6 +10,7 @@ import { type ResetBackupResult } from './reset-backup';
|
|
|
9
10
|
export declare const _internals: {
|
|
10
11
|
cleanupOrphanedBranches: (directory: string, activeSessionIds: string[]) => Promise<OrphanCleanupResult>;
|
|
11
12
|
backupSwarmStateBeforeReset: (directory: string, kind: 'reset' | 'reset-session', relEntries: string[]) => ResetBackupResult;
|
|
13
|
+
recoverStaleCoderSettlements: typeof recoverStaleCoderSettlements;
|
|
12
14
|
};
|
|
13
15
|
/**
|
|
14
16
|
* Handles the /swarm reset-session command.
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* to provide proactive context management guidance to the architect agent.
|
|
7
7
|
*/
|
|
8
8
|
import type { PluginConfig } from '../config';
|
|
9
|
+
import { telemetry } from '../telemetry';
|
|
9
10
|
interface MessageInfo {
|
|
10
11
|
role: string;
|
|
11
12
|
agent?: string;
|
|
@@ -31,6 +32,9 @@ interface MessageWithParts {
|
|
|
31
32
|
info: MessageInfo;
|
|
32
33
|
parts: MessagePart[];
|
|
33
34
|
}
|
|
35
|
+
export declare const _internals: {
|
|
36
|
+
telemetryContextPruned: typeof telemetry.contextPruned;
|
|
37
|
+
};
|
|
34
38
|
/**
|
|
35
39
|
* Creates the experimental.chat.messages.transform hook for context budget tracking.
|
|
36
40
|
* Injects warnings when context usage exceeds configured thresholds.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export interface ContextUsageMessageInfo {
|
|
2
|
+
role?: string;
|
|
3
|
+
tokens?: {
|
|
4
|
+
input?: unknown;
|
|
5
|
+
cache?: {
|
|
6
|
+
read?: unknown;
|
|
7
|
+
write?: unknown;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
export interface ContextUsageMessagePart {
|
|
13
|
+
type?: string;
|
|
14
|
+
text?: string;
|
|
15
|
+
state?: {
|
|
16
|
+
status?: string;
|
|
17
|
+
input?: unknown;
|
|
18
|
+
output?: string;
|
|
19
|
+
error?: string;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
};
|
|
22
|
+
[key: string]: unknown;
|
|
23
|
+
}
|
|
24
|
+
export interface ContextUsageMessage {
|
|
25
|
+
info?: ContextUsageMessageInfo;
|
|
26
|
+
parts?: ContextUsageMessagePart[];
|
|
27
|
+
}
|
|
28
|
+
export type ContextUsageSource = 'provider' | 'estimated';
|
|
29
|
+
export interface ContextUsageResult {
|
|
30
|
+
tokensUsed: number;
|
|
31
|
+
source: ContextUsageSource;
|
|
32
|
+
assistantAnchorIndex: number | null;
|
|
33
|
+
}
|
|
34
|
+
export declare function serializeToolInput(input: unknown): string;
|
|
35
|
+
export declare function estimateToolInputTokens(input: unknown): number;
|
|
36
|
+
export declare function getVisibleToolPartText(part: ContextUsageMessagePart): string;
|
|
37
|
+
export declare function estimateVisibleToolPartTokens(part: ContextUsageMessagePart): number;
|
|
38
|
+
export declare function estimateMessageTokens(message: ContextUsageMessage): number;
|
|
39
|
+
export declare function readProviderPromptTokens(message: ContextUsageMessage | undefined): number | undefined;
|
|
40
|
+
export declare function computeContextUsage(messages: ContextUsageMessage[] | undefined): ContextUsageResult;
|
|
41
|
+
export declare const _test_exports: {
|
|
42
|
+
computeContextUsage: typeof computeContextUsage;
|
|
43
|
+
estimateToolInputTokens: typeof estimateToolInputTokens;
|
|
44
|
+
estimateVisibleToolPartTokens: typeof estimateVisibleToolPartTokens;
|
|
45
|
+
estimateMessageTokens: typeof estimateMessageTokens;
|
|
46
|
+
readProviderPromptTokens: typeof readProviderPromptTokens;
|
|
47
|
+
serializeToolInput: typeof serializeToolInput;
|
|
48
|
+
};
|
|
@@ -2,7 +2,7 @@ import * as fsp from 'node:fs/promises';
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { type CandidateSeverity, type RowFormatFamily } from '../background/candidate-contract.js';
|
|
4
4
|
import { type LaneOutputArtifact } from '../background/lane-output-store.js';
|
|
5
|
-
import { type BackgroundDelegationRecord, type BackgroundDelegationResult, findByBatchId } from '../background/pending-delegations.js';
|
|
5
|
+
import { type BackgroundDelegationRecord, type BackgroundDelegationResult, type BackgroundDelegationWorkflowLaneRecovery, findByBatchId, sweepStaleDelegations } from '../background/pending-delegations.js';
|
|
6
6
|
import { type PrReviewInlineTriggerRow } from '../background/pr-review-trigger-contract.js';
|
|
7
7
|
import { type RevisionDigestResult, resolveCommitCountSince, resolveCommitCountSinceAsync, resolveCurrentGitHead, resolveCurrentGitHeadAsync, resolveCurrentUpstreamPushTarget, resolveCurrentUpstreamPushTargetAsync, resolveCurrentUpstreamRemoteRef, resolveExactRemoteBranchHead, resolveExactRemoteBranchHeadAsync, resolveIsExactSingleChildCommit, resolveIsExactSingleChildCommitAsync, resolveIsWorkingTreeClean, resolveIsWorkingTreeCleanAsync, resolvePrReviewDiffStats, resolvePrReviewDiffStatsAsync, resolvePrWorkflowRevisionDigest, resolvePrWorkflowRevisionDigestDetailed, resolveRemoteRefsContainingHead, resolveRemoteRefsContainingHeadAsync } from '../background/workspace-snapshot.js';
|
|
8
8
|
import { classifyPrWorkflowGitState, type PrWorkflowGitState } from '../git/pr-workflow-state.js';
|
|
@@ -10,7 +10,7 @@ export declare const PR_REVIEW_BASE_DIMENSION_IDS: readonly ["intent-architectur
|
|
|
10
10
|
export declare const PR_REVIEW_REQUIRED_MICRO_LANE_IDS: ("auth-identity-secrets" | "untrusted-input-boundaries" | "subprocess-platform" | "concurrency-state" | "dependencies-build-release" | "api-schema-migrations" | "test-infrastructure" | "ui-accessibility-i18n" | "privacy-observability" | "generated-provenance" | "unclassified-risk")[];
|
|
11
11
|
export type PrReviewBaseDimensionId = (typeof PR_REVIEW_BASE_DIMENSION_IDS)[number];
|
|
12
12
|
export type PrWorkflowMode = 'PR_REVIEW' | 'PR_FEEDBACK';
|
|
13
|
-
export type PrReviewLaneValidationPredicate = 'batch.validated_at' | 'batch.expected_lane_unique' | 'record.missing' | 'record.duplicate_lane' | 'record.subagent_session_id' | 'record.duplicate_subagent_session_id' | 'record.forbidden_subagent_session_id' | 'record.created_at' | 'record.workflow_lane' | 'record.owned_workflow_lanes' | 'record.mode' | 'record.pr_head_sha' | 'record.git_head' | 'record.status' | 'result.output_degraded' | 'result.transcript_incomplete' | 'result.
|
|
13
|
+
export type PrReviewLaneValidationPredicate = 'batch.validated_at' | 'batch.expected_lane_unique' | 'record.missing' | 'record.duplicate_lane' | 'record.subagent_session_id' | 'record.duplicate_subagent_session_id' | 'record.forbidden_subagent_session_id' | 'record.created_at' | 'record.workflow_lane' | 'record.owned_workflow_lanes' | 'record.mode' | 'record.pr_head_sha' | 'record.git_head' | 'record.status' | 'result.output_degraded' | 'result.transcript_incomplete' | 'result.chars' | 'result.digest' | 'result.output_ref' | 'artifact.readable' | 'artifact.ref' | 'artifact.batch_id' | 'artifact.lane_id' | 'artifact.mode' | 'artifact.session_id' | 'artifact.parent_session_id' | 'artifact.agent' | 'artifact.role' | 'artifact.source' | 'artifact.workflow_lane_record' | 'artifact.workflow_lane_expected' | 'artifact.pr_head_sha' | 'artifact.git_head' | 'artifact.revision_digest' | 'record.scope' | 'artifact.scope' | 'artifact.digest' | 'artifact.chars' | 'discovery.header' | 'discovery.row' | 'discovery.coverage' | 'discovery.duplicate_evidence';
|
|
14
14
|
export interface PrReviewLaneValidationFailure {
|
|
15
15
|
predicate: PrReviewLaneValidationPredicate;
|
|
16
16
|
expected: string;
|
|
@@ -25,6 +25,8 @@ export type PrReviewLaneValidationResult = {
|
|
|
25
25
|
* distinguishable from a well-formed one.
|
|
26
26
|
*/
|
|
27
27
|
salvaged?: readonly string[];
|
|
28
|
+
/** Typed recovery disclosures persisted to the durable delegation ledger. */
|
|
29
|
+
recoveries?: readonly BackgroundDelegationWorkflowLaneRecovery[];
|
|
28
30
|
} | {
|
|
29
31
|
ok: false;
|
|
30
32
|
failure: PrReviewLaneValidationFailure;
|
|
@@ -44,6 +46,20 @@ export interface PrReviewDiscoveryLaneValidationInput {
|
|
|
44
46
|
checkWorkflowLane?: boolean;
|
|
45
47
|
};
|
|
46
48
|
}
|
|
49
|
+
export interface PrWorkflowTransportRecoveryValidationInput {
|
|
50
|
+
directory: string;
|
|
51
|
+
record: BackgroundDelegationRecord;
|
|
52
|
+
result: BackgroundDelegationResult;
|
|
53
|
+
artifact: LaneOutputArtifact | null;
|
|
54
|
+
revisionDigest: string;
|
|
55
|
+
}
|
|
56
|
+
export type PrWorkflowTransportRecoveryValidationResult = {
|
|
57
|
+
ok: true;
|
|
58
|
+
recoveries?: readonly BackgroundDelegationWorkflowLaneRecovery[];
|
|
59
|
+
} | {
|
|
60
|
+
ok: false;
|
|
61
|
+
reason: string;
|
|
62
|
+
};
|
|
47
63
|
export interface PrWorkflowCheckoutRecoveryRecord {
|
|
48
64
|
code: 'UNMERGED_INDEX' | 'GIT_OPERATION_IN_PROGRESS' | 'DIRTY_SUBMODULE' | 'SWARM_STATE_TRACKING_ERROR' | 'GIT_STATE_INDETERMINATE';
|
|
49
65
|
retryable: false;
|
|
@@ -408,13 +424,99 @@ export declare function withInactivePrWorkflowCheckoutRestoreLock<T>(directory:
|
|
|
408
424
|
export declare function clearPrWorkflowGateState(directory: string, sessionID: string, expectedRevision?: number, options?: {
|
|
409
425
|
allowSalvagedRead?: boolean;
|
|
410
426
|
}): Promise<void>;
|
|
427
|
+
/**
|
|
428
|
+
* The single session operation the liveness probe needs.
|
|
429
|
+
*
|
|
430
|
+
* Deliberately a narrow LOCAL structural type rather than a type-only import of
|
|
431
|
+
* `SessionOps` from `src/tools/dispatch-lanes.ts`: that module's
|
|
432
|
+
* `isLaneReadyForCollection` is the fail-CLOSED counterpart of this probe, and
|
|
433
|
+
* keeping the two textually independent removes any invitation to "share" the
|
|
434
|
+
* predicate. A type-only import would be erased either way; this is about
|
|
435
|
+
* preventing the wrong reuse, not about module graph cost.
|
|
436
|
+
*/
|
|
437
|
+
interface PrWorkflowLaneLivenessSessionOps {
|
|
438
|
+
status?: (args: {
|
|
439
|
+
query?: {
|
|
440
|
+
directory?: string;
|
|
441
|
+
};
|
|
442
|
+
}) => Promise<{
|
|
443
|
+
data?: Record<string, {
|
|
444
|
+
type?: string;
|
|
445
|
+
}> | null;
|
|
446
|
+
error?: unknown;
|
|
447
|
+
}>;
|
|
448
|
+
}
|
|
449
|
+
/** Why a probe produced no evidence of life. Absent means the probe ran. */
|
|
450
|
+
export type PrWorkflowLaneProbeDegradedReason = 'probe-unavailable' | 'probe-error' | 'probe-timeout' | 'probe-no-data';
|
|
451
|
+
/**
|
|
452
|
+
* Probe which of `records` have a session the host affirmatively reports as
|
|
453
|
+
* still running (issue #2251).
|
|
454
|
+
*
|
|
455
|
+
* **FAIL-OPEN, by design.** For its ERROR and NO-DATA cases this is the exact
|
|
456
|
+
* inverse of `isLaneReadyForCollection` (`src/tools/dispatch-lanes.ts`), which
|
|
457
|
+
* returns `false` on a truthy `error`, on missing `data`, and on a throw —
|
|
458
|
+
* because a lane it cannot verify must not be collected. The two agree, rather
|
|
459
|
+
* than invert, on ONE case: a host that exposes no `status` function at all.
|
|
460
|
+
* There the collector returns `true` (`dispatch-lanes.ts`, the `typeof
|
|
461
|
+
* session.status !== 'function'` guard) and this probe reports
|
|
462
|
+
* `probe-unavailable`, so both fall through to proceeding — an unprobeable host
|
|
463
|
+
* must not wedge either side.
|
|
464
|
+
*
|
|
465
|
+
* Here the default outcome must be "settle": an unavailable, erroring,
|
|
466
|
+
* timing-out or empty probe returns the empty set, so age alone decides and the
|
|
467
|
+
* reachability floor this whole subsystem exists to preserve is untouched. Only
|
|
468
|
+
* a probe that RAN and affirmatively named a live session may contradict
|
|
469
|
+
* staleness.
|
|
470
|
+
*
|
|
471
|
+
* The returned set is built only from a fully-read response — a mid-iteration
|
|
472
|
+
* throw yields the empty set rather than a partial spare list, so a malformed
|
|
473
|
+
* response can never spare an arbitrary subset of lanes.
|
|
474
|
+
*
|
|
475
|
+
* Keys are `subagentSessionId`s. A record without one is unprobeable and is
|
|
476
|
+
* simply never added (it settles), which is the fail-open direction.
|
|
477
|
+
*/
|
|
478
|
+
declare function probeAlivePrWorkflowLaneSessions(directory: string, records: BackgroundDelegationRecord[]): Promise<{
|
|
479
|
+
alive: Set<string>;
|
|
480
|
+
degradedReason?: PrWorkflowLaneProbeDegradedReason;
|
|
481
|
+
}>;
|
|
411
482
|
export interface PrWorkflowStaleLaneSettlement {
|
|
412
|
-
/**
|
|
483
|
+
/**
|
|
484
|
+
* Every lane that still blocks: lanes with a fresh `updatedAt` PLUS lanes
|
|
485
|
+
* past the horizon whose session the liveness probe reported still running.
|
|
486
|
+
*/
|
|
413
487
|
openLaneIds: string[];
|
|
414
488
|
openLanes: number;
|
|
489
|
+
/**
|
|
490
|
+
* Open lanes that block on FRESHNESS alone (age below the horizon).
|
|
491
|
+
*
|
|
492
|
+
* Separated from `openLanes` because the human-only `force` abort override
|
|
493
|
+
* (issue #2251 S3) must distinguish "blocked only by probe retention", which
|
|
494
|
+
* an operator may override, from "blocked by a lane that is genuinely young",
|
|
495
|
+
* which stays fail-closed. Deriving it by subtraction or by comparing lane
|
|
496
|
+
* LABELS would be wrong: `prWorkflowLaneLabel` falls back to `'unknown'`, so
|
|
497
|
+
* labels are not unique.
|
|
498
|
+
*/
|
|
499
|
+
freshOpenLanes: number;
|
|
415
500
|
/** Lanes stale past the horizon, treated as settled with disclosure. */
|
|
416
501
|
presumedStaleLaneIds: string[];
|
|
417
|
-
/**
|
|
502
|
+
/**
|
|
503
|
+
* Lanes past the horizon that the probe spared. Present only when non-empty.
|
|
504
|
+
*/
|
|
505
|
+
probedAliveLaneIds?: string[];
|
|
506
|
+
/**
|
|
507
|
+
* The SAME records as {@link probedAliveLaneIds}, in the same order, keyed by
|
|
508
|
+
* `correlationId` instead of by display label.
|
|
509
|
+
*
|
|
510
|
+
* Both are needed and neither substitutes for the other: `prWorkflowLaneLabel`
|
|
511
|
+
* falls back to `'unknown'` and is not unique, so it cannot address a durable
|
|
512
|
+
* record — while `correlationId` is the ledger's primary key and is what the
|
|
513
|
+
* human-only `force` override must name to finalize exactly these records and
|
|
514
|
+
* nothing else. Present only when non-empty.
|
|
515
|
+
*/
|
|
516
|
+
probeRetainedCorrelationIds?: string[];
|
|
517
|
+
/** Set when the probe could not produce evidence; absent when it ran. */
|
|
518
|
+
probeDegradedReason?: PrWorkflowLaneProbeDegradedReason;
|
|
519
|
+
/** Operator-facing disclosure; `undefined` when nothing was settled or retained. */
|
|
418
520
|
disclosure?: string;
|
|
419
521
|
}
|
|
420
522
|
/**
|
|
@@ -439,6 +541,13 @@ export interface PrWorkflowStaleLaneSettlement {
|
|
|
439
541
|
*
|
|
440
542
|
* A lane with a RECENT `updatedAt` still blocks: a re-verification that CAN run
|
|
441
543
|
* and reports "still progressing" contradicts settlement and fails closed.
|
|
544
|
+
*
|
|
545
|
+
* Issue #2251 adds the second, stronger contradiction: a lane PAST the horizon
|
|
546
|
+
* whose session the host affirmatively reports as `busy`/`retry` is genuinely
|
|
547
|
+
* running (nothing heartbeats `updatedAt`, so age alone cannot see this) and is
|
|
548
|
+
* retained instead of discarded. The probe is fail-open — see
|
|
549
|
+
* {@link probeAlivePrWorkflowLaneSessions} — so an unavailable, erroring or
|
|
550
|
+
* empty probe leaves the age-only behaviour exactly as it was.
|
|
442
551
|
*/
|
|
443
552
|
export declare function settlePresumedStalePrWorkflowLanes(directory: string, sessionID: string): Promise<PrWorkflowStaleLaneSettlement>;
|
|
444
553
|
/**
|
|
@@ -480,6 +589,16 @@ export declare function abortPrWorkflow(directory: string, sessionID: string, op
|
|
|
480
589
|
openLanes: number;
|
|
481
590
|
presumedStaleLanes?: string[];
|
|
482
591
|
presumedStaleDisclosure?: string;
|
|
592
|
+
/** Lanes past the horizon the liveness probe reported as still running. */
|
|
593
|
+
probeRetainedLanes?: string[];
|
|
594
|
+
/**
|
|
595
|
+
* Present ONLY when a human `force` abort cleared the gate while those
|
|
596
|
+
* probe-retained lanes were the sole remaining reason it was blocked
|
|
597
|
+
* (issue #2251 S3).
|
|
598
|
+
*/
|
|
599
|
+
probeRetentionOverrideDisclosure?: string;
|
|
600
|
+
/** Why the liveness probe produced no evidence, when it could not run. */
|
|
601
|
+
probeDegradedReason?: PrWorkflowLaneProbeDegradedReason;
|
|
483
602
|
stateSalvaged?: boolean;
|
|
484
603
|
stateSalvageDisclosure?: string;
|
|
485
604
|
casEscapeDisclosure?: string;
|
|
@@ -652,6 +771,32 @@ export declare const _test_exports: {
|
|
|
652
771
|
removeCheckoutLock: typeof removeCheckoutLockFile;
|
|
653
772
|
checkoutMutationActionTimeoutMs: number;
|
|
654
773
|
classifyPrWorkflowGitStateAsync: typeof classifyPrWorkflowGitState;
|
|
774
|
+
/**
|
|
775
|
+
* The durability sweep, reached through a seam so a test can prove that a
|
|
776
|
+
* failing sweep cannot un-settle the decision `settlePresumedStalePrWorkflow-
|
|
777
|
+
* Lanes` already made in memory. It cannot throw today (it catches internally
|
|
778
|
+
* and returns 0) — the seam is what makes that guarantee testable rather than
|
|
779
|
+
* merely asserted.
|
|
780
|
+
*/
|
|
781
|
+
sweepStaleDelegationsAsync: typeof sweepStaleDelegations;
|
|
782
|
+
/** The fail-open liveness probe (issue #2251). */
|
|
783
|
+
probeLaneLivenessAsync: typeof probeAlivePrWorkflowLaneSessions;
|
|
784
|
+
/**
|
|
785
|
+
* Session handle for the liveness probe.
|
|
786
|
+
*
|
|
787
|
+
* A seam rather than a direct `swarmState.opencodeClient` read at the call
|
|
788
|
+
* site because 20+ test files mutate that field; without this, this suite and
|
|
789
|
+
* the stale-lane suite would be order-dependent in bun's shared process.
|
|
790
|
+
* Mirrors `_internals.getSessionOps` in `src/tools/dispatch-lanes.ts`.
|
|
791
|
+
*/
|
|
792
|
+
getSessionOps: () => PrWorkflowLaneLivenessSessionOps | null;
|
|
793
|
+
/**
|
|
794
|
+
* Probe deadline, read through the seam at CALL time. `freezeClock` patches
|
|
795
|
+
* `Date.now()`, not `setTimeout`, so a test that must reach the timeout branch
|
|
796
|
+
* has to shorten the real deadline. Same precedent as
|
|
797
|
+
* `checkoutMutationActionTimeoutMs` above.
|
|
798
|
+
*/
|
|
799
|
+
laneLivenessProbeTimeoutMs: number;
|
|
655
800
|
resolveCurrentGitHead: typeof resolveCurrentGitHead;
|
|
656
801
|
resolveCurrentGitHeadAsync: typeof resolveCurrentGitHeadAsync;
|
|
657
802
|
resolveCurrentUpstreamPushTarget: typeof resolveCurrentUpstreamPushTarget;
|
|
@@ -918,6 +1063,17 @@ declare function analyzePrReviewBatchRecordIntegrity(args: {
|
|
|
918
1063
|
* accidentally accept stale terminal state or a different output reference.
|
|
919
1064
|
*/
|
|
920
1065
|
export declare function validatePrReviewDiscoveryLaneCompletion(input: PrReviewDiscoveryLaneValidationInput): PrReviewLaneValidationResult;
|
|
1066
|
+
/**
|
|
1067
|
+
* Collection-time proof for transport-recovered structured workflow lanes.
|
|
1068
|
+
*
|
|
1069
|
+
* Reviewer/critic/PR-feedback lanes normally settle later through the workflow
|
|
1070
|
+
* gate, not in `collect_lane_results`, so a truncated inline preview used to
|
|
1071
|
+
* pass through collection with no durable typed provenance. This helper proves
|
|
1072
|
+
* the durable artifact still carries the exact rows the already-declared batch
|
|
1073
|
+
* owns, allowing collection to persist the transport recovery immediately. Any
|
|
1074
|
+
* unsupported or unprovable structured mode fails closed.
|
|
1075
|
+
*/
|
|
1076
|
+
export declare function validatePrWorkflowTransportRecovery(input: PrWorkflowTransportRecoveryValidationInput): Promise<PrWorkflowTransportRecoveryValidationResult>;
|
|
921
1077
|
/** Require at least one semantically valid discovery row or CLEAN attestation. */
|
|
922
1078
|
export declare function prReviewDiscoveryArtifactCoversLane(text: string, expectedWorkflowLane: string, ownedWorkflowLanes?: readonly string[], mode?: string): boolean;
|
|
923
1079
|
/**
|