@telora/daemon 0.15.50 → 0.15.55
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/build-info.json +568 -2
- package/dist/assembly-resolvers.d.ts.map +1 -1
- package/dist/assembly-resolvers.js +25 -2
- package/dist/assembly-resolvers.js.map +1 -1
- package/dist/build-info.d.ts +17 -0
- package/dist/build-info.d.ts.map +1 -0
- package/dist/build-info.js +43 -0
- package/dist/build-info.js.map +1 -0
- package/dist/delivery-artifacts.d.ts +26 -0
- package/dist/delivery-artifacts.d.ts.map +1 -0
- package/dist/delivery-artifacts.js +55 -0
- package/dist/delivery-artifacts.js.map +1 -0
- package/dist/delivery-lifecycle.d.ts +10 -0
- package/dist/delivery-lifecycle.d.ts.map +1 -1
- package/dist/delivery-lifecycle.js +18 -2
- package/dist/delivery-lifecycle.js.map +1 -1
- package/dist/directive-executor.d.ts.map +1 -1
- package/dist/directive-executor.js +7 -8
- package/dist/directive-executor.js.map +1 -1
- package/dist/focus-completion-event.js +1 -1
- package/dist/focus-completion-event.js.map +1 -1
- package/dist/focus-completion.d.ts +31 -27
- package/dist/focus-completion.d.ts.map +1 -1
- package/dist/focus-completion.js +85 -67
- package/dist/focus-completion.js.map +1 -1
- package/dist/focus-engine.d.ts.map +1 -1
- package/dist/focus-engine.js +19 -1
- package/dist/focus-engine.js.map +1 -1
- package/dist/focus-executor.d.ts +3 -3
- package/dist/focus-executor.js +4 -4
- package/dist/focus-executor.js.map +1 -1
- package/dist/focus-loop.js +1 -1
- package/dist/focus-loop.js.map +1 -1
- package/dist/focus-phase.d.ts +4 -0
- package/dist/focus-phase.d.ts.map +1 -1
- package/dist/focus-phase.js +15 -8
- package/dist/focus-phase.js.map +1 -1
- package/dist/listener-auto-advance.d.ts +24 -1
- package/dist/listener-auto-advance.d.ts.map +1 -1
- package/dist/listener-auto-advance.js +147 -19
- package/dist/listener-auto-advance.js.map +1 -1
- package/dist/listener.d.ts +1 -1
- package/dist/listener.js +4 -4
- package/dist/listener.js.map +1 -1
- package/dist/merge-back-loop.js +1 -1
- package/dist/merge-back-loop.js.map +1 -1
- package/dist/queries/deliveries.d.ts +17 -1
- package/dist/queries/deliveries.d.ts.map +1 -1
- package/dist/queries/deliveries.js +29 -1
- package/dist/queries/deliveries.js.map +1 -1
- package/dist/queries/migrations.d.ts +11 -0
- package/dist/queries/migrations.d.ts.map +1 -0
- package/dist/queries/migrations.js +15 -0
- package/dist/queries/migrations.js.map +1 -0
- package/dist/schema-version-gate.d.ts +51 -0
- package/dist/schema-version-gate.d.ts.map +1 -0
- package/dist/schema-version-gate.js +82 -0
- package/dist/schema-version-gate.js.map +1 -0
- package/dist/security-auto-inject.d.ts +15 -4
- package/dist/security-auto-inject.d.ts.map +1 -1
- package/dist/security-auto-inject.js +12 -4
- package/dist/security-auto-inject.js.map +1 -1
- package/dist/security-scan-engine.d.ts +9 -1
- package/dist/security-scan-engine.d.ts.map +1 -1
- package/dist/security-scan-engine.js +31 -12
- package/dist/security-scan-engine.js.map +1 -1
- package/dist/stage-classifier.js +5 -5
- package/dist/stage-classifier.js.map +1 -1
- package/dist/state-cascade.d.ts +10 -11
- package/dist/state-cascade.d.ts.map +1 -1
- package/dist/state-cascade.js +12 -22
- package/dist/state-cascade.js.map +1 -1
- package/dist/supabase.d.ts +2 -1
- package/dist/supabase.d.ts.map +1 -1
- package/dist/supabase.js +3 -1
- package/dist/supabase.js.map +1 -1
- package/dist/team-prompt-base.js +1 -1
- package/dist/team-prompt-base.js.map +1 -1
- package/dist/types/focus.d.ts +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema-version gate (D3-T3).
|
|
3
|
+
*
|
|
4
|
+
* Compares the publish-time `expectedMigrations` set embedded in
|
|
5
|
+
* build-info.json (T1) against the migrations actually applied in the
|
|
6
|
+
* live DB (T2's daemon_get_applied_migrations action). On mismatch:
|
|
7
|
+
* - fail-fast (production default): exit 1 with the missing list
|
|
8
|
+
* - warn (dev default): log and continue
|
|
9
|
+
* - off: skip the check entirely
|
|
10
|
+
*
|
|
11
|
+
* Runs at startup immediately after validateTrackerAuth so the daemon
|
|
12
|
+
* never reaches its write path with a deploy-order schema drift.
|
|
13
|
+
*
|
|
14
|
+
* Operator runbook: docs/runbook-schema-version-gate.md
|
|
15
|
+
* Incident: 2026-05-21 escalation 4bffb633.
|
|
16
|
+
*/
|
|
17
|
+
export type SchemaGateMode = 'fail-fast' | 'warn' | 'off';
|
|
18
|
+
export interface SchemaGateResult {
|
|
19
|
+
mode: SchemaGateMode;
|
|
20
|
+
/** Expected migration versions (timestamp prefixes, e.g. '20260521233716'). */
|
|
21
|
+
expected: string[];
|
|
22
|
+
/** Applied migration versions returned by the live DB. */
|
|
23
|
+
applied: string[];
|
|
24
|
+
/** Expected ∖ applied. Empty when ok. */
|
|
25
|
+
missing: string[];
|
|
26
|
+
ok: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolve the operating mode from environment.
|
|
30
|
+
* TELORA_SCHEMA_GATE=off | 0 -> 'off'
|
|
31
|
+
* TELORA_SCHEMA_GATE=warn -> 'warn'
|
|
32
|
+
* TELORA_SCHEMA_GATE=fail-fast -> 'fail-fast'
|
|
33
|
+
* unset (default):
|
|
34
|
+
* NODE_ENV=production -> 'fail-fast'
|
|
35
|
+
* otherwise -> 'warn'
|
|
36
|
+
*/
|
|
37
|
+
export declare function resolveSchemaGateMode(env?: NodeJS.ProcessEnv): SchemaGateMode;
|
|
38
|
+
/**
|
|
39
|
+
* Extract the supabase migration version (timestamp prefix) from a
|
|
40
|
+
* full filename: '20260521233716_daemon_get_applied_migrations.sql'
|
|
41
|
+
* -> '20260521233716'. Returns the input unchanged if no underscore.
|
|
42
|
+
*/
|
|
43
|
+
export declare function versionPrefix(filename: string): string;
|
|
44
|
+
export interface CheckSchemaVersionDeps {
|
|
45
|
+
mode?: SchemaGateMode;
|
|
46
|
+
getExpected?: () => string[];
|
|
47
|
+
getApplied?: () => Promise<string[]>;
|
|
48
|
+
}
|
|
49
|
+
export declare function checkSchemaVersion(deps?: CheckSchemaVersionDeps): Promise<SchemaGateResult>;
|
|
50
|
+
export declare function reportSchemaGateResult(result: SchemaGateResult): void;
|
|
51
|
+
//# sourceMappingURL=schema-version-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-version-gate.d.ts","sourceRoot":"","sources":["../src/schema-version-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC;AAE1D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,yCAAyC;IACzC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,EAAE,EAAE,OAAO,CAAC;CACb;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,cAAc,CAO1F;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAItD;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACtC;AAED,wBAAsB,kBAAkB,CAAC,IAAI,GAAE,sBAA2B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAcrG;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAoBrE"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema-version gate (D3-T3).
|
|
3
|
+
*
|
|
4
|
+
* Compares the publish-time `expectedMigrations` set embedded in
|
|
5
|
+
* build-info.json (T1) against the migrations actually applied in the
|
|
6
|
+
* live DB (T2's daemon_get_applied_migrations action). On mismatch:
|
|
7
|
+
* - fail-fast (production default): exit 1 with the missing list
|
|
8
|
+
* - warn (dev default): log and continue
|
|
9
|
+
* - off: skip the check entirely
|
|
10
|
+
*
|
|
11
|
+
* Runs at startup immediately after validateTrackerAuth so the daemon
|
|
12
|
+
* never reaches its write path with a deploy-order schema drift.
|
|
13
|
+
*
|
|
14
|
+
* Operator runbook: docs/runbook-schema-version-gate.md
|
|
15
|
+
* Incident: 2026-05-21 escalation 4bffb633.
|
|
16
|
+
*/
|
|
17
|
+
import { getExpectedMigrations as defaultGetExpected } from './build-info.js';
|
|
18
|
+
import { getAppliedMigrations as defaultGetApplied } from './supabase.js';
|
|
19
|
+
/**
|
|
20
|
+
* Resolve the operating mode from environment.
|
|
21
|
+
* TELORA_SCHEMA_GATE=off | 0 -> 'off'
|
|
22
|
+
* TELORA_SCHEMA_GATE=warn -> 'warn'
|
|
23
|
+
* TELORA_SCHEMA_GATE=fail-fast -> 'fail-fast'
|
|
24
|
+
* unset (default):
|
|
25
|
+
* NODE_ENV=production -> 'fail-fast'
|
|
26
|
+
* otherwise -> 'warn'
|
|
27
|
+
*/
|
|
28
|
+
export function resolveSchemaGateMode(env = process.env) {
|
|
29
|
+
const raw = (env.TELORA_SCHEMA_GATE ?? '').trim().toLowerCase();
|
|
30
|
+
if (raw === 'off' || raw === '0')
|
|
31
|
+
return 'off';
|
|
32
|
+
if (raw === 'warn')
|
|
33
|
+
return 'warn';
|
|
34
|
+
if (raw === 'fail-fast')
|
|
35
|
+
return 'fail-fast';
|
|
36
|
+
// Default: prod is strict, dev is permissive
|
|
37
|
+
return env.NODE_ENV === 'production' ? 'fail-fast' : 'warn';
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Extract the supabase migration version (timestamp prefix) from a
|
|
41
|
+
* full filename: '20260521233716_daemon_get_applied_migrations.sql'
|
|
42
|
+
* -> '20260521233716'. Returns the input unchanged if no underscore.
|
|
43
|
+
*/
|
|
44
|
+
export function versionPrefix(filename) {
|
|
45
|
+
const underscore = filename.indexOf('_');
|
|
46
|
+
if (underscore <= 0)
|
|
47
|
+
return filename;
|
|
48
|
+
return filename.slice(0, underscore);
|
|
49
|
+
}
|
|
50
|
+
export async function checkSchemaVersion(deps = {}) {
|
|
51
|
+
const mode = deps.mode ?? resolveSchemaGateMode();
|
|
52
|
+
const expectedFilenames = (deps.getExpected ?? defaultGetExpected)();
|
|
53
|
+
const expected = expectedFilenames.map(versionPrefix);
|
|
54
|
+
// Dev mode -- build-info missing or empty. Skip the gate.
|
|
55
|
+
if (expected.length === 0) {
|
|
56
|
+
return { mode, expected: [], applied: [], missing: [], ok: true };
|
|
57
|
+
}
|
|
58
|
+
const applied = await (deps.getApplied ?? defaultGetApplied)();
|
|
59
|
+
const appliedSet = new Set(applied);
|
|
60
|
+
const missing = expected.filter((v) => !appliedSet.has(v));
|
|
61
|
+
return { mode, expected, applied, missing, ok: missing.length === 0 };
|
|
62
|
+
}
|
|
63
|
+
export function reportSchemaGateResult(result) {
|
|
64
|
+
if (result.mode === 'off')
|
|
65
|
+
return;
|
|
66
|
+
if (result.ok) {
|
|
67
|
+
console.log(`[schema-gate] OK -- all ${result.expected.length} expected migrations applied`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const lines = result.missing.map((m) => ` - ${m}`).join('\n');
|
|
71
|
+
const body = `[schema-gate] Missing ${result.missing.length} migration(s) in live DB:\n${lines}`;
|
|
72
|
+
if (result.mode === 'fail-fast') {
|
|
73
|
+
console.error(body);
|
|
74
|
+
console.error('[schema-gate] Refusing to start. Apply missing migrations or set TELORA_SCHEMA_GATE=warn to override. ' +
|
|
75
|
+
'See docs/runbook-schema-version-gate.md.');
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
console.warn(body);
|
|
79
|
+
console.warn('[schema-gate] Continuing with TELORA_SCHEMA_GATE=warn -- writes that depend on these migrations will fail.');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=schema-version-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-version-gate.js","sourceRoot":"","sources":["../src/schema-version-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Every open finding that the engine sees -- newly observed or with no
|
|
5
5
|
* linked remediation -- is handed to processNewFinding. The function:
|
|
6
|
-
* 1.
|
|
6
|
+
* 1. Creates a fresh Security remediation focus + tree (per-scan-run
|
|
7
|
+
* memoization in security-scan-engine batches findings into one focus).
|
|
7
8
|
* 2. Creates or reuses an entity node representing the vulnerable surface.
|
|
8
9
|
* 3. Creates an injection node on the focus's reality tree with
|
|
9
10
|
* statement = advisory summary; targets the entity node via a
|
|
@@ -34,13 +35,21 @@ export interface FindingForInjection {
|
|
|
34
35
|
export type AutoInjectOptions = Record<string, never>;
|
|
35
36
|
export interface AutoInjectDeps {
|
|
36
37
|
/**
|
|
37
|
-
*
|
|
38
|
-
* product
|
|
38
|
+
* Materialize a new product_focus carrying the Security workflow for this
|
|
39
|
+
* product. Always creates -- no reuse of existing open focuses. Returns
|
|
40
|
+
* the new focus and its reality tree.
|
|
39
41
|
*/
|
|
40
|
-
|
|
42
|
+
createSecurityRemediationFocus: (productId: string, organizationId: string) => Promise<{
|
|
41
43
|
focusId: string;
|
|
42
44
|
treeId: string;
|
|
43
45
|
}>;
|
|
46
|
+
/**
|
|
47
|
+
* Append "(<count> findings)" to a remediation focus's name once the
|
|
48
|
+
* scan batch's count is known. Optional: only called from the engine
|
|
49
|
+
* after the scan loop completes; no-op for tests that don't exercise
|
|
50
|
+
* the finalize path.
|
|
51
|
+
*/
|
|
52
|
+
finalizeSecurityRemediationFocusName?: (focusId: string, findingCount: number) => Promise<void>;
|
|
44
53
|
/**
|
|
45
54
|
* Create or find an entity node representing the vulnerable surface
|
|
46
55
|
* (one per identifier per focus, deduplicated server-side).
|
|
@@ -91,6 +100,8 @@ export interface AutoInjectDeps {
|
|
|
91
100
|
}
|
|
92
101
|
export interface ProcessNewFindingResult {
|
|
93
102
|
status: 'injected' | 'skipped_already_linked';
|
|
103
|
+
/** Focus the finding was injected into (set when status === 'injected'). */
|
|
104
|
+
focusId?: string;
|
|
94
105
|
injectionNodeId?: string;
|
|
95
106
|
deliveryId?: string;
|
|
96
107
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security-auto-inject.d.ts","sourceRoot":"","sources":["../src/security-auto-inject.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"security-auto-inject.d.ts","sourceRoot":"","sources":["../src/security-auto-inject.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Every open finding that the engine sees -- newly observed or with no
|
|
5
5
|
* linked remediation -- is handed to processNewFinding. The function:
|
|
6
|
-
* 1.
|
|
6
|
+
* 1. Creates a fresh Security remediation focus + tree (per-scan-run
|
|
7
|
+
* memoization in security-scan-engine batches findings into one focus).
|
|
7
8
|
* 2. Creates or reuses an entity node representing the vulnerable surface.
|
|
8
9
|
* 3. Creates an injection node on the focus's reality tree with
|
|
9
10
|
* statement = advisory summary; targets the entity node via a
|
|
@@ -39,7 +40,7 @@ function buildEntityLabel(finding) {
|
|
|
39
40
|
export async function processNewFinding(finding, _options, deps) {
|
|
40
41
|
if (finding.linkedInjectionId)
|
|
41
42
|
return { status: 'skipped_already_linked' };
|
|
42
|
-
const focus = await deps.
|
|
43
|
+
const focus = await deps.createSecurityRemediationFocus(finding.productId, finding.organizationId);
|
|
43
44
|
const entity = await deps.upsertEntityNode({
|
|
44
45
|
treeId: focus.treeId,
|
|
45
46
|
organizationId: finding.organizationId,
|
|
@@ -80,6 +81,7 @@ export async function processNewFinding(finding, _options, deps) {
|
|
|
80
81
|
});
|
|
81
82
|
return {
|
|
82
83
|
status: 'injected',
|
|
84
|
+
focusId: focus.focusId,
|
|
83
85
|
injectionNodeId: injection.nodeId,
|
|
84
86
|
deliveryId: delivery.deliveryId,
|
|
85
87
|
};
|
|
@@ -89,8 +91,14 @@ export async function processNewFinding(finding, _options, deps) {
|
|
|
89
91
|
// ---------------------------------------------------------------------------
|
|
90
92
|
export function buildDefaultAutoInjectDeps() {
|
|
91
93
|
return {
|
|
92
|
-
|
|
93
|
-
return callApi('
|
|
94
|
+
createSecurityRemediationFocus: async (productId, organizationId) => {
|
|
95
|
+
return callApi('daemon_create_security_remediation_focus', { productId, organizationId });
|
|
96
|
+
},
|
|
97
|
+
finalizeSecurityRemediationFocusName: async (focusId, findingCount) => {
|
|
98
|
+
await callApi('daemon_finalize_security_remediation_focus_name', {
|
|
99
|
+
focusId,
|
|
100
|
+
findingCount,
|
|
101
|
+
});
|
|
94
102
|
},
|
|
95
103
|
upsertEntityNode: async (input) => {
|
|
96
104
|
return callApi('daemon_upsert_security_entity_node', input);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security-auto-inject.js","sourceRoot":"","sources":["../src/security-auto-inject.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"security-auto-inject.js","sourceRoot":"","sources":["../src/security-auto-inject.ts"],"names":[],"mappings":"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"}
|
|
@@ -116,8 +116,16 @@ export interface SecurityScanDeps {
|
|
|
116
116
|
*
|
|
117
117
|
* Failure semantics: if the first call throws, the cached promise is
|
|
118
118
|
* discarded so the next finding retries the create.
|
|
119
|
+
*
|
|
120
|
+
* Also exposes a `peekFocusId()` accessor so the engine can finalize the
|
|
121
|
+
* focus name (appending the finding count) once the scan loop completes.
|
|
119
122
|
*/
|
|
120
|
-
export
|
|
123
|
+
export interface ScanRunAutoInject {
|
|
124
|
+
deps: AutoInjectDeps;
|
|
125
|
+
/** focusId of the memoized focus, or null if no focus was created. */
|
|
126
|
+
peekFocusId(): string | null;
|
|
127
|
+
}
|
|
128
|
+
export declare function wrapAutoInjectForScanRun(inner: AutoInjectDeps | undefined): ScanRunAutoInject | undefined;
|
|
121
129
|
export declare function runScanForConfig(config: ScanConfig, trigger: 'schedule' | 'manual', deps: SecurityScanDeps): Promise<void>;
|
|
122
130
|
export declare function runSecurityScanTick(deps: SecurityScanDeps, opts?: DueScanConfigsOptions): Promise<void>;
|
|
123
131
|
export declare function buildDefaultSecurityScanDeps(config: DaemonConfig): SecurityScanDeps;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security-scan-engine.d.ts","sourceRoot":"","sources":["../src/security-scan-engine.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"security-scan-engine.d.ts","sourceRoot":"","sources":["../src/security-scan-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -34,23 +34,19 @@ export function registerScanner(scanner) {
|
|
|
34
34
|
export function getRegisteredScanners() {
|
|
35
35
|
return [...DEFAULT_REGISTRY.values()];
|
|
36
36
|
}
|
|
37
|
-
/**
|
|
38
|
-
* Memoize the focus + tree id within one scan-run. The server handler always
|
|
39
|
-
* creates a new focus; without this wrapper, every finding would land in its
|
|
40
|
-
* own focus. Returns undefined when no auto-inject is configured.
|
|
41
|
-
*
|
|
42
|
-
* Failure semantics: if the first call throws, the cached promise is
|
|
43
|
-
* discarded so the next finding retries the create.
|
|
44
|
-
*/
|
|
45
37
|
export function wrapAutoInjectForScanRun(inner) {
|
|
46
38
|
if (!inner)
|
|
47
39
|
return undefined;
|
|
48
40
|
let cachedPromise = null;
|
|
49
|
-
|
|
41
|
+
let resolvedFocusId = null;
|
|
42
|
+
const wrapped = {
|
|
50
43
|
...inner,
|
|
51
|
-
|
|
44
|
+
createSecurityRemediationFocus: (productId, organizationId) => {
|
|
52
45
|
if (!cachedPromise) {
|
|
53
|
-
cachedPromise = inner.
|
|
46
|
+
cachedPromise = inner.createSecurityRemediationFocus(productId, organizationId).then((result) => {
|
|
47
|
+
resolvedFocusId = result.focusId;
|
|
48
|
+
return result;
|
|
49
|
+
}, (err) => {
|
|
54
50
|
cachedPromise = null;
|
|
55
51
|
throw err;
|
|
56
52
|
});
|
|
@@ -58,6 +54,10 @@ export function wrapAutoInjectForScanRun(inner) {
|
|
|
58
54
|
return cachedPromise;
|
|
59
55
|
},
|
|
60
56
|
};
|
|
57
|
+
return {
|
|
58
|
+
deps: wrapped,
|
|
59
|
+
peekFocusId: () => resolvedFocusId,
|
|
60
|
+
};
|
|
61
61
|
}
|
|
62
62
|
export async function runScanForConfig(config, trigger, deps) {
|
|
63
63
|
// Manual triggers carry the "Refresh feeds" intent: flush the OSV/GHSA
|
|
@@ -73,6 +73,7 @@ export async function runScanForConfig(config, trigger, deps) {
|
|
|
73
73
|
// subsequent finding shares the same focus. Next scan run gets a fresh
|
|
74
74
|
// closure -> fresh focus = fresh batch.
|
|
75
75
|
const scanScopedAutoInject = wrapAutoInjectForScanRun(deps.autoInjectDeps);
|
|
76
|
+
let injectedCount = 0;
|
|
76
77
|
const enabledScanners = deps.scanners.filter((s) => config.enabledIocClasses.includes(s.iocClass));
|
|
77
78
|
// Per-class observed identifier sets for re-scan resolution. Only
|
|
78
79
|
// classes whose scanner ran without error contribute -- a failed
|
|
@@ -106,7 +107,10 @@ export async function runScanForConfig(config, trigger, deps) {
|
|
|
106
107
|
status: upsert.status,
|
|
107
108
|
linkedInjectionId: upsert.linkedInjectionId,
|
|
108
109
|
};
|
|
109
|
-
await processNewFinding(forInjection, {}, scanScopedAutoInject);
|
|
110
|
+
const injectResult = await processNewFinding(forInjection, {}, scanScopedAutoInject.deps);
|
|
111
|
+
if (injectResult.status === 'injected') {
|
|
112
|
+
injectedCount++;
|
|
113
|
+
}
|
|
110
114
|
}
|
|
111
115
|
catch (err) {
|
|
112
116
|
console.warn(`[security-scan-engine] auto-inject ${finding.identifier}:`, err.message);
|
|
@@ -131,6 +135,21 @@ export async function runScanForConfig(config, trigger, deps) {
|
|
|
131
135
|
console.warn('[security-scan-engine] resolution sweep failed:', err.message);
|
|
132
136
|
}
|
|
133
137
|
}
|
|
138
|
+
// Finalize the security remediation focus name with the batch finding count
|
|
139
|
+
// so dashboard names like "Security Remediation 2026-05-21 19:44 UTC" become
|
|
140
|
+
// "... (3 findings)". Best-effort -- no-op when no focus was created or the
|
|
141
|
+
// dep is not wired (tests).
|
|
142
|
+
if (scanScopedAutoInject && injectedCount > 0) {
|
|
143
|
+
const focusId = scanScopedAutoInject.peekFocusId();
|
|
144
|
+
if (focusId && deps.autoInjectDeps?.finalizeSecurityRemediationFocusName) {
|
|
145
|
+
try {
|
|
146
|
+
await deps.autoInjectDeps.finalizeSecurityRemediationFocusName(focusId, injectedCount);
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
console.warn('[security-scan-engine] finalizeSecurityRemediationFocusName failed:', err.message);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
134
153
|
// Stamp config.last_run_at so cadence recomputes.
|
|
135
154
|
try {
|
|
136
155
|
await deps.updateConfigLastRun(config.id);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security-scan-engine.js","sourceRoot":"","sources":["../src/security-scan-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EACL,0BAA0B,EAC1B,iBAAiB,GAGlB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,oBAAoB,EACpB,0BAA0B,GAG3B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAiDjD,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E;AAE9E,MAAM,gBAAgB,GAAyB,IAAI,GAAG,EAAE,CAAC;AAEzD,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAC;AACxC,CAAC;
|
|
1
|
+
{"version":3,"file":"security-scan-engine.js","sourceRoot":"","sources":["../src/security-scan-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EACL,0BAA0B,EAC1B,iBAAiB,GAGlB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,oBAAoB,EACpB,0BAA0B,GAG3B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAiDjD,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E;AAE9E,MAAM,gBAAgB,GAAyB,IAAI,GAAG,EAAE,CAAC;AAEzD,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAC;AACxC,CAAC;AA+ED,MAAM,UAAU,wBAAwB,CACtC,KAAiC;IAEjC,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,IAAI,aAAa,GAAwD,IAAI,CAAC;IAC9E,IAAI,eAAe,GAAkB,IAAI,CAAC;IAC1C,MAAM,OAAO,GAAmB;QAC9B,GAAG,KAAK;QACR,8BAA8B,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,EAAE;YAC5D,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,aAAa,GAAG,KAAK,CAAC,8BAA8B,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,IAAI,CAClF,CAAC,MAAM,EAAE,EAAE;oBACT,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC;oBACjC,OAAO,MAAM,CAAC;gBAChB,CAAC,EACD,CAAC,GAAG,EAAE,EAAE;oBACN,aAAa,GAAG,IAAI,CAAC;oBACrB,MAAM,GAAG,CAAC;gBACZ,CAAC,CACF,CAAC;YACJ,CAAC;YACD,OAAO,aAAa,CAAC;QACvB,CAAC;KACF,CAAC;IACF,OAAO;QACL,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,GAAG,EAAE,CAAC,eAAe;KACnC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAkB,EAClB,OAA8B,EAC9B,IAAsB;IAEtB,uEAAuE;IACvE,yEAAyE;IACzE,oEAAoE;IACpE,8CAA8C;IAC9C,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED,0EAA0E;IAC1E,0EAA0E;IAC1E,0EAA0E;IAC1E,uEAAuE;IACvE,wCAAwC;IACxC,MAAM,oBAAoB,GAAG,wBAAwB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC3E,IAAI,aAAa,GAAG,CAAC,CAAC;IAEtB,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEnG,kEAAkE;IAClE,iEAAiE;IACjE,8CAA8C;IAC9C,MAAM,eAAe,GAAG,IAAI,GAAG,EAAuB,CAAC;IACvD,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;QACtC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;gBAChC,MAAM;gBACN,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC;aAC5C,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;YACnC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CACrC,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,cAAc,EACrB,OAAO,CACR,CAAC;gBACF,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBAEjC,4BAA4B;gBAC5B,mCAAmC;gBACnC,iEAAiE;gBACjE,8CAA8C;gBAC9C,MAAM,eAAe,GACnB,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,IAAI,MAAM,CAAC,iBAAiB,KAAK,IAAI,CAAC,CAAC;gBACnF,IAAI,oBAAoB,IAAI,eAAe,EAAE,CAAC;oBAC5C,IAAI,CAAC;wBACH,MAAM,YAAY,GAAwB;4BACxC,EAAE,EAAE,MAAM,CAAC,SAAS;4BACpB,cAAc,EAAE,MAAM,CAAC,cAAc;4BACrC,SAAS,EAAE,MAAM,CAAC,SAAS;4BAC3B,QAAQ,EAAE,OAAO,CAAC,QAAQ;4BAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;4BAC1B,UAAU,EAAE,OAAO,CAAC,UAAU;4BAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;4BACxB,MAAM,EAAE,MAAM,CAAC,MAAM;4BACrB,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;yBAC5C,CAAC;wBACF,MAAM,YAAY,GAAG,MAAM,iBAAiB,CAAC,YAAY,EAAE,EAAE,EAAE,oBAAoB,CAAC,IAAI,CAAC,CAAC;wBAC1F,IAAI,YAAY,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;4BACvC,aAAa,EAAE,CAAC;wBAClB,CAAC;oBACH,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,OAAO,CAAC,IAAI,CACV,sCAAsC,OAAO,CAAC,UAAU,GAAG,EAC1D,GAAa,CAAC,OAAO,CACvB,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;YACD,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CACV,kCAAkC,OAAO,CAAC,QAAQ,UAAU,EAC3D,GAAa,CAAC,OAAO,CACvB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,+DAA+D;IAC/D,iEAAiE;IACjE,sDAAsD;IACtD,IAAI,IAAI,CAAC,cAAc,IAAI,eAAe,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACpD,IAAI,CAAC;YACH,MAAM,YAAY,GAAwB,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CACjF,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CACzD,CAAC;YACF,MAAM,oBAAoB,CAAC,MAAM,CAAC,SAAS,EAAE,YAAY,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAClF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,iDAAiD,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;QAC1F,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,6EAA6E;IAC7E,4EAA4E;IAC5E,4BAA4B;IAC5B,IAAI,oBAAoB,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,oBAAoB,CAAC,WAAW,EAAE,CAAC;QACnD,IAAI,OAAO,IAAI,IAAI,CAAC,cAAc,EAAE,oCAAoC,EAAE,CAAC;YACzE,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,cAAc,CAAC,oCAAoC,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YACzF,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,IAAI,CACV,qEAAqE,EACpE,GAAa,CAAC,OAAO,CACvB,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,kDAAkD;IAClD,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,oDAAoD,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;IAC7F,CAAC;IAED,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,MAAM,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,2DAA2D;AAC3D,8EAA8E;AAE9E,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAsB,EACtB,OAA8B,EAAE;IAEhC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACnD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,SAAS;QAC9B,MAAM,OAAO,GAA0B,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;QAC3F,IAAI,CAAC;YACH,MAAM,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,+DAA+D;YAC/D,kDAAkD;QACpD,CAAC;IACH,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,iDAAiD;AACjD,8EAA8E;AAE9E,MAAM,UAAU,4BAA4B,CAAC,MAAoB;IAC/D,MAAM,UAAU,GAAG,CAAC,SAAiB,EAAU,EAAE;QAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;QAChE,IAAI,CAAC,OAAO;YAAE,OAAO,MAAM,CAAC,QAAQ,CAAC;QACrC,OAAO,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC;IACpD,CAAC,CAAC;IAEF,OAAO;QACL,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YAChC,MAAM,GAAG,GAAG,MAAM,OAAO,CACvB,sCAAsC,EACtC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAC7C,CAAC;YACF,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;QACzB,CAAC;QACD,aAAa,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,EAAE;YAC1D,MAAM,GAAG,GAAG,MAAM,OAAO,CAAsB,gCAAgC,EAAE;gBAC/E,SAAS;gBACT,cAAc;gBACd,GAAG,OAAO;aACX,CAAC,CAAC;YACH,OAAO,GAAG,CAAC;QACb,CAAC;QACD,mBAAmB,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;YACtC,MAAM,OAAO,CAAC,oCAAoC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QACpE,CAAC;QACD,qBAAqB,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;YACxC,MAAM,OAAO,CAAC,kCAAkC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QAClE,CAAC;QACD,UAAU;QACV,eAAe,EAAE,GAAG,EAAE;YACpB,aAAa,EAAE,CAAC;YAChB,cAAc,EAAE,CAAC;QACnB,CAAC;QACD,QAAQ,EAAE,qBAAqB,EAAE;QACjC,cAAc,EAAE,0BAA0B,EAAE;QAC5C,cAAc,EAAE,0BAA0B,EAAE;KAC7C,CAAC;AACJ,CAAC"}
|
package/dist/stage-classifier.js
CHANGED
|
@@ -29,10 +29,10 @@ export function isCascadable(stage) {
|
|
|
29
29
|
if (stage.is_terminal)
|
|
30
30
|
return true;
|
|
31
31
|
// Non-terminal, non-actionable, non-blocking active stages are cascadable
|
|
32
|
-
// (verify,
|
|
32
|
+
// (verify, verify_failed)
|
|
33
33
|
return !isAgentActionable(stage) && !isBlocking(stage);
|
|
34
34
|
}
|
|
35
|
-
return ['verify', '
|
|
35
|
+
return ['verify', 'done', 'cancelled'].includes(stage.name);
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
38
|
* Blocks subsequent ranked deliveries from being picked up.
|
|
@@ -52,7 +52,7 @@ export function isBlocking(stage) {
|
|
|
52
52
|
return true;
|
|
53
53
|
return false;
|
|
54
54
|
}
|
|
55
|
-
return !['done', 'cancelled', 'verify', '
|
|
55
|
+
return !['done', 'cancelled', 'verify', 'verify_failed'].includes(stage.name);
|
|
56
56
|
}
|
|
57
57
|
/** Excluded from cascade checks entirely (cancelled but not done). */
|
|
58
58
|
export function isExcludedFromCascade(stage) {
|
|
@@ -86,7 +86,7 @@ export function isStatusCascadable(status, workflow) {
|
|
|
86
86
|
if (stage)
|
|
87
87
|
return isCascadable(stage);
|
|
88
88
|
}
|
|
89
|
-
return ['verify', '
|
|
89
|
+
return ['verify', 'done', 'cancelled'].includes(status);
|
|
90
90
|
}
|
|
91
91
|
export function isStatusBlocking(status, workflow) {
|
|
92
92
|
if (workflow) {
|
|
@@ -94,7 +94,7 @@ export function isStatusBlocking(status, workflow) {
|
|
|
94
94
|
if (stage)
|
|
95
95
|
return isBlocking(stage);
|
|
96
96
|
}
|
|
97
|
-
return !['done', 'cancelled', 'verify', '
|
|
97
|
+
return !['done', 'cancelled', 'verify', 'verify_failed'].includes(status);
|
|
98
98
|
}
|
|
99
99
|
export function isStatusExcludedFromCascade(status, workflow) {
|
|
100
100
|
if (workflow) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stage-classifier.js","sourceRoot":"","sources":["../src/stage-classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,oEAAoE;AAEpE,mFAAmF;AACnF,MAAM,UAAU,iBAAiB,CAAC,KAAoB;IACpD,IAAI,KAAK,CAAC,mBAAmB,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,mBAAmB,CAAC;IAC9E,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,CAAC;AAC9F,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,UAAU,CAAC,KAAoB;IAC7C,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,WAAW,CAAC;IAC9D,OAAO,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAoB;IAC/C,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACpC,wCAAwC;QACxC,IAAI,KAAK,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC;QACnC,0EAA0E;QAC1E,
|
|
1
|
+
{"version":3,"file":"stage-classifier.js","sourceRoot":"","sources":["../src/stage-classifier.ts"],"names":[],"mappings":"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"}
|
package/dist/state-cascade.d.ts
CHANGED
|
@@ -5,16 +5,17 @@
|
|
|
5
5
|
* aggregate via deriveFocusPhase). Two behaviors live here:
|
|
6
6
|
*
|
|
7
7
|
* 1. Auto-review: phase === 'verifying' + pipelineConfig.review.enabled
|
|
8
|
-
* -> set review_requested_at
|
|
9
|
-
*
|
|
10
|
-
* syncFocusPhase poll
|
|
8
|
+
* -> set review_requested_at. Deliveries stay in `verify`
|
|
9
|
+
* throughout the review window. The phase will become 'reviewing'
|
|
10
|
+
* on the next syncFocusPhase poll because phase derivation reads
|
|
11
|
+
* `review_requested_at + verify > 0`.
|
|
11
12
|
*
|
|
12
13
|
* 2. Stale review clearing: review_requested_at set but a delivery has
|
|
13
14
|
* regressed back to active work -> clear review_requested_at so the
|
|
14
15
|
* user can request a fresh review when verify is reached again.
|
|
15
16
|
*
|
|
16
17
|
* Review completion is NOT auto-routed here. Closing out a review and
|
|
17
|
-
* routing
|
|
18
|
+
* routing verify deliveries to done/verify_failed is the exclusive
|
|
18
19
|
* responsibility of focus-completion.ts's review exit handler, which
|
|
19
20
|
* gates on the exiting team's sessionType === 'review' (a positive
|
|
20
21
|
* signal that an actual review ran). If the review team never spawns
|
|
@@ -26,7 +27,7 @@
|
|
|
26
27
|
* phase regression are handled by syncFocusPhase in directive-executor.ts;
|
|
27
28
|
* they no longer live here.
|
|
28
29
|
*/
|
|
29
|
-
import type { DaemonConfig, PipelineConfig
|
|
30
|
+
import type { DaemonConfig, PipelineConfig } from './types.js';
|
|
30
31
|
import type { FocusDeliveryInfo } from './types.js';
|
|
31
32
|
import { type FocusExecutionPhase } from './focus-phase.js';
|
|
32
33
|
/** Injectable dependencies for cascade functions (testing). */
|
|
@@ -34,15 +35,13 @@ export interface CascadeDeps {
|
|
|
34
35
|
getFocusDeliveries: (focusId: string) => Promise<FocusDeliveryInfo[]>;
|
|
35
36
|
setReviewRequestedAt: (focusId: string, isoTimestamp: string) => Promise<void>;
|
|
36
37
|
clearReviewRequestedAt: (focusId: string) => Promise<void>;
|
|
37
|
-
fetchEffectiveWorkflow: (deliveryId: string) => Promise<Workflow>;
|
|
38
|
-
updateDeliveryStatus: (deliveryId: string, status: string, stageId?: string | null) => Promise<void>;
|
|
39
38
|
}
|
|
40
39
|
/**
|
|
41
40
|
* When a focus reaches the verifying phase and pipelineConfig.review is
|
|
42
|
-
* enabled, set review_requested_at
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* directive.
|
|
41
|
+
* enabled, set review_requested_at. Deliveries stay in `verify` throughout
|
|
42
|
+
* the review window -- there is no separate in-review delivery state. The
|
|
43
|
+
* phase derivation picks up `review_requested_at + verify > 0` on the next
|
|
44
|
+
* poll and emits phase = 'reviewing', firing the reviewing-stage directive.
|
|
46
45
|
*/
|
|
47
46
|
export declare function checkAutoReview(focusId: string, phase: FocusExecutionPhase, pipelineConfig: PipelineConfig | null, reviewRequestedAt: string | null, deliveries: FocusDeliveryInfo[], deps?: CascadeDeps): Promise<void>;
|
|
48
47
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-cascade.d.ts","sourceRoot":"","sources":["../src/state-cascade.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"state-cascade.d.ts","sourceRoot":"","sources":["../src/state-cascade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AASpD,OAAO,EAAoB,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE9E,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACtE,oBAAoB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,sBAAsB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAQD;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,mBAAmB,EAC1B,cAAc,EAAE,cAAc,GAAG,IAAI,EACrC,iBAAiB,EAAE,MAAM,GAAG,IAAI,EAChC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,IAAI,GAAE,WAAyB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,mBAAmB,EAC1B,iBAAiB,EAAE,MAAM,GAAG,IAAI,EAChC,IAAI,GAAE,WAAyB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAsC1E"}
|
package/dist/state-cascade.js
CHANGED
|
@@ -5,16 +5,17 @@
|
|
|
5
5
|
* aggregate via deriveFocusPhase). Two behaviors live here:
|
|
6
6
|
*
|
|
7
7
|
* 1. Auto-review: phase === 'verifying' + pipelineConfig.review.enabled
|
|
8
|
-
* -> set review_requested_at
|
|
9
|
-
*
|
|
10
|
-
* syncFocusPhase poll
|
|
8
|
+
* -> set review_requested_at. Deliveries stay in `verify`
|
|
9
|
+
* throughout the review window. The phase will become 'reviewing'
|
|
10
|
+
* on the next syncFocusPhase poll because phase derivation reads
|
|
11
|
+
* `review_requested_at + verify > 0`.
|
|
11
12
|
*
|
|
12
13
|
* 2. Stale review clearing: review_requested_at set but a delivery has
|
|
13
14
|
* regressed back to active work -> clear review_requested_at so the
|
|
14
15
|
* user can request a fresh review when verify is reached again.
|
|
15
16
|
*
|
|
16
17
|
* Review completion is NOT auto-routed here. Closing out a review and
|
|
17
|
-
* routing
|
|
18
|
+
* routing verify deliveries to done/verify_failed is the exclusive
|
|
18
19
|
* responsibility of focus-completion.ts's review exit handler, which
|
|
19
20
|
* gates on the exiting team's sessionType === 'review' (a positive
|
|
20
21
|
* signal that an actual review ran). If the review team never spawns
|
|
@@ -26,7 +27,7 @@
|
|
|
26
27
|
* phase regression are handled by syncFocusPhase in directive-executor.ts;
|
|
27
28
|
* they no longer live here.
|
|
28
29
|
*/
|
|
29
|
-
import { getActiveFocuses
|
|
30
|
+
import { getActiveFocuses } from './supabase.js';
|
|
30
31
|
import { getFocusDeliveries as _getFocusDeliveries, setReviewRequestedAt as _setReviewRequestedAt, clearReviewRequestedAt as _clearReviewRequestedAt, } from './queries/focuses.js';
|
|
31
32
|
import { configForProduct } from './config.js';
|
|
32
33
|
import { emitLoopTrigger } from './loop-event-bus.js';
|
|
@@ -35,15 +36,13 @@ const defaultDeps = {
|
|
|
35
36
|
getFocusDeliveries: _getFocusDeliveries,
|
|
36
37
|
setReviewRequestedAt: _setReviewRequestedAt,
|
|
37
38
|
clearReviewRequestedAt: _clearReviewRequestedAt,
|
|
38
|
-
fetchEffectiveWorkflow: _fetchEffectiveWorkflow,
|
|
39
|
-
updateDeliveryStatus: _updateDeliveryStatus,
|
|
40
39
|
};
|
|
41
40
|
/**
|
|
42
41
|
* When a focus reaches the verifying phase and pipelineConfig.review is
|
|
43
|
-
* enabled, set review_requested_at
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* directive.
|
|
42
|
+
* enabled, set review_requested_at. Deliveries stay in `verify` throughout
|
|
43
|
+
* the review window -- there is no separate in-review delivery state. The
|
|
44
|
+
* phase derivation picks up `review_requested_at + verify > 0` on the next
|
|
45
|
+
* poll and emits phase = 'reviewing', firing the reviewing-stage directive.
|
|
47
46
|
*/
|
|
48
47
|
export async function checkAutoReview(focusId, phase, pipelineConfig, reviewRequestedAt, deliveries, deps = defaultDeps) {
|
|
49
48
|
if (phase !== 'verifying')
|
|
@@ -57,18 +56,9 @@ export async function checkAutoReview(focusId, phase, pipelineConfig, reviewRequ
|
|
|
57
56
|
return;
|
|
58
57
|
try {
|
|
59
58
|
await deps.setReviewRequestedAt(focusId, new Date().toISOString());
|
|
60
|
-
for (const d of verifyDeliveries) {
|
|
61
|
-
try {
|
|
62
|
-
const dWorkflow = await deps.fetchEffectiveWorkflow(d.id);
|
|
63
|
-
const inReviewStage = dWorkflow.stages.find(s => s.name === 'in_review');
|
|
64
|
-
await deps.updateDeliveryStatus(d.id, 'in_review', inReviewStage?.id ?? null);
|
|
65
|
-
}
|
|
66
|
-
catch (err) {
|
|
67
|
-
console.warn(`[state-cascade] Auto-review: failed to transition delivery "${d.name}":`, err.message);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
59
|
console.log(`[state-cascade] Auto-review triggered for focus ${focusId}: ` +
|
|
71
|
-
`${verifyDeliveries.length} verify deliver${verifyDeliveries.length === 1 ? 'y' : 'ies'}
|
|
60
|
+
`${verifyDeliveries.length} verify deliver${verifyDeliveries.length === 1 ? 'y' : 'ies'} ` +
|
|
61
|
+
`(review_requested_at set; deliveries remain in verify)`);
|
|
72
62
|
emitLoopTrigger({
|
|
73
63
|
type: 'focus_status_changed',
|
|
74
64
|
focusId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-cascade.js","sourceRoot":"","sources":["../src/state-cascade.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"state-cascade.js","sourceRoot":"","sources":["../src/state-cascade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EACL,kBAAkB,IAAI,mBAAmB,EACzC,oBAAoB,IAAI,qBAAqB,EAC7C,sBAAsB,IAAI,uBAAuB,GAClD,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAA4B,MAAM,kBAAkB,CAAC;AAS9E,MAAM,WAAW,GAAgB;IAC/B,kBAAkB,EAAE,mBAAmB;IACvC,oBAAoB,EAAE,qBAAqB;IAC3C,sBAAsB,EAAE,uBAAuB;CAChD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAe,EACf,KAA0B,EAC1B,cAAqC,EACrC,iBAAgC,EAChC,UAA+B,EAC/B,OAAoB,WAAW;IAE/B,IAAI,KAAK,KAAK,WAAW;QAAE,OAAO;IAClC,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO;QAAE,OAAO;IAC7C,IAAI,iBAAiB;QAAE,OAAO;IAE9B,MAAM,gBAAgB,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,KAAK,QAAQ,CAAC,CAAC;IAChF,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAE1C,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;QAEnE,OAAO,CAAC,GAAG,CACT,mDAAmD,OAAO,IAAI;YAC9D,GAAG,gBAAgB,CAAC,MAAM,kBAAkB,gBAAgB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG;YAC1F,wDAAwD,CACzD,CAAC;QAEF,eAAe,CAAC;YACd,IAAI,EAAE,sBAAsB;YAC5B,OAAO;YACP,MAAM,EAAE,iCAAiC,gBAAgB,CAAC,MAAM,cAAc;SAC/E,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CACV,gDAAgD,OAAO,GAAG,EACzD,GAAa,CAAC,OAAO,CACvB,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAAe,EACf,KAA0B,EAC1B,iBAAgC,EAChC,OAAoB,WAAW;IAE/B,IAAI,CAAC,iBAAiB;QAAE,OAAO;IAC/B,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO;IAEtD,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CACT,8DAA8D,OAAO,GAAG;YACxE,uBAAuB,KAAK,GAAG,CAChC,CAAC;QACF,eAAe,CAAC;YACd,IAAI,EAAE,kBAAkB;YACxB,OAAO;YACP,MAAM,EAAE,GAAG,KAAK,wCAAwC;SACzD,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CACV,iEAAiE,OAAO,GAAG,EAC1E,GAAa,CAAC,OAAO,CACvB,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAAoB;IACzD,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACtC,MAAM,EAAE,GAAG,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAE7C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,EAAE,CAAC,cAAc,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;YAEtE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,CAAC;oBACH,MAAM,UAAU,GAAG,MAAM,WAAW,CAAC,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBACxE,MAAM,KAAK,GAAG,gBAAgB,CAAC;wBAC7B,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;wBACzE,iBAAiB,EAAE,KAAK,CAAC,mBAAmB;qBAC7C,CAAC,CAAC;oBAEH,MAAM,eAAe,CACnB,KAAK,CAAC,QAAQ,EACd,KAAK,EACL,KAAK,CAAC,eAAe,EACrB,KAAK,CAAC,mBAAmB,EACzB,UAAU,CACX,CAAC;oBAEF,MAAM,uBAAuB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC;gBAClF,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,IAAI,CACV,iDAAiD,KAAK,CAAC,QAAQ,GAAG,EACjE,GAAa,CAAC,OAAO,CACvB,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CACV,4DAA4D,OAAO,CAAC,EAAE,GAAG,EACxE,GAAa,CAAC,OAAO,CACvB,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
|