@telora/daemon 0.22.181 → 0.22.187

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 (173) hide show
  1. package/build-info.json +9 -3
  2. package/dist/audit/audit-floor-policy.d.ts +188 -0
  3. package/dist/audit/audit-floor-policy.d.ts.map +1 -0
  4. package/dist/audit/audit-floor-policy.js +353 -0
  5. package/dist/audit/audit-floor-policy.js.map +1 -0
  6. package/dist/audit/audit-prompt.d.ts +4 -177
  7. package/dist/audit/audit-prompt.d.ts.map +1 -1
  8. package/dist/audit/audit-prompt.js +6 -329
  9. package/dist/audit/audit-prompt.js.map +1 -1
  10. package/dist/completion/escalations.d.ts.map +1 -1
  11. package/dist/completion/escalations.js +3 -1
  12. package/dist/completion/escalations.js.map +1 -1
  13. package/dist/focus/focus-executor.d.ts.map +1 -1
  14. package/dist/focus/focus-executor.js +2 -0
  15. package/dist/focus/focus-executor.js.map +1 -1
  16. package/dist/focus/session-health.d.ts.map +1 -1
  17. package/dist/focus/session-health.js +2 -1
  18. package/dist/focus/session-health.js.map +1 -1
  19. package/dist/focus-stage-lifecycle/planning-release.d.ts +52 -17
  20. package/dist/focus-stage-lifecycle/planning-release.d.ts.map +1 -1
  21. package/dist/focus-stage-lifecycle/planning-release.js +58 -70
  22. package/dist/focus-stage-lifecycle/planning-release.js.map +1 -1
  23. package/dist/focus-stage-lifecycle/ratify-bar-gate.d.ts +108 -0
  24. package/dist/focus-stage-lifecycle/ratify-bar-gate.d.ts.map +1 -0
  25. package/dist/focus-stage-lifecycle/ratify-bar-gate.js +174 -0
  26. package/dist/focus-stage-lifecycle/ratify-bar-gate.js.map +1 -0
  27. package/dist/git/merge-to-main.d.ts.map +1 -1
  28. package/dist/git/merge-to-main.js.map +1 -1
  29. package/dist/nexus/index.d.ts.map +1 -1
  30. package/dist/nexus/index.js +2 -1
  31. package/dist/nexus/index.js.map +1 -1
  32. package/dist/nexus/intake-prompt-sections.d.ts +70 -0
  33. package/dist/nexus/intake-prompt-sections.d.ts.map +1 -0
  34. package/dist/nexus/intake-prompt-sections.js +145 -0
  35. package/dist/nexus/intake-prompt-sections.js.map +1 -0
  36. package/dist/nexus/intake-spawn.d.ts +49 -13
  37. package/dist/nexus/intake-spawn.d.ts.map +1 -1
  38. package/dist/nexus/intake-spawn.js +45 -122
  39. package/dist/nexus/intake-spawn.js.map +1 -1
  40. package/dist/nexus/intake.d.ts +55 -0
  41. package/dist/nexus/intake.d.ts.map +1 -1
  42. package/dist/nexus/intake.js +62 -1
  43. package/dist/nexus/intake.js.map +1 -1
  44. package/dist/prd/arm-readiness.d.ts +93 -0
  45. package/dist/prd/arm-readiness.d.ts.map +1 -0
  46. package/dist/prd/arm-readiness.js +254 -0
  47. package/dist/prd/arm-readiness.js.map +1 -0
  48. package/dist/prd/arm-refusal.d.ts +149 -0
  49. package/dist/prd/arm-refusal.d.ts.map +1 -0
  50. package/dist/prd/arm-refusal.js +219 -0
  51. package/dist/prd/arm-refusal.js.map +1 -0
  52. package/dist/prd/controller-shared.d.ts +111 -0
  53. package/dist/prd/controller-shared.d.ts.map +1 -1
  54. package/dist/prd/controller-shared.js +3 -1
  55. package/dist/prd/controller-shared.js.map +1 -1
  56. package/dist/prd/controller.d.ts +16 -10
  57. package/dist/prd/controller.d.ts.map +1 -1
  58. package/dist/prd/controller.js +28 -35
  59. package/dist/prd/controller.js.map +1 -1
  60. package/dist/prd/frontier-arming.d.ts +151 -0
  61. package/dist/prd/frontier-arming.d.ts.map +1 -0
  62. package/dist/prd/frontier-arming.js +315 -0
  63. package/dist/prd/frontier-arming.js.map +1 -0
  64. package/dist/prd/index.d.ts +10 -1
  65. package/dist/prd/index.d.ts.map +1 -1
  66. package/dist/prd/index.js +9 -1
  67. package/dist/prd/index.js.map +1 -1
  68. package/dist/prd/scoping-prompt.d.ts +68 -0
  69. package/dist/prd/scoping-prompt.d.ts.map +1 -0
  70. package/dist/prd/scoping-prompt.js +86 -0
  71. package/dist/prd/scoping-prompt.js.map +1 -0
  72. package/dist/prompt/prompt-contradictions.d.ts +20 -1
  73. package/dist/prompt/prompt-contradictions.d.ts.map +1 -1
  74. package/dist/prompt/prompt-contradictions.js +35 -0
  75. package/dist/prompt/prompt-contradictions.js.map +1 -1
  76. package/dist/prompt/team-prompt-base.d.ts +18 -0
  77. package/dist/prompt/team-prompt-base.d.ts.map +1 -1
  78. package/dist/prompt/team-prompt-base.js +56 -11
  79. package/dist/prompt/team-prompt-base.js.map +1 -1
  80. package/dist/prompt-sections/persona-sections.d.ts +36 -13
  81. package/dist/prompt-sections/persona-sections.d.ts.map +1 -1
  82. package/dist/prompt-sections/persona-sections.js +93 -16
  83. package/dist/prompt-sections/persona-sections.js.map +1 -1
  84. package/dist/prompt-sections/scoping-sections.d.ts +19 -5
  85. package/dist/prompt-sections/scoping-sections.d.ts.map +1 -1
  86. package/dist/prompt-sections/scoping-sections.js +45 -38
  87. package/dist/prompt-sections/scoping-sections.js.map +1 -1
  88. package/dist/prompt-sections/shared.d.ts +8 -0
  89. package/dist/prompt-sections/shared.d.ts.map +1 -1
  90. package/dist/prompt-sections/shared.js.map +1 -1
  91. package/dist/queries/focus-criteria-standing.d.ts +170 -7
  92. package/dist/queries/focus-criteria-standing.d.ts.map +1 -1
  93. package/dist/queries/focus-criteria-standing.js +143 -8
  94. package/dist/queries/focus-criteria-standing.js.map +1 -1
  95. package/dist/queries/focus-ratify-release.d.ts +43 -0
  96. package/dist/queries/focus-ratify-release.d.ts.map +1 -0
  97. package/dist/queries/focus-ratify-release.js +45 -0
  98. package/dist/queries/focus-ratify-release.js.map +1 -0
  99. package/dist/queries/focuses.d.ts +0 -10
  100. package/dist/queries/focuses.d.ts.map +1 -1
  101. package/dist/queries/focuses.js +0 -14
  102. package/dist/queries/focuses.js.map +1 -1
  103. package/dist/queries/prd.d.ts +31 -0
  104. package/dist/queries/prd.d.ts.map +1 -1
  105. package/dist/queries/prd.js +26 -1
  106. package/dist/queries/prd.js.map +1 -1
  107. package/dist/queries/shared.js +1 -1
  108. package/dist/resolvers/focus-criteria-standing.d.ts.map +1 -1
  109. package/dist/resolvers/focus-criteria-standing.js +324 -25
  110. package/dist/resolvers/focus-criteria-standing.js.map +1 -1
  111. package/dist/security/security-auto-inject.d.ts +51 -0
  112. package/dist/security/security-auto-inject.d.ts.map +1 -1
  113. package/dist/security/security-auto-inject.js +101 -11
  114. package/dist/security/security-auto-inject.js.map +1 -1
  115. package/dist/security/security-scan-engine.d.ts +4 -4
  116. package/dist/security/security-scan-engine.d.ts.map +1 -1
  117. package/dist/security/security-scan-engine.js +6 -0
  118. package/dist/security/security-scan-engine.js.map +1 -1
  119. package/dist/session/session-lineage.d.ts.map +1 -1
  120. package/dist/session/session-lineage.js +2 -0
  121. package/dist/session/session-lineage.js.map +1 -1
  122. package/dist/shell/constants.d.ts +5 -0
  123. package/dist/shell/constants.d.ts.map +1 -1
  124. package/dist/shell/constants.js +5 -0
  125. package/dist/shell/constants.js.map +1 -1
  126. package/dist/shell/daemon-instance.d.ts +74 -64
  127. package/dist/shell/daemon-instance.d.ts.map +1 -1
  128. package/dist/shell/daemon-instance.js +16 -121
  129. package/dist/shell/daemon-instance.js.map +1 -1
  130. package/dist/shell/health-events.js +1 -1
  131. package/dist/shell/health-events.js.map +1 -1
  132. package/dist/shell/instance-liveness.d.ts +112 -0
  133. package/dist/shell/instance-liveness.d.ts.map +1 -0
  134. package/dist/shell/instance-liveness.js +205 -0
  135. package/dist/shell/instance-liveness.js.map +1 -0
  136. package/dist/shell/schema-version-gate.d.ts +22 -0
  137. package/dist/shell/schema-version-gate.d.ts.map +1 -1
  138. package/dist/shell/schema-version-gate.js +116 -6
  139. package/dist/shell/schema-version-gate.js.map +1 -1
  140. package/dist/shell/worker-pidfile.d.ts +21 -8
  141. package/dist/shell/worker-pidfile.d.ts.map +1 -1
  142. package/dist/shell/worker-pidfile.js +38 -9
  143. package/dist/shell/worker-pidfile.js.map +1 -1
  144. package/dist/spawn/lead-launch.d.ts.map +1 -1
  145. package/dist/spawn/lead-launch.js +2 -1
  146. package/dist/spawn/lead-launch.js.map +1 -1
  147. package/dist/spawn/one-shot-scoping-spawn.d.ts +51 -0
  148. package/dist/spawn/one-shot-scoping-spawn.d.ts.map +1 -0
  149. package/dist/spawn/one-shot-scoping-spawn.js +156 -0
  150. package/dist/spawn/one-shot-scoping-spawn.js.map +1 -0
  151. package/dist/spawn/process-spawn.d.ts +12 -0
  152. package/dist/spawn/process-spawn.d.ts.map +1 -1
  153. package/dist/spawn/process-spawn.js +1 -1
  154. package/dist/spawn/process-spawn.js.map +1 -1
  155. package/dist/spawn/prompt-assembly.d.ts +8 -0
  156. package/dist/spawn/prompt-assembly.d.ts.map +1 -1
  157. package/dist/spawn/prompt-assembly.js +15 -3
  158. package/dist/spawn/prompt-assembly.js.map +1 -1
  159. package/dist/spawn/worktree-session.d.ts +24 -6
  160. package/dist/spawn/worktree-session.d.ts.map +1 -1
  161. package/dist/spawn/worktree-session.js +37 -14
  162. package/dist/spawn/worktree-session.js.map +1 -1
  163. package/dist/testing/arm-coverage-model.d.ts +75 -0
  164. package/dist/testing/arm-coverage-model.d.ts.map +1 -0
  165. package/dist/testing/arm-coverage-model.js +114 -0
  166. package/dist/testing/arm-coverage-model.js.map +1 -0
  167. package/dist/testing/fixtures/index.js +1 -1
  168. package/dist/types/index.js +1 -1
  169. package/dist/verify/verification-boundary-env.d.ts +7 -2
  170. package/dist/verify/verification-boundary-env.d.ts.map +1 -1
  171. package/dist/verify/verification-boundary-env.js +9 -4
  172. package/dist/verify/verification-boundary-env.js.map +1 -1
  173. package/package.json +2 -2
@@ -3,128 +3,15 @@
3
3
  // packages/daemon/src/shell/crash-recovery-session-scope.test.ts,
4
4
  // packages/daemon/src/shell/daemon-instance.test.ts, packages/daemon/src/worktree/worktree-state.test.ts
5
5
  // PINNED-BY-END
6
- /**
7
- * Daemon INSTANCE identity -- which running daemon owns a session row.
8
- *
9
- * `daemon_hostname` answers "which machine", which is enough to keep one host's
10
- * crash recovery off another host's live work. It is NOT enough to separate two
11
- * daemon instances on the SAME host and product: to that scope they are the
12
- * same owner, so one's recovery sweep would mark the other's running sessions
13
- * failed. It is also not enough to answer the question recovery actually has to
14
- * answer before it writes `failed` -- has the team this row represents actually
15
- * stopped? -- because a hostname says nothing about liveness.
16
- *
17
- * An instance id is `<hostname>:<pid>:<startIdentity>`:
18
- *
19
- * - `pid` is the daemon process, comparable on its own host.
20
- * - `startIdentity` is the kernel's start time for that pid (/proc stat field
21
- * 22 on Linux). It makes the id PID-REUSE SAFE: a new process that happens
22
- * to land on a dead daemon's pid has a different start time, so it is not
23
- * mistaken for the instance that owned those rows.
24
- *
25
- * The id is therefore the thing crash recovery can probe: "is the daemon that
26
- * wrote this row still running?" A row whose owner is alive, or whose owner
27
- * cannot be determined, is left alone.
28
- *
29
- * A dead owner is NOT on its own proof that the row's team stopped. Team leads
30
- * are spawned DETACHED, so they survive a hard-killed daemon; the boot reap
31
- * that ends them (`reapAndClearWorkerPidfile`, unified-shell) is explicitly
32
- * best-effort -- a missing or malformed pidfile yields no entries and a failed
33
- * kill is swallowed. So the destructive pass needs a SECOND proof, about the
34
- * session's own process: `classifySessionProcess`. Both must agree before a row
35
- * is closed.
36
- *
37
- * @module shell/daemon-instance
38
- */
39
- import { hostname } from 'node:os';
40
6
  import { createLogger } from './log.js';
41
7
  import { isProcessAlive } from '../spawn/liveness.js';
42
8
  import { readProcessStartIdentity, isProcessGroupAlive } from '../spawn/process-group-kill.js';
43
9
  import { readLeadRecordsBySession } from './worker-pidfile.js';
10
+ import { classifyOwningInstance, defaultInstanceProbes, isReservationInFlight, } from './instance-liveness.js';
11
+ // The identity half, re-exported so none of this module's importers move. The
12
+ // DEFINING module is instance-liveness.ts; new code should import from there.
13
+ export { daemonInstanceId, resetDaemonInstanceIdCache, parseDaemonInstanceId, defaultInstanceProbes, classifyOwningInstance, isReservationInFlight, } from './instance-liveness.js';
44
14
  const log = createLogger({ module: 'daemon-instance' });
45
- /** Separator between instance-id parts. Hostnames cannot contain ':'. */
46
- const SEP = ':';
47
- /** Memoized so every read within one daemon run returns the same identity. */
48
- let cachedId = null;
49
- /**
50
- * This daemon instance's id. Stamped onto every session it creates, and the
51
- * identity its own crash recovery compares against.
52
- */
53
- export function daemonInstanceId() {
54
- if (cachedId === null) {
55
- const start = readProcessStartIdentity(process.pid);
56
- cachedId = [hostname(), String(process.pid), start ?? 'unknown'].join(SEP);
57
- }
58
- return cachedId;
59
- }
60
- /** Reset the memo. Test seam only -- a daemon's identity never changes in life. */
61
- export function resetDaemonInstanceIdCache() {
62
- cachedId = null;
63
- }
64
- /**
65
- * Parse an instance id, or null when it is absent or malformed. A row written
66
- * by a daemon predating this column parses to null and is treated as
67
- * unattributable -- never as "gone".
68
- */
69
- export function parseDaemonInstanceId(id) {
70
- if (typeof id !== 'string' || id.length === 0)
71
- return null;
72
- const parts = id.split(SEP);
73
- if (parts.length !== 3)
74
- return null;
75
- const [host, pidText, start] = parts;
76
- if (!host || !pidText)
77
- return null;
78
- // STRICT: Number.parseInt('200junk') is 200, which would have us probe an
79
- // unintended pid on the strength of a malformed id. Require all digits.
80
- if (!/^[0-9]+$/.test(pidText))
81
- return null;
82
- const pid = Number.parseInt(pidText, 10);
83
- if (!Number.isInteger(pid) || pid <= 0)
84
- return null;
85
- return { hostname: host, pid, startIdentity: start === 'unknown' ? null : (start ?? null) };
86
- }
87
- /** Real probes against this host. */
88
- export function defaultInstanceProbes() {
89
- return {
90
- selfId: daemonInstanceId(),
91
- selfHostname: hostname(),
92
- isProcessAlive,
93
- readStartIdentity: readProcessStartIdentity,
94
- };
95
- }
96
- /**
97
- * Classify the instance that owns a session row.
98
- *
99
- * Every branch that is not `gone` leaves the row alone, because only `gone` is
100
- * positive evidence that the team the row represents has stopped. Recovery
101
- * would rather leave a stale row than falsify a live one: a stale `running` row
102
- * is visible and self-correcting on the next sweep, whereas a live session
103
- * marked `failed` silently tells every reader -- including "is this worktree
104
- * being written?" -- that a running team is not there.
105
- */
106
- export function classifyOwningInstance(instanceId, deps) {
107
- if (instanceId === deps.selfId)
108
- return 'self';
109
- const parsed = parseDaemonInstanceId(instanceId);
110
- if (parsed === null)
111
- return 'unknown';
112
- // A pid from another machine is not a pid we can probe. The host scope should
113
- // already have excluded it; if one arrives anyway, it is unknown, not gone.
114
- if (parsed.hostname !== deps.selfHostname)
115
- return 'unknown';
116
- if (!deps.isProcessAlive(parsed.pid))
117
- return 'gone';
118
- // The pid is alive -- but is it the SAME process, or a reused pid? A start
119
- // identity that disagrees means the original instance died and its pid was
120
- // recycled, so the owner IS gone.
121
- const liveStart = deps.readStartIdentity(parsed.pid);
122
- if (parsed.startIdentity !== null && liveStart !== null && parsed.startIdentity !== liveStart) {
123
- return 'gone';
124
- }
125
- // Alive, and nothing contradicts that it is the owner. Leave it.
126
- return 'peer_alive';
127
- }
128
15
  /**
129
16
  * Real probes against this host. The lead-record read is memoized PER PROBE
130
17
  * OBJECT: a sweep classifying many rows reads the file once, and every row in
@@ -142,13 +29,21 @@ export function defaultSessionProcessProbes() {
142
29
  cached = readLeadRecordsBySession();
143
30
  return cached;
144
31
  },
32
+ // Bound to the real host probes. This is the DEFAULT the mars-shaped
33
+ // stranded reservation is judged by, not only an injected test seam.
34
+ reservationInFlight: (reservedBy) => isReservationInFlight(reservedBy),
145
35
  };
146
36
  }
147
37
  export function classifyRecordedProcess(record, probes) {
148
- // A RESERVATION: the record exists because a spawn was about to happen. It
149
- // names no pid yet, so nothing about it is decidable.
150
- if (record.pending)
151
- return 'indeterminate';
38
+ // A RESERVATION: the record exists because a spawn was about to happen, so it
39
+ // names no pid. Nothing about the PROCESS is decidable -- but whether anything
40
+ // ever will be is, and that is what `reservedBy` answers. A reservation whose
41
+ // reserving instance is still running (or cannot be attributed at all) is in
42
+ // flight and stays `indeterminate`; one whose instance is provably gone is
43
+ // stranded, will never be resolved by anyone, and reads `gone`.
44
+ if (record.pending) {
45
+ return probes.reservationInFlight(record.reservedBy) ? 'indeterminate' : 'gone';
46
+ }
152
47
  const { pid } = record;
153
48
  if (!Number.isInteger(pid) || pid <= 1)
154
49
  return 'indeterminate';
@@ -1 +1 @@
1
- {"version":3,"file":"daemon-instance.js","sourceRoot":"","sources":["../../src/shell/daemon-instance.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"daemon-instance.js","sourceRoot":"","sources":["../../src/shell/daemon-instance.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
- // Pinned by: none -- no test imports this module directly (baselined; see lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/shell/schema-version-gate.test.ts
3
3
  // PINNED-BY-END
4
4
  /**
5
5
  * Daemon-local seam over daemon-core's healthEvents buffer.
@@ -1 +1 @@
1
- {"version":3,"file":"health-events.js","sourceRoot":"","sources":["../../src/shell/health-events.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,0FAA0F;AAC1F,gBAAgB;AAEhB;;;;;;;GAOG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"health-events.js","sourceRoot":"","sources":["../../src/shell/health-events.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,mEAAmE;AACnE,gBAAgB;AAEhB;;;;;;;GAOG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,112 @@
1
+ /** The parts of a parsed instance id. */
2
+ export interface DaemonInstance {
3
+ hostname: string;
4
+ pid: number;
5
+ /** Kernel start time of the daemon pid; null when the platform cannot supply one. */
6
+ startIdentity: string | null;
7
+ }
8
+ /**
9
+ * This daemon instance's id. Stamped onto every session it creates, onto every
10
+ * lead-record RESERVATION it makes, and the identity its own crash recovery
11
+ * compares against.
12
+ */
13
+ export declare function daemonInstanceId(): string;
14
+ /** Reset the memo. Test seam only -- a daemon's identity never changes in life. */
15
+ export declare function resetDaemonInstanceIdCache(): void;
16
+ /**
17
+ * Parse an instance id, or null when it is absent or malformed. A row written
18
+ * by a daemon predating this column parses to null and is treated as
19
+ * unattributable -- never as "gone".
20
+ */
21
+ export declare function parseDaemonInstanceId(id: string | null | undefined): DaemonInstance | null;
22
+ /**
23
+ * What a session row's owning instance is doing now.
24
+ *
25
+ * - `self` -- this daemon owns it. Never reap: the team is ours and live.
26
+ * - `peer_alive` -- another daemon instance on this host is still running. Its
27
+ * sessions are its business; reaping them is the defect.
28
+ * - `gone` -- the owning instance is not running. Its teams stopped with
29
+ * it, so its rows are safe to close.
30
+ * - `unknown` -- no id, a malformed id, or an id from another host whose pid
31
+ * we cannot probe. FAILS SAFE: not reaped.
32
+ */
33
+ export type InstanceLiveness = 'self' | 'peer_alive' | 'gone' | 'unknown';
34
+ /** Probes `classifyOwningInstance` reaches, injectable for tests. */
35
+ export interface InstanceProbeDeps {
36
+ selfId: string;
37
+ selfHostname: string;
38
+ isProcessAlive: (pid: number) => boolean;
39
+ readStartIdentity: (pid: number) => string | null;
40
+ }
41
+ /** Real probes against this host. */
42
+ export declare function defaultInstanceProbes(): InstanceProbeDeps;
43
+ /**
44
+ * Classify the instance that owns a session row.
45
+ *
46
+ * Every branch that is not `gone` leaves the row alone, because only `gone` is
47
+ * positive evidence that the team the row represents has stopped. Recovery
48
+ * would rather leave a stale row than falsify a live one: a stale `running` row
49
+ * is visible and self-correcting on the next sweep, whereas a live session
50
+ * marked `failed` silently tells every reader -- including "is this worktree
51
+ * being written?" -- that a running team is not there.
52
+ */
53
+ export declare function classifyOwningInstance(instanceId: string | null | undefined, deps: InstanceProbeDeps): InstanceLiveness;
54
+ /**
55
+ * Is a lead-record RESERVATION still in flight?
56
+ *
57
+ * This is the ONE definition of the rule `reserveLeadRecord` has stated in a
58
+ * comment since the field was added: "a reservation is 'in flight' only while
59
+ * the instance that made it is still running; once that instance is provably
60
+ * gone nothing will ever resolve it, and it must not hold a worktree open
61
+ * forever." Two judgements read it -- the retention filter
62
+ * (`recordedLeadStillRunning`, so the reap and boot passes retire a stranded
63
+ * reservation) and the session verdict (`classifyRecordedProcess`, so a live
64
+ * daemon's sweeps stop answering `unprovable` about it forever) -- and both
65
+ * reach it through an injectable dep defaulting here, so there is no second
66
+ * copy of the rule to drift.
67
+ *
68
+ * DIRECTION OF FAILURE. Absent or empty `reservedBy` is IN FLIGHT. A reservation
69
+ * written by a daemon predating the field names nobody, and retiring a record on
70
+ * a guess is the one move this module refuses everywhere: unattributable is not
71
+ * gone. Of the four classifications only `gone` retires; `self`, `peer_alive`
72
+ * and `unknown` (a malformed id, or an id from a host whose pids we cannot
73
+ * probe) all read as in flight.
74
+ *
75
+ * THE OBJECTION, AND WHY `gone` IS NEVERTHELESS THE RIGHT VERDICT.
76
+ * `docs/DECISIONS.md` (2026-09-21) records the consideration this
77
+ * implementation has to answer: expiring a reservation because its reserving
78
+ * instance is gone converts "unprovable" into "nothing was spawned", which is
79
+ * the inference this module refuses everywhere else -- a lead is spawned
80
+ * DETACHED and can outlive the daemon that reserved it, and dropping its only
81
+ * record would make it unnameable by the force-stop and next-boot reaps.
82
+ *
83
+ * The answer is that a reservation is ALREADY unnameable by every kill path, so
84
+ * retiring it costs no reaper anything. Three independent guards see to that,
85
+ * and each is there on purpose:
86
+ *
87
+ * 1. It carries `PENDING_PID` (0). `reapPersistedWorkerGroups` skips every
88
+ * `pending` entry outright, before any liveness probe -- `kill(-0, ...)`
89
+ * signals the CALLER's own process group, which is the daemon.
90
+ * 2. `readWorkerPidfile`, the reader every pid-consuming pass goes through,
91
+ * FILTERS reservations out, so the untracked-lead sweep never sees one.
92
+ * 3. Even if it did, that sweep's `unverifiedReason` refuses to signal any
93
+ * entry with no `startIdentity`, and a reservation has none.
94
+ *
95
+ * So retaining the row buys no kill capability. What retention DOES buy is the
96
+ * claim "we do not know" -- and once the reserving instance is gone that claim
97
+ * can never improve: nothing will ever write the pid, resolve the reservation or
98
+ * release it, so the session it names stays paralysed for good (session-health
99
+ * skips it `unprovable_process`, abandoned-merge recovery refuses to restore its
100
+ * worktree, and the worktree write signal answers `provable: false`). A detached
101
+ * lead that really did survive the window is equally unnameable whether the row
102
+ * is kept or dropped, because its pid was never written. No capability lost,
103
+ * permanent paralysis ended: that asymmetry is what makes `gone` correct here
104
+ * and not elsewhere.
105
+ *
106
+ * Note what this does NOT do: it never retires a reservation of a LIVE instance.
107
+ * `launchLeadProcess` refuses a spawn whose record could not be reserved, so
108
+ * deleting a running daemon's reservation would reopen the very pre-spawn window
109
+ * the reservation exists to close.
110
+ */
111
+ export declare function isReservationInFlight(reservedBy: string | undefined, deps?: InstanceProbeDeps): boolean;
112
+ //# sourceMappingURL=instance-liveness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance-liveness.d.ts","sourceRoot":"","sources":["../../src/shell/instance-liveness.ts"],"names":[],"mappings":"AAgDA,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,qFAAqF;IACrF,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAQD;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAMzC;AAED,mFAAmF;AACnF,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,cAAc,GAAG,IAAI,CAY1F;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,CAAC;AAE1E,qEAAqE;AACrE,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACzC,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACnD;AAED,qCAAqC;AACrC,wBAAgB,qBAAqB,IAAI,iBAAiB,CAOzD;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACrC,IAAI,EAAE,iBAAiB,GACtB,gBAAgB,CAsBlB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,IAAI,GAAE,iBAA2C,GAChD,OAAO,CAoBT"}
@@ -0,0 +1,205 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/shell/daemon-instance.test.ts,
3
+ // packages/daemon/src/shell/worker-pidfile.test.ts
4
+ // PINNED-BY-END
5
+ /**
6
+ * Daemon instance IDENTITY and its liveness -- the leaf half of
7
+ * shell/daemon-instance.ts.
8
+ *
9
+ * `daemon_hostname` answers "which machine", which is enough to keep one host's
10
+ * crash recovery off another host's live work. It is NOT enough to separate two
11
+ * daemon instances on the SAME host and product: to that scope they are the
12
+ * same owner, so one's recovery sweep would mark the other's running sessions
13
+ * failed. It is also not enough to answer the question recovery actually has to
14
+ * answer before it writes `failed` -- has the team this row represents actually
15
+ * stopped? -- because a hostname says nothing about liveness.
16
+ *
17
+ * An instance id is `<hostname>:<pid>:<startIdentity>`:
18
+ *
19
+ * - `pid` is the daemon process, comparable on its own host.
20
+ * - `startIdentity` is the kernel's start time for that pid (/proc stat field
21
+ * 22 on Linux). It makes the id PID-REUSE SAFE: a new process that happens
22
+ * to land on a dead daemon's pid has a different start time, so it is not
23
+ * mistaken for the instance that owned those rows.
24
+ *
25
+ * WHY THIS IS ITS OWN MODULE. It was the first half of `daemon-instance.ts`,
26
+ * which also holds the SESSION-process half and therefore imports
27
+ * `shell/worker-pidfile.ts` (`readLeadRecordsBySession`, `WorkerPidEntry`).
28
+ * That import is one-directional, so `worker-pidfile.ts` could not ask the
29
+ * identity question back -- and asking it is exactly what a reservation's
30
+ * `reservedBy` field needs (see {@link isReservationInFlight}). Splitting the
31
+ * identity half down here inverts nothing and duplicates nothing: this module's
32
+ * imports stop at node:os, the logger and the two process probes, none of which
33
+ * reach the pidfile.
34
+ *
35
+ * @module shell/instance-liveness
36
+ */
37
+ import { hostname } from 'node:os';
38
+ import { createLogger } from './log.js';
39
+ import { isProcessAlive } from '../spawn/liveness.js';
40
+ import { readProcessStartIdentity } from '../spawn/process-group-kill.js';
41
+ // Kept so this module owns a logger of its own rather than borrowing one across
42
+ // the split; the identity probes themselves are silent by design (they are read
43
+ // in tight sweeps and their verdicts are logged by the callers that act on them).
44
+ const log = createLogger({ module: 'instance-liveness' });
45
+ /** Separator between instance-id parts. Hostnames cannot contain ':'. */
46
+ const SEP = ':';
47
+ /** Memoized so every read within one daemon run returns the same identity. */
48
+ let cachedId = null;
49
+ /**
50
+ * This daemon instance's id. Stamped onto every session it creates, onto every
51
+ * lead-record RESERVATION it makes, and the identity its own crash recovery
52
+ * compares against.
53
+ */
54
+ export function daemonInstanceId() {
55
+ if (cachedId === null) {
56
+ const start = readProcessStartIdentity(process.pid);
57
+ cachedId = [hostname(), String(process.pid), start ?? 'unknown'].join(SEP);
58
+ }
59
+ return cachedId;
60
+ }
61
+ /** Reset the memo. Test seam only -- a daemon's identity never changes in life. */
62
+ export function resetDaemonInstanceIdCache() {
63
+ cachedId = null;
64
+ }
65
+ /**
66
+ * Parse an instance id, or null when it is absent or malformed. A row written
67
+ * by a daemon predating this column parses to null and is treated as
68
+ * unattributable -- never as "gone".
69
+ */
70
+ export function parseDaemonInstanceId(id) {
71
+ if (typeof id !== 'string' || id.length === 0)
72
+ return null;
73
+ const parts = id.split(SEP);
74
+ if (parts.length !== 3)
75
+ return null;
76
+ const [host, pidText, start] = parts;
77
+ if (!host || !pidText)
78
+ return null;
79
+ // STRICT: Number.parseInt('200junk') is 200, which would have us probe an
80
+ // unintended pid on the strength of a malformed id. Require all digits.
81
+ if (!/^[0-9]+$/.test(pidText))
82
+ return null;
83
+ const pid = Number.parseInt(pidText, 10);
84
+ if (!Number.isInteger(pid) || pid <= 0)
85
+ return null;
86
+ return { hostname: host, pid, startIdentity: start === 'unknown' ? null : (start ?? null) };
87
+ }
88
+ /** Real probes against this host. */
89
+ export function defaultInstanceProbes() {
90
+ return {
91
+ selfId: daemonInstanceId(),
92
+ selfHostname: hostname(),
93
+ isProcessAlive,
94
+ readStartIdentity: readProcessStartIdentity,
95
+ };
96
+ }
97
+ /**
98
+ * Classify the instance that owns a session row.
99
+ *
100
+ * Every branch that is not `gone` leaves the row alone, because only `gone` is
101
+ * positive evidence that the team the row represents has stopped. Recovery
102
+ * would rather leave a stale row than falsify a live one: a stale `running` row
103
+ * is visible and self-correcting on the next sweep, whereas a live session
104
+ * marked `failed` silently tells every reader -- including "is this worktree
105
+ * being written?" -- that a running team is not there.
106
+ */
107
+ export function classifyOwningInstance(instanceId, deps) {
108
+ if (instanceId === deps.selfId)
109
+ return 'self';
110
+ const parsed = parseDaemonInstanceId(instanceId);
111
+ if (parsed === null)
112
+ return 'unknown';
113
+ // A pid from another machine is not a pid we can probe. The host scope should
114
+ // already have excluded it; if one arrives anyway, it is unknown, not gone.
115
+ if (parsed.hostname !== deps.selfHostname)
116
+ return 'unknown';
117
+ if (!deps.isProcessAlive(parsed.pid))
118
+ return 'gone';
119
+ // The pid is alive -- but is it the SAME process, or a reused pid? A start
120
+ // identity that disagrees means the original instance died and its pid was
121
+ // recycled, so the owner IS gone.
122
+ const liveStart = deps.readStartIdentity(parsed.pid);
123
+ if (parsed.startIdentity !== null && liveStart !== null && parsed.startIdentity !== liveStart) {
124
+ return 'gone';
125
+ }
126
+ // Alive, and nothing contradicts that it is the owner. Leave it.
127
+ return 'peer_alive';
128
+ }
129
+ /**
130
+ * Is a lead-record RESERVATION still in flight?
131
+ *
132
+ * This is the ONE definition of the rule `reserveLeadRecord` has stated in a
133
+ * comment since the field was added: "a reservation is 'in flight' only while
134
+ * the instance that made it is still running; once that instance is provably
135
+ * gone nothing will ever resolve it, and it must not hold a worktree open
136
+ * forever." Two judgements read it -- the retention filter
137
+ * (`recordedLeadStillRunning`, so the reap and boot passes retire a stranded
138
+ * reservation) and the session verdict (`classifyRecordedProcess`, so a live
139
+ * daemon's sweeps stop answering `unprovable` about it forever) -- and both
140
+ * reach it through an injectable dep defaulting here, so there is no second
141
+ * copy of the rule to drift.
142
+ *
143
+ * DIRECTION OF FAILURE. Absent or empty `reservedBy` is IN FLIGHT. A reservation
144
+ * written by a daemon predating the field names nobody, and retiring a record on
145
+ * a guess is the one move this module refuses everywhere: unattributable is not
146
+ * gone. Of the four classifications only `gone` retires; `self`, `peer_alive`
147
+ * and `unknown` (a malformed id, or an id from a host whose pids we cannot
148
+ * probe) all read as in flight.
149
+ *
150
+ * THE OBJECTION, AND WHY `gone` IS NEVERTHELESS THE RIGHT VERDICT.
151
+ * `docs/DECISIONS.md` (2026-09-21) records the consideration this
152
+ * implementation has to answer: expiring a reservation because its reserving
153
+ * instance is gone converts "unprovable" into "nothing was spawned", which is
154
+ * the inference this module refuses everywhere else -- a lead is spawned
155
+ * DETACHED and can outlive the daemon that reserved it, and dropping its only
156
+ * record would make it unnameable by the force-stop and next-boot reaps.
157
+ *
158
+ * The answer is that a reservation is ALREADY unnameable by every kill path, so
159
+ * retiring it costs no reaper anything. Three independent guards see to that,
160
+ * and each is there on purpose:
161
+ *
162
+ * 1. It carries `PENDING_PID` (0). `reapPersistedWorkerGroups` skips every
163
+ * `pending` entry outright, before any liveness probe -- `kill(-0, ...)`
164
+ * signals the CALLER's own process group, which is the daemon.
165
+ * 2. `readWorkerPidfile`, the reader every pid-consuming pass goes through,
166
+ * FILTERS reservations out, so the untracked-lead sweep never sees one.
167
+ * 3. Even if it did, that sweep's `unverifiedReason` refuses to signal any
168
+ * entry with no `startIdentity`, and a reservation has none.
169
+ *
170
+ * So retaining the row buys no kill capability. What retention DOES buy is the
171
+ * claim "we do not know" -- and once the reserving instance is gone that claim
172
+ * can never improve: nothing will ever write the pid, resolve the reservation or
173
+ * release it, so the session it names stays paralysed for good (session-health
174
+ * skips it `unprovable_process`, abandoned-merge recovery refuses to restore its
175
+ * worktree, and the worktree write signal answers `provable: false`). A detached
176
+ * lead that really did survive the window is equally unnameable whether the row
177
+ * is kept or dropped, because its pid was never written. No capability lost,
178
+ * permanent paralysis ended: that asymmetry is what makes `gone` correct here
179
+ * and not elsewhere.
180
+ *
181
+ * Note what this does NOT do: it never retires a reservation of a LIVE instance.
182
+ * `launchLeadProcess` refuses a spawn whose record could not be reserved, so
183
+ * deleting a running daemon's reservation would reopen the very pre-spawn window
184
+ * the reservation exists to close.
185
+ */
186
+ export function isReservationInFlight(reservedBy, deps = defaultInstanceProbes()) {
187
+ if (reservedBy === undefined || reservedBy.length === 0) {
188
+ // Unattributable. Nothing to probe, so nothing is proved -- keep it.
189
+ //
190
+ // Deliberately EXPLICIT even though it is redundant by construction:
191
+ // `classifyOwningInstance` would also answer 'unknown' here (an absent or
192
+ // empty id parses to null). Stating it at the site the rule is about means
193
+ // the safe direction for the field this function exists to read does not
194
+ // depend on how the parser happens to treat an empty string.
195
+ return true;
196
+ }
197
+ const owner = classifyOwningInstance(reservedBy, deps);
198
+ if (owner === 'gone') {
199
+ log.info(`[instance-liveness] reservation made by ${reservedBy} is stranded -- ` +
200
+ 'that daemon instance is provably gone, so nothing will ever resolve it');
201
+ return false;
202
+ }
203
+ return true;
204
+ }
205
+ //# sourceMappingURL=instance-liveness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance-liveness.js","sourceRoot":"","sources":["../../src/shell/instance-liveness.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,16 @@ export interface SchemaGateResult {
9
9
  applied: string[];
10
10
  /** Expected ∖ applied after the final ledger read. Empty when ok. */
11
11
  missing: string[];
12
+ /**
13
+ * Applied ∖ expected after the final ledger read: migrations the LIVE DB
14
+ * carries that this daemon build does not know about -- i.e. this daemon is
15
+ * OLDER than the schema it is about to arm against.
16
+ *
17
+ * Reported and recorded, never gated on: see the "IT IS A REPORT, NOT A
18
+ * GATE" note in the module header. A non-empty value leaves `ok`,
19
+ * `classification` and `attempts` untouched.
20
+ */
21
+ unknownApplied: string[];
12
22
  ok: boolean;
13
23
  /**
14
24
  * Classification of the initial missing set:
@@ -90,6 +100,16 @@ export declare function parseMigrationTimestamp(version: string): number;
90
100
  * or an unparseable timestamp), which cannot be a recoverable deploy tail.
91
101
  */
92
102
  export declare function classifyMissing(missing: string[], applied: string[], cfg: TransientToleranceConfig): Exclude<GapClassification, 'ok'>;
103
+ /**
104
+ * The reverse set: `applied` ∖ `expected` -- migration versions the live DB
105
+ * carries that this daemon build does not know about. Preserves the ledger's
106
+ * own order so the newest unknown versions read last, as they do in the
107
+ * ledger.
108
+ *
109
+ * Exported so the reverse direction is testable on its own, and so a later
110
+ * caller can ask the question without re-deriving the set difference.
111
+ */
112
+ export declare function computeUnknownApplied(expected: string[], applied: string[]): string[];
93
113
  export interface CheckSchemaVersionDeps {
94
114
  mode?: SchemaGateMode;
95
115
  getExpected?: () => string[];
@@ -104,5 +124,7 @@ export interface CheckSchemaVersionDeps {
104
124
  log?: (msg: string) => void;
105
125
  }
106
126
  export declare function checkSchemaVersion(deps?: CheckSchemaVersionDeps): Promise<SchemaGateResult>;
127
+ /** Health-event code for "this daemon is older than the schema it arms against". */
128
+ export declare const DAEMON_BEHIND_DB_CODE = "schema.daemon_behind_db";
107
129
  export declare function reportSchemaGateResult(result: SchemaGateResult): void;
108
130
  //# sourceMappingURL=schema-version-gate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema-version-gate.d.ts","sourceRoot":"","sources":["../../src/shell/schema-version-gate.ts"],"names":[],"mappings":"AA0CA,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC;AAE1D,sEAAsE;AACtE,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,WAAW,GAAG,OAAO,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,uEAAuE;IACvE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,qEAAqE;IACrE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,EAAE,EAAE,OAAO,CAAC;IACZ;;;;;;;OAOG;IACH,cAAc,EAAE,iBAAiB,CAAC;IAClC,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,cAAc,CAO1F;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAItD;AAMD;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,wEAAwE;IACxE,cAAc,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,2BAA2B,EAAE,wBAKzC,CAAC;AAMF;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAC7C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,wBAAwB,CAQ1B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAK/D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,MAAM,EAAE,EACjB,GAAG,EAAE,wBAAwB,GAC5B,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAclC;AASD,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACrC,iEAAiE;IACjE,kBAAkB,CAAC,EAAE,wBAAwB,CAAC;IAC9C,wDAAwD;IACxD,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,wEAAwE;IACxE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,wBAAsB,kBAAkB,CAAC,IAAI,GAAE,sBAA2B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAgErG;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CA8BrE"}
1
+ {"version":3,"file":"schema-version-gate.d.ts","sourceRoot":"","sources":["../../src/shell/schema-version-gate.ts"],"names":[],"mappings":"AA4DA,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC;AAE1D,sEAAsE;AACtE,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,WAAW,GAAG,OAAO,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,uEAAuE;IACvE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,qEAAqE;IACrE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;;;;OAQG;IACH,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ;;;;;;;OAOG;IACH,cAAc,EAAE,iBAAiB,CAAC;IAClC,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,cAAc,CAO1F;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAItD;AAMD;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,wEAAwE;IACxE,cAAc,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,2BAA2B,EAAE,wBAKzC,CAAC;AAMF;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAC7C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,wBAAwB,CAQ1B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAK/D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,MAAM,EAAE,EACjB,GAAG,EAAE,wBAAwB,GAC5B,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAclC;AAOD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAGrF;AAID,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACrC,iEAAiE;IACjE,kBAAkB,CAAC,EAAE,wBAAwB,CAAC;IAC9C,wDAAwD;IACxD,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,wEAAwE;IACxE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,wBAAsB,kBAAkB,CAAC,IAAI,GAAE,sBAA2B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAuFrG;AAED,oFAAoF;AACpF,eAAO,MAAM,qBAAqB,4BAA4B,CAAC;AA4D/D,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CA+BrE"}