@telora/daemon 0.22.85 → 0.22.87

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 (260) hide show
  1. package/build-info.json +4 -3
  2. package/dist/ci/ci-escalation.d.ts +17 -1
  3. package/dist/ci/ci-escalation.d.ts.map +1 -1
  4. package/dist/ci/ci-escalation.js +51 -3
  5. package/dist/ci/ci-escalation.js.map +1 -1
  6. package/dist/ci/ci-red-attribution.d.ts +85 -0
  7. package/dist/ci/ci-red-attribution.d.ts.map +1 -0
  8. package/dist/ci/ci-red-attribution.js +108 -0
  9. package/dist/ci/ci-red-attribution.js.map +1 -0
  10. package/dist/ci/ci-sensor-loop.d.ts +84 -80
  11. package/dist/ci/ci-sensor-loop.d.ts.map +1 -1
  12. package/dist/ci/ci-sensor-loop.js +132 -129
  13. package/dist/ci/ci-sensor-loop.js.map +1 -1
  14. package/dist/completion/coverage-stabilized.d.ts.map +1 -1
  15. package/dist/completion/coverage-stabilized.js +1 -1
  16. package/dist/completion/coverage-stabilized.js.map +1 -1
  17. package/dist/completion/escalations.d.ts +40 -5
  18. package/dist/completion/escalations.d.ts.map +1 -1
  19. package/dist/completion/escalations.js +19 -11
  20. package/dist/completion/escalations.js.map +1 -1
  21. package/dist/completion/event-escalations.d.ts +12 -1
  22. package/dist/completion/event-escalations.d.ts.map +1 -1
  23. package/dist/completion/event-escalations.js +73 -37
  24. package/dist/completion/event-escalations.js.map +1 -1
  25. package/dist/completion/event.d.ts +4 -1
  26. package/dist/completion/event.d.ts.map +1 -1
  27. package/dist/completion/event.js +1 -1
  28. package/dist/completion/event.js.map +1 -1
  29. package/dist/completion/human-only-act.d.ts +1 -1
  30. package/dist/completion/human-only-act.js +1 -1
  31. package/dist/completion/machine-remediable-demotion.d.ts +28 -1
  32. package/dist/completion/machine-remediable-demotion.d.ts.map +1 -1
  33. package/dist/completion/machine-remediable-demotion.js +9 -6
  34. package/dist/completion/machine-remediable-demotion.js.map +1 -1
  35. package/dist/completion/read-only-pristine.d.ts.map +1 -1
  36. package/dist/completion/read-only-pristine.js +4 -0
  37. package/dist/completion/read-only-pristine.js.map +1 -1
  38. package/dist/completion/review-exit-deps.js +1 -1
  39. package/dist/completion/review-exit-deps.js.map +1 -1
  40. package/dist/completion/review-exit-escalations.d.ts +10 -0
  41. package/dist/completion/review-exit-escalations.d.ts.map +1 -1
  42. package/dist/completion/review-exit-escalations.js +38 -3
  43. package/dist/completion/review-exit-escalations.js.map +1 -1
  44. package/dist/completion/review-exit-phase.d.ts.map +1 -1
  45. package/dist/completion/review-exit-phase.js +8 -7
  46. package/dist/completion/review-exit-phase.js.map +1 -1
  47. package/dist/completion/review-exit-shortfall.d.ts +5 -1
  48. package/dist/completion/review-exit-shortfall.d.ts.map +1 -1
  49. package/dist/completion/review-exit-shortfall.js +8 -3
  50. package/dist/completion/review-exit-shortfall.js.map +1 -1
  51. package/dist/completion/status-advance-phase.d.ts +2 -0
  52. package/dist/completion/status-advance-phase.d.ts.map +1 -1
  53. package/dist/completion/status-advance-phase.js +2 -1
  54. package/dist/completion/status-advance-phase.js.map +1 -1
  55. package/dist/completion/terminated-work-reconcile.js +2 -2
  56. package/dist/completion/terminated-work-reconcile.js.map +1 -1
  57. package/dist/delivery/delivery-advance-block.d.ts +3 -3
  58. package/dist/delivery/delivery-advance-block.d.ts.map +1 -1
  59. package/dist/delivery/delivery-advance-block.js +13 -8
  60. package/dist/delivery/delivery-advance-block.js.map +1 -1
  61. package/dist/delivery/delivery-lifecycle.d.ts +10 -0
  62. package/dist/delivery/delivery-lifecycle.d.ts.map +1 -1
  63. package/dist/delivery/delivery-lifecycle.js +12 -6
  64. package/dist/delivery/delivery-lifecycle.js.map +1 -1
  65. package/dist/delivery/delivery-merge-ops.d.ts.map +1 -1
  66. package/dist/delivery/delivery-merge-ops.js +39 -21
  67. package/dist/delivery/delivery-merge-ops.js.map +1 -1
  68. package/dist/delivery/external-hold.d.ts +8 -2
  69. package/dist/delivery/external-hold.d.ts.map +1 -1
  70. package/dist/delivery/external-hold.js +12 -5
  71. package/dist/delivery/external-hold.js.map +1 -1
  72. package/dist/delivery/operator-hold.d.ts +6 -1
  73. package/dist/delivery/operator-hold.d.ts.map +1 -1
  74. package/dist/delivery/operator-hold.js +31 -10
  75. package/dist/delivery/operator-hold.js.map +1 -1
  76. package/dist/delivery/paused-revival.d.ts +6 -0
  77. package/dist/delivery/paused-revival.d.ts.map +1 -1
  78. package/dist/delivery/paused-revival.js +3 -1
  79. package/dist/delivery/paused-revival.js.map +1 -1
  80. package/dist/directive/directive-dispatch.d.ts.map +1 -1
  81. package/dist/directive/directive-dispatch.js +6 -3
  82. package/dist/directive/directive-dispatch.js.map +1 -1
  83. package/dist/directive/directive-queue.d.ts.map +1 -1
  84. package/dist/directive/directive-queue.js +4 -1
  85. package/dist/directive/directive-queue.js.map +1 -1
  86. package/dist/drift/staleness-sensor.d.ts +14 -0
  87. package/dist/drift/staleness-sensor.d.ts.map +1 -1
  88. package/dist/drift/staleness-sensor.js +30 -1
  89. package/dist/drift/staleness-sensor.js.map +1 -1
  90. package/dist/focus/focus-executor.d.ts.map +1 -1
  91. package/dist/focus/focus-executor.js +6 -8
  92. package/dist/focus/focus-executor.js.map +1 -1
  93. package/dist/focus/focus-loop-registry.d.ts.map +1 -1
  94. package/dist/focus/focus-loop-registry.js +23 -13
  95. package/dist/focus/focus-loop-registry.js.map +1 -1
  96. package/dist/focus/focus-respawn-guard.d.ts.map +1 -1
  97. package/dist/focus/focus-respawn-guard.js +21 -4
  98. package/dist/focus/focus-respawn-guard.js.map +1 -1
  99. package/dist/focus/listener-auto-advance.d.ts.map +1 -1
  100. package/dist/focus/listener-auto-advance.js +10 -6
  101. package/dist/focus/listener-auto-advance.js.map +1 -1
  102. package/dist/focus/verify-open-issues.d.ts.map +1 -1
  103. package/dist/focus/verify-open-issues.js +21 -1
  104. package/dist/focus/verify-open-issues.js.map +1 -1
  105. package/dist/focus-stage-lifecycle/wedge-watchdog.d.ts.map +1 -1
  106. package/dist/focus-stage-lifecycle/wedge-watchdog.js +35 -14
  107. package/dist/focus-stage-lifecycle/wedge-watchdog.js.map +1 -1
  108. package/dist/loops/index.d.ts.map +1 -1
  109. package/dist/loops/index.js +2 -1
  110. package/dist/loops/index.js.map +1 -1
  111. package/dist/merge/focus-merge.d.ts +1 -1
  112. package/dist/merge/focus-merge.d.ts.map +1 -1
  113. package/dist/merge/focus-merge.js +5 -1
  114. package/dist/merge/focus-merge.js.map +1 -1
  115. package/dist/merge/merge-back-loop.d.ts +2 -1
  116. package/dist/merge/merge-back-loop.d.ts.map +1 -1
  117. package/dist/merge/merge-back-loop.js +15 -12
  118. package/dist/merge/merge-back-loop.js.map +1 -1
  119. package/dist/merge/merge-conflict-escalation.d.ts.map +1 -1
  120. package/dist/merge/merge-conflict-escalation.js +4 -0
  121. package/dist/merge/merge-conflict-escalation.js.map +1 -1
  122. package/dist/nexus/return.d.ts +14 -15
  123. package/dist/nexus/return.d.ts.map +1 -1
  124. package/dist/nexus/return.js +41 -31
  125. package/dist/nexus/return.js.map +1 -1
  126. package/dist/prompt-sections/execution-sections.d.ts +13 -5
  127. package/dist/prompt-sections/execution-sections.d.ts.map +1 -1
  128. package/dist/prompt-sections/execution-sections.js +78 -18
  129. package/dist/prompt-sections/execution-sections.js.map +1 -1
  130. package/dist/prompt-sections/routing-decider-sections.d.ts +60 -0
  131. package/dist/prompt-sections/routing-decider-sections.d.ts.map +1 -0
  132. package/dist/prompt-sections/routing-decider-sections.js +197 -0
  133. package/dist/prompt-sections/routing-decider-sections.js.map +1 -0
  134. package/dist/queries/agent-resolvable-aging.d.ts +4 -3
  135. package/dist/queries/agent-resolvable-aging.d.ts.map +1 -1
  136. package/dist/queries/agent-resolvable-aging.js +5 -4
  137. package/dist/queries/agent-resolvable-aging.js.map +1 -1
  138. package/dist/queries/agent-resolvable-promotion.d.ts +172 -124
  139. package/dist/queries/agent-resolvable-promotion.d.ts.map +1 -1
  140. package/dist/queries/agent-resolvable-promotion.js +332 -307
  141. package/dist/queries/agent-resolvable-promotion.js.map +1 -1
  142. package/dist/queries/agent-resolvable-retirement.d.ts +105 -0
  143. package/dist/queries/agent-resolvable-retirement.d.ts.map +1 -0
  144. package/dist/queries/agent-resolvable-retirement.js +227 -0
  145. package/dist/queries/agent-resolvable-retirement.js.map +1 -0
  146. package/dist/queries/cause-key.d.ts +109 -0
  147. package/dist/queries/cause-key.d.ts.map +1 -1
  148. package/dist/queries/cause-key.js +93 -1
  149. package/dist/queries/cause-key.js.map +1 -1
  150. package/dist/queries/deliveries.d.ts +14 -0
  151. package/dist/queries/deliveries.d.ts.map +1 -1
  152. package/dist/queries/deliveries.js +20 -2
  153. package/dist/queries/deliveries.js.map +1 -1
  154. package/dist/queries/delivery-gate-state.d.ts +130 -5
  155. package/dist/queries/delivery-gate-state.d.ts.map +1 -1
  156. package/dist/queries/delivery-gate-state.js +111 -2
  157. package/dist/queries/delivery-gate-state.js.map +1 -1
  158. package/dist/queries/escalation-consumption.d.ts +95 -15
  159. package/dist/queries/escalation-consumption.d.ts.map +1 -1
  160. package/dist/queries/escalation-consumption.js +162 -24
  161. package/dist/queries/escalation-consumption.js.map +1 -1
  162. package/dist/queries/escalation-dispositions.d.ts +19 -7
  163. package/dist/queries/escalation-dispositions.d.ts.map +1 -1
  164. package/dist/queries/escalation-dispositions.js +7 -0
  165. package/dist/queries/escalation-dispositions.js.map +1 -1
  166. package/dist/queries/escalation-suppression.d.ts +63 -19
  167. package/dist/queries/escalation-suppression.d.ts.map +1 -1
  168. package/dist/queries/escalation-suppression.js +64 -35
  169. package/dist/queries/escalation-suppression.js.map +1 -1
  170. package/dist/queries/escalations.d.ts +127 -70
  171. package/dist/queries/escalations.d.ts.map +1 -1
  172. package/dist/queries/escalations.js +170 -188
  173. package/dist/queries/escalations.js.map +1 -1
  174. package/dist/queries/filing-observation.d.ts +82 -0
  175. package/dist/queries/filing-observation.d.ts.map +1 -0
  176. package/dist/queries/filing-observation.js +157 -0
  177. package/dist/queries/filing-observation.js.map +1 -0
  178. package/dist/queries/holds.d.ts +69 -2
  179. package/dist/queries/holds.d.ts.map +1 -1
  180. package/dist/queries/holds.js +106 -11
  181. package/dist/queries/holds.js.map +1 -1
  182. package/dist/queries/incident-correlation.d.ts +291 -0
  183. package/dist/queries/incident-correlation.d.ts.map +1 -0
  184. package/dist/queries/incident-correlation.js +408 -0
  185. package/dist/queries/incident-correlation.js.map +1 -0
  186. package/dist/queries/routing-measurement.d.ts +48 -1
  187. package/dist/queries/routing-measurement.d.ts.map +1 -1
  188. package/dist/queries/routing-measurement.js +64 -2
  189. package/dist/queries/routing-measurement.js.map +1 -1
  190. package/dist/queries/routing-quality.d.ts +8 -0
  191. package/dist/queries/routing-quality.d.ts.map +1 -1
  192. package/dist/queries/routing-quality.js +12 -3
  193. package/dist/queries/routing-quality.js.map +1 -1
  194. package/dist/queries/shared.js +1 -1
  195. package/dist/shell/crash-recovery.d.ts.map +1 -1
  196. package/dist/shell/crash-recovery.js +6 -6
  197. package/dist/shell/crash-recovery.js.map +1 -1
  198. package/dist/shell/install-probe-tick.d.ts.map +1 -1
  199. package/dist/shell/install-probe-tick.js +3 -1
  200. package/dist/shell/install-probe-tick.js.map +1 -1
  201. package/dist/spawn/respawn-cycle-escalation.d.ts +10 -2
  202. package/dist/spawn/respawn-cycle-escalation.d.ts.map +1 -1
  203. package/dist/spawn/respawn-cycle-escalation.js +16 -2
  204. package/dist/spawn/respawn-cycle-escalation.js.map +1 -1
  205. package/dist/spawn/routing-decider-spawn.d.ts +93 -0
  206. package/dist/spawn/routing-decider-spawn.d.ts.map +1 -0
  207. package/dist/spawn/routing-decider-spawn.js +185 -0
  208. package/dist/spawn/routing-decider-spawn.js.map +1 -0
  209. package/dist/spawn/routing-decider.d.ts +42 -0
  210. package/dist/spawn/routing-decider.d.ts.map +1 -0
  211. package/dist/spawn/routing-decider.js +95 -0
  212. package/dist/spawn/routing-decider.js.map +1 -0
  213. package/dist/spawn/shared.d.ts +8 -0
  214. package/dist/spawn/shared.d.ts.map +1 -1
  215. package/dist/spawn/shared.js +1 -1
  216. package/dist/spawn/shared.js.map +1 -1
  217. package/dist/spawn/spawn-decision.d.ts +23 -16
  218. package/dist/spawn/spawn-decision.d.ts.map +1 -1
  219. package/dist/spawn/spawn-decision.js +27 -11
  220. package/dist/spawn/spawn-decision.js.map +1 -1
  221. package/dist/spawn/worktree-session.d.ts +19 -7
  222. package/dist/spawn/worktree-session.d.ts.map +1 -1
  223. package/dist/spawn/worktree-session.js +36 -8
  224. package/dist/spawn/worktree-session.js.map +1 -1
  225. package/dist/testing/fixtures/index.js +1 -1
  226. package/dist/types/index.js +1 -1
  227. package/dist/verify/failure-signature.d.ts +91 -0
  228. package/dist/verify/failure-signature.d.ts.map +1 -0
  229. package/dist/verify/failure-signature.js +233 -0
  230. package/dist/verify/failure-signature.js.map +1 -0
  231. package/dist/verify/shortfall-repeat.d.ts +12 -9
  232. package/dist/verify/shortfall-repeat.d.ts.map +1 -1
  233. package/dist/verify/shortfall-repeat.js +38 -14
  234. package/dist/verify/shortfall-repeat.js.map +1 -1
  235. package/dist/verify/stall-detectors.d.ts +19 -43
  236. package/dist/verify/stall-detectors.d.ts.map +1 -1
  237. package/dist/verify/stall-detectors.js +26 -101
  238. package/dist/verify/stall-detectors.js.map +1 -1
  239. package/dist/verify/unreviewed-settle-detector.d.ts +8 -0
  240. package/dist/verify/unreviewed-settle-detector.d.ts.map +1 -1
  241. package/dist/verify/unreviewed-settle-detector.js +15 -1
  242. package/dist/verify/unreviewed-settle-detector.js.map +1 -1
  243. package/dist/verify/verification-deps-default.d.ts.map +1 -1
  244. package/dist/verify/verification-deps-default.js +14 -2
  245. package/dist/verify/verification-deps-default.js.map +1 -1
  246. package/dist/verify/verification-evidence-unavailable-feedback.d.ts.map +1 -1
  247. package/dist/verify/verification-evidence-unavailable-feedback.js +8 -2
  248. package/dist/verify/verification-evidence-unavailable-feedback.js.map +1 -1
  249. package/dist/verify/verification-feedback.d.ts +62 -14
  250. package/dist/verify/verification-feedback.d.ts.map +1 -1
  251. package/dist/verify/verification-feedback.js +101 -28
  252. package/dist/verify/verification-feedback.js.map +1 -1
  253. package/dist/verify/verify-gate-stall.d.ts +116 -0
  254. package/dist/verify/verify-gate-stall.d.ts.map +1 -0
  255. package/dist/verify/verify-gate-stall.js +169 -0
  256. package/dist/verify/verify-gate-stall.js.map +1 -0
  257. package/dist/verify/verify-restatement.d.ts.map +1 -1
  258. package/dist/verify/verify-restatement.js +2 -1
  259. package/dist/verify/verify-restatement.js.map +1 -1
  260. package/package.json +2 -2
@@ -0,0 +1,291 @@
1
+ /**
2
+ * Incident correlation over escalation rows: the ONE reducer every daemon filing
3
+ * passes through (queries/escalations.ts createEscalation calls it).
4
+ *
5
+ * queries/cause-key.ts defines the two keys: a per-detector CAUSE key
6
+ * (idempotency + dismissal memory) and the cross-detector INCIDENT key (the
7
+ * execution anchor an observation is about). This module applies them to rows:
8
+ *
9
+ * - STAMPING: every row filed with an anchor carries metadata.incident_key, and
10
+ * its own observation is seeded into metadata.symptoms.
11
+ * - CORRELATION (correlateFiling): a filing whose incident already has an open
12
+ * row IN ITS LANE is attached to that row as a symptom instead of becoming a
13
+ * second row. The I/O is injected (incidentIoOver builds it over callApi), so
14
+ * this module takes no value import of the API client.
15
+ * - KIND DEDUP: a row answers for its own kind, a hand-off row's originalKind (a
16
+ * historic promotion refile) / original_cause_key (that refile, or a routing
17
+ * decider's MCP filing carrying sourceCauseKey), and every symptom it carries,
18
+ * so the kind/column dedup reads in queries/escalations.ts see correlated and
19
+ * handed-off rows too.
20
+ *
21
+ * The attach/lane contract (decided 2026-09-12, reversible -- readers group rows
22
+ * by metadata.incident_key and rely on exactly this):
23
+ *
24
+ * 1. LANE = the disposition the chokepoint SENDS (after routeFilingDisposition).
25
+ * A filing attaches only to an OPEN row of its incident whose disposition is
26
+ * the same; with no such row it opens one. The chokepoint sends EVERY daemon
27
+ * filing agent_resolvable (an observation, whatever disposition it proposed)
28
+ * or with no disposition, so a daemon filing attaches only to its incident's
29
+ * open agent_resolvable row (or its plain, disposition-less row) -- never into
30
+ * a human-lane row. Human-lane rows (needs_operator / external_wait carrying
31
+ * metadata.human_act) are made by AGENTS through the MCP escalate surface,
32
+ * which does not pass this reducer. findLaneIncidentRow still matches those
33
+ * lanes exactly, so it reads a store holding them correctly, but no daemon
34
+ * filing is sent in them. One incident has at most one open daemon-filed row
35
+ * per lane, and they share metadata.incident_key.
36
+ * 2. A row's metadata.symptoms lists its OWN opening symptom plus exactly what
37
+ * attached to THAT row -- never a copy of another row's symptoms.
38
+ * 3. A re-observed cause (the target row already carries its cause key as its
39
+ * own, original, or symptom cause key) writes nothing and files nothing. A
40
+ * site with no cause key gets the deterministic kind-scoped stand-in.
41
+ * 4. Exempt in BOTH directions (neither attach nor are attached to): the
42
+ * INCIDENT_HOLD_KINDS, whose own row is read by kind as a spawn/cascade hold
43
+ * with a kind-keyed close-half. A cross-product filing (targetProductId) also
44
+ * never attaches -- the Nexus bridge resolves that row by its own id.
45
+ * 5. A failed read or attach write degrades to filing the row (same incident
46
+ * key, own symptom only); correlation never loses a filing.
47
+ * 6. A symptom is part of an incident only while its condition is live. When a
48
+ * close-half observes its condition clear it resolves its own-kind rows AND
49
+ * retires the matching ABSORBED symptoms from the other open rows in the same
50
+ * scope (retireClearedSymptoms): metadata.symptoms is rewritten without them
51
+ * and each is recorded under metadata.cleared_symptoms (bounded). A row's OWN
52
+ * opening symptom (its cause_key / original_cause_key / kind-scoped stand-in)
53
+ * is never retired this way -- that row closes only through its own kind's
54
+ * close-half. Readers (holds, dedup, the wedge arbiter) read only
55
+ * metadata.symptoms, so a retired symptom holds and suppresses nothing.
56
+ *
57
+ * Kept free of VALUE imports that reach @telora/daemon-core or the API client, so
58
+ * the filing chokepoint can depend on it without dragging the mock-loader chain.
59
+ */
60
+ import type { EscalationResolutionClass } from '@telora/daemon-core';
61
+ import { type IncidentSymptom } from './cause-key.js';
62
+ import type { CallApiDeps } from './shared.js';
63
+ /**
64
+ * Kinds whose OWN open row is read BY KIND as a HOLD, released by a kind-keyed
65
+ * close-half: team_failure (the respawn guard), review_coverage_incomplete (the
66
+ * respawn guard, any disposition), review_handoff_exhausted (the state cascade's
67
+ * breaker hold). Absorbing one into another row would silently drop the hold, and
68
+ * absorbing another condition into one would be closed by the hold's own
69
+ * close-half -- so they never correlate in either direction (their rows still
70
+ * carry the shared incident_key).
71
+ */
72
+ export declare const INCIDENT_HOLD_KINDS: ReadonlySet<string>;
73
+ /** The escalation row fields correlation reads (the escalation_list summary shape). */
74
+ export interface IncidentRow {
75
+ id: string;
76
+ status?: string | null;
77
+ disposition?: string | null;
78
+ escalationKind?: string | null;
79
+ focusId?: string | null;
80
+ deliveryId?: string | null;
81
+ productId?: string | null;
82
+ createdAt?: string | null;
83
+ metadata?: Record<string, unknown> | null;
84
+ }
85
+ /** First-class provenance a filing resolved to (explicit params already applied). */
86
+ export interface IncidentProvenance {
87
+ productId?: string;
88
+ focusId?: string;
89
+ deliveryId?: string;
90
+ }
91
+ /** The filing fields the incident key and symptoms are derived from. */
92
+ export interface IncidentFilingInput {
93
+ escalationKind?: string;
94
+ description: string;
95
+ metadata?: Record<string, unknown>;
96
+ anchor?: {
97
+ branch?: string;
98
+ };
99
+ targetProductId?: string;
100
+ }
101
+ /** Pure: the incident key a metadata bag carries, or null. */
102
+ export declare function readIncidentKey(metadata: unknown): string | null;
103
+ /** Pure: the well-formed symptoms a metadata bag carries (malformed entries dropped). */
104
+ export declare function readSymptoms(metadata: unknown): IncidentSymptom[];
105
+ /**
106
+ * Pure: the branch a filing is about, read from what the site already carries --
107
+ * anchor.branch (merge + stuck-branch filings), then metadata.branch_name
108
+ * (stuck_focus_branch), then metadata.branch (ci_run_red).
109
+ */
110
+ export declare function filingBranch(input: Pick<IncidentFilingInput, 'anchor' | 'metadata'>): string | null;
111
+ /**
112
+ * Pure: the incident key a filing is stamped with. An inbound notification kind
113
+ * never joins an incident. An incident_key already in the filing's metadata wins
114
+ * (a filing that carries its source's key forward); otherwise the key is
115
+ * derived from the RESOLVED provenance (delivery -> focus -> branch|product).
116
+ */
117
+ export declare function resolveFilingIncidentKey(input: IncidentFilingInput, provenance: IncidentProvenance): string | null;
118
+ /**
119
+ * Pure: one filing's observation as an incident symptom. A filing with no
120
+ * metadata.cause_key (a direct createEscalation site) gets a deterministic
121
+ * kind-scoped stand-in, so a re-observation maps to the same symptom. The routed
122
+ * observation's proposed disposition AND proposed human act ride on the symptom, so
123
+ * neither is lost when the filing attaches to another row: every absorbed
124
+ * detector's proposal reaches the routing decider, not only the opener's. A
125
+ * metadata.human_act is carried too, but the daemon chokepoint never writes one, so
126
+ * no daemon filing's symptom has it.
127
+ */
128
+ export declare function filingSymptom(input: IncidentFilingInput, key: string, observedAt: string): IncidentSymptom;
129
+ /**
130
+ * Pure: stamp a filing's metadata with its incident key and append its own
131
+ * symptom to whatever symptoms it already carries (none for a fresh row, so the
132
+ * opener is the first entry; a carried list otherwise).
133
+ * A null key leaves the metadata untouched.
134
+ */
135
+ export declare function stampIncidentMetadata(input: IncidentFilingInput, key: string | null, observedAt: string): Record<string, unknown> | undefined;
136
+ /** Pure: a row sits in the machine lane (agent_resolvable); everything else is human-facing. */
137
+ export declare function isMachineLaneRow(row: Pick<IncidentRow, 'disposition'>): boolean;
138
+ /** Pure: the cause keys recorded as symptoms on an OPEN row (idempotency survives correlation). */
139
+ export declare function openRowSymptomCauseKeys(row: IncidentRow): string[];
140
+ /** Pure: whether a filing may correlate at all (contract rule 4). */
141
+ export declare function filingMayCorrelate(input: Pick<IncidentFilingInput, 'escalationKind' | 'targetProductId'>): boolean;
142
+ /**
143
+ * Pure: the OPEN row of incident `key` in the filing's lane (contract rule 1), or
144
+ * null. Lane = the SENT disposition (null and undefined are one lane). Hold-kind
145
+ * rows are never a target. Among several, the oldest wins (createdAt ascending;
146
+ * rows without one keep list order, which escalation_list returns newest-first, so
147
+ * a later entry is older).
148
+ */
149
+ export declare function findLaneIncidentRow(rows: readonly IncidentRow[], key: string, disposition: string | null | undefined): IncidentRow | null;
150
+ /** Pure: whether a row already carries `causeKey` -- its own, its original, or a symptom's. */
151
+ export declare function rowCarriesCause(row: IncidentRow, causeKey: string): boolean;
152
+ /** The I/O correlation needs, injected so the reducer stays testable without the API client. */
153
+ export interface IncidentAttachIo {
154
+ /** The OPEN rows (pending/in_review) a filing may attach to, narrowed server-side by focus when known. */
155
+ listOpenRows: (opts: {
156
+ focusId?: string;
157
+ }) => Promise<IncidentRow[]>;
158
+ /** Shallow-merge a metadata patch onto a row (escalation_update fields.metadata). */
159
+ updateMetadata: (escalationId: string, metadata: Record<string, unknown>) => Promise<void>;
160
+ }
161
+ /** The default correlation I/O over a callApi (escalation_list + escalation_update). */
162
+ export declare function incidentIoOver(call: NonNullable<CallApiDeps['callApi']>): IncidentAttachIo;
163
+ /** One filing about to be sent, as the reducer sees it. */
164
+ export interface IncidentCorrelationInput {
165
+ /** The incident key the filing is stamped with (never null here). */
166
+ key: string;
167
+ /** The filing, carrying the ROUTED metadata (human_act / observation). */
168
+ filing: IncidentFilingInput;
169
+ /** The disposition the chokepoint sends (the lane). */
170
+ disposition: string | undefined;
171
+ /** The resolved focus, to narrow the open-row read. */
172
+ focusId?: string;
173
+ observedAt: string;
174
+ }
175
+ /** What the reducer decided. attached / already_carried mean no new row is filed. */
176
+ export interface IncidentCorrelation {
177
+ outcome: 'attached' | 'already_carried' | 'open_row' | 'attach_failed';
178
+ /** The lane row attached to, carrying the cause, or whose attach failed; null for open_row. */
179
+ incidentRowId: string | null;
180
+ /** A log line for the chokepoint, when there is something to say. */
181
+ note: string | null;
182
+ warn: boolean;
183
+ }
184
+ /**
185
+ * Correlate one filing onto its incident (the contract in the module header):
186
+ * attach to the open lane row, report a re-observed cause, or tell the chokepoint
187
+ * to file the row. Never throws -- a failed read or write degrades to open_row /
188
+ * attach_failed, and the chokepoint files the row.
189
+ */
190
+ export declare function correlateFiling(input: IncidentCorrelationInput, io: IncidentAttachIo): Promise<IncidentCorrelation>;
191
+ /**
192
+ * Pure: whether a row answers for `kind` in a DEDUP read: its own column kind,
193
+ * the legacy metadata.kind, a hand-off row's metadata.originalKind or
194
+ * original_cause_key, or any symptom correlated onto it (by kind or by a cause key
195
+ * minted for the kind, `<kind>::...`). Hold reads must NOT use this -- a handed-off
196
+ * or absorbed condition has no close-half that would clear a hold keyed on it.
197
+ */
198
+ export declare function rowAnswersForKind(row: IncidentRow, kind: string): boolean;
199
+ /** Pure: a symptom is an observation of `kind` -- by its kind, or by a cause key minted for the kind (`<kind>::...`). */
200
+ export declare function symptomAnswersForKind(symptom: IncidentSymptom, kind: string): boolean;
201
+ /**
202
+ * Pure: whether a row is about `deliveryId` in a DEDUP read: the delivery_id
203
+ * column, the metadata fallbacks, or an incident key naming the delivery (a
204
+ * historic promotion refile is anchored to the focus, so only its carried key names it).
205
+ */
206
+ export declare function rowNamesDelivery(row: IncidentRow, deliveryId: string): boolean;
207
+ /**
208
+ * Pure: an OPEN row of `kind` on `focusId` -- the typed focus_id + escalation_kind
209
+ * columns, or (back-compat, a row filed before the column promotion)
210
+ * metadata.focusId + metadata.kind. With `matchCorrelated` (DEDUP reads only), also
211
+ * a row on the focus answering for the kind as a hand-off row or a correlated
212
+ * symptom (rowAnswersForKind).
213
+ */
214
+ export declare function isOpenFocusKindRow(row: IncidentRow, focusId: string, kind: string, matchCorrelated?: boolean): boolean;
215
+ /**
216
+ * Pure: an OPEN worktree-dirty-class row for `focusId` whose kind is in `kinds`.
217
+ * Shared by hasOpenWorktreeDirtyEscalation (dedup, matchCorrelated) and
218
+ * resolveOpenWorktreeDirtyEscalations (auto-close, never correlated: it must not
219
+ * close a row whose own condition is a different one) so both agree on what counts.
220
+ *
221
+ * The status re-check is defense-in-depth. The live escalation_list handler
222
+ * already honors the `statuses` filter server-side, but the invariant "a RESOLVED
223
+ * worktree-dirty row must never suppress (or be re-resolved as) a legitimate new
224
+ * escalation" must hold however the rows were fetched (custom `kinds`, a future
225
+ * caller that forgets the statuses filter, etc.).
226
+ */
227
+ export declare function isOpenWorktreeDirtyMatch(row: IncidentRow, focusId: string, kinds: ReadonlySet<string>, matchCorrelated?: boolean): boolean;
228
+ /** One retired symptom, recorded on its row under metadata.cleared_symptoms (snake_case JSONB). */
229
+ export interface ClearedSymptom {
230
+ cause_key: string;
231
+ escalation_kind: string | null;
232
+ cleared_at: string;
233
+ resolution_class: string;
234
+ }
235
+ /**
236
+ * A close-half's clearing event: WHICH absorbed symptoms its condition clearing
237
+ * retires, and WHERE. `scope` must be at least as narrow as the close-half's own
238
+ * row match; a row is touched only when it matches every scope field given, and an
239
+ * EMPTY scope touches nothing (fail-safe: never org-wide).
240
+ */
241
+ export interface SymptomClearing {
242
+ /** Symptom kinds the event clears (symptomAnswersForKind). */
243
+ kinds?: readonly string[];
244
+ /** Exact symptom cause keys the event clears. */
245
+ causeKeys?: readonly string[];
246
+ scope: {
247
+ focusId?: string;
248
+ productId?: string;
249
+ };
250
+ /** The class of actor that observed the clearing (the close-half's own resolution class). */
251
+ resolutionClass: EscalationResolutionClass;
252
+ }
253
+ /** Pure: the well-formed cleared-symptom records a metadata bag carries. */
254
+ export declare function readClearedSymptoms(metadata: unknown): ClearedSymptom[];
255
+ /**
256
+ * Pure: the cause keys that are a row's OWN -- its metadata.cause_key, a hand-off
257
+ * row's original_cause_key, and the kind-scoped stand-in its opening symptom got
258
+ * when filed without a cause key (filingSymptom). Never retired by retirement.
259
+ */
260
+ export declare function rowOwnCauseKeys(row: IncidentRow): Set<string>;
261
+ /**
262
+ * Pure: the metadata patch that retires a clearing's matching absorbed symptoms from
263
+ * one row -- the remaining metadata.symptoms plus metadata.cleared_symptoms with each
264
+ * retired one appended (de-duped by cause key, newest kept, bounded to
265
+ * INCIDENT_SYMPTOM_CAP) -- or null when the row is closed, out of scope, or carries
266
+ * nothing to retire. The row's own opening symptom is never retired.
267
+ */
268
+ export declare function symptomRetirementPatch(row: IncidentRow, clearing: SymptomClearing, clearedAt: string): {
269
+ symptoms: IncidentSymptom[];
270
+ cleared_symptoms: ClearedSymptom[];
271
+ } | null;
272
+ /** What a retirement pass did: symptoms retired, and warnings for the caller to log. */
273
+ export interface SymptomRetirementOutcome {
274
+ retired: number;
275
+ warnings: string[];
276
+ }
277
+ /**
278
+ * Retire a clearing's matching absorbed symptoms from the OPEN rows in its scope
279
+ * (contract rule 6). `rows` reuses rows the close-half already read for the scope
280
+ * (no second read); omitted, the open rows are read, narrowed by scope.focusId.
281
+ * `skipIds` are the close-half's own rows (being resolved, not rewritten). A clearing
282
+ * of hold kinds only reads nothing -- a hold kind is never absorbed (rule 4).
283
+ * Best-effort and never throws: a failed read or write becomes a warning and the
284
+ * pass continues. The write reads-then-writes like an attach (not atomic).
285
+ */
286
+ export declare function retireClearedSymptoms(clearing: SymptomClearing, io: IncidentAttachIo, opts?: {
287
+ rows?: readonly IncidentRow[];
288
+ skipIds?: readonly string[];
289
+ clearedAt?: string;
290
+ }): Promise<SymptomRetirementOutcome>;
291
+ //# sourceMappingURL=incident-correlation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"incident-correlation.d.ts","sourceRoot":"","sources":["../../src/queries/incident-correlation.ts"],"names":[],"mappings":"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"}