instar 1.3.1661 → 1.3.1663

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 (160) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +195 -30
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/core/ClaudeKeyHealth.d.ts +21 -0
  5. package/dist/core/ClaudeKeyHealth.d.ts.map +1 -1
  6. package/dist/core/ClaudeKeyHealth.js +81 -5
  7. package/dist/core/ClaudeKeyHealth.js.map +1 -1
  8. package/dist/core/MeshRpc.d.ts +14 -0
  9. package/dist/core/MeshRpc.d.ts.map +1 -1
  10. package/dist/core/MeshRpc.js +1 -0
  11. package/dist/core/MeshRpc.js.map +1 -1
  12. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  13. package/dist/core/PostUpdateMigrator.js +18 -0
  14. package/dist/core/PostUpdateMigrator.js.map +1 -1
  15. package/dist/core/SessionManager.d.ts.map +1 -1
  16. package/dist/core/SessionManager.js +8 -6
  17. package/dist/core/SessionManager.js.map +1 -1
  18. package/dist/core/SlackReplyRelayInstaller.d.ts.map +1 -1
  19. package/dist/core/SlackReplyRelayInstaller.js +2 -0
  20. package/dist/core/SlackReplyRelayInstaller.js.map +1 -1
  21. package/dist/core/StateManager.d.ts +8 -0
  22. package/dist/core/StateManager.d.ts.map +1 -1
  23. package/dist/core/StateManager.js +11 -0
  24. package/dist/core/StateManager.js.map +1 -1
  25. package/dist/core/WriteDomainRegistry.d.ts.map +1 -1
  26. package/dist/core/WriteDomainRegistry.js +9 -0
  27. package/dist/core/WriteDomainRegistry.js.map +1 -1
  28. package/dist/core/claudeKeyRecovery.d.ts +102 -0
  29. package/dist/core/claudeKeyRecovery.d.ts.map +1 -0
  30. package/dist/core/claudeKeyRecovery.js +178 -0
  31. package/dist/core/claudeKeyRecovery.js.map +1 -0
  32. package/dist/core/memorySessionPolicy.d.ts +12 -0
  33. package/dist/core/memorySessionPolicy.d.ts.map +1 -1
  34. package/dist/core/memorySessionPolicy.js +20 -0
  35. package/dist/core/memorySessionPolicy.js.map +1 -1
  36. package/dist/core/pickSessionByTmux.d.ts +11 -0
  37. package/dist/core/pickSessionByTmux.d.ts.map +1 -0
  38. package/dist/core/pickSessionByTmux.js +11 -0
  39. package/dist/core/pickSessionByTmux.js.map +1 -0
  40. package/dist/core/types.d.ts +14 -0
  41. package/dist/core/types.d.ts.map +1 -1
  42. package/dist/core/types.js.map +1 -1
  43. package/dist/data/standards-guard-index.json +2 -2
  44. package/dist/data/standards-guard-index.meta.json +3 -3
  45. package/dist/data/standards-registry.md +12 -2
  46. package/dist/data/standards-registry.meta.json +3 -3
  47. package/dist/feedback-factory/execute/changeSet.d.ts.map +1 -1
  48. package/dist/feedback-factory/execute/changeSet.js +18 -1
  49. package/dist/feedback-factory/execute/changeSet.js.map +1 -1
  50. package/dist/feedback-factory/execute/executePolicy.d.ts +1 -1
  51. package/dist/feedback-factory/execute/executePolicy.d.ts.map +1 -1
  52. package/dist/feedback-factory/execute/executePolicy.js +2 -2
  53. package/dist/feedback-factory/execute/executePolicy.js.map +1 -1
  54. package/dist/messaging/SpawnRequestManager.d.ts +31 -0
  55. package/dist/messaging/SpawnRequestManager.d.ts.map +1 -1
  56. package/dist/messaging/SpawnRequestManager.js +149 -11
  57. package/dist/messaging/SpawnRequestManager.js.map +1 -1
  58. package/dist/messaging/TelegramAdapter.d.ts +11 -11
  59. package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
  60. package/dist/messaging/TelegramAdapter.js +59 -14
  61. package/dist/messaging/TelegramAdapter.js.map +1 -1
  62. package/dist/messaging/slack/SlackAdapter.d.ts +23 -0
  63. package/dist/messaging/slack/SlackAdapter.d.ts.map +1 -1
  64. package/dist/messaging/slack/SlackAdapter.js +69 -0
  65. package/dist/messaging/slack/SlackAdapter.js.map +1 -1
  66. package/dist/native/InstarWedgeCanary.app/Contents/MacOS/InstarWedgeCanary +0 -0
  67. package/dist/native/instar-desktop-host +0 -0
  68. package/dist/scaffold/templates.d.ts.map +1 -1
  69. package/dist/scaffold/templates.js +9 -0
  70. package/dist/scaffold/templates.js.map +1 -1
  71. package/dist/server/AgentServer.d.ts +1 -0
  72. package/dist/server/AgentServer.d.ts.map +1 -1
  73. package/dist/server/AgentServer.js +1 -0
  74. package/dist/server/AgentServer.js.map +1 -1
  75. package/dist/server/routes.d.ts +4 -0
  76. package/dist/server/routes.d.ts.map +1 -1
  77. package/dist/server/routes.js +99 -4
  78. package/dist/server/routes.js.map +1 -1
  79. package/dist/testing/selfActionRegistry.d.ts.map +1 -1
  80. package/dist/testing/selfActionRegistry.js +48 -0
  81. package/dist/testing/selfActionRegistry.js.map +1 -1
  82. package/dist/threadline/A2ADeliveryTracker.d.ts +49 -0
  83. package/dist/threadline/A2ADeliveryTracker.d.ts.map +1 -1
  84. package/dist/threadline/A2ADeliveryTracker.js +81 -2
  85. package/dist/threadline/A2ADeliveryTracker.js.map +1 -1
  86. package/dist/threadline/InboundMessageGate.d.ts.map +1 -1
  87. package/dist/threadline/InboundMessageGate.js +12 -0
  88. package/dist/threadline/InboundMessageGate.js.map +1 -1
  89. package/dist/threadline/ThreadlineBootstrap.d.ts.map +1 -1
  90. package/dist/threadline/ThreadlineBootstrap.js +13 -2
  91. package/dist/threadline/ThreadlineBootstrap.js.map +1 -1
  92. package/dist/threadline/ThreadlineEndpoints.d.ts.map +1 -1
  93. package/dist/threadline/ThreadlineEndpoints.js +9 -0
  94. package/dist/threadline/ThreadlineEndpoints.js.map +1 -1
  95. package/dist/threadline/ThreadlineMCPServer.d.ts +25 -1
  96. package/dist/threadline/ThreadlineMCPServer.d.ts.map +1 -1
  97. package/dist/threadline/ThreadlineMCPServer.js +38 -1
  98. package/dist/threadline/ThreadlineMCPServer.js.map +1 -1
  99. package/dist/threadline/ThreadlineMcpHttpService.d.ts.map +1 -1
  100. package/dist/threadline/ThreadlineMcpHttpService.js +6 -2
  101. package/dist/threadline/ThreadlineMcpHttpService.js.map +1 -1
  102. package/dist/threadline/ThreadlineRouter.d.ts +17 -1
  103. package/dist/threadline/ThreadlineRouter.d.ts.map +1 -1
  104. package/dist/threadline/ThreadlineRouter.js +22 -2
  105. package/dist/threadline/ThreadlineRouter.js.map +1 -1
  106. package/dist/threadline/TopicLinkageHandler.d.ts +9 -0
  107. package/dist/threadline/TopicLinkageHandler.d.ts.map +1 -1
  108. package/dist/threadline/TopicLinkageHandler.js +13 -2
  109. package/dist/threadline/TopicLinkageHandler.js.map +1 -1
  110. package/dist/threadline/autoAck.d.ts +37 -21
  111. package/dist/threadline/autoAck.d.ts.map +1 -1
  112. package/dist/threadline/autoAck.js +34 -19
  113. package/dist/threadline/autoAck.js.map +1 -1
  114. package/dist/threadline/client/MessageEncryptor.d.ts +5 -0
  115. package/dist/threadline/client/MessageEncryptor.d.ts.map +1 -1
  116. package/dist/threadline/client/MessageEncryptor.js.map +1 -1
  117. package/dist/threadline/client/ThreadlineClient.d.ts +26 -0
  118. package/dist/threadline/client/ThreadlineClient.d.ts.map +1 -1
  119. package/dist/threadline/client/ThreadlineClient.js +70 -4
  120. package/dist/threadline/client/ThreadlineClient.js.map +1 -1
  121. package/dist/threadline/inboundIdLedgerWiring.d.ts.map +1 -1
  122. package/dist/threadline/inboundIdLedgerWiring.js +4 -1
  123. package/dist/threadline/inboundIdLedgerWiring.js.map +1 -1
  124. package/dist/threadline/mcp-http-client.d.ts +11 -0
  125. package/dist/threadline/mcp-http-client.d.ts.map +1 -1
  126. package/dist/threadline/mcp-http-client.js +34 -0
  127. package/dist/threadline/mcp-http-client.js.map +1 -1
  128. package/dist/threadline/mcp-stdio-entry.js +4 -1
  129. package/dist/threadline/mcp-stdio-entry.js.map +1 -1
  130. package/dist/threadline/requiredAck.d.ts +64 -0
  131. package/dist/threadline/requiredAck.d.ts.map +1 -0
  132. package/dist/threadline/requiredAck.js +117 -0
  133. package/dist/threadline/requiredAck.js.map +1 -0
  134. package/dist/threadline/requiredAckService.d.ts +223 -0
  135. package/dist/threadline/requiredAckService.d.ts.map +1 -0
  136. package/dist/threadline/requiredAckService.js +565 -0
  137. package/dist/threadline/requiredAckService.js.map +1 -0
  138. package/dist/threadline/requiredAckStore.d.ts +149 -0
  139. package/dist/threadline/requiredAckStore.d.ts.map +1 -0
  140. package/dist/threadline/requiredAckStore.js +283 -0
  141. package/dist/threadline/requiredAckStore.js.map +1 -0
  142. package/package.json +1 -1
  143. package/src/data/builtin-manifest.json +66 -66
  144. package/src/data/feature-ladders.json +3 -1
  145. package/src/data/standards-guard-index.json +2 -2
  146. package/src/data/standards-guard-index.meta.json +3 -3
  147. package/src/data/standards-registry.md +12 -2
  148. package/src/data/standards-registry.meta.json +3 -3
  149. package/src/scaffold/templates.ts +9 -0
  150. package/src/templates/scripts/slack-reply.sh +7 -0
  151. package/upgrades/1.3.1663.md +77 -0
  152. package/upgrades/cloud-key-recovery-reply.eli16.md +19 -0
  153. package/upgrades/side-effects/a2a-required-acknowledgment.md +130 -0
  154. package/upgrades/side-effects/agent-health-quiet-default.md +74 -0
  155. package/upgrades/side-effects/cloud-key-recovery-reply.md +141 -0
  156. package/upgrades/side-effects/feedback-changeset-byte-cap-calibration.md +60 -0
  157. package/upgrades/side-effects/memory-privacy-ladder-off-by-default.md +100 -0
  158. package/upgrades/side-effects/memory-privacy-linux-replies.md +109 -0
  159. package/upgrades/side-effects/person-decides-counterpart.md +62 -0
  160. package/upgrades/side-effects/session-by-tmux.md +48 -0
@@ -0,0 +1,149 @@
1
+ /**
2
+ * RequiredAckStore — durable state of docs/specs/a2a-required-acknowledgment.md,
3
+ * in the A2ADeliveryTracker's database: peer capabilities (D1) and the one D5 table
4
+ * `a2a_ack_watch`, which holds two kinds of row.
5
+ *
6
+ * A `watch` row follows one inbound message through this receiver:
7
+ * prepared → router in flight (the handle already exists, in the prompt)
8
+ * queued → in the spawn manager's in-memory queue (the D2 journal row)
9
+ * open → a session has it; the D5 clock is running
10
+ * closed → acknowledged, replied, unacknowledged, dropped, or not delivered
11
+ *
12
+ * A `pending` row is a kinded ack the sender must hear (`read`, `dropped`,
13
+ * `unknown`, `unacknowledged`). It stores whether the trigger arrived encrypted,
14
+ * because known keys empty on restart. Its text is rebuilt from the fixed set.
15
+ *
16
+ * Signal-only: nothing here can block a session or a message.
17
+ */
18
+ import type { Database as BetterSqliteDatabase } from 'better-sqlite3';
19
+ import type { HeldReason } from './requiredAck.js';
20
+ export declare const REQUIRED_ACK_SCHEMA = "\nCREATE TABLE IF NOT EXISTS a2a_peer_caps (\n peer_fp TEXT PRIMARY KEY,\n ack_kinds INTEGER NOT NULL,\n seen_at TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS a2a_ack_watch (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n row_kind TEXT NOT NULL,\n status TEXT NOT NULL,\n peer_fp TEXT NOT NULL,\n message_id TEXT NOT NULL,\n thread_id TEXT,\n ack_ref TEXT,\n session_name TEXT,\n launch_lane TEXT,\n trigger_encrypted INTEGER NOT NULL DEFAULT 0,\n copies INTEGER NOT NULL DEFAULT 0,\n handed_off INTEGER NOT NULL DEFAULT 0,\n replied_before_open INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n opened_at TEXT,\n reminded_at TEXT,\n closed_at TEXT,\n close_reason TEXT,\n ack_kind TEXT,\n ack_state TEXT,\n ack_reason TEXT,\n summary TEXT,\n attempts INTEGER NOT NULL DEFAULT 0,\n next_attempt_at TEXT,\n expires_at TEXT,\n sent_at TEXT\n);\nCREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_ack_watch_ref ON a2a_ack_watch(ack_ref) WHERE ack_ref IS NOT NULL;\nCREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_ack_watch_msg ON a2a_ack_watch(peer_fp, message_id) WHERE row_kind = 'watch';\nCREATE INDEX IF NOT EXISTS idx_a2a_ack_watch_open ON a2a_ack_watch(status, opened_at) WHERE status IN ('open','queued','prepared','pending');\nCREATE INDEX IF NOT EXISTS idx_a2a_ack_watch_peer ON a2a_ack_watch(peer_fp, close_reason);\n";
21
+ /** Closed rows are removed after this long (D5). */
22
+ export declare const WATCH_RETENTION_MS: number;
23
+ export interface WatchRow {
24
+ id: number;
25
+ status: 'prepared' | 'queued' | 'open' | 'closed';
26
+ peerFp: string;
27
+ messageId: string;
28
+ threadId: string | null;
29
+ ackRef: string;
30
+ sessionName: string | null;
31
+ launchLane: 'interactive' | 'headless' | null;
32
+ triggerEncrypted: boolean;
33
+ copies: number;
34
+ handedOff: boolean;
35
+ repliedBeforeOpen: boolean;
36
+ openedAt: string | null;
37
+ remindedAt: string | null;
38
+ closeReason: string | null;
39
+ }
40
+ export interface PendingRow {
41
+ id: number;
42
+ peerFp: string;
43
+ messageId: string;
44
+ threadId: string | null;
45
+ ackKind: 'held' | 'read';
46
+ ackState: string | null;
47
+ ackReason: HeldReason | null;
48
+ summary: string | null;
49
+ triggerEncrypted: boolean;
50
+ attempts: number;
51
+ nextAttemptAt: string;
52
+ expiresAt: string;
53
+ }
54
+ export interface RequiredAckPeerCounts {
55
+ /** Messages this peer sent us that sessions never acknowledged within the window. */
56
+ unacknowledged: number;
57
+ /** Must-hear receipts that expired before they could be sent. */
58
+ pendingExpired: number;
59
+ /** Pending receipts still waiting to go out. */
60
+ pending: number;
61
+ /** Messages that reached a topic session on another machine, so are not watched. */
62
+ notWatchedRemoteTopic: number;
63
+ /** Watches currently running. */
64
+ openWatches: number;
65
+ }
66
+ /** A short random handle. A peer never chooses it, and it maps only through this table. */
67
+ export declare function mintAckRef(): string;
68
+ export declare class RequiredAckStore {
69
+ private readonly db;
70
+ constructor(db: BetterSqliteDatabase);
71
+ /** Record the highest value per peer. A chat message without the stamp deletes the row. */
72
+ notePeerCaps(peerFp: string, ackKinds: unknown, at: string): void;
73
+ peerAckKinds(peerFp: string): number | null;
74
+ /**
75
+ * The row for one inbound message, before the router runs. The handle exists from
76
+ * here, so a session can never hold a handle with no row behind it. A resend of the
77
+ * same id reuses the row: a row a session never answered is re-armed, so the new
78
+ * copy's receipts apply; an acknowledged or replied one stays closed.
79
+ */
80
+ prepareWatch(input: {
81
+ peerFp: string;
82
+ messageId: string;
83
+ threadId: string | null;
84
+ triggerEncrypted: boolean;
85
+ at: string;
86
+ }): WatchRow;
87
+ watchForMessage(peerFp: string, messageId: string): WatchRow | null;
88
+ watchForRef(ackRef: string): WatchRow | null;
89
+ /** The D2 journal: held in the spawn queue. A row already handed off stays as it is. */
90
+ markQueued(id: number, threadId: string | null): void;
91
+ /**
92
+ * A session received the message. If a reply beat the row, the row opens already
93
+ * closed. Idempotent: a later copy reaching a session leaves the clock running.
94
+ * Returns true when the clock started.
95
+ */
96
+ openWatch(id: number, input: {
97
+ sessionName: string | null;
98
+ lane: 'interactive' | 'headless';
99
+ threadId?: string | null;
100
+ at: string;
101
+ }): boolean;
102
+ closeWatch(id: number, reason: string, at: string): void;
103
+ /** One queued copy died. Returns true when no copy is left and none reached a session. */
104
+ dropCopy(id: number): boolean;
105
+ /**
106
+ * A session-authored send was accepted on this thread to this peer. Closes open
107
+ * rows; a row not yet open remembers the reply, and opens already closed.
108
+ */
109
+ closeOnReply(peerFp: string, threadId: string, at: string): number;
110
+ /** Open watches, oldest first. Bounded by the partial index. */
111
+ openWatches(limit?: number): WatchRow[];
112
+ markReminded(ids: number[], at: string): void;
113
+ /** Reminder events (not rows: a burst shares one timestamp) sent to sessions about this peer since `sinceIso`. */
114
+ remindersSince(peerFp: string, sinceIso: string): number;
115
+ /** Rows a restart interrupted: the server had a message that never finished its hand-off. */
116
+ interruptedWatches(limit?: number): WatchRow[];
117
+ /** Durably queue a kinded ack the sender must hear. Idempotent per (peer, message, kind, state). */
118
+ addPending(input: {
119
+ peerFp: string;
120
+ messageId: string;
121
+ threadId: string | null;
122
+ ackKind: 'held' | 'read';
123
+ ackState: string | null;
124
+ ackReason: HeldReason | null;
125
+ summary?: string | null;
126
+ triggerEncrypted: boolean;
127
+ at: string;
128
+ expiresAt: string;
129
+ }): number;
130
+ /** A `read` write and the watch close, as one step: a limit or a crash cannot lose both. */
131
+ acceptRead(input: {
132
+ watch: WatchRow;
133
+ summary: string;
134
+ at: string;
135
+ expiresAt: string;
136
+ }): number;
137
+ duePending(nowIsoStr: string, limit?: number): PendingRow[];
138
+ /** Pending rows past their hour close as expired, counted on the health read. */
139
+ expirePending(nowIsoStr: string): number;
140
+ markPendingSent(ids: number[], at: string): void;
141
+ closePending(ids: number[], reason: string, at: string): void;
142
+ markPendingRetry(ids: number[], attempts: number, nextAttemptAt: string): void;
143
+ /** A remote topic session has it: not watched, and health says so. */
144
+ markNotWatched(id: number, at: string): void;
145
+ peerCounts(peerFp: string): RequiredAckPeerCounts;
146
+ /** Retention: closed rows older than 14 days. Bounded per sweep. */
147
+ sweep(nowMs: number): number;
148
+ }
149
+ //# sourceMappingURL=requiredAckStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requiredAckStore.d.ts","sourceRoot":"","sources":["../../src/threadline/requiredAckStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,QAAQ,IAAI,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,eAAO,MAAM,mBAAmB,k0CAsC/B,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,kBAAkB,QAA2B,CAAC;AAG3D,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,aAAa,GAAG,UAAU,GAAG,IAAI,CAAC;IAC9C,gBAAgB,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,qFAAqF;IACrF,cAAc,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,cAAc,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,oFAAoF;IACpF,qBAAqB,EAAE,MAAM,CAAC;IAC9B,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;CACrB;AAqBD,2FAA2F;AAC3F,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,EAAE;IAA/B,YAA6B,EAAE,EAAE,oBAAoB,EAAI;IAIzD,2FAA2F;IAC3F,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAUhE;IAED,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG1C;IAID;;;;;OAKG;IACH,YAAY,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,gBAAgB,EAAE,OAAO,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,QAAQ,CAoBnI;IAED,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAGlE;IAED,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAG3C;IAED,wFAAwF;IACxF,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAKpD;IAED;;;;OAIG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,aAAa,GAAG,UAAU,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAwB5I;IAED,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAEvD;IAED,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAM5B;IAED;;;OAGG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAUjE;IAED,gEAAgE;IAChE,WAAW,CAAC,KAAK,SAAM,GAAG,QAAQ,EAAE,CAEnC;IAED,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAG5C;IAED,kHAAkH;IAClH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGvD;IAED,6FAA6F;IAC7F,kBAAkB,CAAC,KAAK,SAAM,GAAG,QAAQ,EAAE,CAE1C;IAID,oGAAoG;IACpG,UAAU,CAAC,KAAK,EAAE;QAChB,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;QACrF,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/E,gBAAgB,EAAE,OAAO,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;KAC1D,GAAG,MAAM,CAUT;IAED,4FAA4F;IAC5F,UAAU,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,QAAQ,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAU7F;IAED,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,UAAU,EAAE,CAIvD;IAED,iFAAiF;IACjF,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAIvC;IAED,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAG/C;IAED,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAG5D;IAED,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,CAG7E;IAED,sEAAsE;IACtE,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAE3C;IAID,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,qBAAqB,CAahD;IAED,oEAAoE;IACpE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK3B;CACF"}
@@ -0,0 +1,283 @@
1
+ /**
2
+ * RequiredAckStore — durable state of docs/specs/a2a-required-acknowledgment.md,
3
+ * in the A2ADeliveryTracker's database: peer capabilities (D1) and the one D5 table
4
+ * `a2a_ack_watch`, which holds two kinds of row.
5
+ *
6
+ * A `watch` row follows one inbound message through this receiver:
7
+ * prepared → router in flight (the handle already exists, in the prompt)
8
+ * queued → in the spawn manager's in-memory queue (the D2 journal row)
9
+ * open → a session has it; the D5 clock is running
10
+ * closed → acknowledged, replied, unacknowledged, dropped, or not delivered
11
+ *
12
+ * A `pending` row is a kinded ack the sender must hear (`read`, `dropped`,
13
+ * `unknown`, `unacknowledged`). It stores whether the trigger arrived encrypted,
14
+ * because known keys empty on restart. Its text is rebuilt from the fixed set.
15
+ *
16
+ * Signal-only: nothing here can block a session or a message.
17
+ */
18
+ import crypto from 'node:crypto';
19
+ export const REQUIRED_ACK_SCHEMA = `
20
+ CREATE TABLE IF NOT EXISTS a2a_peer_caps (
21
+ peer_fp TEXT PRIMARY KEY,
22
+ ack_kinds INTEGER NOT NULL,
23
+ seen_at TEXT NOT NULL
24
+ );
25
+ CREATE TABLE IF NOT EXISTS a2a_ack_watch (
26
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
27
+ row_kind TEXT NOT NULL,
28
+ status TEXT NOT NULL,
29
+ peer_fp TEXT NOT NULL,
30
+ message_id TEXT NOT NULL,
31
+ thread_id TEXT,
32
+ ack_ref TEXT,
33
+ session_name TEXT,
34
+ launch_lane TEXT,
35
+ trigger_encrypted INTEGER NOT NULL DEFAULT 0,
36
+ copies INTEGER NOT NULL DEFAULT 0,
37
+ handed_off INTEGER NOT NULL DEFAULT 0,
38
+ replied_before_open INTEGER NOT NULL DEFAULT 0,
39
+ created_at TEXT NOT NULL,
40
+ opened_at TEXT,
41
+ reminded_at TEXT,
42
+ closed_at TEXT,
43
+ close_reason TEXT,
44
+ ack_kind TEXT,
45
+ ack_state TEXT,
46
+ ack_reason TEXT,
47
+ summary TEXT,
48
+ attempts INTEGER NOT NULL DEFAULT 0,
49
+ next_attempt_at TEXT,
50
+ expires_at TEXT,
51
+ sent_at TEXT
52
+ );
53
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_ack_watch_ref ON a2a_ack_watch(ack_ref) WHERE ack_ref IS NOT NULL;
54
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_ack_watch_msg ON a2a_ack_watch(peer_fp, message_id) WHERE row_kind = 'watch';
55
+ CREATE INDEX IF NOT EXISTS idx_a2a_ack_watch_open ON a2a_ack_watch(status, opened_at) WHERE status IN ('open','queued','prepared','pending');
56
+ CREATE INDEX IF NOT EXISTS idx_a2a_ack_watch_peer ON a2a_ack_watch(peer_fp, close_reason);
57
+ `;
58
+ /** Closed rows are removed after this long (D5). */
59
+ export const WATCH_RETENTION_MS = 14 * 24 * 60 * 60 * 1000;
60
+ const SWEEP_LIMIT = 500;
61
+ function toWatch(r) {
62
+ return {
63
+ id: r.id, status: r.status, peerFp: r.peer_fp, messageId: r.message_id, threadId: r.thread_id ?? null,
64
+ ackRef: r.ack_ref, sessionName: r.session_name ?? null, launchLane: r.launch_lane ?? null,
65
+ triggerEncrypted: r.trigger_encrypted === 1, copies: r.copies, handedOff: r.handed_off === 1,
66
+ repliedBeforeOpen: r.replied_before_open === 1, openedAt: r.opened_at ?? null, remindedAt: r.reminded_at ?? null,
67
+ closeReason: r.close_reason ?? null,
68
+ };
69
+ }
70
+ function toPending(r) {
71
+ return {
72
+ id: r.id, peerFp: r.peer_fp, messageId: r.message_id, threadId: r.thread_id ?? null,
73
+ ackKind: r.ack_kind, ackState: r.ack_state ?? null, ackReason: r.ack_reason ?? null,
74
+ summary: r.summary ?? null, triggerEncrypted: r.trigger_encrypted === 1, attempts: r.attempts,
75
+ nextAttemptAt: r.next_attempt_at, expiresAt: r.expires_at,
76
+ };
77
+ }
78
+ /** A short random handle. A peer never chooses it, and it maps only through this table. */
79
+ export function mintAckRef() {
80
+ return `ack-${crypto.randomBytes(6).toString('hex')}`;
81
+ }
82
+ export class RequiredAckStore {
83
+ db;
84
+ constructor(db) {
85
+ this.db = db;
86
+ }
87
+ // ── D1: capabilities ──────────────────────────────────────────────
88
+ /** Record the highest value per peer. A chat message without the stamp deletes the row. */
89
+ notePeerCaps(peerFp, ackKinds, at) {
90
+ if (!peerFp)
91
+ return;
92
+ if (typeof ackKinds === 'number' && Number.isFinite(ackKinds) && ackKinds >= 1) {
93
+ this.db.prepare(`INSERT INTO a2a_peer_caps (peer_fp, ack_kinds, seen_at) VALUES (?, ?, ?)
94
+ ON CONFLICT(peer_fp) DO UPDATE SET ack_kinds = MAX(a2a_peer_caps.ack_kinds, excluded.ack_kinds), seen_at = excluded.seen_at`).run(peerFp, Math.floor(ackKinds), at);
95
+ }
96
+ else {
97
+ this.db.prepare(`DELETE FROM a2a_peer_caps WHERE peer_fp = ?`).run(peerFp);
98
+ }
99
+ }
100
+ peerAckKinds(peerFp) {
101
+ const r = this.db.prepare(`SELECT ack_kinds FROM a2a_peer_caps WHERE peer_fp = ?`).get(peerFp);
102
+ return r?.ack_kinds ?? null;
103
+ }
104
+ // ── Watch rows ────────────────────────────────────────────────────
105
+ /**
106
+ * The row for one inbound message, before the router runs. The handle exists from
107
+ * here, so a session can never hold a handle with no row behind it. A resend of the
108
+ * same id reuses the row: a row a session never answered is re-armed, so the new
109
+ * copy's receipts apply; an acknowledged or replied one stays closed.
110
+ */
111
+ prepareWatch(input) {
112
+ const existing = this.db.prepare(`SELECT * FROM a2a_ack_watch WHERE row_kind = 'watch' AND peer_fp = ? AND message_id = ?`)
113
+ .get(input.peerFp, input.messageId);
114
+ if (existing) {
115
+ if (existing.status === 'closed' && existing.close_reason !== 'acknowledged' && existing.close_reason !== 'replied') {
116
+ this.db.prepare(`UPDATE a2a_ack_watch SET status = 'prepared', closed_at = NULL, close_reason = NULL, copies = 0, reminded_at = NULL, opened_at = NULL, handed_off = 0 WHERE id = ?`).run(existing.id);
117
+ }
118
+ // A copy that arrived encrypted means the peer holds keys, so the acknowledgment
119
+ // must never go plaintext, whichever copy came first.
120
+ if (input.triggerEncrypted && !existing.trigger_encrypted) {
121
+ this.db.prepare(`UPDATE a2a_ack_watch SET trigger_encrypted = 1 WHERE id = ?`).run(existing.id);
122
+ }
123
+ return toWatch(this.db.prepare(`SELECT * FROM a2a_ack_watch WHERE id = ?`).get(existing.id));
124
+ }
125
+ const ackRef = mintAckRef();
126
+ this.db.prepare(`INSERT INTO a2a_ack_watch (row_kind, status, peer_fp, message_id, thread_id, ack_ref, trigger_encrypted, created_at)
127
+ VALUES ('watch', 'prepared', ?, ?, ?, ?, ?, ?)`).run(input.peerFp, input.messageId, input.threadId, ackRef, input.triggerEncrypted ? 1 : 0, input.at);
128
+ return toWatch(this.db.prepare(`SELECT * FROM a2a_ack_watch WHERE ack_ref = ?`).get(ackRef));
129
+ }
130
+ watchForMessage(peerFp, messageId) {
131
+ const r = this.db.prepare(`SELECT * FROM a2a_ack_watch WHERE row_kind = 'watch' AND peer_fp = ? AND message_id = ?`).get(peerFp, messageId);
132
+ return r ? toWatch(r) : null;
133
+ }
134
+ watchForRef(ackRef) {
135
+ const r = this.db.prepare(`SELECT * FROM a2a_ack_watch WHERE row_kind = 'watch' AND ack_ref = ?`).get(ackRef);
136
+ return r ? toWatch(r) : null;
137
+ }
138
+ /** The D2 journal: held in the spawn queue. A row already handed off stays as it is. */
139
+ markQueued(id, threadId) {
140
+ this.db.prepare(`UPDATE a2a_ack_watch SET status = 'queued', copies = copies + 1, thread_id = COALESCE(?, thread_id)
141
+ WHERE id = ? AND status IN ('prepared','queued')`).run(threadId, id);
142
+ }
143
+ /**
144
+ * A session received the message. If a reply beat the row, the row opens already
145
+ * closed. Idempotent: a later copy reaching a session leaves the clock running.
146
+ * Returns true when the clock started.
147
+ */
148
+ openWatch(id, input) {
149
+ const r = this.db.prepare(`SELECT status, replied_before_open FROM a2a_ack_watch WHERE id = ?`).get(id);
150
+ if (!r)
151
+ return false;
152
+ if (r.status === 'open') {
153
+ // The spawn manager's callback got here first; the router's report knows the
154
+ // thread it resolved and, on the injected path, the session.
155
+ this.db.prepare(`UPDATE a2a_ack_watch SET thread_id = COALESCE(?, thread_id), session_name = COALESCE(session_name, ?) WHERE id = ?`)
156
+ .run(input.threadId ?? null, input.sessionName, id);
157
+ return false;
158
+ }
159
+ if (r.status === 'closed') {
160
+ this.db.prepare(`UPDATE a2a_ack_watch SET handed_off = 1 WHERE id = ?`).run(id);
161
+ return false;
162
+ }
163
+ if (r.replied_before_open === 1) {
164
+ this.db.prepare(`UPDATE a2a_ack_watch SET status = 'closed', handed_off = 1, closed_at = ?, close_reason = 'replied', session_name = ?, launch_lane = ?, thread_id = COALESCE(?, thread_id) WHERE id = ?`).run(input.at, input.sessionName, input.lane, input.threadId ?? null, id);
165
+ return false;
166
+ }
167
+ this.db.prepare(`UPDATE a2a_ack_watch SET status = 'open', handed_off = 1, opened_at = ?, session_name = ?, launch_lane = ?, thread_id = COALESCE(?, thread_id) WHERE id = ?`).run(input.at, input.sessionName, input.lane, input.threadId ?? null, id);
168
+ return true;
169
+ }
170
+ closeWatch(id, reason, at) {
171
+ this.db.prepare(`UPDATE a2a_ack_watch SET status = 'closed', closed_at = ?, close_reason = ? WHERE id = ? AND status != 'closed'`).run(at, reason, id);
172
+ }
173
+ /** One queued copy died. Returns true when no copy is left and none reached a session. */
174
+ dropCopy(id) {
175
+ const r = this.db.prepare(`SELECT status, copies, handed_off FROM a2a_ack_watch WHERE id = ?`).get(id);
176
+ if (!r || r.status !== 'queued' || r.handed_off === 1)
177
+ return false;
178
+ const left = Math.max(0, r.copies - 1);
179
+ this.db.prepare(`UPDATE a2a_ack_watch SET copies = ? WHERE id = ?`).run(left, id);
180
+ return left === 0;
181
+ }
182
+ /**
183
+ * A session-authored send was accepted on this thread to this peer. Closes open
184
+ * rows; a row not yet open remembers the reply, and opens already closed.
185
+ */
186
+ closeOnReply(peerFp, threadId, at) {
187
+ const closed = this.db.prepare(`UPDATE a2a_ack_watch SET status = 'closed', closed_at = ?, close_reason = 'replied'
188
+ WHERE row_kind = 'watch' AND peer_fp = ? AND thread_id = ? AND status = 'open'`).run(at, peerFp, threadId);
189
+ this.db.prepare(`UPDATE a2a_ack_watch SET replied_before_open = 1
190
+ WHERE row_kind = 'watch' AND peer_fp = ? AND thread_id = ? AND status IN ('prepared','queued')`).run(peerFp, threadId);
191
+ return closed.changes;
192
+ }
193
+ /** Open watches, oldest first. Bounded by the partial index. */
194
+ openWatches(limit = 500) {
195
+ return this.db.prepare(`SELECT * FROM a2a_ack_watch WHERE status = 'open' AND row_kind = 'watch' ORDER BY opened_at ASC LIMIT ?`).all(limit).map(toWatch);
196
+ }
197
+ markReminded(ids, at) {
198
+ const stmt = this.db.prepare(`UPDATE a2a_ack_watch SET reminded_at = ? WHERE id = ?`);
199
+ this.db.transaction(() => { for (const id of ids)
200
+ stmt.run(at, id); })();
201
+ }
202
+ /** Reminder events (not rows: a burst shares one timestamp) sent to sessions about this peer since `sinceIso`. */
203
+ remindersSince(peerFp, sinceIso) {
204
+ const r = this.db.prepare(`SELECT COUNT(DISTINCT reminded_at) AS n FROM a2a_ack_watch WHERE row_kind = 'watch' AND peer_fp = ? AND reminded_at IS NOT NULL AND reminded_at >= ?`).get(peerFp, sinceIso);
205
+ return r.n;
206
+ }
207
+ /** Rows a restart interrupted: the server had a message that never finished its hand-off. */
208
+ interruptedWatches(limit = 500) {
209
+ return this.db.prepare(`SELECT * FROM a2a_ack_watch WHERE row_kind = 'watch' AND status IN ('prepared','queued') ORDER BY created_at ASC LIMIT ?`).all(limit).map(toWatch);
210
+ }
211
+ // ── Pending kinded acks ───────────────────────────────────────────
212
+ /** Durably queue a kinded ack the sender must hear. Idempotent per (peer, message, kind, state). */
213
+ addPending(input) {
214
+ const existing = this.db.prepare(`SELECT id FROM a2a_ack_watch WHERE row_kind = 'pending' AND status = 'pending' AND peer_fp = ? AND message_id = ? AND ack_kind = ? AND COALESCE(ack_state,'') = COALESCE(?,'')`).get(input.peerFp, input.messageId, input.ackKind, input.ackState);
215
+ if (existing)
216
+ return existing.id;
217
+ const info = this.db.prepare(`INSERT INTO a2a_ack_watch (row_kind, status, peer_fp, message_id, thread_id, trigger_encrypted, created_at, ack_kind, ack_state, ack_reason, summary, next_attempt_at, expires_at)
218
+ VALUES ('pending', 'pending', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(input.peerFp, input.messageId, input.threadId, input.triggerEncrypted ? 1 : 0, input.at, input.ackKind, input.ackState, input.ackReason, input.summary ?? null, input.at, input.expiresAt);
219
+ return Number(info.lastInsertRowid);
220
+ }
221
+ /** A `read` write and the watch close, as one step: a limit or a crash cannot lose both. */
222
+ acceptRead(input) {
223
+ return this.db.transaction(() => {
224
+ const id = this.addPending({
225
+ peerFp: input.watch.peerFp, messageId: input.watch.messageId, threadId: input.watch.threadId,
226
+ ackKind: 'read', ackState: null, ackReason: null, summary: input.summary,
227
+ triggerEncrypted: input.watch.triggerEncrypted, at: input.at, expiresAt: input.expiresAt,
228
+ });
229
+ this.db.prepare(`UPDATE a2a_ack_watch SET status = 'closed', closed_at = ?, close_reason = 'acknowledged' WHERE id = ?`).run(input.at, input.watch.id);
230
+ return id;
231
+ })();
232
+ }
233
+ duePending(nowIsoStr, limit = 200) {
234
+ return this.db.prepare(`SELECT * FROM a2a_ack_watch WHERE status = 'pending' AND row_kind = 'pending' AND next_attempt_at <= ? ORDER BY next_attempt_at ASC LIMIT ?`).all(nowIsoStr, limit).map(toPending);
235
+ }
236
+ /** Pending rows past their hour close as expired, counted on the health read. */
237
+ expirePending(nowIsoStr) {
238
+ return this.db.prepare(`UPDATE a2a_ack_watch SET status = 'closed', closed_at = ?, close_reason = 'expired' WHERE status = 'pending' AND row_kind = 'pending' AND expires_at <= ?`).run(nowIsoStr, nowIsoStr).changes;
239
+ }
240
+ markPendingSent(ids, at) {
241
+ const stmt = this.db.prepare(`UPDATE a2a_ack_watch SET status = 'closed', closed_at = ?, close_reason = 'sent', sent_at = ? WHERE id = ?`);
242
+ this.db.transaction(() => { for (const id of ids)
243
+ stmt.run(at, at, id); })();
244
+ }
245
+ closePending(ids, reason, at) {
246
+ const stmt = this.db.prepare(`UPDATE a2a_ack_watch SET status = 'closed', closed_at = ?, close_reason = ? WHERE id = ?`);
247
+ this.db.transaction(() => { for (const id of ids)
248
+ stmt.run(at, reason, id); })();
249
+ }
250
+ markPendingRetry(ids, attempts, nextAttemptAt) {
251
+ const stmt = this.db.prepare(`UPDATE a2a_ack_watch SET attempts = ?, next_attempt_at = ? WHERE id = ?`);
252
+ this.db.transaction(() => { for (const id of ids)
253
+ stmt.run(attempts, nextAttemptAt, id); })();
254
+ }
255
+ /** A remote topic session has it: not watched, and health says so. */
256
+ markNotWatched(id, at) {
257
+ this.db.prepare(`UPDATE a2a_ack_watch SET status = 'closed', closed_at = ?, close_reason = 'remote-topic', handed_off = 1 WHERE id = ?`).run(at, id);
258
+ }
259
+ // ── Reads ─────────────────────────────────────────────────────────
260
+ peerCounts(peerFp) {
261
+ const rows = this.db.prepare(`SELECT row_kind, status, close_reason, ack_state, COUNT(*) AS n FROM a2a_ack_watch WHERE peer_fp = ? GROUP BY row_kind, status, close_reason, ack_state`).all(peerFp);
262
+ const out = { unacknowledged: 0, pendingExpired: 0, pending: 0, notWatchedRemoteTopic: 0, openWatches: 0 };
263
+ for (const r of rows) {
264
+ if (r.row_kind === 'watch' && r.status === 'closed' && r.close_reason === 'unacknowledged')
265
+ out.unacknowledged += r.n;
266
+ else if (r.row_kind === 'watch' && r.status === 'closed' && r.close_reason === 'remote-topic')
267
+ out.notWatchedRemoteTopic += r.n;
268
+ else if (r.row_kind === 'watch' && r.status === 'open')
269
+ out.openWatches += r.n;
270
+ else if (r.row_kind === 'pending' && r.status === 'pending')
271
+ out.pending += r.n;
272
+ else if (r.row_kind === 'pending' && r.close_reason === 'expired')
273
+ out.pendingExpired += r.n;
274
+ }
275
+ return out;
276
+ }
277
+ /** Retention: closed rows older than 14 days. Bounded per sweep. */
278
+ sweep(nowMs) {
279
+ const cutoff = new Date(nowMs - WATCH_RETENTION_MS).toISOString();
280
+ return this.db.prepare(`DELETE FROM a2a_ack_watch WHERE id IN (SELECT id FROM a2a_ack_watch WHERE status = 'closed' AND closed_at < ? LIMIT ${SWEEP_LIMIT})`).run(cutoff).changes;
281
+ }
282
+ }
283
+ //# sourceMappingURL=requiredAckStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requiredAckStore.js","sourceRoot":"","sources":["../../src/threadline/requiredAckStore.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.1661",
3
+ "version": "1.3.1663",
4
4
  "description": "Coherence infrastructure for self-evolving AI agents — on the Claude Code or Codex subscription you already have.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",