@catalyst-cloud/schema 0.1.22 → 0.1.24

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@catalyst-cloud/schema",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
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",
@@ -1607,6 +1607,34 @@ export const durableEventTypes = {
1607
1607
  wakes: { consumerClass: "dispatcher" },
1608
1608
  entity: "ticket",
1609
1609
  },
1610
+ "runner.container.stopped": {
1611
+ rationale:
1612
+ "CTC-1118 D4 — RunnerDispatchDO observed its own Container stop (activity expiry, a platform rollout SIGTERM, or an orderly exit) and reported it to the tenant DO. A positive observation ('a container stopped'), never an inferred absence — the entitlement plane's epistemic rule (entitlement.ts's RevokeRequest.observation). NOT wake-eligible: the report only collapses a held lease's deadline (existence-plane, never ownership — ADR-0037 Amendment 7), it does not itself create new eligible work for the dispatcher.",
1613
+ ingestVerb: "coordination.publish",
1614
+ wakes: false,
1615
+ entity: "runner",
1616
+ },
1617
+ "runner.start.failed": {
1618
+ rationale:
1619
+ "CTC-951 — the MirrorDO alarm's existence-push (ADR-0037 Amendment 7) tried to start a tenant runner and the platform refused it. ADR-0039 durable-fact example ('a runner reported an outcome'): the first failure of a backoff episode. NOT wake-eligible — a start failure must never itself trigger the dispatcher, or the dispatch plane would wake on its own retry clock.",
1620
+ ingestVerb: "coordination.publish",
1621
+ wakes: false,
1622
+ entity: "runner",
1623
+ },
1624
+ "runner.start.recovered": {
1625
+ rationale:
1626
+ "CTC-951 — a tenant runner start succeeded after a prior runner.start.failed backoff episode closed it. The paired recovery fact to runner.start.failed; never appended for a start that never failed, and never appended merely because the eligible work that triggered the episode disappeared during backoff (that is a silent clear, not a recovery).",
1627
+ ingestVerb: "coordination.publish",
1628
+ wakes: false,
1629
+ entity: "runner",
1630
+ },
1631
+ "runner.work.reclaimable": {
1632
+ rationale:
1633
+ "CTC-1118 D5 — the MirrorDO alarm's existence-push found eligible work whose lease row still records a holder with a PAST deadline: a tenure that died without releasing, now being re-driven. ADR-0039 durable-fact example ('work became eligible'/'a runner reported an outcome') and the ticket's own Gherkin acceptance signal — a positive observation (a deadline verifiably passed while a holder was recorded), deduped per lapsed tenure via (ticket, phase, generation) so a unit that stays eligible across several alarm passes does not re-emit. NOT wake-eligible: the existence-push that discovers this already proceeds with its own /ensure call in the same pass, so nothing needs to wake on this event alone.",
1634
+ ingestVerb: "coordination.publish",
1635
+ wakes: false,
1636
+ entity: "ticket",
1637
+ },
1610
1638
  "session.ended": {
1611
1639
  rationale: "An agent session ended — a real lifecycle boundary fact.",
1612
1640
  ingestVerb: "coordination.publish",
@@ -166,10 +166,18 @@ export function mayPruneHotEvent(check: HotEventPruneCheck): boolean {
166
166
  //
167
167
  // Transcripts are NOT events and get their OWN retention class: short default, longer
168
168
  // keep-on-failure, neither inherited from event retention above nor from ADR-0036's original
169
- // no-lifecycle default. Enforced by two operator-applied R2 lifecycle delete-age rules keyed on the
170
- // name markers below (docs/event-backbone/retention-and-deletion.md's transcript section;
171
- // docs/devops.md carries the exact provisioning calls). The name prefixes are imported by
172
- // apps/mirror's transcript name grammar so route grammar and lifecycle rules share one definition.
169
+ // no-lifecycle default. The name prefixes are imported by apps/mirror's transcript name grammar so
170
+ // the route grammar and the retention markers share one definition.
171
+ //
172
+ // ⚠️ THE TWO WINDOWS BELOW ARE POLICY, NOT WHAT THE BUCKET CURRENTLY ENFORCES. R2 lifecycle rules
173
+ // filter on `conditions.prefix` ONLY — no suffix, no tag — and these markers sit in the LAST key
174
+ // segment, so NO lifecycle rule can select by outcome. The interim enforcement is ONE delete-age
175
+ // rule per account transcript-scope prefix (`${account}/linear-`) at the 180-day FAIL window:
176
+ // fail-class matches exactly, ok-class is kept 6x longer, and the error is toward retention rather
177
+ // than toward destroying post-mortem evidence. Splitting the two windows needs an R2 suffix/tag
178
+ // filter or a name-aware sweeper (ADR-0041 point 4; revisit at CTC-967). Provisioning calls:
179
+ // docs/devops.md → "Session transcript lifecycle rules"; policy: the transcript section of
180
+ // docs/event-backbone/retention-and-deletion.md.
173
181
 
174
182
  /** A transcript whose worker reported a clean outcome is kept 30 days. */
175
183
  export const TRANSCRIPT_RETENTION_OK_MS = 30 * 24 * 60 * 60 * 1000; // 30 days