@lucern/contracts 1.0.56 → 1.0.57

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.
@@ -0,0 +1,306 @@
1
+ import { z } from 'zod';
2
+
3
+ // src/manifests/operation-manifest.ts
4
+ var OPERATION_VERBS = [
5
+ // read plane
6
+ "get",
7
+ "list",
8
+ "search",
9
+ "traverse",
10
+ "compile",
11
+ "diff",
12
+ "replay",
13
+ // write plane
14
+ "create",
15
+ "refine",
16
+ "append",
17
+ "fork",
18
+ "transition",
19
+ "evaluate",
20
+ "graduate",
21
+ // governance plane
22
+ "declare",
23
+ "bind",
24
+ "grant"
25
+ ];
26
+ var OPERATION_KINDS = [
27
+ "node",
28
+ "edge",
29
+ "container",
30
+ "slice",
31
+ "record",
32
+ "policy",
33
+ "unresolved"
34
+ ];
35
+ var OPERATION_AXES = [
36
+ "scope",
37
+ "horizon",
38
+ "lens",
39
+ "policy",
40
+ "strategy",
41
+ "carrier"
42
+ ];
43
+ var PROJECTION_CLASSES = [
44
+ "canonical_public",
45
+ "internal_backing",
46
+ "extension",
47
+ "compat",
48
+ "client_local"
49
+ ];
50
+ var SURFACE_EXPOSURE = ["public", "internal", "absent"];
51
+ var OPERATION_SOURCES = [
52
+ "registry",
53
+ "kernelApi",
54
+ "mcp_extension",
55
+ "cli_bespoke"
56
+ ];
57
+ var operationRowSchema = z.object({
58
+ /** Canonical operation identity. Snake_case for graph operations; dotted
59
+ * `domain.method` for kernelApi host bindings; `domain subcommand` for CLI
60
+ * bespoke handlers. Unique across the manifest. */
61
+ name: z.string().min(1),
62
+ /** SC.2 verb. */
63
+ verb: z.enum(OPERATION_VERBS),
64
+ /** SC.2 target: the kind, and an optional type that narrows it. */
65
+ target: z.object({
66
+ kind: z.enum(OPERATION_KINDS),
67
+ type: z.string().min(1).optional()
68
+ }),
69
+ /** SC.2 axes this operation accepts. */
70
+ axes: z.array(z.enum(OPERATION_AXES)).readonly(),
71
+ /** Projection class (design doc): where in the surface taxonomy this row
72
+ * lives. `internal_backing` is a class, not a second language. */
73
+ projection: z.object({
74
+ class: z.enum(PROJECTION_CLASSES),
75
+ /** Per-surface exposure. `kernelApi` is present so the shadow surface is
76
+ * expressible; the four public surfaces mirror the registry map. */
77
+ surfaces: z.object({
78
+ sdk: z.enum(SURFACE_EXPOSURE),
79
+ rest: z.enum(SURFACE_EXPOSURE),
80
+ mcp: z.enum(SURFACE_EXPOSURE),
81
+ cli: z.enum(SURFACE_EXPOSURE),
82
+ host: z.enum(SURFACE_EXPOSURE),
83
+ kernelApi: z.enum(SURFACE_EXPOSURE)
84
+ }),
85
+ /** Compat rows carry an alias + exit-criteria doc pointer. */
86
+ compat: z.object({ aliasOf: z.string(), exitCriteria: z.string() }).optional()
87
+ }),
88
+ /** Where this row was expressed from (census population). */
89
+ source: z.enum(OPERATION_SOURCES),
90
+ /** Concrete source binding: the code location this row projects. For registry
91
+ * rows, the registry entry name; for kernelApi rows, the `api.*` ref path and
92
+ * its `components.lucern.*` component path; for extension/bespoke rows, the
93
+ * wiring symbol / command path. */
94
+ binding: z.object({
95
+ /** The primary source identifier (registry name, api ref path, tool name,
96
+ * or CLI command path). */
97
+ ref: z.string().min(1),
98
+ /** kernelApi component path (`components.lucern.*`) when source=kernelApi. */
99
+ componentPath: z.string().optional(),
100
+ /** For extension/bespoke rows that back a registry op, the registry op name
101
+ * they are a projection of (so census facts about registry ops are
102
+ * expressed on the row, not double-counted as phantom operations). */
103
+ backsRegistryOp: z.string().optional()
104
+ }),
105
+ /** Lifecycle status. `active` for served operations; `compat` for legacy
106
+ * aliases awaiting deletion criteria. */
107
+ status: z.enum(["active", "compat"]),
108
+ /** M2-derivation pointers, named-but-null in M1 (see file header). */
109
+ derivation: z.object({
110
+ /** Arg/returns schema derived in M2. Null in M1. */
111
+ schema: z.null(),
112
+ /** Legality-matrix row derived in M2. Null in M1. */
113
+ legality: z.null(),
114
+ /** Receipt shape derived in M2. Null in M1. */
115
+ receipt: z.null()
116
+ }),
117
+ /** Human-readable provenance from the census/registry. */
118
+ rationale: z.string()
119
+ });
120
+ var operationManifestSchema = z.object({
121
+ schemaVersion: z.literal("operation_manifest.m1.v1"),
122
+ generatedAt: z.string(),
123
+ /** Census reconciliation block: the counts this manifest expresses, keyed by
124
+ * the SC.1 disposition dimensions, so the derivability test can assert them
125
+ * against the disposition doc and surface any point-in-time delta. */
126
+ census: z.object({
127
+ total: z.number(),
128
+ bySource: z.object({
129
+ registry: z.number(),
130
+ kernelApi: z.number(),
131
+ mcp_extension: z.number(),
132
+ cli_bespoke: z.number()
133
+ }),
134
+ byProjectionClass: z.object({
135
+ canonical_public: z.number(),
136
+ internal_backing: z.number(),
137
+ extension: z.number(),
138
+ compat: z.number(),
139
+ client_local: z.number()
140
+ }),
141
+ registryBySurfaceClass: z.record(z.string(), z.number())
142
+ }),
143
+ operations: z.array(operationRowSchema)
144
+ });
145
+ var SC1_CENSUS_TARGETS = {
146
+ /** 190 function-registry contracts (surface-manifest.json). Exact. */
147
+ registryContracts: 190,
148
+ /** Registry class split (161 canonical public + 25 internal + 4 compat). */
149
+ registryCanonicalPublic: 161,
150
+ registryPlatformInternal: 25,
151
+ registryLegacyCompat: 4,
152
+ /** kernelApi allowlist refs. Census recorded 124 post-#1651; the live
153
+ * allowlist is the authority and the check tolerates a documented delta. */
154
+ kernelApiRefsCensus: 124,
155
+ /** MCP extension wirings the server hand-registers beyond the generated
156
+ * build (census: 159 MCP tools − 144 generated = 15). Every extension tool
157
+ * is *also* a registry contract, so these are expressed as projection facts
158
+ * (mcp_extension source rows that `backsRegistryOp`), not new operations. */
159
+ mcpExtensions: 15,
160
+ /** CLI bespoke handlers (census: 19). Gateway-hitting bespoke verbs +
161
+ * client-local tooling. Expressed as cli_bespoke rows; the gateway-hitting
162
+ * subset backs a registry op or is a promotion candidate. */
163
+ cliBespoke: 19
164
+ };
165
+ var MCP_EXTENSION_WIRINGS = [
166
+ // bootstrap group (BOOTSTRAP_MCP_TOOLS)
167
+ "generate_session_handoff",
168
+ "begin_build_session",
169
+ // coordination group (COORDINATION_MCP_TOOLS) — the SC.1 session-runtime family
170
+ "register_session",
171
+ "heartbeat_session",
172
+ "end_session",
173
+ "list_active_sessions",
174
+ "send_agent_message",
175
+ "broadcast_message",
176
+ "get_agent_inbox",
177
+ "claim_files",
178
+ // epistemic-contract group (EPISTEMIC_CONTRACT_MCP_TOOLS)
179
+ "create_epistemic_contract",
180
+ "evaluate_contract",
181
+ "get_contract_status",
182
+ // MCP-only internal contract evaluators (manifest.ts MCP_ONLY_INTERNAL_OPERATION_NAMES)
183
+ "evaluate_engineering_contract",
184
+ "evaluate_research_contract"
185
+ ];
186
+ var CLI_BESPOKE_HANDLERS = [
187
+ // gateway-hitting bespoke verbs (SC.1: the 5 promotion candidates + the
188
+ // reconciliation/capture verbs that also carry bespoke handlers)
189
+ {
190
+ command: "checkpoint",
191
+ gatewayHitting: true,
192
+ backsRegistryOp: null,
193
+ promotionCandidate: true
194
+ },
195
+ {
196
+ command: "evidence record-ci",
197
+ gatewayHitting: true,
198
+ backsRegistryOp: "create_evidence",
199
+ promotionCandidate: true
200
+ },
201
+ {
202
+ command: "dispatch record",
203
+ gatewayHitting: true,
204
+ backsRegistryOp: null,
205
+ promotionCandidate: true
206
+ },
207
+ {
208
+ command: "pivot record",
209
+ gatewayHitting: true,
210
+ backsRegistryOp: null,
211
+ promotionCandidate: true
212
+ },
213
+ {
214
+ command: "contradiction declare",
215
+ gatewayHitting: true,
216
+ backsRegistryOp: "flag_contradiction",
217
+ promotionCandidate: true
218
+ },
219
+ {
220
+ command: "campaign closeout",
221
+ gatewayHitting: true,
222
+ backsRegistryOp: null,
223
+ promotionCandidate: false
224
+ },
225
+ {
226
+ command: "worktrees context",
227
+ gatewayHitting: true,
228
+ backsRegistryOp: "get_worktree",
229
+ promotionCandidate: false
230
+ },
231
+ {
232
+ command: "worktrees reconcile-gate",
233
+ gatewayHitting: true,
234
+ backsRegistryOp: null,
235
+ promotionCandidate: false
236
+ },
237
+ {
238
+ command: "embeddings",
239
+ gatewayHitting: true,
240
+ backsRegistryOp: null,
241
+ promotionCandidate: false
242
+ },
243
+ // client-local handlers (SC.1 §"Client-local ~10") — no server operation
244
+ {
245
+ command: "auth",
246
+ gatewayHitting: false,
247
+ backsRegistryOp: null,
248
+ promotionCandidate: false
249
+ },
250
+ {
251
+ command: "profile",
252
+ gatewayHitting: false,
253
+ backsRegistryOp: null,
254
+ promotionCandidate: false
255
+ },
256
+ {
257
+ command: "scope",
258
+ gatewayHitting: false,
259
+ backsRegistryOp: null,
260
+ promotionCandidate: false
261
+ },
262
+ {
263
+ command: "doctor",
264
+ gatewayHitting: false,
265
+ backsRegistryOp: null,
266
+ promotionCandidate: false
267
+ },
268
+ {
269
+ command: "completions",
270
+ gatewayHitting: false,
271
+ backsRegistryOp: null,
272
+ promotionCandidate: false
273
+ },
274
+ {
275
+ command: "login",
276
+ gatewayHitting: false,
277
+ backsRegistryOp: null,
278
+ promotionCandidate: false
279
+ },
280
+ {
281
+ command: "version",
282
+ gatewayHitting: false,
283
+ backsRegistryOp: null,
284
+ promotionCandidate: false
285
+ },
286
+ {
287
+ command: "functions",
288
+ gatewayHitting: false,
289
+ backsRegistryOp: null,
290
+ promotionCandidate: false
291
+ },
292
+ {
293
+ command: "replay",
294
+ gatewayHitting: false,
295
+ backsRegistryOp: null,
296
+ promotionCandidate: false
297
+ },
298
+ {
299
+ command: "local-workflow",
300
+ gatewayHitting: false,
301
+ backsRegistryOp: null,
302
+ promotionCandidate: false
303
+ }
304
+ ];
305
+
306
+ export { CLI_BESPOKE_HANDLERS, MCP_EXTENSION_WIRINGS, OPERATION_AXES, OPERATION_KINDS, OPERATION_SOURCES, OPERATION_VERBS, PROJECTION_CLASSES, SC1_CENSUS_TARGETS, SURFACE_EXPOSURE, operationManifestSchema, operationRowSchema };
@@ -41,5 +41,5 @@
41
41
  "convex-validators",
42
42
  "proof-attestation"
43
43
  ],
44
- "signedAt": 1782994689967
44
+ "signedAt": 1783073301464
45
45
  }
@@ -2975,9 +2975,39 @@ var domainEvents = defineTable({
2975
2975
  name: "by_resource",
2976
2976
  columns: ["resourceType", "resourceId", "timestamp"]
2977
2977
  },
2978
+ // OB.2: global chronological order for the Axiom forwarding scan. The
2979
+ // forwarder pages events strictly by (timestamp, eventId) after its
2980
+ // checkpoint cursor, so it needs a total time order independent of topic /
2981
+ // type / tenant. The forwarder additionally tie-breaks on eventId in
2982
+ // application code for events sharing a millisecond timestamp.
2983
+ { kind: "index", name: "by_timestamp", columns: ["timestamp"] },
2978
2984
  { kind: "index", name: "by_expiresAt", columns: ["expiresAt"] }
2979
2985
  ]
2980
2986
  });
2987
+ var domainEventForwardCheckpoints = defineTable({
2988
+ name: "domainEventForwardCheckpoints",
2989
+ component: "kernel",
2990
+ category: "events",
2991
+ shape: z.object({
2992
+ // Logical sink name. One checkpoint row per forwarding destination so a
2993
+ // second sink (e.g. a future OTel path) never contends on this cursor.
2994
+ sink: z.string(),
2995
+ // Cursor: the timestamp of the last successfully forwarded event (ms epoch).
2996
+ lastForwardedTimestamp: z.number(),
2997
+ // Cursor tie-breaker: the eventId of the last successfully forwarded event.
2998
+ lastForwardedEventId: z.string(),
2999
+ // Running count of events forwarded through this sink (observability of the
3000
+ // observer — lets an operator confirm the pump is moving without Axiom).
3001
+ forwardedCount: z.number(),
3002
+ // When this checkpoint row was last advanced (ms epoch).
3003
+ updatedAt: z.number(),
3004
+ // Last tick outcome, for at-a-glance health without querying Axiom.
3005
+ lastStatus: z.enum(["ok", "empty", "export_failed"]).optional(),
3006
+ // Redacted last-error summary when lastStatus is export_failed.
3007
+ lastError: z.string().optional()
3008
+ }),
3009
+ indices: [{ kind: "index", name: "by_sink", columns: ["sink"] }]
3010
+ });
2981
3011
  var idempotencyTokens = defineTable({
2982
3012
  name: "idempotencyTokens",
2983
3013
  component: "kernel",
@@ -13505,6 +13535,7 @@ var KERNEL_TABLE_CONTRACTS = [
13505
13535
  decisionRiskLedger,
13506
13536
  decisionSnapshots,
13507
13537
  domainEvents,
13538
+ domainEventForwardCheckpoints,
13508
13539
  deliberationContributions,
13509
13540
  deliberationSessions,
13510
13541
  stakeholderGroups,
@@ -205,6 +205,14 @@ export declare const KERNEL_TABLE_CONTRACTS: readonly [import("../dsl.js").Table
205
205
  data: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>;
206
206
  correlationId: import("zod").ZodOptional<import("zod").ZodString>;
207
207
  expiresAt: import("zod").ZodNumber;
208
+ }>, import("../dsl.js").TableContract<{
209
+ sink: import("zod").ZodString;
210
+ lastForwardedTimestamp: import("zod").ZodNumber;
211
+ lastForwardedEventId: import("zod").ZodString;
212
+ forwardedCount: import("zod").ZodNumber;
213
+ updatedAt: import("zod").ZodNumber;
214
+ lastStatus: import("zod").ZodOptional<import("zod").ZodEnum<["ok", "empty", "export_failed"]>>;
215
+ lastError: import("zod").ZodOptional<import("zod").ZodString>;
208
216
  }>, import("../dsl.js").TableContract<{
209
217
  sessionId: import("../dsl.js").ConvexIdSchema<"deliberationSessions">;
210
218
  topicId: import("zod").ZodOptional<import("zod").ZodString>;
@@ -5650,6 +5658,14 @@ export declare const TABLE_CONTRACTS_BY_COMPONENT: {
5650
5658
  data: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>;
5651
5659
  correlationId: import("zod").ZodOptional<import("zod").ZodString>;
5652
5660
  expiresAt: import("zod").ZodNumber;
5661
+ }>, import("../dsl.js").TableContract<{
5662
+ sink: import("zod").ZodString;
5663
+ lastForwardedTimestamp: import("zod").ZodNumber;
5664
+ lastForwardedEventId: import("zod").ZodString;
5665
+ forwardedCount: import("zod").ZodNumber;
5666
+ updatedAt: import("zod").ZodNumber;
5667
+ lastStatus: import("zod").ZodOptional<import("zod").ZodEnum<["ok", "empty", "export_failed"]>>;
5668
+ lastError: import("zod").ZodOptional<import("zod").ZodString>;
5653
5669
  }>, import("../dsl.js").TableContract<{
5654
5670
  sessionId: import("../dsl.js").ConvexIdSchema<"deliberationSessions">;
5655
5671
  topicId: import("zod").ZodOptional<import("zod").ZodString>;
@@ -11096,6 +11112,14 @@ export declare const ALL_TABLE_CONTRACTS: readonly [import("../dsl.js").TableCon
11096
11112
  data: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>;
11097
11113
  correlationId: import("zod").ZodOptional<import("zod").ZodString>;
11098
11114
  expiresAt: import("zod").ZodNumber;
11115
+ }>, import("../dsl.js").TableContract<{
11116
+ sink: import("zod").ZodString;
11117
+ lastForwardedTimestamp: import("zod").ZodNumber;
11118
+ lastForwardedEventId: import("zod").ZodString;
11119
+ forwardedCount: import("zod").ZodNumber;
11120
+ updatedAt: import("zod").ZodNumber;
11121
+ lastStatus: import("zod").ZodOptional<import("zod").ZodEnum<["ok", "empty", "export_failed"]>>;
11122
+ lastError: import("zod").ZodOptional<import("zod").ZodString>;
11099
11123
  }>, import("../dsl.js").TableContract<{
11100
11124
  sessionId: import("../dsl.js").ConvexIdSchema<"deliberationSessions">;
11101
11125
  topicId: import("zod").ZodOptional<import("zod").ZodString>;
@@ -17678,6 +17702,14 @@ export declare function listTableContractsByName(name: string): (import("../dsl.
17678
17702
  data: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>;
17679
17703
  correlationId: import("zod").ZodOptional<import("zod").ZodString>;
17680
17704
  expiresAt: import("zod").ZodNumber;
17705
+ }> | import("../dsl.js").TableContract<{
17706
+ sink: import("zod").ZodString;
17707
+ lastForwardedTimestamp: import("zod").ZodNumber;
17708
+ lastForwardedEventId: import("zod").ZodString;
17709
+ forwardedCount: import("zod").ZodNumber;
17710
+ updatedAt: import("zod").ZodNumber;
17711
+ lastStatus: import("zod").ZodOptional<import("zod").ZodEnum<["ok", "empty", "export_failed"]>>;
17712
+ lastError: import("zod").ZodOptional<import("zod").ZodString>;
17681
17713
  }> | import("../dsl.js").TableContract<{
17682
17714
  tenantId: import("zod").ZodString;
17683
17715
  fnName: import("zod").ZodString;
@@ -23120,6 +23152,14 @@ export declare function getTableContract(name: string, component?: string): impo
23120
23152
  data: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>;
23121
23153
  correlationId: import("zod").ZodOptional<import("zod").ZodString>;
23122
23154
  expiresAt: import("zod").ZodNumber;
23155
+ }> | import("../dsl.js").TableContract<{
23156
+ sink: import("zod").ZodString;
23157
+ lastForwardedTimestamp: import("zod").ZodNumber;
23158
+ lastForwardedEventId: import("zod").ZodString;
23159
+ forwardedCount: import("zod").ZodNumber;
23160
+ updatedAt: import("zod").ZodNumber;
23161
+ lastStatus: import("zod").ZodOptional<import("zod").ZodEnum<["ok", "empty", "export_failed"]>>;
23162
+ lastError: import("zod").ZodOptional<import("zod").ZodString>;
23123
23163
  }> | import("../dsl.js").TableContract<{
23124
23164
  tenantId: import("zod").ZodString;
23125
23165
  fnName: import("zod").ZodString;
@@ -2842,9 +2842,39 @@ var domainEvents = defineTable({
2842
2842
  name: "by_resource",
2843
2843
  columns: ["resourceType", "resourceId", "timestamp"]
2844
2844
  },
2845
+ // OB.2: global chronological order for the Axiom forwarding scan. The
2846
+ // forwarder pages events strictly by (timestamp, eventId) after its
2847
+ // checkpoint cursor, so it needs a total time order independent of topic /
2848
+ // type / tenant. The forwarder additionally tie-breaks on eventId in
2849
+ // application code for events sharing a millisecond timestamp.
2850
+ { kind: "index", name: "by_timestamp", columns: ["timestamp"] },
2845
2851
  { kind: "index", name: "by_expiresAt", columns: ["expiresAt"] }
2846
2852
  ]
2847
2853
  });
2854
+ var domainEventForwardCheckpoints = defineTable({
2855
+ name: "domainEventForwardCheckpoints",
2856
+ component: "kernel",
2857
+ category: "events",
2858
+ shape: z.object({
2859
+ // Logical sink name. One checkpoint row per forwarding destination so a
2860
+ // second sink (e.g. a future OTel path) never contends on this cursor.
2861
+ sink: z.string(),
2862
+ // Cursor: the timestamp of the last successfully forwarded event (ms epoch).
2863
+ lastForwardedTimestamp: z.number(),
2864
+ // Cursor tie-breaker: the eventId of the last successfully forwarded event.
2865
+ lastForwardedEventId: z.string(),
2866
+ // Running count of events forwarded through this sink (observability of the
2867
+ // observer — lets an operator confirm the pump is moving without Axiom).
2868
+ forwardedCount: z.number(),
2869
+ // When this checkpoint row was last advanced (ms epoch).
2870
+ updatedAt: z.number(),
2871
+ // Last tick outcome, for at-a-glance health without querying Axiom.
2872
+ lastStatus: z.enum(["ok", "empty", "export_failed"]).optional(),
2873
+ // Redacted last-error summary when lastStatus is export_failed.
2874
+ lastError: z.string().optional()
2875
+ }),
2876
+ indices: [{ kind: "index", name: "by_sink", columns: ["sink"] }]
2877
+ });
2848
2878
  var idempotencyTokens = defineTable({
2849
2879
  name: "idempotencyTokens",
2850
2880
  component: "kernel",
@@ -13486,6 +13516,7 @@ var KERNEL_TABLE_CONTRACTS = [
13486
13516
  decisionRiskLedger,
13487
13517
  decisionSnapshots,
13488
13518
  domainEvents,
13519
+ domainEventForwardCheckpoints,
13489
13520
  deliberationContributions,
13490
13521
  deliberationSessions,
13491
13522
  stakeholderGroups,
@@ -22,3 +22,25 @@ export declare const domainEvents: import("../../../dsl.js").TableContract<{
22
22
  correlationId: z.ZodOptional<z.ZodString>;
23
23
  expiresAt: z.ZodNumber;
24
24
  }>;
25
+ /**
26
+ * Axiom forwarding checkpoint — the OB.2 log-lake cursor.
27
+ *
28
+ * The scheduled `events:recordEvent` -> Axiom forwarder (OB.2) is cursor-based
29
+ * and idempotent: it persists, per sink, the `(timestamp, eventId)` of the last
30
+ * domain event it successfully forwarded. On each tick it reads events strictly
31
+ * after that cursor, forwards them through the transport-core Axiom exporter,
32
+ * and advances the checkpoint ONLY after a successful export. Forwarding is
33
+ * fail-open — an export failure leaves the checkpoint unadvanced so the same
34
+ * window is retried next tick, and it never touches the source `domainEvents`
35
+ * ledger. One row per `sink` (e.g. `axiom-events`); the row is upserted, never
36
+ * accreted, because it is operational cursor state, not epistemic state.
37
+ */
38
+ export declare const domainEventForwardCheckpoints: import("../../../dsl.js").TableContract<{
39
+ sink: z.ZodString;
40
+ lastForwardedTimestamp: z.ZodNumber;
41
+ lastForwardedEventId: z.ZodString;
42
+ forwardedCount: z.ZodNumber;
43
+ updatedAt: z.ZodNumber;
44
+ lastStatus: z.ZodOptional<z.ZodEnum<["ok", "empty", "export_failed"]>>;
45
+ lastError: z.ZodOptional<z.ZodString>;
46
+ }>;
@@ -50,8 +50,38 @@ var domainEvents = defineTable({
50
50
  name: "by_resource",
51
51
  columns: ["resourceType", "resourceId", "timestamp"]
52
52
  },
53
+ // OB.2: global chronological order for the Axiom forwarding scan. The
54
+ // forwarder pages events strictly by (timestamp, eventId) after its
55
+ // checkpoint cursor, so it needs a total time order independent of topic /
56
+ // type / tenant. The forwarder additionally tie-breaks on eventId in
57
+ // application code for events sharing a millisecond timestamp.
58
+ { kind: "index", name: "by_timestamp", columns: ["timestamp"] },
53
59
  { kind: "index", name: "by_expiresAt", columns: ["expiresAt"] }
54
60
  ]
55
61
  });
62
+ var domainEventForwardCheckpoints = defineTable({
63
+ name: "domainEventForwardCheckpoints",
64
+ component: "kernel",
65
+ category: "events",
66
+ shape: z.object({
67
+ // Logical sink name. One checkpoint row per forwarding destination so a
68
+ // second sink (e.g. a future OTel path) never contends on this cursor.
69
+ sink: z.string(),
70
+ // Cursor: the timestamp of the last successfully forwarded event (ms epoch).
71
+ lastForwardedTimestamp: z.number(),
72
+ // Cursor tie-breaker: the eventId of the last successfully forwarded event.
73
+ lastForwardedEventId: z.string(),
74
+ // Running count of events forwarded through this sink (observability of the
75
+ // observer — lets an operator confirm the pump is moving without Axiom).
76
+ forwardedCount: z.number(),
77
+ // When this checkpoint row was last advanced (ms epoch).
78
+ updatedAt: z.number(),
79
+ // Last tick outcome, for at-a-glance health without querying Axiom.
80
+ lastStatus: z.enum(["ok", "empty", "export_failed"]).optional(),
81
+ // Redacted last-error summary when lastStatus is export_failed.
82
+ lastError: z.string().optional()
83
+ }),
84
+ indices: [{ kind: "index", name: "by_sink", columns: ["sink"] }]
85
+ });
56
86
 
57
- export { domainEvents };
87
+ export { domainEventForwardCheckpoints, domainEvents };
@@ -2975,9 +2975,39 @@ var domainEvents = defineTable({
2975
2975
  name: "by_resource",
2976
2976
  columns: ["resourceType", "resourceId", "timestamp"]
2977
2977
  },
2978
+ // OB.2: global chronological order for the Axiom forwarding scan. The
2979
+ // forwarder pages events strictly by (timestamp, eventId) after its
2980
+ // checkpoint cursor, so it needs a total time order independent of topic /
2981
+ // type / tenant. The forwarder additionally tie-breaks on eventId in
2982
+ // application code for events sharing a millisecond timestamp.
2983
+ { kind: "index", name: "by_timestamp", columns: ["timestamp"] },
2978
2984
  { kind: "index", name: "by_expiresAt", columns: ["expiresAt"] }
2979
2985
  ]
2980
2986
  });
2987
+ var domainEventForwardCheckpoints = defineTable({
2988
+ name: "domainEventForwardCheckpoints",
2989
+ component: "kernel",
2990
+ category: "events",
2991
+ shape: z.object({
2992
+ // Logical sink name. One checkpoint row per forwarding destination so a
2993
+ // second sink (e.g. a future OTel path) never contends on this cursor.
2994
+ sink: z.string(),
2995
+ // Cursor: the timestamp of the last successfully forwarded event (ms epoch).
2996
+ lastForwardedTimestamp: z.number(),
2997
+ // Cursor tie-breaker: the eventId of the last successfully forwarded event.
2998
+ lastForwardedEventId: z.string(),
2999
+ // Running count of events forwarded through this sink (observability of the
3000
+ // observer — lets an operator confirm the pump is moving without Axiom).
3001
+ forwardedCount: z.number(),
3002
+ // When this checkpoint row was last advanced (ms epoch).
3003
+ updatedAt: z.number(),
3004
+ // Last tick outcome, for at-a-glance health without querying Axiom.
3005
+ lastStatus: z.enum(["ok", "empty", "export_failed"]).optional(),
3006
+ // Redacted last-error summary when lastStatus is export_failed.
3007
+ lastError: z.string().optional()
3008
+ }),
3009
+ indices: [{ kind: "index", name: "by_sink", columns: ["sink"] }]
3010
+ });
2981
3011
  var idempotencyTokens = defineTable({
2982
3012
  name: "idempotencyTokens",
2983
3013
  component: "kernel",
@@ -13505,6 +13535,7 @@ var KERNEL_TABLE_CONTRACTS = [
13505
13535
  decisionRiskLedger,
13506
13536
  decisionSnapshots,
13507
13537
  domainEvents,
13538
+ domainEventForwardCheckpoints,
13508
13539
  deliberationContributions,
13509
13540
  deliberationSessions,
13510
13541
  stakeholderGroups,
@@ -181,6 +181,12 @@ export declare const TENANT_BOOTSTRAP_TABLE_REQUIREMENTS: readonly [{
181
181
  readonly prepopulation: "runtime_data";
182
182
  readonly copyMode: "none";
183
183
  readonly description: "Deliberation sessions are created by tenant workflows.";
184
+ }, {
185
+ readonly component: "kernel";
186
+ readonly table: "domainEventForwardCheckpoints";
187
+ readonly prepopulation: "runtime_data";
188
+ readonly copyMode: "none";
189
+ readonly description: "Per-forwarder cursor checkpoints for domain-event log shipping; created at runtime by the log-lake forwarder.";
184
190
  }, {
185
191
  readonly component: "kernel";
186
192
  readonly table: "domainEvents";
@@ -815,6 +821,12 @@ export declare const TENANT_BOOTSTRAP_SEED_MANIFEST: {
815
821
  readonly prepopulation: "runtime_data";
816
822
  readonly copyMode: "none";
817
823
  readonly description: "Deliberation sessions are created by tenant workflows.";
824
+ }, {
825
+ readonly component: "kernel";
826
+ readonly table: "domainEventForwardCheckpoints";
827
+ readonly prepopulation: "runtime_data";
828
+ readonly copyMode: "none";
829
+ readonly description: "Per-forwarder cursor checkpoints for domain-event log shipping; created at runtime by the log-lake forwarder.";
818
830
  }, {
819
831
  readonly component: "kernel";
820
832
  readonly table: "domainEvents";
@@ -186,6 +186,13 @@ var TENANT_BOOTSTRAP_TABLE_REQUIREMENTS = [
186
186
  copyMode: "none",
187
187
  description: "Deliberation sessions are created by tenant workflows."
188
188
  },
189
+ {
190
+ component: "kernel",
191
+ table: "domainEventForwardCheckpoints",
192
+ prepopulation: "runtime_data",
193
+ copyMode: "none",
194
+ description: "Per-forwarder cursor checkpoints for domain-event log shipping; created at runtime by the log-lake forwarder."
195
+ },
189
196
  {
190
197
  component: "kernel",
191
198
  table: "domainEvents",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lucern/contracts",
3
- "version": "1.0.56",
3
+ "version": "1.0.57",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",