@opengsd/gsd-pi 1.10.0-dev.a5e42e99 → 1.11.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 (172) hide show
  1. package/README.md +10 -10
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/gsd/db/engine.js +8 -2
  4. package/dist/resources/extensions/gsd/db-canonical-foundation-schema.js +120 -0
  5. package/dist/resources/extensions/gsd/db-migration-steps.js +4 -0
  6. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  7. package/dist/web/standalone/.next/BUILD_ID +1 -1
  8. package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
  9. package/dist/web/standalone/.next/build-manifest.json +3 -3
  10. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  11. package/dist/web/standalone/.next/required-server-files.json +3 -3
  12. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  13. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  14. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  15. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  16. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  17. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  18. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  19. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  20. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  21. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  22. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  23. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  24. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  25. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  26. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  27. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  28. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  29. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  30. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  31. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  32. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  33. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  34. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  35. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  36. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  37. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  38. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  39. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  40. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  41. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  42. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  43. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  44. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  45. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  46. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  47. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  48. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  49. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  50. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  51. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  52. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  53. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  54. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  55. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  56. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  57. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  58. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  59. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  60. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  61. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  62. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  63. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  64. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  65. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  66. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  67. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  68. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  69. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  70. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
  71. package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
  72. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  73. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  74. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  75. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  76. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  77. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  78. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  79. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  80. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  81. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  82. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  83. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  84. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  85. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  86. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  87. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  88. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  89. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  90. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  91. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  92. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  93. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  94. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  96. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  105. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  109. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/index.html +1 -1
  119. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  120. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  121. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  122. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  124. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/page.js +2 -2
  126. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app-paths-manifest.json +5 -5
  128. package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
  129. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  130. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/middleware.js +3 -3
  132. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  133. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  134. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  135. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +1 -0
  136. package/dist/web/standalone/.next/static/chunks/app/{layout-4ae2d68984392bbf.js → layout-b35cbfff38aaf4cf.js} +1 -1
  137. package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +1 -0
  138. package/dist/web/standalone/.next/static/chunks/{main-app-90d1d8d5e5d2dc6b.js → main-app-590a74400e35f685.js} +1 -1
  139. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +1 -0
  140. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  141. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  142. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  143. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  144. package/dist/web/standalone/server.js +1 -1
  145. package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
  146. package/integrations/hermes/pyproject.toml +1 -1
  147. package/package.json +6 -6
  148. package/packages/cloud-mcp-gateway/package.json +2 -2
  149. package/packages/contracts/package.json +1 -1
  150. package/packages/daemon/package.json +4 -4
  151. package/packages/gsd-agent-core/package.json +5 -5
  152. package/packages/gsd-agent-modes/package.json +7 -7
  153. package/packages/gsd-cloud/package.json +1 -1
  154. package/packages/mcp-server/package.json +4 -4
  155. package/packages/native/package.json +1 -1
  156. package/packages/pi-agent-core/package.json +1 -1
  157. package/packages/pi-ai/package.json +1 -1
  158. package/packages/pi-coding-agent/package.json +7 -7
  159. package/packages/pi-tui/package.json +2 -2
  160. package/packages/rpc-client/package.json +2 -2
  161. package/pkg/package.json +1 -1
  162. package/src/resources/extensions/gsd/db/engine.ts +9 -1
  163. package/src/resources/extensions/gsd/db-canonical-foundation-schema.ts +129 -0
  164. package/src/resources/extensions/gsd/db-migration-steps.ts +5 -0
  165. package/src/resources/extensions/gsd/tests/db-canonical-foundation.test.ts +459 -0
  166. package/src/resources/extensions/gsd/tests/db-engine-migrate-guards.test.ts +3 -3
  167. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +1 -0
  168. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +0 -1
  169. package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +0 -1
  170. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +0 -1
  171. /package/dist/web/standalone/.next/static/{xwUaOqui04jIIFVsIBLiL → 8ub6oiEp2YnlOHQU20LJr}/_buildManifest.js +0 -0
  172. /package/dist/web/standalone/.next/static/{xwUaOqui04jIIFVsIBLiL → 8ub6oiEp2YnlOHQU20LJr}/_ssgManifest.js +0 -0
@@ -47,7 +47,9 @@ import {
47
47
  applyMigrationV28MemoryLastHitAt,
48
48
  applyMigrationV29RepositoryTargets,
49
49
  applyMigrationV30ReworkBriefs,
50
+ applyMigrationV31CanonicalFoundation,
50
51
  } from "../db-migration-steps.js";
52
+ import { createCanonicalFoundationSchemaV31 } from "../db-canonical-foundation-schema.js";
51
53
  import {
52
54
  isMemoriesFtsAvailableSchema,
53
55
  rebuildMemoriesFtsSchemaOnce,
@@ -97,7 +99,7 @@ const providerLoader = createSqliteProviderLoader({
97
99
  nodeVersion: process.versions.node,
98
100
  writeStderr: (message: string) => process.stderr.write(message),
99
101
  });
100
- export const SCHEMA_VERSION = 30;
102
+ export const SCHEMA_VERSION = 31;
101
103
  function initSchema(db: DbAdapter, fileBacked: boolean, dbPath: string | null): void {
102
104
  const conservativeFilePragmas = fileBacked && _isLikelyWslDrvFsPathForTest(dbPath);
103
105
  if (fileBacked) db.exec(conservativeFilePragmas ? "PRAGMA journal_mode=DELETE" : "PRAGMA journal_mode=WAL");
@@ -135,6 +137,7 @@ function initSchema(db: DbAdapter, fileBacked: boolean, dbPath: string | null):
135
137
  } else {
136
138
  createCoordinationTablesV24(db);
137
139
  createRuntimeKvTableV25(db);
140
+ createCanonicalFoundationSchemaV31(db);
138
141
 
139
142
  // Fresh install — all tables are created above with the full current schema,
140
143
  // so it is safe to create all migration-specific indexes here. For existing
@@ -388,6 +391,11 @@ function migrateSchema(db: DbAdapter, dbPath: string | null): void {
388
391
  recordSchemaVersion(db, 30);
389
392
  }
390
393
 
394
+ if (currentVersion < 31) {
395
+ applyMigrationV31CanonicalFoundation(db);
396
+ recordSchemaVersion(db, 31);
397
+ }
398
+
391
399
  if (_migrationFaultForTest) throw new Error("migration fault injected for test");
392
400
 
393
401
  db.exec("COMMIT");
@@ -0,0 +1,129 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Additive v31 authority, operation provenance, domain event, and outbox schema.
3
+
4
+ import type { DbAdapter } from "./db-adapter.js";
5
+
6
+ /**
7
+ * v31 mapping:
8
+ * - schema_version remains DDL compatibility, not the domain revision.
9
+ * - audit_events remains optional operational telemetry, not domain history.
10
+ * - milestone_commit_attributions remains Git-specific, not operation provenance.
11
+ * - command_queue and runtime_kv remain coordination/cache surfaces, not an outbox.
12
+ */
13
+ export function createCanonicalFoundationSchemaV31(db: DbAdapter): void {
14
+ db.exec(`
15
+ CREATE TABLE IF NOT EXISTS project_authority (
16
+ singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
17
+ project_id TEXT NOT NULL UNIQUE,
18
+ project_root_realpath TEXT NOT NULL DEFAULT '',
19
+ revision INTEGER NOT NULL DEFAULT 0 CHECK (revision >= 0),
20
+ authority_epoch INTEGER NOT NULL DEFAULT 0 CHECK (authority_epoch >= 0),
21
+ created_at TEXT NOT NULL DEFAULT '',
22
+ updated_at TEXT NOT NULL DEFAULT ''
23
+ )
24
+ `);
25
+
26
+ db.exec(`
27
+ CREATE TABLE IF NOT EXISTS workflow_operations (
28
+ operation_id TEXT PRIMARY KEY,
29
+ project_id TEXT NOT NULL,
30
+ operation_type TEXT NOT NULL,
31
+ idempotency_key TEXT NOT NULL,
32
+ expected_revision INTEGER NOT NULL CHECK (expected_revision >= 0),
33
+ resulting_revision INTEGER NOT NULL CHECK (resulting_revision = expected_revision + 1),
34
+ expected_authority_epoch INTEGER NOT NULL CHECK (expected_authority_epoch >= 0),
35
+ resulting_authority_epoch INTEGER NOT NULL CHECK (
36
+ resulting_authority_epoch = expected_authority_epoch OR
37
+ resulting_authority_epoch = expected_authority_epoch + 1
38
+ ),
39
+ actor_type TEXT NOT NULL,
40
+ actor_id TEXT DEFAULT NULL,
41
+ source_transport TEXT NOT NULL,
42
+ trace_id TEXT DEFAULT NULL,
43
+ turn_id TEXT DEFAULT NULL,
44
+ request_hash TEXT NOT NULL,
45
+ created_at TEXT NOT NULL,
46
+ UNIQUE (project_id, idempotency_key),
47
+ UNIQUE (project_id, resulting_revision),
48
+ UNIQUE (operation_id, project_id, resulting_revision, resulting_authority_epoch),
49
+ FOREIGN KEY (project_id) REFERENCES project_authority(project_id)
50
+ )
51
+ `);
52
+
53
+ db.exec(`
54
+ CREATE TABLE IF NOT EXISTS workflow_domain_events (
55
+ event_id TEXT PRIMARY KEY,
56
+ operation_id TEXT NOT NULL,
57
+ event_index INTEGER NOT NULL DEFAULT 0 CHECK (event_index >= 0),
58
+ project_id TEXT NOT NULL,
59
+ project_revision INTEGER NOT NULL CHECK (project_revision > 0),
60
+ authority_epoch INTEGER NOT NULL CHECK (authority_epoch >= 0),
61
+ event_type TEXT NOT NULL,
62
+ entity_type TEXT NOT NULL,
63
+ entity_id TEXT NOT NULL,
64
+ caused_by_event_id TEXT DEFAULT NULL,
65
+ payload_json TEXT NOT NULL DEFAULT '{}',
66
+ created_at TEXT NOT NULL,
67
+ UNIQUE (operation_id, event_index),
68
+ FOREIGN KEY (operation_id, project_id, project_revision, authority_epoch)
69
+ REFERENCES workflow_operations(
70
+ operation_id, project_id, resulting_revision, resulting_authority_epoch
71
+ ),
72
+ FOREIGN KEY (caused_by_event_id) REFERENCES workflow_domain_events(event_id)
73
+ )
74
+ `);
75
+
76
+ db.exec(`
77
+ CREATE TRIGGER IF NOT EXISTS trg_workflow_domain_events_immutable_update
78
+ BEFORE UPDATE ON workflow_domain_events
79
+ BEGIN
80
+ SELECT RAISE(ABORT, 'workflow domain events are immutable');
81
+ END
82
+ `);
83
+ db.exec(`
84
+ CREATE TRIGGER IF NOT EXISTS trg_workflow_domain_events_immutable_delete
85
+ BEFORE DELETE ON workflow_domain_events
86
+ BEGIN
87
+ SELECT RAISE(ABORT, 'workflow domain events are immutable');
88
+ END
89
+ `);
90
+
91
+ db.exec(`
92
+ CREATE TABLE IF NOT EXISTS workflow_outbox (
93
+ outbox_id INTEGER PRIMARY KEY AUTOINCREMENT,
94
+ event_id TEXT NOT NULL,
95
+ destination TEXT NOT NULL,
96
+ available_at TEXT NOT NULL DEFAULT '',
97
+ attempt_count INTEGER NOT NULL DEFAULT 0 CHECK (attempt_count >= 0),
98
+ claimed_by TEXT DEFAULT NULL,
99
+ claim_expires_at TEXT DEFAULT NULL,
100
+ delivered_at TEXT DEFAULT NULL,
101
+ last_error TEXT DEFAULT NULL,
102
+ UNIQUE (event_id, destination),
103
+ FOREIGN KEY (event_id) REFERENCES workflow_domain_events(event_id)
104
+ )
105
+ `);
106
+
107
+ db.exec(`
108
+ CREATE INDEX IF NOT EXISTS idx_workflow_operations_created
109
+ ON workflow_operations(project_id, created_at, operation_id)
110
+ `);
111
+ db.exec(`
112
+ CREATE INDEX IF NOT EXISTS idx_workflow_domain_events_entity
113
+ ON workflow_domain_events(project_id, entity_type, entity_id, project_revision, event_index)
114
+ `);
115
+ db.exec(`
116
+ CREATE INDEX IF NOT EXISTS idx_workflow_outbox_pending
117
+ ON workflow_outbox(delivered_at, available_at, outbox_id)
118
+ `);
119
+
120
+ db.exec(`
121
+ INSERT OR IGNORE INTO project_authority (
122
+ singleton, project_id, project_root_realpath,
123
+ revision, authority_epoch, created_at, updated_at
124
+ ) VALUES (
125
+ 1, lower(hex(randomblob(16))), '',
126
+ 0, 0, '', ''
127
+ )
128
+ `);
129
+ }
@@ -2,6 +2,7 @@
2
2
  // File Purpose: Schema migration DDL steps for the GSD database facade.
3
3
 
4
4
  import type { DbAdapter } from "./db-adapter.js";
5
+ import { createCanonicalFoundationSchemaV31 } from "./db-canonical-foundation-schema.js";
5
6
  import { ensureColumn } from "./db-schema-metadata.js";
6
7
 
7
8
  export function applyMigrationV2Artifacts(db: DbAdapter): void {
@@ -494,3 +495,7 @@ export function applyMigrationV30ReworkBriefs(db: DbAdapter): void {
494
495
  db.exec("CREATE INDEX IF NOT EXISTS idx_rework_briefs_task ON rework_briefs(milestone_id, slice_id, task_id)");
495
496
  db.exec("CREATE INDEX IF NOT EXISTS idx_rework_findings_status ON rework_brief_findings(brief_id, severity, status)");
496
497
  }
498
+
499
+ export function applyMigrationV31CanonicalFoundation(db: DbAdapter): void {
500
+ createCanonicalFoundationSchemaV31(db);
501
+ }
@@ -0,0 +1,459 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Executable contract for the additive v31 canonical database foundation.
3
+
4
+ import assert from "node:assert/strict";
5
+ import { spawnSync } from "node:child_process";
6
+ import { copyFileSync, mkdtempSync, rmSync } from "node:fs";
7
+ import { createRequire } from "node:module";
8
+ import { tmpdir } from "node:os";
9
+ import { dirname, join } from "node:path";
10
+ import { afterEach, test } from "node:test";
11
+ import { pathToFileURL } from "node:url";
12
+
13
+ import {
14
+ SCHEMA_VERSION,
15
+ _getAdapter,
16
+ _setMigrationFaultForTest,
17
+ closeDatabase,
18
+ openDatabase,
19
+ } from "../gsd-db.ts";
20
+
21
+ const require = createRequire(import.meta.url);
22
+ const tempDirs = new Set<string>();
23
+
24
+ interface RawDb {
25
+ exec(sql: string): void;
26
+ prepare(sql: string): {
27
+ get(...args: unknown[]): Record<string, unknown> | undefined;
28
+ all(...args: unknown[]): Array<Record<string, unknown>>;
29
+ };
30
+ close(): void;
31
+ }
32
+
33
+ function openRawDatabase(path: string): RawDb {
34
+ const sqlite = require("node:sqlite") as { DatabaseSync: new (path: string) => RawDb };
35
+ return new sqlite.DatabaseSync(path);
36
+ }
37
+
38
+ function createDatabasePath(): string {
39
+ const dir = mkdtempSync(join(tmpdir(), "gsd-canonical-foundation-"));
40
+ tempDirs.add(dir);
41
+ return join(dir, "gsd.db");
42
+ }
43
+
44
+ function tableExists(db: RawDb, table: string): boolean {
45
+ return Boolean(
46
+ db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = ?").get(table),
47
+ );
48
+ }
49
+
50
+ function maxSchemaVersion(db: RawDb): number {
51
+ return Number(db.prepare("SELECT MAX(version) AS version FROM schema_version").get()?.version);
52
+ }
53
+
54
+ function rewindToV30(dbPath: string): void {
55
+ assert.equal(openDatabase(dbPath), true);
56
+ closeDatabase();
57
+
58
+ const raw = openRawDatabase(dbPath);
59
+ try {
60
+ raw.exec(`
61
+ DROP TABLE IF EXISTS workflow_outbox;
62
+ DROP TABLE IF EXISTS workflow_domain_events;
63
+ DROP TABLE IF EXISTS workflow_operations;
64
+ DROP TABLE IF EXISTS project_authority;
65
+ DELETE FROM schema_version;
66
+ INSERT INTO schema_version (version, applied_at) VALUES (30, '2026-07-12T00:00:00.000Z');
67
+ INSERT OR IGNORE INTO milestones (id, title, status, created_at)
68
+ VALUES ('M-LEGACY', 'Preserved legacy milestone', 'active', '2026-07-12T00:00:00.000Z');
69
+ INSERT OR IGNORE INTO audit_events
70
+ (event_id, trace_id, category, type, ts, payload_json)
71
+ VALUES
72
+ ('audit-legacy', 'trace-legacy', 'workflow', 'legacy', '2026-07-12T00:00:00.000Z', '{"kept":true}');
73
+ `);
74
+ } finally {
75
+ raw.close();
76
+ }
77
+ }
78
+
79
+ function inspectFromFreshProcess(dbPath: string): Record<string, unknown> {
80
+ const moduleHref = pathToFileURL(
81
+ join(process.cwd(), "src/resources/extensions/gsd/gsd-db.ts"),
82
+ ).href;
83
+ const script = [
84
+ `import { openDatabase, closeDatabase, _getAdapter } from ${JSON.stringify(moduleHref)};`,
85
+ "const path = process.argv[1];",
86
+ "if (!openDatabase(path)) throw new Error('database open failed');",
87
+ "const db = _getAdapter();",
88
+ "const version = db.prepare('SELECT MAX(version) AS value FROM schema_version').get().value;",
89
+ "const authority = db.prepare('SELECT project_id, revision, authority_epoch FROM project_authority').get();",
90
+ "const legacy = db.prepare(\"SELECT title FROM milestones WHERE id = 'M-LEGACY'\").get();",
91
+ "console.log(JSON.stringify({ version, authority, legacy }));",
92
+ "closeDatabase();",
93
+ ].join("\n");
94
+ const env = { ...process.env };
95
+ delete env.NODE_TEST_CONTEXT;
96
+ const child = spawnSync(
97
+ process.execPath,
98
+ [
99
+ "--import",
100
+ "./src/resources/extensions/gsd/tests/resolve-ts.mjs",
101
+ "--experimental-strip-types",
102
+ "--input-type=module",
103
+ "-e",
104
+ script,
105
+ dbPath,
106
+ ],
107
+ { cwd: process.cwd(), encoding: "utf8", env, timeout: 30_000 },
108
+ );
109
+ assert.equal(child.status, 0, child.stderr || child.stdout);
110
+ return JSON.parse(child.stdout) as Record<string, unknown>;
111
+ }
112
+
113
+ afterEach(() => {
114
+ _setMigrationFaultForTest(false);
115
+ closeDatabase();
116
+ for (const dir of tempDirs) rmSync(dir, { recursive: true, force: true });
117
+ tempDirs.clear();
118
+ });
119
+
120
+ test("fresh database creates the v31 authority root and linked operation journal", () => {
121
+ assert.equal(SCHEMA_VERSION, 31);
122
+ const dbPath = createDatabasePath();
123
+ assert.equal(openDatabase(dbPath), true);
124
+ const db = _getAdapter();
125
+ assert.ok(db);
126
+
127
+ const authority = db.prepare(`
128
+ SELECT singleton, project_id, project_root_realpath, revision, authority_epoch
129
+ FROM project_authority
130
+ `).get();
131
+ assert.deepEqual(
132
+ {
133
+ singleton: authority?.singleton,
134
+ projectIdLength: String(authority?.project_id ?? "").length,
135
+ root: authority?.project_root_realpath,
136
+ revision: authority?.revision,
137
+ epoch: authority?.authority_epoch,
138
+ },
139
+ { singleton: 1, projectIdLength: 32, root: "", revision: 0, epoch: 0 },
140
+ );
141
+
142
+ assert.throws(
143
+ () => db.exec("INSERT INTO project_authority (singleton, project_id) VALUES (2, 'second')"),
144
+ /CHECK constraint failed/i,
145
+ );
146
+ assert.throws(
147
+ () => db.exec("UPDATE project_authority SET revision = -1 WHERE singleton = 1"),
148
+ /CHECK constraint failed/i,
149
+ );
150
+ assert.throws(
151
+ () => db.exec("UPDATE project_authority SET authority_epoch = -1 WHERE singleton = 1"),
152
+ /CHECK constraint failed/i,
153
+ );
154
+
155
+ db.exec(`
156
+ INSERT INTO workflow_operations (
157
+ operation_id, project_id, operation_type, idempotency_key,
158
+ expected_revision, resulting_revision,
159
+ expected_authority_epoch, resulting_authority_epoch,
160
+ actor_type, actor_id, source_transport, request_hash, created_at
161
+ )
162
+ SELECT
163
+ 'op-1', project_id, 'test.operation', 'idem-1',
164
+ 0, 1, 0, 0, 'agent', 'test-agent', 'test', 'request-1', '2026-07-12T00:00:01.000Z'
165
+ FROM project_authority WHERE singleton = 1;
166
+
167
+ INSERT INTO workflow_domain_events (
168
+ event_id, operation_id, event_index, project_id, project_revision,
169
+ authority_epoch, event_type, entity_type, entity_id, payload_json, created_at
170
+ )
171
+ SELECT
172
+ 'event-1', 'op-1', 0, project_id, 1,
173
+ 0, 'test.started', 'project', project_id, '{"step":1}', '2026-07-12T00:00:02.000Z'
174
+ FROM project_authority WHERE singleton = 1;
175
+
176
+ INSERT INTO workflow_domain_events (
177
+ event_id, operation_id, event_index, project_id, project_revision,
178
+ authority_epoch, event_type, entity_type, entity_id, caused_by_event_id,
179
+ payload_json, created_at
180
+ )
181
+ SELECT
182
+ 'event-2', 'op-1', 1, project_id, 1,
183
+ 0, 'test.finished', 'project', project_id, 'event-1',
184
+ '{"step":2}', '2026-07-12T00:00:03.000Z'
185
+ FROM project_authority WHERE singleton = 1;
186
+
187
+ INSERT INTO workflow_outbox (event_id, destination, available_at)
188
+ VALUES ('event-2', 'projection', '2026-07-12T00:00:04.000Z');
189
+ `);
190
+
191
+ const chain = db.prepare(`
192
+ SELECT
193
+ p.revision AS authority_revision,
194
+ o.expected_revision,
195
+ o.resulting_revision,
196
+ COUNT(DISTINCT e.event_id) AS event_count,
197
+ COUNT(DISTINCT x.outbox_id) AS outbox_count
198
+ FROM project_authority p
199
+ JOIN workflow_operations o ON o.project_id = p.project_id
200
+ JOIN workflow_domain_events e ON e.operation_id = o.operation_id
201
+ LEFT JOIN workflow_outbox x ON x.event_id = e.event_id
202
+ GROUP BY p.revision, o.expected_revision, o.resulting_revision
203
+ `).get();
204
+ assert.deepEqual(chain, {
205
+ authority_revision: 0,
206
+ expected_revision: 0,
207
+ resulting_revision: 1,
208
+ event_count: 2,
209
+ outbox_count: 1,
210
+ });
211
+
212
+ assert.throws(
213
+ () => db.exec(`
214
+ INSERT INTO workflow_operations (
215
+ operation_id, project_id, operation_type, idempotency_key,
216
+ expected_revision, resulting_revision,
217
+ expected_authority_epoch, resulting_authority_epoch,
218
+ actor_type, source_transport, request_hash, created_at
219
+ )
220
+ SELECT 'op-duplicate', project_id, 'test.operation', 'idem-1', 1, 2, 0, 0,
221
+ 'agent', 'test', 'request-2', '2026-07-12T00:00:05.000Z'
222
+ FROM project_authority WHERE singleton = 1
223
+ `),
224
+ /UNIQUE constraint failed/i,
225
+ );
226
+ assert.throws(
227
+ () => db.exec(`
228
+ INSERT INTO workflow_operations (
229
+ operation_id, project_id, operation_type, idempotency_key,
230
+ expected_revision, resulting_revision,
231
+ expected_authority_epoch, resulting_authority_epoch,
232
+ actor_type, source_transport, request_hash, created_at
233
+ )
234
+ SELECT 'op-same-revision', project_id, 'test.operation', 'idem-2', 0, 1, 0, 0,
235
+ 'agent', 'test', 'request-2', '2026-07-12T00:00:05.000Z'
236
+ FROM project_authority WHERE singleton = 1
237
+ `),
238
+ /UNIQUE constraint failed/i,
239
+ );
240
+ assert.throws(
241
+ () => db.exec(`
242
+ INSERT INTO workflow_domain_events (
243
+ event_id, operation_id, event_index, project_id, project_revision,
244
+ authority_epoch, event_type, entity_type, entity_id, payload_json, created_at
245
+ )
246
+ SELECT 'event-duplicate-index', 'op-1', 1, project_id, 1, 0,
247
+ 'test.duplicate', 'project', project_id, '{}', '2026-07-12T00:00:06.000Z'
248
+ FROM project_authority WHERE singleton = 1
249
+ `),
250
+ /UNIQUE constraint failed/i,
251
+ );
252
+ assert.throws(
253
+ () => db.exec(`
254
+ INSERT INTO workflow_domain_events (
255
+ event_id, operation_id, event_index, project_id, project_revision,
256
+ authority_epoch, event_type, entity_type, entity_id, payload_json, created_at
257
+ )
258
+ SELECT 'event-wrong-revision', 'op-1', 2, project_id, 2, 0,
259
+ 'test.wrong-revision', 'project', project_id, '{}', '2026-07-12T00:00:06.000Z'
260
+ FROM project_authority WHERE singleton = 1
261
+ `),
262
+ /FOREIGN KEY constraint failed/i,
263
+ );
264
+ assert.throws(
265
+ () => db.exec(`
266
+ INSERT INTO workflow_outbox (event_id, destination, available_at)
267
+ VALUES ('missing-event', 'projection', '2026-07-12T00:00:07.000Z')
268
+ `),
269
+ /FOREIGN KEY constraint failed/i,
270
+ );
271
+ assert.throws(
272
+ () => db.exec(`
273
+ INSERT INTO workflow_outbox (event_id, destination, available_at)
274
+ VALUES ('event-2', 'projection', '2026-07-12T00:00:08.000Z')
275
+ `),
276
+ /UNIQUE constraint failed/i,
277
+ );
278
+ });
279
+
280
+ test("operations record the resulting authority epoch used by their events", () => {
281
+ const dbPath = createDatabasePath();
282
+ assert.equal(openDatabase(dbPath), true);
283
+ const db = _getAdapter();
284
+ assert.ok(db);
285
+
286
+ db.exec(`
287
+ INSERT INTO workflow_operations (
288
+ operation_id, project_id, operation_type, idempotency_key,
289
+ expected_revision, resulting_revision,
290
+ expected_authority_epoch, resulting_authority_epoch,
291
+ actor_type, source_transport, request_hash, created_at
292
+ )
293
+ SELECT 'op-cutover', project_id, 'authority.cutover', 'idem-cutover',
294
+ 0, 1, 0, 1, 'agent', 'test', 'request-cutover', '2026-07-12T00:00:01.000Z'
295
+ FROM project_authority WHERE singleton = 1;
296
+
297
+ INSERT INTO workflow_domain_events (
298
+ event_id, operation_id, event_index, project_id, project_revision,
299
+ authority_epoch, event_type, entity_type, entity_id, payload_json, created_at
300
+ )
301
+ SELECT 'event-cutover', 'op-cutover', 0, project_id, 1, 1,
302
+ 'authority.cutover', 'project', project_id, '{}', '2026-07-12T00:00:02.000Z'
303
+ FROM project_authority WHERE singleton = 1;
304
+
305
+ INSERT INTO workflow_operations (
306
+ operation_id, project_id, operation_type, idempotency_key,
307
+ expected_revision, resulting_revision,
308
+ expected_authority_epoch, resulting_authority_epoch,
309
+ actor_type, source_transport, request_hash, created_at
310
+ )
311
+ SELECT 'op-unchanged-epoch', project_id, 'test.operation', 'idem-unchanged-epoch',
312
+ 1, 2, 1, 1, 'agent', 'test', 'request-unchanged', '2026-07-12T00:00:03.000Z'
313
+ FROM project_authority WHERE singleton = 1;
314
+ `);
315
+
316
+ assert.throws(
317
+ () => db.exec(`
318
+ INSERT INTO workflow_domain_events (
319
+ event_id, operation_id, event_index, project_id, project_revision,
320
+ authority_epoch, event_type, entity_type, entity_id, payload_json, created_at
321
+ )
322
+ SELECT 'event-stale-epoch', 'op-cutover', 1, project_id, 1, 0,
323
+ 'authority.stale', 'project', project_id, '{}', '2026-07-12T00:00:04.000Z'
324
+ FROM project_authority WHERE singleton = 1
325
+ `),
326
+ /FOREIGN KEY constraint failed/i,
327
+ );
328
+ assert.throws(
329
+ () => db.exec(`
330
+ INSERT INTO workflow_operations (
331
+ operation_id, project_id, operation_type, idempotency_key,
332
+ expected_revision, resulting_revision,
333
+ expected_authority_epoch, resulting_authority_epoch,
334
+ actor_type, source_transport, request_hash, created_at
335
+ )
336
+ SELECT 'op-epoch-jump', project_id, 'authority.cutover', 'idem-epoch-jump',
337
+ 2, 3, 1, 3, 'agent', 'test', 'request-jump', '2026-07-12T00:00:05.000Z'
338
+ FROM project_authority WHERE singleton = 1
339
+ `),
340
+ /CHECK constraint failed/i,
341
+ );
342
+ });
343
+
344
+ test("domain events reject updates and deletes", () => {
345
+ const dbPath = createDatabasePath();
346
+ assert.equal(openDatabase(dbPath), true);
347
+ const db = _getAdapter();
348
+ assert.ok(db);
349
+
350
+ db.exec(`
351
+ INSERT INTO workflow_operations (
352
+ operation_id, project_id, operation_type, idempotency_key,
353
+ expected_revision, resulting_revision,
354
+ expected_authority_epoch, resulting_authority_epoch,
355
+ actor_type, source_transport, request_hash, created_at
356
+ )
357
+ SELECT 'op-immutable', project_id, 'test.operation', 'idem-immutable',
358
+ 0, 1, 0, 0, 'agent', 'test', 'request-immutable', '2026-07-12T00:00:01.000Z'
359
+ FROM project_authority WHERE singleton = 1;
360
+
361
+ INSERT INTO workflow_domain_events (
362
+ event_id, operation_id, event_index, project_id, project_revision,
363
+ authority_epoch, event_type, entity_type, entity_id, payload_json, created_at
364
+ )
365
+ SELECT 'event-immutable', 'op-immutable', 0, project_id, 1, 0,
366
+ 'test.recorded', 'project', project_id, '{"original":true}', '2026-07-12T00:00:02.000Z'
367
+ FROM project_authority WHERE singleton = 1;
368
+ `);
369
+
370
+ assert.throws(
371
+ () => db.exec(`UPDATE workflow_domain_events SET payload_json = '{}' WHERE event_id = 'event-immutable'`),
372
+ /workflow domain events are immutable/i,
373
+ );
374
+ assert.throws(
375
+ () => db.exec(`DELETE FROM workflow_domain_events WHERE event_id = 'event-immutable'`),
376
+ /workflow domain events are immutable/i,
377
+ );
378
+ });
379
+
380
+ test("v30 upgrade preserves legacy rows and creates an independently healthy backup", () => {
381
+ const dbPath = createDatabasePath();
382
+ rewindToV30(dbPath);
383
+
384
+ assert.equal(openDatabase(dbPath), true);
385
+ closeDatabase();
386
+
387
+ let projectId = "";
388
+ const upgraded = openRawDatabase(dbPath);
389
+ try {
390
+ assert.equal(maxSchemaVersion(upgraded), 31);
391
+ assert.equal(tableExists(upgraded, "project_authority"), true);
392
+ assert.equal(upgraded.prepare("SELECT title FROM milestones WHERE id = 'M-LEGACY'").get()?.title, "Preserved legacy milestone");
393
+ assert.equal(upgraded.prepare("SELECT payload_json FROM audit_events WHERE event_id = 'audit-legacy'").get()?.payload_json, '{"kept":true}');
394
+ assert.equal(upgraded.prepare("PRAGMA quick_check").get()?.quick_check, "ok");
395
+ projectId = String(upgraded.prepare("SELECT project_id FROM project_authority").get()?.project_id);
396
+ } finally {
397
+ upgraded.close();
398
+ }
399
+
400
+ const backup = openRawDatabase(`${dbPath}.backup-v30`);
401
+ try {
402
+ assert.equal(maxSchemaVersion(backup), 30);
403
+ assert.equal(tableExists(backup, "project_authority"), false);
404
+ assert.equal(backup.prepare("SELECT title FROM milestones WHERE id = 'M-LEGACY'").get()?.title, "Preserved legacy milestone");
405
+ assert.equal(backup.prepare("PRAGMA quick_check").get()?.quick_check, "ok");
406
+ } finally {
407
+ backup.close();
408
+ }
409
+
410
+ const reopened = inspectFromFreshProcess(dbPath);
411
+ assert.deepEqual(reopened, {
412
+ version: 31,
413
+ authority: { project_id: projectId, revision: 0, authority_epoch: 0 },
414
+ legacy: { title: "Preserved legacy milestone" },
415
+ });
416
+
417
+ const restoredPath = join(dirname(dbPath), "restored.db");
418
+ copyFileSync(`${dbPath}.backup-v30`, restoredPath);
419
+ const restored = inspectFromFreshProcess(restoredPath);
420
+ assert.equal(restored.version, 31);
421
+ assert.deepEqual(restored.legacy, { title: "Preserved legacy milestone" });
422
+ assert.deepEqual(
423
+ Object.fromEntries(
424
+ Object.entries(restored.authority as Record<string, unknown>).filter(([key]) => key !== "project_id"),
425
+ ),
426
+ { revision: 0, authority_epoch: 0 },
427
+ );
428
+ });
429
+
430
+ test("faulted v30 migration leaves no v31 state and retries cleanly", () => {
431
+ const dbPath = createDatabasePath();
432
+ rewindToV30(dbPath);
433
+
434
+ _setMigrationFaultForTest(true);
435
+ assert.throws(() => openDatabase(dbPath), /migration fault injected/);
436
+ _setMigrationFaultForTest(false);
437
+
438
+ const rolledBack = openRawDatabase(dbPath);
439
+ try {
440
+ assert.equal(maxSchemaVersion(rolledBack), 30);
441
+ assert.equal(tableExists(rolledBack, "project_authority"), false);
442
+ assert.equal(tableExists(rolledBack, "workflow_operations"), false);
443
+ assert.equal(tableExists(rolledBack, "workflow_domain_events"), false);
444
+ assert.equal(tableExists(rolledBack, "workflow_outbox"), false);
445
+ } finally {
446
+ rolledBack.close();
447
+ }
448
+
449
+ assert.equal(openDatabase(dbPath), true);
450
+ closeDatabase();
451
+ const retried = openRawDatabase(dbPath);
452
+ try {
453
+ assert.equal(maxSchemaVersion(retried), 31);
454
+ assert.equal(retried.prepare("SELECT COUNT(*) AS count FROM project_authority").get()?.count, 1);
455
+ assert.equal(retried.prepare("SELECT COUNT(*) AS count FROM milestones WHERE id = 'M-LEGACY'").get()?.count, 1);
456
+ } finally {
457
+ retried.close();
458
+ }
459
+ });
@@ -101,9 +101,9 @@ describe('db-engine migrate guards', () => {
101
101
  assert.ok(openDatabase(dbPath), 'fresh open should succeed');
102
102
  closeDatabase();
103
103
 
104
- // Rewind the DB to v(SCHEMA_VERSION-1): stamp the prior version and drop
105
- // the objects the last migration adds, so the re-run has real work to redo.
106
- const startVersion = SCHEMA_VERSION - 2;
104
+ // Rewind to v28 and remove a v29 column so the multi-step migration has
105
+ // real work to redo even as later schema versions are added.
106
+ const startVersion = 28;
107
107
  const raw = openRawSqliteForTest(dbPath);
108
108
  raw.exec('DELETE FROM schema_version');
109
109
  raw.exec(`INSERT INTO schema_version (version, applied_at) VALUES (${startVersion}, '2026-01-01T00:00:00Z')`);
@@ -51,6 +51,7 @@ const TYPED_DB_WRITER_FILES = new Set([
51
51
  ]);
52
52
 
53
53
  const SCHEMA_DB_WRITER_FILES = new Set([
54
+ "db-canonical-foundation-schema.ts",
54
55
  "db-memory-fts-schema.ts",
55
56
  "db-schema-metadata.ts",
56
57
  "db-verification-evidence-schema.ts",
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9492],{14040:(e,t,l)=>{(window.__NEXT_P=window.__NEXT_P||[]).push(["/_not-found/page",function(){return l(32910)}])},29999:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"styles",{enumerable:!0,get:function(){return l}});let l={error:{fontFamily:'system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"',height:"100vh",textAlign:"center",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},desc:{display:"inline-block"},h1:{display:"inline-block",margin:"0 20px 0 0",padding:"0 23px 0 0",fontSize:24,fontWeight:500,verticalAlign:"top",lineHeight:"49px"},h2:{fontSize:14,fontWeight:400,lineHeight:"49px",margin:0}};("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},32910:(e,t,l)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return o}});let r=l(18870),n=l(48664),o=function(){return(0,r.jsx)("html",{children:(0,r.jsx)("body",{children:(0,r.jsx)(n.HTTPAccessErrorFallback,{status:404,message:"This page could not be found."})})})};("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},48664:(e,t,l)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"HTTPAccessErrorFallback",{enumerable:!0,get:function(){return o}});let r=l(18870),n=l(29999);function o({status:e,message:t}){return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("title",{children:`${e}: ${t}`}),(0,r.jsx)("div",{style:n.styles.error,children:(0,r.jsxs)("div",{children:[(0,r.jsx)("style",{dangerouslySetInnerHTML:{__html:"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}),(0,r.jsx)("h1",{className:"next-error-h1",style:n.styles.h1,children:e}),(0,r.jsx)("div",{style:n.styles.desc,children:(0,r.jsx)("h2",{style:n.styles.h2,children:t})})]})})]})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)}},e=>{e.O(0,[9990,686,7358],()=>e(e.s=14040)),_N_E=e.O()}]);