@dsh-enhanced/plugin-control-plane 0.1.65 → 0.1.67
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/README.md +123 -7
- package/lib/attestation.d.ts.map +1 -1
- package/lib/attestation.js +33 -1
- package/lib/attestation.js.map +1 -1
- package/lib/creation-capability-empty-handoff.d.ts +57 -0
- package/lib/creation-capability-empty-handoff.d.ts.map +1 -0
- package/lib/creation-capability-empty-handoff.js +147 -0
- package/lib/creation-capability-empty-handoff.js.map +1 -0
- package/lib/creation-capability-execution.d.ts +13 -0
- package/lib/creation-capability-execution.d.ts.map +1 -0
- package/lib/creation-capability-execution.js +112 -0
- package/lib/creation-capability-execution.js.map +1 -0
- package/lib/creation-capability-feedback.d.ts +58 -1
- package/lib/creation-capability-feedback.d.ts.map +1 -1
- package/lib/creation-capability-feedback.js +532 -50
- package/lib/creation-capability-feedback.js.map +1 -1
- package/lib/creation-capability-handoff-common.d.ts +60 -0
- package/lib/creation-capability-handoff-common.d.ts.map +1 -0
- package/lib/creation-capability-handoff-common.js +195 -0
- package/lib/creation-capability-handoff-common.js.map +1 -0
- package/lib/creation-capability-journal.d.ts +19 -0
- package/lib/creation-capability-journal.d.ts.map +1 -1
- package/lib/creation-capability-journal.js +62 -21
- package/lib/creation-capability-journal.js.map +1 -1
- package/lib/creation-capability-runtime.d.ts +65 -1
- package/lib/creation-capability-runtime.d.ts.map +1 -1
- package/lib/creation-capability-runtime.js +178 -18
- package/lib/creation-capability-runtime.js.map +1 -1
- package/lib/creation-capability-sealed-audit.d.ts +19 -0
- package/lib/creation-capability-sealed-audit.d.ts.map +1 -0
- package/lib/creation-capability-sealed-audit.js +114 -0
- package/lib/creation-capability-sealed-audit.js.map +1 -0
- package/lib/creation-capability-sealed-handoff.d.ts +160 -0
- package/lib/creation-capability-sealed-handoff.d.ts.map +1 -0
- package/lib/creation-capability-sealed-handoff.js +695 -0
- package/lib/creation-capability-sealed-handoff.js.map +1 -0
- package/lib/creation-capability-trend-snapshot.d.ts +70 -0
- package/lib/creation-capability-trend-snapshot.d.ts.map +1 -0
- package/lib/creation-capability-trend-snapshot.js +117 -0
- package/lib/creation-capability-trend-snapshot.js.map +1 -0
- package/lib/creation-capability-types.d.ts +254 -4
- package/lib/creation-capability-types.d.ts.map +1 -1
- package/lib/in-process-reload.d.ts +191 -0
- package/lib/in-process-reload.d.ts.map +1 -0
- package/lib/in-process-reload.js +284 -0
- package/lib/in-process-reload.js.map +1 -0
- package/lib/index.d.ts +15 -4
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +10 -2
- package/lib/index.js.map +1 -1
- package/lib/linux-source-build.d.ts +16 -0
- package/lib/linux-source-build.d.ts.map +1 -0
- package/lib/linux-source-build.js +268 -0
- package/lib/linux-source-build.js.map +1 -0
- package/lib/linux-source-preflight.d.ts +31 -0
- package/lib/linux-source-preflight.d.ts.map +1 -0
- package/lib/linux-source-preflight.js +101 -0
- package/lib/linux-source-preflight.js.map +1 -0
- package/lib/live-qualification-runtime.d.ts +6 -2
- package/lib/live-qualification-runtime.d.ts.map +1 -1
- package/lib/live-qualification-runtime.js +65 -11
- package/lib/live-qualification-runtime.js.map +1 -1
- package/lib/owner-task-gap-types.d.ts +23 -0
- package/lib/owner-task-gap-types.d.ts.map +1 -1
- package/lib/owner-task-gaps.d.ts +4 -0
- package/lib/owner-task-gaps.d.ts.map +1 -1
- package/lib/owner-task-gaps.js +35 -1
- package/lib/owner-task-gaps.js.map +1 -1
- package/lib/revision-capability-journal.d.ts +103 -0
- package/lib/revision-capability-journal.d.ts.map +1 -0
- package/lib/revision-capability-journal.js +872 -0
- package/lib/revision-capability-journal.js.map +1 -0
- package/lib/revision-capability-runtime.d.ts +74 -0
- package/lib/revision-capability-runtime.d.ts.map +1 -0
- package/lib/revision-capability-runtime.js +562 -0
- package/lib/revision-capability-runtime.js.map +1 -0
- package/lib/revision-capability-types.d.ts +289 -0
- package/lib/revision-capability-types.d.ts.map +1 -0
- package/lib/revision-capability-types.js +2 -0
- package/lib/revision-capability-types.js.map +1 -0
- package/lib/scanner-owner-runtime.d.ts +34 -0
- package/lib/scanner-owner-runtime.d.ts.map +1 -0
- package/lib/scanner-owner-runtime.js +99 -0
- package/lib/scanner-owner-runtime.js.map +1 -0
- package/lib/service.d.ts +107 -6
- package/lib/service.d.ts.map +1 -1
- package/lib/service.js +643 -47
- package/lib/service.js.map +1 -1
- package/lib/source-approval-authority.d.ts.map +1 -1
- package/lib/source-approval-authority.js +25 -7
- package/lib/source-approval-authority.js.map +1 -1
- package/lib/source-build-diagnostics.d.ts +31 -0
- package/lib/source-build-diagnostics.d.ts.map +1 -0
- package/lib/source-build-diagnostics.js +110 -0
- package/lib/source-build-diagnostics.js.map +1 -0
- package/lib/source-build.d.ts +25 -2
- package/lib/source-build.d.ts.map +1 -1
- package/lib/source-build.js +145 -26
- package/lib/source-build.js.map +1 -1
- package/lib/source-creation.d.ts +6 -2
- package/lib/source-creation.d.ts.map +1 -1
- package/lib/source-creation.js +11 -2
- package/lib/source-creation.js.map +1 -1
- package/lib/source-job-types.d.ts +3 -1
- package/lib/source-job-types.d.ts.map +1 -1
- package/lib/source-jobs.d.ts +33 -1
- package/lib/source-jobs.d.ts.map +1 -1
- package/lib/source-jobs.js +141 -29
- package/lib/source-jobs.js.map +1 -1
- package/lib/source-workspace.d.ts.map +1 -1
- package/lib/source-workspace.js +0 -1
- package/lib/source-workspace.js.map +1 -1
- package/lib/sqlite.d.ts +1 -1
- package/lib/sqlite.d.ts.map +1 -1
- package/lib/sqlite.js +36 -1
- package/lib/sqlite.js.map +1 -1
- package/lib/store.d.ts +22 -2
- package/lib/store.d.ts.map +1 -1
- package/lib/store.js +477 -177
- package/lib/store.js.map +1 -1
- package/lib/systemd-host-authority.d.ts.map +1 -1
- package/lib/systemd-host-authority.js +4 -0
- package/lib/systemd-host-authority.js.map +1 -1
- package/lib/task-observation-runtime.d.ts +6 -2
- package/lib/task-observation-runtime.d.ts.map +1 -1
- package/lib/task-observation-runtime.js +69 -11
- package/lib/task-observation-runtime.js.map +1 -1
- package/lib/types.d.ts +47 -1
- package/lib/types.d.ts.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/work-item-creation-contract.d.ts +17 -0
- package/lib/work-item-creation-contract.d.ts.map +1 -0
- package/lib/work-item-creation-contract.js +61 -0
- package/lib/work-item-creation-contract.js.map +1 -0
- package/package.json +10 -10
package/lib/source-jobs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-jobs.d.ts","sourceRoot":"","sources":["../src/source-jobs.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"source-jobs.d.ts","sourceRoot":"","sources":["../src/source-jobs.ts"],"names":[],"mappings":"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"}
|
package/lib/source-jobs.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
+
import { normalizeSourceCreationGrant } from './source-creation.js';
|
|
1
2
|
import { createHash, randomUUID } from 'node:crypto';
|
|
2
3
|
import { isAbsolute, join, resolve } from 'node:path';
|
|
3
4
|
import { realpath } from 'node:fs/promises';
|
|
4
|
-
import { SourceGrowthRunUnavailableError, isSourceOwnerContinuation, validateSourceGrowthRunBinding } from '@dsh-enhanced/assistant-growth-contract';
|
|
5
|
+
import { SourceGrowthRunUnavailableError, isSourceOwnerContinuation, validateAnySourceGrowthRunBinding as validateSourceGrowthRunBinding } from '@dsh-enhanced/assistant-growth-contract';
|
|
5
6
|
import { automationDefinitionDigest } from '@dsh-enhanced/assistant-automations';
|
|
6
7
|
import { controlPlaneDigest, expectedSourceRelease } from './store.js';
|
|
7
8
|
import { awaitSourceSignal, inspectSourceContext } from './source-context.js';
|
|
8
9
|
import { assertPluginModificationAllowed, removeSourceJobWorktree, validateScopedPluginFiles } from './source-workspace.js';
|
|
9
10
|
import { assertManagedVersionPaths } from './source-versioning.js';
|
|
10
11
|
import { resolveSourceBaseline, validateSourceBaselineConfig } from './source-baseline.js';
|
|
11
|
-
import { removeSourceJobContainer } from './source-build.js';
|
|
12
|
+
import { removeSourceJobContainer, validateSourceBuildConfig } from './source-build.js';
|
|
12
13
|
import { inspectSourceRevisionContext, validateSourceRevisionGrant } from './source-revision.js';
|
|
13
14
|
import { inspectSourceCreationContext, validateSourceCreationFiles, validateSourceCreationGrant } from './source-creation.js';
|
|
14
15
|
import { inheritedEnvironment } from './trust.js';
|
|
16
|
+
import { SOURCE_BUILD_CHECK_FAILED } from './source-build-diagnostics.js';
|
|
15
17
|
export const SOURCE_JOB_OWNER = 'plugin-control-plane-source';
|
|
16
18
|
const EXECUTOR = 'plugin-control-plane-source-check';
|
|
17
19
|
const CATALOG = controlPlaneDigest({ executor: EXECUTOR, version: 1, operation: 'isolated-check-pending-plan' });
|
|
@@ -34,6 +36,7 @@ export function validateSourceJobsConfig(value, build) {
|
|
|
34
36
|
|| !Number.isSafeInteger(value.budgetAmount) || value.budgetAmount < 1) {
|
|
35
37
|
throw new Error('plugin-control-plane: invalid sourceJobs authority configuration');
|
|
36
38
|
}
|
|
39
|
+
validateSourceBuildConfig(build);
|
|
37
40
|
if (value.baseline !== undefined)
|
|
38
41
|
validateSourceBaselineConfig(value.baseline);
|
|
39
42
|
if (value.allowedModes !== undefined && (!Array.isArray(value.allowedModes) || value.allowedModes.length < 1
|
|
@@ -45,18 +48,24 @@ export function validateSourceJobsConfig(value, build) {
|
|
|
45
48
|
validateSourceCreationGrant(value.creation);
|
|
46
49
|
if (value.revision !== undefined)
|
|
47
50
|
validateSourceRevisionGrant(value.revision);
|
|
48
|
-
if (
|
|
51
|
+
if ('backend' in build && build.backend === 'macos-seatbelt'
|
|
49
52
|
&& (!value.allowedModes || value.allowedModes.some(mode => mode === 'modify')
|
|
50
53
|
|| value.creation === undefined && value.revision === undefined)) {
|
|
51
54
|
throw new Error('plugin-control-plane: native source jobs require finite create/revise-created grants');
|
|
52
55
|
}
|
|
53
56
|
}
|
|
54
|
-
function
|
|
57
|
+
export function normalizeSourceJobsConfig(value, build) {
|
|
58
|
+
validateSourceJobsConfig(value, build);
|
|
59
|
+
return { ...structuredClone(value), ...(value.creation ? { creation: normalizeSourceCreationGrant(value.creation) } : {}) };
|
|
60
|
+
}
|
|
61
|
+
function projection(job, diagnostics) {
|
|
55
62
|
return { id: job.id, name: job.intent.name, gapId: job.intent.gapId, baseCommit: job.intent.baseCommit,
|
|
56
63
|
...(job.intent.mode === undefined ? {} : { mode: job.intent.mode }),
|
|
57
64
|
status: job.status, createdAt: job.createdAt, expiresAt: job.expiresAt,
|
|
58
|
-
...(job.planId === undefined ? {} : { planId: job.planId }), ...(job.failureCode === undefined ? {} : { failureCode: job.failureCode })
|
|
65
|
+
...(job.planId === undefined ? {} : { planId: job.planId }), ...(job.failureCode === undefined ? {} : { failureCode: job.failureCode }),
|
|
66
|
+
...(diagnostics !== undefined && job.status === 'failed' && job.failureCode === SOURCE_BUILD_CHECK_FAILED ? { diagnostics } : {}) };
|
|
59
67
|
}
|
|
68
|
+
const MAX_RETAINED_DIAGNOSTICS = 64;
|
|
60
69
|
/** Persisted intent + native Automations execution. This class owns no scheduler. */
|
|
61
70
|
export class SourceJobRuntime {
|
|
62
71
|
options;
|
|
@@ -75,9 +84,15 @@ export class SourceJobRuntime {
|
|
|
75
84
|
continuationCursor = 0;
|
|
76
85
|
continuationStatus;
|
|
77
86
|
continuationTransition = 0;
|
|
87
|
+
/** Process-local, bounded build diagnostics; the failure code itself is durable. */
|
|
88
|
+
diagnostics = new Map();
|
|
78
89
|
constructor(options) {
|
|
79
90
|
this.options = options;
|
|
80
91
|
validateSourceJobsConfig(options.config, options.build);
|
|
92
|
+
// Preserve the live object identity used by effect-boundary drift checks.
|
|
93
|
+
// False has no authority and is canonically absent, just like the default.
|
|
94
|
+
if (options.config.creation?.workItemFailures === false)
|
|
95
|
+
delete options.config.creation.workItemFailures;
|
|
81
96
|
this.authorityDigest = controlPlaneDigest({ config: options.config, build: options.build });
|
|
82
97
|
this.continuationNonce = controlPlaneDigest({ authority: this.authorityDigest, generation: this.generation });
|
|
83
98
|
}
|
|
@@ -177,6 +192,15 @@ export class SourceJobRuntime {
|
|
|
177
192
|
}
|
|
178
193
|
return Promise.allSettled(this.growthFlights).then(() => undefined);
|
|
179
194
|
}
|
|
195
|
+
/** A revision is adoptable only when its independent review, and any configured regression, verified. */
|
|
196
|
+
revisionAdoptionReady(job, planId) {
|
|
197
|
+
if (this.options.store.getRevisionVerificationStatus(planId) !== 'verified')
|
|
198
|
+
return false;
|
|
199
|
+
if (job.intent.revision?.growthRun.revisionRegressionAcceptance === undefined)
|
|
200
|
+
return true;
|
|
201
|
+
return this.options.verifyPreparedRevisionRegression !== undefined
|
|
202
|
+
&& this.options.store.getRevisionRegressionStatus(planId) === 'verified';
|
|
203
|
+
}
|
|
180
204
|
async continuePrepared(job, signal) {
|
|
181
205
|
if (!job.planId || !this.options.store.getOwnerTaskFailureReference(job.intent.gapId))
|
|
182
206
|
return;
|
|
@@ -226,6 +250,13 @@ export class SourceJobRuntime {
|
|
|
226
250
|
await assertCurrent();
|
|
227
251
|
await this.options.verifyPreparedRevisionRegression(job, signal);
|
|
228
252
|
}
|
|
253
|
+
// Verified acceptance and the optional independent parent regression end the review lane.
|
|
254
|
+
// Replacing the stable adopted entry is a separately authorized continuation.
|
|
255
|
+
if (this.revisionAdoptionReady(job, planId)
|
|
256
|
+
&& this.options.revisionAdoptionEligible?.(planId) && this.options.adoptVerifiedRevision) {
|
|
257
|
+
await assertCurrent();
|
|
258
|
+
await this.options.adoptVerifiedRevision(job, signal);
|
|
259
|
+
}
|
|
229
260
|
return;
|
|
230
261
|
}
|
|
231
262
|
if (initial.mode === 'prepared-create') {
|
|
@@ -265,6 +296,16 @@ export class SourceJobRuntime {
|
|
|
265
296
|
await this.options.adoptReleased(job, signal, assertCurrent);
|
|
266
297
|
}
|
|
267
298
|
}
|
|
299
|
+
inspectWorkItemReadiness(owner) {
|
|
300
|
+
if (!this.available() || !this.modeAllowed('create') || ('expiresAt' in this.options.build && Date.now() >= this.options.build.expiresAt) || this.options.config.creation?.workItemFailures !== true || Date.now() >= this.options.config.creation.expiresAt)
|
|
301
|
+
return undefined;
|
|
302
|
+
const current = this.receipt();
|
|
303
|
+
if (!isSourceOwnerContinuation(current, owner))
|
|
304
|
+
return undefined;
|
|
305
|
+
const config = this.options.config;
|
|
306
|
+
const authority = { id: config.authorityId, digest: this.authorityDigest, expiresAt: config.expiresAt };
|
|
307
|
+
return { authority, creation: structuredClone(config.creation), remaining: this.options.store.inspectSourceJobQuota({ authority: { ...authority, maxSubmissions: config.maxSubmissions }, creation: config.creation }) };
|
|
308
|
+
}
|
|
268
309
|
available() { return this.active && !this.abort.signal.aborted && Date.now() < this.options.config.expiresAt; }
|
|
269
310
|
close() {
|
|
270
311
|
return this.closing ??= (async () => {
|
|
@@ -313,8 +354,15 @@ export class SourceJobRuntime {
|
|
|
313
354
|
throw new Error('source job caller scope mismatch');
|
|
314
355
|
return owner;
|
|
315
356
|
}
|
|
316
|
-
withGapSource(gapId, owner, callback)
|
|
317
|
-
|
|
357
|
+
withJobSource(job, callback) { return this.withGapSource(job.intent.gapId, job.intent.owner, callback, job.intent.creation?.growthRun ?? job.intent.revision?.growthRun); }
|
|
358
|
+
withGapSource(gapId, owner, callback, growthRun) {
|
|
359
|
+
const reference = this.options.store.getOwnerTaskFailureReference(gapId);
|
|
360
|
+
if (reference?.schemaVersion === 2) {
|
|
361
|
+
if (growthRun?.protocol !== 'assistant-growth/source-run/v2' || !this.options.withWorkItemGrowthRunFence)
|
|
362
|
+
throw new SourceGrowthRunUnavailableError('work item growth source fence unavailable');
|
|
363
|
+
return this.options.withWorkItemGrowthRunFence(growthRun, gapId, owner, false, callback);
|
|
364
|
+
}
|
|
365
|
+
if (reference === undefined)
|
|
318
366
|
return callback();
|
|
319
367
|
if (!this.options.withGapSourceFence)
|
|
320
368
|
throw new Error('source job task provenance service unavailable');
|
|
@@ -346,7 +394,7 @@ export class SourceJobRuntime {
|
|
|
346
394
|
if (!parent || parent.name !== job.intent.name || controlPlaneDigest(parent.parent) !== controlPlaneDigest(job.intent.revision.parent))
|
|
347
395
|
throw new Error('source revision parent changed');
|
|
348
396
|
}
|
|
349
|
-
this.
|
|
397
|
+
this.withJobSource(job, () => this.assertGrowthRun((job.intent.creation?.growthRun ?? job.intent.revision?.growthRun), job.intent.mode, job.intent.gapId, job.intent.owner, false));
|
|
350
398
|
}
|
|
351
399
|
assertGrowthRun(growthRun, mode, gapId, owner, generation) {
|
|
352
400
|
const taskBacked = this.options.store.getOwnerTaskFailureReference(gapId) !== undefined;
|
|
@@ -358,12 +406,16 @@ export class SourceJobRuntime {
|
|
|
358
406
|
if (growthRun === undefined)
|
|
359
407
|
throw new Error('task-backed creation requires a frozen source growth run');
|
|
360
408
|
validateSourceGrowthRunBinding(growthRun);
|
|
409
|
+
if (growthRun.protocol === 'assistant-growth/source-run/v2' && (mode !== 'create' || this.options.config.creation?.workItemFailures !== true || this.options.store.getOwnerTaskFailureReference(gapId)?.schemaVersion !== 2))
|
|
410
|
+
throw new Error('work item growth requires explicit create authority');
|
|
361
411
|
if (!this.options.assertGrowthRun)
|
|
362
412
|
throw new SourceGrowthRunUnavailableError('source growth run producer unavailable');
|
|
363
413
|
this.options.assertGrowthRun(growthRun, gapId, owner, generation);
|
|
364
414
|
}
|
|
365
415
|
enqueue(input) {
|
|
366
416
|
this.assertMode(input.mode);
|
|
417
|
+
if (input.growthRun?.protocol === 'assistant-growth/source-run/v2' && input.mode !== 'create')
|
|
418
|
+
throw new Error('work item growth only permits create');
|
|
367
419
|
if (input.mode !== 'create' && input.mode !== 'revise-created' && input.growthRun !== undefined)
|
|
368
420
|
throw new Error('modify source job cannot carry a growth run');
|
|
369
421
|
if (input.mode === 'create' || input.mode === 'revise-created')
|
|
@@ -382,7 +434,7 @@ export class SourceJobRuntime {
|
|
|
382
434
|
async enqueueOwned(input) {
|
|
383
435
|
this.assertMode(input.mode);
|
|
384
436
|
const signal = AbortSignal.any([input.signal, this.abort.signal, AbortSignal.timeout(15_000)]);
|
|
385
|
-
const assertCurrent = async () => { signal.throwIfAborted(); await awaitSourceSignal(signal, input.assertCurrent); this.withGapSource(input.gapId, this.assertCaller(input.owner), () => { }); if (!this.available())
|
|
437
|
+
const assertCurrent = async () => { signal.throwIfAborted(); await awaitSourceSignal(signal, input.assertCurrent); this.withGapSource(input.gapId, this.assertCaller(input.owner), () => { }, input.growthRun); if (!this.available())
|
|
386
438
|
throw new Error('source job authority unavailable'); signal.throwIfAborted(); };
|
|
387
439
|
await assertCurrent();
|
|
388
440
|
if (input.mode === 'create' || input.mode === 'revise-created')
|
|
@@ -410,7 +462,7 @@ export class SourceJobRuntime {
|
|
|
410
462
|
const owner = reference?.owner ?? currentOwner;
|
|
411
463
|
if (reference && !isSourceOwnerContinuation(currentOwner, owner))
|
|
412
464
|
throw new Error('source job task owner changed');
|
|
413
|
-
this.withGapSource(input.gapId, currentOwner, () => this.assertGrowthRun(input.growthRun, input.mode, input.gapId, owner, true));
|
|
465
|
+
this.withGapSource(input.gapId, currentOwner, () => this.assertGrowthRun(input.growthRun, input.mode, input.gapId, owner, true), input.growthRun);
|
|
414
466
|
const parent = input.mode === 'revise-created' ? this.options.inspectRevisionParent?.(input.parentPlanId) : undefined;
|
|
415
467
|
if (input.mode === 'revise-created' && (!parent || parent.name !== input.name))
|
|
416
468
|
throw new Error('adopted revision parent unavailable or mismatched');
|
|
@@ -464,7 +516,7 @@ export class SourceJobRuntime {
|
|
|
464
516
|
files: structuredClone(input.files), ttlMs: input.ttlMs, build: structuredClone(this.options.build),
|
|
465
517
|
worktree: join(this.options.statePath, 'source-worktrees', `worktree-job-${token}`),
|
|
466
518
|
...('backend' in this.options.build
|
|
467
|
-
? { nativeResource: { backend:
|
|
519
|
+
? { nativeResource: { backend: this.options.build.backend, key: id } }
|
|
468
520
|
: { containerName: `dsh-source-job-${token}` }),
|
|
469
521
|
};
|
|
470
522
|
await assertCurrent();
|
|
@@ -472,7 +524,7 @@ export class SourceJobRuntime {
|
|
|
472
524
|
const job = this.withGapSource(gap.id, owner, () => {
|
|
473
525
|
this.assertGrowthRun(input.growthRun, input.mode, gap.id, owner, true);
|
|
474
526
|
return this.options.store.enqueueSourceJob({ id, automationId: id, idempotencyKey: input.idempotencyKey, intent });
|
|
475
|
-
});
|
|
527
|
+
}, input.growthRun);
|
|
476
528
|
if (job.status === 'queued')
|
|
477
529
|
this.scheduleOrFail(job);
|
|
478
530
|
return projection(this.options.store.getSourceJob(id));
|
|
@@ -487,7 +539,7 @@ export class SourceJobRuntime {
|
|
|
487
539
|
|| job.intent.owner.principalVersion !== owner.principalVersion || job.intent.owner.workspace !== owner.workspace
|
|
488
540
|
|| job.intent.owner.agentPreset !== owner.agentPreset)
|
|
489
541
|
throw new Error('source job not found for current owner');
|
|
490
|
-
return projection(this.refreshQueued(job));
|
|
542
|
+
return projection(this.refreshQueued(job), this.diagnostics.get(job.id));
|
|
491
543
|
}
|
|
492
544
|
/** Native runner admission can fail before our executor is invoked. */
|
|
493
545
|
refreshQueued(job) {
|
|
@@ -503,10 +555,13 @@ export class SourceJobRuntime {
|
|
|
503
555
|
code = 'source-job-growth-run-missing';
|
|
504
556
|
else {
|
|
505
557
|
try {
|
|
506
|
-
this.
|
|
558
|
+
this.withJobSource(job, () => { providerUnavailable = this.growthProducerUnavailable(job); });
|
|
507
559
|
}
|
|
508
|
-
catch {
|
|
509
|
-
|
|
560
|
+
catch (error) {
|
|
561
|
+
if (error instanceof SourceGrowthRunUnavailableError)
|
|
562
|
+
providerUnavailable = true;
|
|
563
|
+
else
|
|
564
|
+
code = 'source-job-task-source-changed';
|
|
510
565
|
}
|
|
511
566
|
}
|
|
512
567
|
if (job.expiresAt <= Date.now())
|
|
@@ -534,10 +589,25 @@ export class SourceJobRuntime {
|
|
|
534
589
|
throw error;
|
|
535
590
|
}
|
|
536
591
|
}
|
|
592
|
+
linuxRevisionReviewTimeoutMs() {
|
|
593
|
+
// A Linux revision can run two independently bounded reviews after its
|
|
594
|
+
// repository build. This outer window never changes their own budgets or
|
|
595
|
+
// the frozen source expiry; legacy backend definitions retain their identity.
|
|
596
|
+
if (!('backend' in this.options.build) || this.options.build.backend !== 'linux-native')
|
|
597
|
+
return 0;
|
|
598
|
+
return (this.options.verifyPreparedRevision ? 1_800_000 : 0)
|
|
599
|
+
+ (this.options.verifyPreparedRevisionRegression ? 1_800_000 : 0)
|
|
600
|
+
+ (this.options.adoptVerifiedRevision ? 180_000 : 0);
|
|
601
|
+
}
|
|
537
602
|
definition(job) {
|
|
538
603
|
const config = this.options.config;
|
|
539
604
|
return { name: `Source check: ${job.intent.name}`, schedule: { kind: 'at', at: new Date(job.dispatchAt ?? job.createdAt + 1000).toISOString() },
|
|
540
|
-
workspace: config.workspace, agentPreset: config.preset, timeoutMs: job.intent.build.timeoutMs + 120_000
|
|
605
|
+
workspace: config.workspace, agentPreset: config.preset, timeoutMs: job.intent.build.timeoutMs + 120_000
|
|
606
|
+
+ (job.intent.mode === 'revise-created' ? this.linuxRevisionReviewTimeoutMs() : 0)
|
|
607
|
+
+ (job.intent.mode === 'create' && job.intent.creation?.growthRun?.protocol === 'assistant-growth/source-run/v2'
|
|
608
|
+
&& 'backend' in this.options.build
|
|
609
|
+
&& this.options.build.backend === 'linux-native' && this.options.verifyPreparedCreation ? 1_800_000 : 0)
|
|
610
|
+
+ (this.options.advanceReleased ? this.options.releaseTimeoutMs ?? 40_000 : 0) + (this.options.adoptReleased ? this.options.adoptionTimeoutMs ?? 60_000 : 0),
|
|
541
611
|
misfire: { kind: 'latest' }, overlap: 'skip', retrySafety: 'never', maxRetries: 0, principal: config.principalId,
|
|
542
612
|
...(config.budgetId === undefined ? {} : { budgetId: config.budgetId, budgetAmount: config.budgetAmount }),
|
|
543
613
|
execution: { kind: 'host', executorId: EXECUTOR, executorContractVersion: 1, runbookId: EXECUTOR, runbookVersion: 1, catalogDigest: CATALOG,
|
|
@@ -556,7 +626,7 @@ export class SourceJobRuntime {
|
|
|
556
626
|
if ((health.automationStatus === 'paused' && dueAt <= Date.now())
|
|
557
627
|
|| (terminal !== undefined && terminal.immutableContext.state === 'verified'
|
|
558
628
|
&& terminal.immutableContext.definitionHash === job.definitionHash && terminal.createdAt >= job.createdAt)) {
|
|
559
|
-
job = this.
|
|
629
|
+
job = this.withJobSource(job, () => {
|
|
560
630
|
this.assertGrowthRun(job.intent.creation?.growthRun ?? job.intent.revision?.growthRun, job.intent.mode, job.intent.gapId, job.intent.owner, false);
|
|
561
631
|
return this.options.store.rearmQueuedGrowthSourceJob({ id: job.id, revision: job.revision,
|
|
562
632
|
priorDefinitionHash: job.definitionHash, priorDefinitionVersion: health.definitionVersion, dispatchAt: Date.now() + 1000 });
|
|
@@ -621,12 +691,14 @@ export class SourceJobRuntime {
|
|
|
621
691
|
throw new Error('source job native activation did not become active');
|
|
622
692
|
}
|
|
623
693
|
hasContinuations() {
|
|
624
|
-
return !!(this.options.approvePrepared || this.options.verifyPreparedRevisionRegression || this.options.verifyPreparedRevision
|
|
694
|
+
return !!(this.options.approvePrepared || this.options.verifyPreparedRevisionRegression || this.options.verifyPreparedRevision
|
|
695
|
+
|| this.options.verifyPreparedCreation || this.options.adoptVerifiedCreation || this.options.adoptVerifiedRevision
|
|
696
|
+
|| this.options.releasePrepared || this.options.advanceReleased || this.options.adoptReleased);
|
|
625
697
|
}
|
|
626
698
|
continuationJobs() {
|
|
627
699
|
if (!this.hasContinuations())
|
|
628
700
|
return [];
|
|
629
|
-
return this.options.store.listPreparedSourceApprovalJobs(this.options.releasePrepared !== undefined, this.options.advanceReleased !== undefined, this.options.adoptReleased !== undefined, this.options.verifyPreparedCreation !== undefined, this.options.adoptVerifiedCreation !== undefined, this.options.verifyPreparedRevision !== undefined, this.options.verifyPreparedRevisionRegression !== undefined)
|
|
701
|
+
return this.options.store.listPreparedSourceApprovalJobs(this.options.releasePrepared !== undefined, this.options.advanceReleased !== undefined, this.options.adoptReleased !== undefined, this.options.verifyPreparedCreation !== undefined, this.options.adoptVerifiedCreation !== undefined, this.options.verifyPreparedRevision !== undefined, this.options.verifyPreparedRevisionRegression !== undefined, this.options.adoptVerifiedRevision !== undefined)
|
|
630
702
|
.filter(job => this.modeAllowed(job.intent.mode) && this.eligibleContinuation(job));
|
|
631
703
|
}
|
|
632
704
|
/** Admission reads durable state and validates the current owner; it never invokes continuation approval or release hooks. */
|
|
@@ -647,7 +719,9 @@ export class SourceJobRuntime {
|
|
|
647
719
|
const verify = status === undefined && this.options.verifyPreparedRevision !== undefined;
|
|
648
720
|
const regression = status === 'verified' && plan.sourceRevision.growthRun.revisionRegressionAcceptance !== undefined
|
|
649
721
|
&& this.options.store.getRevisionRegressionStatus(plan.id) === undefined && this.options.verifyPreparedRevisionRegression !== undefined;
|
|
650
|
-
|
|
722
|
+
const adoption = this.options.revisionAdoptionEligible !== undefined && this.options.adoptVerifiedRevision !== undefined
|
|
723
|
+
&& this.revisionAdoptionReady(job, plan.id) && this.options.revisionAdoptionEligible(plan.id) === true;
|
|
724
|
+
if (!verify && !regression && !adoption)
|
|
651
725
|
return false;
|
|
652
726
|
try {
|
|
653
727
|
this.assertOwner(job);
|
|
@@ -671,7 +745,7 @@ export class SourceJobRuntime {
|
|
|
671
745
|
return false;
|
|
672
746
|
try {
|
|
673
747
|
this.assertOwner(job);
|
|
674
|
-
this.
|
|
748
|
+
this.withJobSource(job, () => {
|
|
675
749
|
this.assertGrowthRun(job.intent.creation?.growthRun, job.intent.mode, job.intent.gapId, job.intent.owner, false);
|
|
676
750
|
});
|
|
677
751
|
}
|
|
@@ -707,7 +781,7 @@ export class SourceJobRuntime {
|
|
|
707
781
|
continuationTimeoutMs() {
|
|
708
782
|
const release = this.options.releaseTimeoutMs ?? 40_000, adoption = this.options.adoptionTimeoutMs ?? 60_000;
|
|
709
783
|
const needed = (this.options.adoptReleased ? adoption : 0) + (this.options.advanceReleased ? release + 40_000 : this.options.releasePrepared ? 40_000 : 10_000);
|
|
710
|
-
return Math.max(this.options.verifyPreparedCreation ? 1_800_000 : 10_000, needed);
|
|
784
|
+
return Math.max(this.linuxRevisionReviewTimeoutMs(), this.options.verifyPreparedCreation ? 1_800_000 : 10_000, needed);
|
|
711
785
|
}
|
|
712
786
|
continuationSignalTimeoutMs(job) {
|
|
713
787
|
if (job.planId) {
|
|
@@ -812,7 +886,7 @@ export class SourceJobRuntime {
|
|
|
812
886
|
const health = this.options.ports.automations.inspectSystemOwned({ owner: SOURCE_JOB_OWNER, automationId: job.automationId });
|
|
813
887
|
if (health.definitionHash !== rebound.definitionHash)
|
|
814
888
|
throw new Error('source job premature occurrence native binding changed');
|
|
815
|
-
const pending = this.
|
|
889
|
+
const pending = this.withJobSource(rebound, () => {
|
|
816
890
|
this.assertGrowthRun(rebound.intent.creation?.growthRun ?? rebound.intent.revision?.growthRun, rebound.intent.mode, rebound.intent.gapId, rebound.intent.owner, false);
|
|
817
891
|
return this.options.store.rearmQueuedGrowthSourceJob({ id: rebound.id, revision: rebound.revision,
|
|
818
892
|
priorDefinitionHash: rebound.definitionHash, priorDefinitionVersion: health.definitionVersion, dispatchAt: Date.now() + 1000 });
|
|
@@ -825,12 +899,15 @@ export class SourceJobRuntime {
|
|
|
825
899
|
return failure(false);
|
|
826
900
|
}
|
|
827
901
|
let claimed = false;
|
|
902
|
+
let claimedJob;
|
|
828
903
|
const growthController = (job.intent.creation?.growthRun ?? job.intent.revision?.growthRun) === undefined ? undefined : new AbortController();
|
|
829
904
|
if (growthController)
|
|
830
905
|
this.growthControllers.add(growthController);
|
|
831
906
|
const signal = AbortSignal.any([input.signal, this.abort.signal,
|
|
832
907
|
...(growthController ? [growthController.signal] : []),
|
|
833
|
-
AbortSignal.timeout(Math.max(1, Math.min(job.intent.build.timeoutMs + 120_000
|
|
908
|
+
AbortSignal.timeout(Math.max(1, Math.min(job.intent.build.timeoutMs + 120_000
|
|
909
|
+
+ (job.intent.mode === 'revise-created' && this.linuxRevisionReviewTimeoutMs()
|
|
910
|
+
? this.linuxRevisionReviewTimeoutMs() : this.options.verifyPreparedCreation ? 1_800_000 : 0)
|
|
834
911
|
+ (this.options.advanceReleased ? this.options.releaseTimeoutMs ?? 40_000 : 0) + (this.options.adoptReleased ? this.options.adoptionTimeoutMs ?? 60_000 : 0), job.expiresAt - Date.now())))]);
|
|
835
912
|
try {
|
|
836
913
|
this.assertOwner(job);
|
|
@@ -839,9 +916,11 @@ export class SourceJobRuntime {
|
|
|
839
916
|
|| input.ownerRouteId !== job.intent.owner.authorityId || input.principal !== job.intent.owner.principalId
|
|
840
917
|
|| input.targetScope.workspace !== job.intent.owner.workspace || input.targetScope.preset !== job.intent.owner.agentPreset)
|
|
841
918
|
throw new Error('source job executor binding mismatch');
|
|
842
|
-
|
|
919
|
+
const queuedJob = job;
|
|
920
|
+
job = this.withJobSource(queuedJob, () => this.options.store.claimSourceJob({ id: queuedJob.id, revision: queuedJob.revision, definitionHash: input.definitionHash, occurrenceId: input.occurrenceId }));
|
|
843
921
|
claimed = true;
|
|
844
922
|
const owned = job;
|
|
923
|
+
claimedJob = owned;
|
|
845
924
|
const assertCurrent = async () => {
|
|
846
925
|
signal.throwIfAborted();
|
|
847
926
|
this.assertOwner(owned);
|
|
@@ -874,8 +953,40 @@ export class SourceJobRuntime {
|
|
|
874
953
|
if (!claimed && current?.status === 'queued'
|
|
875
954
|
&& (current.revision !== job.revision || current.definitionHash !== input.definitionHash))
|
|
876
955
|
return failure(false);
|
|
877
|
-
if (
|
|
878
|
-
|
|
956
|
+
if (claimed && claimedJob && current?.status === 'running' && current.revision === claimedJob.revision
|
|
957
|
+
&& current.occurrenceId === claimedJob.occurrenceId && current.intentDigest === claimedJob.intentDigest) {
|
|
958
|
+
let notStarted = false;
|
|
959
|
+
try {
|
|
960
|
+
notStarted = this.options.isPreparationNotStarted?.(error, claimedJob) === true;
|
|
961
|
+
}
|
|
962
|
+
catch { /* Unavailable proof remains unknown. */ }
|
|
963
|
+
let diagnostics;
|
|
964
|
+
if (!notStarted) {
|
|
965
|
+
try {
|
|
966
|
+
diagnostics = this.options.deterministicBuildFailure?.(error, claimedJob);
|
|
967
|
+
}
|
|
968
|
+
catch { /* Unavailable proof remains unknown. */ }
|
|
969
|
+
}
|
|
970
|
+
if (diagnostics !== undefined) {
|
|
971
|
+
this.options.store.settleSourceJob({ id: claimedJob.id, revision: claimedJob.revision,
|
|
972
|
+
status: 'failed', failureCode: SOURCE_BUILD_CHECK_FAILED });
|
|
973
|
+
this.diagnostics.delete(claimedJob.id);
|
|
974
|
+
this.diagnostics.set(claimedJob.id, diagnostics);
|
|
975
|
+
while (this.diagnostics.size > MAX_RETAINED_DIAGNOSTICS)
|
|
976
|
+
this.diagnostics.delete(this.diagnostics.keys().next().value);
|
|
977
|
+
return { outcome: 'failed', failureClass: 'execution', failurePhase: 'host-execution',
|
|
978
|
+
failureCode: SOURCE_BUILD_CHECK_FAILED, sideEffectState: 'possible', retryability: 'unsafe' };
|
|
979
|
+
}
|
|
980
|
+
if (notStarted) {
|
|
981
|
+
this.options.store.settleSourceJob({ id: claimedJob.id, revision: claimedJob.revision,
|
|
982
|
+
status: 'failed', failureCode: 'source-job-preparation-not-started' });
|
|
983
|
+
return { outcome: 'failed', failureClass: 'configuration', failurePhase: 'host-execution',
|
|
984
|
+
failureCode: 'source-job-preparation-not-started', sideEffectState: 'possible', retryability: 'unsafe' };
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
if (!claimed && current?.status === 'queued' && current.revision === job.revision
|
|
988
|
+
|| claimed && current?.status === 'running' && current.revision === job.revision && current.occurrenceId === input.occurrenceId) {
|
|
989
|
+
this.options.store.settleSourceJob({ id: job.id, revision: job.revision, status: claimed ? 'unknown' : 'failed', failureCode: claimed ? 'source-job-interrupted' : 'source-job-preflight-rejected' });
|
|
879
990
|
}
|
|
880
991
|
return failure(claimed);
|
|
881
992
|
}
|
|
@@ -895,7 +1006,8 @@ export class SourceJobRuntime {
|
|
|
895
1006
|
if (controlPlaneDigest(trust) !== job.intent.trustDigest)
|
|
896
1007
|
throw new Error('source job trust changed');
|
|
897
1008
|
if ('backend' in job.intent.build) {
|
|
898
|
-
if (job.intent.nativeResource?.backend !==
|
|
1009
|
+
if (job.intent.nativeResource?.backend !== job.intent.build.backend || job.intent.nativeResource.key !== job.id
|
|
1010
|
+
|| controlPlaneDigest(this.options.build) !== controlPlaneDigest(job.intent.build)
|
|
899
1011
|
|| await this.options.inspectNativeQuiescence?.(job.id) !== 'quiescent') {
|
|
900
1012
|
throw new Error('native source job has no valid durable quiescence receipt');
|
|
901
1013
|
}
|