@fitlab-ai/agent-infra 0.9.13 → 0.9.14

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 (280) hide show
  1. package/bin/cli.ts +26 -9
  2. package/dist/bin/cli.js +173 -157
  3. package/dist/bin/internal-cli.js +42 -21
  4. package/dist/lib/agent-client.js +5 -0
  5. package/dist/lib/internal/agent-client.js +5 -2
  6. package/dist/lib/internal/cli-route-inventory.js +152 -0
  7. package/dist/lib/internal/codex-lifecycle.js +9 -6
  8. package/dist/lib/internal/codex-sandbox-controller.js +8 -2
  9. package/dist/lib/internal/git-workflow.js +10 -6
  10. package/dist/lib/internal/platform-checks.js +16 -4
  11. package/dist/lib/internal/platform-comment.js +16 -4
  12. package/dist/lib/internal/platform-context.js +4 -1
  13. package/dist/lib/internal/platform-issue.js +12 -4
  14. package/dist/lib/internal/platform-metadata.js +88 -0
  15. package/dist/lib/internal/platform-pr-review.js +16 -3
  16. package/dist/lib/internal/platform-pr.js +24 -10
  17. package/dist/lib/internal/platform-release-notes.js +6 -3
  18. package/dist/lib/internal/platform-security.js +93 -0
  19. package/dist/lib/internal/pr-review-grade.js +14 -3
  20. package/dist/lib/internal/release-workflow.js +19 -5
  21. package/dist/lib/internal/sandbox-control.js +22 -5
  22. package/dist/lib/internal/task-activity.js +13 -4
  23. package/dist/lib/internal/task-artifact.js +186 -27
  24. package/dist/lib/internal/task-context.js +4 -1
  25. package/dist/lib/internal/task-create.js +48 -15
  26. package/dist/lib/internal/task-delivery.js +4 -1
  27. package/dist/lib/internal/task-event.js +4 -1
  28. package/dist/lib/internal/task-finalization.js +4 -1
  29. package/dist/lib/internal/task-invalidation.js +4 -1
  30. package/dist/lib/internal/task-ledger.js +12 -1
  31. package/dist/lib/internal/task-lifecycle.js +4 -1
  32. package/dist/lib/internal/task-operation-registry.js +421 -0
  33. package/dist/lib/internal/task-orchestration.js +12 -0
  34. package/dist/lib/internal/task-override.js +10 -3
  35. package/dist/lib/internal/task-qualification.js +90 -0
  36. package/dist/lib/internal/task-review.js +4 -1
  37. package/dist/lib/internal/task-short-id.js +11 -1
  38. package/dist/lib/internal/task-snapshot.js +4 -1
  39. package/dist/lib/internal/task-validate.js +7 -2
  40. package/dist/lib/internal/task-verify.js +5 -1
  41. package/dist/lib/internal/task-warning.js +8 -1
  42. package/dist/lib/platform/comment-safety.js +226 -0
  43. package/dist/lib/platform/github-provider.js +233 -6
  44. package/dist/lib/platform/issue-comments.js +146 -34
  45. package/dist/lib/platform/pr-change-report.js +6 -12
  46. package/dist/lib/platform/pr-summary.js +28 -7
  47. package/dist/lib/platform/provider-contract.d.ts +67 -1
  48. package/dist/lib/platform/provider-contract.js +6 -2
  49. package/dist/lib/platform/provider-validation.js +76 -3
  50. package/dist/lib/platform/pull-requests.js +115 -170
  51. package/dist/lib/platform/repository-metadata.js +377 -0
  52. package/dist/lib/platform/security-alerts.js +155 -0
  53. package/dist/lib/platform/verification-sync.js +33 -26
  54. package/dist/lib/process-data/index.js +7 -0
  55. package/dist/lib/run/index.js +5 -0
  56. package/dist/lib/sandbox/commands/control-status.js +22 -0
  57. package/dist/lib/sandbox/commands/create.js +32 -6
  58. package/dist/lib/sandbox/commands/ls.js +5 -0
  59. package/dist/lib/sandbox/commands/rm.js +827 -120
  60. package/dist/lib/sandbox/commands/show.js +16 -0
  61. package/dist/lib/sandbox/control/client.js +83 -9
  62. package/dist/lib/sandbox/control/completed-reentry.js +85 -0
  63. package/dist/lib/sandbox/control/container-identity.js +28 -31
  64. package/dist/lib/sandbox/control/executor.js +149 -14
  65. package/dist/lib/sandbox/control/lifecycle.js +621 -127
  66. package/dist/lib/sandbox/control/native-file-lock.js +177 -0
  67. package/dist/lib/sandbox/control/server.js +305 -35
  68. package/dist/lib/sandbox/control/state.js +5 -3
  69. package/dist/lib/sandbox/control/task-view.js +183 -0
  70. package/dist/lib/sandbox/engines/authority.js +289 -0
  71. package/dist/lib/sandbox/engines/docker-exact-discovery.js +97 -0
  72. package/dist/lib/sandbox/index.js +5 -0
  73. package/dist/lib/sandbox/recovery.js +21 -1
  74. package/dist/lib/sandbox/workspace-view.js +2 -1
  75. package/dist/lib/sandbox/worktree-safety.js +4 -1
  76. package/dist/lib/server/index.js +8 -0
  77. package/dist/lib/task/artifact-lifecycle.js +42 -13
  78. package/dist/lib/task/artifact-operations.js +520 -0
  79. package/dist/lib/task/artifact-repair-intent.js +59 -0
  80. package/dist/lib/task/artifact-schema.js +135 -0
  81. package/dist/lib/task/capabilities.js +72 -1
  82. package/dist/lib/task/control-authority.js +4 -0
  83. package/dist/lib/task/create-service.js +103 -4
  84. package/dist/lib/task/create.js +25 -0
  85. package/dist/lib/task/events.js +186 -67
  86. package/dist/lib/task/index.js +11 -3
  87. package/dist/lib/task/local-artifact-finalization.js +75 -150
  88. package/dist/lib/task/orchestration.js +192 -52
  89. package/dist/lib/task/qualification-audit.js +490 -0
  90. package/dist/lib/task/qualification-confirmation.js +109 -0
  91. package/dist/lib/task/qualification-intents.js +148 -0
  92. package/dist/lib/task/review-artifacts.js +22 -23
  93. package/dist/lib/task/review-finalization.js +121 -4
  94. package/dist/lib/task/sections.js +6 -4
  95. package/dist/lib/task/verification-config.js +11 -0
  96. package/dist/lib/task/verification-engine.js +54 -4
  97. package/dist/lifecycle-build-manifest.json +3 -3
  98. package/lib/agent-client.ts +9 -0
  99. package/lib/internal/agent-client.ts +4 -2
  100. package/lib/internal/cli-route-inventory.ts +140 -0
  101. package/lib/internal/codex-lifecycle.ts +8 -6
  102. package/lib/internal/codex-sandbox-controller.ts +7 -2
  103. package/lib/internal/git-workflow.ts +9 -6
  104. package/lib/internal/platform-checks.ts +12 -4
  105. package/lib/internal/platform-comment.ts +12 -4
  106. package/lib/internal/platform-context.ts +3 -1
  107. package/lib/internal/platform-issue.ts +11 -4
  108. package/lib/internal/platform-metadata.ts +70 -0
  109. package/lib/internal/platform-pr-review.ts +14 -3
  110. package/lib/internal/platform-pr.ts +23 -10
  111. package/lib/internal/platform-release-notes.ts +5 -3
  112. package/lib/internal/platform-security.ts +83 -0
  113. package/lib/internal/pr-review-grade.ts +10 -3
  114. package/lib/internal/release-workflow.ts +17 -5
  115. package/lib/internal/sandbox-control.ts +19 -5
  116. package/lib/internal/task-activity.ts +12 -4
  117. package/lib/internal/task-artifact.ts +164 -25
  118. package/lib/internal/task-context.ts +3 -1
  119. package/lib/internal/task-create.ts +76 -15
  120. package/lib/internal/task-delivery.ts +3 -1
  121. package/lib/internal/task-event.ts +3 -1
  122. package/lib/internal/task-finalization.ts +3 -1
  123. package/lib/internal/task-invalidation.ts +3 -1
  124. package/lib/internal/task-ledger.ts +11 -1
  125. package/lib/internal/task-lifecycle.ts +3 -1
  126. package/lib/internal/task-operation-registry.ts +482 -0
  127. package/lib/internal/task-orchestration.ts +12 -0
  128. package/lib/internal/task-override.ts +9 -3
  129. package/lib/internal/task-qualification.ts +61 -0
  130. package/lib/internal/task-review.ts +3 -1
  131. package/lib/internal/task-short-id.ts +10 -1
  132. package/lib/internal/task-snapshot.ts +3 -1
  133. package/lib/internal/task-validate.ts +6 -2
  134. package/lib/internal/task-verify.ts +4 -1
  135. package/lib/internal/task-warning.ts +7 -1
  136. package/lib/platform/comment-safety.ts +250 -0
  137. package/lib/platform/github-provider.ts +229 -7
  138. package/lib/platform/issue-comments.ts +160 -35
  139. package/lib/platform/pr-change-report.ts +6 -12
  140. package/lib/platform/pr-summary.ts +27 -6
  141. package/lib/platform/provider-contract.ts +78 -3
  142. package/lib/platform/provider-validation.ts +85 -3
  143. package/lib/platform/pull-requests.ts +126 -178
  144. package/lib/platform/repository-metadata.ts +453 -0
  145. package/lib/platform/security-alerts.ts +191 -0
  146. package/lib/platform/verification-sync.ts +32 -28
  147. package/lib/process-data/index.ts +7 -0
  148. package/lib/run/index.ts +5 -0
  149. package/lib/sandbox/commands/control-status.ts +26 -0
  150. package/lib/sandbox/commands/create.ts +46 -6
  151. package/lib/sandbox/commands/ls.ts +7 -0
  152. package/lib/sandbox/commands/rm.ts +1000 -87
  153. package/lib/sandbox/commands/show.ts +16 -0
  154. package/lib/sandbox/control/client.ts +103 -9
  155. package/lib/sandbox/control/completed-reentry.ts +98 -0
  156. package/lib/sandbox/control/container-identity.ts +27 -43
  157. package/lib/sandbox/control/executor.ts +177 -12
  158. package/lib/sandbox/control/lifecycle.ts +629 -17
  159. package/lib/sandbox/control/native-file-lock.ts +209 -0
  160. package/lib/sandbox/control/protocol.ts +5 -2
  161. package/lib/sandbox/control/server.ts +319 -37
  162. package/lib/sandbox/control/state.ts +6 -3
  163. package/lib/sandbox/control/task-view.ts +240 -0
  164. package/lib/sandbox/engines/authority.ts +365 -0
  165. package/lib/sandbox/engines/docker-exact-discovery.ts +132 -0
  166. package/lib/sandbox/index.ts +7 -0
  167. package/lib/sandbox/recovery.ts +21 -1
  168. package/lib/sandbox/workspace-view.ts +9 -3
  169. package/lib/sandbox/worktree-safety.ts +4 -1
  170. package/lib/server/index.ts +10 -0
  171. package/lib/task/artifact-lifecycle.ts +38 -16
  172. package/lib/task/artifact-operations.ts +626 -0
  173. package/lib/task/artifact-repair-intent.ts +71 -0
  174. package/lib/task/artifact-schema.ts +192 -0
  175. package/lib/task/capabilities.ts +70 -1
  176. package/lib/task/control-authority.ts +11 -1
  177. package/lib/task/create-service.ts +131 -6
  178. package/lib/task/create.ts +27 -0
  179. package/lib/task/events.ts +161 -65
  180. package/lib/task/index.ts +16 -3
  181. package/lib/task/local-artifact-finalization.ts +87 -218
  182. package/lib/task/orchestration.ts +172 -49
  183. package/lib/task/qualification-audit.ts +599 -0
  184. package/lib/task/qualification-confirmation.ts +117 -0
  185. package/lib/task/qualification-intents.ts +150 -0
  186. package/lib/task/review-artifacts.ts +21 -22
  187. package/lib/task/review-finalization.ts +133 -4
  188. package/lib/task/sections.ts +6 -4
  189. package/lib/task/verification-config.ts +12 -0
  190. package/lib/task/verification-engine.ts +55 -4
  191. package/package.json +6 -1
  192. package/templates/.agents/rules/README.en.md +2 -0
  193. package/templates/.agents/rules/README.zh-CN.md +2 -0
  194. package/templates/.agents/rules/decision-qualification.en.md +22 -0
  195. package/templates/.agents/rules/decision-qualification.zh-CN.md +22 -0
  196. package/templates/.agents/rules/evidence-reporting.en.md +28 -0
  197. package/templates/.agents/rules/evidence-reporting.zh-CN.md +28 -0
  198. package/templates/.agents/rules/label-milestone-setup.en.md +7 -7
  199. package/templates/.agents/rules/label-milestone-setup.zh-CN.md +7 -7
  200. package/templates/.agents/rules/local-artifact-repair.en.md +5 -1
  201. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +5 -1
  202. package/templates/.agents/rules/security-alerts.en.md +8 -8
  203. package/templates/.agents/rules/security-alerts.zh-CN.md +8 -8
  204. package/templates/.agents/skills/analyze-task/SKILL.en.md +15 -2
  205. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +19 -2
  206. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -12
  207. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -12
  208. package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
  209. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
  210. package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
  211. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
  212. package/templates/.agents/skills/code-task/SKILL.en.md +14 -1
  213. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +14 -1
  214. package/templates/.agents/skills/code-task/config/verify.en.json +5 -14
  215. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +5 -14
  216. package/templates/.agents/skills/code-task/reference/code-rules.en.md +5 -4
  217. package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +5 -4
  218. package/templates/.agents/skills/code-task/reference/dual-mode.en.md +1 -1
  219. package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +1 -1
  220. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +3 -1
  221. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +3 -1
  222. package/templates/.agents/skills/code-task/reference/report-template.en.md +42 -15
  223. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +39 -12
  224. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +5 -1
  225. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +5 -1
  226. package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +2 -0
  227. package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +2 -0
  228. package/templates/.agents/skills/complete-task/SKILL.en.md +9 -22
  229. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +9 -22
  230. package/templates/.agents/skills/create-task/SKILL.en.md +8 -0
  231. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +7 -0
  232. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  233. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  234. package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
  235. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
  236. package/templates/.agents/skills/init-labels/SKILL.en.md +8 -8
  237. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +8 -8
  238. package/templates/.agents/skills/init-milestones/SKILL.en.md +9 -11
  239. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +9 -11
  240. package/templates/.agents/skills/plan-task/SKILL.en.md +14 -1
  241. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +16 -1
  242. package/templates/.agents/skills/plan-task/config/verify.en.json +4 -14
  243. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +4 -14
  244. package/templates/.agents/skills/review-analysis/SKILL.en.md +14 -1
  245. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +14 -1
  246. package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -18
  247. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -18
  248. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +50 -23
  249. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +45 -18
  250. package/templates/.agents/skills/review-code/SKILL.en.md +14 -1
  251. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +14 -1
  252. package/templates/.agents/skills/review-code/config/verify.en.json +1 -23
  253. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -23
  254. package/templates/.agents/skills/review-code/reference/report-template.en.md +49 -22
  255. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +45 -18
  256. package/templates/.agents/skills/review-plan/SKILL.en.md +14 -1
  257. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +14 -1
  258. package/templates/.agents/skills/review-plan/config/verify.en.json +1 -18
  259. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -18
  260. package/templates/.agents/skills/review-plan/reference/report-template.en.md +49 -22
  261. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +45 -18
  262. package/templates/.agents/skills/review-pr/SKILL.en.md +5 -1
  263. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +5 -1
  264. package/templates/.agents/skills/review-pr/reference/report-template.en.md +4 -3
  265. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +4 -3
  266. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +5 -1
  267. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +5 -1
  268. package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +3 -1
  269. package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +3 -1
  270. package/templates/.agents/skills/test/SKILL.en.md +13 -2
  271. package/templates/.agents/skills/test/SKILL.zh-CN.md +13 -2
  272. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +14 -0
  273. package/templates/.agents/templates/task.en.md +6 -0
  274. package/templates/.agents/templates/task.zh-CN.md +6 -0
  275. package/templates/.agents/scripts/security-alerts.github.sh +0 -151
  276. package/templates/.agents/scripts/security-alerts.sh +0 -31
  277. package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +0 -146
  278. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +0 -32
  279. package/templates/.agents/skills/init-milestones/scripts/init-milestones.github.sh +0 -294
  280. package/templates/.agents/skills/init-milestones/scripts/init-milestones.sh +0 -6
@@ -0,0 +1,209 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { createRequire } from 'node:module';
3
+ import fs from 'node:fs';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+
7
+ type NativeFsExt = Readonly<{
8
+ flockSync: (fd: number, flags: string) => void;
9
+ lockFileExSync: (fd: number, flags: number, offsetLow: number, offsetHigh: number, lengthLow: number, lengthHigh: number) => void;
10
+ unlockFileExSync: (fd: number, offsetLow: number, offsetHigh: number, lengthLow: number, lengthHigh: number) => void;
11
+ constants: Readonly<{
12
+ LOCKFILE_EXCLUSIVE_LOCK: number;
13
+ LOCKFILE_FAIL_IMMEDIATELY: number;
14
+ }>;
15
+ getNativeModuleSource?: () => string;
16
+ }>;
17
+
18
+ export type SandboxLockCapability = Readonly<{
19
+ supported: boolean;
20
+ primitive: 'flock' | 'LockFileEx' | 'unavailable';
21
+ binarySource: string | null;
22
+ reason?: string;
23
+ }>;
24
+
25
+ export type SandboxLockNamespace = Readonly<{
26
+ lockRoot: string;
27
+ domainDirectory: string;
28
+ lockDomain: string;
29
+ carrierIdentityDigest: string;
30
+ lockPath: string;
31
+ }>;
32
+
33
+ export type SandboxResourceLock = Readonly<{
34
+ path: string;
35
+ lockDomain: string;
36
+ release(): void;
37
+ }>;
38
+
39
+ const require = createRequire(import.meta.url);
40
+ const LOCK_ROOT_NAME = path.join('.agent-infra', 'sandbox-locks');
41
+
42
+ function loadNative(): NativeFsExt {
43
+ try {
44
+ return require('fs-ext-extra-prebuilt') as NativeFsExt;
45
+ } catch {
46
+ throw new Error('SANDBOX_LOCK_UNSUPPORTED: native lock module is unavailable');
47
+ }
48
+ }
49
+
50
+ function digest(value: string): string {
51
+ return createHash('sha256').update(value).digest('hex');
52
+ }
53
+
54
+ function assertPrivateDirectory(directory: string, home: string): void {
55
+ const resolvedHome = path.resolve(home);
56
+ let current = resolvedHome;
57
+ const relative = path.relative(resolvedHome, path.resolve(directory));
58
+ if (!relative || relative.startsWith('..') || path.isAbsolute(relative)) {
59
+ throw new Error('SANDBOX_LOCK_UNSUPPORTED: lock root must be below the user home');
60
+ }
61
+ for (const segment of relative.split(path.sep).filter(Boolean)) {
62
+ current = path.join(current, segment);
63
+ if (fs.existsSync(current)) {
64
+ const stat = fs.lstatSync(current);
65
+ if (stat.isSymbolicLink() || !stat.isDirectory()) {
66
+ throw new Error('SANDBOX_LOCK_UNSUPPORTED: lock namespace contains a link or non-directory');
67
+ }
68
+ if (process.platform !== 'win32' && typeof process.getuid === 'function'
69
+ && stat.uid !== process.getuid()) {
70
+ throw new Error('SANDBOX_LOCK_UNSUPPORTED: lock namespace owner mismatch');
71
+ }
72
+ } else {
73
+ try {
74
+ fs.mkdirSync(current, { mode: 0o700 });
75
+ } catch (error) {
76
+ if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;
77
+ const stat = fs.lstatSync(current);
78
+ if (stat.isSymbolicLink() || !stat.isDirectory()) {
79
+ throw new Error('SANDBOX_LOCK_UNSUPPORTED: lock namespace contains a link or non-directory');
80
+ }
81
+ }
82
+ }
83
+ if (process.platform !== 'win32') fs.chmodSync(current, 0o700);
84
+ }
85
+ const real = fs.realpathSync.native(path.resolve(directory));
86
+ const realRelative = path.relative(fs.realpathSync.native(resolvedHome), real);
87
+ if (!realRelative || realRelative.startsWith('..') || path.isAbsolute(realRelative)) {
88
+ throw new Error('SANDBOX_LOCK_UNSUPPORTED: lock namespace realpath escapes the user home');
89
+ }
90
+ }
91
+
92
+ export function resolveSandboxLockNamespace(
93
+ carrierIdentity: string,
94
+ options: Readonly<{ lockDomain?: string; home?: string }> = {}
95
+ ): SandboxLockNamespace {
96
+ if (!carrierIdentity.trim()) throw new Error('SANDBOX_LOCK_IDENTITY_INVALID');
97
+ const home = path.resolve(options.home ?? os.homedir());
98
+ const lockRoot = path.join(home, LOCK_ROOT_NAME);
99
+ assertPrivateDirectory(lockRoot, home);
100
+ const primitive = process.platform === 'win32' ? 'LockFileEx' : 'flock';
101
+ const lockDomain = options.lockDomain ?? digest(`${process.platform}\0${process.arch}\0${primitive}`);
102
+ if (!/^[a-f0-9]{64}$/u.test(lockDomain)) throw new Error('SANDBOX_LOCK_DOMAIN_INVALID');
103
+ const domainDirectory = path.join(lockRoot, lockDomain);
104
+ assertPrivateDirectory(domainDirectory, home);
105
+ const carrierIdentityDigest = digest(carrierIdentity);
106
+ return {
107
+ lockRoot,
108
+ domainDirectory,
109
+ lockDomain,
110
+ carrierIdentityDigest,
111
+ lockPath: path.join(domainDirectory, `${carrierIdentityDigest}.lock`)
112
+ };
113
+ }
114
+
115
+ export function stableSandboxLockPath(
116
+ carrierIdentity: string,
117
+ lockDomain?: string,
118
+ options: Readonly<{ home?: string }> = {}
119
+ ): string {
120
+ return resolveSandboxLockNamespace(carrierIdentity, { lockDomain, home: options.home }).lockPath;
121
+ }
122
+
123
+ export function probeNativeLockCapability(): SandboxLockCapability {
124
+ try {
125
+ const native = loadNative();
126
+ return {
127
+ supported: true,
128
+ primitive: process.platform === 'win32' ? 'LockFileEx' : 'flock',
129
+ binarySource: native.getNativeModuleSource?.() ?? null
130
+ };
131
+ } catch (error) {
132
+ return {
133
+ supported: false,
134
+ primitive: 'unavailable',
135
+ binarySource: null,
136
+ reason: error instanceof Error ? error.message : String(error)
137
+ };
138
+ }
139
+ }
140
+
141
+ export function acquireSandboxResourceLock(
142
+ carrierIdentity: string,
143
+ options: Readonly<{ lockDomain?: string; home?: string }> = {}
144
+ ): SandboxResourceLock {
145
+ const native = loadNative();
146
+ const namespace = resolveSandboxLockNamespace(carrierIdentity, options);
147
+ if (fs.existsSync(namespace.lockPath)) {
148
+ const existing = fs.lstatSync(namespace.lockPath);
149
+ if (existing.isSymbolicLink() || !existing.isFile()) {
150
+ throw new Error('SANDBOX_LOCK_UNSUPPORTED: lock object is not a regular file');
151
+ }
152
+ if (process.platform !== 'win32' && typeof process.getuid === 'function'
153
+ && existing.uid !== process.getuid()) {
154
+ throw new Error('SANDBOX_LOCK_UNSUPPORTED: lock object owner mismatch');
155
+ }
156
+ }
157
+ let fd: number | undefined;
158
+ try {
159
+ const noFollow = process.platform !== 'win32' && typeof fs.constants.O_NOFOLLOW === 'number'
160
+ ? fs.constants.O_NOFOLLOW : 0;
161
+ fd = fs.openSync(namespace.lockPath, fs.constants.O_CREAT | fs.constants.O_RDWR | noFollow, 0o600);
162
+ if (process.platform !== 'win32') fs.chmodSync(namespace.lockPath, 0o600);
163
+ if (process.platform === 'win32') {
164
+ native.lockFileExSync(
165
+ fd,
166
+ native.constants.LOCKFILE_EXCLUSIVE_LOCK | native.constants.LOCKFILE_FAIL_IMMEDIATELY,
167
+ 0, 0, 1, 0
168
+ );
169
+ } else {
170
+ native.flockSync(fd, 'exnb');
171
+ }
172
+ } catch (error) {
173
+ try {
174
+ if (fd !== undefined) fs.closeSync(fd);
175
+ } catch {
176
+ // Preserve the lock acquisition error.
177
+ }
178
+ const code = error && typeof error === 'object' && 'code' in error ? String((error as { code?: unknown }).code) : '';
179
+ if (['EAGAIN', 'EACCES', 'EWOULDBLOCK'].includes(code)) {
180
+ throw new Error('SANDBOX_LOCK_BUSY');
181
+ }
182
+ throw new Error(`SANDBOX_LOCK_UNSUPPORTED: ${error instanceof Error ? error.message : String(error)}`);
183
+ }
184
+
185
+ let released = false;
186
+ return {
187
+ path: namespace.lockPath,
188
+ lockDomain: namespace.lockDomain,
189
+ release() {
190
+ if (released) return;
191
+ released = true;
192
+ let failure: unknown = null;
193
+ try {
194
+ if (fd === undefined) throw new Error('descriptor is missing');
195
+ if (process.platform === 'win32') native.unlockFileExSync(fd, 0, 0, 1, 0);
196
+ else native.flockSync(fd, 'un');
197
+ } catch (error) {
198
+ failure = error;
199
+ } finally {
200
+ try {
201
+ if (fd !== undefined) fs.closeSync(fd);
202
+ } catch (error) {
203
+ failure ??= error;
204
+ }
205
+ }
206
+ if (failure) throw new Error(`SANDBOX_LOCK_RELEASE_FAILED: ${failure instanceof Error ? failure.message : String(failure)}`);
207
+ }
208
+ };
209
+ }
@@ -3,6 +3,8 @@ import { validateTaskCreateCandidate, type TaskCreateCandidateV1 } from '../../t
3
3
  import { normalizeAgentToken } from '../../agent-clients/tokens.ts';
4
4
  import type { ProcessIdentity } from '../../server/process-state.ts';
5
5
  import type { CodexControllerLeaseProofV1 } from './controller-registration.ts';
6
+ import type { SandboxAuthorityEvidenceV1 } from '../engines/authority.ts';
7
+ import type { SandboxTaskView } from './task-view.ts';
6
8
 
7
9
  export const SANDBOX_CONTROL_MAX_BYTES = 64 * 1024;
8
10
  export const SANDBOX_CONTROL_MAX_LOGICAL_RECORDS = 1024;
@@ -37,6 +39,7 @@ export type SandboxControlContainerIdentity = Readonly<{
37
39
  export type SandboxControlManifestBase = Readonly<{
38
40
  engine: string; repoRoot: string; worktreeRoot: string; project: string; container: string;
39
41
  containerIdentity: SandboxControlContainerIdentity;
42
+ authorityEvidence: SandboxAuthorityEvidenceV1;
40
43
  branch: string; mode: 'task-bound' | 'branch-only'; taskId: string | null; token: string;
41
44
  generation: string; channelDir: string; publicStatusDir: string; processingDir: string;
42
45
  }>;
@@ -107,9 +110,9 @@ export type SandboxControlResponse = Readonly<{
107
110
  payload?: SandboxControlPayloadReference | null;
108
111
  }>;
109
112
  export type SandboxControlStatus = Readonly<{
110
- version: 2; generation: string; broker: ProcessIdentity & { brokerId: string };
113
+ version: 3; generation: string; broker: ProcessIdentity & { brokerId: string };
111
114
  state: 'starting' | 'healthy' | 'busy' | 'parked'; reasonCode: string | null;
112
- activeRequestId: string | null; updatedAt: number;
115
+ activeRequestId: string | null; updatedAt: number; taskView: SandboxTaskView;
113
116
  }>;
114
117
  export type SandboxControlLease = Readonly<{
115
118
  version: 2; generation: string; nonce: string; owner: ProcessIdentity;