@straiffi/archon 1.8.20 → 1.8.22

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 (170) hide show
  1. package/dist/client/assets/{ActivityView-DDE3U1zB.js → ActivityView-CdEPjmqD.js} +1 -1
  2. package/dist/client/assets/GitHubActionsDialog-CA189pr2.js +1 -0
  3. package/dist/client/assets/VerificationDialog-BPVkhKRj.js +4 -0
  4. package/dist/client/assets/{architectureDiagram-3BPJPVTR-oPUmRpZr.js → architectureDiagram-3BPJPVTR-BrZ08mqq.js} +1 -1
  5. package/dist/client/assets/{blockDiagram-GPEHLZMM-0sq1jkkp.js → blockDiagram-GPEHLZMM-b93XwJ6Z.js} +1 -1
  6. package/dist/client/assets/{c4Diagram-AAUBKEIU-BeDxMy7J.js → c4Diagram-AAUBKEIU-BKOdbZ_v.js} +1 -1
  7. package/dist/client/assets/channel-D0zqzBT_.js +1 -0
  8. package/dist/client/assets/{chunk-2J33WTMH-D8VGsje2.js → chunk-2J33WTMH-D7Vxn_1m.js} +1 -1
  9. package/dist/client/assets/{chunk-3OPIFGDE-DuTUTeBe.js → chunk-3OPIFGDE-B1zo2UZq.js} +1 -1
  10. package/dist/client/assets/{chunk-5ZQYHXKU-BzX5dPNW.js → chunk-5ZQYHXKU-BajvkDdQ.js} +1 -1
  11. package/dist/client/assets/{chunk-727SXJPM-DS9putxN.js → chunk-727SXJPM-CSH7cVpV.js} +1 -1
  12. package/dist/client/assets/{chunk-AQP2D5EJ-CWzFZRBv.js → chunk-AQP2D5EJ-DE-wgUNP.js} +1 -1
  13. package/dist/client/assets/{chunk-CSCIHK7Q-DXZ-ADYW.js → chunk-CSCIHK7Q-Ba7JgCEf.js} +1 -1
  14. package/dist/client/assets/{chunk-KSCS5N6A-BD7mL3KK.js → chunk-KSCS5N6A-0o3YWkHM.js} +1 -1
  15. package/dist/client/assets/{chunk-L5ZTLDWV-DmYQi9AP.js → chunk-L5ZTLDWV-DihWczP8.js} +1 -1
  16. package/dist/client/assets/{chunk-LZXEDZCA-CZyFYHvS.js → chunk-LZXEDZCA-Bxnu-hme.js} +2 -2
  17. package/dist/client/assets/{chunk-ND2GUHAM-BxdjvT9I.js → chunk-ND2GUHAM-CoaR5kmP.js} +1 -1
  18. package/dist/client/assets/{chunk-NZK2D7GU-BwuZcZ_9.js → chunk-NZK2D7GU-By92Rd3d.js} +1 -1
  19. package/dist/client/assets/{chunk-O5CBEL6O-CC-TZXr3.js → chunk-O5CBEL6O-D83Pkgfu.js} +1 -1
  20. package/dist/client/assets/{chunk-WU5MYG2G-CJZJkca2.js → chunk-WU5MYG2G-v8OVf5Lz.js} +1 -1
  21. package/dist/client/assets/classDiagram-4FO5ZUOK-ChhyvHH2.js +1 -0
  22. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Cl02kurK.js +1 -0
  23. package/dist/client/assets/{dagre-BM42HDAG-D2L5RvPF.js → dagre-BM42HDAG-Dq1ALF7Z.js} +1 -1
  24. package/dist/client/assets/{diagram-2AECGRRQ-DBJzxSqZ.js → diagram-2AECGRRQ-1t1_TKtu.js} +1 -1
  25. package/dist/client/assets/{diagram-5GNKFQAL-J_1M-Wou.js → diagram-5GNKFQAL-DtvYRL6f.js} +1 -1
  26. package/dist/client/assets/{diagram-KO2AKTUF-CmT1Vbmc.js → diagram-KO2AKTUF-PRNrSX5F.js} +1 -1
  27. package/dist/client/assets/{diagram-LMA3HP47-DfPoJyQI.js → diagram-LMA3HP47-DaTX0DhT.js} +1 -1
  28. package/dist/client/assets/{diagram-OG6HWLK6-D4uEb6vo.js → diagram-OG6HWLK6-C2p9p-92.js} +1 -1
  29. package/dist/client/assets/{erDiagram-TEJ5UH35-l7yIFj0e.js → erDiagram-TEJ5UH35-DKzLtnp-.js} +1 -1
  30. package/dist/client/assets/{flowDiagram-I6XJVG4X-B3caTMes.js → flowDiagram-I6XJVG4X-GdL8lm6e.js} +1 -1
  31. package/dist/client/assets/{ganttDiagram-6RSMTGT7-9Am36v9m.js → ganttDiagram-6RSMTGT7-Ok-4XYwT.js} +1 -1
  32. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-B7OjYsv_.js → gitGraphDiagram-PVQCEYII-DSMrOCK7.js} +1 -1
  33. package/dist/client/assets/index-Bs8KsdV9.js +276 -0
  34. package/dist/client/assets/index-DdwM8Wgt.css +2 -0
  35. package/dist/client/assets/{infoDiagram-5YYISTIA-ZAcNejkW.js → infoDiagram-5YYISTIA-Dl4hRXis.js} +1 -1
  36. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-BaaJwuN0.js → ishikawaDiagram-YF4QCWOH-C1Dc1fTT.js} +1 -1
  37. package/dist/client/assets/{journeyDiagram-JHISSGLW-DjzTU3kM.js → journeyDiagram-JHISSGLW-CUscmJze.js} +1 -1
  38. package/dist/client/assets/{kanban-definition-UN3LZRKU-DYRchzub.js → kanban-definition-UN3LZRKU-C0nwYjQV.js} +1 -1
  39. package/dist/client/assets/{line-X0j9gj61.js → line-ByiuEIg_.js} +1 -1
  40. package/dist/client/assets/{mermaid-parser.core-DCKG87Vl.js → mermaid-parser.core-B-XdAyDR.js} +1 -1
  41. package/dist/client/assets/{mermaid.core-BxI5T2gs.js → mermaid.core-D_bIfuZD.js} +3 -3
  42. package/dist/client/assets/{mindmap-definition-RKZ34NQL-BE7MZzQO.js → mindmap-definition-RKZ34NQL-BGNiPJDK.js} +1 -1
  43. package/dist/client/assets/{pieDiagram-4H26LBE5-D3fTYovg.js → pieDiagram-4H26LBE5-CP6FpAoO.js} +1 -1
  44. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-B35nXRdQ.js → quadrantDiagram-W4KKPZXB-dsAWBAQn.js} +1 -1
  45. package/dist/client/assets/{requirementDiagram-4Y6WPE33-CLBcHvP0.js → requirementDiagram-4Y6WPE33-DJH-zHqF.js} +1 -1
  46. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-DdBCxGHF.js → sankeyDiagram-5OEKKPKP-BJMnZrqH.js} +1 -1
  47. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-KcLt0X1K.js → sequenceDiagram-3UESZ5HK-CzNjUSlM.js} +1 -1
  48. package/dist/client/assets/{stateDiagram-AJRCARHV-Bq23ObLK.js → stateDiagram-AJRCARHV-jppMhOwh.js} +1 -1
  49. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CLR1WgdV.js +1 -0
  50. package/dist/client/assets/{timeline-definition-PNZ67QCA-SK3oVUD9.js → timeline-definition-PNZ67QCA-BX2CI5H_.js} +1 -1
  51. package/dist/client/assets/{vennDiagram-CIIHVFJN-COVtAlEC.js → vennDiagram-CIIHVFJN-Bd1KZaXh.js} +1 -1
  52. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-BvfOOwga.js → wardleyDiagram-YWT4CUSO-D-0BNz49.js} +1 -1
  53. package/dist/client/assets/{xychartDiagram-2RQKCTM6-DFnAD9k4.js → xychartDiagram-2RQKCTM6-DbYa0ZWK.js} +1 -1
  54. package/dist/client/index.html +2 -2
  55. package/dist/server/db.js +780 -16
  56. package/dist/server/db.js.map +1 -1
  57. package/dist/server/index.js +198 -20
  58. package/dist/server/index.js.map +1 -1
  59. package/dist/server/lib/agent.js +8 -4
  60. package/dist/server/lib/agent.js.map +1 -1
  61. package/dist/server/lib/agentProvider.js +8 -1
  62. package/dist/server/lib/agentProvider.js.map +1 -1
  63. package/dist/server/lib/approvalReconciliation.js +101 -0
  64. package/dist/server/lib/approvalReconciliation.js.map +1 -0
  65. package/dist/server/lib/approvalRequests.js +587 -0
  66. package/dist/server/lib/approvalRequests.js.map +1 -0
  67. package/dist/server/lib/approvalRoutes.js +143 -0
  68. package/dist/server/lib/approvalRoutes.js.map +1 -0
  69. package/dist/server/lib/automationProgression.js +44 -14
  70. package/dist/server/lib/automationProgression.js.map +1 -1
  71. package/dist/server/lib/buildCompletionContinuation.js +14 -3
  72. package/dist/server/lib/buildCompletionContinuation.js.map +1 -1
  73. package/dist/server/lib/buildExecutionEnvironment.js +350 -66
  74. package/dist/server/lib/buildExecutionEnvironment.js.map +1 -1
  75. package/dist/server/lib/buildOpenQuestionOperations.js +47 -3
  76. package/dist/server/lib/buildOpenQuestionOperations.js.map +1 -1
  77. package/dist/server/lib/buildSequences.js +267 -18
  78. package/dist/server/lib/buildSequences.js.map +1 -1
  79. package/dist/server/lib/buildSetupAuthority.js +138 -0
  80. package/dist/server/lib/buildSetupAuthority.js.map +1 -0
  81. package/dist/server/lib/bundleReviewOperations.js +15 -4
  82. package/dist/server/lib/bundleReviewOperations.js.map +1 -1
  83. package/dist/server/lib/checkDefinitions.js +29 -1
  84. package/dist/server/lib/checkDefinitions.js.map +1 -1
  85. package/dist/server/lib/checkRunner.js +306 -27
  86. package/dist/server/lib/checkRunner.js.map +1 -1
  87. package/dist/server/lib/checkRuns.js +4 -2
  88. package/dist/server/lib/checkRuns.js.map +1 -1
  89. package/dist/server/lib/consequentialActionAuthority.js +142 -0
  90. package/dist/server/lib/consequentialActionAuthority.js.map +1 -0
  91. package/dist/server/lib/consequentialActions.js +231 -0
  92. package/dist/server/lib/consequentialActions.js.map +1 -0
  93. package/dist/server/lib/dockerSandboxCredentials.js +64 -10
  94. package/dist/server/lib/dockerSandboxCredentials.js.map +1 -1
  95. package/dist/server/lib/dockerSandboxEnvironmentOperations.js +119 -0
  96. package/dist/server/lib/dockerSandboxEnvironmentOperations.js.map +1 -1
  97. package/dist/server/lib/dockerSandboxExecutionEnvironment.js +174 -11
  98. package/dist/server/lib/dockerSandboxExecutionEnvironment.js.map +1 -1
  99. package/dist/server/lib/dockerSandboxExecutionProvider.js +12 -3
  100. package/dist/server/lib/dockerSandboxExecutionProvider.js.map +1 -1
  101. package/dist/server/lib/dockerSandboxNetworkPolicy.js +222 -0
  102. package/dist/server/lib/dockerSandboxNetworkPolicy.js.map +1 -0
  103. package/dist/server/lib/executionCredentialCapabilities.js +106 -0
  104. package/dist/server/lib/executionCredentialCapabilities.js.map +1 -0
  105. package/dist/server/lib/executionEnvironment.js.map +1 -1
  106. package/dist/server/lib/executionEnvironmentContexts.js +59 -3
  107. package/dist/server/lib/executionEnvironmentContexts.js.map +1 -1
  108. package/dist/server/lib/executionEnvironmentLifecycle.js +34 -0
  109. package/dist/server/lib/executionEnvironmentLifecycle.js.map +1 -1
  110. package/dist/server/lib/executionEnvironmentRoutes.js +127 -9
  111. package/dist/server/lib/executionEnvironmentRoutes.js.map +1 -1
  112. package/dist/server/lib/executionEnvironmentValidation.js +169 -45
  113. package/dist/server/lib/executionEnvironmentValidation.js.map +1 -1
  114. package/dist/server/lib/executionEnvironmentValidationOperations.js +203 -19
  115. package/dist/server/lib/executionEnvironmentValidationOperations.js.map +1 -1
  116. package/dist/server/lib/executionEnvironments.js +103 -14
  117. package/dist/server/lib/executionEnvironments.js.map +1 -1
  118. package/dist/server/lib/executionProfileRoutes.js +67 -0
  119. package/dist/server/lib/executionProfileRoutes.js.map +1 -0
  120. package/dist/server/lib/executionProfileStore.js +117 -0
  121. package/dist/server/lib/executionProfileStore.js.map +1 -0
  122. package/dist/server/lib/executionProfiles.js +324 -0
  123. package/dist/server/lib/executionProfiles.js.map +1 -0
  124. package/dist/server/lib/executionReconciliation.js +345 -197
  125. package/dist/server/lib/executionReconciliation.js.map +1 -1
  126. package/dist/server/lib/executionRetry.js +24 -5
  127. package/dist/server/lib/executionRetry.js.map +1 -1
  128. package/dist/server/lib/executionRunAuthority.js +467 -0
  129. package/dist/server/lib/executionRunAuthority.js.map +1 -0
  130. package/dist/server/lib/executionRuns.js +30 -4
  131. package/dist/server/lib/executionRuns.js.map +1 -1
  132. package/dist/server/lib/executionTimeline.js +2 -1
  133. package/dist/server/lib/executionTimeline.js.map +1 -1
  134. package/dist/server/lib/git.js +77 -10
  135. package/dist/server/lib/git.js.map +1 -1
  136. package/dist/server/lib/gitPushApprovals.js +367 -0
  137. package/dist/server/lib/gitPushApprovals.js.map +1 -0
  138. package/dist/server/lib/hostExecutionEnvironment.js +7 -1
  139. package/dist/server/lib/hostExecutionEnvironment.js.map +1 -1
  140. package/dist/server/lib/mobileAccess.js +115 -1
  141. package/dist/server/lib/mobileAccess.js.map +1 -1
  142. package/dist/server/lib/productionCheckApprovals.js +106 -0
  143. package/dist/server/lib/productionCheckApprovals.js.map +1 -0
  144. package/dist/server/lib/projects.js +1 -0
  145. package/dist/server/lib/projects.js.map +1 -1
  146. package/dist/server/lib/run.js +58 -2
  147. package/dist/server/lib/run.js.map +1 -1
  148. package/dist/server/lib/ticketFollowUpOperations.js +32 -6
  149. package/dist/server/lib/ticketFollowUpOperations.js.map +1 -1
  150. package/dist/server/lib/transcriptRuns.js +3 -0
  151. package/dist/server/lib/transcriptRuns.js.map +1 -1
  152. package/dist/server/lib/types.js +40 -0
  153. package/dist/server/lib/types.js.map +1 -1
  154. package/dist/server/lib/workspaceProcessEnvironment.js +72 -1
  155. package/dist/server/lib/workspaceProcessEnvironment.js.map +1 -1
  156. package/dist/server/workers/build.js +214 -46
  157. package/dist/server/workers/build.js.map +1 -1
  158. package/dist/server/workers/followUp.js +74 -1
  159. package/dist/server/workers/followUp.js.map +1 -1
  160. package/dist/server/workers/review.js +30 -13
  161. package/dist/server/workers/review.js.map +1 -1
  162. package/package.json +1 -1
  163. package/dist/client/assets/GitHubActionsDialog-CM1z-amZ.js +0 -1
  164. package/dist/client/assets/VerificationDialog-oHjNllh6.js +0 -4
  165. package/dist/client/assets/channel-CF8hkOdu.js +0 -1
  166. package/dist/client/assets/classDiagram-4FO5ZUOK-D6FiG9_B.js +0 -1
  167. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Bim05ijr.js +0 -1
  168. package/dist/client/assets/index-CsZfTdMO.css +0 -2
  169. package/dist/client/assets/index-DDefs3iM.js +0 -275
  170. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-BLzZdVo0.js +0 -1
@@ -1,14 +1,18 @@
1
1
  import db from '../db.js';
2
2
  import { ExecutionEnvironmentFailure, } from './executionEnvironment.js';
3
- import { QUALIFIED_DOCKER_SANDBOX_TEMPLATES, QUALIFIED_SBX_VERSION, } from './dockerSandboxExecutionEnvironment.js';
3
+ import { QUALIFIED_DOCKER_SANDBOX_TEMPLATES, QUALIFIED_SBX_VERSION, DockerSandboxNetworkRollbackFailure, proveScopedDestinationAccess, removeScopedRulesBestEffort, } from './dockerSandboxExecutionEnvironment.js';
4
4
  import { createDockerSandboxExecutionProvider } from './dockerSandboxExecutionProvider.js';
5
5
  import { createDockerSandboxOpencodeSessionOperations } from './dockerSandboxOpencodeSessionOperations.js';
6
6
  import { defaultDockerSandboxEnvironmentDependencies, dockerSandboxRunner, ensureDockerSandboxRuntimeReady, reconnectAndInspectDockerSandbox, resolveExpectedDockerSandboxIdentity, stopAndVerifyDockerSandbox, } from './dockerSandboxEnvironmentOperations.js';
7
7
  import { ExecutionEnvironmentRouteError, currentExecutionEnvironmentValidationFingerprint, prepareAndValidateExecutionEnvironmentForTarget, validateExecutionEnvironmentForTarget, } from './executionEnvironmentValidationOperations.js';
8
8
  import { validateExecutionEnvironmentSkills } from './executionEnvironmentValidation.js';
9
- import { acquireExecutionEnvironmentLease, captureExecutionEnvironmentPlacement, getExecutionEnvironment, getExecutionEnvironmentBindingForRun, listExecutionEnvironments, releaseExecutionEnvironmentLease, transitionExecutionEnvironment, } from './executionEnvironments.js';
9
+ import { acquireExecutionEnvironmentLease, appendExecutionEnvironmentEvent, captureExecutionEnvironmentPlacement, getExecutionEnvironment, getExecutionEnvironmentBindingForRun, listExecutionEnvironments, releaseExecutionEnvironmentLease, transitionExecutionEnvironment, } from './executionEnvironments.js';
10
10
  import { hostExecutionEnvironment } from './hostExecutionEnvironment.js';
11
11
  import { getModelProvider, normalizeModelId } from './models.js';
12
+ import { createExecutionRunAuthority, persistExecutionRunAuthority, resolveEnvironmentCredentialEvidence, resolveExecutionRunProfile, } from './executionRunAuthority.js';
13
+ import { fingerprintCredentialRequirements } from './executionProfiles.js';
14
+ import { normalizeExecutionEnvironmentDestinations } from './executionEnvironmentLifecycle.js';
15
+ import { createDockerSandboxLauncherEnvironment, createGovernedHostRuntimeEnvironment, createHostLauncherEnvironment, createLegacyHostRuntimeEnvironment, createProviderManagedRuntimeEnvironment, } from './workspaceProcessEnvironment.js';
12
16
  export class BuildExecutionEnvironmentFailure extends Error {
13
17
  code;
14
18
  remediation;
@@ -26,7 +30,7 @@ const describePreparationFailure = (error) => {
26
30
  return '';
27
31
  };
28
32
  const getLatestValidation = (projectId, environmentId, agent, provider) => db.prepare(`
29
- SELECT run.status, run.domain_status, run.metadata_json
33
+ SELECT run.id, run.status, run.domain_status, run.metadata_json
30
34
  FROM execution_environment_run_bindings binding
31
35
  JOIN execution_runs run ON run.id = binding.execution_run_id AND run.project_id = binding.project_id
32
36
  WHERE binding.project_id = ? AND binding.environment_id = ?
@@ -82,7 +86,45 @@ const validationProvider = (row) => {
82
86
  return null;
83
87
  }
84
88
  };
85
- const findExecutionEnvironment = (project, agent, target, pinnedEnvironmentId, pinnedEnvironmentRevision, pinnedEnvironmentValidationFingerprint) => {
89
+ const getValidationCredentialCapability = (projectId, environmentId, validationRunId) => {
90
+ const row = db.prepare(`
91
+ SELECT metadata_json
92
+ FROM execution_environment_events
93
+ WHERE project_id = ? AND environment_id = ?
94
+ AND event_type = 'environment_validation_completed'
95
+ AND json_extract(metadata_json, '$.executionRunId') = ?
96
+ ORDER BY sequence DESC
97
+ LIMIT 1
98
+ `).get(projectId, environmentId, validationRunId);
99
+ try {
100
+ const metadata = row?.metadata_json ? JSON.parse(row.metadata_json) : null;
101
+ const validation = metadata?.validation && typeof metadata.validation === 'object'
102
+ ? metadata.validation
103
+ : null;
104
+ const agent = validation?.agent && typeof validation.agent === 'object'
105
+ ? validation.agent
106
+ : null;
107
+ const value = validation?.credentialCapability ?? agent?.credentialCapability;
108
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
109
+ return null;
110
+ }
111
+ const capability = value;
112
+ if ((capability.execution_provider !== 'host' && capability.execution_provider !== 'docker_sandbox')
113
+ || (capability.agent !== 'opencode' && capability.agent !== 'claude')
114
+ || capability.workload !== 'build'
115
+ || typeof capability.satisfies_requested_protection !== 'boolean'
116
+ || !capability.inventory
117
+ || !capability.destination
118
+ || typeof capability.classification !== 'string') {
119
+ return null;
120
+ }
121
+ return capability;
122
+ }
123
+ catch {
124
+ return null;
125
+ }
126
+ };
127
+ const findExecutionEnvironment = (project, agent, target, profileRevision, pinnedEnvironmentId, pinnedEnvironmentRevision, pinnedEnvironmentValidationFingerprint) => {
86
128
  const fingerprint = currentExecutionEnvironmentValidationFingerprint(agent);
87
129
  return listExecutionEnvironments(project.id).find(candidate => ((!pinnedEnvironmentId || candidate.id === pinnedEnvironmentId)
88
130
  && (pinnedEnvironmentRevision === undefined || candidate.environment_revision === pinnedEnvironmentRevision)
@@ -95,19 +137,24 @@ const findExecutionEnvironment = (project, agent, target, pinnedEnvironmentId, p
95
137
  && candidate.target_key === target.identity.key
96
138
  && candidate.target_workspace_path === target.workspacePath
97
139
  && candidate.environment_validation_fingerprint === fingerprint
140
+ && (candidate.execution_profile_fingerprint === profileRevision.fingerprint
141
+ || (profileRevision.revision === 0 && candidate.execution_profile_fingerprint == null))
142
+ && (candidate.credential_requirements_fingerprint === fingerprintCredentialRequirements(profileRevision.profile.credential_requirements)
143
+ || (profileRevision.revision === 0 && candidate.credential_requirements_fingerprint == null))
144
+ && candidate.retirement_requested_at == null
98
145
  && candidate.template_identity === QUALIFIED_DOCKER_SANDBOX_TEMPLATES[agent]
99
146
  && candidate.agent_identity === agent
100
147
  && candidate.compatible_agents.length === 1
101
148
  && candidate.compatible_agents[0] === agent
102
149
  && ['ready', 'running', 'stopped'].includes(candidate.lifecycle_state))) ?? null;
103
150
  };
104
- const resolveValidatedEnvironment = (project, agent, target, model, pinnedEnvironmentId, pinnedEnvironmentRevision, pinnedEnvironmentValidationFingerprint) => {
151
+ const resolveValidatedEnvironment = (project, agent, target, model, profileRevision, pinnedEnvironmentId, pinnedEnvironmentRevision, pinnedEnvironmentValidationFingerprint) => {
105
152
  const requestedModel = agent === 'opencode' ? normalizeModelId(model) : null;
106
153
  const requestedProvider = agent === 'opencode' ? getModelProvider(requestedModel) : 'anthropic';
107
154
  if (agent === 'opencode' && !requestedProvider) {
108
155
  throw new BuildExecutionEnvironmentFailure('validation_provider_missing', 'OpenCode Build requires a model with a provider before a Docker Sandbox can be used.', 'Choose a provider-backed OpenCode model for this ticket, then retry Build.');
109
156
  }
110
- const environment = findExecutionEnvironment(project, agent, target, pinnedEnvironmentId, pinnedEnvironmentRevision, pinnedEnvironmentValidationFingerprint);
157
+ const environment = findExecutionEnvironment(project, agent, target, profileRevision, pinnedEnvironmentId, pinnedEnvironmentRevision, pinnedEnvironmentValidationFingerprint);
111
158
  if (!environment) {
112
159
  throw new BuildExecutionEnvironmentFailure('environment_missing', 'No validated Docker Sandbox matches this exact Build target and agent.', `Select this target and validate its ${agent} Docker Sandbox before starting Build.`);
113
160
  }
@@ -136,6 +183,7 @@ const validateBuildProvider = async (input) => {
136
183
  target: input.target,
137
184
  initiatedBy: 'automation',
138
185
  signal: input.signal,
186
+ profileRevision: input.profileRevision,
139
187
  }, {
140
188
  adapter: input.dependencies.adapter,
141
189
  runtimeController: input.dependencies.runtimeController,
@@ -145,7 +193,7 @@ const validateBuildProvider = async (input) => {
145
193
  throw new BuildExecutionEnvironmentFailure('validation_stale', 'The Docker Sandbox could not validate the exact Build provider and target.', `Resolve ${input.agent} authentication and provider access, validate the exact target, then retry Build.`);
146
194
  }
147
195
  };
148
- const createAuthority = (environment, agent) => ({
196
+ const createAuthority = (environment, agent, credentialEvidence) => ({
149
197
  schema_version: 1,
150
198
  provider: 'docker_sandbox',
151
199
  provider_version: environment.provider_version,
@@ -158,10 +206,13 @@ const createAuthority = (environment, agent) => ({
158
206
  workspace_path: environment.target_workspace_path,
159
207
  },
160
208
  capabilities: environment.capabilities,
161
- degradation_reasons: environment.workspace_mode === 'direct' ? ['direct_workspace_writable'] : [],
209
+ degradation_reasons: [
210
+ ...(environment.workspace_mode === 'direct' ? ['direct_workspace_writable'] : []),
211
+ ...credentialEvidence.degradation_reasons,
212
+ ],
162
213
  agent,
163
- authentication_mode: 'validated_guest',
164
- credential_delivery: 'sandbox_template',
214
+ authentication_mode: credentialEvidence.authentication_mode,
215
+ credential_delivery: credentialEvidence.credential_delivery,
165
216
  });
166
217
  const parsePlacement = (value) => {
167
218
  if (!value) {
@@ -287,68 +338,171 @@ export const recordBuildExecutionProvider = (projectId, executionRunId, provider
287
338
  }
288
339
  };
289
340
  export const resolveBuildExecutionEnvironment = async (input) => {
290
- if (input.project.build_execution_provider !== 'docker_sandbox') {
291
- return { provider: hostExecutionEnvironment, environment: null, authority: null, release: async () => { } };
341
+ const profileRevision = resolveExecutionRunProfile(input.project, input.executionRunId);
342
+ const selectedProvider = profileRevision.profile.provider_preference;
343
+ const hasPinnedEnvironmentLineage = input.pinnedEnvironmentId !== undefined
344
+ || input.pinnedEnvironmentRevision !== undefined
345
+ || input.pinnedEnvironmentValidationFingerprint !== undefined;
346
+ if (hasPinnedEnvironmentLineage
347
+ && (selectedProvider !== 'docker_sandbox'
348
+ || !input.pinnedEnvironmentId
349
+ || input.pinnedEnvironmentRevision === undefined
350
+ || !input.pinnedEnvironmentValidationFingerprint)) {
351
+ throw new BuildExecutionEnvironmentFailure('environment_identity_invalid', 'The historical Docker Sandbox lineage is incomplete or conflicts with the selected execution profile.', 'Retry as a fresh Build instead of resuming this historical provider session.');
352
+ }
353
+ const modelProvider = input.agent === 'opencode' ? getModelProvider(input.model) || null : 'anthropic';
354
+ const resolveHostEnvironment = (fallback) => {
355
+ const runAuthority = createExecutionRunAuthority({
356
+ profileRevision,
357
+ provider: 'host',
358
+ agent: input.agent,
359
+ modelProvider,
360
+ target: input.target,
361
+ environment: null,
362
+ fallback: fallback ? { used: true, from: fallback.from, reason: fallback.reason } : undefined,
363
+ });
364
+ persistExecutionRunAuthority({
365
+ projectId: input.project.id,
366
+ executionRunId: input.executionRunId,
367
+ profileRevision,
368
+ authority: runAuthority,
369
+ });
370
+ if (fallback) {
371
+ recordBuildExecutionProvider(input.project.id, input.executionRunId, 'host');
372
+ }
373
+ return {
374
+ provider: hostExecutionEnvironment,
375
+ environment: null,
376
+ authority: null,
377
+ runAuthority,
378
+ launcherEnvironment: createHostLauncherEnvironment(),
379
+ runtimeEnvironment: profileRevision.profile.compatibility === 'legacy_host'
380
+ ? createLegacyHostRuntimeEnvironment(input.target.workspacePath, { PWD: input.target.workspacePath })
381
+ : createGovernedHostRuntimeEnvironment(input.target.workspacePath, { PWD: input.target.workspacePath }),
382
+ release: async () => { },
383
+ };
384
+ };
385
+ if (selectedProvider !== 'docker_sandbox') {
386
+ return resolveHostEnvironment();
292
387
  }
293
388
  const dependencies = input.dependencies ?? defaultDockerSandboxEnvironmentDependencies;
294
- let environment;
295
- try {
296
- environment = resolveValidatedEnvironment(input.project, input.agent, input.target, input.model ?? null, input.pinnedEnvironmentId, input.pinnedEnvironmentRevision, input.pinnedEnvironmentValidationFingerprint);
297
- }
298
- catch (error) {
299
- if (error instanceof BuildExecutionEnvironmentFailure
300
- && error.code === 'environment_missing'
301
- && !input.pinnedEnvironmentId) {
302
- const requestedProvider = input.agent === 'opencode' ? getModelProvider(input.model) : 'anthropic';
303
- try {
304
- await prepareAndValidateExecutionEnvironmentForTarget({
305
- projectId: input.project.id,
306
- agent: input.agent,
307
- provider: requestedProvider,
308
- model: input.agent === 'opencode' ? normalizeModelId(input.model) || null : null,
309
- target: input.target,
310
- initiatedBy: 'automation',
311
- signal: input.signal,
312
- }, {
313
- adapter: dependencies.adapter,
314
- runtimeController: dependencies.runtimeController,
315
- runner: dependencies.runner,
316
- });
317
- }
318
- catch (preparationError) {
319
- throw new BuildExecutionEnvironmentFailure('validation_stale', `The exact ticket Build target could not be prepared for Docker Sandbox execution.${describePreparationFailure(preparationError)}`, 'Review the reported Docker Sandbox preparation failure, resolve it, then retry Build.', { cause: preparationError });
320
- }
321
- environment = resolveValidatedEnvironment(input.project, input.agent, input.target, input.model ?? null, input.pinnedEnvironmentId, input.pinnedEnvironmentRevision, input.pinnedEnvironmentValidationFingerprint);
389
+ const applicableRequirements = profileRevision.profile.credential_requirements.filter(requirement => (requirement.agent === input.agent && requirement.model_provider === modelProvider));
390
+ const canFallback = profileRevision.profile.fallback === 'explicit_host'
391
+ && !hasPinnedEnvironmentLineage
392
+ && profileRevision.profile.isolation === 'host_process_allowed'
393
+ && applicableRequirements.every(requirement => requirement.required_protection === 'legacy_host_inheritance');
394
+ const resolveFallback = (error) => {
395
+ if (input.signal?.aborted) {
396
+ throw input.signal.reason instanceof Error
397
+ ? input.signal.reason
398
+ : new Error('Docker Sandbox Build preparation was cancelled');
322
399
  }
323
- else if (!shouldRetryValidation(error)) {
400
+ if (!canFallback) {
324
401
  throw error;
325
402
  }
326
- else {
327
- const candidate = findExecutionEnvironment(input.project, input.agent, input.target, input.pinnedEnvironmentId, input.pinnedEnvironmentRevision, input.pinnedEnvironmentValidationFingerprint);
328
- if (!candidate) {
329
- throw error;
403
+ const reason = error instanceof BuildExecutionEnvironmentFailure ? error.code : 'docker_preparation_failed';
404
+ return resolveHostEnvironment({ from: 'docker_sandbox', reason });
405
+ };
406
+ let environment;
407
+ let validatedDuringResolution = false;
408
+ try {
409
+ try {
410
+ environment = resolveValidatedEnvironment(input.project, input.agent, input.target, input.model ?? null, profileRevision, input.pinnedEnvironmentId, input.pinnedEnvironmentRevision, input.pinnedEnvironmentValidationFingerprint);
411
+ }
412
+ catch (error) {
413
+ if (error instanceof BuildExecutionEnvironmentFailure
414
+ && error.code === 'environment_missing'
415
+ && !input.pinnedEnvironmentId) {
416
+ const requestedProvider = input.agent === 'opencode' ? getModelProvider(input.model) : 'anthropic';
417
+ try {
418
+ await prepareAndValidateExecutionEnvironmentForTarget({
419
+ projectId: input.project.id,
420
+ agent: input.agent,
421
+ provider: requestedProvider,
422
+ model: input.agent === 'opencode' ? normalizeModelId(input.model) || null : null,
423
+ target: input.target,
424
+ initiatedBy: 'automation',
425
+ signal: input.signal,
426
+ profileRevision,
427
+ }, {
428
+ adapter: dependencies.adapter,
429
+ runtimeController: dependencies.runtimeController,
430
+ runner: dependencies.runner,
431
+ });
432
+ validatedDuringResolution = true;
433
+ }
434
+ catch (preparationError) {
435
+ throw new BuildExecutionEnvironmentFailure('validation_stale', `The exact ticket Build target could not be prepared for Docker Sandbox execution.${describePreparationFailure(preparationError)}`, 'Review the reported Docker Sandbox preparation failure, resolve it, then retry Build.', { cause: preparationError });
436
+ }
437
+ environment = resolveValidatedEnvironment(input.project, input.agent, input.target, input.model ?? null, profileRevision, input.pinnedEnvironmentId, input.pinnedEnvironmentRevision, input.pinnedEnvironmentValidationFingerprint);
330
438
  }
331
- try {
332
- await validateBuildProvider({
333
- project: input.project,
334
- environment: candidate,
335
- agent: input.agent,
336
- model: input.model ?? null,
337
- target: input.target,
338
- signal: input.signal,
339
- dependencies,
340
- });
439
+ else if (!shouldRetryValidation(error)) {
440
+ throw error;
341
441
  }
342
- catch (validationError) {
343
- if (validationError instanceof BuildExecutionEnvironmentFailure) {
344
- throw validationError;
442
+ else {
443
+ const candidate = findExecutionEnvironment(input.project, input.agent, input.target, profileRevision, input.pinnedEnvironmentId, input.pinnedEnvironmentRevision, input.pinnedEnvironmentValidationFingerprint);
444
+ if (!candidate) {
445
+ throw error;
446
+ }
447
+ try {
448
+ await validateBuildProvider({
449
+ project: input.project,
450
+ environment: candidate,
451
+ agent: input.agent,
452
+ model: input.model ?? null,
453
+ target: input.target,
454
+ signal: input.signal,
455
+ dependencies,
456
+ profileRevision,
457
+ });
458
+ validatedDuringResolution = true;
459
+ }
460
+ catch (validationError) {
461
+ if (validationError instanceof BuildExecutionEnvironmentFailure) {
462
+ throw validationError;
463
+ }
464
+ throw new BuildExecutionEnvironmentFailure('validation_stale', 'The Docker Sandbox provider preflight failed before Build could start.', `Resolve ${input.agent} authentication and provider access, then retry Build.`, { cause: validationError });
345
465
  }
346
- throw new BuildExecutionEnvironmentFailure('validation_stale', 'The Docker Sandbox provider preflight failed before Build could start.', `Resolve ${input.agent} authentication and provider access, then retry Build.`, { cause: validationError });
466
+ environment = resolveValidatedEnvironment(input.project, input.agent, input.target, input.model ?? null, profileRevision, input.pinnedEnvironmentId, input.pinnedEnvironmentRevision, input.pinnedEnvironmentValidationFingerprint);
347
467
  }
348
- environment = resolveValidatedEnvironment(input.project, input.agent, input.target, input.model ?? null, input.pinnedEnvironmentId, input.pinnedEnvironmentRevision, input.pinnedEnvironmentValidationFingerprint);
349
468
  }
350
469
  }
351
- const authority = createAuthority(environment, input.agent);
470
+ catch (error) {
471
+ return resolveFallback(error);
472
+ }
473
+ if (hasPinnedEnvironmentLineage
474
+ && (environment.id !== input.pinnedEnvironmentId
475
+ || environment.environment_revision !== input.pinnedEnvironmentRevision
476
+ || environment.environment_validation_fingerprint !== input.pinnedEnvironmentValidationFingerprint)) {
477
+ throw new BuildExecutionEnvironmentFailure('environment_identity_invalid', 'The resolved Docker Sandbox does not match the historical environment lineage.', 'Restore the exact historical environment or retry as a fresh Build.');
478
+ }
479
+ if (!validatedDuringResolution) {
480
+ try {
481
+ await validateBuildProvider({
482
+ project: input.project,
483
+ environment,
484
+ agent: input.agent,
485
+ model: input.model ?? null,
486
+ target: input.target,
487
+ signal: input.signal,
488
+ dependencies,
489
+ profileRevision,
490
+ });
491
+ }
492
+ catch (error) {
493
+ return resolveFallback(new BuildExecutionEnvironmentFailure('validation_stale', 'The Docker Sandbox provider preflight could not refresh credential and destination evidence before Build.', `Resolve ${input.agent} authentication and provider access, then retry Build.`, { cause: error }));
494
+ }
495
+ }
496
+ const validation = getLatestValidation(input.project.id, environment.id, input.agent, modelProvider);
497
+ const credentialCapability = validation
498
+ ? getValidationCredentialCapability(input.project.id, environment.id, validation.id)
499
+ : null;
500
+ const authority = createAuthority(environment, input.agent, resolveEnvironmentCredentialEvidence({
501
+ profileRevision,
502
+ agent: input.agent,
503
+ modelProvider,
504
+ credentialCapability,
505
+ }));
352
506
  try {
353
507
  acquireExecutionEnvironmentLease({
354
508
  projectId: input.project.id,
@@ -358,7 +512,7 @@ export const resolveBuildExecutionEnvironment = async (input) => {
358
512
  });
359
513
  }
360
514
  catch (error) {
361
- throw new BuildExecutionEnvironmentFailure('environment_leased', 'The selected Docker Sandbox is already leased by another run.', 'Wait for the active Build or reconciliation to release the environment.', { cause: error });
515
+ return resolveFallback(new BuildExecutionEnvironmentFailure('environment_leased', 'The selected Docker Sandbox is already leased by another run.', 'Wait for the active Build or reconciliation to release the environment.', { cause: error }));
362
516
  }
363
517
  let released = false;
364
518
  const release = async () => {
@@ -421,6 +575,12 @@ export const resolveBuildExecutionEnvironment = async (input) => {
421
575
  released = true;
422
576
  };
423
577
  input.onLeaseAcquired?.(release);
578
+ const resolveFallbackAfterLease = async (error) => {
579
+ if (!input.signal?.aborted) {
580
+ await release();
581
+ }
582
+ return resolveFallback(error);
583
+ };
424
584
  try {
425
585
  await ensureDockerSandboxRuntimeReady(dependencies, input.signal);
426
586
  await reconnectAndInspectDockerSandbox(environment, dependencies, input.signal);
@@ -442,9 +602,81 @@ export const resolveBuildExecutionEnvironment = async (input) => {
442
602
  },
443
603
  metadata: { executionRunId: input.executionRunId },
444
604
  });
445
- throw new BuildExecutionEnvironmentFailure('runtime_unavailable', 'The required Docker Sandbox runtime or exact persisted sandbox is unavailable.', 'Restore Docker Sandbox readiness and retry; Archon will not fall back to host execution.', { cause: error });
605
+ return resolveFallbackAfterLease(new BuildExecutionEnvironmentFailure('runtime_unavailable', 'The required Docker Sandbox runtime or exact persisted sandbox is unavailable.', 'Restore Docker Sandbox readiness and retry Build.', { cause: error }));
446
606
  }
447
607
  const expected = resolveExpectedDockerSandboxIdentity(environment);
608
+ const requestedNetwork = profileRevision.profile.network;
609
+ const networkDestinations = requestedNetwork.mode === 'allowlist'
610
+ ? normalizeExecutionEnvironmentDestinations(requestedNetwork.destinations)
611
+ : [];
612
+ let networkEvidence = {
613
+ observed_global_posture: 'unknown',
614
+ destination_decisions: [],
615
+ };
616
+ const appendNetworkRuleOwnership = (appliedRuleIds) => {
617
+ if (appliedRuleIds.length === 0) {
618
+ return;
619
+ }
620
+ appendExecutionEnvironmentEvent({
621
+ projectId: input.project.id,
622
+ environmentId: environment.id,
623
+ eventType: 'environment_network_rules_applied',
624
+ fromState: environment.lifecycle_state,
625
+ toState: environment.lifecycle_state,
626
+ message: 'Archon applied scoped network rules for the requested allowlist destinations.',
627
+ metadata: {
628
+ sandboxName: expected.name,
629
+ executionRunId: input.executionRunId,
630
+ appliedRuleIds,
631
+ },
632
+ });
633
+ };
634
+ const rollbackUnpersistedRules = async (appliedRuleIds, cause) => {
635
+ const failures = await removeScopedRulesBestEffort(dependencies.adapter, expected.name, appliedRuleIds);
636
+ if (failures.length === 0) {
637
+ return null;
638
+ }
639
+ return new DockerSandboxNetworkRollbackFailure(expected.name, appliedRuleIds, appliedRuleIds.filter(ruleId => !failures.some(failure => failure.ruleId === ruleId)), failures, cause);
640
+ };
641
+ if (networkDestinations.length > 0) {
642
+ try {
643
+ const proof = await proveScopedDestinationAccess(dependencies.adapter, expected.name, networkDestinations);
644
+ try {
645
+ appendNetworkRuleOwnership(proof.appliedRuleIds);
646
+ }
647
+ catch (persistenceError) {
648
+ throw await rollbackUnpersistedRules(proof.appliedRuleIds, persistenceError) ?? persistenceError;
649
+ }
650
+ const decidedAt = new Date().toISOString();
651
+ networkEvidence = {
652
+ observed_global_posture: 'unknown',
653
+ destination_decisions: Object.values(proof.checks).map(check => ({
654
+ target: check.target,
655
+ decision: check.decision,
656
+ evaluated_rule_id: check.evaluatedRuleId,
657
+ decided_at: decidedAt,
658
+ })),
659
+ };
660
+ }
661
+ catch (error) {
662
+ let networkFailure = error;
663
+ if (error instanceof DockerSandboxNetworkRollbackFailure && error.remainingRuleIds.length > 0) {
664
+ try {
665
+ appendNetworkRuleOwnership(error.remainingRuleIds);
666
+ }
667
+ catch (persistenceError) {
668
+ networkFailure = await rollbackUnpersistedRules(error.remainingRuleIds, persistenceError)
669
+ ?? (error.cause ?? error);
670
+ }
671
+ }
672
+ if (input.signal?.aborted) {
673
+ throw input.signal.reason instanceof Error
674
+ ? input.signal.reason
675
+ : new Error('Docker Sandbox network policy reconciliation was cancelled');
676
+ }
677
+ return resolveFallbackAfterLease(new BuildExecutionEnvironmentFailure('network_enforcement_unproven', `The Docker Sandbox could not prove scoped allowlist access for every requested destination: ${networkFailure instanceof Error ? networkFailure.message : 'policy check failed.'}`, 'Restore the sandbox network policy for the requested destinations, then retry Build.', { cause: networkFailure }));
678
+ }
679
+ }
448
680
  let skillCheck = null;
449
681
  try {
450
682
  skillCheck = await validateExecutionEnvironmentSkills(dependencies.adapter, expected, input.skills ?? [], { signal: input.signal });
@@ -455,12 +687,56 @@ export const resolveBuildExecutionEnvironment = async (input) => {
455
687
  ? input.signal.reason
456
688
  : new Error('Docker Sandbox skill verification was cancelled');
457
689
  }
458
- throw new BuildExecutionEnvironmentFailure('skills_unavailable', 'The exact Docker Sandbox target could not verify the selected OpenCode skills.', 'Restore sandbox skill discovery, then retry Build.', { cause: error });
690
+ return resolveFallbackAfterLease(new BuildExecutionEnvironmentFailure('skills_unavailable', 'The exact Docker Sandbox target could not verify the selected OpenCode skills.', 'Restore sandbox skill discovery, then retry Build.', { cause: error }));
459
691
  }
460
692
  if (skillCheck && skillCheck.state !== 'passed') {
461
693
  const missingSkills = skillCheck.details?.missingSkills ?? input.skills ?? [];
462
694
  const skillSummary = missingSkills.length > 0 ? ` Missing skills: ${missingSkills.join(', ')}.` : '';
463
- throw new BuildExecutionEnvironmentFailure('skills_unavailable', `The exact Docker Sandbox target does not provide all selected OpenCode skills.${skillSummary}`, 'Import the selected skills into the sandbox target or remove them from the ticket, then retry Build.');
695
+ return resolveFallbackAfterLease(new BuildExecutionEnvironmentFailure('skills_unavailable', `The exact Docker Sandbox target does not provide all selected OpenCode skills.${skillSummary}`, 'Import the selected skills into the sandbox target or remove them from the ticket, then retry Build.'));
696
+ }
697
+ let observedGlobalPosture;
698
+ try {
699
+ observedGlobalPosture = await dependencies.adapter.inspectGlobalNetworkPosture({ signal: input.signal });
700
+ }
701
+ catch (error) {
702
+ if (input.signal?.aborted) {
703
+ throw input.signal.reason instanceof Error
704
+ ? input.signal.reason
705
+ : new Error('Docker Sandbox network posture observation was cancelled');
706
+ }
707
+ observedGlobalPosture = 'unknown';
708
+ }
709
+ networkEvidence = {
710
+ ...networkEvidence,
711
+ observed_global_posture: observedGlobalPosture,
712
+ };
713
+ let runAuthority;
714
+ try {
715
+ runAuthority = createExecutionRunAuthority({
716
+ profileRevision,
717
+ provider: 'docker_sandbox',
718
+ agent: input.agent,
719
+ modelProvider,
720
+ target: input.target,
721
+ environment,
722
+ credentialCapability,
723
+ networkEvidence,
724
+ });
725
+ }
726
+ catch (error) {
727
+ return resolveFallbackAfterLease(error);
728
+ }
729
+ try {
730
+ persistExecutionRunAuthority({
731
+ projectId: input.project.id,
732
+ executionRunId: input.executionRunId,
733
+ profileRevision,
734
+ authority: runAuthority,
735
+ });
736
+ }
737
+ catch (error) {
738
+ await release();
739
+ throw error;
464
740
  }
465
741
  const baseProvider = await createDockerSandboxExecutionProvider({
466
742
  adapter: dependencies.adapter,
@@ -530,6 +806,14 @@ export const resolveBuildExecutionEnvironment = async (input) => {
530
806
  return { ...handle, placementIdentity, placementFailure };
531
807
  },
532
808
  };
533
- return { provider, environment, authority, release };
809
+ return {
810
+ provider,
811
+ environment,
812
+ authority,
813
+ runAuthority,
814
+ launcherEnvironment: createDockerSandboxLauncherEnvironment(),
815
+ runtimeEnvironment: createProviderManagedRuntimeEnvironment(),
816
+ release,
817
+ };
534
818
  };
535
819
  //# sourceMappingURL=buildExecutionEnvironment.js.map