@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.
- package/dist/client/assets/{ActivityView-CdEPjmqD.js → ActivityView-Y5IaJiim.js} +1 -1
- package/dist/client/assets/GitHubActionsDialog-GWVxWGPK.js +1 -0
- package/dist/client/assets/VerificationDialog-C4RMuI4y.js +4 -0
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-BrZ08mqq.js → architectureDiagram-3BPJPVTR-CeM6gbLN.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-b93XwJ6Z.js → blockDiagram-GPEHLZMM-BP4hta96.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-BKOdbZ_v.js → c4Diagram-AAUBKEIU-5aJScvhn.js} +1 -1
- package/dist/client/assets/channel-B3DjZXbm.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-D7Vxn_1m.js → chunk-2J33WTMH-BKc2IelV.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-B1zo2UZq.js → chunk-3OPIFGDE-DCc15la5.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-BajvkDdQ.js → chunk-5ZQYHXKU-DSD9HbTp.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-CSH7cVpV.js → chunk-727SXJPM-DrAjnKiA.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-DE-wgUNP.js → chunk-AQP2D5EJ-DxKnpHfQ.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-Ba7JgCEf.js → chunk-CSCIHK7Q-DLejrAB_.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-0o3YWkHM.js → chunk-KSCS5N6A-BWRNmF8S.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-DihWczP8.js → chunk-L5ZTLDWV-D48i966f.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-Bxnu-hme.js → chunk-LZXEDZCA-DLhg6Bok.js} +2 -2
- package/dist/client/assets/{chunk-ND2GUHAM-CoaR5kmP.js → chunk-ND2GUHAM-B4-7cOEq.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-By92Rd3d.js → chunk-NZK2D7GU-D2ttXA_d.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-D83Pkgfu.js → chunk-O5CBEL6O-BrWrOVCq.js} +1 -1
- package/dist/client/assets/{chunk-WU5MYG2G-v8OVf5Lz.js → chunk-WU5MYG2G-CLcPwxPe.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-DproSkn2.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-JVMMzJxJ.js +1 -0
- package/dist/client/assets/{dagre-BM42HDAG-Dq1ALF7Z.js → dagre-BM42HDAG-DIXN8_VX.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-1t1_TKtu.js → diagram-2AECGRRQ-D2wjdCij.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-DtvYRL6f.js → diagram-5GNKFQAL-E1Og_PHE.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-PRNrSX5F.js → diagram-KO2AKTUF-B6P1Ud8a.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-DaTX0DhT.js → diagram-LMA3HP47-C3Jxq56v.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-C2p9p-92.js → diagram-OG6HWLK6-Do9LVhdL.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-DKzLtnp-.js → erDiagram-TEJ5UH35-DLb5E4-f.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-GdL8lm6e.js → flowDiagram-I6XJVG4X-CcTs_wU9.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-Ok-4XYwT.js → ganttDiagram-6RSMTGT7-q9ez5fri.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-DSMrOCK7.js → gitGraphDiagram-PVQCEYII-BcaKiz4c.js} +1 -1
- package/dist/client/assets/index-1CokwSFm.css +2 -0
- package/dist/client/assets/index-CSOKbu3w.js +276 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-Dl4hRXis.js → infoDiagram-5YYISTIA-Cu0w4frE.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-C1Dc1fTT.js → ishikawaDiagram-YF4QCWOH-CJ47Z-ak.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-CUscmJze.js → journeyDiagram-JHISSGLW-fAL_Zcvs.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-C0nwYjQV.js → kanban-definition-UN3LZRKU-BTNIybMC.js} +1 -1
- package/dist/client/assets/{line-ByiuEIg_.js → line-BvsadeZR.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-B-XdAyDR.js → mermaid-parser.core-C0EkH2y_.js} +1 -1
- package/dist/client/assets/{mermaid.core-D_bIfuZD.js → mermaid.core-BU5QIIbY.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-BGNiPJDK.js → mindmap-definition-RKZ34NQL-CWbSYK8f.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-CP6FpAoO.js → pieDiagram-4H26LBE5-t4w2cB-y.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-dsAWBAQn.js → quadrantDiagram-W4KKPZXB-Cqasvrpa.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-DJH-zHqF.js → requirementDiagram-4Y6WPE33-_l-mY-tb.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-BJMnZrqH.js → sankeyDiagram-5OEKKPKP-Cr9YrZ-Y.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-CzNjUSlM.js → sequenceDiagram-3UESZ5HK-DvzZhQpb.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-jppMhOwh.js → stateDiagram-AJRCARHV-cFjPpAO3.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-btHMH5Cg.js +1 -0
- package/dist/client/assets/{timeline-definition-PNZ67QCA-BX2CI5H_.js → timeline-definition-PNZ67QCA-BjRNrEJY.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-Bd1KZaXh.js → vennDiagram-CIIHVFJN-xs9afjrw.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-D-0BNz49.js → wardleyDiagram-YWT4CUSO-DH68ZYti.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-DbYa0ZWK.js → xychartDiagram-2RQKCTM6-DLW5ktTU.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/db.js +231 -14
- package/dist/server/db.js.map +1 -1
- package/dist/server/index.js +93 -9
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/agent.js +368 -143
- package/dist/server/lib/agent.js.map +1 -1
- package/dist/server/lib/agentProvider.js.map +1 -1
- package/dist/server/lib/approvalReconciliation.js +14 -2
- package/dist/server/lib/approvalReconciliation.js.map +1 -1
- package/dist/server/lib/buildExecutionEnvironment.js +251 -57
- package/dist/server/lib/buildExecutionEnvironment.js.map +1 -1
- package/dist/server/lib/chatOperations.js +125 -3
- package/dist/server/lib/chatOperations.js.map +1 -1
- package/dist/server/lib/chatPostBuildRuns.js +12 -6
- package/dist/server/lib/chatPostBuildRuns.js.map +1 -1
- package/dist/server/lib/chatTargets.js +2 -1
- package/dist/server/lib/chatTargets.js.map +1 -1
- package/dist/server/lib/checkDefinitionCwd.js +34 -0
- package/dist/server/lib/checkDefinitionCwd.js.map +1 -0
- package/dist/server/lib/checkExecutionEnvironment.js +95 -0
- package/dist/server/lib/checkExecutionEnvironment.js.map +1 -0
- package/dist/server/lib/checkPolicyDefinitionIds.js +41 -0
- package/dist/server/lib/checkPolicyDefinitionIds.js.map +1 -0
- package/dist/server/lib/checkRepairDispatch.js +2 -0
- package/dist/server/lib/checkRepairDispatch.js.map +1 -1
- package/dist/server/lib/checkRunner.js +371 -175
- package/dist/server/lib/checkRunner.js.map +1 -1
- package/dist/server/lib/checkRuns.js +99 -8
- package/dist/server/lib/checkRuns.js.map +1 -1
- package/dist/server/lib/claudeAgentProvider.js +3 -6
- package/dist/server/lib/claudeAgentProvider.js.map +1 -1
- package/dist/server/lib/claudeStdin.js +27 -0
- package/dist/server/lib/claudeStdin.js.map +1 -0
- package/dist/server/lib/completedAssistantOutput.js +38 -0
- package/dist/server/lib/completedAssistantOutput.js.map +1 -0
- package/dist/server/lib/consequentialActionAuthority.js +99 -8
- package/dist/server/lib/consequentialActionAuthority.js.map +1 -1
- package/dist/server/lib/consequentialActions.js +42 -2
- package/dist/server/lib/consequentialActions.js.map +1 -1
- package/dist/server/lib/dockerSandboxCredentials.js +10 -3
- package/dist/server/lib/dockerSandboxCredentials.js.map +1 -1
- package/dist/server/lib/dockerSandboxEnvironmentOperations.js +9 -8
- package/dist/server/lib/dockerSandboxEnvironmentOperations.js.map +1 -1
- package/dist/server/lib/dockerSandboxExecutionEnvironment.js +167 -75
- package/dist/server/lib/dockerSandboxExecutionEnvironment.js.map +1 -1
- package/dist/server/lib/dockerSandboxExecutionProvider.js +22 -14
- package/dist/server/lib/dockerSandboxExecutionProvider.js.map +1 -1
- package/dist/server/lib/dockerSandboxNetworkPolicy.js +23 -14
- package/dist/server/lib/dockerSandboxNetworkPolicy.js.map +1 -1
- package/dist/server/lib/dockerSandboxReleaseProfiles.js +91 -0
- package/dist/server/lib/dockerSandboxReleaseProfiles.js.map +1 -0
- package/dist/server/lib/dockerSandboxRuntimeController.js +16 -1
- package/dist/server/lib/dockerSandboxRuntimeController.js.map +1 -1
- package/dist/server/lib/executionCredentialCapabilities.js +9 -6
- package/dist/server/lib/executionCredentialCapabilities.js.map +1 -1
- package/dist/server/lib/executionEnvironment.js.map +1 -1
- package/dist/server/lib/executionEnvironmentLifecycle.js +7 -0
- package/dist/server/lib/executionEnvironmentLifecycle.js.map +1 -1
- package/dist/server/lib/executionEnvironmentOperations.js +241 -0
- package/dist/server/lib/executionEnvironmentOperations.js.map +1 -0
- package/dist/server/lib/executionEnvironmentReconciliation.js +98 -3
- package/dist/server/lib/executionEnvironmentReconciliation.js.map +1 -1
- package/dist/server/lib/executionEnvironmentRoutes.js +83 -29
- package/dist/server/lib/executionEnvironmentRoutes.js.map +1 -1
- package/dist/server/lib/executionEnvironmentValidation.js +19 -5
- package/dist/server/lib/executionEnvironmentValidation.js.map +1 -1
- package/dist/server/lib/executionEnvironmentValidationOperations.js +58 -31
- package/dist/server/lib/executionEnvironmentValidationOperations.js.map +1 -1
- package/dist/server/lib/executionEnvironments.js +187 -9
- package/dist/server/lib/executionEnvironments.js.map +1 -1
- package/dist/server/lib/executionProfileCheckPolicy.js +14 -0
- package/dist/server/lib/executionProfileCheckPolicy.js.map +1 -0
- package/dist/server/lib/executionProfileRoutes.js +9 -1
- package/dist/server/lib/executionProfileRoutes.js.map +1 -1
- package/dist/server/lib/executionProfileStore.js +5 -3
- package/dist/server/lib/executionProfileStore.js.map +1 -1
- package/dist/server/lib/executionProfiles.js +97 -15
- package/dist/server/lib/executionProfiles.js.map +1 -1
- package/dist/server/lib/executionReconciliation.js +43 -6
- package/dist/server/lib/executionReconciliation.js.map +1 -1
- package/dist/server/lib/executionRunAuthority.js +115 -24
- package/dist/server/lib/executionRunAuthority.js.map +1 -1
- package/dist/server/lib/executionTargets.js +30 -4
- package/dist/server/lib/executionTargets.js.map +1 -1
- package/dist/server/lib/executionWorkloads.js +75 -0
- package/dist/server/lib/executionWorkloads.js.map +1 -0
- package/dist/server/lib/git.js +10 -1
- package/dist/server/lib/git.js.map +1 -1
- package/dist/server/lib/opencodeAgentProvider.js +3 -1
- package/dist/server/lib/opencodeAgentProvider.js.map +1 -1
- package/dist/server/lib/opencodeSessionOperations.js +5 -3
- package/dist/server/lib/opencodeSessionOperations.js.map +1 -1
- package/dist/server/lib/planQuestions.js +2 -1
- package/dist/server/lib/planQuestions.js.map +1 -1
- package/dist/server/lib/postBuildCheckRuns.js +9 -5
- package/dist/server/lib/postBuildCheckRuns.js.map +1 -1
- package/dist/server/lib/preview.js +47 -6
- package/dist/server/lib/preview.js.map +1 -1
- package/dist/server/lib/previewProxy.js +11 -3
- package/dist/server/lib/previewProxy.js.map +1 -1
- package/dist/server/lib/productionCheckApprovals.js +97 -35
- package/dist/server/lib/productionCheckApprovals.js.map +1 -1
- package/dist/server/lib/projectMemorySuggestions.js +29 -6
- package/dist/server/lib/projectMemorySuggestions.js.map +1 -1
- package/dist/server/lib/requiredCheckPolicy.js +3 -40
- package/dist/server/lib/requiredCheckPolicy.js.map +1 -1
- package/dist/server/lib/reviewAgentWatchdog.js +75 -0
- package/dist/server/lib/reviewAgentWatchdog.js.map +1 -0
- package/dist/server/lib/reviewFindingReconciliation.js +176 -0
- package/dist/server/lib/reviewFindingReconciliation.js.map +1 -0
- package/dist/server/lib/reviewFindings.js +45 -17
- package/dist/server/lib/reviewFindings.js.map +1 -1
- package/dist/server/lib/run.js +370 -80
- package/dist/server/lib/run.js.map +1 -1
- package/dist/server/lib/serviceRuns.js +196 -0
- package/dist/server/lib/serviceRuns.js.map +1 -0
- package/dist/server/lib/sessionTargets.js +34 -0
- package/dist/server/lib/sessionTargets.js.map +1 -1
- package/dist/server/lib/shell.js +20 -0
- package/dist/server/lib/shell.js.map +1 -1
- package/dist/server/lib/specArtifact.js +36 -15
- package/dist/server/lib/specArtifact.js.map +1 -1
- package/dist/server/lib/specBundleGroups.js +4 -4
- package/dist/server/lib/specBundleGroups.js.map +1 -1
- package/dist/server/lib/specOperations.js +2 -0
- package/dist/server/lib/specOperations.js.map +1 -1
- package/dist/server/lib/specReviewOperations.js +2 -0
- package/dist/server/lib/specReviewOperations.js.map +1 -1
- package/dist/server/lib/specTicketMaterialization.js +37 -24
- package/dist/server/lib/specTicketMaterialization.js.map +1 -1
- package/dist/server/lib/ticketFollowUpOperations.js +9 -4
- package/dist/server/lib/ticketFollowUpOperations.js.map +1 -1
- package/dist/server/lib/ticketRunOperations.js +1 -0
- package/dist/server/lib/ticketRunOperations.js.map +1 -1
- package/dist/server/lib/types.js +1 -0
- package/dist/server/lib/types.js.map +1 -1
- package/dist/server/lib/workloadExecutionEnvironment.js +2 -0
- package/dist/server/lib/workloadExecutionEnvironment.js.map +1 -0
- package/dist/server/lib/workspaceIdentity.js +30 -6
- package/dist/server/lib/workspaceIdentity.js.map +1 -1
- package/dist/server/workers/build.js +39 -8
- package/dist/server/workers/build.js.map +1 -1
- package/dist/server/workers/chat.js +142 -15
- package/dist/server/workers/chat.js.map +1 -1
- package/dist/server/workers/followUp.js +77 -20
- package/dist/server/workers/followUp.js.map +1 -1
- package/dist/server/workers/plan.js +295 -48
- package/dist/server/workers/plan.js.map +1 -1
- package/dist/server/workers/planFollowUp.js +77 -7
- package/dist/server/workers/planFollowUp.js.map +1 -1
- package/dist/server/workers/review.js +153 -40
- package/dist/server/workers/review.js.map +1 -1
- package/dist/server/workers/specReview.js +43 -5
- package/dist/server/workers/specReview.js.map +1 -1
- package/dist/server/workers/specSession.js +156 -31
- package/dist/server/workers/specSession.js.map +1 -1
- package/package.json +1 -1
- package/dist/client/assets/GitHubActionsDialog-CA189pr2.js +0 -1
- package/dist/client/assets/VerificationDialog-BPVkhKRj.js +0 -4
- package/dist/client/assets/channel-D0zqzBT_.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-ChhyvHH2.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Cl02kurK.js +0 -1
- package/dist/client/assets/index-Bs8KsdV9.js +0 -276
- package/dist/client/assets/index-DdwM8Wgt.css +0 -2
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CLR1WgdV.js +0 -1
package/dist/server/db.js
CHANGED
|
@@ -4,6 +4,7 @@ import { parseCheckDefinitionsJsonStrict, parseLegacyTestCommandsJsonStrict, pro
|
|
|
4
4
|
import { ensureParentDirectory, resolveArchonDbPath } from './lib/runtimePaths.js';
|
|
5
5
|
import { TRANSCRIPT_RUN_TEXT_LIMIT_BYTES, truncateUtf8 } from './lib/transcriptRuns.js';
|
|
6
6
|
import { createExecutionProfile, EXECUTION_PROFILE_SCHEMA_VERSION, fingerprintExecutionProfile, normalizeExecutionProfile, serializeExecutionProfile, } from './lib/executionProfiles.js';
|
|
7
|
+
import { hasConfiguredCheckPolicy } from './lib/executionProfileCheckPolicy.js';
|
|
7
8
|
const dbPath = ensureParentDirectory(resolveArchonDbPath());
|
|
8
9
|
const db = new Database(dbPath);
|
|
9
10
|
db.pragma('foreign_keys = ON');
|
|
@@ -181,7 +182,7 @@ db.exec(`
|
|
|
181
182
|
id TEXT PRIMARY KEY,
|
|
182
183
|
project_id TEXT NOT NULL,
|
|
183
184
|
revision INTEGER NOT NULL CHECK (revision > 0),
|
|
184
|
-
schema_version INTEGER NOT NULL CHECK (schema_version IN (1, 2)),
|
|
185
|
+
schema_version INTEGER NOT NULL CHECK (schema_version IN (1, 2, 3)),
|
|
185
186
|
fingerprint TEXT NOT NULL CHECK (length(fingerprint) = 64),
|
|
186
187
|
profile_json TEXT NOT NULL CHECK (
|
|
187
188
|
json_valid(profile_json)
|
|
@@ -221,7 +222,7 @@ db.exec(`
|
|
|
221
222
|
ON execution_profile_audit_events(project_id, created_at DESC, id DESC);
|
|
222
223
|
`);
|
|
223
224
|
const executionProfileRevisionsTableSql = db.prepare("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'execution_profile_revisions'").get()?.sql ?? '';
|
|
224
|
-
if (!executionProfileRevisionsTableSql.includes('schema_version IN (1, 2)')) {
|
|
225
|
+
if (!executionProfileRevisionsTableSql.includes('schema_version IN (1, 2, 3)')) {
|
|
225
226
|
db.pragma('foreign_keys = OFF');
|
|
226
227
|
db.transaction(() => {
|
|
227
228
|
const referencingTriggers = db.prepare(`
|
|
@@ -236,7 +237,7 @@ if (!executionProfileRevisionsTableSql.includes('schema_version IN (1, 2)')) {
|
|
|
236
237
|
id TEXT PRIMARY KEY,
|
|
237
238
|
project_id TEXT NOT NULL,
|
|
238
239
|
revision INTEGER NOT NULL CHECK (revision > 0),
|
|
239
|
-
schema_version INTEGER NOT NULL CHECK (schema_version IN (1, 2)),
|
|
240
|
+
schema_version INTEGER NOT NULL CHECK (schema_version IN (1, 2, 3)),
|
|
240
241
|
fingerprint TEXT NOT NULL CHECK (length(fingerprint) = 64),
|
|
241
242
|
profile_json TEXT NOT NULL CHECK (
|
|
242
243
|
json_valid(profile_json)
|
|
@@ -297,7 +298,7 @@ const backfillExecutionProfiles = () => {
|
|
|
297
298
|
}
|
|
298
299
|
})();
|
|
299
300
|
};
|
|
300
|
-
const
|
|
301
|
+
const backfillExecutionProfilesToCurrentSchema = () => {
|
|
301
302
|
const legacyRows = db.prepare(`
|
|
302
303
|
SELECT projects.id AS project_id,
|
|
303
304
|
revisions.id AS revision_id,
|
|
@@ -306,7 +307,7 @@ const backfillExecutionProfilesToSchemaV2 = () => {
|
|
|
306
307
|
INNER JOIN execution_profile_revisions revisions
|
|
307
308
|
ON revisions.id = projects.active_execution_profile_revision_id
|
|
308
309
|
AND revisions.project_id = projects.id
|
|
309
|
-
WHERE revisions.schema_version
|
|
310
|
+
WHERE revisions.schema_version IN (1, 2) AND projects.deletion_started_at IS NULL
|
|
310
311
|
`).all();
|
|
311
312
|
const nextRevisionNumber = db.prepare(`
|
|
312
313
|
SELECT COALESCE(MAX(revision), 0) + 1 AS revision
|
|
@@ -348,19 +349,118 @@ const backfillExecutionProfilesToSchemaV2 = () => {
|
|
|
348
349
|
revisionId = existing.id;
|
|
349
350
|
}
|
|
350
351
|
else {
|
|
351
|
-
revisionId = `${row.project_id}:execution-profile:
|
|
352
|
+
revisionId = `${row.project_id}:execution-profile:v${EXECUTION_PROFILE_SCHEMA_VERSION}`;
|
|
352
353
|
const revisionNumber = nextRevisionNumber.get(row.project_id).revision;
|
|
353
354
|
insertRevision.run(revisionId, row.project_id, revisionNumber, fingerprint, serializeExecutionProfile(normalized.profile));
|
|
354
355
|
}
|
|
355
356
|
const activated = activateRevision.run(revisionId, row.project_id, row.revision_id);
|
|
356
357
|
if (activated.changes > 0) {
|
|
357
|
-
insertEvent.run(`${revisionId}:
|
|
358
|
+
insertEvent.run(`${revisionId}:schema-backfill`, row.project_id, revisionId, row.revision_id);
|
|
358
359
|
}
|
|
359
360
|
}
|
|
360
361
|
})();
|
|
361
362
|
};
|
|
363
|
+
const backfillExecutionProfileWorkloadEligibility = () => {
|
|
364
|
+
const listActiveRows = db.prepare(`
|
|
365
|
+
SELECT projects.id AS project_id,
|
|
366
|
+
revisions.id AS revision_id,
|
|
367
|
+
revisions.profile_json,
|
|
368
|
+
projects.required_check_definition_ids,
|
|
369
|
+
projects.pre_review_check_definition_ids,
|
|
370
|
+
projects.post_build_check_definition_ids,
|
|
371
|
+
projects.auto_fix_check_definition_ids
|
|
372
|
+
FROM projects
|
|
373
|
+
INNER JOIN execution_profile_revisions revisions
|
|
374
|
+
ON revisions.id = projects.active_execution_profile_revision_id
|
|
375
|
+
AND revisions.project_id = projects.id
|
|
376
|
+
WHERE revisions.schema_version = ${EXECUTION_PROFILE_SCHEMA_VERSION}
|
|
377
|
+
AND projects.deletion_started_at IS NULL
|
|
378
|
+
`);
|
|
379
|
+
const nextRevisionNumber = db.prepare(`
|
|
380
|
+
SELECT COALESCE(MAX(revision), 0) + 1 AS revision
|
|
381
|
+
FROM execution_profile_revisions WHERE project_id = ?
|
|
382
|
+
`);
|
|
383
|
+
const findRevisionByFingerprint = db.prepare(`
|
|
384
|
+
SELECT id FROM execution_profile_revisions WHERE project_id = ? AND fingerprint = ?
|
|
385
|
+
`);
|
|
386
|
+
const insertRevision = db.prepare(`
|
|
387
|
+
INSERT OR IGNORE INTO execution_profile_revisions (
|
|
388
|
+
id, project_id, revision, schema_version, fingerprint, profile_json
|
|
389
|
+
) VALUES (?, ?, ?, ${EXECUTION_PROFILE_SCHEMA_VERSION}, ?, ?)
|
|
390
|
+
`);
|
|
391
|
+
const activateRevision = db.prepare(`
|
|
392
|
+
UPDATE projects SET active_execution_profile_revision_id = ?
|
|
393
|
+
WHERE id = ? AND active_execution_profile_revision_id = ?
|
|
394
|
+
`);
|
|
395
|
+
const insertEvent = db.prepare(`
|
|
396
|
+
INSERT OR IGNORE INTO execution_profile_audit_events (
|
|
397
|
+
id, project_id, event_type, profile_revision_id, previous_profile_revision_id
|
|
398
|
+
) VALUES (?, ?, ?, ?, ?)
|
|
399
|
+
`);
|
|
400
|
+
db.transaction(() => {
|
|
401
|
+
const activeRows = listActiveRows.all();
|
|
402
|
+
for (const row of activeRows) {
|
|
403
|
+
let normalized;
|
|
404
|
+
try {
|
|
405
|
+
normalized = normalizeExecutionProfile(JSON.parse(row.profile_json));
|
|
406
|
+
}
|
|
407
|
+
catch {
|
|
408
|
+
normalized = null;
|
|
409
|
+
}
|
|
410
|
+
if (!normalized?.ok) {
|
|
411
|
+
throw new Error(`Stored execution profile revision ${row.revision_id} is invalid`);
|
|
412
|
+
}
|
|
413
|
+
const buildEligible = normalized.profile.eligible_workloads.includes('build');
|
|
414
|
+
const needsChatBuild = buildEligible && !normalized.profile.eligible_workloads.includes('chat_build');
|
|
415
|
+
const needsCheckTemplate = buildEligible
|
|
416
|
+
&& hasConfiguredCheckPolicy(row)
|
|
417
|
+
&& normalized.profile.check_template_policy.mode !== 'agent_template';
|
|
418
|
+
if (!needsChatBuild && !needsCheckTemplate) {
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
const repaired = normalizeExecutionProfile({
|
|
422
|
+
...normalized.profile,
|
|
423
|
+
eligible_workloads: [
|
|
424
|
+
...normalized.profile.eligible_workloads,
|
|
425
|
+
...(needsChatBuild ? ['chat_build'] : []),
|
|
426
|
+
...(needsCheckTemplate ? ['check'] : []),
|
|
427
|
+
],
|
|
428
|
+
check_template_policy: needsCheckTemplate
|
|
429
|
+
? { mode: 'agent_template', agent: 'opencode' }
|
|
430
|
+
: normalized.profile.check_template_policy,
|
|
431
|
+
});
|
|
432
|
+
if (!repaired.ok) {
|
|
433
|
+
throw new Error(`Stored execution profile revision ${row.revision_id} is invalid`);
|
|
434
|
+
}
|
|
435
|
+
const fingerprint = fingerprintExecutionProfile(repaired.profile);
|
|
436
|
+
let target = findRevisionByFingerprint.get(row.project_id, fingerprint);
|
|
437
|
+
const repairKey = needsChatBuild && needsCheckTemplate
|
|
438
|
+
? 'chat-build-check'
|
|
439
|
+
: needsChatBuild
|
|
440
|
+
? 'chat-build'
|
|
441
|
+
: 'configured-check';
|
|
442
|
+
if (!target) {
|
|
443
|
+
const revisionId = `${row.project_id}:execution-profile:${repairKey}-v${EXECUTION_PROFILE_SCHEMA_VERSION}`;
|
|
444
|
+
const revisionNumber = nextRevisionNumber.get(row.project_id).revision;
|
|
445
|
+
const inserted = insertRevision.run(revisionId, row.project_id, revisionNumber, fingerprint, serializeExecutionProfile(repaired.profile));
|
|
446
|
+
target = findRevisionByFingerprint.get(row.project_id, fingerprint);
|
|
447
|
+
if (!target) {
|
|
448
|
+
throw new Error(`Failed to migrate stored execution profile revision ${row.revision_id}`);
|
|
449
|
+
}
|
|
450
|
+
if (inserted.changes > 0) {
|
|
451
|
+
insertEvent.run(`${target.id}:${repairKey}-backfill-created`, row.project_id, 'revision_created', target.id, row.revision_id);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
const activated = activateRevision.run(target.id, row.project_id, row.revision_id);
|
|
455
|
+
if (activated.changes > 0) {
|
|
456
|
+
insertEvent.run(`${target.id}:${repairKey}-backfill-activated`, row.project_id, 'revision_activated', target.id, row.revision_id);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}).immediate();
|
|
460
|
+
};
|
|
362
461
|
backfillExecutionProfiles();
|
|
363
|
-
|
|
462
|
+
backfillExecutionProfilesToCurrentSchema();
|
|
463
|
+
backfillExecutionProfileWorkloadEligibility();
|
|
364
464
|
const hostCompatibilityProfile = createExecutionProfile('host');
|
|
365
465
|
const hostCompatibilityProfileJson = serializeExecutionProfile(hostCompatibilityProfile).replaceAll("'", "''");
|
|
366
466
|
const hostCompatibilityFingerprint = fingerprintExecutionProfile(hostCompatibilityProfile);
|
|
@@ -2195,6 +2295,7 @@ db.exec(`
|
|
|
2195
2295
|
stage TEXT NOT NULL,
|
|
2196
2296
|
diff_signature TEXT,
|
|
2197
2297
|
workspace_signature TEXT,
|
|
2298
|
+
change_scope TEXT,
|
|
2198
2299
|
message_id TEXT,
|
|
2199
2300
|
model TEXT,
|
|
2200
2301
|
variant TEXT,
|
|
@@ -2212,6 +2313,7 @@ const migrateReviewRunsLifecycleSchema = () => {
|
|
|
2212
2313
|
const workspaceSignatureColumn = columns.find(column => column.name === 'workspace_signature');
|
|
2213
2314
|
const needsMigration = diffSignatureColumn?.notnull === 1
|
|
2214
2315
|
|| workspaceSignatureColumn?.notnull === 1
|
|
2316
|
+
|| !columns.some(column => column.name === 'change_scope')
|
|
2215
2317
|
|| !columns.some(column => column.name === 'model')
|
|
2216
2318
|
|| !columns.some(column => column.name === 'variant')
|
|
2217
2319
|
|| !columns.some(column => column.name === 'failure_message')
|
|
@@ -2232,6 +2334,7 @@ const migrateReviewRunsLifecycleSchema = () => {
|
|
|
2232
2334
|
stage TEXT NOT NULL,
|
|
2233
2335
|
diff_signature TEXT,
|
|
2234
2336
|
workspace_signature TEXT,
|
|
2337
|
+
change_scope TEXT,
|
|
2235
2338
|
message_id TEXT,
|
|
2236
2339
|
model TEXT,
|
|
2237
2340
|
variant TEXT,
|
|
@@ -2246,12 +2349,13 @@ const migrateReviewRunsLifecycleSchema = () => {
|
|
|
2246
2349
|
db.exec(`
|
|
2247
2350
|
INSERT INTO review_runs_v2 (
|
|
2248
2351
|
id, ticket_id, project_id, worktree_bundle_id, stage, diff_signature,
|
|
2249
|
-
workspace_signature, message_id, model, variant, failure_message,
|
|
2352
|
+
workspace_signature, change_scope, message_id, model, variant, failure_message,
|
|
2250
2353
|
status, created_at, updated_at
|
|
2251
2354
|
)
|
|
2252
2355
|
SELECT
|
|
2253
2356
|
id, ticket_id, project_id, worktree_bundle_id, stage, diff_signature,
|
|
2254
|
-
${selectColumn('workspace_signature', 'NULL')},
|
|
2357
|
+
${selectColumn('workspace_signature', 'NULL')},
|
|
2358
|
+
${selectColumn('change_scope', 'NULL')}, message_id,
|
|
2255
2359
|
${selectColumn('model', 'NULL')}, ${selectColumn('variant', 'NULL')},
|
|
2256
2360
|
${selectColumn('failure_message', 'NULL')}, status, created_at,
|
|
2257
2361
|
${selectColumn('updated_at', 'created_at')}
|
|
@@ -2497,6 +2601,49 @@ const migrateExecutionLifecycleSchema = () => {
|
|
|
2497
2601
|
}
|
|
2498
2602
|
};
|
|
2499
2603
|
migrateExecutionLifecycleSchema();
|
|
2604
|
+
db.exec(`
|
|
2605
|
+
CREATE TABLE IF NOT EXISTS service_run_details (
|
|
2606
|
+
execution_run_id TEXT PRIMARY KEY,
|
|
2607
|
+
project_id TEXT NOT NULL,
|
|
2608
|
+
context_key TEXT NOT NULL,
|
|
2609
|
+
target_kind TEXT NOT NULL,
|
|
2610
|
+
target_key TEXT NOT NULL,
|
|
2611
|
+
target_workspace_path TEXT NOT NULL,
|
|
2612
|
+
execution_profile_revision_id TEXT NOT NULL,
|
|
2613
|
+
execution_profile_fingerprint TEXT NOT NULL,
|
|
2614
|
+
provider_kind TEXT,
|
|
2615
|
+
environment_id TEXT,
|
|
2616
|
+
environment_revision INTEGER,
|
|
2617
|
+
service_snapshot_json TEXT NOT NULL,
|
|
2618
|
+
placement_json TEXT,
|
|
2619
|
+
interruption_scope TEXT,
|
|
2620
|
+
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
2621
|
+
started_at DATETIME,
|
|
2622
|
+
completed_at DATETIME,
|
|
2623
|
+
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
2624
|
+
FOREIGN KEY (execution_run_id, project_id) REFERENCES execution_runs(id, project_id) ON DELETE CASCADE,
|
|
2625
|
+
FOREIGN KEY (project_id, execution_profile_revision_id)
|
|
2626
|
+
REFERENCES execution_profile_revisions(project_id, id) ON DELETE RESTRICT,
|
|
2627
|
+
CHECK (length(CAST(context_key AS BLOB)) BETWEEN 1 AND 1000),
|
|
2628
|
+
CHECK (length(CAST(target_kind AS BLOB)) BETWEEN 1 AND 100),
|
|
2629
|
+
CHECK (length(CAST(target_key AS BLOB)) BETWEEN 1 AND 1000),
|
|
2630
|
+
CHECK (length(CAST(target_workspace_path AS BLOB)) BETWEEN 1 AND 4096),
|
|
2631
|
+
CHECK (length(execution_profile_fingerprint) = 64 AND execution_profile_fingerprint NOT GLOB '*[^0-9a-f]*'),
|
|
2632
|
+
CHECK (provider_kind IS NULL OR provider_kind IN ('host', 'docker_sandbox')),
|
|
2633
|
+
CHECK ((environment_id IS NULL) = (environment_revision IS NULL)),
|
|
2634
|
+
CHECK (environment_revision IS NULL OR environment_revision >= 1),
|
|
2635
|
+
CHECK (length(CAST(service_snapshot_json AS BLOB)) BETWEEN 2 AND 16384),
|
|
2636
|
+
CHECK (placement_json IS NULL OR length(CAST(placement_json AS BLOB)) BETWEEN 2 AND 16384),
|
|
2637
|
+
CHECK (interruption_scope IS NULL OR interruption_scope IN ('local_processes', 'whole_environment'))
|
|
2638
|
+
);
|
|
2639
|
+
|
|
2640
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_active_service_run_context
|
|
2641
|
+
ON service_run_details(project_id, context_key)
|
|
2642
|
+
WHERE completed_at IS NULL;
|
|
2643
|
+
|
|
2644
|
+
CREATE INDEX IF NOT EXISTS idx_service_run_profile
|
|
2645
|
+
ON service_run_details(project_id, execution_profile_revision_id, created_at);
|
|
2646
|
+
`);
|
|
2500
2647
|
const executionEnvironmentStates = "'queued', 'preparing', 'ready', 'running', 'stopped', 'retiring', 'cleanup_pending', 'retired', 'failed', 'unavailable'";
|
|
2501
2648
|
db.exec(`
|
|
2502
2649
|
CREATE TABLE IF NOT EXISTS execution_environments (
|
|
@@ -2526,6 +2673,11 @@ db.exec(`
|
|
|
2526
2673
|
cleanup_claim_id TEXT,
|
|
2527
2674
|
cleanup_claimed_at DATETIME,
|
|
2528
2675
|
cleanup_attempts INTEGER NOT NULL DEFAULT 0,
|
|
2676
|
+
cleanup_retry_at DATETIME,
|
|
2677
|
+
idle_stop_at DATETIME,
|
|
2678
|
+
operation_claim_id TEXT,
|
|
2679
|
+
operation_kind TEXT,
|
|
2680
|
+
operation_claimed_at DATETIME,
|
|
2529
2681
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
2530
2682
|
preparation_started_at DATETIME,
|
|
2531
2683
|
ready_at DATETIME,
|
|
@@ -2567,7 +2719,10 @@ db.exec(`
|
|
|
2567
2719
|
CHECK (failure_message IS NULL OR length(failure_message) <= 4000),
|
|
2568
2720
|
CHECK (failure_details_json IS NULL OR length(CAST(failure_details_json AS BLOB)) <= 16384),
|
|
2569
2721
|
CHECK ((cleanup_claim_id IS NULL) = (cleanup_claimed_at IS NULL)),
|
|
2570
|
-
CHECK (cleanup_attempts >= 0)
|
|
2722
|
+
CHECK (cleanup_attempts >= 0),
|
|
2723
|
+
CHECK ((operation_claim_id IS NULL) = (operation_kind IS NULL)),
|
|
2724
|
+
CHECK ((operation_claim_id IS NULL) = (operation_claimed_at IS NULL)),
|
|
2725
|
+
CHECK (operation_kind IS NULL OR operation_kind IN ('stop', 'retire', 'reset', 'cleanup_retry'))
|
|
2571
2726
|
);
|
|
2572
2727
|
|
|
2573
2728
|
CREATE TABLE IF NOT EXISTS execution_environment_events (
|
|
@@ -2691,6 +2846,11 @@ ensureColumn('execution_environments', 'execution_profile_revision_id', 'TEXT');
|
|
|
2691
2846
|
ensureColumn('execution_environments', 'execution_profile_fingerprint', 'TEXT');
|
|
2692
2847
|
ensureColumn('execution_environments', 'credential_requirements_fingerprint', 'TEXT');
|
|
2693
2848
|
ensureColumn('execution_environments', 'retirement_requested_at', 'DATETIME');
|
|
2849
|
+
ensureColumn('execution_environments', 'cleanup_retry_at', 'DATETIME');
|
|
2850
|
+
ensureColumn('execution_environments', 'idle_stop_at', 'DATETIME');
|
|
2851
|
+
ensureColumn('execution_environments', 'operation_claim_id', 'TEXT');
|
|
2852
|
+
ensureColumn('execution_environments', 'operation_kind', 'TEXT');
|
|
2853
|
+
ensureColumn('execution_environments', 'operation_claimed_at', 'DATETIME');
|
|
2694
2854
|
ensureColumn('execution_environment_run_bindings', 'execution_profile_fingerprint', 'TEXT');
|
|
2695
2855
|
ensureColumn('execution_environment_run_bindings', 'authority_json', 'TEXT');
|
|
2696
2856
|
ensureColumn('execution_environment_run_bindings', 'placement_json', 'TEXT');
|
|
@@ -3086,9 +3246,41 @@ db.exec('DROP INDEX IF EXISTS idx_execution_environments_reuse');
|
|
|
3086
3246
|
db.exec('CREATE INDEX idx_execution_environments_reuse ON execution_environments(project_id, provider_kind, target_key, target_workspace_path, environment_revision, workspace_mode, environment_validation_fingerprint, execution_profile_fingerprint, credential_requirements_fingerprint, retirement_requested_at, lifecycle_state)');
|
|
3087
3247
|
db.exec('CREATE UNIQUE INDEX IF NOT EXISTS idx_execution_environments_external_id ON execution_environments(provider_kind, external_id) WHERE external_id IS NOT NULL');
|
|
3088
3248
|
db.exec('CREATE INDEX IF NOT EXISTS idx_execution_environments_cleanup ON execution_environments(lifecycle_state, cleanup_claim_id, updated_at, cleanup_attempts)');
|
|
3249
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_execution_environments_cleanup_retry ON execution_environments(lifecycle_state, cleanup_retry_at, cleanup_claim_id)');
|
|
3250
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_execution_environments_idle_stop ON execution_environments(idle_stop_at, lifecycle_state) WHERE idle_stop_at IS NOT NULL');
|
|
3251
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_execution_environments_operation_claim ON execution_environments(operation_claim_id, operation_claimed_at) WHERE operation_claim_id IS NOT NULL');
|
|
3089
3252
|
db.exec('CREATE INDEX IF NOT EXISTS idx_execution_environment_events_sequence ON execution_environment_events(project_id, environment_id, sequence)');
|
|
3090
3253
|
db.exec('CREATE INDEX IF NOT EXISTS idx_execution_environment_bindings_run ON execution_environment_run_bindings(project_id, execution_run_id, bound_at)');
|
|
3091
3254
|
db.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_execution_environment_active_execution_lease ON execution_environment_run_bindings(environment_id) WHERE relationship = 'execution' AND released_at IS NULL");
|
|
3255
|
+
db.exec(`
|
|
3256
|
+
CREATE TRIGGER IF NOT EXISTS validate_execution_environment_operation_claim
|
|
3257
|
+
BEFORE UPDATE OF operation_claim_id, operation_kind, operation_claimed_at ON execution_environments
|
|
3258
|
+
WHEN NOT (
|
|
3259
|
+
(NEW.operation_claim_id IS NULL AND NEW.operation_kind IS NULL AND NEW.operation_claimed_at IS NULL)
|
|
3260
|
+
OR (
|
|
3261
|
+
length(NEW.operation_claim_id) BETWEEN 1 AND 128
|
|
3262
|
+
AND NEW.operation_kind IN ('stop', 'retire', 'reset', 'cleanup_retry')
|
|
3263
|
+
AND NEW.operation_claimed_at IS NOT NULL
|
|
3264
|
+
)
|
|
3265
|
+
)
|
|
3266
|
+
BEGIN
|
|
3267
|
+
SELECT RAISE(ABORT, 'Invalid execution environment operation claim');
|
|
3268
|
+
END;
|
|
3269
|
+
|
|
3270
|
+
CREATE TRIGGER IF NOT EXISTS validate_execution_environment_lease_admission
|
|
3271
|
+
BEFORE INSERT ON execution_environment_run_bindings
|
|
3272
|
+
WHEN NEW.relationship = 'execution' AND NOT EXISTS (
|
|
3273
|
+
SELECT 1 FROM execution_environments
|
|
3274
|
+
WHERE id = NEW.environment_id
|
|
3275
|
+
AND project_id = NEW.project_id
|
|
3276
|
+
AND lifecycle_state IN ('ready', 'running', 'stopped')
|
|
3277
|
+
AND retirement_requested_at IS NULL
|
|
3278
|
+
AND operation_claim_id IS NULL
|
|
3279
|
+
)
|
|
3280
|
+
BEGIN
|
|
3281
|
+
SELECT RAISE(ABORT, 'Execution environment is not admitting leases');
|
|
3282
|
+
END;
|
|
3283
|
+
`);
|
|
3092
3284
|
db.exec(`
|
|
3093
3285
|
CREATE TRIGGER IF NOT EXISTS validate_repository_graph_execution_run_binding
|
|
3094
3286
|
BEFORE UPDATE OF execution_run_id ON repository_graph_scans
|
|
@@ -3360,6 +3552,8 @@ db.exec(`
|
|
|
3360
3552
|
automation_boundary_purpose TEXT,
|
|
3361
3553
|
purpose TEXT NOT NULL DEFAULT 'manual',
|
|
3362
3554
|
causal_source_run_id TEXT,
|
|
3555
|
+
runtime_compatibility_json TEXT,
|
|
3556
|
+
batch_environment_json TEXT,
|
|
3363
3557
|
FOREIGN KEY (execution_run_id) REFERENCES execution_runs(id) ON DELETE CASCADE,
|
|
3364
3558
|
FOREIGN KEY (rerun_of_batch_run_id) REFERENCES execution_runs(id) ON DELETE RESTRICT,
|
|
3365
3559
|
FOREIGN KEY (causal_source_run_id) REFERENCES execution_runs(id) ON DELETE RESTRICT,
|
|
@@ -3409,6 +3603,7 @@ db.exec(`
|
|
|
3409
3603
|
total_persisted_bytes INTEGER NOT NULL DEFAULT 0,
|
|
3410
3604
|
retained_output TEXT NOT NULL DEFAULT '',
|
|
3411
3605
|
output_retention_state TEXT NOT NULL DEFAULT 'retained',
|
|
3606
|
+
placement_json TEXT,
|
|
3412
3607
|
FOREIGN KEY (execution_run_id) REFERENCES execution_runs(id) ON DELETE CASCADE,
|
|
3413
3608
|
FOREIGN KEY (batch_run_id) REFERENCES execution_runs(id) ON DELETE RESTRICT,
|
|
3414
3609
|
FOREIGN KEY (rerun_of_attempt_run_id) REFERENCES execution_runs(id) ON DELETE RESTRICT,
|
|
@@ -3416,7 +3611,7 @@ db.exec(`
|
|
|
3416
3611
|
CHECK (length(definition_fingerprint) = 64 AND definition_fingerprint NOT GLOB '*[^0-9a-f]*'),
|
|
3417
3612
|
CHECK (outcome IS NULL OR outcome IN ('passed', 'command_failure', 'spawn_failure',
|
|
3418
3613
|
'infrastructure_failure', 'evidence_persistence_failure', 'timeout',
|
|
3419
|
-
'workspace_changed_before_start', 'user_stop', 'restart_loss', 'shutdown_loss', 'ambiguous_process_loss')),
|
|
3614
|
+
'workspace_changed_before_start', 'user_stop', 'restart_loss', 'shutdown_loss', 'ambiguous_process_loss', 'environment_loss')),
|
|
3420
3615
|
CHECK (output_revision >= 0 AND retained_start_offset >= 0 AND retained_end_offset >= retained_start_offset
|
|
3421
3616
|
AND total_persisted_bytes >= retained_end_offset),
|
|
3422
3617
|
CHECK (output_retention_state IN ('retained', 'expired'))
|
|
@@ -3424,11 +3619,15 @@ db.exec(`
|
|
|
3424
3619
|
`);
|
|
3425
3620
|
ensureColumn('check_attempt_details', 'retained_end_offset', 'INTEGER NOT NULL DEFAULT 0');
|
|
3426
3621
|
ensureColumn('check_attempt_details', 'retained_output', "TEXT NOT NULL DEFAULT ''");
|
|
3622
|
+
ensureColumn('check_attempt_details', 'placement_json', 'TEXT');
|
|
3623
|
+
ensureColumn('check_batch_details', 'runtime_compatibility_json', 'TEXT');
|
|
3624
|
+
ensureColumn('check_batch_details', 'batch_environment_json', 'TEXT');
|
|
3427
3625
|
const checkAttemptSchema = db.prepare(`
|
|
3428
3626
|
SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'check_attempt_details'
|
|
3429
3627
|
`).get();
|
|
3430
3628
|
if (checkAttemptSchema && (!checkAttemptSchema.sql.includes('evidence_persistence_failure')
|
|
3431
|
-
|| !checkAttemptSchema.sql.includes('ambiguous_process_loss')
|
|
3629
|
+
|| !checkAttemptSchema.sql.includes('ambiguous_process_loss')
|
|
3630
|
+
|| !checkAttemptSchema.sql.includes('environment_loss'))) {
|
|
3432
3631
|
const foreignKeysEnabled = db.pragma('foreign_keys', { simple: true }) === 1;
|
|
3433
3632
|
if (foreignKeysEnabled) {
|
|
3434
3633
|
db.pragma('foreign_keys = OFF');
|
|
@@ -3469,7 +3668,7 @@ if (checkAttemptSchema && (!checkAttemptSchema.sql.includes('evidence_persistenc
|
|
|
3469
3668
|
CHECK (length(definition_fingerprint) = 64 AND definition_fingerprint NOT GLOB '*[^0-9a-f]*'),
|
|
3470
3669
|
CHECK (outcome IS NULL OR outcome IN ('passed', 'command_failure', 'spawn_failure',
|
|
3471
3670
|
'infrastructure_failure', 'evidence_persistence_failure', 'timeout',
|
|
3472
|
-
'workspace_changed_before_start', 'user_stop', 'restart_loss', 'shutdown_loss', 'ambiguous_process_loss')),
|
|
3671
|
+
'workspace_changed_before_start', 'user_stop', 'restart_loss', 'shutdown_loss', 'ambiguous_process_loss', 'environment_loss')),
|
|
3473
3672
|
CHECK (output_revision >= 0 AND retained_start_offset >= 0 AND retained_end_offset >= retained_start_offset
|
|
3474
3673
|
AND total_persisted_bytes >= retained_end_offset),
|
|
3475
3674
|
CHECK (output_retention_state IN ('retained', 'expired'))
|
|
@@ -3503,6 +3702,7 @@ if (checkAttemptSchema && (!checkAttemptSchema.sql.includes('evidence_persistenc
|
|
|
3503
3702
|
throw new Error(`Check attempt migration left an invalid foreign key: ${JSON.stringify(foreignKeyViolation)}`);
|
|
3504
3703
|
}
|
|
3505
3704
|
}
|
|
3705
|
+
ensureColumn('check_attempt_details', 'placement_json', 'TEXT');
|
|
3506
3706
|
db.exec(`
|
|
3507
3707
|
CREATE TABLE IF NOT EXISTS check_attempt_diagnostic_parsers (
|
|
3508
3708
|
attempt_run_id TEXT PRIMARY KEY,
|
|
@@ -4416,6 +4616,8 @@ db.prepare(`
|
|
|
4416
4616
|
db.exec('DROP TRIGGER IF EXISTS validate_check_batch_details_insert');
|
|
4417
4617
|
db.exec('DROP TRIGGER IF EXISTS preserve_check_batch_snapshots');
|
|
4418
4618
|
db.exec('DROP TRIGGER IF EXISTS preserve_completed_check_batch_details');
|
|
4619
|
+
db.exec('DROP TRIGGER IF EXISTS preserve_check_batch_environment_binding');
|
|
4620
|
+
db.exec('DROP TRIGGER IF EXISTS preserve_check_attempt_placement');
|
|
4419
4621
|
db.exec(`
|
|
4420
4622
|
CREATE TRIGGER IF NOT EXISTS preserve_check_batch_snapshots
|
|
4421
4623
|
BEFORE UPDATE OF execution_run_id, target_kind, target_bundle_id, target_label,
|
|
@@ -4432,6 +4634,14 @@ db.exec(`
|
|
|
4432
4634
|
SELECT RAISE(ABORT, 'Completed check batch details are immutable');
|
|
4433
4635
|
END;
|
|
4434
4636
|
|
|
4637
|
+
CREATE TRIGGER IF NOT EXISTS preserve_check_batch_environment_binding
|
|
4638
|
+
BEFORE UPDATE OF runtime_compatibility_json, batch_environment_json ON check_batch_details
|
|
4639
|
+
WHEN OLD.runtime_compatibility_json IS NOT NULL OR OLD.batch_environment_json IS NOT NULL
|
|
4640
|
+
OR NEW.runtime_compatibility_json IS NULL OR NEW.batch_environment_json IS NULL
|
|
4641
|
+
BEGIN
|
|
4642
|
+
SELECT RAISE(ABORT, 'Check batch environment binding is immutable');
|
|
4643
|
+
END;
|
|
4644
|
+
|
|
4435
4645
|
CREATE TRIGGER IF NOT EXISTS preserve_check_attempt_snapshots
|
|
4436
4646
|
BEFORE UPDATE OF execution_run_id, batch_run_id, definition_id, command_snapshot_json,
|
|
4437
4647
|
definition_fingerprint, initial_workspace_identity_json, rerun_of_attempt_run_id
|
|
@@ -4448,6 +4658,13 @@ db.exec(`
|
|
|
4448
4658
|
SELECT RAISE(ABORT, 'Completed check attempt details are immutable');
|
|
4449
4659
|
END;
|
|
4450
4660
|
|
|
4661
|
+
CREATE TRIGGER IF NOT EXISTS preserve_check_attempt_placement
|
|
4662
|
+
BEFORE UPDATE OF placement_json ON check_attempt_details
|
|
4663
|
+
WHEN OLD.placement_json IS NOT NULL OR NEW.placement_json IS NULL
|
|
4664
|
+
BEGIN
|
|
4665
|
+
SELECT RAISE(ABORT, 'Check attempt placement is immutable');
|
|
4666
|
+
END;
|
|
4667
|
+
|
|
4451
4668
|
CREATE TRIGGER IF NOT EXISTS validate_check_batch_details_insert
|
|
4452
4669
|
BEFORE INSERT ON check_batch_details
|
|
4453
4670
|
WHEN NOT EXISTS (
|