@telora/daemon 0.22.187 → 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.
- package/build-info.json +6 -3
- package/dist/backends/index.d.ts.map +1 -1
- package/dist/backends/index.js +2 -0
- package/dist/backends/index.js.map +1 -1
- package/dist/completion/completion-fact-readers.d.ts +35 -0
- package/dist/completion/completion-fact-readers.d.ts.map +1 -0
- package/dist/completion/completion-fact-readers.js +70 -0
- package/dist/completion/completion-fact-readers.js.map +1 -0
- package/dist/completion/escalations.d.ts.map +1 -1
- package/dist/completion/escalations.js +2 -1
- package/dist/completion/escalations.js.map +1 -1
- package/dist/completion/event-dep-defaults.d.ts +27 -0
- package/dist/completion/event-dep-defaults.d.ts.map +1 -0
- package/dist/completion/event-dep-defaults.js +30 -0
- package/dist/completion/event-dep-defaults.js.map +1 -0
- package/dist/completion/event-phases.d.ts.map +1 -1
- package/dist/completion/event-phases.js +5 -13
- package/dist/completion/event-phases.js.map +1 -1
- package/dist/completion/event.d.ts +32 -0
- package/dist/completion/event.d.ts.map +1 -1
- package/dist/completion/event.js +31 -25
- package/dist/completion/event.js.map +1 -1
- package/dist/completion/review-exit-phase.d.ts.map +1 -1
- package/dist/completion/review-exit-phase.js +11 -4
- package/dist/completion/review-exit-phase.js.map +1 -1
- package/dist/completion/session-hold.d.ts +13 -1
- package/dist/completion/session-hold.d.ts.map +1 -1
- package/dist/completion/session-hold.js +18 -0
- package/dist/completion/session-hold.js.map +1 -1
- package/dist/completion/standing-approval-convergence.d.ts.map +1 -1
- package/dist/completion/standing-approval-convergence.js +2 -1
- package/dist/completion/standing-approval-convergence.js.map +1 -1
- package/dist/completion/team-phase.d.ts.map +1 -1
- package/dist/completion/team-phase.js +1 -0
- package/dist/completion/team-phase.js.map +1 -1
- package/dist/completion/unclaimed-migration-notice-phase.d.ts +97 -0
- package/dist/completion/unclaimed-migration-notice-phase.d.ts.map +1 -0
- package/dist/completion/unclaimed-migration-notice-phase.js +270 -0
- package/dist/completion/unclaimed-migration-notice-phase.js.map +1 -0
- package/dist/directive/directive-executor.d.ts.map +1 -1
- package/dist/directive/directive-executor.js +1 -20
- package/dist/directive/directive-executor.js.map +1 -1
- package/dist/focus/focus-executor.d.ts +1 -0
- package/dist/focus/focus-executor.d.ts.map +1 -1
- package/dist/focus/focus-executor.js +18 -17
- package/dist/focus/focus-executor.js.map +1 -1
- package/dist/focus/focus-loop-registry.js +2 -2
- package/dist/focus/focus-loop-registry.js.map +1 -1
- package/dist/focus/focus-team-state.js +1 -1
- package/dist/focus/listener-spawn.d.ts.map +1 -1
- package/dist/focus/listener-spawn.js +5 -20
- package/dist/focus/listener-spawn.js.map +1 -1
- package/dist/focus/listener-state.d.ts.map +1 -1
- package/dist/focus/listener-state.js +1 -0
- package/dist/focus/listener-state.js.map +1 -1
- package/dist/focus/listener.d.ts +1 -0
- package/dist/focus/listener.d.ts.map +1 -1
- package/dist/focus/listener.js +9 -0
- package/dist/focus/listener.js.map +1 -1
- package/dist/focus/migration-claim-pass.d.ts +50 -0
- package/dist/focus/migration-claim-pass.d.ts.map +1 -0
- package/dist/focus/migration-claim-pass.js +234 -0
- package/dist/focus/migration-claim-pass.js.map +1 -0
- package/dist/focus/pending-spawn-pass-deps.d.ts.map +1 -1
- package/dist/focus/pending-spawn-pass-deps.js +2 -1
- package/dist/focus/pending-spawn-pass-deps.js.map +1 -1
- package/dist/focus/team-actionable-work.d.ts +21 -0
- package/dist/focus/team-actionable-work.d.ts.map +1 -1
- package/dist/focus/team-actionable-work.js +3 -0
- package/dist/focus/team-actionable-work.js.map +1 -1
- package/dist/git/types.d.ts.map +1 -1
- package/dist/git/types.js +2 -1
- package/dist/git/types.js.map +1 -1
- package/dist/loops/llm-client.d.ts +1 -1
- package/dist/loops/llm-client.d.ts.map +1 -1
- package/dist/loops/llm-client.js +29 -106
- package/dist/loops/llm-client.js.map +1 -1
- package/dist/migrations/migration-claim-lifecycle.d.ts +166 -0
- package/dist/migrations/migration-claim-lifecycle.d.ts.map +1 -0
- package/dist/migrations/migration-claim-lifecycle.js +198 -0
- package/dist/migrations/migration-claim-lifecycle.js.map +1 -0
- package/dist/migrations/migration-held-set.d.ts +171 -0
- package/dist/migrations/migration-held-set.d.ts.map +1 -0
- package/dist/migrations/migration-held-set.js +295 -0
- package/dist/migrations/migration-held-set.js.map +1 -0
- package/dist/migrations/migration-inventory.d.ts +187 -0
- package/dist/migrations/migration-inventory.d.ts.map +1 -0
- package/dist/migrations/migration-inventory.js +253 -0
- package/dist/migrations/migration-inventory.js.map +1 -0
- package/dist/migrations/migration-manifest.d.ts +114 -0
- package/dist/migrations/migration-manifest.d.ts.map +1 -0
- package/dist/migrations/migration-manifest.js +295 -0
- package/dist/migrations/migration-manifest.js.map +1 -0
- package/dist/prompt/team-prompt-base.js +1 -1
- package/dist/prompt-sections/migration-numbering-section.d.ts +58 -0
- package/dist/prompt-sections/migration-numbering-section.d.ts.map +1 -0
- package/dist/prompt-sections/migration-numbering-section.js +70 -0
- package/dist/prompt-sections/migration-numbering-section.js.map +1 -0
- package/dist/prompt-sections/migration-numbering-state.d.ts +30 -0
- package/dist/prompt-sections/migration-numbering-state.d.ts.map +1 -0
- package/dist/prompt-sections/migration-numbering-state.js +24 -0
- package/dist/prompt-sections/migration-numbering-state.js.map +1 -0
- package/dist/prompt-sections/unclaimed-migration-section.d.ts +38 -0
- package/dist/prompt-sections/unclaimed-migration-section.d.ts.map +1 -0
- package/dist/prompt-sections/unclaimed-migration-section.js +57 -0
- package/dist/prompt-sections/unclaimed-migration-section.js.map +1 -0
- package/dist/queries/agent-resolvable-promotion.d.ts +12 -0
- package/dist/queries/agent-resolvable-promotion.d.ts.map +1 -1
- package/dist/queries/agent-resolvable-promotion.js +17 -6
- package/dist/queries/agent-resolvable-promotion.js.map +1 -1
- package/dist/queries/claim-pass-focuses.d.ts +19 -0
- package/dist/queries/claim-pass-focuses.d.ts.map +1 -0
- package/dist/queries/claim-pass-focuses.js +72 -0
- package/dist/queries/claim-pass-focuses.js.map +1 -0
- package/dist/queries/daemon-connection.d.ts.map +1 -1
- package/dist/queries/daemon-connection.js +1 -0
- package/dist/queries/daemon-connection.js.map +1 -1
- package/dist/queries/delivery-gate-state.d.ts +3 -0
- package/dist/queries/delivery-gate-state.d.ts.map +1 -1
- package/dist/queries/delivery-gate-state.js +1 -1
- package/dist/queries/delivery-gate-state.js.map +1 -1
- package/dist/queries/focus-discovery.d.ts +25 -2
- package/dist/queries/focus-discovery.d.ts.map +1 -1
- package/dist/queries/focus-discovery.js +16 -9
- package/dist/queries/focus-discovery.js.map +1 -1
- package/dist/queries/focus-unclaimed-migration.d.ts +146 -0
- package/dist/queries/focus-unclaimed-migration.d.ts.map +1 -0
- package/dist/queries/focus-unclaimed-migration.js +266 -0
- package/dist/queries/focus-unclaimed-migration.js.map +1 -0
- package/dist/queries/live-focus-branches.d.ts +32 -0
- package/dist/queries/live-focus-branches.d.ts.map +1 -0
- package/dist/queries/live-focus-branches.js +66 -0
- package/dist/queries/live-focus-branches.js.map +1 -0
- package/dist/queries/migration-claims.d.ts +25 -0
- package/dist/queries/migration-claims.d.ts.map +1 -0
- package/dist/queries/migration-claims.js +79 -0
- package/dist/queries/migration-claims.js.map +1 -0
- package/dist/queries/schemas.d.ts +2 -0
- package/dist/queries/schemas.d.ts.map +1 -1
- package/dist/queries/schemas.js +6 -0
- package/dist/queries/schemas.js.map +1 -1
- package/dist/queries/shared.js +1 -1
- package/dist/queries/verify-own-holds.d.ts +89 -0
- package/dist/queries/verify-own-holds.d.ts.map +1 -0
- package/dist/queries/verify-own-holds.js +93 -0
- package/dist/queries/verify-own-holds.js.map +1 -0
- package/dist/session/session-lineage.d.ts.map +1 -1
- package/dist/session/session-lineage.js +3 -0
- package/dist/session/session-lineage.js.map +1 -1
- package/dist/shell/heartbeat-metadata.d.ts +48 -2
- package/dist/shell/heartbeat-metadata.d.ts.map +1 -1
- package/dist/shell/heartbeat-metadata.js +80 -3
- package/dist/shell/heartbeat-metadata.js.map +1 -1
- package/dist/shell/heartbeat.d.ts +13 -0
- package/dist/shell/heartbeat.d.ts.map +1 -1
- package/dist/shell/heartbeat.js +31 -10
- package/dist/shell/heartbeat.js.map +1 -1
- package/dist/shell/mcp-resolution.js +1 -1
- package/dist/shell/mcp-resolution.js.map +1 -1
- package/dist/shell/migration-held-set-publish.d.ts +170 -0
- package/dist/shell/migration-held-set-publish.d.ts.map +1 -0
- package/dist/shell/migration-held-set-publish.js +172 -0
- package/dist/shell/migration-held-set-publish.js.map +1 -0
- package/dist/shell/worker-pidfile.d.ts.map +1 -1
- package/dist/shell/worker-pidfile.js +1 -0
- package/dist/shell/worker-pidfile.js.map +1 -1
- package/dist/spawn/helpers.d.ts.map +1 -1
- package/dist/spawn/helpers.js +1 -0
- package/dist/spawn/helpers.js.map +1 -1
- package/dist/spawn/lead-launch.d.ts.map +1 -1
- package/dist/spawn/lead-launch.js +1 -0
- package/dist/spawn/lead-launch.js.map +1 -1
- package/dist/spawn/lead-process-ownership.d.ts.map +1 -1
- package/dist/spawn/lead-process-ownership.js +1 -0
- package/dist/spawn/lead-process-ownership.js.map +1 -1
- package/dist/spawn/one-shot-model.d.ts +145 -0
- package/dist/spawn/one-shot-model.d.ts.map +1 -0
- package/dist/spawn/one-shot-model.js +329 -0
- package/dist/spawn/one-shot-model.js.map +1 -0
- package/dist/spawn/process-group-kill.d.ts.map +1 -1
- package/dist/spawn/process-group-kill.js +1 -0
- package/dist/spawn/process-group-kill.js.map +1 -1
- package/dist/spawn/process-spawn.d.ts +18 -1
- package/dist/spawn/process-spawn.d.ts.map +1 -1
- package/dist/spawn/process-spawn.js +11 -6
- package/dist/spawn/process-spawn.js.map +1 -1
- package/dist/spawn/prompt-assembly.d.ts +115 -18
- package/dist/spawn/prompt-assembly.d.ts.map +1 -1
- package/dist/spawn/prompt-assembly.js +121 -2
- package/dist/spawn/prompt-assembly.js.map +1 -1
- package/dist/spawn/review-hold-park.d.ts.map +1 -1
- package/dist/spawn/review-hold-park.js +7 -3
- package/dist/spawn/review-hold-park.js.map +1 -1
- package/dist/spawn/routing-decider-spawn.d.ts +30 -0
- package/dist/spawn/routing-decider-spawn.d.ts.map +1 -1
- package/dist/spawn/routing-decider-spawn.js +84 -2
- package/dist/spawn/routing-decider-spawn.js.map +1 -1
- package/dist/spawn/routing-decider.d.ts.map +1 -1
- package/dist/spawn/routing-decider.js +22 -0
- package/dist/spawn/routing-decider.js.map +1 -1
- package/dist/spawn/spawn-and-acknowledge.d.ts +61 -0
- package/dist/spawn/spawn-and-acknowledge.d.ts.map +1 -0
- package/dist/spawn/spawn-and-acknowledge.js +117 -0
- package/dist/spawn/spawn-and-acknowledge.js.map +1 -0
- package/dist/spawn/spawn-cooldown.d.ts +15 -1
- package/dist/spawn/spawn-cooldown.d.ts.map +1 -1
- package/dist/spawn/spawn-cooldown.js +67 -19
- package/dist/spawn/spawn-cooldown.js.map +1 -1
- package/dist/spawn/spawn-decision.d.ts +10 -10
- package/dist/spawn/spawn-decision.d.ts.map +1 -1
- package/dist/spawn/spawn-decision.js +33 -5
- package/dist/spawn/spawn-decision.js.map +1 -1
- package/dist/templates/claude-md.d.ts +1 -1
- package/dist/templates/claude-md.d.ts.map +1 -1
- package/dist/templates/claude-md.js +24 -0
- package/dist/templates/claude-md.js.map +1 -1
- package/dist/testing/fixtures/index.js +1 -1
- package/dist/testing/fixtures/migration-namespace-repo.d.ts +63 -0
- package/dist/testing/fixtures/migration-namespace-repo.d.ts.map +1 -0
- package/dist/testing/fixtures/migration-namespace-repo.js +164 -0
- package/dist/testing/fixtures/migration-namespace-repo.js.map +1 -0
- package/dist/testing/fixtures/stubborn-lead-process.d.ts.map +1 -1
- package/dist/testing/fixtures/stubborn-lead-process.js +1 -0
- package/dist/testing/fixtures/stubborn-lead-process.js.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/verify/ai-inspection-runner.d.ts.map +1 -1
- package/dist/verify/ai-inspection-runner.js +26 -7
- package/dist/verify/ai-inspection-runner.js.map +1 -1
- package/dist/verify/de-restatement.d.ts +9 -2
- package/dist/verify/de-restatement.d.ts.map +1 -1
- package/dist/verify/de-restatement.js +14 -76
- package/dist/verify/de-restatement.js.map +1 -1
- package/dist/verify/default-on-guards.d.ts +5 -2
- package/dist/verify/default-on-guards.d.ts.map +1 -1
- package/dist/verify/default-on-guards.js +5 -3
- package/dist/verify/default-on-guards.js.map +1 -1
- package/dist/verify/no-own-delta-verdict.d.ts +16 -2
- package/dist/verify/no-own-delta-verdict.d.ts.map +1 -1
- package/dist/verify/no-own-delta-verdict.js +18 -2
- package/dist/verify/no-own-delta-verdict.js.map +1 -1
- package/dist/verify/verification-deps-default.d.ts.map +1 -1
- package/dist/verify/verification-deps-default.js +6 -0
- package/dist/verify/verification-deps-default.js.map +1 -1
- package/dist/verify/verification-deps.d.ts +10 -0
- package/dist/verify/verification-deps.d.ts.map +1 -1
- package/dist/verify/verification-deterministic.d.ts +7 -0
- package/dist/verify/verification-deterministic.d.ts.map +1 -1
- package/dist/verify/verification-deterministic.js.map +1 -1
- package/dist/verify/verification-engine.d.ts +1 -20
- package/dist/verify/verification-engine.d.ts.map +1 -1
- package/dist/verify/verification-engine.js +24 -55
- package/dist/verify/verification-engine.js.map +1 -1
- package/dist/verify/verification-evidence-unavailable-feedback.d.ts +3 -1
- package/dist/verify/verification-evidence-unavailable-feedback.d.ts.map +1 -1
- package/dist/verify/verification-evidence-unavailable-feedback.js +3 -1
- package/dist/verify/verification-evidence-unavailable-feedback.js.map +1 -1
- package/dist/verify/verification-feedback.d.ts +4 -12
- package/dist/verify/verification-feedback.d.ts.map +1 -1
- package/dist/verify/verification-feedback.js +7 -12
- package/dist/verify/verification-feedback.js.map +1 -1
- package/dist/verify/verification-history-reset.d.ts.map +1 -1
- package/dist/verify/verification-history-reset.js +11 -3
- package/dist/verify/verification-history-reset.js.map +1 -1
- package/dist/verify/verification-model-unavailable-hold.d.ts +92 -0
- package/dist/verify/verification-model-unavailable-hold.d.ts.map +1 -0
- package/dist/verify/verification-model-unavailable-hold.js +207 -0
- package/dist/verify/verification-model-unavailable-hold.js.map +1 -0
- package/dist/verify/verification-strategies.d.ts +32 -0
- package/dist/verify/verification-strategies.d.ts.map +1 -0
- package/dist/verify/verification-strategies.js +47 -0
- package/dist/verify/verification-strategies.js.map +1 -0
- package/dist/verify/verify-reconciliation.d.ts.map +1 -1
- package/dist/verify/verify-reconciliation.js +2 -1
- package/dist/verify/verify-reconciliation.js.map +1 -1
- package/dist/verify/verify-restatement.d.ts.map +1 -1
- package/dist/verify/verify-restatement.js +21 -8
- package/dist/verify/verify-restatement.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The focus's durable record of "my branch holds a migration I never claimed",
|
|
3
|
+
* and its clear.
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS IS STATE AND NOT AN ESCALATION. It names no human-only act: the team
|
|
6
|
+
* that wrote the file is the one that can claim the number or remove it. An
|
|
7
|
+
* escalation would be a row in a human queue that can only wait for the same
|
|
8
|
+
* team to act, and a routine triage pass could resolve it while the file is
|
|
9
|
+
* still unclaimed. So it is a fact about the focus that clears itself when the
|
|
10
|
+
* fact stops being true.
|
|
11
|
+
*
|
|
12
|
+
* WHY focus_debug_artifacts, and not the deliveries' git_state: the same reason
|
|
13
|
+
* `focus-integration-conflict.ts` gives. `org_nodes.git_state` is a
|
|
14
|
+
* forward-only ladder with one slot per delivery, and this is a fact about the
|
|
15
|
+
* focus BRANCH shared by every delivery on it -- with no room for the number or
|
|
16
|
+
* the path. A debug section is one row per (focus, kind), rendered with its own
|
|
17
|
+
* stamp, read by nothing in the machine's decision path, and cleared by
|
|
18
|
+
* DELETING the row, which is exactly what "until the team claims or removes it"
|
|
19
|
+
* wants.
|
|
20
|
+
*
|
|
21
|
+
* SINCE-WHEN SURVIVES THE RE-RECORD. `updated_at` moves on every write and the
|
|
22
|
+
* record is re-written on every pass that still sees the file, so `updated_at`
|
|
23
|
+
* alone would always read "just now" and hide a file unclaimed for a week. The
|
|
24
|
+
* content carries `Unclaimed since:` explicitly and a re-record reads the
|
|
25
|
+
* existing section and carries the value forward; a failed read degrades to
|
|
26
|
+
* "since now" rather than losing the record.
|
|
27
|
+
*
|
|
28
|
+
* @module queries/focus-unclaimed-migration
|
|
29
|
+
*/
|
|
30
|
+
import { type CallApiDeps } from './shared.js';
|
|
31
|
+
import type { UnclaimedFile } from '../migrations/migration-claim-lifecycle.js';
|
|
32
|
+
/** The focus_debug_artifacts section the record lives in. */
|
|
33
|
+
export declare const UNCLAIMED_MIGRATION_SECTION_KIND = "unclaimed_migration";
|
|
34
|
+
/** The line carrying the first-observed timestamp across re-records. */
|
|
35
|
+
export declare const UNCLAIMED_SINCE_PREFIX = "Unclaimed since: ";
|
|
36
|
+
/**
|
|
37
|
+
* The line recording that this record has been PUT IN FRONT OF THE TEAM.
|
|
38
|
+
*
|
|
39
|
+
* WHY THE RECORD IS NOT ENOUGH ON ITS OWN. A record that nobody reads before
|
|
40
|
+
* the branch merges is a note written to an empty room: the file lands on
|
|
41
|
+
* integration holding a number no claim knows about, and the team that wrote it
|
|
42
|
+
* has finished. So an unnamed record is TEAM-ACTIONABLE WORK -- the completion
|
|
43
|
+
* path treats it the way it treats an outstanding merge-conflict resolution,
|
|
44
|
+
* and the team is not torn down before it has been handed the file.
|
|
45
|
+
*
|
|
46
|
+
* WHY IT IS MARKED, AND WHY THAT BOUNDS IT. The hold lasts exactly one coding
|
|
47
|
+
* turn: once the record has been composed into a spawn prompt, this line is
|
|
48
|
+
* written and the hold lifts, whether or not the team acted. A hold that
|
|
49
|
+
* persisted until the team complied would be a wedge -- the record clears only
|
|
50
|
+
* on a claim or a removal, and neither is something the daemon can force.
|
|
51
|
+
* Telling the team once is what was missing; compelling it is not this
|
|
52
|
+
* mechanism's business.
|
|
53
|
+
*/
|
|
54
|
+
export declare const UNCLAIMED_NAMED_PREFIX = "Named to the team at: ";
|
|
55
|
+
/** Render the human-facing record. */
|
|
56
|
+
export declare function renderUnclaimedMigrationArtifact(args: {
|
|
57
|
+
focusName: string;
|
|
58
|
+
branchName: string;
|
|
59
|
+
files: readonly UnclaimedFile[];
|
|
60
|
+
since: string;
|
|
61
|
+
/** When the team was handed this record, if it has been. */
|
|
62
|
+
namedAt?: string | null;
|
|
63
|
+
}): string;
|
|
64
|
+
/** When an existing record was last put in front of the team, or null. */
|
|
65
|
+
export declare function parseUnclaimedNamedAt(content: string | null | undefined): string | null;
|
|
66
|
+
/** Read the first-observed timestamp back out of an existing record. */
|
|
67
|
+
export declare function parseUnclaimedSince(content: string | undefined): string | null;
|
|
68
|
+
/**
|
|
69
|
+
* Record that this focus's branch holds unclaimed migrations, carrying forward
|
|
70
|
+
* the first-observed timestamp when one is already on record.
|
|
71
|
+
*/
|
|
72
|
+
export declare function recordUnclaimedMigrations(args: {
|
|
73
|
+
focusId: string;
|
|
74
|
+
focusName: string;
|
|
75
|
+
branchName: string;
|
|
76
|
+
files: readonly UnclaimedFile[];
|
|
77
|
+
detectedAt: string;
|
|
78
|
+
}, deps?: CallApiDeps): Promise<void>;
|
|
79
|
+
/** Clear the record. Idempotent: deleting a section that is not there is a no-op. */
|
|
80
|
+
export declare function clearUnclaimedMigrations(focusId: string, deps?: CallApiDeps): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Read the record back, for the spawn prompt.
|
|
83
|
+
*
|
|
84
|
+
* Returns the rendered content, or null when the focus has no such record.
|
|
85
|
+
* The section is stored as prose because it is also a human-facing Debug-tab
|
|
86
|
+
* artifact; the prompt carries the same text rather than re-rendering it, so a
|
|
87
|
+
* team and a human read the identical account.
|
|
88
|
+
*/
|
|
89
|
+
export declare function readUnclaimedMigrationRecord(focusId: string, deps?: CallApiDeps): Promise<string | null>;
|
|
90
|
+
/**
|
|
91
|
+
* The same read, but a FAILURE THROWS.
|
|
92
|
+
*
|
|
93
|
+
* Two callers need the difference. A spawn must never be failed by a debug-tab
|
|
94
|
+
* read, so it takes the lenient form above. The completion path must not read
|
|
95
|
+
* a failed read as "there is nothing to tell" -- that is the destructive
|
|
96
|
+
* direction, the one that lets a team go with an unclaimed migration still on
|
|
97
|
+
* its branch -- so it takes this one and fails closed. Swallowing inside the
|
|
98
|
+
* query made both callers the same, and quietly defeated the second one's
|
|
99
|
+
* fail-closed handler: it could never see the failure it was written for.
|
|
100
|
+
*/
|
|
101
|
+
export declare function readUnclaimedMigrationRecordStrict(focusId: string, deps?: CallApiDeps): Promise<string | null>;
|
|
102
|
+
/**
|
|
103
|
+
* The ordinals an existing record names.
|
|
104
|
+
*
|
|
105
|
+
* Read back so the lifecycle can keep an ordinal NAMED until the team resolves
|
|
106
|
+
* it. Without this the record clears the moment the branch merges -- its own
|
|
107
|
+
* unclaimed file then reads as inherited from integration, the detection goes
|
|
108
|
+
* quiet, and the record reports success for a problem that only moved.
|
|
109
|
+
*
|
|
110
|
+
* Parsed from the rendered lines rather than stored twice: one text is what a
|
|
111
|
+
* human reads on the Debug tab AND what the team is shown, and a second
|
|
112
|
+
* machine-readable copy is a second thing to keep in step.
|
|
113
|
+
*/
|
|
114
|
+
export declare function parseUnclaimedOrdinals(content: string | null | undefined): string[];
|
|
115
|
+
/** One migration an existing record names: its number and the file it named. */
|
|
116
|
+
export interface RecordedUnclaimedEntry {
|
|
117
|
+
ordinal: string;
|
|
118
|
+
path: string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* The record's entries, WITH their paths.
|
|
122
|
+
*
|
|
123
|
+
* The ordinals alone are not enough to re-render the record. When integration
|
|
124
|
+
* cannot be read, an ordinal the branch no longer shows can be neither proved
|
|
125
|
+
* merged nor proved removed -- so it must be carried forward verbatim, and
|
|
126
|
+
* carrying it forward needs the file it named. Reading it back from the record
|
|
127
|
+
* (rather than storing a second machine-readable copy) keeps one text as both
|
|
128
|
+
* what a human reads and what the lifecycle reasons over.
|
|
129
|
+
*/
|
|
130
|
+
export declare function parseUnclaimedEntries(content: string | null | undefined): RecordedUnclaimedEntry[];
|
|
131
|
+
/**
|
|
132
|
+
* Mark this focus's record as having been handed to the team.
|
|
133
|
+
*
|
|
134
|
+
* Called when the record is composed into a spawn prompt -- the moment the team
|
|
135
|
+
* is actually told. Writing it earlier (at detection) would lift the hold
|
|
136
|
+
* before anyone read it; writing it later (after the session ends) would hold a
|
|
137
|
+
* second turn for a file already named.
|
|
138
|
+
*
|
|
139
|
+
* Best effort by construction: a spawn is never failed by this write. The cost
|
|
140
|
+
* of losing it is one extra coding turn, and the cost of the whole mechanism
|
|
141
|
+
* failing is what it was before -- the team is still shown the record on every
|
|
142
|
+
* spawn while it stands, because the section renders on the record's existence,
|
|
143
|
+
* not on this marker.
|
|
144
|
+
*/
|
|
145
|
+
export declare function markUnclaimedMigrationNamed(focusId: string, namedAt: string, deps?: CallApiDeps): Promise<void>;
|
|
146
|
+
//# sourceMappingURL=focus-unclaimed-migration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focus-unclaimed-migration.d.ts","sourceRoot":"","sources":["../../src/queries/focus-unclaimed-migration.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAW,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAC;AAEhF,6DAA6D;AAC7D,eAAO,MAAM,gCAAgC,wBAAwB,CAAC;AAEtE,wEAAwE;AACxE,eAAO,MAAM,sBAAsB,sBAAsB,CAAC;AAE1D;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAQ/D,sCAAsC;AACtC,wBAAgB,gCAAgC,CAAC,IAAI,EAAE;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GAAG,MAAM,CAwBT;AAED,0EAA0E;AAC1E,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CASvF;AAED,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAS9E;AASD;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE;IACJ,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;CACpB,EACD,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAED,qFAAqF;AACrF,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;;;;;;GAOG;AACH,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQxB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,kCAAkC,CACtD,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAMxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,EAAE,CAEnF;AAED,gFAAgF;AAChF,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACjC,sBAAsB,EAAE,CAQ1B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,IAAI,CAAC,CAgBf"}
|
|
@@ -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":"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"}
|
|
@@ -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"}
|