@straiffi/archon 1.7.4 → 1.7.6
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-BgMz3NNT.js → ActivityView-BrZY8vYf.js} +1 -1
- package/dist/client/assets/{GitHubActionsDialog-CNqWDS3E.js → GitHubActionsDialog-CUfdVw97.js} +1 -1
- package/dist/client/assets/{TestsDialog-Cll7xJe0.js → TestsDialog-FXcnLOyf.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-BL5dYiul.js → architectureDiagram-3BPJPVTR-D0PXGvSL.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-Bi5x2v80.js → blockDiagram-GPEHLZMM-BCLAxnp5.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-esEm54Ay.js → c4Diagram-AAUBKEIU-DVZ5yZWV.js} +1 -1
- package/dist/client/assets/channel-BCPCrThZ.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-DACfY8xM.js → chunk-2J33WTMH-BGJYj1Lu.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-DZNUiaUs.js → chunk-3OPIFGDE-DI5-yK3m.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-ClDfkMAp.js → chunk-5ZQYHXKU-Dnr5DDsb.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-CCwA3GWT.js → chunk-727SXJPM-8HdFwn-P.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-Byl4DRZ9.js → chunk-AQP2D5EJ-C7x9t2uJ.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-CXymZQ7A.js → chunk-CSCIHK7Q-CrhwRPh5.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-VV3D8g6a.js → chunk-KSCS5N6A-CdD62r5U.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-BL9N5GRI.js → chunk-L5ZTLDWV-CqQVvwc_.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-DKNN-zno.js → chunk-LZXEDZCA-DLHrqoJ4.js} +2 -2
- package/dist/client/assets/{chunk-ND2GUHAM-CHCpQ1yr.js → chunk-ND2GUHAM-B0yOdiPF.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-B0Dm74mt.js → chunk-NZK2D7GU-boM-MocY.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-DAa5z2xG.js → chunk-O5CBEL6O-B0jgJn0t.js} +1 -1
- package/dist/client/assets/{chunk-WU5MYG2G-DrVJWKVR.js → chunk-WU5MYG2G-C_S_v-m2.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-BdJlc_1i.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Bidw5Zc1.js +1 -0
- package/dist/client/assets/{dagre-BM42HDAG-B0fsl8mE.js → dagre-BM42HDAG-DKl6Y8ya.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-Cx_VEbSS.js → diagram-2AECGRRQ-6Lyn9DBp.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-Cv7VVn5r.js → diagram-5GNKFQAL-wdS1vEkN.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-C8Sl5czV.js → diagram-KO2AKTUF-CPih29jF.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-C3dZaLz2.js → diagram-LMA3HP47-Cr5Px74d.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-BAU9DtTr.js → diagram-OG6HWLK6-i0PjSScd.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-DpNc-eBD.js → erDiagram-TEJ5UH35-Dt4yOC9J.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-DGwTAT1S.js → flowDiagram-I6XJVG4X-Bf6kvajC.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-MPZhEgzJ.js → ganttDiagram-6RSMTGT7-DgxePMk_.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-CY0tHL5N.js → gitGraphDiagram-PVQCEYII-BZq2cmFS.js} +1 -1
- package/dist/client/assets/index-BJGHMaMz.css +2 -0
- package/dist/client/assets/{index-CJRgmWwY.js → index-CjRMYO1U.js} +106 -106
- package/dist/client/assets/{infoDiagram-5YYISTIA-BBZeKjf4.js → infoDiagram-5YYISTIA-Chij69KN.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-CM_iFrES.js → ishikawaDiagram-YF4QCWOH-3qHCLFgD.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-Do_lY94X.js → journeyDiagram-JHISSGLW-DvRW8tbA.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-brxg3j37.js → kanban-definition-UN3LZRKU-DjR2T5I1.js} +1 -1
- package/dist/client/assets/{line-PHHbm9rj.js → line-B9OzrQ1Y.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-CLxAkW69.js → mermaid-parser.core-DYcDor4d.js} +1 -1
- package/dist/client/assets/{mermaid.core-CebvSmx9.js → mermaid.core-DG8QYo2u.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-CX_-ZaJF.js → mindmap-definition-RKZ34NQL-f4QPF6b3.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-BJuHvql_.js → pieDiagram-4H26LBE5-CMkl2jBu.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-DiJll7l9.js → quadrantDiagram-W4KKPZXB-BXaUHzJi.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-Bg-tXgcj.js → requirementDiagram-4Y6WPE33-B-Inuj_6.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-BoK2egfZ.js → sankeyDiagram-5OEKKPKP-BjsmZFYI.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-DcrDWNzv.js → sequenceDiagram-3UESZ5HK-B1PAm6sX.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-B995qt1S.js → stateDiagram-AJRCARHV-pLONNEN8.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-kWPDF3wr.js +1 -0
- package/dist/client/assets/{timeline-definition-PNZ67QCA-DqSVAhqL.js → timeline-definition-PNZ67QCA-BLMkSXo_.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-D9wVraVY.js → vennDiagram-CIIHVFJN-CEwGRegG.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-CLff9zVd.js → wardleyDiagram-YWT4CUSO-_md2IBXC.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-BuHUMMH2.js → xychartDiagram-2RQKCTM6-DVzwfXHc.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/db.js +282 -0
- package/dist/server/db.js.map +1 -1
- package/dist/server/index.js +332 -130
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/attachments.js +16 -0
- package/dist/server/lib/attachments.js.map +1 -1
- package/dist/server/lib/automationResumeDecision.js +141 -0
- package/dist/server/lib/automationResumeDecision.js.map +1 -0
- package/dist/server/lib/buildSequences.js +52 -0
- package/dist/server/lib/buildSequences.js.map +1 -1
- package/dist/server/lib/executionArtifactCleanupState.js +12 -0
- package/dist/server/lib/executionArtifactCleanupState.js.map +1 -0
- package/dist/server/lib/executionArtifactRetention.js +405 -0
- package/dist/server/lib/executionArtifactRetention.js.map +1 -0
- package/dist/server/lib/executionArtifacts.js +705 -0
- package/dist/server/lib/executionArtifacts.js.map +1 -0
- package/dist/server/lib/executionRetry.js +9 -1
- package/dist/server/lib/executionRetry.js.map +1 -1
- package/dist/server/lib/executionRetryContext.js +21 -0
- package/dist/server/lib/executionRetryContext.js.map +1 -1
- package/dist/server/lib/executionRuns.js +62 -2
- package/dist/server/lib/executionRuns.js.map +1 -1
- package/dist/server/lib/executionTimeline.js +38 -10
- package/dist/server/lib/executionTimeline.js.map +1 -1
- package/dist/server/lib/lightweightPrompt.js +2 -2
- package/dist/server/lib/lightweightPrompt.js.map +1 -1
- package/dist/server/lib/projects.js +16 -3
- package/dist/server/lib/projects.js.map +1 -1
- package/dist/server/lib/pullRequestContent.js +148 -25
- package/dist/server/lib/pullRequestContent.js.map +1 -1
- package/dist/server/lib/queue.js +1 -0
- package/dist/server/lib/queue.js.map +1 -1
- package/dist/server/lib/runtimePaths.js +7 -0
- package/dist/server/lib/runtimePaths.js.map +1 -1
- package/dist/server/lib/ticketAutomationCommit.js +11 -4
- package/dist/server/lib/ticketAutomationCommit.js.map +1 -1
- package/dist/server/lib/ticketFollowUpOperations.js +19 -15
- package/dist/server/lib/ticketFollowUpOperations.js.map +1 -1
- package/dist/server/lib/ticketUndo.js +83 -31
- package/dist/server/lib/ticketUndo.js.map +1 -1
- package/dist/server/lib/tickets.js +67 -6
- package/dist/server/lib/tickets.js.map +1 -1
- package/dist/server/lib/types.js +11 -0
- package/dist/server/lib/types.js.map +1 -1
- package/dist/server/workers/followUp.js +94 -6
- package/dist/server/workers/followUp.js.map +1 -1
- package/dist/server/workers/review.js +1 -0
- package/dist/server/workers/review.js.map +1 -1
- package/package.json +1 -1
- package/dist/client/assets/channel-CqNHF3FD.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-BjEgQwKg.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-gGomH-F_.js +0 -1
- package/dist/client/assets/index-mRkJWu70.css +0 -2
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-Dn8P7Sa1.js +0 -1
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
import { isAbsolute, relative, resolve, sep, dirname } from 'path';
|
|
2
|
+
import { randomUUID } from 'crypto';
|
|
3
|
+
import { realpath, unlink } from 'fs/promises';
|
|
4
|
+
import db from '../db.js';
|
|
5
|
+
import { withExecutionRunTransaction } from './executionRuns.js';
|
|
6
|
+
import { resolveArchonArtifactsRoot } from './runtimePaths.js';
|
|
7
|
+
import { truncateUtf8 } from './transcriptRuns.js';
|
|
8
|
+
import { claimProjectArtifactCleanup } from './executionArtifactCleanupState.js';
|
|
9
|
+
export const SHORT_ARTIFACT_RETENTION_DAYS = 7;
|
|
10
|
+
export const STANDARD_ARTIFACT_RETENTION_DAYS = 30;
|
|
11
|
+
export const DEFAULT_ARTIFACT_CLEANUP_BATCH_SIZE = 100;
|
|
12
|
+
export const DEFAULT_ARTIFACT_CLEANUP_INTERVAL_MS = 6 * 60 * 60 * 1000;
|
|
13
|
+
export const MIN_ARTIFACT_CLEANUP_INTERVAL_MS = 5 * 60 * 1000;
|
|
14
|
+
export const MAX_ARTIFACT_CLEANUP_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
15
|
+
export const ARTIFACT_REGISTRATION_STALE_MS = 60 * 60 * 1000;
|
|
16
|
+
const ARTIFACT_CLEANUP_CLAIM_STALE_MS = 60 * 60 * 1000;
|
|
17
|
+
const MAX_CLEANUP_ATTEMPTS = 10;
|
|
18
|
+
const MAX_CLEANUP_ERROR_BYTES = 2_048;
|
|
19
|
+
export class ExecutionArtifactCleanupError extends Error {
|
|
20
|
+
code;
|
|
21
|
+
constructor(code, message) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = 'ExecutionArtifactCleanupError';
|
|
24
|
+
this.code = code;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const sqlTimestamp = (date) => new Date(Math.floor(date.getTime() / 1_000) * 1_000).toISOString();
|
|
28
|
+
const boundedError = (error) => {
|
|
29
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
30
|
+
return truncateUtf8(message, MAX_CLEANUP_ERROR_BYTES).text ?? 'Artifact cleanup failed';
|
|
31
|
+
};
|
|
32
|
+
export const resolveArtifactCleanupIntervalMs = (value = process.env.ARCHON_ARTIFACT_CLEANUP_INTERVAL_MS) => {
|
|
33
|
+
if (value === undefined || !/^\d+$/.test(value.trim())) {
|
|
34
|
+
return DEFAULT_ARTIFACT_CLEANUP_INTERVAL_MS;
|
|
35
|
+
}
|
|
36
|
+
const interval = Number(value.trim());
|
|
37
|
+
return Number.isSafeInteger(interval)
|
|
38
|
+
&& interval >= MIN_ARTIFACT_CLEANUP_INTERVAL_MS
|
|
39
|
+
&& interval <= MAX_ARTIFACT_CLEANUP_INTERVAL_MS
|
|
40
|
+
? interval
|
|
41
|
+
: DEFAULT_ARTIFACT_CLEANUP_INTERVAL_MS;
|
|
42
|
+
};
|
|
43
|
+
const resolveManifestPath = async (relativePath, allowMissingRoot = false) => {
|
|
44
|
+
if (isAbsolute(relativePath) || relativePath.includes('\\')) {
|
|
45
|
+
throw new Error('Artifact storage path is invalid');
|
|
46
|
+
}
|
|
47
|
+
const configuredRoot = resolveArchonArtifactsRoot();
|
|
48
|
+
const configuredPath = resolve(configuredRoot, relativePath);
|
|
49
|
+
const configuredFromRoot = relative(resolve(configuredRoot), configuredPath);
|
|
50
|
+
if (!configuredFromRoot
|
|
51
|
+
|| configuredFromRoot === '..'
|
|
52
|
+
|| configuredFromRoot.startsWith(`..${sep}`)
|
|
53
|
+
|| isAbsolute(configuredFromRoot)) {
|
|
54
|
+
throw new Error('Artifact storage path escapes the artifact root');
|
|
55
|
+
}
|
|
56
|
+
let root;
|
|
57
|
+
try {
|
|
58
|
+
root = await realpath(configuredRoot);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error.code === 'ENOENT' && allowMissingRoot) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
if (error.code === 'ENOENT') {
|
|
65
|
+
throw new Error('Artifact storage root is unavailable', { cause: error });
|
|
66
|
+
}
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
const path = resolve(root, relativePath);
|
|
70
|
+
const fromRoot = relative(root, path);
|
|
71
|
+
if (!fromRoot || fromRoot === '..' || fromRoot.startsWith(`..${sep}`) || isAbsolute(fromRoot)) {
|
|
72
|
+
throw new Error('Artifact storage path escapes the artifact root');
|
|
73
|
+
}
|
|
74
|
+
let actualParent;
|
|
75
|
+
try {
|
|
76
|
+
actualParent = await realpath(dirname(path));
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
if (error.code === 'ENOENT') {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
const parentFromRoot = relative(root, actualParent);
|
|
85
|
+
if (parentFromRoot === '..' || parentFromRoot.startsWith(`..${sep}`) || isAbsolute(parentFromRoot)) {
|
|
86
|
+
throw new Error('Artifact storage directory escapes the artifact root');
|
|
87
|
+
}
|
|
88
|
+
return path;
|
|
89
|
+
};
|
|
90
|
+
const removeManifestPath = async (relativePath, allowMissingRoot = false) => {
|
|
91
|
+
const path = await resolveManifestPath(relativePath, allowMissingRoot);
|
|
92
|
+
if (!path) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
await unlink(path);
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
if (error.code !== 'ENOENT') {
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const claimArtifactForExpiry = (artifact, now, ignoreExpiry) => {
|
|
105
|
+
const claimId = randomUUID();
|
|
106
|
+
const staleClaimAt = sqlTimestamp(new Date(Date.parse(now) - ARTIFACT_CLEANUP_CLAIM_STALE_MS));
|
|
107
|
+
const result = db.prepare(`
|
|
108
|
+
UPDATE execution_artifacts
|
|
109
|
+
SET availability = CASE WHEN availability IN ('available', 'missing') THEN 'expired' ELSE availability END,
|
|
110
|
+
expiry_prior_availability = CASE
|
|
111
|
+
WHEN availability IN ('available', 'missing') THEN availability
|
|
112
|
+
ELSE expiry_prior_availability
|
|
113
|
+
END,
|
|
114
|
+
cleanup_claim_id = ?, cleanup_claimed_at = ?, updated_at = ?
|
|
115
|
+
WHERE id = ? AND project_id = ? AND execution_run_id = ?
|
|
116
|
+
AND availability IN ('available', 'missing', 'expired', 'deletion_failed')
|
|
117
|
+
AND (? = 1 OR julianday(expires_at) <= julianday(?))
|
|
118
|
+
AND (cleanup_claim_id IS NULL OR julianday(cleanup_claimed_at) <= julianday(?))
|
|
119
|
+
`).run(claimId, now, now, artifact.id, artifact.project_id, artifact.execution_run_id, ignoreExpiry ? 1 : 0, now, staleClaimAt);
|
|
120
|
+
if (result.changes !== 1) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
return db.prepare('SELECT * FROM execution_artifacts WHERE id = ? AND cleanup_claim_id = ?').get(artifact.id, claimId);
|
|
124
|
+
};
|
|
125
|
+
const recordArtifactDeletionFailure = (artifact, error, now, emitter) => withExecutionRunTransaction(transaction => {
|
|
126
|
+
const result = db.prepare(`
|
|
127
|
+
UPDATE execution_artifacts
|
|
128
|
+
SET availability = 'deletion_failed',
|
|
129
|
+
deletion_attempts = MIN(deletion_attempts + 1, ?),
|
|
130
|
+
last_deletion_error = ?,
|
|
131
|
+
last_deletion_attempt_at = ?,
|
|
132
|
+
updated_at = ?,
|
|
133
|
+
cleanup_claim_id = NULL, cleanup_claimed_at = NULL
|
|
134
|
+
WHERE id = ? AND project_id = ? AND execution_run_id = ?
|
|
135
|
+
AND availability IN ('expired', 'deletion_failed')
|
|
136
|
+
AND cleanup_claim_id = ?
|
|
137
|
+
`).run(MAX_CLEANUP_ATTEMPTS, boundedError(error), now, now, artifact.id, artifact.project_id, artifact.execution_run_id, artifact.cleanup_claim_id);
|
|
138
|
+
if (result.changes === 1) {
|
|
139
|
+
transaction.appendLifecycleEvent({
|
|
140
|
+
projectId: artifact.project_id,
|
|
141
|
+
runId: artifact.execution_run_id,
|
|
142
|
+
eventType: 'artifact_deletion_failed',
|
|
143
|
+
domainStatus: 'deletion_failed',
|
|
144
|
+
metadata: artifact.sensitivity === 'normal' ? { artifact_id: artifact.id } : null,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}, emitter);
|
|
148
|
+
const finalizeArtifactExpiry = (artifact, now, emitter) => withExecutionRunTransaction(transaction => {
|
|
149
|
+
const result = db.prepare(`
|
|
150
|
+
UPDATE execution_artifacts
|
|
151
|
+
SET availability = 'deleted', deleted_at = ?, updated_at = ?,
|
|
152
|
+
last_deletion_error = NULL, last_deletion_attempt_at = ?,
|
|
153
|
+
cleanup_claim_id = NULL, cleanup_claimed_at = NULL
|
|
154
|
+
WHERE id = ? AND project_id = ? AND execution_run_id = ?
|
|
155
|
+
AND availability IN ('expired', 'deletion_failed')
|
|
156
|
+
AND cleanup_claim_id = ?
|
|
157
|
+
`).run(now, now, now, artifact.id, artifact.project_id, artifact.execution_run_id, artifact.cleanup_claim_id);
|
|
158
|
+
if (result.changes !== 1) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
const metadata = {
|
|
162
|
+
prior_availability: artifact.expiry_prior_availability ?? 'available',
|
|
163
|
+
};
|
|
164
|
+
if (artifact.sensitivity === 'normal') {
|
|
165
|
+
metadata.artifact_id = artifact.id;
|
|
166
|
+
}
|
|
167
|
+
transaction.appendLifecycleEvent({
|
|
168
|
+
projectId: artifact.project_id,
|
|
169
|
+
runId: artifact.execution_run_id,
|
|
170
|
+
eventType: 'artifact_expired',
|
|
171
|
+
domainStatus: 'deleted',
|
|
172
|
+
metadata,
|
|
173
|
+
});
|
|
174
|
+
return true;
|
|
175
|
+
}, emitter);
|
|
176
|
+
const processArtifact = async (candidate, now, ignoreExpiry, emitter) => {
|
|
177
|
+
const artifact = claimArtifactForExpiry(candidate, now, ignoreExpiry);
|
|
178
|
+
if (!artifact) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
try {
|
|
182
|
+
if (artifact.storage_type === 'managed_file') {
|
|
183
|
+
if (!artifact.managed_relative_path) {
|
|
184
|
+
throw new Error('Managed artifact path is missing');
|
|
185
|
+
}
|
|
186
|
+
await removeManifestPath(artifact.managed_relative_path);
|
|
187
|
+
}
|
|
188
|
+
return finalizeArtifactExpiry(artifact, now, emitter);
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
recordArtifactDeletionFailure(artifact, error, now, emitter);
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
const listArtifactCandidates = (now, projectId, ignoreExpiry = false) => {
|
|
196
|
+
const projectClause = projectId === undefined ? '' : 'AND project_id = ?';
|
|
197
|
+
const deletionClause = projectId === undefined
|
|
198
|
+
? 'AND NOT EXISTS (SELECT 1 FROM projects WHERE projects.id = execution_artifacts.project_id AND projects.deletion_started_at IS NOT NULL)'
|
|
199
|
+
: '';
|
|
200
|
+
const expiryClause = ignoreExpiry ? '' : 'AND julianday(expires_at) <= julianday(?)';
|
|
201
|
+
const terminalFailureClause = projectId === undefined
|
|
202
|
+
? 'AND NOT (availability = \'deletion_failed\' AND deletion_attempts >= ?)'
|
|
203
|
+
: '';
|
|
204
|
+
const parameters = [];
|
|
205
|
+
if (projectId !== undefined) {
|
|
206
|
+
parameters.push(projectId);
|
|
207
|
+
}
|
|
208
|
+
if (!ignoreExpiry) {
|
|
209
|
+
parameters.push(now);
|
|
210
|
+
}
|
|
211
|
+
if (projectId === undefined) {
|
|
212
|
+
parameters.push(MAX_CLEANUP_ATTEMPTS);
|
|
213
|
+
}
|
|
214
|
+
parameters.push(DEFAULT_ARTIFACT_CLEANUP_BATCH_SIZE);
|
|
215
|
+
return db.prepare(`
|
|
216
|
+
SELECT * FROM execution_artifacts
|
|
217
|
+
WHERE availability IN ('available', 'missing', 'expired', 'deletion_failed')
|
|
218
|
+
${projectClause}
|
|
219
|
+
${expiryClause}
|
|
220
|
+
${deletionClause}
|
|
221
|
+
${terminalFailureClause}
|
|
222
|
+
ORDER BY expires_at ASC, id ASC
|
|
223
|
+
LIMIT ?
|
|
224
|
+
`).all(...parameters);
|
|
225
|
+
};
|
|
226
|
+
export const reconcileFinalizedExecutionArtifacts = async ({ now = new Date(), emitter, } = {}) => {
|
|
227
|
+
if (Number.isNaN(now.getTime())) {
|
|
228
|
+
throw new Error('Artifact cleanup time must be valid');
|
|
229
|
+
}
|
|
230
|
+
const timestamp = sqlTimestamp(now);
|
|
231
|
+
const candidates = listArtifactCandidates(timestamp);
|
|
232
|
+
const result = { processed: candidates.length, deleted: 0, failed: [] };
|
|
233
|
+
for (const candidate of candidates) {
|
|
234
|
+
try {
|
|
235
|
+
if (await processArtifact(candidate, timestamp, false, emitter)) {
|
|
236
|
+
result.deleted += 1;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
result.failed.push({ id: candidate.id, error: boundedError(error) });
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return result;
|
|
244
|
+
};
|
|
245
|
+
const listIntentCandidates = (mode, now, projectId) => {
|
|
246
|
+
const staleAt = sqlTimestamp(new Date(Date.parse(now) - ARTIFACT_REGISTRATION_STALE_MS));
|
|
247
|
+
const projectClause = projectId === undefined ? '' : 'AND project_id = ?';
|
|
248
|
+
const deletionClause = projectId === undefined
|
|
249
|
+
? 'AND NOT EXISTS (SELECT 1 FROM projects WHERE projects.id = execution_artifact_registration_intents.project_id AND projects.deletion_started_at IS NOT NULL)'
|
|
250
|
+
: '';
|
|
251
|
+
const terminalFailureClause = projectId === undefined
|
|
252
|
+
? "AND NOT (state = 'cleanup_failed' AND cleanup_attempts >= ?)"
|
|
253
|
+
: '';
|
|
254
|
+
const limitClause = projectId === undefined ? 'LIMIT ?' : '';
|
|
255
|
+
const parameters = projectId === undefined ? [mode, staleAt] : [projectId, mode, staleAt];
|
|
256
|
+
if (projectId === undefined) {
|
|
257
|
+
parameters.push(MAX_CLEANUP_ATTEMPTS, DEFAULT_ARTIFACT_CLEANUP_BATCH_SIZE);
|
|
258
|
+
}
|
|
259
|
+
return db.prepare(`
|
|
260
|
+
SELECT * FROM execution_artifact_registration_intents
|
|
261
|
+
WHERE 1 = 1 ${projectClause}
|
|
262
|
+
AND (
|
|
263
|
+
? = 'startup'
|
|
264
|
+
OR state IN ('cleanup_pending', 'cleanup_failed')
|
|
265
|
+
OR julianday(updated_at) <= julianday(?)
|
|
266
|
+
)
|
|
267
|
+
${deletionClause}
|
|
268
|
+
${terminalFailureClause}
|
|
269
|
+
ORDER BY updated_at ASC, artifact_id ASC
|
|
270
|
+
${limitClause}
|
|
271
|
+
`).all(...parameters);
|
|
272
|
+
};
|
|
273
|
+
const claimIntent = (intent, now) => {
|
|
274
|
+
const claimId = randomUUID();
|
|
275
|
+
const staleClaimAt = sqlTimestamp(new Date(Date.parse(now) - ARTIFACT_CLEANUP_CLAIM_STALE_MS));
|
|
276
|
+
const result = db.prepare(`
|
|
277
|
+
UPDATE execution_artifact_registration_intents
|
|
278
|
+
SET state = 'cleanup_pending', cleanup_claim_id = ?, cleanup_claimed_at = ?, updated_at = ?
|
|
279
|
+
WHERE artifact_id = ? AND project_id = ? AND execution_run_id = ?
|
|
280
|
+
AND temporary_relative_path = ? AND final_relative_path = ?
|
|
281
|
+
AND state = ? AND updated_at = ?
|
|
282
|
+
AND (cleanup_claim_id IS NULL OR julianday(cleanup_claimed_at) <= julianday(?))
|
|
283
|
+
`).run(claimId, now, now, intent.artifact_id, intent.project_id, intent.execution_run_id, intent.temporary_relative_path, intent.final_relative_path, intent.state, intent.updated_at, staleClaimAt);
|
|
284
|
+
return result.changes === 1 ? claimId : null;
|
|
285
|
+
};
|
|
286
|
+
const recordIntentCleanupFailure = (intent, claimId, error, now) => {
|
|
287
|
+
db.prepare(`
|
|
288
|
+
UPDATE execution_artifact_registration_intents
|
|
289
|
+
SET state = CASE WHEN cleanup_attempts >= 9 THEN 'cleanup_failed' ELSE 'cleanup_pending' END,
|
|
290
|
+
cleanup_attempts = MIN(cleanup_attempts + 1, ?),
|
|
291
|
+
last_cleanup_error = ?, last_cleanup_attempt_at = ?, updated_at = ?,
|
|
292
|
+
cleanup_claim_id = NULL, cleanup_claimed_at = NULL
|
|
293
|
+
WHERE artifact_id = ? AND project_id = ? AND execution_run_id = ?
|
|
294
|
+
AND temporary_relative_path = ? AND final_relative_path = ?
|
|
295
|
+
AND state = 'cleanup_pending'
|
|
296
|
+
AND cleanup_claim_id = ?
|
|
297
|
+
`).run(MAX_CLEANUP_ATTEMPTS, boundedError(error), now, now, intent.artifact_id, intent.project_id, intent.execution_run_id, intent.temporary_relative_path, intent.final_relative_path, claimId);
|
|
298
|
+
};
|
|
299
|
+
const processIntent = async (intent, now) => {
|
|
300
|
+
const claimId = claimIntent(intent, now);
|
|
301
|
+
if (!claimId) {
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
try {
|
|
305
|
+
const results = await Promise.allSettled([
|
|
306
|
+
removeManifestPath(intent.temporary_relative_path, true),
|
|
307
|
+
removeManifestPath(intent.final_relative_path, true),
|
|
308
|
+
]);
|
|
309
|
+
const failure = results.find(result => result.status === 'rejected');
|
|
310
|
+
if (failure?.status === 'rejected') {
|
|
311
|
+
throw failure.reason;
|
|
312
|
+
}
|
|
313
|
+
const removed = db.prepare(`
|
|
314
|
+
DELETE FROM execution_artifact_registration_intents
|
|
315
|
+
WHERE artifact_id = ? AND project_id = ? AND execution_run_id = ?
|
|
316
|
+
AND temporary_relative_path = ? AND final_relative_path = ?
|
|
317
|
+
AND state = 'cleanup_pending'
|
|
318
|
+
AND cleanup_claim_id = ?
|
|
319
|
+
`).run(intent.artifact_id, intent.project_id, intent.execution_run_id, intent.temporary_relative_path, intent.final_relative_path, claimId);
|
|
320
|
+
return removed.changes === 1;
|
|
321
|
+
}
|
|
322
|
+
catch (error) {
|
|
323
|
+
recordIntentCleanupFailure(intent, claimId, error, now);
|
|
324
|
+
throw error;
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
export const reconcileExecutionArtifactRegistrationIntents = async ({ mode = 'periodic', now = new Date(), projectId, } = {}) => {
|
|
328
|
+
if (Number.isNaN(now.getTime())) {
|
|
329
|
+
throw new Error('Artifact intent cleanup time must be valid');
|
|
330
|
+
}
|
|
331
|
+
const timestamp = sqlTimestamp(now);
|
|
332
|
+
const candidates = listIntentCandidates(mode, timestamp, projectId);
|
|
333
|
+
const result = {
|
|
334
|
+
processed: candidates.length,
|
|
335
|
+
deleted: 0,
|
|
336
|
+
skippedFresh: 0,
|
|
337
|
+
failed: [],
|
|
338
|
+
};
|
|
339
|
+
for (const intent of candidates) {
|
|
340
|
+
try {
|
|
341
|
+
if (await processIntent(intent, timestamp)) {
|
|
342
|
+
result.deleted += 1;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
result.failed.push({ id: intent.artifact_id, error: boundedError(error) });
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return result;
|
|
350
|
+
};
|
|
351
|
+
export const reconcileProjectExecutionArtifacts = async (projectId, { now = new Date(), beginCleanup, finalize, emitter, } = {}) => {
|
|
352
|
+
if (Number.isNaN(now.getTime())) {
|
|
353
|
+
throw new Error('Artifact cleanup time must be valid');
|
|
354
|
+
}
|
|
355
|
+
const release = claimProjectArtifactCleanup(projectId);
|
|
356
|
+
if (!release) {
|
|
357
|
+
throw new ExecutionArtifactCleanupError('active_registration', 'Artifact cleanup is already active for this project');
|
|
358
|
+
}
|
|
359
|
+
try {
|
|
360
|
+
const timestamp = sqlTimestamp(now);
|
|
361
|
+
const staleAt = sqlTimestamp(new Date(now.getTime() - ARTIFACT_REGISTRATION_STALE_MS));
|
|
362
|
+
const freshIntent = db.prepare(`
|
|
363
|
+
SELECT artifact_id FROM execution_artifact_registration_intents
|
|
364
|
+
WHERE project_id = ?
|
|
365
|
+
AND state NOT IN ('cleanup_pending', 'cleanup_failed')
|
|
366
|
+
AND julianday(updated_at) > julianday(?)
|
|
367
|
+
ORDER BY updated_at DESC LIMIT 1
|
|
368
|
+
`).get(projectId, staleAt);
|
|
369
|
+
if (freshIntent) {
|
|
370
|
+
throw new ExecutionArtifactCleanupError('active_registration', 'Cannot delete project while an artifact registration is active');
|
|
371
|
+
}
|
|
372
|
+
beginCleanup?.();
|
|
373
|
+
const intents = await reconcileExecutionArtifactRegistrationIntents({ mode: 'periodic', now, projectId });
|
|
374
|
+
if (intents.failed.length > 0
|
|
375
|
+
|| (db.prepare('SELECT 1 FROM execution_artifact_registration_intents WHERE project_id = ? LIMIT 1').get(projectId))) {
|
|
376
|
+
throw new ExecutionArtifactCleanupError('cleanup_failed', 'Cannot delete project because artifact registration cleanup failed');
|
|
377
|
+
}
|
|
378
|
+
const candidates = db.prepare(`
|
|
379
|
+
SELECT * FROM execution_artifacts
|
|
380
|
+
WHERE project_id = ? AND availability <> 'deleted'
|
|
381
|
+
ORDER BY expires_at ASC, id ASC
|
|
382
|
+
`).all(projectId);
|
|
383
|
+
let failed = false;
|
|
384
|
+
for (const candidate of candidates) {
|
|
385
|
+
try {
|
|
386
|
+
await processArtifact(candidate, timestamp, true, emitter);
|
|
387
|
+
}
|
|
388
|
+
catch {
|
|
389
|
+
failed = true;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (failed || db.prepare(`
|
|
393
|
+
SELECT 1 FROM execution_artifacts
|
|
394
|
+
WHERE project_id = ? AND availability <> 'deleted'
|
|
395
|
+
LIMIT 1
|
|
396
|
+
`).get(projectId)) {
|
|
397
|
+
throw new ExecutionArtifactCleanupError('cleanup_failed', 'Cannot delete project because artifact file cleanup failed');
|
|
398
|
+
}
|
|
399
|
+
finalize?.();
|
|
400
|
+
}
|
|
401
|
+
finally {
|
|
402
|
+
release();
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
//# sourceMappingURL=executionArtifactRetention.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executionArtifactRetention.js","sourceRoot":"","sources":["../../../server/lib/executionArtifactRetention.ts"],"names":[],"mappings":"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"}
|