@telora/daemon 0.15.36 → 0.15.40
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 +2 -2
- package/dist/assembly-resolvers.d.ts +1 -1
- package/dist/assembly-resolvers.d.ts.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/delivery-lifecycle.d.ts +3 -0
- package/dist/delivery-lifecycle.d.ts.map +1 -1
- package/dist/delivery-lifecycle.js +13 -1
- package/dist/delivery-lifecycle.js.map +1 -1
- package/dist/drift-eval-loop.d.ts +63 -0
- package/dist/drift-eval-loop.d.ts.map +1 -0
- package/dist/drift-eval-loop.js +215 -0
- package/dist/drift-eval-loop.js.map +1 -0
- package/dist/drift-evaluator.d.ts +51 -0
- package/dist/drift-evaluator.d.ts.map +1 -0
- package/dist/drift-evaluator.js +62 -0
- package/dist/drift-evaluator.js.map +1 -0
- package/dist/feeds/ghsa.d.ts +88 -0
- package/dist/feeds/ghsa.d.ts.map +1 -0
- package/dist/feeds/ghsa.js +219 -0
- package/dist/feeds/ghsa.js.map +1 -0
- package/dist/feeds/local.d.ts +55 -0
- package/dist/feeds/local.d.ts.map +1 -0
- package/dist/feeds/local.js +196 -0
- package/dist/feeds/local.js.map +1 -0
- package/dist/feeds/osv.d.ts +89 -0
- package/dist/feeds/osv.d.ts.map +1 -0
- package/dist/feeds/osv.js +266 -0
- package/dist/feeds/osv.js.map +1 -0
- package/dist/focus-completion-event.d.ts +2 -0
- package/dist/focus-completion-event.d.ts.map +1 -1
- package/dist/focus-completion-event.js +51 -13
- package/dist/focus-completion-event.js.map +1 -1
- package/dist/focus-completion.d.ts +1 -1
- package/dist/focus-completion.js +7 -7
- package/dist/focus-completion.js.map +1 -1
- package/dist/focus-engine.d.ts.map +1 -1
- package/dist/focus-engine.js +71 -0
- package/dist/focus-engine.js.map +1 -1
- package/dist/focus-executor.d.ts +53 -0
- package/dist/focus-executor.d.ts.map +1 -1
- package/dist/focus-executor.js +41 -26
- package/dist/focus-executor.js.map +1 -1
- package/dist/focus-loop.d.ts +1 -1
- package/dist/focus-loop.js +2 -2
- package/dist/focus-loop.js.map +1 -1
- package/dist/focus-phase.js +1 -1
- package/dist/focus-phase.js.map +1 -1
- package/dist/focus-prompt-builder.d.ts +1 -1
- package/dist/focus-prompt-builder.js +1 -1
- package/dist/listener-auto-advance.d.ts +3 -3
- package/dist/listener-auto-advance.js +10 -10
- package/dist/listener-auto-advance.js.map +1 -1
- package/dist/listener.js +1 -1
- package/dist/listener.js.map +1 -1
- package/dist/queries/deliveries.d.ts +20 -1
- package/dist/queries/deliveries.d.ts.map +1 -1
- package/dist/queries/deliveries.js +8 -1
- package/dist/queries/deliveries.js.map +1 -1
- package/dist/queries/drift.d.ts +50 -0
- package/dist/queries/drift.d.ts.map +1 -0
- package/dist/queries/drift.js +28 -0
- package/dist/queries/drift.js.map +1 -0
- package/dist/queries/focuses.d.ts.map +1 -1
- package/dist/queries/focuses.js +1 -0
- package/dist/queries/focuses.js.map +1 -1
- package/dist/queries/index.d.ts +2 -0
- package/dist/queries/index.d.ts.map +1 -1
- package/dist/queries/index.js +1 -0
- package/dist/queries/index.js.map +1 -1
- package/dist/queries/schemas.d.ts +2 -0
- package/dist/queries/schemas.d.ts.map +1 -1
- package/dist/queries/schemas.js +1 -0
- package/dist/queries/schemas.js.map +1 -1
- package/dist/scanners/deps.d.ts +101 -0
- package/dist/scanners/deps.d.ts.map +1 -0
- package/dist/scanners/deps.js +242 -0
- package/dist/scanners/deps.js.map +1 -0
- package/dist/scanners/signatures.d.ts +44 -0
- package/dist/scanners/signatures.d.ts.map +1 -0
- package/dist/scanners/signatures.js +140 -0
- package/dist/scanners/signatures.js.map +1 -0
- package/dist/scanners/workflow.d.ts +34 -0
- package/dist/scanners/workflow.d.ts.map +1 -0
- package/dist/scanners/workflow.js +239 -0
- package/dist/scanners/workflow.js.map +1 -0
- package/dist/security-auto-inject.d.ts +114 -0
- package/dist/security-auto-inject.d.ts.map +1 -0
- package/dist/security-auto-inject.js +148 -0
- package/dist/security-auto-inject.js.map +1 -0
- package/dist/security-rescan-resolution.d.ts +84 -0
- package/dist/security-rescan-resolution.d.ts.map +1 -0
- package/dist/security-rescan-resolution.js +114 -0
- package/dist/security-rescan-resolution.js.map +1 -0
- package/dist/security-scan-engine.d.ts +96 -0
- package/dist/security-scan-engine.d.ts.map +1 -0
- package/dist/security-scan-engine.js +189 -0
- package/dist/security-scan-engine.js.map +1 -0
- package/dist/stage-classifier.d.ts +2 -2
- package/dist/stage-classifier.d.ts.map +1 -1
- package/dist/stage-classifier.js +7 -7
- package/dist/stage-classifier.js.map +1 -1
- package/dist/state-cascade.d.ts +1 -1
- package/dist/state-cascade.js +1 -1
- package/dist/team-prompt-base.d.ts.map +1 -1
- package/dist/team-prompt-base.js +15 -0
- package/dist/team-prompt-base.js.map +1 -1
- package/dist/types/focus.d.ts +6 -0
- package/dist/types/focus.d.ts.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-scan resolution: when a scan run completes that covered a finding's
|
|
3
|
+
* IOC class but did not re-produce a previously-open finding, flip the
|
|
4
|
+
* finding to 'resolved' and (if the linked injection's delivery is done)
|
|
5
|
+
* auto-verify the injection.
|
|
6
|
+
*
|
|
7
|
+
* Called by the scanner engine immediately after a run finishes writing
|
|
8
|
+
* its findings, before suppression-expiry sweeps and before the next
|
|
9
|
+
* tick begins.
|
|
10
|
+
*
|
|
11
|
+
* @module security-rescan-resolution
|
|
12
|
+
*/
|
|
13
|
+
import { callApi } from './queries/shared.js';
|
|
14
|
+
/**
|
|
15
|
+
* Resolve previously-open findings that didn't re-appear in this run.
|
|
16
|
+
*
|
|
17
|
+
* @returns the list of finding ids that were flipped to 'resolved'.
|
|
18
|
+
*/
|
|
19
|
+
export async function resolveStaleFindings(productId, observedSets, deps) {
|
|
20
|
+
const iocClasses = observedSets.map((s) => s.iocClass);
|
|
21
|
+
if (iocClasses.length === 0)
|
|
22
|
+
return [];
|
|
23
|
+
const openFindings = await deps.listOpenFindings(productId, iocClasses);
|
|
24
|
+
const observedByClass = new Map();
|
|
25
|
+
for (const set of observedSets) {
|
|
26
|
+
observedByClass.set(set.iocClass, set.identifiers);
|
|
27
|
+
}
|
|
28
|
+
const resolvedIds = [];
|
|
29
|
+
for (const finding of openFindings) {
|
|
30
|
+
const observedInClass = observedByClass.get(finding.iocClass);
|
|
31
|
+
if (!observedInClass)
|
|
32
|
+
continue;
|
|
33
|
+
if (observedInClass.has(finding.identifier))
|
|
34
|
+
continue;
|
|
35
|
+
// Finding was open, its class was covered, but it didn't re-appear.
|
|
36
|
+
await deps.markFindingResolved(finding.id);
|
|
37
|
+
await deps.writeAudit({
|
|
38
|
+
findingId: finding.id,
|
|
39
|
+
organizationId: finding.organizationId,
|
|
40
|
+
action: 'resolved',
|
|
41
|
+
payload: { reason: 'absent_in_rescan', ioc_class: finding.iocClass },
|
|
42
|
+
});
|
|
43
|
+
resolvedIds.push(finding.id);
|
|
44
|
+
// Auto-verify the linked injection if its delivery has reached 'done'.
|
|
45
|
+
if (finding.linkedInjectionId) {
|
|
46
|
+
const status = await deps.getInjectionDeliveryStatus(finding.linkedInjectionId);
|
|
47
|
+
if (status === 'done') {
|
|
48
|
+
await deps.verifyInjection(finding.linkedInjectionId);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return resolvedIds;
|
|
53
|
+
}
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Default Deps -- daemon-side wiring via callApi.
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
export function buildDefaultResolutionDeps() {
|
|
58
|
+
return {
|
|
59
|
+
listOpenFindings: async (productId, iocClasses) => {
|
|
60
|
+
const res = await callApi('daemon_list_open_security_findings', { productId, iocClasses });
|
|
61
|
+
return res.items ?? [];
|
|
62
|
+
},
|
|
63
|
+
markFindingResolved: async (findingId) => {
|
|
64
|
+
await callApi('daemon_resolve_security_finding', { findingId });
|
|
65
|
+
},
|
|
66
|
+
writeAudit: async (input) => {
|
|
67
|
+
await callApi('daemon_write_security_finding_audit', input);
|
|
68
|
+
},
|
|
69
|
+
getInjectionDeliveryStatus: async (injectionNodeId) => {
|
|
70
|
+
const res = await callApi('daemon_get_injection_delivery_status', { injectionNodeId });
|
|
71
|
+
return res.status;
|
|
72
|
+
},
|
|
73
|
+
verifyInjection: async (injectionNodeId) => {
|
|
74
|
+
await callApi('reality_tree_verify_injection', { injectionNodeId });
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Sweep suppressions whose expires_at has passed and flip them back to
|
|
80
|
+
* 'open'. Idempotent: a suppression already expired is a no-op on the
|
|
81
|
+
* second call because the predicate now matches status='open'.
|
|
82
|
+
*
|
|
83
|
+
* @returns the finding ids whose suppression was lifted.
|
|
84
|
+
*/
|
|
85
|
+
export async function runSuppressionExpirySweep(deps) {
|
|
86
|
+
const expired = await deps.listExpiredSuppressions();
|
|
87
|
+
const lifted = [];
|
|
88
|
+
for (const finding of expired) {
|
|
89
|
+
await deps.unsuppressFinding(finding.id);
|
|
90
|
+
await deps.writeAudit({
|
|
91
|
+
findingId: finding.id,
|
|
92
|
+
organizationId: finding.organizationId,
|
|
93
|
+
action: 'unsuppressed',
|
|
94
|
+
payload: { reason: 'suppression_expired' },
|
|
95
|
+
});
|
|
96
|
+
lifted.push(finding.id);
|
|
97
|
+
}
|
|
98
|
+
return lifted;
|
|
99
|
+
}
|
|
100
|
+
export function buildDefaultSuppressionExpirySweepDeps() {
|
|
101
|
+
return {
|
|
102
|
+
listExpiredSuppressions: async () => {
|
|
103
|
+
const res = await callApi('daemon_list_expired_security_suppressions', {});
|
|
104
|
+
return res.items ?? [];
|
|
105
|
+
},
|
|
106
|
+
unsuppressFinding: async (findingId) => {
|
|
107
|
+
await callApi('daemon_unsuppress_security_finding', { findingId });
|
|
108
|
+
},
|
|
109
|
+
writeAudit: async (input) => {
|
|
110
|
+
await callApi('daemon_write_security_finding_audit', input);
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=security-rescan-resolution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-rescan-resolution.js","sourceRoot":"","sources":["../src/security-rescan-resolution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security scan engine.
|
|
3
|
+
*
|
|
4
|
+
* Polls security_scan_configs for due scans (cron-due or manual_run_requested_at
|
|
5
|
+
* set), dispatches pluggable Scanner implementations per IOC class, writes
|
|
6
|
+
* one security_scan_runs row plus N security_findings rows per execution,
|
|
7
|
+
* and (downstream) hands findings to security-auto-inject for severity-gated
|
|
8
|
+
* injection materialization.
|
|
9
|
+
*
|
|
10
|
+
* Activation: gated by shouldRunLoop('TELORA_SECURITY_SCAN_LOOP') in
|
|
11
|
+
* unified-shell.ts. Opt-out semantics match the other daemon loop ticks
|
|
12
|
+
* (unset/anything-but-'0' = enabled, '0' = disabled). See
|
|
13
|
+
* docs/runbook-loop-activation.md.
|
|
14
|
+
*
|
|
15
|
+
* Pattern reference: verification-engine.ts (pluggable strategies + Deps).
|
|
16
|
+
*
|
|
17
|
+
* @module security-scan-engine
|
|
18
|
+
*/
|
|
19
|
+
import type { DaemonConfig } from './types.js';
|
|
20
|
+
import { type AutoInjectDeps } from './security-auto-inject.js';
|
|
21
|
+
import { type ResolutionDeps } from './security-rescan-resolution.js';
|
|
22
|
+
export type Severity = 'low' | 'medium' | 'high' | 'critical';
|
|
23
|
+
/** Configuration row driving an individual product's scan cadence. */
|
|
24
|
+
export interface ScanConfig {
|
|
25
|
+
id: string;
|
|
26
|
+
organizationId: string;
|
|
27
|
+
productId: string;
|
|
28
|
+
scheduleCron: string;
|
|
29
|
+
enabledIocClasses: string[];
|
|
30
|
+
autoInjectSeverityThreshold: Severity;
|
|
31
|
+
enabled: boolean;
|
|
32
|
+
manualRunRequestedAt: string | null;
|
|
33
|
+
lastRunAt: string | null;
|
|
34
|
+
}
|
|
35
|
+
/** Per-scan context passed to each Scanner. */
|
|
36
|
+
export interface ScanContext {
|
|
37
|
+
config: ScanConfig;
|
|
38
|
+
repoPath: string;
|
|
39
|
+
}
|
|
40
|
+
/** Single finding draft emitted by a Scanner. Stored in security_findings. */
|
|
41
|
+
export interface FindingDraft {
|
|
42
|
+
iocClass: string;
|
|
43
|
+
severity: Severity;
|
|
44
|
+
identifier: string;
|
|
45
|
+
payload: Record<string, unknown>;
|
|
46
|
+
}
|
|
47
|
+
/** Per-scanner output for a single scan run. */
|
|
48
|
+
export interface ScanResult {
|
|
49
|
+
findings: FindingDraft[];
|
|
50
|
+
/** Coverage breadcrumb (e.g. packages_audited, files_scanned) + any warnings. */
|
|
51
|
+
coverage: Record<string, unknown>;
|
|
52
|
+
}
|
|
53
|
+
/** Pluggable Scanner contract -- one per IOC class. */
|
|
54
|
+
export interface Scanner {
|
|
55
|
+
/** IOC class slug, matched against ScanConfig.enabledIocClasses. */
|
|
56
|
+
iocClass: string;
|
|
57
|
+
scan(ctx: ScanContext): Promise<ScanResult>;
|
|
58
|
+
}
|
|
59
|
+
export declare function registerScanner(scanner: Scanner): void;
|
|
60
|
+
export declare function getRegisteredScanners(): Scanner[];
|
|
61
|
+
export interface SecurityScanDeps {
|
|
62
|
+
getDueScanConfigs: () => Promise<ScanConfig[]>;
|
|
63
|
+
startRun: (configId: string, trigger: 'schedule' | 'manual') => Promise<string>;
|
|
64
|
+
finishRun: (runId: string, update: {
|
|
65
|
+
status: 'succeeded' | 'failed' | 'partial';
|
|
66
|
+
coverageSummary: Record<string, unknown>;
|
|
67
|
+
findingsCountBySeverity: Record<Severity, number>;
|
|
68
|
+
durationMs: number;
|
|
69
|
+
}) => Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Persist a finding and return its DB-assigned id so downstream
|
|
72
|
+
* hooks (auto-injection, resolution) can reference it.
|
|
73
|
+
*/
|
|
74
|
+
writeFinding: (runId: string, productId: string, organizationId: string, finding: FindingDraft) => Promise<{
|
|
75
|
+
findingId: string;
|
|
76
|
+
}>;
|
|
77
|
+
clearManualRunRequest: (configId: string) => Promise<void>;
|
|
78
|
+
resolveCwd: (productId: string) => string;
|
|
79
|
+
scanners: Scanner[];
|
|
80
|
+
/**
|
|
81
|
+
* Optional severity-gated auto-injection hook. When set, each newly
|
|
82
|
+
* written finding is passed to processNewFinding so the daemon can
|
|
83
|
+
* materialize a remediation injection + delivery for it.
|
|
84
|
+
*/
|
|
85
|
+
autoInjectDeps?: AutoInjectDeps;
|
|
86
|
+
/**
|
|
87
|
+
* Optional re-scan resolution hook. When set, after every scan run
|
|
88
|
+
* finishes, the engine asks the resolution module to flip previously
|
|
89
|
+
* open findings whose identifiers did not re-appear to 'resolved'.
|
|
90
|
+
*/
|
|
91
|
+
resolutionDeps?: ResolutionDeps;
|
|
92
|
+
}
|
|
93
|
+
export declare function runScanForConfig(config: ScanConfig, trigger: 'schedule' | 'manual', deps: SecurityScanDeps): Promise<void>;
|
|
94
|
+
export declare function runSecurityScanTick(deps: SecurityScanDeps): Promise<void>;
|
|
95
|
+
export declare function buildDefaultSecurityScanDeps(config: DaemonConfig): SecurityScanDeps;
|
|
96
|
+
//# sourceMappingURL=security-scan-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-scan-engine.d.ts","sourceRoot":"","sources":["../src/security-scan-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security scan engine.
|
|
3
|
+
*
|
|
4
|
+
* Polls security_scan_configs for due scans (cron-due or manual_run_requested_at
|
|
5
|
+
* set), dispatches pluggable Scanner implementations per IOC class, writes
|
|
6
|
+
* one security_scan_runs row plus N security_findings rows per execution,
|
|
7
|
+
* and (downstream) hands findings to security-auto-inject for severity-gated
|
|
8
|
+
* injection materialization.
|
|
9
|
+
*
|
|
10
|
+
* Activation: gated by shouldRunLoop('TELORA_SECURITY_SCAN_LOOP') in
|
|
11
|
+
* unified-shell.ts. Opt-out semantics match the other daemon loop ticks
|
|
12
|
+
* (unset/anything-but-'0' = enabled, '0' = disabled). See
|
|
13
|
+
* docs/runbook-loop-activation.md.
|
|
14
|
+
*
|
|
15
|
+
* Pattern reference: verification-engine.ts (pluggable strategies + Deps).
|
|
16
|
+
*
|
|
17
|
+
* @module security-scan-engine
|
|
18
|
+
*/
|
|
19
|
+
import { callApi } from './queries/shared.js';
|
|
20
|
+
import { configForProduct } from './config.js';
|
|
21
|
+
import { buildDefaultAutoInjectDeps, processNewFinding, } from './security-auto-inject.js';
|
|
22
|
+
import { resolveStaleFindings, buildDefaultResolutionDeps, } from './security-rescan-resolution.js';
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Default registry -- scanners self-register here in their own modules
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
const DEFAULT_REGISTRY = new Map();
|
|
27
|
+
export function registerScanner(scanner) {
|
|
28
|
+
DEFAULT_REGISTRY.set(scanner.iocClass, scanner);
|
|
29
|
+
}
|
|
30
|
+
export function getRegisteredScanners() {
|
|
31
|
+
return [...DEFAULT_REGISTRY.values()];
|
|
32
|
+
}
|
|
33
|
+
export async function runScanForConfig(config, trigger, deps) {
|
|
34
|
+
const runId = await deps.startRun(config.id, trigger);
|
|
35
|
+
const startedAt = Date.now();
|
|
36
|
+
const coverage = {};
|
|
37
|
+
const warnings = [];
|
|
38
|
+
const counts = { low: 0, medium: 0, high: 0, critical: 0 };
|
|
39
|
+
let anyFailure = false;
|
|
40
|
+
let anySuccess = false;
|
|
41
|
+
const enabledScanners = deps.scanners.filter((s) => config.enabledIocClasses.includes(s.iocClass));
|
|
42
|
+
// Per-class observed identifier sets for re-scan resolution. Only
|
|
43
|
+
// classes whose scanner ran without error contribute -- a failed
|
|
44
|
+
// scanner can't claim coverage for its class.
|
|
45
|
+
const observedByClass = new Map();
|
|
46
|
+
for (const scanner of enabledScanners) {
|
|
47
|
+
try {
|
|
48
|
+
const result = await scanner.scan({
|
|
49
|
+
config,
|
|
50
|
+
repoPath: deps.resolveCwd(config.productId),
|
|
51
|
+
});
|
|
52
|
+
coverage[scanner.iocClass] = result.coverage;
|
|
53
|
+
anySuccess = true;
|
|
54
|
+
const observed = new Set();
|
|
55
|
+
for (const finding of result.findings) {
|
|
56
|
+
const { findingId } = await deps.writeFinding(runId, config.productId, config.organizationId, finding);
|
|
57
|
+
counts[finding.severity] = (counts[finding.severity] ?? 0) + 1;
|
|
58
|
+
observed.add(finding.identifier);
|
|
59
|
+
// Severity-gated auto-injection. Run per-finding so a failing
|
|
60
|
+
// injection for one finding does not block the others.
|
|
61
|
+
if (deps.autoInjectDeps) {
|
|
62
|
+
try {
|
|
63
|
+
const forInjection = {
|
|
64
|
+
id: findingId,
|
|
65
|
+
organizationId: config.organizationId,
|
|
66
|
+
productId: config.productId,
|
|
67
|
+
iocClass: finding.iocClass,
|
|
68
|
+
severity: finding.severity,
|
|
69
|
+
identifier: finding.identifier,
|
|
70
|
+
payload: finding.payload,
|
|
71
|
+
status: 'open',
|
|
72
|
+
suppression: null,
|
|
73
|
+
linkedInjectionId: null,
|
|
74
|
+
};
|
|
75
|
+
const options = {
|
|
76
|
+
autoInjectThreshold: config.autoInjectSeverityThreshold,
|
|
77
|
+
};
|
|
78
|
+
await processNewFinding(forInjection, options, deps.autoInjectDeps);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
warnings.push(`auto-inject ${finding.identifier}: ${err.message}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
observedByClass.set(scanner.iocClass, observed);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
anyFailure = true;
|
|
89
|
+
warnings.push(`${scanner.iocClass}: ${err.message}`);
|
|
90
|
+
coverage[scanner.iocClass] = { error: err.message };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Re-scan resolution: previously-open findings whose class was
|
|
94
|
+
// covered by this run but whose identifier did not re-appear are
|
|
95
|
+
// flipped to 'resolved'. Failures here are non-fatal -- the run
|
|
96
|
+
// already succeeded for its primary purpose (finding fresh issues).
|
|
97
|
+
if (deps.resolutionDeps && observedByClass.size > 0) {
|
|
98
|
+
try {
|
|
99
|
+
const observedSets = Array.from(observedByClass.entries()).map(([iocClass, identifiers]) => ({ iocClass, identifiers }));
|
|
100
|
+
const resolved = await resolveStaleFindings(config.productId, observedSets, deps.resolutionDeps);
|
|
101
|
+
if (resolved.length > 0) {
|
|
102
|
+
coverage.resolved_findings = resolved.length;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
warnings.push(`resolution: ${err.message}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (warnings.length > 0) {
|
|
110
|
+
coverage.warnings = warnings;
|
|
111
|
+
}
|
|
112
|
+
const status = anyFailure
|
|
113
|
+
? anySuccess
|
|
114
|
+
? 'partial'
|
|
115
|
+
: 'failed'
|
|
116
|
+
: 'succeeded';
|
|
117
|
+
await deps.finishRun(runId, {
|
|
118
|
+
status,
|
|
119
|
+
coverageSummary: coverage,
|
|
120
|
+
findingsCountBySeverity: counts,
|
|
121
|
+
durationMs: Date.now() - startedAt,
|
|
122
|
+
});
|
|
123
|
+
if (trigger === 'manual') {
|
|
124
|
+
await deps.clearManualRunRequest(config.id);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
// Loop tick -- invoked by unified-shell on a fixed cadence
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
export async function runSecurityScanTick(deps) {
|
|
131
|
+
const configs = await deps.getDueScanConfigs();
|
|
132
|
+
for (const config of configs) {
|
|
133
|
+
if (!config.enabled)
|
|
134
|
+
continue;
|
|
135
|
+
const trigger = config.manualRunRequestedAt ? 'manual' : 'schedule';
|
|
136
|
+
try {
|
|
137
|
+
await runScanForConfig(config, trigger, deps);
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
// Per-config failures are swallowed so a single broken product
|
|
141
|
+
// does not stop the engine from servicing others. The run row
|
|
142
|
+
// already records the failure status.
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
// Default Deps -- daemon-side wiring via callApi
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
export function buildDefaultSecurityScanDeps(config) {
|
|
150
|
+
const resolveCwd = (productId) => {
|
|
151
|
+
const product = config.products.find((p) => p.id === productId);
|
|
152
|
+
if (!product)
|
|
153
|
+
return config.repoPath;
|
|
154
|
+
return configForProduct(config, product).repoPath;
|
|
155
|
+
};
|
|
156
|
+
return {
|
|
157
|
+
getDueScanConfigs: async () => {
|
|
158
|
+
const res = await callApi('daemon_get_due_security_scan_configs', {});
|
|
159
|
+
return res.items ?? [];
|
|
160
|
+
},
|
|
161
|
+
startRun: async (configId, trigger) => {
|
|
162
|
+
const res = await callApi('daemon_start_security_scan_run', {
|
|
163
|
+
configId,
|
|
164
|
+
trigger,
|
|
165
|
+
});
|
|
166
|
+
return res.runId;
|
|
167
|
+
},
|
|
168
|
+
finishRun: async (runId, update) => {
|
|
169
|
+
await callApi('daemon_finish_security_scan_run', { runId, ...update });
|
|
170
|
+
},
|
|
171
|
+
writeFinding: async (runId, productId, organizationId, finding) => {
|
|
172
|
+
const res = await callApi('daemon_write_security_finding', {
|
|
173
|
+
runId,
|
|
174
|
+
productId,
|
|
175
|
+
organizationId,
|
|
176
|
+
...finding,
|
|
177
|
+
});
|
|
178
|
+
return { findingId: res.findingId };
|
|
179
|
+
},
|
|
180
|
+
clearManualRunRequest: async (configId) => {
|
|
181
|
+
await callApi('daemon_clear_manual_scan_request', { configId });
|
|
182
|
+
},
|
|
183
|
+
resolveCwd,
|
|
184
|
+
scanners: getRegisteredScanners(),
|
|
185
|
+
autoInjectDeps: buildDefaultAutoInjectDeps(),
|
|
186
|
+
resolutionDeps: buildDefaultResolutionDeps(),
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=security-scan-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-scan-engine.js","sourceRoot":"","sources":["../src/security-scan-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* without metadata populated.
|
|
8
8
|
*/
|
|
9
9
|
import type { WorkflowStage, Workflow } from './types.js';
|
|
10
|
-
/** Stage where agent team has work to do (e.g., queued, coding,
|
|
10
|
+
/** Stage where agent team has work to do (e.g., queued, coding, awaiting_verify). */
|
|
11
11
|
export declare function isAgentActionable(stage: WorkflowStage): boolean;
|
|
12
12
|
/** Truly terminal — no more work ever (e.g., done, cancelled). */
|
|
13
13
|
export declare function isTerminal(stage: WorkflowStage): boolean;
|
|
@@ -19,7 +19,7 @@ export declare function isCascadable(stage: WorkflowStage): boolean;
|
|
|
19
19
|
/**
|
|
20
20
|
* Blocks subsequent ranked deliveries from being picked up.
|
|
21
21
|
* Backlog stages, agent-work stages, and paused block.
|
|
22
|
-
* Review/
|
|
22
|
+
* Review/awaiting_verify/terminal stages don't block.
|
|
23
23
|
*/
|
|
24
24
|
export declare function isBlocking(stage: WorkflowStage): boolean;
|
|
25
25
|
/** Excluded from cascade checks entirely (cancelled but not done). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stage-classifier.d.ts","sourceRoot":"","sources":["../src/stage-classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI1D
|
|
1
|
+
{"version":3,"file":"stage-classifier.d.ts","sourceRoot":"","sources":["../src/stage-classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI1D,qFAAqF;AACrF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAG/D;AAED,kEAAkE;AAClE,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAGxD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAS1D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAUxD;AAED,sEAAsE;AACtE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAEnE;AAUD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAMpF;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAM7E;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAM/E;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAM7E;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAMxF"}
|
package/dist/stage-classifier.js
CHANGED
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
* without metadata populated.
|
|
8
8
|
*/
|
|
9
9
|
// ── Stage-level classifiers ──────────────────────────────────────
|
|
10
|
-
/** Stage where agent team has work to do (e.g., queued, coding,
|
|
10
|
+
/** Stage where agent team has work to do (e.g., queued, coding, awaiting_verify). */
|
|
11
11
|
export function isAgentActionable(stage) {
|
|
12
12
|
if (stage.is_agent_actionable !== undefined)
|
|
13
13
|
return stage.is_agent_actionable;
|
|
14
|
-
return stage.name === 'queued' || stage.name === 'coding' || stage.name === '
|
|
14
|
+
return stage.name === 'queued' || stage.name === 'coding' || stage.name === 'awaiting_verify';
|
|
15
15
|
}
|
|
16
16
|
/** Truly terminal — no more work ever (e.g., done, cancelled). */
|
|
17
17
|
export function isTerminal(stage) {
|
|
@@ -29,7 +29,7 @@ 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, in_review,
|
|
32
|
+
// (verify, in_review, awaiting_verify)
|
|
33
33
|
return !isAgentActionable(stage) && !isBlocking(stage);
|
|
34
34
|
}
|
|
35
35
|
return ['verify', 'in_review', 'done', 'cancelled'].includes(stage.name);
|
|
@@ -37,7 +37,7 @@ export function isCascadable(stage) {
|
|
|
37
37
|
/**
|
|
38
38
|
* Blocks subsequent ranked deliveries from being picked up.
|
|
39
39
|
* Backlog stages, agent-work stages, and paused block.
|
|
40
|
-
* Review/
|
|
40
|
+
* Review/awaiting_verify/terminal stages don't block.
|
|
41
41
|
*/
|
|
42
42
|
export function isBlocking(stage) {
|
|
43
43
|
if (stage.meta_bucket !== undefined) {
|
|
@@ -52,7 +52,7 @@ export function isBlocking(stage) {
|
|
|
52
52
|
return true;
|
|
53
53
|
return false;
|
|
54
54
|
}
|
|
55
|
-
return !['done', 'cancelled', 'verify', 'in_review', '
|
|
55
|
+
return !['done', 'cancelled', 'verify', 'in_review', 'awaiting_verify'].includes(stage.name);
|
|
56
56
|
}
|
|
57
57
|
/** Excluded from cascade checks entirely (cancelled but not done). */
|
|
58
58
|
export function isExcludedFromCascade(stage) {
|
|
@@ -70,7 +70,7 @@ export function isStatusAgentActionable(status, workflow) {
|
|
|
70
70
|
if (stage)
|
|
71
71
|
return isAgentActionable(stage);
|
|
72
72
|
}
|
|
73
|
-
return status === 'queued' || status === 'coding' || status === '
|
|
73
|
+
return status === 'queued' || status === 'coding' || status === 'awaiting_verify';
|
|
74
74
|
}
|
|
75
75
|
export function isStatusTerminal(status, workflow) {
|
|
76
76
|
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', 'in_review', '
|
|
97
|
+
return !['done', 'cancelled', 'verify', 'in_review', 'awaiting_verify'].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
|
|
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
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* user can request a fresh review when verify is reached again.
|
|
15
15
|
*
|
|
16
16
|
* Review completion is NOT auto-routed here. Closing out a review and
|
|
17
|
-
* routing in_review deliveries to done/
|
|
17
|
+
* routing in_review deliveries to done/awaiting_verify is the exclusive
|
|
18
18
|
* responsibility of focus-completion.ts's review exit handler, which
|
|
19
19
|
* gates on the exiting team's sessionType === 'review' (a positive
|
|
20
20
|
* signal that an actual review ran). If the review team never spawns
|
package/dist/state-cascade.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* user can request a fresh review when verify is reached again.
|
|
15
15
|
*
|
|
16
16
|
* Review completion is NOT auto-routed here. Closing out a review and
|
|
17
|
-
* routing in_review deliveries to done/
|
|
17
|
+
* routing in_review deliveries to done/awaiting_verify is the exclusive
|
|
18
18
|
* responsibility of focus-completion.ts's review exit handler, which
|
|
19
19
|
* gates on the exiting team's sessionType === 'review' (a positive
|
|
20
20
|
* signal that an actual review ran). If the review team never spawns
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-prompt-base.d.ts","sourceRoot":"","sources":["../src/team-prompt-base.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,iBAAiB,EACjB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACf,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAG9D,MAAM,WAAW,gCAAgC;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,eAAe,EAAE,oBAAoB,CAAC;IACtC,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,kBAAkB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACzC,yBAAyB,CAAC,EAAE,gCAAgC,GAAG,IAAI,CAAC;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,EAAE,CAO1D;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,EAAE,CAWtE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,EAAE,CAgBnD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,EAAE,CAkBtE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,EAAE,CAQlF;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,CAAC,EAAE,iBAAiB,EAAE,GAAG,MAAM,EAAE,CAqB/E;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,CAAC,EAAE,gCAAgC,GAAG,IAAI,GACjD,MAAM,EAAE,CAmBV;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAGtE;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,EAAE,CAOlF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,sBAAsB,GAC9B,MAAM,EAAE,CA0GV;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,MAAM,EAAE,cAAc,EAAE,GACvB,MAAM,EAAE,CAuGV;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"team-prompt-base.d.ts","sourceRoot":"","sources":["../src/team-prompt-base.ts"],"names":[],"mappings":"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"}
|
package/dist/team-prompt-base.js
CHANGED
|
@@ -424,6 +424,21 @@ export function buildStatusUpdateRulesSection() {
|
|
|
424
424
|
'2. When the worker completes, verify its output',
|
|
425
425
|
'3. Set issue to "Done" after verification',
|
|
426
426
|
'',
|
|
427
|
+
'**Completion artifacts (MANDATORY on close):**',
|
|
428
|
+
'- When you set an issue to "Done" or "In Review", you MUST also supply',
|
|
429
|
+
' `completionArtifacts` listing the primary files the work produced or',
|
|
430
|
+
' modified. Shape: `{ "files": ["src/foo.ts", "src/foo.test.ts"], "tests": [...] }`.',
|
|
431
|
+
'- Drift detection compares these references against the worktree on a',
|
|
432
|
+
' schedule. Without them, drift cannot surface for this issue and the',
|
|
433
|
+
' Done-work signal is unreliable.',
|
|
434
|
+
'- Use repo-relative paths (no leading slash, no `./`). Include test files',
|
|
435
|
+
' under `files` or `tests` -- both are checked.',
|
|
436
|
+
'- Workers spawned via Task: when reporting completion, return the list of',
|
|
437
|
+
' files you modified so the team lead can pass them through in the',
|
|
438
|
+
' `issue_update` call.',
|
|
439
|
+
'- Example close call:',
|
|
440
|
+
' `{ "issueId": "<id>", "status": "Done", "completionArtifacts": { "files": ["src/foo.ts"] } }`',
|
|
441
|
+
'',
|
|
427
442
|
];
|
|
428
443
|
}
|
|
429
444
|
/**
|