@catalyst-cloud/schema 0.1.33 → 0.1.35
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/package.json +1 -1
- package/src/events/registry.ts +6 -6
- package/src/migrations.generated.ts +9 -0
- package/src/mirror.ts +18 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@catalyst-cloud/schema",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.35",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Typed Drizzle schema = single source of truth for the per-tenant Mirror DO SQLite store (CTC-13 / ADR-0002). Shared by the mirror Worker, the host-sync replica, and the browser OPFS replica.",
|
|
6
6
|
"license": "MIT",
|
package/src/events/registry.ts
CHANGED
|
@@ -605,42 +605,42 @@ export const durableEventTypes = {
|
|
|
605
605
|
},
|
|
606
606
|
"phase.dispatch.claim-lost": {
|
|
607
607
|
rationale:
|
|
608
|
-
"ADR-0039 durable-fact example ('a phase started, completed, failed, or was preempted'): a dispatch claim was lost to a concurrent race — a real coordination fact about who owns the work.",
|
|
608
|
+
"ADR-0039 durable-fact example ('a phase started, completed, failed, or was preempted'): a dispatch claim was lost to a concurrent race — a real coordination fact about who owns the work. PRODUCER (CTC-1365, ADR-0070): apps/mirror/src/do/MirrorDO.ts's handleWorkAcquire, on a lease_held refusal that reliably names the winning holder+generation.",
|
|
609
609
|
ingestVerb: "coordination.publish",
|
|
610
610
|
wakes: false,
|
|
611
611
|
entity: "ticket",
|
|
612
612
|
},
|
|
613
613
|
"phase.dispatch.escalated": {
|
|
614
614
|
rationale:
|
|
615
|
-
"ADR-0039 durable-fact example ('a phase started, completed, failed, or was preempted'): the phase escalated to a human.",
|
|
615
|
+
"ADR-0039 durable-fact example ('a phase started, completed, failed, or was preempted'): the phase escalated to a human. PRODUCER (CTC-1365, ADR-0070): apps/mirror/src/do/runner-start-dispatch.ts, once per failure episode, on the attempt where its backoff ladder saturates.",
|
|
616
616
|
ingestVerb: "coordination.publish",
|
|
617
617
|
wakes: { consumerClass: "host-channel" },
|
|
618
618
|
entity: "ticket",
|
|
619
619
|
},
|
|
620
620
|
"phase.dispatch.failed": {
|
|
621
621
|
rationale:
|
|
622
|
-
"ADR-0039 durable-fact example ('a phase started, completed, failed, or was preempted'): the phase reported failure.",
|
|
622
|
+
"ADR-0039 durable-fact example ('a phase started, completed, failed, or was preempted'): the phase reported failure. PRODUCER (CTC-1365, ADR-0070): both apps/mirror/src/do/runner-start-dispatch.ts (a container never came to exist, scope:'container') and MirrorDO.ts's handleWorkAcquire (a post-claim routing/slot failure, scope:'assignment').",
|
|
623
623
|
ingestVerb: "coordination.publish",
|
|
624
624
|
wakes: false,
|
|
625
625
|
entity: "ticket",
|
|
626
626
|
},
|
|
627
627
|
"phase.dispatch.launched": {
|
|
628
628
|
rationale:
|
|
629
|
-
"ADR-0039 durable-fact example ('a phase started, completed, failed, or was preempted'): the phase's worker actually started running.",
|
|
629
|
+
"ADR-0039 durable-fact example ('a phase started, completed, failed, or was preempted'): the phase's worker actually started running. PRODUCER (CTC-1365, ADR-0070): apps/mirror/src/do/MirrorDO.ts's handleWorkAcquire, on every successful POST /work/acquire claim — carries the SAME nonce the terminal phase.<p>.complete/.failed event carries.",
|
|
630
630
|
ingestVerb: "coordination.publish",
|
|
631
631
|
wakes: { consumerClass: "dispatcher" },
|
|
632
632
|
entity: "ticket",
|
|
633
633
|
},
|
|
634
634
|
"phase.dispatch.requested": {
|
|
635
635
|
rationale:
|
|
636
|
-
"ADR-0039 durable-fact example ('a phase started, completed, failed, or was preempted'): work became eligible for dispatch — the phase was requested.",
|
|
636
|
+
"ADR-0039 durable-fact example ('a phase started, completed, failed, or was preempted'): work became eligible for dispatch — the phase was requested. PRODUCER (CTC-1365, ADR-0070): apps/mirror/src/do/runner-start-dispatch.ts's createNextSupervisorEpisode, once per supervisor episode, attributed to the team's head-of-queue eligible unit with an explicit nonce: null — no lease exists yet.",
|
|
637
637
|
ingestVerb: "coordination.publish",
|
|
638
638
|
wakes: { consumerClass: "dispatcher" },
|
|
639
639
|
entity: "ticket",
|
|
640
640
|
},
|
|
641
641
|
"phase.dispatch.runaway": {
|
|
642
642
|
rationale:
|
|
643
|
-
"ADR-0039 durable-fact example ('a phase started, completed, failed, or was preempted'): a dispatch safety guard fired (runaway detection) — a real operational fact.",
|
|
643
|
+
"ADR-0039 durable-fact example ('a phase started, completed, failed, or was preempted'): a dispatch safety guard fired (runaway detection) — a real operational fact. PRODUCER (CTC-1365, ADR-0070): apps/mirror/src/do/runner-start-dispatch.ts, when a waiting/unknown supervisor is superseded past its start grace window with zero live leases held by its dispatch key.",
|
|
644
644
|
ingestVerb: "coordination.publish",
|
|
645
645
|
wakes: false,
|
|
646
646
|
entity: "ticket",
|
|
@@ -242,6 +242,13 @@ export const MIRROR_MIGRATIONS = {
|
|
|
242
242
|
tag: "0032_elite_donald_blake",
|
|
243
243
|
breakpoints: true,
|
|
244
244
|
},
|
|
245
|
+
{
|
|
246
|
+
idx: 33,
|
|
247
|
+
version: "6",
|
|
248
|
+
when: 1788282183348,
|
|
249
|
+
tag: "0033_lethal_electro",
|
|
250
|
+
breakpoints: true,
|
|
251
|
+
},
|
|
245
252
|
],
|
|
246
253
|
},
|
|
247
254
|
migrations: {
|
|
@@ -308,5 +315,7 @@ export const MIRROR_MIGRATIONS = {
|
|
|
308
315
|
"-- CTC-851 — backfill comment parents + quarantine the pre-fix empty-issue_id orphans.\n--\n-- 0030 adds the parent_type/parent_entity_id columns and fixes both WRITE legs (webhook normalizer +\n-- reconcile) so new/re-swept comments carry a real parent, but that alone converges only rows the\n-- reconcile re-sweeps — and it walks OPEN issues, so a non-issue comment (or a comment on a closed\n-- issue) keeps its corrupt shape forever. This backfill is what makes the CORPUS canonical rather\n-- than just the new writes.\n--\n-- ⭐ Deliberately a DATA migration in the SHARED bundle (the 0014 pattern): the DO and every host /\n-- OPFS replica apply the same MIRROR_MIGRATIONS through the same runner, so each side repairs its OWN\n-- rows locally. That converges every replica WITHOUT emitting a change_log delta per row (migrations\n-- bypass appendChange), so no ring-buffer flood (the CTC-279 concern).\n--\n-- (a) Healthy rows (a real issue_id) → parent_type='issue', parent_entity_id=issue_id.\n-- (b) Orphans (issue_id empty-string — the measured shape — or NULL, defensively) cannot be repaired\n-- from row data: the replica comments table has no `raw` column and no parent signal beyond the\n-- comment-reply parent_id. A pure in-bundle DML migration cannot call Linear, so it QUARANTINES\n-- them: parent_type='unresolved', issue_id nulled — MARKED with a stated reason, never deleted\n-- (the AC explicitly permits quarantine-with-reason). CTC-851 measured 54 such rows live.\n--\n-- Idempotent by the `parent_type IS NULL` guard: once a row is stamped it is skipped on replay, so a\n-- crash between a statement succeeding and its tag being recorded (execReplaySafe) is safe.\nUPDATE `comments`\n SET `parent_type` = 'issue', `parent_entity_id` = `issue_id`\n WHERE `parent_type` IS NULL AND `issue_id` IS NOT NULL AND `issue_id` <> '';\n--> statement-breakpoint\nUPDATE `comments`\n SET `parent_type` = 'unresolved', `issue_id` = NULL\n WHERE `parent_type` IS NULL AND (`issue_id` = '' OR `issue_id` IS NULL);\n",
|
|
309
316
|
"0032_elite_donald_blake":
|
|
310
317
|
"ALTER TABLE `issues` ADD `creator_id` text;--> statement-breakpoint\nALTER TABLE `issues` ADD `creator_name` text;--> statement-breakpoint\nALTER TABLE `issues` ADD `creator_avatar_url` text;",
|
|
318
|
+
"0033_lethal_electro":
|
|
319
|
+
"ALTER TABLE `labels` ADD `team_id` text;--> statement-breakpoint\nCREATE INDEX `idx_labels_team` ON `labels` (`team_id`);",
|
|
311
320
|
},
|
|
312
321
|
} as const;
|
package/src/mirror.ts
CHANGED
|
@@ -101,13 +101,24 @@ export const issues = sqliteTable(
|
|
|
101
101
|
],
|
|
102
102
|
);
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
104
|
+
// CTC-1088: `team_id` is nullable and ADVISORY, never a gate — NULL means "workspace-scoped, or not
|
|
105
|
+
// yet stamped by the authoritative sweep" (an ambiguity the org-wide reconcile leg bounds to one pass,
|
|
106
|
+
// since it fetches `team { id }` and re-stamps every label every sweep — ADR-0022). Written UNCONDITIONALLY
|
|
107
|
+
// only by that reconcile leg; a webhook or issue-nested label upsert OMITS the column entirely rather
|
|
108
|
+
// than writing null over a real value — the SAME `users.email` precedent this file already documents
|
|
109
|
+
// (see users, above), made safe by `upsertRow`'s `Object.keys(row)` column derivation (do/upsert.ts).
|
|
110
|
+
export const labels = sqliteTable(
|
|
111
|
+
"labels",
|
|
112
|
+
{
|
|
113
|
+
id: text("id").primaryKey(),
|
|
114
|
+
team_id: text("team_id"),
|
|
115
|
+
name: text("name"),
|
|
116
|
+
color: text("color"),
|
|
117
|
+
updated_at: integer("updated_at"),
|
|
118
|
+
removed_at: integer("removed_at"),
|
|
119
|
+
},
|
|
120
|
+
(t) => [index("idx_labels_team").on(t.team_id)],
|
|
121
|
+
);
|
|
111
122
|
|
|
112
123
|
// Teammate identities (CTC-USERS): resolves issue assignees + delegate AGENTS (and comment/PR
|
|
113
124
|
// authors/reviewers) to a name + avatar so the UI never renders a gray "Unknown" chip. AGENT
|