@telora/daemon 0.22.189 → 0.22.208

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 (189) hide show
  1. package/build-info.json +6 -3
  2. package/dist/backends/index.d.ts.map +1 -1
  3. package/dist/backends/index.js +2 -0
  4. package/dist/backends/index.js.map +1 -1
  5. package/dist/completion/completion-fact-readers.d.ts +35 -0
  6. package/dist/completion/completion-fact-readers.d.ts.map +1 -0
  7. package/dist/completion/completion-fact-readers.js +70 -0
  8. package/dist/completion/completion-fact-readers.js.map +1 -0
  9. package/dist/completion/event-dep-defaults.d.ts +27 -0
  10. package/dist/completion/event-dep-defaults.d.ts.map +1 -0
  11. package/dist/completion/event-dep-defaults.js +30 -0
  12. package/dist/completion/event-dep-defaults.js.map +1 -0
  13. package/dist/completion/event-phases.d.ts.map +1 -1
  14. package/dist/completion/event-phases.js +5 -13
  15. package/dist/completion/event-phases.js.map +1 -1
  16. package/dist/completion/event.d.ts +32 -0
  17. package/dist/completion/event.d.ts.map +1 -1
  18. package/dist/completion/event.js +31 -25
  19. package/dist/completion/event.js.map +1 -1
  20. package/dist/completion/session-hold.d.ts +13 -1
  21. package/dist/completion/session-hold.d.ts.map +1 -1
  22. package/dist/completion/session-hold.js +18 -0
  23. package/dist/completion/session-hold.js.map +1 -1
  24. package/dist/completion/team-phase.d.ts.map +1 -1
  25. package/dist/completion/team-phase.js +1 -0
  26. package/dist/completion/team-phase.js.map +1 -1
  27. package/dist/completion/unclaimed-migration-notice-phase.d.ts +97 -0
  28. package/dist/completion/unclaimed-migration-notice-phase.d.ts.map +1 -0
  29. package/dist/completion/unclaimed-migration-notice-phase.js +270 -0
  30. package/dist/completion/unclaimed-migration-notice-phase.js.map +1 -0
  31. package/dist/directive/directive-executor.d.ts.map +1 -1
  32. package/dist/directive/directive-executor.js +1 -20
  33. package/dist/directive/directive-executor.js.map +1 -1
  34. package/dist/focus/focus-executor.d.ts +1 -0
  35. package/dist/focus/focus-executor.d.ts.map +1 -1
  36. package/dist/focus/focus-executor.js +18 -17
  37. package/dist/focus/focus-executor.js.map +1 -1
  38. package/dist/focus/focus-team-state.js +1 -1
  39. package/dist/focus/listener-spawn.d.ts.map +1 -1
  40. package/dist/focus/listener-spawn.js +5 -20
  41. package/dist/focus/listener-spawn.js.map +1 -1
  42. package/dist/focus/listener-state.d.ts.map +1 -1
  43. package/dist/focus/listener-state.js +1 -0
  44. package/dist/focus/listener-state.js.map +1 -1
  45. package/dist/focus/listener.d.ts +1 -0
  46. package/dist/focus/listener.d.ts.map +1 -1
  47. package/dist/focus/listener.js +9 -0
  48. package/dist/focus/listener.js.map +1 -1
  49. package/dist/focus/migration-claim-pass.d.ts +50 -0
  50. package/dist/focus/migration-claim-pass.d.ts.map +1 -0
  51. package/dist/focus/migration-claim-pass.js +234 -0
  52. package/dist/focus/migration-claim-pass.js.map +1 -0
  53. package/dist/focus/pending-spawn-pass-deps.d.ts.map +1 -1
  54. package/dist/focus/pending-spawn-pass-deps.js +2 -1
  55. package/dist/focus/pending-spawn-pass-deps.js.map +1 -1
  56. package/dist/focus/team-actionable-work.d.ts +21 -0
  57. package/dist/focus/team-actionable-work.d.ts.map +1 -1
  58. package/dist/focus/team-actionable-work.js +3 -0
  59. package/dist/focus/team-actionable-work.js.map +1 -1
  60. package/dist/git/types.d.ts.map +1 -1
  61. package/dist/git/types.js +2 -1
  62. package/dist/git/types.js.map +1 -1
  63. package/dist/loops/llm-client.d.ts.map +1 -1
  64. package/dist/loops/llm-client.js +11 -1
  65. package/dist/loops/llm-client.js.map +1 -1
  66. package/dist/migrations/migration-claim-lifecycle.d.ts +166 -0
  67. package/dist/migrations/migration-claim-lifecycle.d.ts.map +1 -0
  68. package/dist/migrations/migration-claim-lifecycle.js +198 -0
  69. package/dist/migrations/migration-claim-lifecycle.js.map +1 -0
  70. package/dist/migrations/migration-held-set.d.ts +171 -0
  71. package/dist/migrations/migration-held-set.d.ts.map +1 -0
  72. package/dist/migrations/migration-held-set.js +295 -0
  73. package/dist/migrations/migration-held-set.js.map +1 -0
  74. package/dist/migrations/migration-inventory.d.ts +187 -0
  75. package/dist/migrations/migration-inventory.d.ts.map +1 -0
  76. package/dist/migrations/migration-inventory.js +253 -0
  77. package/dist/migrations/migration-inventory.js.map +1 -0
  78. package/dist/migrations/migration-manifest.d.ts +114 -0
  79. package/dist/migrations/migration-manifest.d.ts.map +1 -0
  80. package/dist/migrations/migration-manifest.js +295 -0
  81. package/dist/migrations/migration-manifest.js.map +1 -0
  82. package/dist/prompt/team-prompt-base.js +1 -1
  83. package/dist/prompt-sections/migration-numbering-section.d.ts +58 -0
  84. package/dist/prompt-sections/migration-numbering-section.d.ts.map +1 -0
  85. package/dist/prompt-sections/migration-numbering-section.js +70 -0
  86. package/dist/prompt-sections/migration-numbering-section.js.map +1 -0
  87. package/dist/prompt-sections/migration-numbering-state.d.ts +30 -0
  88. package/dist/prompt-sections/migration-numbering-state.d.ts.map +1 -0
  89. package/dist/prompt-sections/migration-numbering-state.js +24 -0
  90. package/dist/prompt-sections/migration-numbering-state.js.map +1 -0
  91. package/dist/prompt-sections/unclaimed-migration-section.d.ts +38 -0
  92. package/dist/prompt-sections/unclaimed-migration-section.d.ts.map +1 -0
  93. package/dist/prompt-sections/unclaimed-migration-section.js +57 -0
  94. package/dist/prompt-sections/unclaimed-migration-section.js.map +1 -0
  95. package/dist/queries/claim-pass-focuses.d.ts +19 -0
  96. package/dist/queries/claim-pass-focuses.d.ts.map +1 -0
  97. package/dist/queries/claim-pass-focuses.js +72 -0
  98. package/dist/queries/claim-pass-focuses.js.map +1 -0
  99. package/dist/queries/daemon-connection.d.ts.map +1 -1
  100. package/dist/queries/daemon-connection.js +1 -0
  101. package/dist/queries/daemon-connection.js.map +1 -1
  102. package/dist/queries/focus-discovery.d.ts +25 -2
  103. package/dist/queries/focus-discovery.d.ts.map +1 -1
  104. package/dist/queries/focus-discovery.js +16 -9
  105. package/dist/queries/focus-discovery.js.map +1 -1
  106. package/dist/queries/focus-unclaimed-migration.d.ts +146 -0
  107. package/dist/queries/focus-unclaimed-migration.d.ts.map +1 -0
  108. package/dist/queries/focus-unclaimed-migration.js +266 -0
  109. package/dist/queries/focus-unclaimed-migration.js.map +1 -0
  110. package/dist/queries/live-focus-branches.d.ts +32 -0
  111. package/dist/queries/live-focus-branches.d.ts.map +1 -0
  112. package/dist/queries/live-focus-branches.js +66 -0
  113. package/dist/queries/live-focus-branches.js.map +1 -0
  114. package/dist/queries/migration-claims.d.ts +25 -0
  115. package/dist/queries/migration-claims.d.ts.map +1 -0
  116. package/dist/queries/migration-claims.js +79 -0
  117. package/dist/queries/migration-claims.js.map +1 -0
  118. package/dist/queries/schemas.d.ts +2 -0
  119. package/dist/queries/schemas.d.ts.map +1 -1
  120. package/dist/queries/schemas.js +6 -0
  121. package/dist/queries/schemas.js.map +1 -1
  122. package/dist/queries/shared.js +1 -1
  123. package/dist/session/session-lineage.d.ts.map +1 -1
  124. package/dist/session/session-lineage.js +3 -0
  125. package/dist/session/session-lineage.js.map +1 -1
  126. package/dist/shell/heartbeat-metadata.d.ts +48 -2
  127. package/dist/shell/heartbeat-metadata.d.ts.map +1 -1
  128. package/dist/shell/heartbeat-metadata.js +80 -3
  129. package/dist/shell/heartbeat-metadata.js.map +1 -1
  130. package/dist/shell/heartbeat.d.ts +13 -0
  131. package/dist/shell/heartbeat.d.ts.map +1 -1
  132. package/dist/shell/heartbeat.js +31 -10
  133. package/dist/shell/heartbeat.js.map +1 -1
  134. package/dist/shell/mcp-resolution.js +1 -1
  135. package/dist/shell/mcp-resolution.js.map +1 -1
  136. package/dist/shell/migration-held-set-publish.d.ts +170 -0
  137. package/dist/shell/migration-held-set-publish.d.ts.map +1 -0
  138. package/dist/shell/migration-held-set-publish.js +172 -0
  139. package/dist/shell/migration-held-set-publish.js.map +1 -0
  140. package/dist/shell/worker-pidfile.d.ts.map +1 -1
  141. package/dist/shell/worker-pidfile.js +1 -0
  142. package/dist/shell/worker-pidfile.js.map +1 -1
  143. package/dist/spawn/helpers.d.ts.map +1 -1
  144. package/dist/spawn/helpers.js +1 -0
  145. package/dist/spawn/helpers.js.map +1 -1
  146. package/dist/spawn/lead-launch.d.ts.map +1 -1
  147. package/dist/spawn/lead-launch.js +1 -0
  148. package/dist/spawn/lead-launch.js.map +1 -1
  149. package/dist/spawn/lead-process-ownership.d.ts.map +1 -1
  150. package/dist/spawn/lead-process-ownership.js +1 -0
  151. package/dist/spawn/lead-process-ownership.js.map +1 -1
  152. package/dist/spawn/process-group-kill.d.ts.map +1 -1
  153. package/dist/spawn/process-group-kill.js +1 -0
  154. package/dist/spawn/process-group-kill.js.map +1 -1
  155. package/dist/spawn/process-spawn.d.ts +18 -1
  156. package/dist/spawn/process-spawn.d.ts.map +1 -1
  157. package/dist/spawn/process-spawn.js +11 -6
  158. package/dist/spawn/process-spawn.js.map +1 -1
  159. package/dist/spawn/prompt-assembly.d.ts +115 -18
  160. package/dist/spawn/prompt-assembly.d.ts.map +1 -1
  161. package/dist/spawn/prompt-assembly.js +121 -2
  162. package/dist/spawn/prompt-assembly.js.map +1 -1
  163. package/dist/spawn/spawn-and-acknowledge.d.ts +61 -0
  164. package/dist/spawn/spawn-and-acknowledge.d.ts.map +1 -0
  165. package/dist/spawn/spawn-and-acknowledge.js +117 -0
  166. package/dist/spawn/spawn-and-acknowledge.js.map +1 -0
  167. package/dist/spawn/spawn-cooldown.js +1 -1
  168. package/dist/spawn/spawn-decision.d.ts +10 -10
  169. package/dist/spawn/spawn-decision.d.ts.map +1 -1
  170. package/dist/spawn/spawn-decision.js +33 -5
  171. package/dist/spawn/spawn-decision.js.map +1 -1
  172. package/dist/templates/claude-md.d.ts +1 -1
  173. package/dist/templates/claude-md.d.ts.map +1 -1
  174. package/dist/templates/claude-md.js +24 -0
  175. package/dist/templates/claude-md.js.map +1 -1
  176. package/dist/testing/fixtures/index.js +1 -1
  177. package/dist/testing/fixtures/migration-namespace-repo.d.ts +63 -0
  178. package/dist/testing/fixtures/migration-namespace-repo.d.ts.map +1 -0
  179. package/dist/testing/fixtures/migration-namespace-repo.js +164 -0
  180. package/dist/testing/fixtures/migration-namespace-repo.js.map +1 -0
  181. package/dist/testing/fixtures/stubborn-lead-process.d.ts.map +1 -1
  182. package/dist/testing/fixtures/stubborn-lead-process.js +1 -0
  183. package/dist/testing/fixtures/stubborn-lead-process.js.map +1 -1
  184. package/dist/types/index.js +1 -1
  185. package/dist/verify/no-own-delta-verdict.d.ts +16 -2
  186. package/dist/verify/no-own-delta-verdict.d.ts.map +1 -1
  187. package/dist/verify/no-own-delta-verdict.js +18 -2
  188. package/dist/verify/no-own-delta-verdict.js.map +1 -1
  189. package/package.json +2 -2
@@ -0,0 +1,266 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/completion/exit-unclaimed-migration-hold.test.ts,
3
+ // packages/daemon/src/completion/unclaimed-migration-notice-phase.test.ts,
4
+ // packages/daemon/src/queries/focus-unclaimed-migration.test.ts,
5
+ // packages/daemon/src/spawn/migration-numbering-wiring.test.ts
6
+ // PINNED-BY-END
7
+ /**
8
+ * The focus's durable record of "my branch holds a migration I never claimed",
9
+ * and its clear.
10
+ *
11
+ * WHY THIS IS STATE AND NOT AN ESCALATION. It names no human-only act: the team
12
+ * that wrote the file is the one that can claim the number or remove it. An
13
+ * escalation would be a row in a human queue that can only wait for the same
14
+ * team to act, and a routine triage pass could resolve it while the file is
15
+ * still unclaimed. So it is a fact about the focus that clears itself when the
16
+ * fact stops being true.
17
+ *
18
+ * WHY focus_debug_artifacts, and not the deliveries' git_state: the same reason
19
+ * `focus-integration-conflict.ts` gives. `org_nodes.git_state` is a
20
+ * forward-only ladder with one slot per delivery, and this is a fact about the
21
+ * focus BRANCH shared by every delivery on it -- with no room for the number or
22
+ * the path. A debug section is one row per (focus, kind), rendered with its own
23
+ * stamp, read by nothing in the machine's decision path, and cleared by
24
+ * DELETING the row, which is exactly what "until the team claims or removes it"
25
+ * wants.
26
+ *
27
+ * SINCE-WHEN SURVIVES THE RE-RECORD. `updated_at` moves on every write and the
28
+ * record is re-written on every pass that still sees the file, so `updated_at`
29
+ * alone would always read "just now" and hide a file unclaimed for a week. The
30
+ * content carries `Unclaimed since:` explicitly and a re-record reads the
31
+ * existing section and carries the value forward; a failed read degrades to
32
+ * "since now" rather than losing the record.
33
+ *
34
+ * @module queries/focus-unclaimed-migration
35
+ */
36
+ import { callApi } from './shared.js';
37
+ /** The focus_debug_artifacts section the record lives in. */
38
+ export const UNCLAIMED_MIGRATION_SECTION_KIND = 'unclaimed_migration';
39
+ /** The line carrying the first-observed timestamp across re-records. */
40
+ export const UNCLAIMED_SINCE_PREFIX = 'Unclaimed since: ';
41
+ /**
42
+ * The line recording that this record has been PUT IN FRONT OF THE TEAM.
43
+ *
44
+ * WHY THE RECORD IS NOT ENOUGH ON ITS OWN. A record that nobody reads before
45
+ * the branch merges is a note written to an empty room: the file lands on
46
+ * integration holding a number no claim knows about, and the team that wrote it
47
+ * has finished. So an unnamed record is TEAM-ACTIONABLE WORK -- the completion
48
+ * path treats it the way it treats an outstanding merge-conflict resolution,
49
+ * and the team is not torn down before it has been handed the file.
50
+ *
51
+ * WHY IT IS MARKED, AND WHY THAT BOUNDS IT. The hold lasts exactly one coding
52
+ * turn: once the record has been composed into a spawn prompt, this line is
53
+ * written and the hold lifts, whether or not the team acted. A hold that
54
+ * persisted until the team complied would be a wedge -- the record clears only
55
+ * on a claim or a removal, and neither is something the daemon can force.
56
+ * Telling the team once is what was missing; compelling it is not this
57
+ * mechanism's business.
58
+ */
59
+ export const UNCLAIMED_NAMED_PREFIX = 'Named to the team at: ';
60
+ /** Render the human-facing record. */
61
+ export function renderUnclaimedMigrationArtifact(args) {
62
+ const { focusName, branchName, files, since } = args;
63
+ const lines = [
64
+ `Focus: ${focusName}`,
65
+ `Branch: ${branchName}`,
66
+ `${UNCLAIMED_SINCE_PREFIX}${since}`,
67
+ '',
68
+ `${files.length} migration file${files.length === 1 ? '' : 's'} on this branch `
69
+ + 'were not claimed through Telora:',
70
+ '',
71
+ ...files.map((f) => `- ${f.ordinal} ${f.path}`),
72
+ '',
73
+ 'A migration number is claimed once, before the file is named, so two focuses',
74
+ 'cut from one base cannot both take it. A file written without a claim is a',
75
+ 'number nobody knows is taken: the next team to claim can be granted it.',
76
+ '',
77
+ 'The team resolves this by claiming the number (telora_product_migration',
78
+ 'action=claim) or removing the file. This record clears itself on the next',
79
+ 'pass that sees either.',
80
+ // Carried across re-records so the one-turn hold is not re-armed by a
81
+ // commit; see UNCLAIMED_NAMED_PREFIX.
82
+ ...(args.namedAt ? ['', `${UNCLAIMED_NAMED_PREFIX}${args.namedAt}`] : []),
83
+ ];
84
+ return lines.join('\n');
85
+ }
86
+ /** When an existing record was last put in front of the team, or null. */
87
+ export function parseUnclaimedNamedAt(content) {
88
+ if (!content)
89
+ return null;
90
+ for (const line of content.split('\n')) {
91
+ if (line.startsWith(UNCLAIMED_NAMED_PREFIX)) {
92
+ const value = line.slice(UNCLAIMED_NAMED_PREFIX.length).trim();
93
+ if (value)
94
+ return value;
95
+ }
96
+ }
97
+ return null;
98
+ }
99
+ /** Read the first-observed timestamp back out of an existing record. */
100
+ export function parseUnclaimedSince(content) {
101
+ if (!content)
102
+ return null;
103
+ for (const line of content.split('\n')) {
104
+ if (line.startsWith(UNCLAIMED_SINCE_PREFIX)) {
105
+ const value = line.slice(UNCLAIMED_SINCE_PREFIX.length).trim();
106
+ if (value)
107
+ return value;
108
+ }
109
+ }
110
+ return null;
111
+ }
112
+ /** The record already on file for this focus, or undefined. */
113
+ async function readExistingRecord(focusId, api) {
114
+ const result = await api('focus_debug_get', { focusId });
115
+ return (result?.sections ?? [])
116
+ .find((s) => s.sectionKind === UNCLAIMED_MIGRATION_SECTION_KIND)?.content;
117
+ }
118
+ /**
119
+ * Record that this focus's branch holds unclaimed migrations, carrying forward
120
+ * the first-observed timestamp when one is already on record.
121
+ */
122
+ export async function recordUnclaimedMigrations(args, deps = {}) {
123
+ const api = deps.callApi ?? callApi;
124
+ const { focusId, focusName, branchName, files, detectedAt } = args;
125
+ let existing;
126
+ try {
127
+ existing = await readExistingRecord(focusId, api);
128
+ }
129
+ catch {
130
+ // A failed read costs the ORIGINAL since-when, never the record itself.
131
+ existing = undefined;
132
+ }
133
+ // THE NAMED MARKER SURVIVES A RE-RECORD, BUT ONLY WHILE THE SET DOES NOT GROW.
134
+ // Re-recording happens on any tick where the branch moved, so resetting the
135
+ // marker each time would hold the team's teardown again after every commit --
136
+ // a fresh coding turn for a file it was told about already. A NEW unclaimed
137
+ // ordinal is new information, though, and earns its own turn, so the marker
138
+ // is dropped the moment the set grows.
139
+ const alreadyNamed = new Set(parseUnclaimedOrdinals(existing));
140
+ const grew = files.some((f) => !alreadyNamed.has(f.ordinal));
141
+ const namedAt = grew ? null : parseUnclaimedNamedAt(existing);
142
+ await api('focus_debug_set', {
143
+ focusId,
144
+ fields: {
145
+ sectionKind: UNCLAIMED_MIGRATION_SECTION_KIND,
146
+ content: renderUnclaimedMigrationArtifact({
147
+ focusName, branchName, files, since: parseUnclaimedSince(existing) ?? detectedAt, namedAt,
148
+ }),
149
+ },
150
+ });
151
+ }
152
+ /** Clear the record. Idempotent: deleting a section that is not there is a no-op. */
153
+ export async function clearUnclaimedMigrations(focusId, deps = {}) {
154
+ const api = deps.callApi ?? callApi;
155
+ await api('focus_debug_clear', {
156
+ focusId,
157
+ fields: { sectionKind: UNCLAIMED_MIGRATION_SECTION_KIND },
158
+ });
159
+ }
160
+ /**
161
+ * Read the record back, for the spawn prompt.
162
+ *
163
+ * Returns the rendered content, or null when the focus has no such record.
164
+ * The section is stored as prose because it is also a human-facing Debug-tab
165
+ * artifact; the prompt carries the same text rather than re-rendering it, so a
166
+ * team and a human read the identical account.
167
+ */
168
+ export async function readUnclaimedMigrationRecord(focusId, deps = {}) {
169
+ try {
170
+ return await readUnclaimedMigrationRecordStrict(focusId, deps);
171
+ }
172
+ catch {
173
+ // A spawn is never failed by a missing debug read: the team simply is not
174
+ // told this time, and the next pass re-records.
175
+ return null;
176
+ }
177
+ }
178
+ /**
179
+ * The same read, but a FAILURE THROWS.
180
+ *
181
+ * Two callers need the difference. A spawn must never be failed by a debug-tab
182
+ * read, so it takes the lenient form above. The completion path must not read
183
+ * a failed read as "there is nothing to tell" -- that is the destructive
184
+ * direction, the one that lets a team go with an unclaimed migration still on
185
+ * its branch -- so it takes this one and fails closed. Swallowing inside the
186
+ * query made both callers the same, and quietly defeated the second one's
187
+ * fail-closed handler: it could never see the failure it was written for.
188
+ */
189
+ export async function readUnclaimedMigrationRecordStrict(focusId, deps = {}) {
190
+ const api = deps.callApi ?? callApi;
191
+ const result = await api('focus_debug_get', { focusId });
192
+ const section = (result?.sections ?? [])
193
+ .find((s) => s.sectionKind === UNCLAIMED_MIGRATION_SECTION_KIND);
194
+ return section?.content ?? null;
195
+ }
196
+ /**
197
+ * The ordinals an existing record names.
198
+ *
199
+ * Read back so the lifecycle can keep an ordinal NAMED until the team resolves
200
+ * it. Without this the record clears the moment the branch merges -- its own
201
+ * unclaimed file then reads as inherited from integration, the detection goes
202
+ * quiet, and the record reports success for a problem that only moved.
203
+ *
204
+ * Parsed from the rendered lines rather than stored twice: one text is what a
205
+ * human reads on the Debug tab AND what the team is shown, and a second
206
+ * machine-readable copy is a second thing to keep in step.
207
+ */
208
+ export function parseUnclaimedOrdinals(content) {
209
+ return parseUnclaimedEntries(content).map((e) => e.ordinal);
210
+ }
211
+ /**
212
+ * The record's entries, WITH their paths.
213
+ *
214
+ * The ordinals alone are not enough to re-render the record. When integration
215
+ * cannot be read, an ordinal the branch no longer shows can be neither proved
216
+ * merged nor proved removed -- so it must be carried forward verbatim, and
217
+ * carrying it forward needs the file it named. Reading it back from the record
218
+ * (rather than storing a second machine-readable copy) keeps one text as both
219
+ * what a human reads and what the lifecycle reasons over.
220
+ */
221
+ export function parseUnclaimedEntries(content) {
222
+ if (!content)
223
+ return [];
224
+ const entries = [];
225
+ for (const line of content.split('\n')) {
226
+ const match = /^- (\S+)\s\s(.+)$/.exec(line);
227
+ if (match?.[1])
228
+ entries.push({ ordinal: match[1], path: (match[2] ?? '').trim() });
229
+ }
230
+ return entries;
231
+ }
232
+ /**
233
+ * Mark this focus's record as having been handed to the team.
234
+ *
235
+ * Called when the record is composed into a spawn prompt -- the moment the team
236
+ * is actually told. Writing it earlier (at detection) would lift the hold
237
+ * before anyone read it; writing it later (after the session ends) would hold a
238
+ * second turn for a file already named.
239
+ *
240
+ * Best effort by construction: a spawn is never failed by this write. The cost
241
+ * of losing it is one extra coding turn, and the cost of the whole mechanism
242
+ * failing is what it was before -- the team is still shown the record on every
243
+ * spawn while it stands, because the section renders on the record's existence,
244
+ * not on this marker.
245
+ */
246
+ export async function markUnclaimedMigrationNamed(focusId, namedAt, deps = {}) {
247
+ const api = deps.callApi ?? callApi;
248
+ try {
249
+ const existing = await readExistingRecord(focusId, api);
250
+ if (existing === undefined)
251
+ return;
252
+ if (parseUnclaimedNamedAt(existing) !== null)
253
+ return; // already named
254
+ await api('focus_debug_set', {
255
+ focusId,
256
+ fields: {
257
+ sectionKind: UNCLAIMED_MIGRATION_SECTION_KIND,
258
+ content: `${existing}\n${UNCLAIMED_NAMED_PREFIX}${namedAt}`,
259
+ },
260
+ });
261
+ }
262
+ catch {
263
+ // See above: never fails a spawn.
264
+ }
265
+ }
266
+ //# sourceMappingURL=focus-unclaimed-migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-unclaimed-migration.js","sourceRoot":"","sources":["../../src/queries/focus-unclaimed-migration.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,mFAAmF;AACnF,6EAA6E;AAC7E,mEAAmE;AACnE,iEAAiE;AACjE,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,OAAO,EAAoB,MAAM,aAAa,CAAC;AAGxD,6DAA6D;AAC7D,MAAM,CAAC,MAAM,gCAAgC,GAAG,qBAAqB,CAAC;AAEtE,wEAAwE;AACxE,MAAM,CAAC,MAAM,sBAAsB,GAAG,mBAAmB,CAAC;AAE1D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,wBAAwB,CAAC;AAQ/D,sCAAsC;AACtC,MAAM,UAAU,gCAAgC,CAAC,IAOhD;IACC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IACrD,MAAM,KAAK,GAAG;QACZ,UAAU,SAAS,EAAE;QACrB,WAAW,UAAU,EAAE;QACvB,GAAG,sBAAsB,GAAG,KAAK,EAAE;QACnC,EAAE;QACF,GAAG,KAAK,CAAC,MAAM,kBAAkB,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,kBAAkB;cAC9E,kCAAkC;QACpC,EAAE;QACF,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,EAAE;QACF,8EAA8E;QAC9E,4EAA4E;QAC5E,yEAAyE;QACzE,EAAE;QACF,yEAAyE;QACzE,2EAA2E;QAC3E,wBAAwB;QACxB,sEAAsE;QACtE,sCAAsC;QACtC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,sBAAsB,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1E,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,qBAAqB,CAAC,OAAkC;IACtE,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,IAAI,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,CAAC;YAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;YAC/D,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,mBAAmB,CAAC,OAA2B;IAC7D,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,IAAI,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,CAAC;YAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;YAC/D,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+DAA+D;AAC/D,KAAK,UAAU,kBAAkB,CAAC,OAAe,EAAE,GAAmB;IACpE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAqC,iBAAiB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IAC7F,OAAO,CAAC,MAAM,EAAE,QAAQ,IAAI,EAAE,CAAC;SAC5B,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,gCAAgC,CAAC,EAAE,OAAO,CAAC;AAC9E,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,IAMC,EACD,OAAoB,EAAE;IAEtB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC;IACpC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IACnE,IAAI,QAA4B,CAAC;IACjC,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,wEAAwE;QACxE,QAAQ,GAAG,SAAS,CAAC;IACvB,CAAC;IAED,+EAA+E;IAC/E,4EAA4E;IAC5E,8EAA8E;IAC9E,4EAA4E;IAC5E,4EAA4E;IAC5E,uCAAuC;IACvC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAE9D,MAAM,GAAG,CAAC,iBAAiB,EAAE;QAC3B,OAAO;QACP,MAAM,EAAE;YACN,WAAW,EAAE,gCAAgC;YAC7C,OAAO,EAAE,gCAAgC,CAAC;gBACxC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,CAAC,QAAQ,CAAC,IAAI,UAAU,EAAE,OAAO;aAC1F,CAAC;SACH;KACF,CAAC,CAAC;AACL,CAAC;AAED,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,OAAe,EACf,OAAoB,EAAE;IAEtB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC;IACpC,MAAM,GAAG,CAAC,mBAAmB,EAAE;QAC7B,OAAO;QACP,MAAM,EAAE,EAAE,WAAW,EAAE,gCAAgC,EAAE;KAC1D,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,OAAe,EACf,OAAoB,EAAE;IAEtB,IAAI,CAAC;QACH,OAAO,MAAM,kCAAkC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,0EAA0E;QAC1E,gDAAgD;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,kCAAkC,CACtD,OAAe,EACf,OAAoB,EAAE;IAEtB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC;IACpC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAqC,iBAAiB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IAC7F,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,QAAQ,IAAI,EAAE,CAAC;SACrC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,gCAAgC,CAAC,CAAC;IACnE,OAAO,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAkC;IACvE,OAAO,qBAAqB,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAC9D,CAAC;AAQD;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAAkC;IAElC,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,MAAM,OAAO,GAA6B,EAAE,CAAC;IAC7C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACrF,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,OAAe,EACf,OAAe,EACf,OAAoB,EAAE;IAEtB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACxD,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO;QACnC,IAAI,qBAAqB,CAAC,QAAQ,CAAC,KAAK,IAAI;YAAE,OAAO,CAAC,gBAAgB;QACtE,MAAM,GAAG,CAAC,iBAAiB,EAAE;YAC3B,OAAO;YACP,MAAM,EAAE;gBACN,WAAW,EAAE,gCAAgC;gBAC7C,OAAO,EAAE,GAAG,QAAQ,KAAK,sBAAsB,GAAG,OAAO,EAAE;aAC5D;SACF,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,kCAAkC;IACpC,CAAC;AACH,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { callApi } from './shared.js';
2
+ /**
3
+ * Focus statuses whose branch holds no numbers the allocator must avoid.
4
+ *
5
+ * The daemon's copy of `supabase/functions/_shared/migration-branch-population.ts`'s list --
6
+ * pinned EQUAL to it by `live-focus-branches.test.ts`, which imports the shared
7
+ * module itself rather than restating the values. Copied rather than imported
8
+ * because a Deno `_shared` module is not on the daemon's import graph, and
9
+ * copied WITH a test rather than trusted, because that is the whole lesson
10
+ * above.
11
+ */
12
+ export declare const TERMINAL_FOCUS_STATUSES: readonly string[];
13
+ /** A focus row as the branch population question needs it. */
14
+ export interface BranchPopulationRow {
15
+ status?: string;
16
+ branchName?: string | null;
17
+ }
18
+ /** Does this focus's branch hold migration numbers? */
19
+ export declare function branchHoldsMigrationNumbers(row: BranchPopulationRow): boolean;
20
+ /** Every branch in that population, deduplicated and ordered. */
21
+ export declare function migrationBranchPopulation(rows: ReadonlyArray<BranchPopulationRow>): string[];
22
+ /**
23
+ * Read that population for one product.
24
+ *
25
+ * Scans EVERY focus (the same read the claim lifecycle pass uses) and narrows
26
+ * with the shared rule, rather than asking the API for a pre-narrowed set whose
27
+ * definition of "live" is somebody else's.
28
+ */
29
+ export declare function listLiveFocusBranches(productId: string, deps?: {
30
+ callApi?: typeof callApi;
31
+ }): Promise<string[]>;
32
+ //# sourceMappingURL=live-focus-branches.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-focus-branches.d.ts","sourceRoot":"","sources":["../../src/queries/live-focus-branches.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EAA8B,CAAC;AAEpF,8DAA8D;AAC9D,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,uDAAuD;AACvD,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAI7E;AAED,iEAAiE;AACjE,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,aAAa,CAAC,mBAAmB,CAAC,GAAG,MAAM,EAAE,CAK5F;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,OAAO,CAAA;CAAO,GACtC,OAAO,CAAC,MAAM,EAAE,CAAC,CAOnB"}
@@ -0,0 +1,66 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/migrations/claim-production-wiring.test.ts,
3
+ // packages/daemon/src/queries/live-focus-branches.test.ts
4
+ // PINNED-BY-END
5
+ /**
6
+ * The branches a product's held set must be read from.
7
+ *
8
+ * DELIBERATELY NOT `getActiveFocuses`. That read is the SPAWN set: active
9
+ * focuses WITH an assigned agent role. Using it here published only the
10
+ * branches of focuses a team was currently running on -- while the grant
11
+ * handler required a reading to cover every non-terminal focus branch. An
12
+ * active focus whose arm had been cleared therefore sat in the required set and
13
+ * never in the published one, and every claim on that product refused as
14
+ * uncovered until somebody re-armed or ended it. A fail-closed allocator with
15
+ * no way out is worse than the collision it guards against: the only move left
16
+ * to a team is to number by hand, which is the failure being removed.
17
+ *
18
+ * The rule itself is stated once, in `supabase/functions/_shared/migration-branch-population.ts`
19
+ * (canonical `src/lib/vocabulary/migration-branch-population.ts`), and applied
20
+ * by BOTH sides -- here and in the grant handler's coverage check. This module
21
+ * is only the daemon's reader for it.
22
+ *
23
+ * @module queries/live-focus-branches
24
+ */
25
+ import { scanAllFocuses } from './focuses.js';
26
+ /**
27
+ * Focus statuses whose branch holds no numbers the allocator must avoid.
28
+ *
29
+ * The daemon's copy of `supabase/functions/_shared/migration-branch-population.ts`'s list --
30
+ * pinned EQUAL to it by `live-focus-branches.test.ts`, which imports the shared
31
+ * module itself rather than restating the values. Copied rather than imported
32
+ * because a Deno `_shared` module is not on the daemon's import graph, and
33
+ * copied WITH a test rather than trusted, because that is the whole lesson
34
+ * above.
35
+ */
36
+ export const TERMINAL_FOCUS_STATUSES = ['complete', 'cancelled'];
37
+ /** Does this focus's branch hold migration numbers? */
38
+ export function branchHoldsMigrationNumbers(row) {
39
+ const branch = (row.branchName ?? '').trim();
40
+ if (branch === '')
41
+ return false;
42
+ return !TERMINAL_FOCUS_STATUSES.includes(row.status ?? '');
43
+ }
44
+ /** Every branch in that population, deduplicated and ordered. */
45
+ export function migrationBranchPopulation(rows) {
46
+ const branches = rows
47
+ .filter((row) => branchHoldsMigrationNumbers(row))
48
+ .map((row) => (row.branchName ?? '').trim());
49
+ return [...new Set(branches)].sort();
50
+ }
51
+ /**
52
+ * Read that population for one product.
53
+ *
54
+ * Scans EVERY focus (the same read the claim lifecycle pass uses) and narrows
55
+ * with the shared rule, rather than asking the API for a pre-narrowed set whose
56
+ * definition of "live" is somebody else's.
57
+ */
58
+ export async function listLiveFocusBranches(productId, deps = {}) {
59
+ const result = await scanAllFocuses({
60
+ productId,
61
+ detail: 'summary',
62
+ ...(deps.callApi ? { callApi: deps.callApi } : {}),
63
+ });
64
+ return migrationBranchPopulation(result.focuses);
65
+ }
66
+ //# sourceMappingURL=live-focus-branches.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-focus-branches.js","sourceRoot":"","sources":["../../src/queries/live-focus-branches.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,6EAA6E;AAC7E,4DAA4D;AAC5D,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAsB,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AAQpF,uDAAuD;AACvD,MAAM,UAAU,2BAA2B,CAAC,GAAwB;IAClE,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7C,IAAI,MAAM,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IAChC,OAAO,CAAC,uBAAuB,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,yBAAyB,CAAC,IAAwC;IAChF,MAAM,QAAQ,GAAG,IAAI;SAClB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,2BAA2B,CAAC,GAAG,CAAC,CAAC;SACjD,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AACvC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,SAAiB,EACjB,OAAqC,EAAE;IAEvC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAkD;QACnF,SAAS;QACT,MAAM,EAAE,SAAS;QACjB,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACnD,CAAC,CAAC;IACH,OAAO,yBAAyB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACnD,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Reading and moving migration claims from the daemon.
3
+ *
4
+ * The daemon is the only party that can SEE what a focus branch holds, so it is
5
+ * the only party that can say a claim was realised or abandoned. It never
6
+ * GRANTS one -- that is the edge handler's, atomically, under the partial
7
+ * unique index -- so nothing here computes a number.
8
+ *
9
+ * @module queries/migration-claims
10
+ */
11
+ import { type CallApiDeps } from './shared.js';
12
+ import type { ConfirmDecision, LifecycleClaim, ReleaseDecision } from '../migrations/migration-claim-lifecycle.js';
13
+ /**
14
+ * Every UNRELEASED claim on a product, keyed by focus.
15
+ *
16
+ * Read per product rather than per focus: one call answers the whole pass, and
17
+ * a focus with no claims simply has no entry -- which is different from a focus
18
+ * whose read failed, and the caller can tell because a failed read throws.
19
+ */
20
+ export declare function listLiveMigrationClaims(productId: string, deps?: CallApiDeps): Promise<Map<string, LifecycleClaim[]>>;
21
+ /** Mark claims confirmed, with the tag the file on the branch actually carries. */
22
+ export declare function confirmMigrationClaims(productId: string, decisions: readonly ConfirmDecision[], deps?: CallApiDeps): Promise<void>;
23
+ /** Release claims whose focus ended without the file, recording why. */
24
+ export declare function releaseMigrationClaims(productId: string, decisions: readonly ReleaseDecision[], deps?: CallApiDeps): Promise<void>;
25
+ //# sourceMappingURL=migration-claims.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-claims.d.ts","sourceRoot":"","sources":["../../src/queries/migration-claims.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,OAAO,EAAW,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,eAAe,EAChB,MAAM,4CAA4C,CAAC;AAYpD;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC,CA8BxC;AAED,mFAAmF;AACnF,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,eAAe,EAAE,EACrC,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wEAAwE;AACxE,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,eAAe,EAAE,EACrC,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,IAAI,CAAC,CAUf"}
@@ -0,0 +1,79 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/queries/migration-claims.test.ts
3
+ // PINNED-BY-END
4
+ /**
5
+ * Reading and moving migration claims from the daemon.
6
+ *
7
+ * The daemon is the only party that can SEE what a focus branch holds, so it is
8
+ * the only party that can say a claim was realised or abandoned. It never
9
+ * GRANTS one -- that is the edge handler's, atomically, under the partial
10
+ * unique index -- so nothing here computes a number.
11
+ *
12
+ * @module queries/migration-claims
13
+ */
14
+ import { callApi } from './shared.js';
15
+ /**
16
+ * Every UNRELEASED claim on a product, keyed by focus.
17
+ *
18
+ * Read per product rather than per focus: one call answers the whole pass, and
19
+ * a focus with no claims simply has no entry -- which is different from a focus
20
+ * whose read failed, and the caller can tell because a failed read throws.
21
+ */
22
+ export async function listLiveMigrationClaims(productId, deps = {}) {
23
+ const api = deps.callApi ?? callApi;
24
+ const result = await api('migration_claim_list', {
25
+ productId,
26
+ includeReleased: false,
27
+ limit: 500,
28
+ });
29
+ const byFocus = new Map();
30
+ for (const row of result?.claims ?? []) {
31
+ if (!row.migrationClaimId || !row.ordinal)
32
+ continue;
33
+ const focusId = row.focusId ?? '';
34
+ // A claim with no focus follows no branch, so the lifecycle has nothing to
35
+ // confirm or release it against. It is grouped under '' and simply skipped
36
+ // by the pass, rather than being attributed to an arbitrary focus.
37
+ const claims = byFocus.get(focusId) ?? [];
38
+ claims.push({
39
+ migrationClaimId: row.migrationClaimId,
40
+ focusId: row.focusId ?? null,
41
+ ordinal: row.ordinal,
42
+ tag: row.tag ?? null,
43
+ confirmedAt: row.confirmedAt ?? null,
44
+ // What the FILE carried at the last confirmation -- the only thing a
45
+ // re-confirmation may compare against. Dropping it here is what made the
46
+ // decision fall back to the frozen intent and rewrite forever.
47
+ confirmedTag: row.confirmedTag ?? null,
48
+ });
49
+ byFocus.set(focusId, claims);
50
+ }
51
+ return byFocus;
52
+ }
53
+ /** Mark claims confirmed, with the tag the file on the branch actually carries. */
54
+ export async function confirmMigrationClaims(productId, decisions, deps = {}) {
55
+ if (decisions.length === 0)
56
+ return;
57
+ const api = deps.callApi ?? callApi;
58
+ await api('migration_claim_confirm', {
59
+ productId,
60
+ claims: decisions.map((d) => ({
61
+ migrationClaimId: d.migrationClaimId,
62
+ confirmedTag: d.confirmedTag,
63
+ })),
64
+ });
65
+ }
66
+ /** Release claims whose focus ended without the file, recording why. */
67
+ export async function releaseMigrationClaims(productId, decisions, deps = {}) {
68
+ if (decisions.length === 0)
69
+ return;
70
+ const api = deps.callApi ?? callApi;
71
+ await api('migration_claim_release', {
72
+ productId,
73
+ claims: decisions.map((d) => ({
74
+ migrationClaimId: d.migrationClaimId,
75
+ reason: d.reason,
76
+ })),
77
+ });
78
+ }
79
+ //# sourceMappingURL=migration-claims.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-claims.js","sourceRoot":"","sources":["../../src/queries/migration-claims.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,kEAAkE;AAClE,gBAAgB;AAEhB;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAoB,MAAM,aAAa,CAAC;AAiBxD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,SAAiB,EACjB,OAAoB,EAAE;IAEtB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC;IACpC,MAAM,MAAM,GAAG,MAAM,GAAG,CAA0B,sBAAsB,EAAE;QACxE,SAAS;QACT,eAAe,EAAE,KAAK;QACtB,KAAK,EAAE,GAAG;KACX,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,IAAI,GAAG,EAA4B,CAAC;IACpD,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC;QACvC,IAAI,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,GAAG,CAAC,OAAO;YAAE,SAAS;QACpD,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;QAClC,2EAA2E;QAC3E,2EAA2E;QAC3E,mEAAmE;QACnE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC;YACV,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;YACtC,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,IAAI;YAC5B,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,IAAI;YACpB,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,IAAI;YACpC,qEAAqE;YACrE,yEAAyE;YACzE,+DAA+D;YAC/D,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,IAAI;SACvC,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,SAAiB,EACjB,SAAqC,EACrC,OAAoB,EAAE;IAEtB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC;IACpC,MAAM,GAAG,CAAC,yBAAyB,EAAE;QACnC,SAAS;QACT,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC5B,gBAAgB,EAAE,CAAC,CAAC,gBAAgB;YACpC,YAAY,EAAE,CAAC,CAAC,YAAY;SAC7B,CAAC,CAAC;KACJ,CAAC,CAAC;AACL,CAAC;AAED,wEAAwE;AACxE,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,SAAiB,EACjB,SAAqC,EACrC,OAAoB,EAAE;IAEtB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC;IACpC,MAAM,GAAG,CAAC,yBAAyB,EAAE;QACnC,SAAS;QACT,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC5B,gBAAgB,EAAE,CAAC,CAAC,gBAAgB;YACpC,MAAM,EAAE,CAAC,CAAC,MAAM;SACjB,CAAC,CAAC;KACJ,CAAC,CAAC;AACL,CAAC"}
@@ -380,6 +380,7 @@ export declare const ReadyFocusSchema: z.ZodObject<{
380
380
  assignedAgentRoleId: z.ZodString;
381
381
  agentRoleName: z.ZodString;
382
382
  answerRearmRequestedAt: z.ZodDefault<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
383
+ unclaimedMigrationNoticeOwed: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
383
384
  armedBaselineDeliveryIds: z.ZodDefault<z.ZodOptional<z.ZodUnknown>>;
384
385
  branchName: z.ZodDefault<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
385
386
  }, z.core.$loose>;
@@ -428,6 +429,7 @@ export declare const ReadyFocusesResponseSchema: z.ZodObject<{
428
429
  assignedAgentRoleId: z.ZodString;
429
430
  agentRoleName: z.ZodString;
430
431
  answerRearmRequestedAt: z.ZodDefault<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
432
+ unclaimedMigrationNoticeOwed: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
431
433
  armedBaselineDeliveryIds: z.ZodDefault<z.ZodOptional<z.ZodUnknown>>;
432
434
  branchName: z.ZodDefault<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
433
435
  }, z.core.$loose>>;
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/queries/schemas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/queries/schemas.ts"],"names":[],"mappings":"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"}
@@ -264,6 +264,12 @@ export const ReadyFocusSchema = z.object({
264
264
  // even though it has no actionable deliveries; the daemon force-spawns and
265
265
  // clears the flag. Absent/null on backends predating the answer re-arm column.
266
266
  answerRearmRequestedAt: nullableString.optional().default(null),
267
+ // This focus owes its team an unclaimed-migration notice (a migration file on
268
+ // its branch with no claim behind it, not yet composed into a prompt). Like
269
+ // the re-arm signal, it force-spawns past the no-actionable-delivery skip --
270
+ // the spawn PROMPT is the notice's only carrier once the lead's stdin is gone,
271
+ // and on the Codex backend it is the only carrier there ever was.
272
+ unclaimedMigrationNoticeOwed: z.boolean().optional().default(false),
267
273
  // Pinned git branch identity (product_focuses.branch_name), persisted the
268
274
  // first time the focus branch is created. Non-null => read it instead of
269
275
  // re-deriving from the live role. Absent on backends predating the column ->