@telora/daemon 0.15.42 → 0.15.47

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.
Files changed (38) hide show
  1. package/build-info.json +2 -2
  2. package/dist/focus-completion.d.ts.map +1 -1
  3. package/dist/focus-completion.js +21 -6
  4. package/dist/focus-completion.js.map +1 -1
  5. package/dist/focus-engine.d.ts.map +1 -1
  6. package/dist/focus-engine.js +9 -9
  7. package/dist/focus-engine.js.map +1 -1
  8. package/dist/focus-merge.d.ts.map +1 -1
  9. package/dist/focus-merge.js +2 -0
  10. package/dist/focus-merge.js.map +1 -1
  11. package/dist/security-auto-inject.d.ts +17 -32
  12. package/dist/security-auto-inject.d.ts.map +1 -1
  13. package/dist/security-auto-inject.js +13 -49
  14. package/dist/security-auto-inject.js.map +1 -1
  15. package/dist/security-finding-gate.d.ts +74 -0
  16. package/dist/security-finding-gate.d.ts.map +1 -0
  17. package/dist/security-finding-gate.js +82 -0
  18. package/dist/security-finding-gate.js.map +1 -0
  19. package/dist/security-rescan-resolution.d.ts +1 -27
  20. package/dist/security-rescan-resolution.d.ts.map +1 -1
  21. package/dist/security-rescan-resolution.js +1 -38
  22. package/dist/security-rescan-resolution.js.map +1 -1
  23. package/dist/security-scan-engine.d.ts +37 -24
  24. package/dist/security-scan-engine.d.ts.map +1 -1
  25. package/dist/security-scan-engine.js +41 -72
  26. package/dist/security-scan-engine.js.map +1 -1
  27. package/dist/spawner-lifecycle.d.ts +2 -0
  28. package/dist/spawner-lifecycle.d.ts.map +1 -1
  29. package/dist/spawner-lifecycle.js +3 -2
  30. package/dist/spawner-lifecycle.js.map +1 -1
  31. package/dist/team-prompt-base.d.ts.map +1 -1
  32. package/dist/team-prompt-base.js +22 -0
  33. package/dist/team-prompt-base.js.map +1 -1
  34. package/dist/verification-engine.d.ts +9 -0
  35. package/dist/verification-engine.d.ts.map +1 -1
  36. package/dist/verification-engine.js +29 -3
  37. package/dist/verification-engine.js.map +1 -1
  38. package/package.json +1 -1
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Deterministic check evaluator for the Security workflow verify-closed gate.
3
+ *
4
+ * The Security workflow declares its verify-closed stage with
5
+ * `agent_directive.gate = { kind: 'deterministic', check:
6
+ * 'security.finding_no_longer_present' }`. The gate's contract: a security
7
+ * remediation injection cannot be verified (retired) unless the linked
8
+ * security_findings row has flipped to status='resolved' (the re-scan
9
+ * resolution sweep clears the indicator).
10
+ *
11
+ * If the gate fails, the linked finding is flipped to status='escalated'
12
+ * with escalation_reason='verify_gate_failed'. After the D1 schema
13
+ * collapse, the Security workflow no longer carries a 'Reopen (failed)'
14
+ * transition — a failed verify-closed escalates and stays.
15
+ *
16
+ * Wired into verification-engine.ts: before calling verifyInjectionOnPass
17
+ * on a 'passed' outcome, the engine consults this gate. A 'passed' outcome
18
+ * is demoted to 'failed' when the finding is still open/remediating.
19
+ *
20
+ * @module security-finding-gate
21
+ */
22
+ export type FindingStatusForGate = 'open' | 'remediating' | 'resolved' | 'escalated';
23
+ export interface FindingLookupResult {
24
+ findingId: string;
25
+ status: FindingStatusForGate;
26
+ }
27
+ export interface SecurityFindingGateDeps {
28
+ /**
29
+ * Look up the security_findings row whose linked_injection_id matches the
30
+ * given injection node id. Returns null when no finding is linked
31
+ * (non-security injection -- gate is a no-op).
32
+ */
33
+ lookupFindingByInjection: (injectionNodeId: string) => Promise<FindingLookupResult | null>;
34
+ /**
35
+ * Flip the finding to status='escalated' and append a security_finding_audit
36
+ * row with action='escalated'. Idempotent at the DB layer.
37
+ */
38
+ escalateFinding: (findingId: string, reason: string) => Promise<void>;
39
+ }
40
+ export type SecurityFindingGateResult = {
41
+ passed: true;
42
+ findingId: null;
43
+ reason?: string;
44
+ } | {
45
+ passed: true;
46
+ findingId: string;
47
+ reason?: string;
48
+ } | {
49
+ passed: false;
50
+ findingId: string;
51
+ reason: string;
52
+ };
53
+ /**
54
+ * Evaluate the `security.finding_no_longer_present` deterministic check for
55
+ * a given injection node.
56
+ *
57
+ * Outcomes:
58
+ * - No finding linked to this injection -> passes as a no-op.
59
+ * - Linked finding has status 'resolved' -> passes.
60
+ * - Linked finding has any other status -> fails, returns the findingId
61
+ * so the caller can escalate.
62
+ *
63
+ * The function does NOT mutate any state -- escalation is the caller's
64
+ * responsibility via `escalateOnGateFail`.
65
+ */
66
+ export declare function evaluateFindingNoLongerPresent(injectionNodeId: string, deps: SecurityFindingGateDeps): Promise<SecurityFindingGateResult>;
67
+ /**
68
+ * Best-effort escalation helper: when the gate fails, flip the linked
69
+ * finding to status='escalated'. Logs and swallows on error so a failed
70
+ * escalation does not throw out of the verification path.
71
+ */
72
+ export declare function escalateOnGateFail(findingId: string, reason: string, deps: SecurityFindingGateDeps): Promise<void>;
73
+ export declare function buildDefaultSecurityFindingGateDeps(): SecurityFindingGateDeps;
74
+ //# sourceMappingURL=security-finding-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-finding-gate.d.ts","sourceRoot":"","sources":["../src/security-finding-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAQH,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,aAAa,GAAG,UAAU,GAAG,WAAW,CAAC;AAErF,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,oBAAoB,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,wBAAwB,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IAC3F;;;OAGG;IACH,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE;AAED,MAAM,MAAM,yBAAyB,GACjC;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAMzD;;;;;;;;;;;;GAYG;AACH,wBAAsB,8BAA8B,CAClD,eAAe,EAAE,MAAM,EACvB,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,yBAAyB,CAAC,CAapC;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAQf;AAMD,wBAAgB,mCAAmC,IAAI,uBAAuB,CAc7E"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Deterministic check evaluator for the Security workflow verify-closed gate.
3
+ *
4
+ * The Security workflow declares its verify-closed stage with
5
+ * `agent_directive.gate = { kind: 'deterministic', check:
6
+ * 'security.finding_no_longer_present' }`. The gate's contract: a security
7
+ * remediation injection cannot be verified (retired) unless the linked
8
+ * security_findings row has flipped to status='resolved' (the re-scan
9
+ * resolution sweep clears the indicator).
10
+ *
11
+ * If the gate fails, the linked finding is flipped to status='escalated'
12
+ * with escalation_reason='verify_gate_failed'. After the D1 schema
13
+ * collapse, the Security workflow no longer carries a 'Reopen (failed)'
14
+ * transition — a failed verify-closed escalates and stays.
15
+ *
16
+ * Wired into verification-engine.ts: before calling verifyInjectionOnPass
17
+ * on a 'passed' outcome, the engine consults this gate. A 'passed' outcome
18
+ * is demoted to 'failed' when the finding is still open/remediating.
19
+ *
20
+ * @module security-finding-gate
21
+ */
22
+ import { callApi } from './queries/shared.js';
23
+ // ---------------------------------------------------------------------------
24
+ // Pure evaluator
25
+ // ---------------------------------------------------------------------------
26
+ /**
27
+ * Evaluate the `security.finding_no_longer_present` deterministic check for
28
+ * a given injection node.
29
+ *
30
+ * Outcomes:
31
+ * - No finding linked to this injection -> passes as a no-op.
32
+ * - Linked finding has status 'resolved' -> passes.
33
+ * - Linked finding has any other status -> fails, returns the findingId
34
+ * so the caller can escalate.
35
+ *
36
+ * The function does NOT mutate any state -- escalation is the caller's
37
+ * responsibility via `escalateOnGateFail`.
38
+ */
39
+ export async function evaluateFindingNoLongerPresent(injectionNodeId, deps) {
40
+ const lookup = await deps.lookupFindingByInjection(injectionNodeId);
41
+ if (!lookup) {
42
+ return { passed: true, findingId: null, reason: 'no_linked_finding' };
43
+ }
44
+ if (lookup.status === 'resolved') {
45
+ return { passed: true, findingId: lookup.findingId, reason: 'finding_resolved' };
46
+ }
47
+ return {
48
+ passed: false,
49
+ findingId: lookup.findingId,
50
+ reason: `finding_status_is_${lookup.status}`,
51
+ };
52
+ }
53
+ /**
54
+ * Best-effort escalation helper: when the gate fails, flip the linked
55
+ * finding to status='escalated'. Logs and swallows on error so a failed
56
+ * escalation does not throw out of the verification path.
57
+ */
58
+ export async function escalateOnGateFail(findingId, reason, deps) {
59
+ try {
60
+ await deps.escalateFinding(findingId, reason);
61
+ }
62
+ catch (err) {
63
+ console.warn(`[security-finding-gate] escalation failed for finding ${findingId}: ${err.message}`);
64
+ }
65
+ }
66
+ // ---------------------------------------------------------------------------
67
+ // Default deps -- daemon-side wiring via callApi
68
+ // ---------------------------------------------------------------------------
69
+ export function buildDefaultSecurityFindingGateDeps() {
70
+ return {
71
+ lookupFindingByInjection: async (injectionNodeId) => {
72
+ const res = await callApi('daemon_lookup_finding_by_injection', { injectionNodeId });
73
+ if (!res?.findingId || !res.status)
74
+ return null;
75
+ return { findingId: res.findingId, status: res.status };
76
+ },
77
+ escalateFinding: async (findingId, reason) => {
78
+ await callApi('daemon_escalate_security_finding', { findingId, reason });
79
+ },
80
+ };
81
+ }
82
+ //# sourceMappingURL=security-finding-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-finding-gate.js","sourceRoot":"","sources":["../src/security-finding-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAgC9C,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,eAAuB,EACvB,IAA6B;IAE7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC;IACpE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IACxE,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QACjC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IACnF,CAAC;IACD,OAAO;QACL,MAAM,EAAE,KAAK;QACb,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,MAAM,EAAE,qBAAqB,MAAM,CAAC,MAAM,EAAE;KAC7C,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAiB,EACjB,MAAc,EACd,IAA6B;IAE7B,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CACV,yDAAyD,SAAS,KAAM,GAAa,CAAC,OAAO,EAAE,CAChG,CAAC;IACJ,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,iDAAiD;AACjD,8EAA8E;AAE9E,MAAM,UAAU,mCAAmC;IACjD,OAAO;QACL,wBAAwB,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE;YAClD,MAAM,GAAG,GAAG,MAAM,OAAO,CACvB,oCAAoC,EACpC,EAAE,eAAe,EAAE,CACpB,CAAC;YACF,IAAI,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,GAAG,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC;YAChD,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;QAC1D,CAAC;QACD,eAAe,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE;YAC3C,MAAM,OAAO,CAAC,kCAAkC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;QAC3E,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -5,8 +5,7 @@
5
5
  * auto-verify the injection.
6
6
  *
7
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.
8
+ * its findings, before the next tick begins.
10
9
  *
11
10
  * @module security-rescan-resolution
12
11
  */
@@ -56,29 +55,4 @@ export interface ScanRunFindingSet {
56
55
  */
57
56
  export declare function resolveStaleFindings(productId: string, observedSets: ScanRunFindingSet[], deps: ResolutionDeps): Promise<string[]>;
58
57
  export declare function buildDefaultResolutionDeps(): ResolutionDeps;
59
- export interface SuppressionExpirySweepDeps {
60
- /** Returns findings where status='suppressed' and suppression.expires_at < now(). */
61
- listExpiredSuppressions: () => Promise<Array<{
62
- id: string;
63
- organizationId: string;
64
- }>>;
65
- /** Set status='open', suppression=null. */
66
- unsuppressFinding: (findingId: string) => Promise<void>;
67
- /** Append audit row with action='unsuppressed' and reason='suppression_expired'. */
68
- writeAudit: (input: {
69
- findingId: string;
70
- organizationId: string;
71
- action: 'unsuppressed';
72
- payload: Record<string, unknown>;
73
- }) => Promise<void>;
74
- }
75
- /**
76
- * Sweep suppressions whose expires_at has passed and flip them back to
77
- * 'open'. Idempotent: a suppression already expired is a no-op on the
78
- * second call because the predicate now matches status='open'.
79
- *
80
- * @returns the finding ids whose suppression was lifted.
81
- */
82
- export declare function runSuppressionExpirySweep(deps: SuppressionExpirySweepDeps): Promise<string[]>;
83
- export declare function buildDefaultSuppressionExpirySweepDeps(): SuppressionExpirySweepDeps;
84
58
  //# sourceMappingURL=security-rescan-resolution.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"security-rescan-resolution.d.ts","sourceRoot":"","sources":["../src/security-rescan-resolution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACzF,8DAA8D;IAC9D,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,2CAA2C;IAC3C,UAAU,EAAE,CAAC,KAAK,EAAE;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,MAAM,EAAE,UAAU,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAClC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpB;;;OAGG;IACH,0BAA0B,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAChF,uEAAuE;IACvE,eAAe,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,iBAAiB,EAAE,EACjC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,MAAM,EAAE,CAAC,CAqCnB;AAMD,wBAAgB,0BAA0B,IAAI,cAAc,CA0B3D;AAMD,MAAM,WAAW,0BAA0B;IACzC,qFAAqF;IACrF,uBAAuB,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACtF,2CAA2C;IAC3C,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,oFAAoF;IACpF,UAAU,EAAE,CAAC,KAAK,EAAE;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,MAAM,EAAE,cAAc,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAClC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,MAAM,EAAE,CAAC,CAcnB;AAED,wBAAgB,sCAAsC,IAAI,0BAA0B,CAgBnF"}
1
+ {"version":3,"file":"security-rescan-resolution.d.ts","sourceRoot":"","sources":["../src/security-rescan-resolution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACzF,8DAA8D;IAC9D,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,2CAA2C;IAC3C,UAAU,EAAE,CAAC,KAAK,EAAE;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,MAAM,EAAE,UAAU,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAClC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpB;;;OAGG;IACH,0BAA0B,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAChF,uEAAuE;IACvE,eAAe,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,iBAAiB,EAAE,EACjC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,MAAM,EAAE,CAAC,CAqCnB;AAMD,wBAAgB,0BAA0B,IAAI,cAAc,CA0B3D"}
@@ -5,8 +5,7 @@
5
5
  * auto-verify the injection.
6
6
  *
7
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.
8
+ * its findings, before the next tick begins.
10
9
  *
11
10
  * @module security-rescan-resolution
12
11
  */
@@ -75,40 +74,4 @@ export function buildDefaultResolutionDeps() {
75
74
  },
76
75
  };
77
76
  }
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
77
  //# sourceMappingURL=security-rescan-resolution.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"security-rescan-resolution.js","sourceRoot":"","sources":["../src/security-rescan-resolution.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"security-rescan-resolution.js","sourceRoot":"","sources":["../src/security-rescan-resolution.ts"],"names":[],"mappings":"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"}
@@ -2,24 +2,27 @@
2
2
  * Security scan engine.
3
3
  *
4
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.
5
+ * set), dispatches pluggable Scanner implementations per IOC class, upserts
6
+ * security_findings rows (one per product/ioc_class/identifier), and hands
7
+ * any newly-observed or unremediated-open finding to security-auto-inject
8
+ * for remediation materialization.
9
+ *
10
+ * No longer writes scan-run rows -- the current-state model only persists
11
+ * findings. `last_run_at` on the config is updated directly at the end of
12
+ * runScanForConfig.
9
13
  *
10
14
  * Activation: gated by shouldRunLoop('TELORA_SECURITY_SCAN_LOOP') in
11
15
  * unified-shell.ts. Opt-out semantics match the other daemon loop ticks
12
16
  * (unset/anything-but-'0' = enabled, '0' = disabled). See
13
17
  * docs/runbook-loop-activation.md.
14
18
  *
15
- * Pattern reference: verification-engine.ts (pluggable strategies + Deps).
16
- *
17
19
  * @module security-scan-engine
18
20
  */
19
21
  import type { DaemonConfig } from './types.js';
20
22
  import { type AutoInjectDeps } from './security-auto-inject.js';
21
23
  import { type ResolutionDeps } from './security-rescan-resolution.js';
22
24
  export type Severity = 'low' | 'medium' | 'high' | 'critical';
25
+ export type FindingStatus = 'open' | 'remediating' | 'resolved' | 'escalated';
23
26
  /** Configuration row driving an individual product's scan cadence. */
24
27
  export interface ScanConfig {
25
28
  id: string;
@@ -27,7 +30,6 @@ export interface ScanConfig {
27
30
  productId: string;
28
31
  scheduleCron: string;
29
32
  enabledIocClasses: string[];
30
- autoInjectSeverityThreshold: Severity;
31
33
  enabled: boolean;
32
34
  manualRunRequestedAt: string | null;
33
35
  lastRunAt: string | null;
@@ -58,22 +60,32 @@ export interface Scanner {
58
60
  }
59
61
  export declare function registerScanner(scanner: Scanner): void;
60
62
  export declare function getRegisteredScanners(): Scanner[];
63
+ export interface UpsertFindingResult {
64
+ findingId: string;
65
+ /** True when this row was just inserted (vs an existing row was updated). */
66
+ wasNew: boolean;
67
+ status: FindingStatus;
68
+ linkedInjectionId: string | null;
69
+ }
70
+ /** Options that further narrow which due configs the tick should pick up. */
71
+ export interface DueScanConfigsOptions {
72
+ /**
73
+ * When true, return only configs with a pending manual-run request and
74
+ * skip cron evaluation entirely. Used by the fast (30s) request-drain
75
+ * loop so the click-to-run latency matches other queued-work pickups.
76
+ */
77
+ manualOnly?: boolean;
78
+ }
61
79
  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>;
80
+ getDueScanConfigs: (opts?: DueScanConfigsOptions) => Promise<ScanConfig[]>;
70
81
  /**
71
- * Persist a finding and return its DB-assigned id so downstream
72
- * hooks (auto-injection, resolution) can reference it.
82
+ * Insert or update one row of security_findings. Conflict on
83
+ * (product_id, ioc_class, identifier) updates last_seen_at, severity,
84
+ * and payload. first_seen_at is set on insert only.
73
85
  */
74
- writeFinding: (runId: string, productId: string, organizationId: string, finding: FindingDraft) => Promise<{
75
- findingId: string;
76
- }>;
86
+ upsertFinding: (productId: string, organizationId: string, finding: FindingDraft) => Promise<UpsertFindingResult>;
87
+ /** Stamp last_run_at on the config after a scan completes. */
88
+ updateConfigLastRun: (configId: string) => Promise<void>;
77
89
  clearManualRunRequest: (configId: string) => Promise<void>;
78
90
  resolveCwd: (productId: string) => string;
79
91
  /**
@@ -84,9 +96,10 @@ export interface SecurityScanDeps {
84
96
  clearFeedCaches: () => void;
85
97
  scanners: Scanner[];
86
98
  /**
87
- * Optional severity-gated auto-injection hook. When set, each newly
88
- * written finding is passed to processNewFinding so the daemon can
89
- * materialize a remediation injection + delivery for it.
99
+ * Optional auto-injection hook. When set, each new finding (or
100
+ * existing open finding with no remediation) is passed to
101
+ * processNewFinding so the daemon can materialize a remediation
102
+ * injection + delivery for it.
90
103
  */
91
104
  autoInjectDeps?: AutoInjectDeps;
92
105
  /**
@@ -97,6 +110,6 @@ export interface SecurityScanDeps {
97
110
  resolutionDeps?: ResolutionDeps;
98
111
  }
99
112
  export declare function runScanForConfig(config: ScanConfig, trigger: 'schedule' | 'manual', deps: SecurityScanDeps): Promise<void>;
100
- export declare function runSecurityScanTick(deps: SecurityScanDeps): Promise<void>;
113
+ export declare function runSecurityScanTick(deps: SecurityScanDeps, opts?: DueScanConfigsOptions): Promise<void>;
101
114
  export declare function buildDefaultSecurityScanDeps(config: DaemonConfig): SecurityScanDeps;
102
115
  //# sourceMappingURL=security-scan-engine.d.ts.map
@@ -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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"}
@@ -2,18 +2,20 @@
2
2
  * Security scan engine.
3
3
  *
4
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.
5
+ * set), dispatches pluggable Scanner implementations per IOC class, upserts
6
+ * security_findings rows (one per product/ioc_class/identifier), and hands
7
+ * any newly-observed or unremediated-open finding to security-auto-inject
8
+ * for remediation materialization.
9
+ *
10
+ * No longer writes scan-run rows -- the current-state model only persists
11
+ * findings. `last_run_at` on the config is updated directly at the end of
12
+ * runScanForConfig.
9
13
  *
10
14
  * Activation: gated by shouldRunLoop('TELORA_SECURITY_SCAN_LOOP') in
11
15
  * unified-shell.ts. Opt-out semantics match the other daemon loop ticks
12
16
  * (unset/anything-but-'0' = enabled, '0' = disabled). See
13
17
  * docs/runbook-loop-activation.md.
14
18
  *
15
- * Pattern reference: verification-engine.ts (pluggable strategies + Deps).
16
- *
17
19
  * @module security-scan-engine
18
20
  */
19
21
  import { callApi } from './queries/shared.js';
@@ -33,13 +35,6 @@ export function getRegisteredScanners() {
33
35
  return [...DEFAULT_REGISTRY.values()];
34
36
  }
35
37
  export async function runScanForConfig(config, trigger, deps) {
36
- const runId = await deps.startRun(config.id, trigger);
37
- const startedAt = Date.now();
38
- const coverage = {};
39
- const warnings = [];
40
- const counts = { low: 0, medium: 0, high: 0, critical: 0 };
41
- let anyFailure = false;
42
- let anySuccess = false;
43
38
  // Manual triggers carry the "Refresh feeds" intent: flush the OSV/GHSA
44
39
  // TTL caches so this scan pulls fresh advisory data instead of replaying
45
40
  // the 15-minute window. Scheduled triggers honour the cache to keep
@@ -58,77 +53,60 @@ export async function runScanForConfig(config, trigger, deps) {
58
53
  config,
59
54
  repoPath: deps.resolveCwd(config.productId),
60
55
  });
61
- coverage[scanner.iocClass] = result.coverage;
62
- anySuccess = true;
63
56
  const observed = new Set();
64
57
  for (const finding of result.findings) {
65
- const { findingId } = await deps.writeFinding(runId, config.productId, config.organizationId, finding);
66
- counts[finding.severity] = (counts[finding.severity] ?? 0) + 1;
58
+ const upsert = await deps.upsertFinding(config.productId, config.organizationId, finding);
67
59
  observed.add(finding.identifier);
68
- // Severity-gated auto-injection. Run per-finding so a failing
69
- // injection for one finding does not block the others.
70
- if (deps.autoInjectDeps) {
60
+ // Trigger auto-inject when:
61
+ // * the finding is brand new, OR
62
+ // * the existing finding is open with no remediation in flight
63
+ // (e.g. previous delivery was cancelled).
64
+ const shouldRemediate = upsert.wasNew || (upsert.status === 'open' && upsert.linkedInjectionId === null);
65
+ if (deps.autoInjectDeps && shouldRemediate) {
71
66
  try {
72
67
  const forInjection = {
73
- id: findingId,
68
+ id: upsert.findingId,
74
69
  organizationId: config.organizationId,
75
70
  productId: config.productId,
76
71
  iocClass: finding.iocClass,
77
72
  severity: finding.severity,
78
73
  identifier: finding.identifier,
79
74
  payload: finding.payload,
80
- status: 'open',
81
- suppression: null,
82
- linkedInjectionId: null,
83
- };
84
- const options = {
85
- autoInjectThreshold: config.autoInjectSeverityThreshold,
75
+ status: upsert.status,
76
+ linkedInjectionId: upsert.linkedInjectionId,
86
77
  };
87
- await processNewFinding(forInjection, options, deps.autoInjectDeps);
78
+ await processNewFinding(forInjection, {}, deps.autoInjectDeps);
88
79
  }
89
80
  catch (err) {
90
- warnings.push(`auto-inject ${finding.identifier}: ${err.message}`);
81
+ console.warn(`[security-scan-engine] auto-inject ${finding.identifier}:`, err.message);
91
82
  }
92
83
  }
93
84
  }
94
85
  observedByClass.set(scanner.iocClass, observed);
95
86
  }
96
87
  catch (err) {
97
- anyFailure = true;
98
- warnings.push(`${scanner.iocClass}: ${err.message}`);
99
- coverage[scanner.iocClass] = { error: err.message };
88
+ console.warn(`[security-scan-engine] scanner ${scanner.iocClass} failed:`, err.message);
100
89
  }
101
90
  }
102
91
  // Re-scan resolution: previously-open findings whose class was
103
92
  // covered by this run but whose identifier did not re-appear are
104
- // flipped to 'resolved'. Failures here are non-fatal -- the run
105
- // already succeeded for its primary purpose (finding fresh issues).
93
+ // flipped to 'resolved'. Failures here are non-fatal.
106
94
  if (deps.resolutionDeps && observedByClass.size > 0) {
107
95
  try {
108
96
  const observedSets = Array.from(observedByClass.entries()).map(([iocClass, identifiers]) => ({ iocClass, identifiers }));
109
- const resolved = await resolveStaleFindings(config.productId, observedSets, deps.resolutionDeps);
110
- if (resolved.length > 0) {
111
- coverage.resolved_findings = resolved.length;
112
- }
97
+ await resolveStaleFindings(config.productId, observedSets, deps.resolutionDeps);
113
98
  }
114
99
  catch (err) {
115
- warnings.push(`resolution: ${err.message}`);
100
+ console.warn('[security-scan-engine] resolution sweep failed:', err.message);
116
101
  }
117
102
  }
118
- if (warnings.length > 0) {
119
- coverage.warnings = warnings;
103
+ // Stamp config.last_run_at so cadence recomputes.
104
+ try {
105
+ await deps.updateConfigLastRun(config.id);
106
+ }
107
+ catch (err) {
108
+ console.warn('[security-scan-engine] updateConfigLastRun failed:', err.message);
120
109
  }
121
- const status = anyFailure
122
- ? anySuccess
123
- ? 'partial'
124
- : 'failed'
125
- : 'succeeded';
126
- await deps.finishRun(runId, {
127
- status,
128
- coverageSummary: coverage,
129
- findingsCountBySeverity: counts,
130
- durationMs: Date.now() - startedAt,
131
- });
132
110
  if (trigger === 'manual') {
133
111
  await deps.clearManualRunRequest(config.id);
134
112
  }
@@ -136,8 +114,8 @@ export async function runScanForConfig(config, trigger, deps) {
136
114
  // ---------------------------------------------------------------------------
137
115
  // Loop tick -- invoked by unified-shell on a fixed cadence
138
116
  // ---------------------------------------------------------------------------
139
- export async function runSecurityScanTick(deps) {
140
- const configs = await deps.getDueScanConfigs();
117
+ export async function runSecurityScanTick(deps, opts = {}) {
118
+ const configs = await deps.getDueScanConfigs(opts);
141
119
  for (const config of configs) {
142
120
  if (!config.enabled)
143
121
  continue;
@@ -147,8 +125,7 @@ export async function runSecurityScanTick(deps) {
147
125
  }
148
126
  catch {
149
127
  // Per-config failures are swallowed so a single broken product
150
- // does not stop the engine from servicing others. The run row
151
- // already records the failure status.
128
+ // does not stop the engine from servicing others.
152
129
  }
153
130
  }
154
131
  }
@@ -163,28 +140,20 @@ export function buildDefaultSecurityScanDeps(config) {
163
140
  return configForProduct(config, product).repoPath;
164
141
  };
165
142
  return {
166
- getDueScanConfigs: async () => {
167
- const res = await callApi('daemon_get_due_security_scan_configs', {});
143
+ getDueScanConfigs: async (opts) => {
144
+ const res = await callApi('daemon_get_due_security_scan_configs', opts?.manualOnly ? { manualOnly: true } : {});
168
145
  return res.items ?? [];
169
146
  },
170
- startRun: async (configId, trigger) => {
171
- const res = await callApi('daemon_start_security_scan_run', {
172
- configId,
173
- trigger,
174
- });
175
- return res.runId;
176
- },
177
- finishRun: async (runId, update) => {
178
- await callApi('daemon_finish_security_scan_run', { runId, ...update });
179
- },
180
- writeFinding: async (runId, productId, organizationId, finding) => {
181
- const res = await callApi('daemon_write_security_finding', {
182
- runId,
147
+ upsertFinding: async (productId, organizationId, finding) => {
148
+ const res = await callApi('daemon_upsert_security_finding', {
183
149
  productId,
184
150
  organizationId,
185
151
  ...finding,
186
152
  });
187
- return { findingId: res.findingId };
153
+ return res;
154
+ },
155
+ updateConfigLastRun: async (configId) => {
156
+ await callApi('daemon_update_scan_config_last_run', { configId });
188
157
  },
189
158
  clearManualRunRequest: async (configId) => {
190
159
  await callApi('daemon_clear_manual_scan_request', { configId });
@@ -1 +1 @@
1
- {"version":3,"file":"security-scan-engine.js","sourceRoot":"","sources":["../src/security-scan-engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"security-scan-engine.js","sourceRoot":"","sources":["../src/security-scan-engine.ts"],"names":[],"mappings":"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"}