@straiffi/archon 1.8.22 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/dist/client/assets/{ActivityView-CdEPjmqD.js → ActivityView-Y5IaJiim.js} +1 -1
  2. package/dist/client/assets/GitHubActionsDialog-GWVxWGPK.js +1 -0
  3. package/dist/client/assets/VerificationDialog-C4RMuI4y.js +4 -0
  4. package/dist/client/assets/{architectureDiagram-3BPJPVTR-BrZ08mqq.js → architectureDiagram-3BPJPVTR-CeM6gbLN.js} +1 -1
  5. package/dist/client/assets/{blockDiagram-GPEHLZMM-b93XwJ6Z.js → blockDiagram-GPEHLZMM-BP4hta96.js} +1 -1
  6. package/dist/client/assets/{c4Diagram-AAUBKEIU-BKOdbZ_v.js → c4Diagram-AAUBKEIU-5aJScvhn.js} +1 -1
  7. package/dist/client/assets/channel-B3DjZXbm.js +1 -0
  8. package/dist/client/assets/{chunk-2J33WTMH-D7Vxn_1m.js → chunk-2J33WTMH-BKc2IelV.js} +1 -1
  9. package/dist/client/assets/{chunk-3OPIFGDE-B1zo2UZq.js → chunk-3OPIFGDE-DCc15la5.js} +1 -1
  10. package/dist/client/assets/{chunk-5ZQYHXKU-BajvkDdQ.js → chunk-5ZQYHXKU-DSD9HbTp.js} +1 -1
  11. package/dist/client/assets/{chunk-727SXJPM-CSH7cVpV.js → chunk-727SXJPM-DrAjnKiA.js} +1 -1
  12. package/dist/client/assets/{chunk-AQP2D5EJ-DE-wgUNP.js → chunk-AQP2D5EJ-DxKnpHfQ.js} +1 -1
  13. package/dist/client/assets/{chunk-CSCIHK7Q-Ba7JgCEf.js → chunk-CSCIHK7Q-DLejrAB_.js} +1 -1
  14. package/dist/client/assets/{chunk-KSCS5N6A-0o3YWkHM.js → chunk-KSCS5N6A-BWRNmF8S.js} +1 -1
  15. package/dist/client/assets/{chunk-L5ZTLDWV-DihWczP8.js → chunk-L5ZTLDWV-D48i966f.js} +1 -1
  16. package/dist/client/assets/{chunk-LZXEDZCA-Bxnu-hme.js → chunk-LZXEDZCA-DLhg6Bok.js} +2 -2
  17. package/dist/client/assets/{chunk-ND2GUHAM-CoaR5kmP.js → chunk-ND2GUHAM-B4-7cOEq.js} +1 -1
  18. package/dist/client/assets/{chunk-NZK2D7GU-By92Rd3d.js → chunk-NZK2D7GU-D2ttXA_d.js} +1 -1
  19. package/dist/client/assets/{chunk-O5CBEL6O-D83Pkgfu.js → chunk-O5CBEL6O-BrWrOVCq.js} +1 -1
  20. package/dist/client/assets/{chunk-WU5MYG2G-v8OVf5Lz.js → chunk-WU5MYG2G-CLcPwxPe.js} +1 -1
  21. package/dist/client/assets/classDiagram-4FO5ZUOK-DproSkn2.js +1 -0
  22. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-JVMMzJxJ.js +1 -0
  23. package/dist/client/assets/{dagre-BM42HDAG-Dq1ALF7Z.js → dagre-BM42HDAG-DIXN8_VX.js} +1 -1
  24. package/dist/client/assets/{diagram-2AECGRRQ-1t1_TKtu.js → diagram-2AECGRRQ-D2wjdCij.js} +1 -1
  25. package/dist/client/assets/{diagram-5GNKFQAL-DtvYRL6f.js → diagram-5GNKFQAL-E1Og_PHE.js} +1 -1
  26. package/dist/client/assets/{diagram-KO2AKTUF-PRNrSX5F.js → diagram-KO2AKTUF-B6P1Ud8a.js} +1 -1
  27. package/dist/client/assets/{diagram-LMA3HP47-DaTX0DhT.js → diagram-LMA3HP47-C3Jxq56v.js} +1 -1
  28. package/dist/client/assets/{diagram-OG6HWLK6-C2p9p-92.js → diagram-OG6HWLK6-Do9LVhdL.js} +1 -1
  29. package/dist/client/assets/{erDiagram-TEJ5UH35-DKzLtnp-.js → erDiagram-TEJ5UH35-DLb5E4-f.js} +1 -1
  30. package/dist/client/assets/{flowDiagram-I6XJVG4X-GdL8lm6e.js → flowDiagram-I6XJVG4X-CcTs_wU9.js} +1 -1
  31. package/dist/client/assets/{ganttDiagram-6RSMTGT7-Ok-4XYwT.js → ganttDiagram-6RSMTGT7-q9ez5fri.js} +1 -1
  32. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-DSMrOCK7.js → gitGraphDiagram-PVQCEYII-BcaKiz4c.js} +1 -1
  33. package/dist/client/assets/index-1CokwSFm.css +2 -0
  34. package/dist/client/assets/index-CSOKbu3w.js +276 -0
  35. package/dist/client/assets/{infoDiagram-5YYISTIA-Dl4hRXis.js → infoDiagram-5YYISTIA-Cu0w4frE.js} +1 -1
  36. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-C1Dc1fTT.js → ishikawaDiagram-YF4QCWOH-CJ47Z-ak.js} +1 -1
  37. package/dist/client/assets/{journeyDiagram-JHISSGLW-CUscmJze.js → journeyDiagram-JHISSGLW-fAL_Zcvs.js} +1 -1
  38. package/dist/client/assets/{kanban-definition-UN3LZRKU-C0nwYjQV.js → kanban-definition-UN3LZRKU-BTNIybMC.js} +1 -1
  39. package/dist/client/assets/{line-ByiuEIg_.js → line-BvsadeZR.js} +1 -1
  40. package/dist/client/assets/{mermaid-parser.core-B-XdAyDR.js → mermaid-parser.core-C0EkH2y_.js} +1 -1
  41. package/dist/client/assets/{mermaid.core-D_bIfuZD.js → mermaid.core-BU5QIIbY.js} +3 -3
  42. package/dist/client/assets/{mindmap-definition-RKZ34NQL-BGNiPJDK.js → mindmap-definition-RKZ34NQL-CWbSYK8f.js} +1 -1
  43. package/dist/client/assets/{pieDiagram-4H26LBE5-CP6FpAoO.js → pieDiagram-4H26LBE5-t4w2cB-y.js} +1 -1
  44. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-dsAWBAQn.js → quadrantDiagram-W4KKPZXB-Cqasvrpa.js} +1 -1
  45. package/dist/client/assets/{requirementDiagram-4Y6WPE33-DJH-zHqF.js → requirementDiagram-4Y6WPE33-_l-mY-tb.js} +1 -1
  46. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-BJMnZrqH.js → sankeyDiagram-5OEKKPKP-Cr9YrZ-Y.js} +1 -1
  47. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-CzNjUSlM.js → sequenceDiagram-3UESZ5HK-DvzZhQpb.js} +1 -1
  48. package/dist/client/assets/{stateDiagram-AJRCARHV-jppMhOwh.js → stateDiagram-AJRCARHV-cFjPpAO3.js} +1 -1
  49. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-btHMH5Cg.js +1 -0
  50. package/dist/client/assets/{timeline-definition-PNZ67QCA-BX2CI5H_.js → timeline-definition-PNZ67QCA-BjRNrEJY.js} +1 -1
  51. package/dist/client/assets/{vennDiagram-CIIHVFJN-Bd1KZaXh.js → vennDiagram-CIIHVFJN-xs9afjrw.js} +1 -1
  52. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-D-0BNz49.js → wardleyDiagram-YWT4CUSO-DH68ZYti.js} +1 -1
  53. package/dist/client/assets/{xychartDiagram-2RQKCTM6-DbYa0ZWK.js → xychartDiagram-2RQKCTM6-DLW5ktTU.js} +1 -1
  54. package/dist/client/index.html +2 -2
  55. package/dist/server/db.js +231 -14
  56. package/dist/server/db.js.map +1 -1
  57. package/dist/server/index.js +93 -9
  58. package/dist/server/index.js.map +1 -1
  59. package/dist/server/lib/agent.js +368 -143
  60. package/dist/server/lib/agent.js.map +1 -1
  61. package/dist/server/lib/agentProvider.js.map +1 -1
  62. package/dist/server/lib/approvalReconciliation.js +14 -2
  63. package/dist/server/lib/approvalReconciliation.js.map +1 -1
  64. package/dist/server/lib/buildExecutionEnvironment.js +251 -57
  65. package/dist/server/lib/buildExecutionEnvironment.js.map +1 -1
  66. package/dist/server/lib/chatOperations.js +125 -3
  67. package/dist/server/lib/chatOperations.js.map +1 -1
  68. package/dist/server/lib/chatPostBuildRuns.js +12 -6
  69. package/dist/server/lib/chatPostBuildRuns.js.map +1 -1
  70. package/dist/server/lib/chatTargets.js +2 -1
  71. package/dist/server/lib/chatTargets.js.map +1 -1
  72. package/dist/server/lib/checkDefinitionCwd.js +34 -0
  73. package/dist/server/lib/checkDefinitionCwd.js.map +1 -0
  74. package/dist/server/lib/checkExecutionEnvironment.js +95 -0
  75. package/dist/server/lib/checkExecutionEnvironment.js.map +1 -0
  76. package/dist/server/lib/checkPolicyDefinitionIds.js +41 -0
  77. package/dist/server/lib/checkPolicyDefinitionIds.js.map +1 -0
  78. package/dist/server/lib/checkRepairDispatch.js +2 -0
  79. package/dist/server/lib/checkRepairDispatch.js.map +1 -1
  80. package/dist/server/lib/checkRunner.js +371 -175
  81. package/dist/server/lib/checkRunner.js.map +1 -1
  82. package/dist/server/lib/checkRuns.js +99 -8
  83. package/dist/server/lib/checkRuns.js.map +1 -1
  84. package/dist/server/lib/claudeAgentProvider.js +3 -6
  85. package/dist/server/lib/claudeAgentProvider.js.map +1 -1
  86. package/dist/server/lib/claudeStdin.js +27 -0
  87. package/dist/server/lib/claudeStdin.js.map +1 -0
  88. package/dist/server/lib/completedAssistantOutput.js +38 -0
  89. package/dist/server/lib/completedAssistantOutput.js.map +1 -0
  90. package/dist/server/lib/consequentialActionAuthority.js +99 -8
  91. package/dist/server/lib/consequentialActionAuthority.js.map +1 -1
  92. package/dist/server/lib/consequentialActions.js +42 -2
  93. package/dist/server/lib/consequentialActions.js.map +1 -1
  94. package/dist/server/lib/dockerSandboxCredentials.js +10 -3
  95. package/dist/server/lib/dockerSandboxCredentials.js.map +1 -1
  96. package/dist/server/lib/dockerSandboxEnvironmentOperations.js +9 -8
  97. package/dist/server/lib/dockerSandboxEnvironmentOperations.js.map +1 -1
  98. package/dist/server/lib/dockerSandboxExecutionEnvironment.js +167 -75
  99. package/dist/server/lib/dockerSandboxExecutionEnvironment.js.map +1 -1
  100. package/dist/server/lib/dockerSandboxExecutionProvider.js +22 -14
  101. package/dist/server/lib/dockerSandboxExecutionProvider.js.map +1 -1
  102. package/dist/server/lib/dockerSandboxNetworkPolicy.js +23 -14
  103. package/dist/server/lib/dockerSandboxNetworkPolicy.js.map +1 -1
  104. package/dist/server/lib/dockerSandboxReleaseProfiles.js +91 -0
  105. package/dist/server/lib/dockerSandboxReleaseProfiles.js.map +1 -0
  106. package/dist/server/lib/dockerSandboxRuntimeController.js +16 -1
  107. package/dist/server/lib/dockerSandboxRuntimeController.js.map +1 -1
  108. package/dist/server/lib/executionCredentialCapabilities.js +9 -6
  109. package/dist/server/lib/executionCredentialCapabilities.js.map +1 -1
  110. package/dist/server/lib/executionEnvironment.js.map +1 -1
  111. package/dist/server/lib/executionEnvironmentLifecycle.js +7 -0
  112. package/dist/server/lib/executionEnvironmentLifecycle.js.map +1 -1
  113. package/dist/server/lib/executionEnvironmentOperations.js +241 -0
  114. package/dist/server/lib/executionEnvironmentOperations.js.map +1 -0
  115. package/dist/server/lib/executionEnvironmentReconciliation.js +98 -3
  116. package/dist/server/lib/executionEnvironmentReconciliation.js.map +1 -1
  117. package/dist/server/lib/executionEnvironmentRoutes.js +83 -29
  118. package/dist/server/lib/executionEnvironmentRoutes.js.map +1 -1
  119. package/dist/server/lib/executionEnvironmentValidation.js +19 -5
  120. package/dist/server/lib/executionEnvironmentValidation.js.map +1 -1
  121. package/dist/server/lib/executionEnvironmentValidationOperations.js +58 -31
  122. package/dist/server/lib/executionEnvironmentValidationOperations.js.map +1 -1
  123. package/dist/server/lib/executionEnvironments.js +187 -9
  124. package/dist/server/lib/executionEnvironments.js.map +1 -1
  125. package/dist/server/lib/executionProfileCheckPolicy.js +14 -0
  126. package/dist/server/lib/executionProfileCheckPolicy.js.map +1 -0
  127. package/dist/server/lib/executionProfileRoutes.js +9 -1
  128. package/dist/server/lib/executionProfileRoutes.js.map +1 -1
  129. package/dist/server/lib/executionProfileStore.js +5 -3
  130. package/dist/server/lib/executionProfileStore.js.map +1 -1
  131. package/dist/server/lib/executionProfiles.js +97 -15
  132. package/dist/server/lib/executionProfiles.js.map +1 -1
  133. package/dist/server/lib/executionReconciliation.js +43 -6
  134. package/dist/server/lib/executionReconciliation.js.map +1 -1
  135. package/dist/server/lib/executionRunAuthority.js +115 -24
  136. package/dist/server/lib/executionRunAuthority.js.map +1 -1
  137. package/dist/server/lib/executionTargets.js +30 -4
  138. package/dist/server/lib/executionTargets.js.map +1 -1
  139. package/dist/server/lib/executionWorkloads.js +75 -0
  140. package/dist/server/lib/executionWorkloads.js.map +1 -0
  141. package/dist/server/lib/git.js +10 -1
  142. package/dist/server/lib/git.js.map +1 -1
  143. package/dist/server/lib/opencodeAgentProvider.js +3 -1
  144. package/dist/server/lib/opencodeAgentProvider.js.map +1 -1
  145. package/dist/server/lib/opencodeSessionOperations.js +5 -3
  146. package/dist/server/lib/opencodeSessionOperations.js.map +1 -1
  147. package/dist/server/lib/planQuestions.js +2 -1
  148. package/dist/server/lib/planQuestions.js.map +1 -1
  149. package/dist/server/lib/postBuildCheckRuns.js +9 -5
  150. package/dist/server/lib/postBuildCheckRuns.js.map +1 -1
  151. package/dist/server/lib/preview.js +47 -6
  152. package/dist/server/lib/preview.js.map +1 -1
  153. package/dist/server/lib/previewProxy.js +11 -3
  154. package/dist/server/lib/previewProxy.js.map +1 -1
  155. package/dist/server/lib/productionCheckApprovals.js +97 -35
  156. package/dist/server/lib/productionCheckApprovals.js.map +1 -1
  157. package/dist/server/lib/projectMemorySuggestions.js +29 -6
  158. package/dist/server/lib/projectMemorySuggestions.js.map +1 -1
  159. package/dist/server/lib/requiredCheckPolicy.js +3 -40
  160. package/dist/server/lib/requiredCheckPolicy.js.map +1 -1
  161. package/dist/server/lib/reviewAgentWatchdog.js +75 -0
  162. package/dist/server/lib/reviewAgentWatchdog.js.map +1 -0
  163. package/dist/server/lib/reviewFindingReconciliation.js +176 -0
  164. package/dist/server/lib/reviewFindingReconciliation.js.map +1 -0
  165. package/dist/server/lib/reviewFindings.js +45 -17
  166. package/dist/server/lib/reviewFindings.js.map +1 -1
  167. package/dist/server/lib/run.js +370 -80
  168. package/dist/server/lib/run.js.map +1 -1
  169. package/dist/server/lib/serviceRuns.js +196 -0
  170. package/dist/server/lib/serviceRuns.js.map +1 -0
  171. package/dist/server/lib/sessionTargets.js +34 -0
  172. package/dist/server/lib/sessionTargets.js.map +1 -1
  173. package/dist/server/lib/shell.js +20 -0
  174. package/dist/server/lib/shell.js.map +1 -1
  175. package/dist/server/lib/specArtifact.js +36 -15
  176. package/dist/server/lib/specArtifact.js.map +1 -1
  177. package/dist/server/lib/specBundleGroups.js +4 -4
  178. package/dist/server/lib/specBundleGroups.js.map +1 -1
  179. package/dist/server/lib/specOperations.js +2 -0
  180. package/dist/server/lib/specOperations.js.map +1 -1
  181. package/dist/server/lib/specReviewOperations.js +2 -0
  182. package/dist/server/lib/specReviewOperations.js.map +1 -1
  183. package/dist/server/lib/specTicketMaterialization.js +37 -24
  184. package/dist/server/lib/specTicketMaterialization.js.map +1 -1
  185. package/dist/server/lib/ticketFollowUpOperations.js +9 -4
  186. package/dist/server/lib/ticketFollowUpOperations.js.map +1 -1
  187. package/dist/server/lib/ticketRunOperations.js +1 -0
  188. package/dist/server/lib/ticketRunOperations.js.map +1 -1
  189. package/dist/server/lib/types.js +1 -0
  190. package/dist/server/lib/types.js.map +1 -1
  191. package/dist/server/lib/workloadExecutionEnvironment.js +2 -0
  192. package/dist/server/lib/workloadExecutionEnvironment.js.map +1 -0
  193. package/dist/server/lib/workspaceIdentity.js +30 -6
  194. package/dist/server/lib/workspaceIdentity.js.map +1 -1
  195. package/dist/server/workers/build.js +39 -8
  196. package/dist/server/workers/build.js.map +1 -1
  197. package/dist/server/workers/chat.js +142 -15
  198. package/dist/server/workers/chat.js.map +1 -1
  199. package/dist/server/workers/followUp.js +77 -20
  200. package/dist/server/workers/followUp.js.map +1 -1
  201. package/dist/server/workers/plan.js +295 -48
  202. package/dist/server/workers/plan.js.map +1 -1
  203. package/dist/server/workers/planFollowUp.js +77 -7
  204. package/dist/server/workers/planFollowUp.js.map +1 -1
  205. package/dist/server/workers/review.js +153 -40
  206. package/dist/server/workers/review.js.map +1 -1
  207. package/dist/server/workers/specReview.js +43 -5
  208. package/dist/server/workers/specReview.js.map +1 -1
  209. package/dist/server/workers/specSession.js +156 -31
  210. package/dist/server/workers/specSession.js.map +1 -1
  211. package/package.json +1 -1
  212. package/dist/client/assets/GitHubActionsDialog-CA189pr2.js +0 -1
  213. package/dist/client/assets/VerificationDialog-BPVkhKRj.js +0 -4
  214. package/dist/client/assets/channel-D0zqzBT_.js +0 -1
  215. package/dist/client/assets/classDiagram-4FO5ZUOK-ChhyvHH2.js +0 -1
  216. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Cl02kurK.js +0 -1
  217. package/dist/client/assets/index-Bs8KsdV9.js +0 -276
  218. package/dist/client/assets/index-DdwM8Wgt.css +0 -2
  219. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CLR1WgdV.js +0 -1
@@ -6,38 +6,20 @@ import { promisify } from 'node:util';
6
6
  import { networkDestinationTarget } from './executionEnvironmentLifecycle.js';
7
7
  import { requireExecutionCapabilities } from './executionEnvironmentLifecycle.js';
8
8
  import { assertExactSandboxNetworkAllowlist, applyScopedNetworkRules as applyScopedSandboxNetworkRules, checkDestinationAccess as checkSandboxDestinationAccess, inspectGlobalNetworkPosture as inspectSandboxGlobalNetworkPosture, inspectSandboxNetworkRules as inspectScopedSandboxNetworkRules, removeScopedNetworkRules as removeScopedSandboxNetworkRules, } from './dockerSandboxNetworkPolicy.js';
9
+ import { RECOMMENDED_DOCKER_SANDBOX_RELEASE, inspectDockerSandboxRelease, isDockerSandboxReleaseHostQualified, resolveDockerSandboxReleaseProfile, } from './dockerSandboxReleaseProfiles.js';
9
10
  export const DOCKER_SANDBOX_PROVIDER = 'docker_sandbox';
10
- export const QUALIFIED_SBX_VERSION = '0.38.0';
11
- export const QUALIFIED_SBX_BUILD = 'c022b14634c4bea846ca12870d1d5e97d5868b54';
12
- export const DOCKER_SANDBOX_ADAPTER_CONTRACT_VERSION = '5';
11
+ export const QUALIFIED_SBX_VERSION = RECOMMENDED_DOCKER_SANDBOX_RELEASE.version;
12
+ export const QUALIFIED_SBX_BUILD = RECOMMENDED_DOCKER_SANDBOX_RELEASE.acceptedBuilds[0];
13
+ export const DOCKER_SANDBOX_ADAPTER_CONTRACT_VERSION = RECOMMENDED_DOCKER_SANDBOX_RELEASE.adapterContractVersion;
13
14
  export const DOCKER_SANDBOX_MAX_NAME_BYTES = 63;
14
- export const QUALIFIED_DOCKER_SANDBOX_TEMPLATES = {
15
- opencode: 'docker.io/docker/sandbox-templates:opencode',
16
- claude: 'docker.io/docker/sandbox-templates:claude-code',
17
- };
15
+ export const QUALIFIED_DOCKER_SANDBOX_TEMPLATES = RECOMMENDED_DOCKER_SANDBOX_RELEASE.templates;
18
16
  const DEFAULT_TIMEOUT_MS = 15_000;
19
17
  const DEFAULT_OUTPUT_LIMIT_BYTES = 256 * 1024;
20
18
  const SANDBOX_NAME_HASH_LENGTH = 16;
21
- const MINIMUM_MACOS_MAJOR = 14;
22
19
  const KVM_DEVICE_PATH = '/dev/kvm';
23
20
  const execFile = promisify(execFileCallback);
24
- const QUALIFIED_DOCKER_SANDBOX_HOSTS = [
25
- { platform: 'linux', architecture: 'x64' },
26
- { platform: 'darwin', architecture: 'arm64' },
27
- ];
28
- export const isQualifiedDockerSandboxHost = (platform, architecture) => QUALIFIED_DOCKER_SANDBOX_HOSTS.some(host => host.platform === platform && host.architecture === architecture);
29
- export const dockerSandboxExecutionEnvironmentCapabilities = {
30
- isolation: 'microvm',
31
- directWritableWorkspace: 'supported',
32
- transparentHeadlessStreams: 'supported',
33
- credentialBrokering: 'supported',
34
- enforcedNetworkAllowlist: 'unknown',
35
- persistentEnvironments: 'supported',
36
- resourceIsolation: 'unknown',
37
- nestedContainers: 'unsupported',
38
- publishedPorts: 'unsupported',
39
- resourceControls: 'unsupported',
40
- };
21
+ export const isQualifiedDockerSandboxHost = (platform, architecture) => isDockerSandboxReleaseHostQualified(RECOMMENDED_DOCKER_SANDBOX_RELEASE, platform, architecture);
22
+ export const dockerSandboxExecutionEnvironmentCapabilities = RECOMMENDED_DOCKER_SANDBOX_RELEASE.capabilities;
41
23
  export const deriveDockerSandboxGlobalNetworkPosture = (readiness) => readiness.observations.some(observation => (observation.code === 'network_policy' && observation.state === 'ready'))
42
24
  ? 'restrictive'
43
25
  : 'unobserved';
@@ -45,9 +27,12 @@ export const deriveDockerSandboxExecutionEnvironmentCapabilities = (posture) =>
45
27
  ...dockerSandboxExecutionEnvironmentCapabilities,
46
28
  enforcedNetworkAllowlist: posture === 'restrictive' ? 'supported' : 'unknown',
47
29
  });
48
- export const dockerSandboxExecutionEnvironmentObservation = (posture = 'unobserved') => ({
49
- providerVersion: QUALIFIED_SBX_VERSION,
50
- capabilities: deriveDockerSandboxExecutionEnvironmentCapabilities(posture),
30
+ export const dockerSandboxExecutionEnvironmentObservation = (posture = 'unobserved', profile = RECOMMENDED_DOCKER_SANDBOX_RELEASE) => ({
31
+ providerVersion: profile.version,
32
+ capabilities: {
33
+ ...profile.capabilities,
34
+ enforcedNetworkAllowlist: posture === 'restrictive' ? 'supported' : 'unknown',
35
+ },
51
36
  degradationReasons: posture === 'restrictive'
52
37
  ? []
53
38
  : ['The selected direct workspace remains writable from the sandbox.'],
@@ -209,20 +194,31 @@ export const parseJsonObject = (command, output) => {
209
194
  }
210
195
  return record;
211
196
  };
212
- export const parseQualifiedSbxVersion = (output) => {
197
+ export const parseSbxVersionIdentity = (output) => {
213
198
  const match = /^sbx version: v(\d+\.\d+\.\d+) ([0-9a-f]{40})\r?\n?$/.exec(output);
214
199
  if (!match) {
215
200
  throw new SbxContractFailure('version', 'sbx version output did not match the qualified contract');
216
201
  }
217
- if (match[1] !== QUALIFIED_SBX_VERSION) {
218
- throw new SbxContractFailure('version', `Unsupported sbx version ${match[1]}; Archon requires exactly ${QUALIFIED_SBX_VERSION}`);
219
- }
220
- if (match[2] !== QUALIFIED_SBX_BUILD) {
221
- throw new SbxContractFailure('version', `Unsupported sbx build ${match[2]}; Archon requires exactly ${QUALIFIED_SBX_BUILD}`);
202
+ return { version: match[1], build: match[2] };
203
+ };
204
+ export const parseQualifiedSbxRelease = (output) => {
205
+ const identity = parseSbxVersionIdentity(output);
206
+ const profile = resolveDockerSandboxReleaseProfile(identity.version, identity.build);
207
+ if (!profile) {
208
+ const release = inspectDockerSandboxRelease(identity.version, identity.build);
209
+ throw new SbxContractFailure('version', release.status === 'security_blocked'
210
+ ? release.reason ?? `Docker Sandbox ${identity.version} is blocked due to a security issue.`
211
+ : release.reason ?? `Unsupported sbx release ${identity.version} build ${identity.build}`);
222
212
  }
223
- return match[1];
213
+ return profile;
214
+ };
215
+ export const parseQualifiedSbxVersion = (output) => {
216
+ return parseQualifiedSbxRelease(output).version;
224
217
  };
225
- export const parseSbxDiagnostics = (output) => {
218
+ export const parseSbxDiagnostics = (output, profile = RECOMMENDED_DOCKER_SANDBOX_RELEASE) => {
219
+ if (profile.parserContracts.diagnostics !== 'v0.38.0') {
220
+ throw new SbxContractFailure('diagnose', `No diagnostics parser is registered for ${profile.id}`);
221
+ }
226
222
  const record = parseJsonObject('diagnose', output);
227
223
  if (record.version !== '1.0' || !Array.isArray(record.checks)) {
228
224
  throw new SbxContractFailure('diagnose', 'sbx diagnose returned an unsupported schema');
@@ -272,7 +268,10 @@ const QUALIFIED_NETWORK_POLICY_STRING_FIELDS = [
272
268
  'layer',
273
269
  'status',
274
270
  ];
275
- export const parseSbxNetworkPolicy = (output) => {
271
+ export const parseSbxNetworkPolicy = (output, profile = RECOMMENDED_DOCKER_SANDBOX_RELEASE) => {
272
+ if (profile.parserContracts.networkPolicy !== 'v0.38.0') {
273
+ throw new SbxContractFailure('policy list', `No network policy parser is registered for ${profile.id}`);
274
+ }
276
275
  const record = parseJsonObject('policy list', output);
277
276
  if (Object.keys(record).some(field => field !== 'rules')
278
277
  || !Array.isArray(record.rules)
@@ -336,8 +335,8 @@ const macOsMajorVersion = (version) => {
336
335
  const match = /^(\d+)(?:\.|$)/.exec(version);
337
336
  return match ? Number(match[1]) : null;
338
337
  };
339
- const probeDockerSandboxPlatformReadiness = async (platform, architecture, options) => {
340
- if (!isQualifiedDockerSandboxHost(platform, architecture)) {
338
+ const probeDockerSandboxPlatformReadiness = async (platform, architecture, options, profile) => {
339
+ if (!isDockerSandboxReleaseHostQualified(profile, platform, architecture)) {
341
340
  return {
342
341
  code: 'platform',
343
342
  state: 'unsupported',
@@ -365,7 +364,7 @@ const probeDockerSandboxPlatformReadiness = async (platform, architecture, optio
365
364
  remediation: 'Run macOS Sonoma 14 or later on Apple silicon, then recheck.',
366
365
  };
367
366
  }
368
- if (majorVersion < MINIMUM_MACOS_MAJOR) {
367
+ if (majorVersion < profile.minimumMacosMajor) {
369
368
  return {
370
369
  code: 'platform',
371
370
  state: 'unsupported',
@@ -464,6 +463,9 @@ export const probeDockerSandboxReadiness = async (runner, options = {}) => {
464
463
  const architecture = options.architecture ?? process.arch;
465
464
  const observations = [];
466
465
  let providerVersion = null;
466
+ let providerBuild = null;
467
+ let releaseStatus = null;
468
+ let releaseProfile = null;
467
469
  let versionResult;
468
470
  try {
469
471
  versionResult = await runner.run(['version'], options);
@@ -473,6 +475,9 @@ export const probeDockerSandboxReadiness = async (runner, options = {}) => {
473
475
  if (error instanceof SbxCommandFailure && error.kind === 'missing_cli') {
474
476
  return {
475
477
  providerVersion: null,
478
+ providerBuild: null,
479
+ releaseStatus: null,
480
+ recommendedVersion: RECOMMENDED_DOCKER_SANDBOX_RELEASE.version,
476
481
  observations: [
477
482
  { code: 'cli', state: 'not_ready', summary: 'sbx CLI is not installed.', remediation: 'Install the qualified sbx release from Docker.' },
478
483
  ...['version', 'platform', 'virtualization', 'daemon', 'docker_login', 'network_policy', 'opencode_template', 'claude_template']
@@ -486,8 +491,25 @@ export const probeDockerSandboxReadiness = async (runner, options = {}) => {
486
491
  if (versionResult.exitCode !== 0) {
487
492
  throw new SbxContractFailure('version', `sbx version exited with code ${versionResult.exitCode}`);
488
493
  }
489
- providerVersion = parseQualifiedSbxVersion(versionResult.stdout);
490
- observations.push({ code: 'version', state: 'ready', summary: `sbx ${providerVersion} is qualified.`, remediation: null });
494
+ const identity = parseSbxVersionIdentity(versionResult.stdout);
495
+ providerVersion = identity.version;
496
+ providerBuild = identity.build;
497
+ const release = inspectDockerSandboxRelease(identity.version, identity.build);
498
+ releaseStatus = release.status;
499
+ releaseProfile = release.profile;
500
+ if (!releaseProfile || release.status === 'security_blocked') {
501
+ throw new SbxContractFailure('version', release.reason ?? `Docker Sandbox ${identity.version} is unsupported.`);
502
+ }
503
+ observations.push({
504
+ code: 'version',
505
+ state: 'ready',
506
+ summary: release.status === 'deprecated'
507
+ ? `sbx ${providerVersion} is qualified but deprecated.`
508
+ : `sbx ${providerVersion} is qualified and recommended.`,
509
+ remediation: release.status === 'deprecated'
510
+ ? `Upgrade to sbx ${RECOMMENDED_DOCKER_SANDBOX_RELEASE.version}.`
511
+ : null,
512
+ });
491
513
  }
492
514
  catch (error) {
493
515
  observations.push({
@@ -497,14 +519,30 @@ export const probeDockerSandboxReadiness = async (runner, options = {}) => {
497
519
  remediation: `Install sbx ${QUALIFIED_SBX_VERSION}.`,
498
520
  });
499
521
  }
500
- const platformObservation = await probeDockerSandboxPlatformReadiness(platform, architecture, options);
522
+ if (!releaseProfile || releaseStatus === 'security_blocked') {
523
+ observations.push(...['platform', 'virtualization', 'daemon', 'docker_login', 'network_policy', 'opencode_template', 'claude_template']
524
+ .map(code => ({
525
+ code,
526
+ state: 'unknown',
527
+ summary: 'Not checked because the installed sbx release is not supported.',
528
+ remediation: null,
529
+ })));
530
+ return {
531
+ providerVersion,
532
+ providerBuild,
533
+ releaseStatus: releaseStatus ?? 'unsupported',
534
+ recommendedVersion: RECOMMENDED_DOCKER_SANDBOX_RELEASE.version,
535
+ observations,
536
+ };
537
+ }
538
+ const platformObservation = await probeDockerSandboxPlatformReadiness(platform, architecture, options, releaseProfile);
501
539
  observations.push(platformObservation);
502
540
  observations.push(await probeDockerSandboxVirtualizationReadiness(platform, architecture, platformObservation, options.kvmAccess));
503
541
  const diagnose = await runner.run(['diagnose', '--output', 'json'], options);
504
542
  if (diagnose.exitCode !== 0 && diagnose.stdout.trim().length === 0) {
505
543
  throw new SbxContractFailure('diagnose', 'sbx diagnose failed without structured output');
506
544
  }
507
- const checks = parseSbxDiagnostics(diagnose.stdout);
545
+ const checks = parseSbxDiagnostics(diagnose.stdout, releaseProfile);
508
546
  observations.push(diagnosticObservation(checks, 'daemon', ['daemon'], 'Daemon readiness was not reported.'));
509
547
  observations.push(diagnosticObservation(checks, 'docker_login', ['authentication'], 'Docker login readiness was not reported.'));
510
548
  const daemonReady = observations.some(observation => observation.code === 'daemon' && observation.state === 'ready');
@@ -521,7 +559,7 @@ export const probeDockerSandboxReadiness = async (runner, options = {}) => {
521
559
  }
522
560
  else {
523
561
  try {
524
- const rules = parseSbxNetworkPolicy(policy.stdout);
562
+ const rules = parseSbxNetworkPolicy(policy.stdout, releaseProfile);
525
563
  const activeGlobalNetworkRules = rules.filter(rule => (rule.scope === 'global'
526
564
  && rule.resourceType === 'network'
527
565
  && rule.status === 'active')).length;
@@ -564,7 +602,13 @@ export const probeDockerSandboxReadiness = async (runner, options = {}) => {
564
602
  remediation: 'Review qualified template output before enabling this capability.',
565
603
  });
566
604
  }
567
- return { providerVersion, observations };
605
+ return {
606
+ providerVersion,
607
+ providerBuild,
608
+ releaseStatus,
609
+ recommendedVersion: RECOMMENDED_DOCKER_SANDBOX_RELEASE.version,
610
+ observations,
611
+ };
568
612
  };
569
613
  const slug = (value, maximum) => {
570
614
  const normalized = value.toLowerCase().replace(/[^a-z0-9.-]+/g, '-').replace(/^[^a-z0-9]+|[^a-z0-9]+$/g, '');
@@ -613,7 +657,27 @@ const describeInspectionShape = (record) => {
613
657
  const description = fields.map(field => `${field}:${jsonValueKind(record[field])}`).join(', ');
614
658
  return description.slice(0, 500);
615
659
  };
616
- export const parseDockerSandboxInspection = (output) => {
660
+ const resolveInspectionTemplate = (image, imageDigest) => {
661
+ if (imageDigest === undefined) {
662
+ return image;
663
+ }
664
+ if (typeof imageDigest !== 'string' || !/^sha256:[0-9a-f]{64}$/.test(imageDigest)) {
665
+ throw new SbxContractFailure('inspect', 'sbx inspect returned an unrecognized image digest');
666
+ }
667
+ const digestSeparator = image.indexOf('@');
668
+ const tagSeparator = image.lastIndexOf(':');
669
+ const pathSeparator = image.lastIndexOf('/');
670
+ const repository = digestSeparator >= 0
671
+ ? image.slice(0, digestSeparator)
672
+ : tagSeparator > pathSeparator
673
+ ? image.slice(0, tagSeparator)
674
+ : image;
675
+ return `${repository}@${imageDigest}`;
676
+ };
677
+ export const parseDockerSandboxInspection = (output, profile = RECOMMENDED_DOCKER_SANDBOX_RELEASE) => {
678
+ if (profile.parserContracts.inspection !== 'v0.38.0') {
679
+ throw new SbxContractFailure('inspect', `No inspection parser is registered for ${profile.id}`);
680
+ }
617
681
  const record = parseJsonObject('inspect', output);
618
682
  const fields = Object.keys(record).sort();
619
683
  const workspace = record.workspace;
@@ -633,7 +697,7 @@ export const parseDockerSandboxInspection = (output) => {
633
697
  agent: record.agent,
634
698
  state: record.state,
635
699
  workspacePath: workspace,
636
- template: record.image,
700
+ template: resolveInspectionTemplate(record.image, record.image_digest),
637
701
  };
638
702
  };
639
703
  const assertInspectionMatches = (expected, observed) => {
@@ -653,12 +717,22 @@ export const requireSuccessfulCommand = (command, result) => {
653
717
  throw new SbxContractFailure(command, exitCodeFailureMessage(command, result));
654
718
  }
655
719
  };
656
- const isQualifiedMissingSandboxResult = (result) => (result.args[0] === 'inspect'
657
- && typeof result.args[1] === 'string'
658
- && result.args[1].length > 0
659
- && result.exitCode === 1
660
- && result.stdout === ''
661
- && result.stderr === `ERROR: sandbox '${result.args[1]}' not found\n`);
720
+ const requireReleaseCommandContract = (profile, contract) => {
721
+ if (!profile.commandContracts.includes(contract)) {
722
+ throw new SbxContractFailure(contract, `Docker Sandbox release ${profile.id} does not qualify the ${contract} command`);
723
+ }
724
+ };
725
+ const isQualifiedMissingSandboxResult = (result, profile) => {
726
+ if (profile.parserContracts.missingSandbox !== 'v0.38.0') {
727
+ return false;
728
+ }
729
+ return result.args[0] === 'inspect'
730
+ && typeof result.args[1] === 'string'
731
+ && result.args[1].length > 0
732
+ && result.exitCode === 1
733
+ && result.stdout === ''
734
+ && result.stderr === `ERROR: sandbox '${result.args[1]}' not found\n`;
735
+ };
662
736
  export const createDockerSandboxAdapter = (runner, qualificationOptions = {}) => {
663
737
  let qualification = null;
664
738
  const waitForQualification = (operation, signal) => {
@@ -673,9 +747,9 @@ export const createDockerSandboxAdapter = (runner, qualificationOptions = {}) =>
673
747
  reject(new SbxCommandFailure('cancelled', ['version'], 'sbx version qualification was cancelled'));
674
748
  };
675
749
  signal.addEventListener('abort', onAbort, { once: true });
676
- operation.then(() => {
750
+ operation.then(profile => {
677
751
  signal.removeEventListener('abort', onAbort);
678
- resolve();
752
+ resolve(profile);
679
753
  }, error => {
680
754
  signal.removeEventListener('abort', onAbort);
681
755
  reject(error);
@@ -685,9 +759,6 @@ export const createDockerSandboxAdapter = (runner, qualificationOptions = {}) =>
685
759
  const ensureQualified = (options) => {
686
760
  const platform = qualificationOptions.platform ?? process.platform;
687
761
  const architecture = qualificationOptions.architecture ?? process.arch;
688
- if (!isQualifiedDockerSandboxHost(platform, architecture)) {
689
- throw new SbxContractFailure('platform', `Unsupported sbx platform ${platform}/${architecture}; Archon requires linux/x64 or darwin/arm64`);
690
- }
691
762
  if (!qualification) {
692
763
  const qualificationCommandOptions = {
693
764
  timeoutMs: options.timeoutMs,
@@ -696,7 +767,11 @@ export const createDockerSandboxAdapter = (runner, qualificationOptions = {}) =>
696
767
  };
697
768
  const attempt = runner.run(['version'], qualificationCommandOptions).then(result => {
698
769
  requireSuccessfulCommand('version', result);
699
- parseQualifiedSbxVersion(result.stdout);
770
+ const profile = parseQualifiedSbxRelease(result.stdout);
771
+ if (!isDockerSandboxReleaseHostQualified(profile, platform, architecture)) {
772
+ throw new SbxContractFailure('platform', `Unsupported sbx platform ${platform}/${architecture} for ${profile.version}`);
773
+ }
774
+ return profile;
700
775
  });
701
776
  qualification = attempt.catch(error => {
702
777
  qualification = null;
@@ -706,15 +781,16 @@ export const createDockerSandboxAdapter = (runner, qualificationOptions = {}) =>
706
781
  return waitForQualification(qualification, options.signal);
707
782
  };
708
783
  const inspect = async (name, options = {}) => {
709
- await ensureQualified(options);
784
+ const profile = await ensureQualified(options);
785
+ requireReleaseCommandContract(profile, 'inspect');
710
786
  const result = await runner.run(['inspect', name, '--json'], options);
711
787
  if (result.exitCode !== 0) {
712
- if (isQualifiedMissingSandboxResult(result)) {
788
+ if (isQualifiedMissingSandboxResult(result, profile)) {
713
789
  return null;
714
790
  }
715
791
  throw new SbxContractFailure('inspect', exitCodeFailureMessage('inspect', result));
716
792
  }
717
- return parseDockerSandboxInspection(result.stdout);
793
+ return parseDockerSandboxInspection(result.stdout, profile);
718
794
  };
719
795
  const requireExpected = async (expected, options) => {
720
796
  const observed = await inspect(expected.name, options);
@@ -725,6 +801,8 @@ export const createDockerSandboxAdapter = (runner, qualificationOptions = {}) =>
725
801
  return observed;
726
802
  };
727
803
  const reconnect = async (expected, options = {}) => {
804
+ const profile = await ensureQualified(options);
805
+ requireReleaseCommandContract(profile, 'exec');
728
806
  let observed = await requireExpected(expected, options);
729
807
  if (observed.state === 'stopped') {
730
808
  const result = await runner.run(['exec', observed.name, '--', 'true'], options);
@@ -735,6 +813,8 @@ export const createDockerSandboxAdapter = (runner, qualificationOptions = {}) =>
735
813
  };
736
814
  return {
737
815
  create: async (request, options = {}) => {
816
+ const profile = await ensureQualified(options);
817
+ requireReleaseCommandContract(profile, 'create');
738
818
  const name = createDockerSandboxName(request.identity);
739
819
  const existing = await inspect(name, options);
740
820
  const expected = { name, agent: request.agent, workspacePath: request.workspacePath, template: request.template };
@@ -751,11 +831,15 @@ export const createDockerSandboxAdapter = (runner, qualificationOptions = {}) =>
751
831
  inspect,
752
832
  reconnect,
753
833
  exec: async (expected, command, args, options = {}) => {
834
+ const profile = await ensureQualified(options);
835
+ requireReleaseCommandContract(profile, 'exec');
754
836
  await requireExpected(expected, options);
755
837
  const workdir = options.cwd === undefined ? [] : ['--workdir', options.cwd];
756
838
  return runner.run(['exec', ...workdir, expected.name, '--', command, ...args], options);
757
839
  },
758
840
  stop: async (expected, options = {}) => {
841
+ const profile = await ensureQualified(options);
842
+ requireReleaseCommandContract(profile, 'stop');
759
843
  let observed = await requireExpected(expected, options);
760
844
  if (observed.state === 'running') {
761
845
  requireSuccessfulCommand('stop', await runner.run(['stop', expected.name], options));
@@ -766,28 +850,35 @@ export const createDockerSandboxAdapter = (runner, qualificationOptions = {}) =>
766
850
  }
767
851
  },
768
852
  remove: async (expected, options = {}) => {
853
+ const profile = await ensureQualified(options);
854
+ requireReleaseCommandContract(profile, 'remove');
769
855
  await requireExpected(expected, options);
770
856
  requireSuccessfulCommand('rm', await runner.run(['rm', '--force', expected.name], options));
771
857
  },
772
858
  applyScopedNetworkRules: async (sandboxName, resources, options = {}) => {
773
- await ensureQualified(options);
774
- return applyScopedSandboxNetworkRules(runner, sandboxName, resources, options);
859
+ const profile = await ensureQualified(options);
860
+ requireReleaseCommandContract(profile, 'policy-allow');
861
+ return applyScopedSandboxNetworkRules(runner, sandboxName, resources, options, profile);
775
862
  },
776
863
  inspectSandboxNetworkRules: async (sandboxName, options = {}) => {
777
- await ensureQualified(options);
778
- return inspectScopedSandboxNetworkRules(runner, sandboxName, options);
864
+ const profile = await ensureQualified(options);
865
+ requireReleaseCommandContract(profile, 'policy-list');
866
+ return inspectScopedSandboxNetworkRules(runner, sandboxName, options, profile);
779
867
  },
780
868
  inspectGlobalNetworkPosture: async (options = {}) => {
781
- await ensureQualified(options);
782
- return inspectSandboxGlobalNetworkPosture(runner, options);
869
+ const profile = await ensureQualified(options);
870
+ requireReleaseCommandContract(profile, 'policy-list');
871
+ return inspectSandboxGlobalNetworkPosture(runner, options, profile);
783
872
  },
784
873
  checkDestinationAccess: async (sandboxName, target, options = {}) => {
785
- await ensureQualified(options);
786
- return checkSandboxDestinationAccess(runner, sandboxName, target, options);
874
+ const profile = await ensureQualified(options);
875
+ requireReleaseCommandContract(profile, 'policy-check');
876
+ return checkSandboxDestinationAccess(runner, sandboxName, target, options, profile);
787
877
  },
788
878
  removeScopedNetworkRules: async (sandboxName, ruleIds, options = {}) => {
789
- await ensureQualified(options);
790
- return removeScopedSandboxNetworkRules(runner, sandboxName, ruleIds, options);
879
+ const profile = await ensureQualified(options);
880
+ requireReleaseCommandContract(profile, 'policy-remove');
881
+ return removeScopedSandboxNetworkRules(runner, sandboxName, ruleIds, options, profile);
791
882
  },
792
883
  };
793
884
  };
@@ -879,6 +970,7 @@ export const removeScopedRulesBestEffort = async (adapter, sandboxName, ownedRul
879
970
  return failures;
880
971
  };
881
972
  export const createDockerSandboxExecutionEnvironmentLifecycle = (dependencies) => {
973
+ const releaseProfile = dependencies.releaseProfile ?? RECOMMENDED_DOCKER_SANDBOX_RELEASE;
882
974
  const appliedNetworkPolicies = new Map();
883
975
  const inspect = async (environment, options = {}) => {
884
976
  const expected = dependencies.resolveExpected(environment);
@@ -925,7 +1017,7 @@ export const createDockerSandboxExecutionEnvironmentLifecycle = (dependencies) =
925
1017
  };
926
1018
  return {
927
1019
  prepare: async (request) => {
928
- requireExecutionCapabilities(DOCKER_SANDBOX_PROVIDER, dockerSandboxExecutionEnvironmentObservation(), request.requiredCapabilities);
1020
+ requireExecutionCapabilities(DOCKER_SANDBOX_PROVIDER, dockerSandboxExecutionEnvironmentObservation('unobserved', releaseProfile), request.requiredCapabilities);
929
1021
  if (!request.persistent) {
930
1022
  throw new SbxContractFailure('create', 'Docker Sandbox lifecycle requires persistent environments');
931
1023
  }
@@ -941,7 +1033,7 @@ export const createDockerSandboxExecutionEnvironmentLifecycle = (dependencies) =
941
1033
  return {
942
1034
  id: preparation.id,
943
1035
  provider: DOCKER_SANDBOX_PROVIDER,
944
- providerVersion: QUALIFIED_SBX_VERSION,
1036
+ providerVersion: releaseProfile.version,
945
1037
  externalId: sandbox.name,
946
1038
  target: request.target,
947
1039
  state: 'ready',