@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.
- package/dist/client/assets/{ActivityView-DDE3U1zB.js → ActivityView-CdEPjmqD.js} +1 -1
- package/dist/client/assets/GitHubActionsDialog-CA189pr2.js +1 -0
- package/dist/client/assets/VerificationDialog-BPVkhKRj.js +4 -0
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-oPUmRpZr.js → architectureDiagram-3BPJPVTR-BrZ08mqq.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-0sq1jkkp.js → blockDiagram-GPEHLZMM-b93XwJ6Z.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-BeDxMy7J.js → c4Diagram-AAUBKEIU-BKOdbZ_v.js} +1 -1
- package/dist/client/assets/channel-D0zqzBT_.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-D8VGsje2.js → chunk-2J33WTMH-D7Vxn_1m.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-DuTUTeBe.js → chunk-3OPIFGDE-B1zo2UZq.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-BzX5dPNW.js → chunk-5ZQYHXKU-BajvkDdQ.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-DS9putxN.js → chunk-727SXJPM-CSH7cVpV.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-CWzFZRBv.js → chunk-AQP2D5EJ-DE-wgUNP.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-DXZ-ADYW.js → chunk-CSCIHK7Q-Ba7JgCEf.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-BD7mL3KK.js → chunk-KSCS5N6A-0o3YWkHM.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-DmYQi9AP.js → chunk-L5ZTLDWV-DihWczP8.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-CZyFYHvS.js → chunk-LZXEDZCA-Bxnu-hme.js} +2 -2
- package/dist/client/assets/{chunk-ND2GUHAM-BxdjvT9I.js → chunk-ND2GUHAM-CoaR5kmP.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-BwuZcZ_9.js → chunk-NZK2D7GU-By92Rd3d.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-CC-TZXr3.js → chunk-O5CBEL6O-D83Pkgfu.js} +1 -1
- package/dist/client/assets/{chunk-WU5MYG2G-CJZJkca2.js → chunk-WU5MYG2G-v8OVf5Lz.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-ChhyvHH2.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Cl02kurK.js +1 -0
- package/dist/client/assets/{dagre-BM42HDAG-D2L5RvPF.js → dagre-BM42HDAG-Dq1ALF7Z.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-DBJzxSqZ.js → diagram-2AECGRRQ-1t1_TKtu.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-J_1M-Wou.js → diagram-5GNKFQAL-DtvYRL6f.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-CmT1Vbmc.js → diagram-KO2AKTUF-PRNrSX5F.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-DfPoJyQI.js → diagram-LMA3HP47-DaTX0DhT.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-D4uEb6vo.js → diagram-OG6HWLK6-C2p9p-92.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-l7yIFj0e.js → erDiagram-TEJ5UH35-DKzLtnp-.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-B3caTMes.js → flowDiagram-I6XJVG4X-GdL8lm6e.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-9Am36v9m.js → ganttDiagram-6RSMTGT7-Ok-4XYwT.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-B7OjYsv_.js → gitGraphDiagram-PVQCEYII-DSMrOCK7.js} +1 -1
- package/dist/client/assets/index-Bs8KsdV9.js +276 -0
- package/dist/client/assets/index-DdwM8Wgt.css +2 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-ZAcNejkW.js → infoDiagram-5YYISTIA-Dl4hRXis.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-BaaJwuN0.js → ishikawaDiagram-YF4QCWOH-C1Dc1fTT.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-DjzTU3kM.js → journeyDiagram-JHISSGLW-CUscmJze.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-DYRchzub.js → kanban-definition-UN3LZRKU-C0nwYjQV.js} +1 -1
- package/dist/client/assets/{line-X0j9gj61.js → line-ByiuEIg_.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-DCKG87Vl.js → mermaid-parser.core-B-XdAyDR.js} +1 -1
- package/dist/client/assets/{mermaid.core-BxI5T2gs.js → mermaid.core-D_bIfuZD.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-BE7MZzQO.js → mindmap-definition-RKZ34NQL-BGNiPJDK.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-D3fTYovg.js → pieDiagram-4H26LBE5-CP6FpAoO.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-B35nXRdQ.js → quadrantDiagram-W4KKPZXB-dsAWBAQn.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-CLBcHvP0.js → requirementDiagram-4Y6WPE33-DJH-zHqF.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-DdBCxGHF.js → sankeyDiagram-5OEKKPKP-BJMnZrqH.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-KcLt0X1K.js → sequenceDiagram-3UESZ5HK-CzNjUSlM.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-Bq23ObLK.js → stateDiagram-AJRCARHV-jppMhOwh.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CLR1WgdV.js +1 -0
- package/dist/client/assets/{timeline-definition-PNZ67QCA-SK3oVUD9.js → timeline-definition-PNZ67QCA-BX2CI5H_.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-COVtAlEC.js → vennDiagram-CIIHVFJN-Bd1KZaXh.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-BvfOOwga.js → wardleyDiagram-YWT4CUSO-D-0BNz49.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-DFnAD9k4.js → xychartDiagram-2RQKCTM6-DbYa0ZWK.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/db.js +780 -16
- package/dist/server/db.js.map +1 -1
- package/dist/server/index.js +198 -20
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/agent.js +8 -4
- package/dist/server/lib/agent.js.map +1 -1
- package/dist/server/lib/agentProvider.js +8 -1
- package/dist/server/lib/agentProvider.js.map +1 -1
- package/dist/server/lib/approvalReconciliation.js +101 -0
- package/dist/server/lib/approvalReconciliation.js.map +1 -0
- package/dist/server/lib/approvalRequests.js +587 -0
- package/dist/server/lib/approvalRequests.js.map +1 -0
- package/dist/server/lib/approvalRoutes.js +143 -0
- package/dist/server/lib/approvalRoutes.js.map +1 -0
- package/dist/server/lib/automationProgression.js +44 -14
- package/dist/server/lib/automationProgression.js.map +1 -1
- package/dist/server/lib/buildCompletionContinuation.js +14 -3
- package/dist/server/lib/buildCompletionContinuation.js.map +1 -1
- package/dist/server/lib/buildExecutionEnvironment.js +350 -66
- package/dist/server/lib/buildExecutionEnvironment.js.map +1 -1
- package/dist/server/lib/buildOpenQuestionOperations.js +47 -3
- package/dist/server/lib/buildOpenQuestionOperations.js.map +1 -1
- package/dist/server/lib/buildSequences.js +267 -18
- package/dist/server/lib/buildSequences.js.map +1 -1
- package/dist/server/lib/buildSetupAuthority.js +138 -0
- package/dist/server/lib/buildSetupAuthority.js.map +1 -0
- package/dist/server/lib/bundleReviewOperations.js +15 -4
- package/dist/server/lib/bundleReviewOperations.js.map +1 -1
- package/dist/server/lib/checkDefinitions.js +29 -1
- package/dist/server/lib/checkDefinitions.js.map +1 -1
- package/dist/server/lib/checkRunner.js +306 -27
- package/dist/server/lib/checkRunner.js.map +1 -1
- package/dist/server/lib/checkRuns.js +4 -2
- package/dist/server/lib/checkRuns.js.map +1 -1
- package/dist/server/lib/consequentialActionAuthority.js +142 -0
- package/dist/server/lib/consequentialActionAuthority.js.map +1 -0
- package/dist/server/lib/consequentialActions.js +231 -0
- package/dist/server/lib/consequentialActions.js.map +1 -0
- package/dist/server/lib/dockerSandboxCredentials.js +64 -10
- package/dist/server/lib/dockerSandboxCredentials.js.map +1 -1
- package/dist/server/lib/dockerSandboxEnvironmentOperations.js +119 -0
- package/dist/server/lib/dockerSandboxEnvironmentOperations.js.map +1 -1
- package/dist/server/lib/dockerSandboxExecutionEnvironment.js +174 -11
- package/dist/server/lib/dockerSandboxExecutionEnvironment.js.map +1 -1
- package/dist/server/lib/dockerSandboxExecutionProvider.js +12 -3
- package/dist/server/lib/dockerSandboxExecutionProvider.js.map +1 -1
- package/dist/server/lib/dockerSandboxNetworkPolicy.js +222 -0
- package/dist/server/lib/dockerSandboxNetworkPolicy.js.map +1 -0
- package/dist/server/lib/executionCredentialCapabilities.js +106 -0
- package/dist/server/lib/executionCredentialCapabilities.js.map +1 -0
- package/dist/server/lib/executionEnvironment.js.map +1 -1
- package/dist/server/lib/executionEnvironmentContexts.js +59 -3
- package/dist/server/lib/executionEnvironmentContexts.js.map +1 -1
- package/dist/server/lib/executionEnvironmentLifecycle.js +34 -0
- package/dist/server/lib/executionEnvironmentLifecycle.js.map +1 -1
- package/dist/server/lib/executionEnvironmentRoutes.js +127 -9
- package/dist/server/lib/executionEnvironmentRoutes.js.map +1 -1
- package/dist/server/lib/executionEnvironmentValidation.js +169 -45
- package/dist/server/lib/executionEnvironmentValidation.js.map +1 -1
- package/dist/server/lib/executionEnvironmentValidationOperations.js +203 -19
- package/dist/server/lib/executionEnvironmentValidationOperations.js.map +1 -1
- package/dist/server/lib/executionEnvironments.js +103 -14
- package/dist/server/lib/executionEnvironments.js.map +1 -1
- package/dist/server/lib/executionProfileRoutes.js +67 -0
- package/dist/server/lib/executionProfileRoutes.js.map +1 -0
- package/dist/server/lib/executionProfileStore.js +117 -0
- package/dist/server/lib/executionProfileStore.js.map +1 -0
- package/dist/server/lib/executionProfiles.js +324 -0
- package/dist/server/lib/executionProfiles.js.map +1 -0
- package/dist/server/lib/executionReconciliation.js +345 -197
- package/dist/server/lib/executionReconciliation.js.map +1 -1
- package/dist/server/lib/executionRetry.js +24 -5
- package/dist/server/lib/executionRetry.js.map +1 -1
- package/dist/server/lib/executionRunAuthority.js +467 -0
- package/dist/server/lib/executionRunAuthority.js.map +1 -0
- package/dist/server/lib/executionRuns.js +30 -4
- package/dist/server/lib/executionRuns.js.map +1 -1
- package/dist/server/lib/executionTimeline.js +2 -1
- package/dist/server/lib/executionTimeline.js.map +1 -1
- package/dist/server/lib/git.js +77 -10
- package/dist/server/lib/git.js.map +1 -1
- package/dist/server/lib/gitPushApprovals.js +367 -0
- package/dist/server/lib/gitPushApprovals.js.map +1 -0
- package/dist/server/lib/hostExecutionEnvironment.js +7 -1
- package/dist/server/lib/hostExecutionEnvironment.js.map +1 -1
- package/dist/server/lib/mobileAccess.js +115 -1
- package/dist/server/lib/mobileAccess.js.map +1 -1
- package/dist/server/lib/productionCheckApprovals.js +106 -0
- package/dist/server/lib/productionCheckApprovals.js.map +1 -0
- package/dist/server/lib/projects.js +1 -0
- package/dist/server/lib/projects.js.map +1 -1
- package/dist/server/lib/run.js +58 -2
- package/dist/server/lib/run.js.map +1 -1
- package/dist/server/lib/ticketFollowUpOperations.js +32 -6
- package/dist/server/lib/ticketFollowUpOperations.js.map +1 -1
- package/dist/server/lib/transcriptRuns.js +3 -0
- package/dist/server/lib/transcriptRuns.js.map +1 -1
- package/dist/server/lib/types.js +40 -0
- package/dist/server/lib/types.js.map +1 -1
- package/dist/server/lib/workspaceProcessEnvironment.js +72 -1
- package/dist/server/lib/workspaceProcessEnvironment.js.map +1 -1
- package/dist/server/workers/build.js +214 -46
- package/dist/server/workers/build.js.map +1 -1
- package/dist/server/workers/followUp.js +74 -1
- package/dist/server/workers/followUp.js.map +1 -1
- package/dist/server/workers/review.js +30 -13
- package/dist/server/workers/review.js.map +1 -1
- package/package.json +1 -1
- package/dist/client/assets/GitHubActionsDialog-CM1z-amZ.js +0 -1
- package/dist/client/assets/VerificationDialog-oHjNllh6.js +0 -4
- package/dist/client/assets/channel-CF8hkOdu.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-D6FiG9_B.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Bim05ijr.js +0 -1
- package/dist/client/assets/index-CsZfTdMO.css +0 -2
- package/dist/client/assets/index-DDefs3iM.js +0 -275
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-BLzZdVo0.js +0 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import db from '../db.js';
|
|
2
2
|
import { terminalizeAgentRunsForExecutionRun, terminalizeLegacyAgentRuns } from './agentRuns.js';
|
|
3
3
|
import { recoverInterruptedBuildOpenQuestionBatch } from './buildOpenQuestions.js';
|
|
4
|
-
import { activateQueuedBuildSequenceTicket, getBuildSequenceIdForTicket, reconcileActiveBuildSequences, stopBuildSequence } from './buildSequences.js';
|
|
4
|
+
import { activateQueuedBuildSequenceTicket, getBuildSequenceIdForTicket, getBuildSequenceTicketExecutionProfileSelection, reconcileActiveBuildSequences, stopBuildSequence, } from './buildSequences.js';
|
|
5
|
+
import { parseExecutionProfileSelectionMetadata } from './executionRunAuthority.js';
|
|
5
6
|
import { aggregateCheckBatch, completeCheckAttempt, getExecutionRun, reconcileInterruptedTestRuns, transitionExecutionRun, withExecutionRunTransaction, } from './executionRuns.js';
|
|
6
7
|
import { getCheckBatchDetails } from './checkRuns.js';
|
|
7
8
|
import { reconcileGitHubActionsRuns } from './integrations/githubActionsSessions.js';
|
|
@@ -18,6 +19,72 @@ const TERMINAL_EXECUTION_STATUSES = "('completed', 'failed', 'cancelled', 'inter
|
|
|
18
19
|
const ACTIVE_EXECUTION_STATUS_SET = new Set(['queued', 'running', 'waiting']);
|
|
19
20
|
const TERMINAL_EXECUTION_STATUS_SET = new Set(['completed', 'failed', 'cancelled', 'interrupted']);
|
|
20
21
|
const RESTART_FAILURE_MESSAGE = 'Interrupted by server restart';
|
|
22
|
+
const parseRunSelection = (metadataJson) => {
|
|
23
|
+
try {
|
|
24
|
+
return parseExecutionProfileSelectionMetadata(metadataJson ? JSON.parse(metadataJson) : null);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const isQualifiedQueuedBuildHandoff = (projectId, sequenceId, ticketId, runId) => {
|
|
31
|
+
let itemSelection;
|
|
32
|
+
try {
|
|
33
|
+
itemSelection = getBuildSequenceTicketExecutionProfileSelection(sequenceId, ticketId);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const source = db.prepare(`
|
|
39
|
+
SELECT source.id, previous_item.ticket_id
|
|
40
|
+
FROM build_sequences sequence
|
|
41
|
+
JOIN build_sequence_tickets current_item ON current_item.build_sequence_id = sequence.id
|
|
42
|
+
AND current_item.ticket_id = ? AND current_item.status IN ('active', 'queued')
|
|
43
|
+
JOIN build_sequence_tickets previous_item ON previous_item.build_sequence_id = sequence.id
|
|
44
|
+
AND previous_item.position = current_item.position - 1 AND previous_item.status = 'done'
|
|
45
|
+
JOIN execution_runs source ON source.project_id = sequence.project_id
|
|
46
|
+
AND source.kind IN ('build', 'build_follow_up') AND source.status = 'completed'
|
|
47
|
+
AND json_extract(source.metadata_json, '$.post_build_finalization.status') IN ('pending', 'finalized', 'completed')
|
|
48
|
+
JOIN execution_run_links source_ticket ON source_ticket.execution_run_id = source.id
|
|
49
|
+
AND source_ticket.project_id = source.project_id AND source_ticket.entity_type = 'ticket'
|
|
50
|
+
AND source_ticket.entity_id = previous_item.ticket_id AND source_ticket.relationship = 'primary'
|
|
51
|
+
JOIN execution_run_links source_sequence ON source_sequence.execution_run_id = source.id
|
|
52
|
+
AND source_sequence.project_id = source.project_id AND source_sequence.entity_type = 'build_sequence'
|
|
53
|
+
AND source_sequence.entity_id = sequence.id AND source_sequence.relationship = 'context'
|
|
54
|
+
WHERE sequence.id = ? AND sequence.project_id = ? AND sequence.status = 'active'
|
|
55
|
+
ORDER BY source.created_at DESC, source.id DESC
|
|
56
|
+
LIMIT 1
|
|
57
|
+
`).get(ticketId, sequenceId, projectId);
|
|
58
|
+
if (!source || !isLatestTicketBuildSource(projectId, source.id, source.ticket_id)) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
const activeRuns = db.prepare(`
|
|
62
|
+
SELECT run.id, run.status, run.parent_run_id, run.metadata_json, item.activation_execution_run_id
|
|
63
|
+
FROM execution_runs run
|
|
64
|
+
JOIN execution_run_links ticket_link ON ticket_link.execution_run_id = run.id
|
|
65
|
+
AND ticket_link.project_id = run.project_id AND ticket_link.entity_type = 'ticket'
|
|
66
|
+
AND ticket_link.entity_id = ? AND ticket_link.relationship = 'primary'
|
|
67
|
+
LEFT JOIN build_sequence_tickets item ON item.build_sequence_id = ? AND item.ticket_id = ?
|
|
68
|
+
WHERE run.project_id = ? AND run.kind = 'build' AND run.status IN ${ACTIVE_EXECUTION_STATUSES}
|
|
69
|
+
ORDER BY run.created_at ASC, run.id ASC
|
|
70
|
+
`).all(ticketId, sequenceId, ticketId, projectId);
|
|
71
|
+
if (!runId) {
|
|
72
|
+
return activeRuns.length === 0;
|
|
73
|
+
}
|
|
74
|
+
if (activeRuns.length !== 1) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
const [run] = activeRuns;
|
|
78
|
+
const runSelection = parseRunSelection(run.metadata_json);
|
|
79
|
+
return Boolean(run.id === runId
|
|
80
|
+
&& run.status === 'queued'
|
|
81
|
+
&& run.parent_run_id === source.id
|
|
82
|
+
&& run.activation_execution_run_id === run.id
|
|
83
|
+
&& runSelection
|
|
84
|
+
&& runSelection.revisionId === itemSelection.revisionId
|
|
85
|
+
&& runSelection.fingerprint === itemSelection.fingerprint
|
|
86
|
+
&& runSelection.reason === itemSelection.reason);
|
|
87
|
+
};
|
|
21
88
|
const terminalizeInterruptedReviewRuns = (executionRunId, ticketId) => {
|
|
22
89
|
const linked = db.prepare(`
|
|
23
90
|
UPDATE review_runs
|
|
@@ -390,6 +457,8 @@ const reconcileBuildOpenQuestionBatches = () => {
|
|
|
390
457
|
let questionsReopened = 0;
|
|
391
458
|
let automationPaused = 0;
|
|
392
459
|
let inconsistentBatchesRecovered = 0;
|
|
460
|
+
let orphanedProgressionChildrenInterrupted = 0;
|
|
461
|
+
const interruptedRunIds = new Set();
|
|
393
462
|
const createLegacyRecoveryProgression = (batch) => {
|
|
394
463
|
const state = getBundleAutomationState(batch.project_id, batch.worktree_bundle_id);
|
|
395
464
|
if (!state?.automation_progression_run_id
|
|
@@ -426,6 +495,7 @@ const reconcileBuildOpenQuestionBatches = () => {
|
|
|
426
495
|
let terminalized = 0;
|
|
427
496
|
let errored = 0;
|
|
428
497
|
for (const referencedRun of referencedRuns) {
|
|
498
|
+
interruptedRunIds.add(referencedRun.id);
|
|
429
499
|
const interrupted = interruptBuildOpenQuestionRun(transaction, referencedRun);
|
|
430
500
|
terminalized += interrupted.terminalized;
|
|
431
501
|
errored += interrupted.errored;
|
|
@@ -451,6 +521,7 @@ const reconcileBuildOpenQuestionBatches = () => {
|
|
|
451
521
|
childRunId: ownedRun.id,
|
|
452
522
|
});
|
|
453
523
|
const recovered = withExecutionRunTransaction(transaction => {
|
|
524
|
+
interruptedRunIds.add(ownedRun.id);
|
|
454
525
|
const interrupted = interruptBuildOpenQuestionRun(transaction, ownedRun);
|
|
455
526
|
const batchRecovery = recoverInterruptedBuildOpenQuestionBatch(batch.id);
|
|
456
527
|
waitAutomationProgression({
|
|
@@ -477,6 +548,34 @@ const reconcileBuildOpenQuestionBatches = () => {
|
|
|
477
548
|
questionsReopened += recovered.questions_reopened;
|
|
478
549
|
automationPaused += recovered.automation_paused;
|
|
479
550
|
}
|
|
551
|
+
// Follow-up runs owned by an automation progression but referencing no pending or
|
|
552
|
+
// running batch survive restarts as active zombies. The direct-workflow sweep skips
|
|
553
|
+
// them (progression parents are excluded), so interrupt them here to keep waiting
|
|
554
|
+
// open-question progressions adoptable.
|
|
555
|
+
const orphanedProgressionChildren = db.prepare(`
|
|
556
|
+
SELECT id, project_id, source_kind, source_id, metadata_json, initiated_by
|
|
557
|
+
FROM execution_runs orphan_run
|
|
558
|
+
WHERE orphan_run.kind = 'build_follow_up'
|
|
559
|
+
AND orphan_run.status IN ${ACTIVE_EXECUTION_STATUSES}
|
|
560
|
+
AND EXISTS (
|
|
561
|
+
SELECT 1 FROM execution_runs parent
|
|
562
|
+
WHERE parent.id = orphan_run.parent_run_id
|
|
563
|
+
AND parent.project_id = orphan_run.project_id
|
|
564
|
+
AND parent.kind = 'automation_progression'
|
|
565
|
+
)
|
|
566
|
+
ORDER BY orphan_run.created_at ASC, orphan_run.id ASC
|
|
567
|
+
`).all();
|
|
568
|
+
for (const run of orphanedProgressionChildren) {
|
|
569
|
+
if (interruptedRunIds.has(run.id)) {
|
|
570
|
+
continue;
|
|
571
|
+
}
|
|
572
|
+
withExecutionRunTransaction(transaction => {
|
|
573
|
+
const interrupted = interruptBuildOpenQuestionRun(transaction, run);
|
|
574
|
+
childRowsTerminalized += interrupted.terminalized;
|
|
575
|
+
ticketsErrored += interrupted.errored;
|
|
576
|
+
});
|
|
577
|
+
orphanedProgressionChildrenInterrupted += 1;
|
|
578
|
+
}
|
|
480
579
|
return {
|
|
481
580
|
adopted_interrupted: adoptedInterrupted,
|
|
482
581
|
legacy_recovered: legacyRecovered,
|
|
@@ -485,18 +584,13 @@ const reconcileBuildOpenQuestionBatches = () => {
|
|
|
485
584
|
questions_reopened: questionsReopened,
|
|
486
585
|
automation_paused: automationPaused,
|
|
487
586
|
inconsistent_batches_recovered: inconsistentBatchesRecovered,
|
|
587
|
+
orphaned_progression_children_interrupted: orphanedProgressionChildrenInterrupted,
|
|
488
588
|
};
|
|
489
589
|
};
|
|
490
590
|
const interruptSequenceBuild = (input) => {
|
|
491
591
|
const rows = db.prepare(`
|
|
492
592
|
SELECT execution_runs.id, execution_runs.project_id, execution_runs.status
|
|
493
593
|
FROM execution_runs
|
|
494
|
-
INNER JOIN execution_run_links sequence_link
|
|
495
|
-
ON sequence_link.execution_run_id = execution_runs.id
|
|
496
|
-
AND sequence_link.project_id = execution_runs.project_id
|
|
497
|
-
AND sequence_link.entity_type = 'build_sequence'
|
|
498
|
-
AND sequence_link.entity_id = ?
|
|
499
|
-
AND sequence_link.relationship = 'context'
|
|
500
594
|
INNER JOIN execution_run_links ticket_link
|
|
501
595
|
ON ticket_link.execution_run_id = execution_runs.id
|
|
502
596
|
AND ticket_link.project_id = execution_runs.project_id
|
|
@@ -506,31 +600,11 @@ const interruptSequenceBuild = (input) => {
|
|
|
506
600
|
WHERE execution_runs.project_id = ?
|
|
507
601
|
AND execution_runs.kind = 'build'
|
|
508
602
|
AND execution_runs.status IN ${ACTIVE_EXECUTION_STATUSES}
|
|
509
|
-
`).all(input.
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
AND previous_item.position = current_item.position - 1
|
|
515
|
-
AND previous_item.status = 'done'
|
|
516
|
-
JOIN execution_runs source ON source.project_id = ?
|
|
517
|
-
JOIN execution_run_links source_ticket ON source_ticket.execution_run_id = source.id
|
|
518
|
-
AND source_ticket.project_id = source.project_id
|
|
519
|
-
AND source_ticket.entity_type = 'ticket'
|
|
520
|
-
AND source_ticket.entity_id = previous_item.ticket_id
|
|
521
|
-
AND source_ticket.relationship = 'primary'
|
|
522
|
-
WHERE current_item.build_sequence_id = ?
|
|
523
|
-
AND current_item.ticket_id = ?
|
|
524
|
-
AND current_item.status IN ('active', 'queued')
|
|
525
|
-
AND source.kind IN ('build', 'build_follow_up')
|
|
526
|
-
AND source.status = 'completed'
|
|
527
|
-
AND json_extract(source.metadata_json, '$.post_build_finalization.status') IN ('pending', 'blocked', 'finalized', 'completed')
|
|
528
|
-
LIMIT 1
|
|
529
|
-
`).get(input.projectId, input.sequenceId, input.ticketId));
|
|
530
|
-
if (queuedHandoff && rows.every(row => row.status === 'queued')) {
|
|
531
|
-
return false;
|
|
532
|
-
}
|
|
533
|
-
if (rows.length > 1) {
|
|
603
|
+
`).all(input.ticketId, input.projectId);
|
|
604
|
+
const preservesHandoff = input.itemStatus !== null && (rows.length === 0
|
|
605
|
+
? isQualifiedQueuedBuildHandoff(input.projectId, input.sequenceId, input.ticketId)
|
|
606
|
+
: rows.length === 1 && isQualifiedQueuedBuildHandoff(input.projectId, input.sequenceId, input.ticketId, rows[0].id));
|
|
607
|
+
if (preservesHandoff) {
|
|
534
608
|
return false;
|
|
535
609
|
}
|
|
536
610
|
if (rows.length === 0) {
|
|
@@ -540,23 +614,24 @@ const interruptSequenceBuild = (input) => {
|
|
|
540
614
|
`).run(input.ticketId, input.projectId);
|
|
541
615
|
return true;
|
|
542
616
|
}
|
|
543
|
-
const
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
617
|
+
for (const run of rows) {
|
|
618
|
+
withExecutionRunTransaction(transaction => {
|
|
619
|
+
transaction.transitionExecutionRun({
|
|
620
|
+
projectId: run.project_id,
|
|
621
|
+
runId: run.id,
|
|
622
|
+
status: 'interrupted',
|
|
623
|
+
domainStatus: 'interrupted',
|
|
624
|
+
failure: { code: 'server_restarted', message: 'The server restarted while this sequenced Build run was active.' },
|
|
625
|
+
eventType: 'build_interrupted',
|
|
626
|
+
eventMessage: 'The server restarted while this sequenced Build run was active.',
|
|
627
|
+
});
|
|
628
|
+
terminalizeAgentRunsForExecutionRun(run.id, 'error', RESTART_FAILURE_MESSAGE);
|
|
629
|
+
db.prepare(`
|
|
630
|
+
UPDATE tickets SET agent_status = 'error'
|
|
631
|
+
WHERE id = ? AND project_id = ? AND (agent_status = 'running' OR agent_status IS NULL)
|
|
632
|
+
`).run(input.ticketId, input.projectId);
|
|
553
633
|
});
|
|
554
|
-
|
|
555
|
-
db.prepare(`
|
|
556
|
-
UPDATE tickets SET agent_status = 'error'
|
|
557
|
-
WHERE id = ? AND project_id = ? AND (agent_status = 'running' OR agent_status IS NULL)
|
|
558
|
-
`).run(input.ticketId, input.projectId);
|
|
559
|
-
});
|
|
634
|
+
}
|
|
560
635
|
return true;
|
|
561
636
|
};
|
|
562
637
|
const reconcileSpecReviews = () => {
|
|
@@ -606,27 +681,10 @@ const reconcileSpecReviews = () => {
|
|
|
606
681
|
};
|
|
607
682
|
};
|
|
608
683
|
const reconcileDirectWorkflow = (policy) => {
|
|
609
|
-
const queuedBuildHandoffCondition = policy.kind === 'build'
|
|
610
|
-
? `
|
|
611
|
-
AND NOT (
|
|
612
|
-
execution_runs.status = 'queued'
|
|
613
|
-
AND EXISTS (
|
|
614
|
-
SELECT 1
|
|
615
|
-
FROM execution_runs parent
|
|
616
|
-
WHERE parent.id = execution_runs.parent_run_id
|
|
617
|
-
AND parent.project_id = execution_runs.project_id
|
|
618
|
-
AND parent.kind IN ('build', 'build_follow_up')
|
|
619
|
-
AND parent.status = 'completed'
|
|
620
|
-
AND json_extract(parent.metadata_json, '$.post_build_finalization.status') IN ('pending', 'blocked', 'finalized', 'completed')
|
|
621
|
-
)
|
|
622
|
-
)
|
|
623
|
-
`
|
|
624
|
-
: '';
|
|
625
684
|
const rows = db.prepare(`
|
|
626
685
|
SELECT id, project_id, source_kind, source_id
|
|
627
686
|
FROM execution_runs
|
|
628
687
|
WHERE kind = ? AND status IN ${ACTIVE_EXECUTION_STATUSES}
|
|
629
|
-
${queuedBuildHandoffCondition}
|
|
630
688
|
AND NOT EXISTS (
|
|
631
689
|
SELECT 1 FROM execution_runs parent
|
|
632
690
|
WHERE parent.id = execution_runs.parent_run_id
|
|
@@ -637,7 +695,20 @@ const reconcileDirectWorkflow = (policy) => {
|
|
|
637
695
|
`).all(policy.kind);
|
|
638
696
|
let childRowsTerminalized = 0;
|
|
639
697
|
let domainParentsErrored = 0;
|
|
698
|
+
let interrupted = 0;
|
|
640
699
|
const interruptRun = (row) => {
|
|
700
|
+
if (policy.kind === 'build' && row.source_id) {
|
|
701
|
+
const item = db.prepare(`
|
|
702
|
+
SELECT build_sequence_id
|
|
703
|
+
FROM build_sequence_tickets
|
|
704
|
+
WHERE ticket_id = ? AND activation_execution_run_id = ?
|
|
705
|
+
`).get(row.source_id, row.id);
|
|
706
|
+
// A durable post-Build handoff is the sole Build restart-preserved scheduling class.
|
|
707
|
+
if (item && isQualifiedQueuedBuildHandoff(row.project_id, item.build_sequence_id, row.source_id, row.id)) {
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
interrupted += 1;
|
|
641
712
|
withExecutionRunTransaction(transaction => {
|
|
642
713
|
transaction.transitionExecutionRun({
|
|
643
714
|
projectId: row.project_id,
|
|
@@ -713,16 +784,22 @@ const reconcileDirectWorkflow = (policy) => {
|
|
|
713
784
|
`).run(policy.domainParent.sourceKind).changes;
|
|
714
785
|
}
|
|
715
786
|
return {
|
|
716
|
-
interrupted
|
|
787
|
+
interrupted,
|
|
717
788
|
child_rows_terminalized: childRowsTerminalized,
|
|
718
789
|
domain_parents_errored: domainParentsErrored,
|
|
719
790
|
};
|
|
720
791
|
};
|
|
721
792
|
const reconcileCheckBatches = async () => {
|
|
793
|
+
const hasApprovalRequests = Boolean(db.prepare(`
|
|
794
|
+
SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'approval_requests'
|
|
795
|
+
`).get());
|
|
722
796
|
const attempts = db.prepare(`
|
|
723
|
-
SELECT run.id, run.project_id, run.parent_run_id, details.execution_run_id AS details_run_id
|
|
797
|
+
SELECT run.id, run.project_id, run.parent_run_id, details.execution_run_id AS details_run_id,
|
|
798
|
+
details.command_snapshot_json, ${hasApprovalRequests ? 'approval.status' : 'NULL'} AS approval_status
|
|
724
799
|
FROM execution_runs run
|
|
725
800
|
LEFT JOIN check_attempt_details details ON details.execution_run_id = run.id
|
|
801
|
+
${hasApprovalRequests ? `LEFT JOIN approval_requests approval
|
|
802
|
+
ON approval.execution_run_id = run.id AND approval.project_id = run.project_id` : ''}
|
|
726
803
|
WHERE run.kind = 'check_attempt' AND run.status IN ${ACTIVE_EXECUTION_STATUSES}
|
|
727
804
|
ORDER BY run.created_at ASC, run.id ASC
|
|
728
805
|
`).all();
|
|
@@ -733,20 +810,30 @@ const reconcileCheckBatches = async () => {
|
|
|
733
810
|
let postBuildChatsFinalized = 0;
|
|
734
811
|
let postBuildContinuationsResumed = 0;
|
|
735
812
|
for (const attempt of attempts) {
|
|
813
|
+
if (attempt.approval_status === 'pending' || attempt.approval_status === 'approved') {
|
|
814
|
+
continue;
|
|
815
|
+
}
|
|
736
816
|
if (attempt.parent_run_id) {
|
|
737
817
|
affectedBatchIds.add(attempt.parent_run_id);
|
|
738
818
|
}
|
|
739
819
|
if (attempt.details_run_id) {
|
|
820
|
+
const productionConsumed = attempt.approval_status === 'consumed'
|
|
821
|
+
&& attempt.command_snapshot_json !== null
|
|
822
|
+
&& JSON.parse(attempt.command_snapshot_json).consequence === 'production';
|
|
740
823
|
completeCheckAttempt({
|
|
741
824
|
projectId: attempt.project_id,
|
|
742
825
|
runId: attempt.id,
|
|
743
|
-
outcome: 'restart_loss',
|
|
826
|
+
outcome: productionConsumed ? 'ambiguous_process_loss' : 'restart_loss',
|
|
744
827
|
finalWorkspaceIdentity: {
|
|
745
828
|
state: 'unavailable',
|
|
746
829
|
reason: 'worktree_unavailable',
|
|
747
|
-
message:
|
|
830
|
+
message: productionConsumed
|
|
831
|
+
? 'The production command process identity was lost; its external outcome is ambiguous'
|
|
832
|
+
: 'The server restarted before this check attempt completed',
|
|
748
833
|
},
|
|
749
|
-
exitError:
|
|
834
|
+
exitError: productionConsumed
|
|
835
|
+
? 'The production command process identity was lost; automatic replay is prohibited'
|
|
836
|
+
: 'The server restarted before this check attempt completed',
|
|
750
837
|
});
|
|
751
838
|
interruptedAttempts += 1;
|
|
752
839
|
continue;
|
|
@@ -1039,135 +1126,196 @@ export const reconcileEnvironmentValidationRuns = async (adapter) => {
|
|
|
1039
1126
|
}
|
|
1040
1127
|
return { interrupted };
|
|
1041
1128
|
};
|
|
1042
|
-
export const createExecutionReconciliationPolicies = (input) =>
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1129
|
+
export const createExecutionReconciliationPolicies = (input) => {
|
|
1130
|
+
const approvedRequests = [];
|
|
1131
|
+
return [
|
|
1132
|
+
{
|
|
1133
|
+
key: 'approval',
|
|
1134
|
+
workLocality: 'durable_orchestration',
|
|
1135
|
+
startupStrategy: 'reconcile',
|
|
1136
|
+
terminalStatus: null,
|
|
1137
|
+
failureCode: null,
|
|
1138
|
+
updatesDomainRecords: true,
|
|
1139
|
+
pausesAutomation: true,
|
|
1140
|
+
reconcile: async () => db.prepare(`
|
|
1141
|
+
SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'approval_requests'
|
|
1142
|
+
`).get()
|
|
1143
|
+
? (await import('./approvalReconciliation.js')).reconcileApprovalRequests({
|
|
1144
|
+
resumeApproved: request => {
|
|
1145
|
+
approvedRequests.push(request);
|
|
1146
|
+
},
|
|
1147
|
+
reconcileConsumed: request => {
|
|
1148
|
+
if (request.action_kind === 'git_push') {
|
|
1149
|
+
return import('./gitPushApprovals.js').then(async (pushes) => {
|
|
1150
|
+
await pushes.reconcileConsumedGitPush(request);
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
},
|
|
1154
|
+
resolveTerminal: async (request) => {
|
|
1155
|
+
if (request.action_kind === 'git_push') {
|
|
1156
|
+
await (await import('./gitPushApprovals.js')).finalizeGitPushApproval(request.project_id, request.id);
|
|
1157
|
+
}
|
|
1158
|
+
else {
|
|
1159
|
+
await (await import('./checkRunner.js')).finalizeProductionCheckApproval(request.project_id, request.id);
|
|
1160
|
+
}
|
|
1161
|
+
},
|
|
1162
|
+
})
|
|
1163
|
+
: { expired: 0, invalidated: 0, pending: 0, approved_unclaimed: 0, consumed_delegated: 0 },
|
|
1164
|
+
},
|
|
1165
|
+
{
|
|
1166
|
+
key: 'environment_validation',
|
|
1167
|
+
workLocality: 'local_process',
|
|
1168
|
+
startupStrategy: 'interrupt',
|
|
1169
|
+
terminalStatus: 'interrupted',
|
|
1170
|
+
failureCode: 'server_restarted',
|
|
1171
|
+
updatesDomainRecords: false,
|
|
1172
|
+
pausesAutomation: false,
|
|
1173
|
+
reconcile: reconcileEnvironmentValidationRuns,
|
|
1174
|
+
},
|
|
1175
|
+
{
|
|
1176
|
+
key: 'test',
|
|
1177
|
+
workLocality: 'local_process',
|
|
1178
|
+
startupStrategy: 'interrupt',
|
|
1179
|
+
terminalStatus: 'interrupted',
|
|
1180
|
+
failureCode: 'server_restarted',
|
|
1181
|
+
updatesDomainRecords: false,
|
|
1182
|
+
pausesAutomation: true,
|
|
1183
|
+
reconcile: () => ({ interrupted: reconcileInterruptedTestRuns() }),
|
|
1184
|
+
},
|
|
1185
|
+
{
|
|
1186
|
+
key: 'check_batch',
|
|
1187
|
+
workLocality: 'local_process',
|
|
1188
|
+
startupStrategy: 'interrupt',
|
|
1189
|
+
terminalStatus: 'interrupted',
|
|
1190
|
+
failureCode: 'restart_loss',
|
|
1191
|
+
updatesDomainRecords: true,
|
|
1192
|
+
pausesAutomation: false,
|
|
1193
|
+
reconcile: async () => {
|
|
1194
|
+
const result = await reconcileCheckBatches();
|
|
1195
|
+
for (const request of approvedRequests.splice(0)) {
|
|
1196
|
+
if (request.action_kind === 'git_push') {
|
|
1197
|
+
await (await import('./gitPushApprovals.js')).resumeGitPushApproval(request.project_id, request.id);
|
|
1198
|
+
}
|
|
1199
|
+
else {
|
|
1200
|
+
await (await import('./checkRunner.js')).resumeProductionCheckApproval(request.project_id, request.id);
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
return result;
|
|
1204
|
+
},
|
|
1205
|
+
},
|
|
1206
|
+
{
|
|
1207
|
+
key: 'check_auto_fix',
|
|
1208
|
+
workLocality: 'durable_orchestration',
|
|
1209
|
+
startupStrategy: 'reconcile',
|
|
1210
|
+
terminalStatus: null,
|
|
1211
|
+
failureCode: null,
|
|
1212
|
+
updatesDomainRecords: true,
|
|
1213
|
+
pausesAutomation: true,
|
|
1214
|
+
reconcile: async () => db.prepare(`
|
|
1082
1215
|
SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'check_auto_fix_loops'
|
|
1083
1216
|
`).get()
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1217
|
+
? (await import('./checkAutoFix.js')).reconcileCheckAutoFixLoops()
|
|
1218
|
+
: { interrupted: 0 },
|
|
1219
|
+
},
|
|
1220
|
+
{
|
|
1221
|
+
key: 'check_repair',
|
|
1222
|
+
workLocality: 'durable_orchestration',
|
|
1223
|
+
startupStrategy: 'reconcile',
|
|
1224
|
+
terminalStatus: null,
|
|
1225
|
+
failureCode: null,
|
|
1226
|
+
updatesDomainRecords: true,
|
|
1227
|
+
pausesAutomation: true,
|
|
1228
|
+
reconcile: async () => (await import('./checkRepairReconciliation.js')).reconcileCheckRepairs(),
|
|
1229
|
+
},
|
|
1230
|
+
{
|
|
1231
|
+
key: 'repository_graph_scan',
|
|
1232
|
+
workLocality: 'local_process',
|
|
1233
|
+
startupStrategy: 'interrupt',
|
|
1234
|
+
terminalStatus: 'interrupted',
|
|
1235
|
+
failureCode: 'server_restarted',
|
|
1236
|
+
updatesDomainRecords: true,
|
|
1237
|
+
pausesAutomation: false,
|
|
1238
|
+
reconcile: reconcileRepositoryGraphScans,
|
|
1239
|
+
},
|
|
1240
|
+
{
|
|
1241
|
+
key: 'automation',
|
|
1242
|
+
workLocality: 'durable_orchestration',
|
|
1243
|
+
startupStrategy: 'reconcile',
|
|
1244
|
+
terminalStatus: null,
|
|
1245
|
+
failureCode: null,
|
|
1246
|
+
updatesDomainRecords: true,
|
|
1247
|
+
pausesAutomation: true,
|
|
1248
|
+
reconcile: reconcileAutomationExecutions,
|
|
1249
|
+
},
|
|
1250
|
+
{
|
|
1251
|
+
key: 'build_sequence',
|
|
1252
|
+
workLocality: 'durable_orchestration',
|
|
1253
|
+
startupStrategy: 'reconcile',
|
|
1254
|
+
terminalStatus: 'interrupted',
|
|
1255
|
+
failureCode: 'server_restarted',
|
|
1256
|
+
updatesDomainRecords: true,
|
|
1257
|
+
pausesAutomation: false,
|
|
1258
|
+
reconcile: () => reconcileActiveBuildSequences({ interruptActiveChild: interruptSequenceBuild }),
|
|
1259
|
+
},
|
|
1260
|
+
{
|
|
1261
|
+
key: 'build_open_question_batch',
|
|
1262
|
+
workLocality: 'durable_orchestration',
|
|
1263
|
+
startupStrategy: 'reconcile',
|
|
1264
|
+
terminalStatus: 'interrupted',
|
|
1265
|
+
failureCode: 'server_restarted',
|
|
1266
|
+
updatesDomainRecords: true,
|
|
1267
|
+
pausesAutomation: true,
|
|
1268
|
+
reconcile: reconcileBuildOpenQuestionBatches,
|
|
1269
|
+
},
|
|
1270
|
+
...directWorkflowPolicies.map(policy => ({
|
|
1271
|
+
key: policy.kind,
|
|
1272
|
+
workLocality: 'local_process',
|
|
1273
|
+
startupStrategy: 'interrupt',
|
|
1274
|
+
terminalStatus: 'interrupted',
|
|
1275
|
+
failureCode: 'server_restarted',
|
|
1276
|
+
updatesDomainRecords: Boolean(policy.domainParent),
|
|
1277
|
+
pausesAutomation: false,
|
|
1278
|
+
reconcile: () => reconcileDirectWorkflow(policy),
|
|
1279
|
+
})),
|
|
1280
|
+
{
|
|
1281
|
+
key: 'build_setup',
|
|
1282
|
+
workLocality: 'durable_orchestration',
|
|
1283
|
+
startupStrategy: 'reconcile',
|
|
1284
|
+
terminalStatus: 'failed',
|
|
1285
|
+
failureCode: 'server_restarted',
|
|
1286
|
+
updatesDomainRecords: true,
|
|
1287
|
+
pausesAutomation: false,
|
|
1288
|
+
reconcile: async () => db.prepare(`
|
|
1289
|
+
SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'build_setup_evidence'
|
|
1290
|
+
`).get()
|
|
1291
|
+
? (await import('./buildSetupAuthority.js')).reconcileBuildSetupEvidence()
|
|
1292
|
+
: { failed: 0 },
|
|
1293
|
+
},
|
|
1294
|
+
{
|
|
1295
|
+
key: 'spec_review',
|
|
1296
|
+
workLocality: 'local_process',
|
|
1297
|
+
startupStrategy: 'interrupt',
|
|
1298
|
+
terminalStatus: 'interrupted',
|
|
1299
|
+
failureCode: 'server_restarted',
|
|
1300
|
+
updatesDomainRecords: true,
|
|
1301
|
+
pausesAutomation: false,
|
|
1302
|
+
reconcile: reconcileSpecReviews,
|
|
1303
|
+
},
|
|
1304
|
+
{
|
|
1305
|
+
key: 'github_actions',
|
|
1306
|
+
workLocality: 'externally_observable',
|
|
1307
|
+
startupStrategy: 'reconcile',
|
|
1308
|
+
terminalStatus: null,
|
|
1309
|
+
failureCode: null,
|
|
1310
|
+
updatesDomainRecords: false,
|
|
1311
|
+
pausesAutomation: false,
|
|
1312
|
+
reconcile: () => reconcileGitHubActionsRuns({
|
|
1313
|
+
getConfig: input.getGitHubConfig,
|
|
1314
|
+
startPolling: false,
|
|
1315
|
+
}),
|
|
1316
|
+
},
|
|
1317
|
+
];
|
|
1318
|
+
};
|
|
1171
1319
|
export const reconcileStartupExecutions = async (input) => {
|
|
1172
1320
|
const policies = input.policies ?? createExecutionReconciliationPolicies(input);
|
|
1173
1321
|
const summary = {};
|