@secondlayer/shared 7.8.0 → 7.10.0

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 (52) hide show
  1. package/dist/src/archive/derived-stage-report.d.ts +99 -0
  2. package/dist/src/archive/derived-stage-report.js +64 -0
  3. package/dist/src/archive/derived-stage-report.js.map +10 -0
  4. package/dist/src/archive/disk-guard.d.ts +46 -0
  5. package/dist/src/archive/disk-guard.js +69 -0
  6. package/dist/src/archive/disk-guard.js.map +10 -0
  7. package/dist/src/archive/per-height-digest.d.ts +99 -0
  8. package/dist/src/archive/per-height-digest.js +194 -0
  9. package/dist/src/archive/per-height-digest.js.map +11 -0
  10. package/dist/src/archive/range-digest.d.ts +96 -0
  11. package/dist/src/archive/semantic-digest-builder.d.ts +1183 -0
  12. package/dist/src/archive/semantic-digest-builder.js +302 -0
  13. package/dist/src/archive/semantic-digest-builder.js.map +11 -0
  14. package/dist/src/archive/semantic-digest.d.ts +131 -0
  15. package/dist/src/archive/semantic-digest.js +143 -0
  16. package/dist/src/archive/semantic-digest.js.map +10 -0
  17. package/dist/src/coverage/index.d.ts +1670 -0
  18. package/dist/src/coverage/index.js +1483 -0
  19. package/dist/src/coverage/index.js.map +23 -0
  20. package/dist/src/db/index.d.ts +105 -1
  21. package/dist/src/db/index.js +31 -1
  22. package/dist/src/db/index.js.map +6 -5
  23. package/dist/src/db/queries/chain-reorgs.d.ts +96 -0
  24. package/dist/src/db/queries/chain-reorgs.js +30 -1
  25. package/dist/src/db/queries/chain-reorgs.js.map +6 -5
  26. package/dist/src/db/queries/contracts.d.ts +96 -0
  27. package/dist/src/db/queries/instance.d.ts +1127 -0
  28. package/dist/src/db/queries/instance.js +92 -0
  29. package/dist/src/db/queries/instance.js.map +10 -0
  30. package/dist/src/db/queries/integrity.d.ts +96 -0
  31. package/dist/src/db/queries/subgraph-gaps.d.ts +96 -0
  32. package/dist/src/db/queries/subgraph-operations.d.ts +96 -0
  33. package/dist/src/db/queries/subgraphs.d.ts +99 -1
  34. package/dist/src/db/queries/subgraphs.js +52 -23
  35. package/dist/src/db/queries/subgraphs.js.map +7 -7
  36. package/dist/src/db/queries/subscriptions.d.ts +96 -0
  37. package/dist/src/db/queries/subscriptions.js +47 -31
  38. package/dist/src/db/queries/subscriptions.js.map +5 -5
  39. package/dist/src/db/schema.d.ts +97 -1
  40. package/dist/src/index.d.ts +109 -1
  41. package/dist/src/index.js +52 -1
  42. package/dist/src/index.js.map +7 -6
  43. package/dist/src/node/client.d.ts +11 -1
  44. package/dist/src/node/client.js +42 -4
  45. package/dist/src/node/client.js.map +3 -3
  46. package/dist/src/node/local-client.d.ts +96 -0
  47. package/dist/src/node/nakamoto.d.ts +22 -7
  48. package/dist/src/node/nakamoto.js +46 -5
  49. package/dist/src/node/nakamoto.js.map +3 -3
  50. package/migrations/0115_instances.ts +33 -0
  51. package/migrations/0116_coverage_schema.ts +163 -0
  52. package/package.json +29 -1
@@ -0,0 +1,92 @@
1
+ import { createRequire } from "node:module";
2
+ var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true,
12
+ configurable: true,
13
+ set: __exportSetter.bind(all, name)
14
+ });
15
+ };
16
+
17
+ // src/db/queries/instance.ts
18
+ var INSTANCE_NETWORKS = ["mainnet", "testnet", "devnet"];
19
+
20
+ class InstanceNetworkMismatchError extends Error {
21
+ existing;
22
+ requested;
23
+ name = "InstanceNetworkMismatchError";
24
+ constructor(existing, requested) {
25
+ super(`instance network is ${existing}; cannot change to ${requested}`);
26
+ this.existing = existing;
27
+ this.requested = requested;
28
+ }
29
+ }
30
+
31
+ class InvalidInstanceNetworkError extends Error {
32
+ value;
33
+ name = "InvalidInstanceNetworkError";
34
+ constructor(value) {
35
+ super(`instance network must be mainnet, testnet, or devnet (got ${value})`);
36
+ this.value = value;
37
+ }
38
+ }
39
+ function parseInstanceNetwork(value) {
40
+ const network = value.trim().toLowerCase();
41
+ if (INSTANCE_NETWORKS.includes(network)) {
42
+ return network;
43
+ }
44
+ throw new InvalidInstanceNetworkError(value);
45
+ }
46
+ function instanceNetworkFromEnv(env = process.env) {
47
+ return parseInstanceNetwork(env.STACKS_NETWORK ?? env.NETWORK ?? "mainnet");
48
+ }
49
+ async function getInstance(db) {
50
+ const row = await db.selectFrom("instances").select(["id", "network", "created_at"]).executeTakeFirst();
51
+ return row ? toInstance(row) : null;
52
+ }
53
+ async function ensureInstance(db, input) {
54
+ const existing = await getInstance(db);
55
+ if (existing) {
56
+ if (existing.network !== input.network) {
57
+ throw new InstanceNetworkMismatchError(existing.network, input.network);
58
+ }
59
+ return existing;
60
+ }
61
+ try {
62
+ const inserted = await db.insertInto("instances").values({ network: input.network }).returning(["id", "network", "created_at"]).executeTakeFirstOrThrow();
63
+ return toInstance(inserted);
64
+ } catch {
65
+ const raced = await getInstance(db);
66
+ if (!raced)
67
+ throw new Error("failed to create instance");
68
+ if (raced.network !== input.network) {
69
+ throw new InstanceNetworkMismatchError(raced.network, input.network);
70
+ }
71
+ return raced;
72
+ }
73
+ }
74
+ function toInstance(row) {
75
+ return {
76
+ id: row.id,
77
+ network: parseInstanceNetwork(row.network),
78
+ created_at: row.created_at
79
+ };
80
+ }
81
+ export {
82
+ parseInstanceNetwork,
83
+ instanceNetworkFromEnv,
84
+ getInstance,
85
+ ensureInstance,
86
+ InvalidInstanceNetworkError,
87
+ InstanceNetworkMismatchError,
88
+ INSTANCE_NETWORKS
89
+ };
90
+
91
+ //# debugId=52C8BB0A1418347D64756E2164756E21
92
+ //# sourceMappingURL=instance.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/db/queries/instance.ts"],
4
+ "sourcesContent": [
5
+ "import type { Kysely } from \"kysely\";\nimport type { Database } from \"../types.ts\";\n\nexport const INSTANCE_NETWORKS = [\"mainnet\", \"testnet\", \"devnet\"] as const;\nexport type InstanceNetwork = (typeof INSTANCE_NETWORKS)[number];\n\nexport type InstanceRow = {\n\tid: string;\n\tnetwork: InstanceNetwork;\n\tcreated_at: Date;\n};\n\nexport class InstanceNetworkMismatchError extends Error {\n\treadonly name = \"InstanceNetworkMismatchError\";\n\tconstructor(\n\t\treadonly existing: InstanceNetwork,\n\t\treadonly requested: InstanceNetwork,\n\t) {\n\t\tsuper(`instance network is ${existing}; cannot change to ${requested}`);\n\t}\n}\n\nexport class InvalidInstanceNetworkError extends Error {\n\treadonly name = \"InvalidInstanceNetworkError\";\n\tconstructor(readonly value: string) {\n\t\tsuper(\n\t\t\t`instance network must be mainnet, testnet, or devnet (got ${value})`,\n\t\t);\n\t}\n}\n\nexport function parseInstanceNetwork(value: string): InstanceNetwork {\n\tconst network = value.trim().toLowerCase();\n\tif ((INSTANCE_NETWORKS as readonly string[]).includes(network)) {\n\t\treturn network as InstanceNetwork;\n\t}\n\tthrow new InvalidInstanceNetworkError(value);\n}\n\n/** STACKS_NETWORK, then NETWORK, then mainnet. */\nexport function instanceNetworkFromEnv(\n\tenv: NodeJS.ProcessEnv = process.env,\n): InstanceNetwork {\n\treturn parseInstanceNetwork(env.STACKS_NETWORK ?? env.NETWORK ?? \"mainnet\");\n}\n\nexport async function getInstance(\n\tdb: Kysely<Database>,\n): Promise<InstanceRow | null> {\n\tconst row = await db\n\t\t.selectFrom(\"instances\")\n\t\t.select([\"id\", \"network\", \"created_at\"])\n\t\t.executeTakeFirst();\n\treturn row ? toInstance(row) : null;\n}\n\n/**\n * Return the singleton instance, creating it on first call.\n * A second call with a different network is refused — the network is\n * immutable for the life of the database.\n */\nexport async function ensureInstance(\n\tdb: Kysely<Database>,\n\tinput: { network: InstanceNetwork },\n): Promise<InstanceRow> {\n\tconst existing = await getInstance(db);\n\tif (existing) {\n\t\tif (existing.network !== input.network) {\n\t\t\tthrow new InstanceNetworkMismatchError(existing.network, input.network);\n\t\t}\n\t\treturn existing;\n\t}\n\ttry {\n\t\tconst inserted = await db\n\t\t\t.insertInto(\"instances\")\n\t\t\t.values({ network: input.network })\n\t\t\t.returning([\"id\", \"network\", \"created_at\"])\n\t\t\t.executeTakeFirstOrThrow();\n\t\treturn toInstance(inserted);\n\t} catch {\n\t\t// Lost the singleton race — the other writer won.\n\t\tconst raced = await getInstance(db);\n\t\tif (!raced) throw new Error(\"failed to create instance\");\n\t\tif (raced.network !== input.network) {\n\t\t\tthrow new InstanceNetworkMismatchError(raced.network, input.network);\n\t\t}\n\t\treturn raced;\n\t}\n}\n\nfunction toInstance(row: {\n\tid: string;\n\tnetwork: string;\n\tcreated_at: Date;\n}): InstanceRow {\n\treturn {\n\t\tid: row.id,\n\t\tnetwork: parseInstanceNetwork(row.network),\n\t\tcreated_at: row.created_at,\n\t};\n}\n"
6
+ ],
7
+ "mappings": ";;;;;;;;;;;;;;;;;AAGO,IAAM,oBAAoB,CAAC,WAAW,WAAW,QAAQ;AAAA;AASzD,MAAM,qCAAqC,MAAM;AAAA,EAG7C;AAAA,EACA;AAAA,EAHD,OAAO;AAAA,EAChB,WAAW,CACD,UACA,WACR;AAAA,IACD,MAAM,uBAAuB,8BAA8B,WAAW;AAAA,IAH7D;AAAA,IACA;AAAA;AAIX;AAAA;AAEO,MAAM,oCAAoC,MAAM;AAAA,EAEjC;AAAA,EADZ,OAAO;AAAA,EAChB,WAAW,CAAU,OAAe;AAAA,IACnC,MACC,6DAA6D,QAC9D;AAAA,IAHoB;AAAA;AAKtB;AAEO,SAAS,oBAAoB,CAAC,OAAgC;AAAA,EACpE,MAAM,UAAU,MAAM,KAAK,EAAE,YAAY;AAAA,EACzC,IAAK,kBAAwC,SAAS,OAAO,GAAG;AAAA,IAC/D,OAAO;AAAA,EACR;AAAA,EACA,MAAM,IAAI,4BAA4B,KAAK;AAAA;AAIrC,SAAS,sBAAsB,CACrC,MAAyB,QAAQ,KACf;AAAA,EAClB,OAAO,qBAAqB,IAAI,kBAAkB,IAAI,WAAW,SAAS;AAAA;AAG3E,eAAsB,WAAW,CAChC,IAC8B;AAAA,EAC9B,MAAM,MAAM,MAAM,GAChB,WAAW,WAAW,EACtB,OAAO,CAAC,MAAM,WAAW,YAAY,CAAC,EACtC,iBAAiB;AAAA,EACnB,OAAO,MAAM,WAAW,GAAG,IAAI;AAAA;AAQhC,eAAsB,cAAc,CACnC,IACA,OACuB;AAAA,EACvB,MAAM,WAAW,MAAM,YAAY,EAAE;AAAA,EACrC,IAAI,UAAU;AAAA,IACb,IAAI,SAAS,YAAY,MAAM,SAAS;AAAA,MACvC,MAAM,IAAI,6BAA6B,SAAS,SAAS,MAAM,OAAO;AAAA,IACvE;AAAA,IACA,OAAO;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACH,MAAM,WAAW,MAAM,GACrB,WAAW,WAAW,EACtB,OAAO,EAAE,SAAS,MAAM,QAAQ,CAAC,EACjC,UAAU,CAAC,MAAM,WAAW,YAAY,CAAC,EACzC,wBAAwB;AAAA,IAC1B,OAAO,WAAW,QAAQ;AAAA,IACzB,MAAM;AAAA,IAEP,MAAM,QAAQ,MAAM,YAAY,EAAE;AAAA,IAClC,IAAI,CAAC;AAAA,MAAO,MAAM,IAAI,MAAM,2BAA2B;AAAA,IACvD,IAAI,MAAM,YAAY,MAAM,SAAS;AAAA,MACpC,MAAM,IAAI,6BAA6B,MAAM,SAAS,MAAM,OAAO;AAAA,IACpE;AAAA,IACA,OAAO;AAAA;AAAA;AAIT,SAAS,UAAU,CAAC,KAIJ;AAAA,EACf,OAAO;AAAA,IACN,IAAI,IAAI;AAAA,IACR,SAAS,qBAAqB,IAAI,OAAO;AAAA,IACzC,YAAY,IAAI;AAAA,EACjB;AAAA;",
8
+ "debugId": "52C8BB0A1418347D64756E2164756E21",
9
+ "names": []
10
+ }
@@ -1,5 +1,23 @@
1
1
  import { Kysely } from "kysely";
2
2
  import { ColumnType, Generated } from "kysely";
3
+ /**
4
+ * Coverage-kernel constraints. SQL CHECKs in migration 0116 must stay
5
+ * identical — property tests treat this file as the spec.
6
+ */
7
+ declare const STAGE_KINDS: readonly ["raw", "decode", "subgraph", "queue"];
8
+ type StageKind = (typeof STAGE_KINDS)[number];
9
+ declare const NATIVE_CLOCKS: readonly ["block", "cursor", "queue"];
10
+ type NativeClock = (typeof NATIVE_CLOCKS)[number];
11
+ declare const REPAIR_MODES: readonly ["range_safe", "full_reindex", "archive_replay", "none"];
12
+ type RepairMode = (typeof REPAIR_MODES)[number];
13
+ declare const RUN_STATUSES: readonly ["pending", "running", "complete", "syncing", "lagging", "gap", "stale", "failed", "unverified_import", "unanchored", "source_unavailable", "out_of_scope", "disabled", "halted"];
14
+ type RunStatus = (typeof RUN_STATUSES)[number];
15
+ declare const FAILURE_UNITS: readonly ["block", "range", "cursor", "queue"];
16
+ type FailureUnit = (typeof FAILURE_UNITS)[number];
17
+ declare const FAILURE_CLASSES: readonly ["omission", "version", "digest_mismatch", "crash", "reorg", "source_gap", "handler", "timeout", "unknown"];
18
+ type FailureClass = (typeof FAILURE_CLASSES)[number];
19
+ declare const RETRY_STATES: readonly ["open", "retrying", "halted", "resolved"];
20
+ type RetryState = (typeof RETRY_STATES)[number];
3
21
  interface BlocksTable {
4
22
  height: number;
5
23
  hash: string;
@@ -191,6 +209,12 @@ interface ApiKeysTable {
191
209
  revoked_at: Date | null;
192
210
  created_at: Generated<Date>;
193
211
  }
212
+ /** Singleton self-host / publisher identity. Network is immutable. */
213
+ interface InstancesTable {
214
+ id: Generated<string>;
215
+ network: string;
216
+ created_at: Generated<Date>;
217
+ }
194
218
  interface AccountsTable {
195
219
  id: Generated<string>;
196
220
  /** NULL for unclaimed ghost accounts (anonymous self-serve keys). */
@@ -721,6 +745,72 @@ interface ObserverJournalTable {
721
745
  error: string | null;
722
746
  processed_at: Date | null;
723
747
  }
748
+ /** Declared coverage stage. Identity is the `id` string (`raw`, `decode:stx`, …). */
749
+ interface StageRegistryTable {
750
+ id: string;
751
+ kind: StageKind;
752
+ depends_on: string | null;
753
+ native_clock: NativeClock;
754
+ producer_version: string;
755
+ repair_mode: RepairMode;
756
+ enabled: Generated<boolean>;
757
+ created_at: Generated<Date>;
758
+ }
759
+ /** One versioned sweep of a stage. */
760
+ interface StageRunsTable {
761
+ id: Generated<string>;
762
+ stage_id: string;
763
+ code_hash: string;
764
+ config_hash: string;
765
+ handler_hash: string | null;
766
+ target_height: number | null;
767
+ target_cursor: string | null;
768
+ status: RunStatus;
769
+ complete_through: number | null;
770
+ started_at: Generated<Date>;
771
+ finished_at: Date | null;
772
+ }
773
+ /** Per-block acknowledgement. Unique on (stage, height, hash). */
774
+ interface StageBlockReceiptsTable {
775
+ id: Generated<string>;
776
+ stage_id: string;
777
+ run_id: string | null;
778
+ block_height: number;
779
+ block_hash: string;
780
+ input_count: number;
781
+ input_digest: string;
782
+ effect_digest: string;
783
+ finalized: Generated<boolean>;
784
+ compacted_at: Date | null;
785
+ created_at: Generated<Date>;
786
+ }
787
+ /** Compacted finalized range. Only sealed after receipts in the range finalize. */
788
+ interface CoverageSegmentsTable {
789
+ id: Generated<string>;
790
+ stage_id: string;
791
+ from_height: number;
792
+ to_height: number;
793
+ chain_digest: string;
794
+ input_digest: string;
795
+ output_digest: string;
796
+ sealed_at: Generated<Date>;
797
+ }
798
+ /** Exact unit or range that failed, plus retry/retention state. */
799
+ interface StageFailuresTable {
800
+ id: Generated<string>;
801
+ stage_id: string;
802
+ run_id: string | null;
803
+ unit_kind: FailureUnit;
804
+ from_height: number | null;
805
+ to_height: number | null;
806
+ class: FailureClass;
807
+ retry_state: RetryState;
808
+ retry_count: Generated<number>;
809
+ last_error: string | null;
810
+ created_at: Generated<Date>;
811
+ resolved_at: Date | null;
812
+ retain_until: Generated<Date>;
813
+ }
724
814
  interface Database {
725
815
  blocks: BlocksTable;
726
816
  transactions: TransactionsTable;
@@ -733,6 +823,7 @@ interface Database {
733
823
  contracts: ContractsTable;
734
824
  subgraphs: SubgraphsTable;
735
825
  api_keys: ApiKeysTable;
826
+ instances: InstancesTable;
736
827
  accounts: AccountsTable;
737
828
  sessions: SessionsTable;
738
829
  magic_links: MagicLinksTable;
@@ -785,6 +876,11 @@ interface Database {
785
876
  chain_read_cache: ChainReadCacheTable;
786
877
  pending_fork_blocks: PendingForkBlocksTable;
787
878
  observer_journal: ObserverJournalTable;
879
+ stage_registry: StageRegistryTable;
880
+ stage_runs: StageRunsTable;
881
+ stage_block_receipts: StageBlockReceiptsTable;
882
+ coverage_segments: CoverageSegmentsTable;
883
+ stage_failures: StageFailuresTable;
788
884
  }
789
885
  /** Prepaid x402 credit — one running USD-micros balance per payer principal. */
790
886
  interface X402BalancesTable {
@@ -1,5 +1,23 @@
1
1
  import { Kysely } from "kysely";
2
2
  import { ColumnType, Generated } from "kysely";
3
+ /**
4
+ * Coverage-kernel constraints. SQL CHECKs in migration 0116 must stay
5
+ * identical — property tests treat this file as the spec.
6
+ */
7
+ declare const STAGE_KINDS: readonly ["raw", "decode", "subgraph", "queue"];
8
+ type StageKind = (typeof STAGE_KINDS)[number];
9
+ declare const NATIVE_CLOCKS: readonly ["block", "cursor", "queue"];
10
+ type NativeClock = (typeof NATIVE_CLOCKS)[number];
11
+ declare const REPAIR_MODES: readonly ["range_safe", "full_reindex", "archive_replay", "none"];
12
+ type RepairMode = (typeof REPAIR_MODES)[number];
13
+ declare const RUN_STATUSES: readonly ["pending", "running", "complete", "syncing", "lagging", "gap", "stale", "failed", "unverified_import", "unanchored", "source_unavailable", "out_of_scope", "disabled", "halted"];
14
+ type RunStatus = (typeof RUN_STATUSES)[number];
15
+ declare const FAILURE_UNITS: readonly ["block", "range", "cursor", "queue"];
16
+ type FailureUnit = (typeof FAILURE_UNITS)[number];
17
+ declare const FAILURE_CLASSES: readonly ["omission", "version", "digest_mismatch", "crash", "reorg", "source_gap", "handler", "timeout", "unknown"];
18
+ type FailureClass = (typeof FAILURE_CLASSES)[number];
19
+ declare const RETRY_STATES: readonly ["open", "retrying", "halted", "resolved"];
20
+ type RetryState = (typeof RETRY_STATES)[number];
3
21
  interface BlocksTable {
4
22
  height: number;
5
23
  hash: string;
@@ -191,6 +209,12 @@ interface ApiKeysTable {
191
209
  revoked_at: Date | null;
192
210
  created_at: Generated<Date>;
193
211
  }
212
+ /** Singleton self-host / publisher identity. Network is immutable. */
213
+ interface InstancesTable {
214
+ id: Generated<string>;
215
+ network: string;
216
+ created_at: Generated<Date>;
217
+ }
194
218
  interface AccountsTable {
195
219
  id: Generated<string>;
196
220
  /** NULL for unclaimed ghost accounts (anonymous self-serve keys). */
@@ -721,6 +745,72 @@ interface ObserverJournalTable {
721
745
  error: string | null;
722
746
  processed_at: Date | null;
723
747
  }
748
+ /** Declared coverage stage. Identity is the `id` string (`raw`, `decode:stx`, …). */
749
+ interface StageRegistryTable {
750
+ id: string;
751
+ kind: StageKind;
752
+ depends_on: string | null;
753
+ native_clock: NativeClock;
754
+ producer_version: string;
755
+ repair_mode: RepairMode;
756
+ enabled: Generated<boolean>;
757
+ created_at: Generated<Date>;
758
+ }
759
+ /** One versioned sweep of a stage. */
760
+ interface StageRunsTable {
761
+ id: Generated<string>;
762
+ stage_id: string;
763
+ code_hash: string;
764
+ config_hash: string;
765
+ handler_hash: string | null;
766
+ target_height: number | null;
767
+ target_cursor: string | null;
768
+ status: RunStatus;
769
+ complete_through: number | null;
770
+ started_at: Generated<Date>;
771
+ finished_at: Date | null;
772
+ }
773
+ /** Per-block acknowledgement. Unique on (stage, height, hash). */
774
+ interface StageBlockReceiptsTable {
775
+ id: Generated<string>;
776
+ stage_id: string;
777
+ run_id: string | null;
778
+ block_height: number;
779
+ block_hash: string;
780
+ input_count: number;
781
+ input_digest: string;
782
+ effect_digest: string;
783
+ finalized: Generated<boolean>;
784
+ compacted_at: Date | null;
785
+ created_at: Generated<Date>;
786
+ }
787
+ /** Compacted finalized range. Only sealed after receipts in the range finalize. */
788
+ interface CoverageSegmentsTable {
789
+ id: Generated<string>;
790
+ stage_id: string;
791
+ from_height: number;
792
+ to_height: number;
793
+ chain_digest: string;
794
+ input_digest: string;
795
+ output_digest: string;
796
+ sealed_at: Generated<Date>;
797
+ }
798
+ /** Exact unit or range that failed, plus retry/retention state. */
799
+ interface StageFailuresTable {
800
+ id: Generated<string>;
801
+ stage_id: string;
802
+ run_id: string | null;
803
+ unit_kind: FailureUnit;
804
+ from_height: number | null;
805
+ to_height: number | null;
806
+ class: FailureClass;
807
+ retry_state: RetryState;
808
+ retry_count: Generated<number>;
809
+ last_error: string | null;
810
+ created_at: Generated<Date>;
811
+ resolved_at: Date | null;
812
+ retain_until: Generated<Date>;
813
+ }
724
814
  interface Database {
725
815
  blocks: BlocksTable;
726
816
  transactions: TransactionsTable;
@@ -733,6 +823,7 @@ interface Database {
733
823
  contracts: ContractsTable;
734
824
  subgraphs: SubgraphsTable;
735
825
  api_keys: ApiKeysTable;
826
+ instances: InstancesTable;
736
827
  accounts: AccountsTable;
737
828
  sessions: SessionsTable;
738
829
  magic_links: MagicLinksTable;
@@ -785,6 +876,11 @@ interface Database {
785
876
  chain_read_cache: ChainReadCacheTable;
786
877
  pending_fork_blocks: PendingForkBlocksTable;
787
878
  observer_journal: ObserverJournalTable;
879
+ stage_registry: StageRegistryTable;
880
+ stage_runs: StageRunsTable;
881
+ stage_block_receipts: StageBlockReceiptsTable;
882
+ coverage_segments: CoverageSegmentsTable;
883
+ stage_failures: StageFailuresTable;
788
884
  }
789
885
  /** Prepaid x402 credit — one running USD-micros balance per payer principal. */
790
886
  interface X402BalancesTable {
@@ -1,5 +1,23 @@
1
1
  import { Kysely } from "kysely";
2
2
  import { ColumnType, Generated, Selectable } from "kysely";
3
+ /**
4
+ * Coverage-kernel constraints. SQL CHECKs in migration 0116 must stay
5
+ * identical — property tests treat this file as the spec.
6
+ */
7
+ declare const STAGE_KINDS: readonly ["raw", "decode", "subgraph", "queue"];
8
+ type StageKind = (typeof STAGE_KINDS)[number];
9
+ declare const NATIVE_CLOCKS: readonly ["block", "cursor", "queue"];
10
+ type NativeClock = (typeof NATIVE_CLOCKS)[number];
11
+ declare const REPAIR_MODES: readonly ["range_safe", "full_reindex", "archive_replay", "none"];
12
+ type RepairMode = (typeof REPAIR_MODES)[number];
13
+ declare const RUN_STATUSES: readonly ["pending", "running", "complete", "syncing", "lagging", "gap", "stale", "failed", "unverified_import", "unanchored", "source_unavailable", "out_of_scope", "disabled", "halted"];
14
+ type RunStatus = (typeof RUN_STATUSES)[number];
15
+ declare const FAILURE_UNITS: readonly ["block", "range", "cursor", "queue"];
16
+ type FailureUnit = (typeof FAILURE_UNITS)[number];
17
+ declare const FAILURE_CLASSES: readonly ["omission", "version", "digest_mismatch", "crash", "reorg", "source_gap", "handler", "timeout", "unknown"];
18
+ type FailureClass = (typeof FAILURE_CLASSES)[number];
19
+ declare const RETRY_STATES: readonly ["open", "retrying", "halted", "resolved"];
20
+ type RetryState = (typeof RETRY_STATES)[number];
3
21
  interface BlocksTable {
4
22
  height: number;
5
23
  hash: string;
@@ -191,6 +209,12 @@ interface ApiKeysTable {
191
209
  revoked_at: Date | null;
192
210
  created_at: Generated<Date>;
193
211
  }
212
+ /** Singleton self-host / publisher identity. Network is immutable. */
213
+ interface InstancesTable {
214
+ id: Generated<string>;
215
+ network: string;
216
+ created_at: Generated<Date>;
217
+ }
194
218
  interface AccountsTable {
195
219
  id: Generated<string>;
196
220
  /** NULL for unclaimed ghost accounts (anonymous self-serve keys). */
@@ -721,6 +745,72 @@ interface ObserverJournalTable {
721
745
  error: string | null;
722
746
  processed_at: Date | null;
723
747
  }
748
+ /** Declared coverage stage. Identity is the `id` string (`raw`, `decode:stx`, …). */
749
+ interface StageRegistryTable {
750
+ id: string;
751
+ kind: StageKind;
752
+ depends_on: string | null;
753
+ native_clock: NativeClock;
754
+ producer_version: string;
755
+ repair_mode: RepairMode;
756
+ enabled: Generated<boolean>;
757
+ created_at: Generated<Date>;
758
+ }
759
+ /** One versioned sweep of a stage. */
760
+ interface StageRunsTable {
761
+ id: Generated<string>;
762
+ stage_id: string;
763
+ code_hash: string;
764
+ config_hash: string;
765
+ handler_hash: string | null;
766
+ target_height: number | null;
767
+ target_cursor: string | null;
768
+ status: RunStatus;
769
+ complete_through: number | null;
770
+ started_at: Generated<Date>;
771
+ finished_at: Date | null;
772
+ }
773
+ /** Per-block acknowledgement. Unique on (stage, height, hash). */
774
+ interface StageBlockReceiptsTable {
775
+ id: Generated<string>;
776
+ stage_id: string;
777
+ run_id: string | null;
778
+ block_height: number;
779
+ block_hash: string;
780
+ input_count: number;
781
+ input_digest: string;
782
+ effect_digest: string;
783
+ finalized: Generated<boolean>;
784
+ compacted_at: Date | null;
785
+ created_at: Generated<Date>;
786
+ }
787
+ /** Compacted finalized range. Only sealed after receipts in the range finalize. */
788
+ interface CoverageSegmentsTable {
789
+ id: Generated<string>;
790
+ stage_id: string;
791
+ from_height: number;
792
+ to_height: number;
793
+ chain_digest: string;
794
+ input_digest: string;
795
+ output_digest: string;
796
+ sealed_at: Generated<Date>;
797
+ }
798
+ /** Exact unit or range that failed, plus retry/retention state. */
799
+ interface StageFailuresTable {
800
+ id: Generated<string>;
801
+ stage_id: string;
802
+ run_id: string | null;
803
+ unit_kind: FailureUnit;
804
+ from_height: number | null;
805
+ to_height: number | null;
806
+ class: FailureClass;
807
+ retry_state: RetryState;
808
+ retry_count: Generated<number>;
809
+ last_error: string | null;
810
+ created_at: Generated<Date>;
811
+ resolved_at: Date | null;
812
+ retain_until: Generated<Date>;
813
+ }
724
814
  interface Database {
725
815
  blocks: BlocksTable;
726
816
  transactions: TransactionsTable;
@@ -733,6 +823,7 @@ interface Database {
733
823
  contracts: ContractsTable;
734
824
  subgraphs: SubgraphsTable;
735
825
  api_keys: ApiKeysTable;
826
+ instances: InstancesTable;
736
827
  accounts: AccountsTable;
737
828
  sessions: SessionsTable;
738
829
  magic_links: MagicLinksTable;
@@ -785,6 +876,11 @@ interface Database {
785
876
  chain_read_cache: ChainReadCacheTable;
786
877
  pending_fork_blocks: PendingForkBlocksTable;
787
878
  observer_journal: ObserverJournalTable;
879
+ stage_registry: StageRegistryTable;
880
+ stage_runs: StageRunsTable;
881
+ stage_block_receipts: StageBlockReceiptsTable;
882
+ coverage_segments: CoverageSegmentsTable;
883
+ stage_failures: StageFailuresTable;
788
884
  }
789
885
  /** Prepaid x402 credit — one running USD-micros balance per payer principal. */
790
886
  interface X402BalancesTable {
@@ -1,6 +1,24 @@
1
1
  import { Kysely } from "kysely";
2
2
  import postgres from "postgres";
3
3
  import { ColumnType, Generated, Selectable } from "kysely";
4
+ /**
5
+ * Coverage-kernel constraints. SQL CHECKs in migration 0116 must stay
6
+ * identical — property tests treat this file as the spec.
7
+ */
8
+ declare const STAGE_KINDS: readonly ["raw", "decode", "subgraph", "queue"];
9
+ type StageKind = (typeof STAGE_KINDS)[number];
10
+ declare const NATIVE_CLOCKS: readonly ["block", "cursor", "queue"];
11
+ type NativeClock = (typeof NATIVE_CLOCKS)[number];
12
+ declare const REPAIR_MODES: readonly ["range_safe", "full_reindex", "archive_replay", "none"];
13
+ type RepairMode = (typeof REPAIR_MODES)[number];
14
+ declare const RUN_STATUSES: readonly ["pending", "running", "complete", "syncing", "lagging", "gap", "stale", "failed", "unverified_import", "unanchored", "source_unavailable", "out_of_scope", "disabled", "halted"];
15
+ type RunStatus = (typeof RUN_STATUSES)[number];
16
+ declare const FAILURE_UNITS: readonly ["block", "range", "cursor", "queue"];
17
+ type FailureUnit = (typeof FAILURE_UNITS)[number];
18
+ declare const FAILURE_CLASSES: readonly ["omission", "version", "digest_mismatch", "crash", "reorg", "source_gap", "handler", "timeout", "unknown"];
19
+ type FailureClass = (typeof FAILURE_CLASSES)[number];
20
+ declare const RETRY_STATES: readonly ["open", "retrying", "halted", "resolved"];
21
+ type RetryState = (typeof RETRY_STATES)[number];
4
22
  interface BlocksTable {
5
23
  height: number;
6
24
  hash: string;
@@ -192,6 +210,12 @@ interface ApiKeysTable {
192
210
  revoked_at: Date | null;
193
211
  created_at: Generated<Date>;
194
212
  }
213
+ /** Singleton self-host / publisher identity. Network is immutable. */
214
+ interface InstancesTable {
215
+ id: Generated<string>;
216
+ network: string;
217
+ created_at: Generated<Date>;
218
+ }
195
219
  interface AccountsTable {
196
220
  id: Generated<string>;
197
221
  /** NULL for unclaimed ghost accounts (anonymous self-serve keys). */
@@ -722,6 +746,72 @@ interface ObserverJournalTable {
722
746
  error: string | null;
723
747
  processed_at: Date | null;
724
748
  }
749
+ /** Declared coverage stage. Identity is the `id` string (`raw`, `decode:stx`, …). */
750
+ interface StageRegistryTable {
751
+ id: string;
752
+ kind: StageKind;
753
+ depends_on: string | null;
754
+ native_clock: NativeClock;
755
+ producer_version: string;
756
+ repair_mode: RepairMode;
757
+ enabled: Generated<boolean>;
758
+ created_at: Generated<Date>;
759
+ }
760
+ /** One versioned sweep of a stage. */
761
+ interface StageRunsTable {
762
+ id: Generated<string>;
763
+ stage_id: string;
764
+ code_hash: string;
765
+ config_hash: string;
766
+ handler_hash: string | null;
767
+ target_height: number | null;
768
+ target_cursor: string | null;
769
+ status: RunStatus;
770
+ complete_through: number | null;
771
+ started_at: Generated<Date>;
772
+ finished_at: Date | null;
773
+ }
774
+ /** Per-block acknowledgement. Unique on (stage, height, hash). */
775
+ interface StageBlockReceiptsTable {
776
+ id: Generated<string>;
777
+ stage_id: string;
778
+ run_id: string | null;
779
+ block_height: number;
780
+ block_hash: string;
781
+ input_count: number;
782
+ input_digest: string;
783
+ effect_digest: string;
784
+ finalized: Generated<boolean>;
785
+ compacted_at: Date | null;
786
+ created_at: Generated<Date>;
787
+ }
788
+ /** Compacted finalized range. Only sealed after receipts in the range finalize. */
789
+ interface CoverageSegmentsTable {
790
+ id: Generated<string>;
791
+ stage_id: string;
792
+ from_height: number;
793
+ to_height: number;
794
+ chain_digest: string;
795
+ input_digest: string;
796
+ output_digest: string;
797
+ sealed_at: Generated<Date>;
798
+ }
799
+ /** Exact unit or range that failed, plus retry/retention state. */
800
+ interface StageFailuresTable {
801
+ id: Generated<string>;
802
+ stage_id: string;
803
+ run_id: string | null;
804
+ unit_kind: FailureUnit;
805
+ from_height: number | null;
806
+ to_height: number | null;
807
+ class: FailureClass;
808
+ retry_state: RetryState;
809
+ retry_count: Generated<number>;
810
+ last_error: string | null;
811
+ created_at: Generated<Date>;
812
+ resolved_at: Date | null;
813
+ retain_until: Generated<Date>;
814
+ }
725
815
  interface Database {
726
816
  blocks: BlocksTable;
727
817
  transactions: TransactionsTable;
@@ -734,6 +824,7 @@ interface Database {
734
824
  contracts: ContractsTable;
735
825
  subgraphs: SubgraphsTable;
736
826
  api_keys: ApiKeysTable;
827
+ instances: InstancesTable;
737
828
  accounts: AccountsTable;
738
829
  sessions: SessionsTable;
739
830
  magic_links: MagicLinksTable;
@@ -786,6 +877,11 @@ interface Database {
786
877
  chain_read_cache: ChainReadCacheTable;
787
878
  pending_fork_blocks: PendingForkBlocksTable;
788
879
  observer_journal: ObserverJournalTable;
880
+ stage_registry: StageRegistryTable;
881
+ stage_runs: StageRunsTable;
882
+ stage_block_receipts: StageBlockReceiptsTable;
883
+ coverage_segments: CoverageSegmentsTable;
884
+ stage_failures: StageFailuresTable;
789
885
  }
790
886
  /** Prepaid x402 credit — one running USD-micros balance per payer principal. */
791
887
  interface X402BalancesTable {
@@ -1025,6 +1121,8 @@ declare function resolveSubgraphRawClient(subgraph: Subgraph): ReturnType<typeof
1025
1121
  * Platform-mode deploys use `pgSchemaNameFor(accountId, name)`.
1026
1122
  */
1027
1123
  declare function pgSchemaName(subgraphName: string): string;
1124
+ /** OSS writes empty account_id — name is the local unique key. */
1125
+ declare function localSubgraphAccountId(accountId?: string): string;
1028
1126
  /**
1029
1127
  * Account-scoped schema name. Matches migration 0028's rename pattern:
1030
1128
  * subgraph_{first8charsOfAccountId, dashes-as-underscores}_{name}
@@ -1131,4 +1229,4 @@ declare function recordLiveProgress(db: Kysely<Database>, name: string, lastProc
1131
1229
  * forward write between the rewind and the fork block's reprocess. Do not
1132
1230
  * call this from the live catch-up path. */
1133
1231
  declare function rewindLiveProgress(db: Kysely<Database>, name: string, lastProcessedBlock: number): Promise<void>;
1134
- export { updateSubgraphVisibility, updateSubgraphStatus, updateSubgraphHandlerPath, updateSubgraphExpiry, subgraphDatabaseUrl, rewindLiveProgress, resolveSubgraphRawClient, resolveSubgraphDb, registerSubgraph, recordSubgraphProcessed, recordLiveProgress, recordLiveError, pgSchemaNameFor, pgSchemaName, listSubgraphs, isByoSubgraph, getSubgraph, findPublicSubgraphByName, encryptDatabaseUrl, deleteSubgraph };
1232
+ export { updateSubgraphVisibility, updateSubgraphStatus, updateSubgraphHandlerPath, updateSubgraphExpiry, subgraphDatabaseUrl, rewindLiveProgress, resolveSubgraphRawClient, resolveSubgraphDb, registerSubgraph, recordSubgraphProcessed, recordLiveProgress, recordLiveError, pgSchemaNameFor, pgSchemaName, localSubgraphAccountId, listSubgraphs, isByoSubgraph, getSubgraph, findPublicSubgraphByName, encryptDatabaseUrl, deleteSubgraph };