opencode-swarm 7.144.3 → 7.144.5

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.
Files changed (127) hide show
  1. package/.opencode/skills/swarm-pr-review/SKILL.md +3 -1
  2. package/.opencode/skills/swarm-pr-review/references/lane-output-recoverability.md +28 -0
  3. package/.opencode/skills/swarm-pr-review/references/prompt-templates.md +2 -0
  4. package/README.md +3 -1
  5. package/dist/background/pending-delegations.d.ts +14 -0
  6. package/dist/background/workspace-snapshot.d.ts +7 -0
  7. package/dist/cli/{capability-probe-f1paszww.js → capability-probe-976tt4ba.js} +6 -2
  8. package/dist/cli/{config-doctor-pkr9w2nv.js → config-doctor-m005xfdt.js} +3 -3
  9. package/dist/cli/{core-7pymdx0b.js → core-6vdtfb8s.js} +4 -3
  10. package/dist/cli/{curation-policy-y1pqpztb.js → curation-policy-a511r0qz.js} +6 -6
  11. package/dist/cli/{curator-wbzcjd0q.js → curator-0t87anp5.js} +35 -34
  12. package/dist/cli/{curator-drift-2jbjv03a.js → curator-drift-ckjm272w.js} +2 -2
  13. package/dist/cli/curator-llm-factory-j8tk9rxm.js +63 -0
  14. package/dist/cli/{dispatch-1y1rnv1h.js → dispatch-ndxbsk98.js} +2 -2
  15. package/dist/cli/{evidence-summary-service-rcgrdm52.js → evidence-summary-service-c22gahjc.js} +15 -14
  16. package/dist/cli/{gate-evidence-jmzctnhg.js → gate-evidence-hh8kc9wt.js} +9 -8
  17. package/dist/cli/guardrail-explain-9gjw2dsd.js +64 -0
  18. package/dist/cli/{guardrail-log-k1s9xf3h.js → guardrail-log-ejf5zjac.js} +5 -5
  19. package/dist/cli/{hive-promoter-vcj5h0e3.js → hive-promoter-gkbfpdtv.js} +35 -34
  20. package/dist/cli/{index-s2rcz51a.js → index-1jsmmx7y.js} +66 -34
  21. package/dist/cli/{index-qj22wyw2.js → index-1pxqkvvq.js} +3 -3
  22. package/dist/cli/{index-p863y7xx.js → index-3qdzpv91.js} +1 -1
  23. package/dist/cli/{index-8hkjk37c.js → index-58cvm3dw.js} +36 -1
  24. package/dist/cli/{index-ghzvxj3g.js → index-5wenr2vs.js} +40 -37
  25. package/dist/cli/{index-wck434f8.js → index-63tgh0cn.js} +15 -4
  26. package/dist/cli/{index-xwpmxpb7.js → index-641yjpk8.js} +6 -6
  27. package/dist/cli/{index-zwrqe065.js → index-6z5jtf7d.js} +2 -2
  28. package/dist/cli/{index-j6mfyy0a.js → index-7e4q41nb.js} +3 -3
  29. package/dist/cli/{index-6s2q144w.js → index-855hseq4.js} +43 -22
  30. package/dist/cli/index-9e6fdz2h.js +282 -0
  31. package/dist/cli/{index-zswmbm15.js → index-9s8drsf9.js} +2 -2
  32. package/dist/cli/{index-x68tw7v3.js → index-a1hxejxc.js} +168 -36
  33. package/dist/cli/{index-b6e016tv.js → index-abtrcs16.js} +1 -1
  34. package/dist/cli/{index-8fwhhayc.js → index-b44qqqt2.js} +27 -18
  35. package/dist/cli/{index-k3cxyk66.js → index-cwtpqm5f.js} +1 -1
  36. package/dist/cli/{index-2en8s72h.js → index-dc04v786.js} +30 -2
  37. package/dist/cli/{index-7554tecy.js → index-dtbzyr3s.js} +2 -2
  38. package/dist/cli/{index-eya357bk.js → index-ea09xax6.js} +5 -5
  39. package/dist/cli/{index-74hpm6sh.js → index-f36ybbsv.js} +12 -6
  40. package/dist/cli/{index-wd24zn2e.js → index-f9vvg5xb.js} +1 -1
  41. package/dist/cli/{index-rn0eq85g.js → index-fv0s19g9.js} +1 -1
  42. package/dist/cli/{index-ep14xc5z.js → index-fv2pzwnp.js} +6 -5
  43. package/dist/cli/{index-dpfphnmy.js → index-h1p08s3n.js} +1 -1
  44. package/dist/cli/{index-584grrwn.js → index-hkdgkkhb.js} +2 -2
  45. package/dist/cli/{index-1brb14xc.js → index-kdak6s63.js} +12 -6
  46. package/dist/cli/{index-satc0vs6.js → index-kh0jt9pg.js} +300 -1181
  47. package/dist/cli/{index-p7hbphaq.js → index-mkmcz6x8.js} +4 -4
  48. package/dist/cli/{index-krxcxkdq.js → index-n4hwcsbd.js} +20 -5
  49. package/dist/cli/{index-06cn7haa.js → index-rdgtfj74.js} +2 -2
  50. package/dist/cli/{index-b227mpnk.js → index-rnyt30tm.js} +4 -4
  51. package/dist/cli/{index-whezv7vc.js → index-v3y3qg48.js} +1 -1
  52. package/dist/cli/{index-0fgwdtvp.js → index-vdha477y.js} +1 -1
  53. package/dist/cli/{index-pr8vhj6j.js → index-wbrqvm2g.js} +8 -8
  54. package/dist/cli/{index-8214dd7j.js → index-wknz5c8q.js} +2 -2
  55. package/dist/cli/{index-pag8nsb1.js → index-wm6f7t7w.js} +3 -3
  56. package/dist/cli/{index-247wf23m.js → index-wmsehjq6.js} +2847 -1791
  57. package/dist/cli/{index-4nt52yr9.js → index-zj6t9zgx.js} +173 -25
  58. package/dist/cli/index-zy7f84cs.js +1210 -0
  59. package/dist/cli/index.d.ts +11 -1
  60. package/dist/cli/index.js +64 -42
  61. package/dist/cli/{knowledge-escalator-x6jrcrwj.js → knowledge-escalator-1d79m1tr.js} +14 -13
  62. package/dist/cli/{knowledge-events-aw22r72m.js → knowledge-events-ces29ncg.js} +12 -11
  63. package/dist/cli/{knowledge-link-bntppte4.js → knowledge-link-4cg4776a.js} +5 -5
  64. package/dist/cli/{knowledge-store-19xg1rw1.js → knowledge-store-pe8webc2.js} +6 -6
  65. package/dist/cli/{knowledge-validator-8wh82z0a.js → knowledge-validator-4yjf1f7k.js} +8 -8
  66. package/dist/cli/{pending-delegations-1y303j3k.js → pending-delegations-9h1jmtw1.js} +5 -5
  67. package/dist/cli/{pr-subscriptions-wvd041rp.js → pr-subscriptions-8pg34pev.js} +5 -5
  68. package/dist/cli/{runner-jn55k8xb.js → runner-cqecp1na.js} +6 -6
  69. package/dist/cli/{scan-cursor-429r5db9.js → scan-cursor-d6exjmqj.js} +9 -7
  70. package/dist/cli/{schema-jdwjcby0.js → schema-2esybebd.js} +4 -2
  71. package/dist/cli/{scope-persistence-s0s1bz15.js → scope-persistence-ej59x0yc.js} +9 -8
  72. package/dist/cli/{skill-generator-ffbj0ye5.js → skill-generator-yqta3yrg.js} +16 -15
  73. package/dist/cli/{telemetry-xyfb5vm8.js → telemetry-cybx6cfz.js} +1 -1
  74. package/dist/cli/{workspace-snapshot-w3tg4ne5.js → workspace-snapshot-d89zm6wm.js} +5 -2
  75. package/dist/cli/{worktree-collision-ownership-z5ftwjz3.js → worktree-collision-ownership-vy0kxa98.js} +28 -21
  76. package/dist/cli/{worktree-isolation-y2p93438.js → worktree-isolation-rwq0kke7.js} +35 -34
  77. package/dist/cli/{worktree-provisioning-owner-g24xd417.js → worktree-provisioning-owner-zzkjycp1.js} +3 -3
  78. package/dist/commands/ci-simulate.d.ts +2 -0
  79. package/dist/commands/index.d.ts +1 -0
  80. package/dist/commands/recover.d.ts +17 -0
  81. package/dist/commands/registry.d.ts +9 -1
  82. package/dist/commands/reset-session.d.ts +2 -0
  83. package/dist/config/cache-paths.d.ts +57 -0
  84. package/dist/config/evidence-schema.d.ts +3 -3
  85. package/dist/config/schema.d.ts +9 -0
  86. package/dist/git/branch.d.ts +2 -0
  87. package/dist/git/pr.d.ts +2 -0
  88. package/dist/hooks/context-budget.d.ts +4 -0
  89. package/dist/hooks/context-usage.d.ts +48 -0
  90. package/dist/hooks/delegation-gate/worktree-isolation.d.ts +7 -0
  91. package/dist/hooks/diff-scope.d.ts +7 -0
  92. package/dist/hooks/pr-workflow-gate.d.ts +29 -2
  93. package/dist/hooks/review-receipt-scope.d.ts +7 -0
  94. package/dist/hooks/reviewer-scope-lifecycle.d.ts +9 -0
  95. package/dist/hooks/semantic-diff-injection.d.ts +8 -0
  96. package/dist/index.js +607 -591
  97. package/dist/mutation/engine.d.ts +11 -0
  98. package/dist/observability/catalog.d.ts +8 -6
  99. package/dist/review/diff-source.d.ts +2 -0
  100. package/dist/sandbox/capability-probe.d.ts +22 -0
  101. package/dist/sandbox/executor.d.ts +15 -0
  102. package/dist/sandbox/linux/bubblewrap-executor.d.ts +6 -0
  103. package/dist/sandbox/macos/sandbox-exec-executor.d.ts +41 -0
  104. package/dist/sast/semgrep.d.ts +3 -2
  105. package/dist/telemetry.d.ts +17 -1
  106. package/dist/tools/checkpoint.d.ts +11 -0
  107. package/dist/tools/complexity-hotspots.d.ts +15 -0
  108. package/dist/tools/context-status.d.ts +9 -3
  109. package/dist/tools/diff-summary.d.ts +12 -0
  110. package/dist/tools/dispatch-lanes.d.ts +35 -2
  111. package/dist/tools/gh-evidence.d.ts +17 -1
  112. package/dist/tools/knowledge-receipt.d.ts +1 -1
  113. package/dist/tools/pkg-audit.d.ts +13 -0
  114. package/dist/tools/pre-check-batch.d.ts +9 -0
  115. package/dist/tools/prepare-pr-workflow-checkout.d.ts +1 -0
  116. package/dist/tools/sast-scan.d.ts +3 -0
  117. package/dist/utils/bun-compat.d.ts +80 -3
  118. package/dist/utils/git-binary-missing-error.d.ts +80 -2
  119. package/dist/utils/git-executable.d.ts +179 -0
  120. package/dist/utils/gitignore-warning.d.ts +10 -0
  121. package/dist/workflow/coder-settlement.d.ts +92 -0
  122. package/dist/worktree/core.d.ts +8 -0
  123. package/dist/worktree/merge.d.ts +33 -0
  124. package/package.json +3 -2
  125. package/dist/cli/curator-llm-factory-7are9wjh.js +0 -62
  126. package/dist/cli/guardrail-explain-brgw4sve.js +0 -63
  127. package/dist/cli/index-q1exe2b3.js +0 -256
@@ -5,23 +5,28 @@ import {
5
5
  import {
6
6
  scanDelegationFallbacksForRecovery,
7
7
  scanDelegationsForRecovery
8
- } from "./index-krxcxkdq.js";
8
+ } from "./index-n4hwcsbd.js";
9
9
  import {
10
10
  WORKTREE_PROVISIONING_OWNER_LEASE_MS,
11
11
  removeWorktreeProvisioningOwner,
12
12
  scanWorktreeProvisioningOwnersForRecovery
13
- } from "./index-k3cxyk66.js";
14
- import"./index-rn0eq85g.js";
13
+ } from "./index-cwtpqm5f.js";
14
+ import"./index-fv0s19g9.js";
15
15
  import"./index-z6xqpmqg.js";
16
+ import {
17
+ init_git_executable,
18
+ resolveGitExecutable
19
+ } from "./index-9e6fdz2h.js";
20
+ import"./index-4rhhvd1a.js";
16
21
  import"./index-zjygnfay.js";
17
22
  import"./index-ed5ykebp.js";
18
- import"./index-wd24zn2e.js";
19
- import"./index-s2rcz51a.js";
23
+ import"./index-f9vvg5xb.js";
24
+ import"./index-1jsmmx7y.js";
20
25
  import"./index-7g4c7s5r.js";
21
26
  import"./index-bpmtbmy9.js";
22
27
  import {
23
28
  bunSpawn
24
- } from "./index-4nt52yr9.js";
29
+ } from "./index-zj6t9zgx.js";
25
30
  import"./index-zgwm4ryv.js";
26
31
  import"./index-a76rekgs.js";
27
32
 
@@ -32,6 +37,7 @@ import * as path2 from "path";
32
37
  // src/hooks/delegation-gate/worktree-ownership-tag.ts
33
38
  import * as fs from "fs";
34
39
  import * as path from "path";
40
+ init_git_executable();
35
41
  var OWNERSHIP_TAG_SCAN_TIMEOUT_MS = 2000;
36
42
  var MAX_OWNERSHIP_TAGS = 512;
37
43
  function decodeTagPart(value) {
@@ -52,21 +58,22 @@ async function scanBackgroundWorktreeOwnershipTagsForRecovery(directory) {
52
58
  reason: `Git metadata could not be inspected: ${error instanceof Error ? error.message : String(error)}`
53
59
  };
54
60
  }
55
- const proc = bunSpawn([
56
- "git",
57
- "-C",
58
- directory,
59
- "for-each-ref",
60
- `--count=${MAX_OWNERSHIP_TAGS + 1}`,
61
- "--format=%(refname:strip=2)%00%(objectname)",
62
- "refs/tags/swarm-preserved-owner/"
63
- ], {
64
- stdin: "ignore",
65
- stdout: "pipe",
66
- stderr: "ignore",
67
- timeout: OWNERSHIP_TAG_SCAN_TIMEOUT_MS
68
- });
61
+ let proc;
69
62
  try {
63
+ proc = bunSpawn([
64
+ resolveGitExecutable(),
65
+ "-C",
66
+ directory,
67
+ "for-each-ref",
68
+ `--count=${MAX_OWNERSHIP_TAGS + 1}`,
69
+ "--format=%(refname:strip=2)%00%(objectname)",
70
+ "refs/tags/swarm-preserved-owner/"
71
+ ], {
72
+ stdin: "ignore",
73
+ stdout: "pipe",
74
+ stderr: "ignore",
75
+ timeout: OWNERSHIP_TAG_SCAN_TIMEOUT_MS
76
+ });
70
77
  const exitCode = await proc.exited;
71
78
  if (exitCode !== 0) {
72
79
  return {
@@ -104,7 +111,7 @@ async function scanBackgroundWorktreeOwnershipTagsForRecovery(directory) {
104
111
  };
105
112
  } finally {
106
113
  try {
107
- proc.kill();
114
+ proc?.kill();
108
115
  } catch {}
109
116
  }
110
117
  }
@@ -20,62 +20,63 @@ import {
20
20
  sanitizeWorktreeTaskId,
21
21
  standardWorktreeByCallID,
22
22
  standardWorktreeSerializationSessions
23
- } from "./index-247wf23m.js";
24
- import"./index-7554tecy.js";
25
- import"./index-2en8s72h.js";
26
- import"./index-satc0vs6.js";
23
+ } from "./index-wmsehjq6.js";
24
+ import"./index-dtbzyr3s.js";
25
+ import"./index-dc04v786.js";
26
+ import"./index-kh0jt9pg.js";
27
27
  import"./index-134d35c1.js";
28
- import"./index-b6e016tv.js";
29
- import"./index-zwrqe065.js";
30
- import"./index-8214dd7j.js";
28
+ import"./index-abtrcs16.js";
29
+ import"./index-6z5jtf7d.js";
30
+ import"./index-wknz5c8q.js";
31
31
  import"./index-y8552snf.js";
32
- import"./index-wck434f8.js";
32
+ import"./index-63tgh0cn.js";
33
33
  import"./index-70ha9e09.js";
34
34
  import"./index-c8s9a3zh.js";
35
35
  import"./index-9ss2m4rs.js";
36
- import"./index-74hpm6sh.js";
37
- import"./index-584grrwn.js";
38
- import"./index-pag8nsb1.js";
39
- import"./index-eya357bk.js";
40
- import"./index-b227mpnk.js";
41
- import"./index-0fgwdtvp.js";
36
+ import"./index-f36ybbsv.js";
37
+ import"./index-hkdgkkhb.js";
38
+ import"./index-wm6f7t7w.js";
39
+ import"./index-ea09xax6.js";
40
+ import"./index-rnyt30tm.js";
41
+ import"./index-vdha477y.js";
42
42
  import"./index-rtry5xyf.js";
43
43
  import"./index-zsrtt42s.js";
44
- import"./index-krxcxkdq.js";
45
- import"./index-k3cxyk66.js";
46
- import"./index-x68tw7v3.js";
47
- import"./index-6s2q144w.js";
48
- import"./index-p7hbphaq.js";
49
- import"./index-j6mfyy0a.js";
44
+ import"./index-n4hwcsbd.js";
45
+ import"./index-cwtpqm5f.js";
46
+ import"./index-a1hxejxc.js";
47
+ import"./index-855hseq4.js";
48
+ import"./index-mkmcz6x8.js";
49
+ import"./index-7e4q41nb.js";
50
50
  import"./index-556ja8an.js";
51
51
  import"./index-7sy3aa9m.js";
52
52
  import"./index-wx8zdh4a.js";
53
- import"./index-8fwhhayc.js";
54
- import"./index-q1exe2b3.js";
55
- import"./index-xwpmxpb7.js";
56
- import"./index-pr8vhj6j.js";
53
+ import"./index-b44qqqt2.js";
54
+ import"./index-zy7f84cs.js";
55
+ import"./index-641yjpk8.js";
56
+ import"./index-wbrqvm2g.js";
57
57
  import {
58
58
  resolveWorktreeIsolationConfig
59
- } from "./index-qj22wyw2.js";
59
+ } from "./index-1pxqkvvq.js";
60
60
  import"./index-gprxjmm7.js";
61
61
  import"./index-n832052r.js";
62
- import"./index-rn0eq85g.js";
62
+ import"./index-fv0s19g9.js";
63
63
  import"./index-z6xqpmqg.js";
64
- import"./index-8hkjk37c.js";
65
- import"./index-1brb14xc.js";
64
+ import"./index-58cvm3dw.js";
65
+ import"./index-kdak6s63.js";
66
+ import"./index-v3y3qg48.js";
67
+ import"./index-9e6fdz2h.js";
66
68
  import"./index-4rhhvd1a.js";
67
- import"./index-whezv7vc.js";
68
69
  import"./index-zjygnfay.js";
69
70
  import"./index-ae75rja9.js";
70
- import"./index-dpfphnmy.js";
71
- import"./index-zswmbm15.js";
71
+ import"./index-h1p08s3n.js";
72
+ import"./index-9s8drsf9.js";
72
73
  import"./index-ed5ykebp.js";
73
74
  import"./index-bk5tah7q.js";
74
- import"./index-wd24zn2e.js";
75
- import"./index-s2rcz51a.js";
75
+ import"./index-f9vvg5xb.js";
76
+ import"./index-1jsmmx7y.js";
76
77
  import"./index-7g4c7s5r.js";
77
78
  import"./index-bpmtbmy9.js";
78
- import"./index-4nt52yr9.js";
79
+ import"./index-zj6t9zgx.js";
79
80
  import"./index-zgwm4ryv.js";
80
81
  import"./index-a76rekgs.js";
81
82
  export {
@@ -5,12 +5,12 @@ import {
5
5
  recordWorktreeProvisioningOwner,
6
6
  removeWorktreeProvisioningOwner,
7
7
  scanWorktreeProvisioningOwnersForRecovery
8
- } from "./index-k3cxyk66.js";
9
- import"./index-rn0eq85g.js";
8
+ } from "./index-cwtpqm5f.js";
9
+ import"./index-fv0s19g9.js";
10
10
  import"./index-z6xqpmqg.js";
11
11
  import"./index-zjygnfay.js";
12
12
  import"./index-ed5ykebp.js";
13
- import"./index-4nt52yr9.js";
13
+ import"./index-zj6t9zgx.js";
14
14
  import"./index-zgwm4ryv.js";
15
15
  import"./index-a76rekgs.js";
16
16
  export {
@@ -22,10 +22,12 @@
22
22
  import * as fs from 'node:fs';
23
23
  import { detectDefaultRemoteBranch, getDefaultBaseBranch } from '../git/branch.js';
24
24
  import { runExternalTool } from '../utils/external-tool-runner.js';
25
+ import { resolveGitExecutable } from '../utils/git-executable.js';
25
26
  export declare const _internals: {
26
27
  runExternalTool: typeof runExternalTool;
27
28
  getDefaultBaseBranch: typeof getDefaultBaseBranch;
28
29
  detectDefaultRemoteBranch: typeof detectDefaultRemoteBranch;
30
+ resolveGitExecutable: typeof resolveGitExecutable;
29
31
  platform: string;
30
32
  osTmpdir: () => string;
31
33
  fs: {
@@ -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>;
@@ -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.
@@ -63,3 +63,60 @@ export declare function getPluginCachePaths(): readonly string[];
63
63
  * be cleared during update/install to force a fresh resolution from npm.
64
64
  */
65
65
  export declare function getPluginLockFilePaths(): readonly string[];
66
+ /**
67
+ * Anchored version-pinned cache leaf shape: `opencode-swarm@<semver>`, e.g.
68
+ * `opencode-swarm@7.143.1`, `opencode-swarm@1.2.3-rc.1`,
69
+ * `opencode-swarm@1.2.3+build.5`. Matches full `major.minor.patch` with
70
+ * optional pre-release and build-metadata segments (semver 2.0.0 grammar).
71
+ *
72
+ * Deliberately NOT a `startsWith('opencode-swarm@')` prefix test — that would
73
+ * admit a traversal payload like `opencode-swarm@../../..` as a "valid" leaf.
74
+ * The anchored `^...$` with only `[0-9A-Za-z.-]` permitted in the
75
+ * pre-release/build segments admits no path separator, NUL byte, whitespace,
76
+ * or non-ASCII character. Shared by the delete-time safety check
77
+ * (`isSafeCachePath` in `src/cli/index.ts`, applied AFTER canonicalization)
78
+ * and this module's own discovery function below, so both agree on exactly
79
+ * which leaves are "version-pinned opencode-swarm" without duplicating the
80
+ * pattern (issue #2236 RC3).
81
+ */
82
+ export declare const VERSION_PINNED_LEAF: RegExp;
83
+ /**
84
+ * Enumerate `packages/` parent directories for version-pinned opencode-swarm
85
+ * cache leaves (e.g. `opencode-swarm@7.143.1`) that {@link getPluginCachePaths}
86
+ * cannot discover — that list is fixed to the literal `opencode-swarm@latest`
87
+ * / `opencode-swarm` leaves, so a version-pinned OpenCode host install (issue
88
+ * #2236's reporter had `opencode-swarm@7.143.1`) is invisible to it.
89
+ *
90
+ * PERFORMS FILESYSTEM I/O (`readdirSync`). Callers MUST invoke this at
91
+ * COMMAND TIME only — never at module scope — to preserve AGENTS.md
92
+ * invariant 1 (plugin init must stay side-effect-minimal).
93
+ * {@link getPluginCachePaths} stays pure specifically so it can keep being
94
+ * called at module scope (`src/cli/index.ts:45`); this is the separate,
95
+ * impure counterpart invoked explicitly by `update()` (`src/cli/index.ts`)
96
+ * and the `/swarm diagnose` cache check (`src/services/diagnose-service.ts`).
97
+ *
98
+ * Returns full paths to matched entries. Does NOT apply the delete-time
99
+ * safety allowlist (`isSafeCachePath` in `src/cli/index.ts`) — callers that
100
+ * intend to delete a returned path MUST still run it through that check, and
101
+ * the check MUST run on the realpath-canonicalized string, exactly like every
102
+ * other cache-deletion call site.
103
+ */
104
+ export declare function discoverVersionPinnedCachePaths(): string[];
105
+ /**
106
+ * Resolve a cache path to its actual package root. Some OpenCode cache
107
+ * layouts nest the package under `<cachePath>/node_modules/opencode-swarm`;
108
+ * others ARE the package root directly. Shared by `evictPluginCaches`
109
+ * (`src/cli/index.ts`, to read the pre-deletion version) and the
110
+ * `/swarm diagnose` cache check (`src/services/diagnose-service.ts`) so both
111
+ * agree on where `package.json` lives for a given cache path, per issue
112
+ * #2236 RC3 ("don't duplicate the version-reading logic").
113
+ */
114
+ export declare function resolveCachePackageRoot(cachePath: string): string;
115
+ /**
116
+ * Best-effort read of the installed opencode-swarm version at a cache path.
117
+ * Returns `null` (never throws) if `package.json` is missing, unreadable, or
118
+ * unparsable — this feeds human-readable console/diagnostic reporting, not a
119
+ * safety decision, so a version that can't be determined must degrade
120
+ * gracefully rather than abort the caller's eviction/diagnosis loop.
121
+ */
122
+ export declare function readCachePackageVersion(cachePath: string): string | null;
@@ -220,10 +220,10 @@ export declare const RetrospectiveEvidenceSchema: z.ZodObject<{
220
220
  user_directives: z.ZodDefault<z.ZodArray<z.ZodObject<{
221
221
  directive: z.ZodString;
222
222
  category: z.ZodEnum<{
223
+ other: "other";
223
224
  process: "process";
224
225
  architecture: "architecture";
225
226
  tooling: "tooling";
226
- other: "other";
227
227
  code_style: "code_style";
228
228
  }>;
229
229
  scope: z.ZodEnum<{
@@ -743,10 +743,10 @@ export declare const EvidenceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
743
743
  user_directives: z.ZodDefault<z.ZodArray<z.ZodObject<{
744
744
  directive: z.ZodString;
745
745
  category: z.ZodEnum<{
746
+ other: "other";
746
747
  process: "process";
747
748
  architecture: "architecture";
748
749
  tooling: "tooling";
749
- other: "other";
750
750
  code_style: "code_style";
751
751
  }>;
752
752
  scope: z.ZodEnum<{
@@ -1233,10 +1233,10 @@ export declare const EvidenceBundleSchema: z.ZodObject<{
1233
1233
  user_directives: z.ZodDefault<z.ZodArray<z.ZodObject<{
1234
1234
  directive: z.ZodString;
1235
1235
  category: z.ZodEnum<{
1236
+ other: "other";
1236
1237
  process: "process";
1237
1238
  architecture: "architecture";
1238
1239
  tooling: "tooling";
1239
- other: "other";
1240
1240
  code_style: "code_style";
1241
1241
  }>;
1242
1242
  scope: z.ZodEnum<{
@@ -462,6 +462,10 @@ export declare const DesignDocsConfigSchema: z.ZodObject<{
462
462
  language: z.ZodOptional<z.ZodString>;
463
463
  }, z.core.$strip>;
464
464
  export type DesignDocsConfig = z.infer<typeof DesignDocsConfigSchema>;
465
+ export declare const GitConfigSchema: z.ZodObject<{
466
+ binary: z.ZodOptional<z.ZodString>;
467
+ }, z.core.$strip>;
468
+ export type GitConfig = z.infer<typeof GitConfigSchema>;
465
469
  export declare const UIReviewConfigSchema: z.ZodObject<{
466
470
  enabled: z.ZodDefault<z.ZodBoolean>;
467
471
  trigger_paths: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -550,6 +554,7 @@ export declare const GuardrailsConfigSchema: z.ZodObject<{
550
554
  execution_stall_warn_calls: z.ZodDefault<z.ZodNumber>;
551
555
  execution_stall_stop_calls: z.ZodDefault<z.ZodNumber>;
552
556
  execution_stall_episode_minutes: z.ZodDefault<z.ZodNumber>;
557
+ sandbox_macos_enabled: z.ZodOptional<z.ZodBoolean>;
553
558
  }, z.core.$strip>;
554
559
  export type GuardrailsConfig = z.infer<typeof GuardrailsConfigSchema>;
555
560
  export declare const WatchdogConfigSchema: z.ZodObject<{
@@ -1917,6 +1922,7 @@ export declare const PluginConfigSchema: z.ZodObject<{
1917
1922
  execution_stall_warn_calls: z.ZodDefault<z.ZodNumber>;
1918
1923
  execution_stall_stop_calls: z.ZodDefault<z.ZodNumber>;
1919
1924
  execution_stall_episode_minutes: z.ZodDefault<z.ZodNumber>;
1925
+ sandbox_macos_enabled: z.ZodOptional<z.ZodBoolean>;
1920
1926
  }, z.core.$strip>>;
1921
1927
  watchdog: z.ZodOptional<z.ZodObject<{
1922
1928
  scope_guard: z.ZodDefault<z.ZodBoolean>;
@@ -2046,6 +2052,9 @@ export declare const PluginConfigSchema: z.ZodObject<{
2046
2052
  out_dir: z.ZodDefault<z.ZodString>;
2047
2053
  language: z.ZodOptional<z.ZodString>;
2048
2054
  }, z.core.$strip>>;
2055
+ git: z.ZodOptional<z.ZodObject<{
2056
+ binary: z.ZodOptional<z.ZodString>;
2057
+ }, z.core.$strip>>;
2049
2058
  ui_review: z.ZodOptional<z.ZodObject<{
2050
2059
  enabled: z.ZodDefault<z.ZodBoolean>;
2051
2060
  trigger_paths: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -1,4 +1,5 @@
1
1
  import * as child_process from 'node:child_process';
2
+ import { resolveGitExecutable } from '../utils/git-executable.js';
2
3
  export type GitRepositoryStatus = {
3
4
  isRepo: true;
4
5
  } | {
@@ -201,5 +202,6 @@ export declare const _internals: {
201
202
  resetToMainAfterMerge: typeof resetToMainAfterMerge;
202
203
  spawnSync: typeof __spawnSyncSeam.spawnSync;
203
204
  readLaneEnvFileFromDiskSync: typeof readLaneEnvFileFromDiskSync;
205
+ resolveGitExecutable: typeof resolveGitExecutable;
204
206
  };
205
207
  export {};
package/dist/git/pr.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as child_process from 'node:child_process';
2
+ import { resolveGhBinary } from '../tools/gh-evidence.js';
2
3
  import { readLaneEnvFileFromDiskSync } from './branch.js';
3
4
  export declare const GIT_TIMEOUT_MS = 30000;
4
5
  /**
@@ -70,6 +71,7 @@ export declare const _internals: {
70
71
  spawnSync: typeof __spawnSyncSeam.spawnSync;
71
72
  readLaneEnvFileFromDiskSync: typeof readLaneEnvFileFromDiskSync;
72
73
  getMergeGroupRun: typeof getMergeGroupRun;
74
+ resolveGhBinary: typeof resolveGhBinary;
73
75
  };
74
76
  /**
75
77
  * Check if gh CLI is available
@@ -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
+ };
@@ -11,6 +11,7 @@
11
11
  import type { PluginConfig, WorktreeIsolationConfig } from '../../config';
12
12
  import { tryAcquireLock } from '../../parallel/file-locks';
13
13
  import { bunSpawn } from '../../utils/bun-compat';
14
+ import { resolveGitExecutable } from '../../utils/git-executable.js';
14
15
  import type { WorktreeHandle } from '../../worktree';
15
16
  import { attemptMergeBackFromDirty, cleanupOrphanedBranches, postMergeCleanup, provisionWorktree, pruneStaleWorktreeMetadata, removeWorktree, startupOrphanRecovery } from '../../worktree';
16
17
  import type { DirtyMergeOptions, MergeOperationProvenance } from '../../worktree/merge';
@@ -338,4 +339,10 @@ export declare const _internals: {
338
339
  isLaneOwnedByCurrentSession: typeof isLaneOwnedByCurrentSession;
339
340
  /** FR-001b: bunSpawn — exposed for test injection so collision check can be mocked. */
340
341
  bunSpawn: typeof bunSpawn;
342
+ /**
343
+ * Issue #2236 hardening (F1/F4/F5) — resolves the absolute git executable
344
+ * path instead of spawning the bare `'git'` name. Exposed for test
345
+ * injection following the `src/worktree/core.ts` convention.
346
+ */
347
+ resolveGitExecutable: typeof resolveGitExecutable;
341
348
  };
@@ -5,6 +5,7 @@
5
5
  * Never throws.
6
6
  */
7
7
  import { bunSpawn } from '../utils/bun-compat';
8
+ import { resolveGitExecutable } from '../utils/git-executable.js';
8
9
  /**
9
10
  * Test-only dependency-injection seam — see `gitignore-warning.ts:_internals`
10
11
  * for the rationale (`mock.module` from `bun:test` leaks across files in
@@ -13,6 +14,12 @@ import { bunSpawn } from '../utils/bun-compat';
13
14
  */
14
15
  export declare const _internals: {
15
16
  bunSpawn: typeof bunSpawn;
17
+ /**
18
+ * Test seam for git binary resolution (issue #2236 hardening, lane C1b).
19
+ * This hook is not on the plugin init path, so the synchronous resolver
20
+ * is used (unlike `gitignore-warning.ts`, which must use the async one).
21
+ */
22
+ resolveGitExecutable: typeof resolveGitExecutable;
16
23
  };
17
24
  /**
18
25
  * Validate that git-changed files match the declared scope for a task.
@@ -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, sweepStaleDelegations } 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.truncated' | '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';
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;
@@ -1047,6 +1063,17 @@ declare function analyzePrReviewBatchRecordIntegrity(args: {
1047
1063
  * accidentally accept stale terminal state or a different output reference.
1048
1064
  */
1049
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>;
1050
1077
  /** Require at least one semantically valid discovery row or CLEAN attestation. */
1051
1078
  export declare function prReviewDiscoveryArtifactCoversLane(text: string, expectedWorkflowLane: string, ownedWorkflowLanes?: readonly string[], mode?: string): boolean;
1052
1079
  /**
@@ -17,6 +17,7 @@
17
17
  */
18
18
  import * as child_process from 'node:child_process';
19
19
  import * as fs from 'node:fs';
20
+ import { resolveGitExecutable } from '../utils/git-executable.js';
20
21
  export declare const REVIEWER_TASK_SCOPE_DESCRIPTION = "reviewer-task-files-v2";
21
22
  export declare const REVIEWER_TASK_SCOPE_HEADER = "opencode-swarm-reviewer-task-scope-v2";
22
23
  export interface ReviewerTaskScopeDeliveryEntry {
@@ -82,6 +83,12 @@ export declare function resolveReviewerScopeTaskId(directory: string, args: unkn
82
83
  export declare const _internals: {
83
84
  spawn: typeof child_process.spawn;
84
85
  realpath: typeof fs.promises.realpath;
86
+ /**
87
+ * Issue #2236 hardening (F1/F4/F5) — resolves the absolute git executable
88
+ * path instead of spawning the bare `'git'` name. Exposed for test
89
+ * injection following the `src/worktree/core.ts` convention.
90
+ */
91
+ resolveGitExecutable: typeof resolveGitExecutable;
85
92
  };
86
93
  /**
87
94
  * Build the exact reviewer-task manifest for a guardrails-observed file list.