@paradigma-inc/flywheel 0.2.50 → 0.2.61

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 (100) hide show
  1. package/package.json +1 -1
  2. package/skills/flywheel-repo/SKILL.md +1 -1
  3. package/skills/flywheel-repo/references/repository-commands.md +5 -4
  4. package/src/runtime/required-runtime-commands.json +1 -0
  5. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/hosted.js +2 -1
  6. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/hosted.js.map +1 -1
  7. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/repository.js +87 -19
  8. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/repository.js.map +1 -1
  9. package/src/runtime/vendor/flywheel-cli-dist/commands/registry.js +1 -1
  10. package/src/runtime/vendor/flywheel-cli-dist/commands/registry.js.map +1 -1
  11. package/src/runtime/vendor/flywheel-cli-dist/commands/repository-operation.js +7 -0
  12. package/src/runtime/vendor/flywheel-cli-dist/commands/repository-operation.js.map +1 -1
  13. package/src/runtime/vendor/flywheel-cli-dist/commands/repository-output.js +20 -0
  14. package/src/runtime/vendor/flywheel-cli-dist/commands/repository-output.js.map +1 -1
  15. package/src/runtime/vendor/flywheel-cli-dist/commands/repository-projection.js +5 -2
  16. package/src/runtime/vendor/flywheel-cli-dist/commands/repository-projection.js.map +1 -1
  17. package/src/runtime/vendor/flywheel-cli-dist/commands/repository-refusal-hints.js +20 -17
  18. package/src/runtime/vendor/flywheel-cli-dist/commands/repository-refusal-hints.js.map +1 -1
  19. package/src/runtime/vendor/flywheel-cli-dist/commands/tombstone-recovery.js +17 -0
  20. package/src/runtime/vendor/flywheel-cli-dist/commands/tombstone-recovery.js.map +1 -0
  21. package/src/runtime/vendor/flywheel-cli-dist/errors.js +16 -0
  22. package/src/runtime/vendor/flywheel-cli-dist/errors.js.map +1 -1
  23. package/src/runtime/vendor/flywheel-cli-dist/local/adapter.js +77 -25
  24. package/src/runtime/vendor/flywheel-cli-dist/local/adapter.js.map +1 -1
  25. package/src/runtime/vendor/flywheel-cli-dist/local/domain/errors.js +9 -0
  26. package/src/runtime/vendor/flywheel-cli-dist/local/domain/errors.js.map +1 -1
  27. package/src/runtime/vendor/flywheel-cli-dist/local/domain/rebase/replay.js +1 -1
  28. package/src/runtime/vendor/flywheel-cli-dist/local/domain/rebase/replay.js.map +1 -1
  29. package/src/runtime/vendor/flywheel-cli-dist/local/domain/service/revert.js +16 -16
  30. package/src/runtime/vendor/flywheel-cli-dist/local/domain/service/revert.js.map +1 -1
  31. package/src/runtime/vendor/flywheel-cli-dist/local/domain/service/staging.js +9 -2
  32. package/src/runtime/vendor/flywheel-cli-dist/local/domain/service/staging.js.map +1 -1
  33. package/src/runtime/vendor/flywheel-cli-dist/local/errors.js +21 -0
  34. package/src/runtime/vendor/flywheel-cli-dist/local/errors.js.map +1 -0
  35. package/src/runtime/vendor/flywheel-cli-dist/local/fs/state.js +9 -11
  36. package/src/runtime/vendor/flywheel-cli-dist/local/fs/state.js.map +1 -1
  37. package/src/runtime/vendor/flywheel-cli-dist/local/fs/writer-lock.js +5 -10
  38. package/src/runtime/vendor/flywheel-cli-dist/local/fs/writer-lock.js.map +1 -1
  39. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/bootstrap.js +2 -1
  40. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/bootstrap.js.map +1 -1
  41. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/dispatch.js +2 -1
  42. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/dispatch.js.map +1 -1
  43. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/operations/core.js +3 -3
  44. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/operations/core.js.map +1 -1
  45. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/operations/maintenance.js +7 -0
  46. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/operations/maintenance.js.map +1 -1
  47. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/operations/projections.js +1 -0
  48. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/operations/projections.js.map +1 -1
  49. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/projection.js +44 -8
  50. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/projection.js.map +1 -1
  51. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/recover-departed.js +8 -2
  52. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/recover-departed.js.map +1 -1
  53. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/remote/purge.js +100 -5
  54. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/remote/purge.js.map +1 -1
  55. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/remote/push.js +8 -4
  56. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/remote/push.js.map +1 -1
  57. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/snapshot-diff.js +2 -5
  58. package/src/runtime/vendor/flywheel-cli-dist/local/runtime/snapshot-diff.js.map +1 -1
  59. package/src/runtime/vendor/flywheel-cli-dist/local/store/apply.js +6 -2
  60. package/src/runtime/vendor/flywheel-cli-dist/local/store/apply.js.map +1 -1
  61. package/src/runtime/vendor/flywheel-cli-dist/local/store/backup/archive.js +1 -8
  62. package/src/runtime/vendor/flywheel-cli-dist/local/store/backup/archive.js.map +1 -1
  63. package/src/runtime/vendor/flywheel-cli-dist/local/store/backup/backup.js +2 -1
  64. package/src/runtime/vendor/flywheel-cli-dist/local/store/backup/backup.js.map +1 -1
  65. package/src/runtime/vendor/flywheel-cli-dist/local/store/backup/restore.js +2 -1
  66. package/src/runtime/vendor/flywheel-cli-dist/local/store/backup/restore.js.map +1 -1
  67. package/src/runtime/vendor/flywheel-cli-dist/local/store/backup/retained-directory.js +1 -1
  68. package/src/runtime/vendor/flywheel-cli-dist/local/store/backup/retained-directory.js.map +1 -1
  69. package/src/runtime/vendor/flywheel-cli-dist/local/store/migrate.js +4 -4
  70. package/src/runtime/vendor/flywheel-cli-dist/local/store/migrate.js.map +1 -1
  71. package/src/runtime/vendor/flywheel-cli-dist/local/store/migration/steps.js +8 -3
  72. package/src/runtime/vendor/flywheel-cli-dist/local/store/migration/steps.js.map +1 -1
  73. package/src/runtime/vendor/flywheel-cli-dist/local/store/migration/versions.js +2 -2
  74. package/src/runtime/vendor/flywheel-cli-dist/local/store/migration/versions.js.map +1 -1
  75. package/src/runtime/vendor/flywheel-cli-dist/local/store/migrations/009_repository_backup_state.sql +8 -0
  76. package/src/runtime/vendor/flywheel-cli-dist/local/store/migrations.js +1 -0
  77. package/src/runtime/vendor/flywheel-cli-dist/local/store/migrations.js.map +1 -1
  78. package/src/runtime/vendor/flywheel-cli-dist/local/store/pending.js +6 -2
  79. package/src/runtime/vendor/flywheel-cli-dist/local/store/pending.js.map +1 -1
  80. package/src/runtime/vendor/flywheel-cli-dist/local/store/projection/nodes.js +33 -16
  81. package/src/runtime/vendor/flywheel-cli-dist/local/store/projection/nodes.js.map +1 -1
  82. package/src/runtime/vendor/flywheel-cli-dist/local/store/projection/rules.js +87 -1
  83. package/src/runtime/vendor/flywheel-cli-dist/local/store/projection/rules.js.map +1 -1
  84. package/src/runtime/vendor/flywheel-cli-dist/local/store/snapshot/replace.js +51 -12
  85. package/src/runtime/vendor/flywheel-cli-dist/local/store/snapshot/replace.js.map +1 -1
  86. package/src/runtime/vendor/flywheel-cli-dist/local/store/sqlite/errors.js +24 -0
  87. package/src/runtime/vendor/flywheel-cli-dist/local/store/sqlite/errors.js.map +1 -1
  88. package/src/runtime/vendor/flywheel-cli-dist/local/store/sqlite/schema.js +1 -0
  89. package/src/runtime/vendor/flywheel-cli-dist/local/store/sqlite/schema.js.map +1 -1
  90. package/src/runtime/vendor/flywheel-cli-dist/local/store/sqlite/store.js +38 -1
  91. package/src/runtime/vendor/flywheel-cli-dist/local/store/sqlite/store.js.map +1 -1
  92. package/src/runtime/vendor/flywheel-cli-dist/local/store/sync.js +4 -0
  93. package/src/runtime/vendor/flywheel-cli-dist/local/store/sync.js.map +1 -1
  94. package/src/runtime/vendor/flywheel-cli-dist/local/store/workspace.js +7 -1
  95. package/src/runtime/vendor/flywheel-cli-dist/local/store/workspace.js.map +1 -1
  96. package/src/runtime/vendor/flywheel-cli-dist/main.js +83 -82
  97. package/src/runtime/vendor/flywheel-cli-dist/main.js.map +1 -1
  98. package/src/runtime/vendor/flywheel-cli-dist/prebuilds/darwin-arm64/node.napi.node +0 -0
  99. package/src/runtime/vendor/flywheel-cli-dist/prebuilds/darwin-x64/node.napi.node +0 -0
  100. package/src/runtime/vendor/manifest.json +6 -1
@@ -1,6 +1,6 @@
1
1
  import { migrationNames } from "../migrations.js";
2
- export const CURRENT_REPOSITORY_USER_VERSION = 8;
3
- export const PREDECESSOR_REPOSITORY_USER_VERSIONS = [1, 2, 3, 4, 5, 6, 7];
2
+ export const CURRENT_REPOSITORY_USER_VERSION = 9;
3
+ export const PREDECESSOR_REPOSITORY_USER_VERSIONS = [1, 2, 3, 4, 5, 6, 7, 8];
4
4
  export function isPredecessorRepositoryUserVersion(value) {
5
5
  return PREDECESSOR_REPOSITORY_USER_VERSIONS.includes(value);
6
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"versions.js","sourceRoot":"","sources":["../../../../src/local/store/migration/versions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,CAAC;AACjD,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAU,CAAC;AAInF,MAAM,UAAU,kCAAkC,CAAC,KAAa;IAC9D,OAAO,oCAAoC,CAAC,QAAQ,CAAC,KAAyC,CAAC,CAAC;AAClG,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,OAAyC;IAC/E,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"versions.js","sourceRoot":"","sources":["../../../../src/local/store/migration/versions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,CAAC;AACjD,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAU,CAAC;AAItF,MAAM,UAAU,kCAAkC,CAAC,KAAa;IAC9D,OAAO,oCAAoC,CAAC,QAAQ,CAAC,KAAyC,CAAC,CAAC;AAClG,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,OAAyC;IAC/E,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,8 @@
1
+ CREATE TABLE repository_backup_state (
2
+ repository_id TEXT PRIMARY KEY NOT NULL REFERENCES repository_metadata(repository_id),
3
+ completed_at TEXT NOT NULL CHECK (
4
+ completed_at GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9][0-9][0-9][0-9]Z'
5
+ ),
6
+ archive_digest TEXT NOT NULL CHECK (length(archive_digest) = 71 AND substr(archive_digest, 1, 7) = 'sha256:' AND substr(archive_digest, 8) NOT GLOB '*[^0-9a-f]*')
7
+ );
8
+ PRAGMA user_version = 9;
@@ -8,6 +8,7 @@ export const migrationNames = [
8
8
  "006_sync_journal.sql",
9
9
  "007_repository_node_source_timestamps.sql",
10
10
  "008_boundaries_departures_and_author.sql",
11
+ "009_repository_backup_state.sql",
11
12
  ];
12
13
  export function loadMigration(name) {
13
14
  return readFileSync(new URL(`./migrations/${name}`, import.meta.url), "utf8");
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../../src/local/store/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,iBAAiB;IACjB,8BAA8B;IAC9B,kCAAkC;IAClC,4BAA4B;IAC5B,6BAA6B;IAC7B,sBAAsB;IACtB,2CAA2C;IAC3C,0CAA0C;CAClC,CAAC;AAIX,MAAM,UAAU,aAAa,CAAC,IAAmB;IAC/C,OAAO,YAAY,CAAC,IAAI,GAAG,CAAC,gBAAgB,IAAI,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;AAChF,CAAC"}
1
+ {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../../src/local/store/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,iBAAiB;IACjB,8BAA8B;IAC9B,kCAAkC;IAClC,4BAA4B;IAC5B,6BAA6B;IAC7B,sBAAsB;IACtB,2CAA2C;IAC3C,0CAA0C;IAC1C,iCAAiC;CACzB,CAAC;AAIX,MAAM,UAAU,aAAa,CAAC,IAAmB;IAC/C,OAAO,YAAY,CAAC,IAAI,GAAG,CAAC,gBAAgB,IAAI,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;AAChF,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { DatabaseSync } from "node:sqlite";
2
2
  import { iterateOperationLatestValues } from "./latest-values.js";
3
3
  import { applyOperations } from "./projection/apply.js";
4
+ import { assertNoDuplicateSemanticEdges, assertTombstonesReleaseLineage } from "./projection/rules.js";
4
5
  import { assertProjectionInvariants } from "./snapshot/replace.js";
5
6
  import { snapshotTablesFromConnection } from "./snapshot/read.js";
6
7
  import { SNAPSHOT_TABLES } from "./snapshot/schema.js";
@@ -60,6 +61,7 @@ function withPendingGraph(repositoryId, identity, baseHeadCommitId, baseTables,
60
61
  runSql(markLocal, repositoryId, objectDigest);
61
62
  }
62
63
  assertProjectionInvariants(database, repositoryId);
64
+ assertTombstonesReleaseLineage(database, repositoryId, staging.operations);
63
65
  return render(database);
64
66
  }
65
67
  finally {
@@ -79,12 +81,14 @@ function applyPendingSnapshot(repositoryId, identity, baseHeadCommitId, baseTabl
79
81
  /**
80
82
  * Reject an invalid batch against its committed base without exposing the
81
83
  * rendered pending graph; the append path only needs pass/fail plus the
82
- * first-failing-operation attribution `applyOperations` already raises.
84
+ * first-failing-operation attribution `applyOperations` already raises. Only
85
+ * this new-write path refuses a duplicated semantic edge relation; rendering a
86
+ * batch saved earlier still shows it.
83
87
  */
84
88
  export function validatePendingBatch(repositoryId, identity, baseHeadCommitId, baseTables, staging, committedOperationIds) {
85
89
  if (staging.operations.length === 0 && staging.latestValues.length === 0)
86
90
  return;
87
- withPendingGraph(repositoryId, identity, baseHeadCommitId, validateSnapshotTables(repositoryId, baseTables), staging, committedOperationIds, () => undefined);
91
+ withPendingGraph(repositoryId, identity, baseHeadCommitId, validateSnapshotTables(repositoryId, baseTables), staging, committedOperationIds, database => assertNoDuplicateSemanticEdges(database, repositoryId, staging.operations));
88
92
  }
89
93
  export function pendingRepositorySnapshot(repositoryId, identity, baseHeadCommitId, baseTables, staging, committedOperationIds) {
90
94
  const tables = validateSnapshotTables(repositoryId, baseTables);
@@ -1 +1 @@
1
- {"version":3,"file":"pending.js","sourceRoot":"","sources":["../../../src/local/store/pending.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pending.js","sourceRoot":"","sources":["../../../src/local/store/pending.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { RepositoryStoreError } from "../sqlite/errors.js";
2
- import { getRow, runSql } from "../sqlite/rows.js";
2
+ import { allRows, getRow, runSql } from "../sqlite/rows.js";
3
3
  import { RepositoryCommit } from "../../domain/models/commits.js";
4
4
  const NODE_FIELDS = ["title", "slug_name", "summary", "content", "origin_host", "external_transcript_ref"];
5
5
  function stringValue(value) {
@@ -41,20 +41,37 @@ export function applyNodeFieldSet(database, commit, operation, latestValue) {
41
41
  SET ${field} = ?, ${field}_digest = ?, updated_by_commit_id = ?
42
42
  WHERE repository_id = ? AND node_id = ?`), latestValue.value, replacement, commit.commitId, commit.repositoryId, nodeId);
43
43
  }
44
- function structuralDependencyCount(database, repositoryId, nodeId) {
45
- const row = getRow(database.prepare(`SELECT COUNT(*) AS count FROM (
46
- SELECT parent_node_id FROM repository_lineage
44
+ /**
45
+ * Every relationship in this repository that references the node, in a stable
46
+ * order. Purge requires none; relations held by other repositories are not
47
+ * visible here and are settled by the hosted purge.
48
+ */
49
+ export function structuralDependencies(database, repositoryId, nodeId) {
50
+ const rows = allRows(database.prepare(`SELECT * FROM (
51
+ SELECT 1 AS rank, parent_repository_id AS a, parent_node_id AS b, child_node_id AS c, NULL AS d FROM repository_lineage
47
52
  WHERE repository_id = ? AND ((parent_repository_id = ? AND parent_node_id = ?) OR child_node_id = ?)
48
- UNION ALL SELECT containment_id FROM repository_containments WHERE repository_id = ? AND (container_node_id = ? OR child_node_id = ?)
49
- UNION ALL SELECT edge_id FROM repository_semantic_edges WHERE repository_id = ? AND (graph_node_id = ? OR source_node_id = ? OR target_node_id = ?)
50
- UNION ALL SELECT tag_id FROM repository_tag_definitions WHERE repository_id = ? AND scope_node_id = ? AND state = 'active'
51
- UNION ALL SELECT tag_id FROM repository_tag_assignments
53
+ UNION ALL SELECT 2, containment_id, container_node_id, child_node_id, NULL FROM repository_containments
54
+ WHERE repository_id = ? AND (container_node_id = ? OR child_node_id = ?)
55
+ UNION ALL SELECT 3, edge_id, graph_node_id, source_node_id, target_node_id FROM repository_semantic_edges
56
+ WHERE repository_id = ? AND (graph_node_id = ? OR source_node_id = ? OR target_node_id = ?)
57
+ UNION ALL SELECT 4, tag_id, scope_node_id, NULL, NULL FROM repository_tag_definitions
58
+ WHERE repository_id = ? AND scope_node_id = ? AND state = 'active'
59
+ UNION ALL SELECT 5, tag_id, scope_repository_id, scope_node_id, node_id FROM repository_tag_assignments
52
60
  WHERE repository_id = ? AND ((scope_repository_id = ? AND scope_node_id = ?) OR node_id = ?)
53
- UNION ALL SELECT artifact_id FROM repository_artifact_references WHERE repository_id = ? AND node_owner_id = ?
54
- )`, { readBigInts: true }), repositoryId, repositoryId, nodeId, nodeId, repositoryId, nodeId, nodeId, repositoryId, nodeId, nodeId, nodeId, repositoryId, nodeId, repositoryId, repositoryId, nodeId, nodeId, repositoryId, nodeId);
55
- if (!row || typeof row.count !== "bigint")
56
- throw new RepositoryStoreError("structural dependency count is invalid");
57
- return row.count;
61
+ UNION ALL SELECT 6, artifact_id, NULL, NULL, NULL FROM repository_artifact_references WHERE repository_id = ? AND node_owner_id = ?
62
+ ) ORDER BY rank, a, b, c, d`), repositoryId, repositoryId, nodeId, nodeId, repositoryId, nodeId, nodeId, repositoryId, nodeId, nodeId, nodeId, repositoryId, nodeId, repositoryId, repositoryId, nodeId, nodeId, repositoryId, nodeId);
63
+ return rows.map((row) => {
64
+ const [a, b, c, d] = [row.a, row.b, row.c, row.d].map(String);
65
+ switch (row.rank) {
66
+ case 1: return { kind: "lineage", parent_repository_id: a, parent_node_id: b, child_node_id: c };
67
+ case 2: return { kind: "containment", containment_id: a, container_node_id: b, child_node_id: c };
68
+ case 3: return { kind: "semantic_edge", edge_id: a, graph_node_id: b, source_node_id: c, target_node_id: d };
69
+ case 4: return { kind: "tag_definition", tag_id: a, scope_node_id: b };
70
+ case 5: return { kind: "tag_assignment", tag_id: a, scope_repository_id: b, scope_node_id: c, node_id: d };
71
+ case 6: return { kind: "artifact", artifact_id: a };
72
+ default: throw new RepositoryStoreError("structural dependency row is invalid");
73
+ }
74
+ });
58
75
  }
59
76
  function assertRestoreStructure(database, repositoryId, nodeId) {
60
77
  // Retained semantic edges do not block restoring one endpoint while the
@@ -98,7 +115,7 @@ export function applyNodeLifecycle(database, commit, operation) {
98
115
  throw new RepositoryStoreError("invalid node lifecycle operation");
99
116
  if (operation.type === "node.restore.v1")
100
117
  assertRestoreStructure(database, commit.repositoryId, nodeId);
101
- else if (revertsNodeCreate(database, commit, nodeId) && structuralDependencyCount(database, commit.repositoryId, nodeId) !== 0n) {
118
+ else if (revertsNodeCreate(database, commit, nodeId) && structuralDependencies(database, commit.repositoryId, nodeId).length !== 0) {
102
119
  throw new RepositoryStoreError("node create revert has new live structural dependencies");
103
120
  }
104
121
  const next = operation.type === "node.tombstone.v1" ? "tombstoned" : "live";
@@ -117,9 +134,9 @@ export function applyNodePurge(database, commit, operation) {
117
134
  if (nodeId !== confirmation || expectedHead !== commit.expectedHead) {
118
135
  throw new RepositoryStoreError("node purge confirmation or head is invalid");
119
136
  }
120
- const dependencies = structuralDependencyCount(database, commit.repositoryId, nodeId);
121
- if (dependencies !== 0n)
137
+ if (structuralDependencies(database, commit.repositoryId, nodeId).length !== 0) {
122
138
  throw new RepositoryStoreError("node purge has live structural dependencies");
139
+ }
123
140
  if (runSql(database.prepare("UPDATE repository_nodes SET lifecycle_state = 'purged', lifecycle_commit_id = ? WHERE repository_id = ? AND node_id = ? AND lifecycle_state = 'tombstoned'"), commit.commitId, commit.repositoryId, nodeId).changes !== 1)
124
141
  throw new RepositoryStoreError("node purge projection precondition failed");
125
142
  runSql(database.prepare("DELETE FROM repository_node_latest_values WHERE repository_id = ? AND node_id = ?"), commit.repositoryId, nodeId);
@@ -1 +1 @@
1
- {"version":3,"file":"nodes.js","sourceRoot":"","sources":["../../../../src/local/store/projection/nodes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"nodes.js","sourceRoot":"","sources":["../../../../src/local/store/projection/nodes.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
+ import { RepositoryServiceError } from "../../domain/errors.js";
1
2
  import { validateAcyclicRelation, validateSemanticEdgeScale } from "../../domain/invariants.js";
2
- import { RepositoryStoreError } from "../sqlite/errors.js";
3
+ import { RepositoryNodeTombstoneBlockedError, RepositoryStoreError } from "../sqlite/errors.js";
3
4
  import { allRows, getRow } from "../sqlite/rows.js";
4
5
  function asString(value) {
5
6
  return typeof value === "string" ? value : undefined;
@@ -13,6 +14,45 @@ export function assertLiveNodes(database, repositoryId, nodeIds) {
13
14
  throw new RepositoryStoreError("structural relation requires live repository nodes");
14
15
  }
15
16
  }
17
+ /**
18
+ * New work may not leave lineage on a node it tombstones. Only the finished
19
+ * batch counts: a link removed later in the batch, or a node restored before
20
+ * the batch ends, does not block, and history already accepted before the
21
+ * batch is never re-checked. A node's links are its incoming relations and the
22
+ * outgoing relations it parents in this repository; a same-ID parent held by
23
+ * another repository is a different node.
24
+ */
25
+ export function assertTombstonesReleaseLineage(database, repositoryId, operations) {
26
+ // A node tombstoned, restored and tombstoned again is left tombstoned by its last tombstone.
27
+ const lastTombstones = new Map();
28
+ for (const operation of operations) {
29
+ if (operation.type === "node.tombstone.v1")
30
+ lastTombstones.set(String(operation.payload.node_id), operation);
31
+ }
32
+ if (lastTombstones.size === 0)
33
+ return;
34
+ const lifecycle = database.prepare("SELECT lifecycle_state FROM repository_nodes WHERE repository_id = ? AND node_id = ?");
35
+ const links = database.prepare(`SELECT parent_repository_id, parent_node_id, child_node_id FROM repository_lineage
36
+ WHERE repository_id = ? AND (child_node_id = ? OR (parent_repository_id = repository_id AND parent_node_id = ?))
37
+ ORDER BY parent_repository_id, parent_node_id, child_node_id`);
38
+ for (const operation of operations) {
39
+ if (operation.type !== "node.tombstone.v1")
40
+ continue;
41
+ const nodeId = String(operation.payload.node_id);
42
+ if (lastTombstones.get(nodeId) !== operation)
43
+ continue;
44
+ if (getRow(lifecycle, repositoryId, nodeId)?.lifecycle_state !== "tombstoned")
45
+ continue;
46
+ const rows = allRows(links, repositoryId, nodeId, nodeId);
47
+ if (rows.length === 0)
48
+ continue;
49
+ throw new RepositoryNodeTombstoneBlockedError(repositoryId, nodeId, operation.operationId, rows.map(row => ({
50
+ parentRepositoryId: String(row.parent_repository_id),
51
+ parentNodeId: String(row.parent_node_id),
52
+ childNodeId: String(row.child_node_id),
53
+ })));
54
+ }
55
+ }
16
56
  export function assertAcyclicRelation(database, repositoryId, parentId, childId, table) {
17
57
  if (parentId === childId) {
18
58
  throw new RepositoryStoreError(`${table === "repository_lineage" ? "lineage" : "containment"} cycle is invalid`);
@@ -86,4 +126,50 @@ export function assertAllSemanticEdgesValid(database, repositoryId) {
86
126
  assertSemanticEdgeValid(database, repositoryId, graphId, sourceId, targetId);
87
127
  }
88
128
  }
129
+ /**
130
+ * Refuses a batch whose resulting graph gives one relation (graph, source,
131
+ * target and relation digest) a second semantic edge. Only edges this batch
132
+ * added are checked, after the whole batch applied, so an edge removed in the
133
+ * same batch can be replaced and history accepted before this rule keeps its
134
+ * parallel edges. One query covers the batch and reads each graph the batch
135
+ * added edges to once.
136
+ */
137
+ export function assertNoDuplicateSemanticEdges(database, repositoryId, operations) {
138
+ const added = operations.flatMap(operation => operation.type === "edge.add.v1" ? [operation.payload.edge_id] : []);
139
+ if (added.length === 0)
140
+ return;
141
+ // The materialized sets let SQLite build temporary indexes to match them,
142
+ // instead of scanning a whole graph once per added edge. Of two edges for one
143
+ // relation, the one added later in the batch is the proposed duplicate; an
144
+ // edge from before the batch is always the existing one.
145
+ const row = getRow(database.prepare(`WITH added(edge_id, position) AS MATERIALIZED (SELECT value, key FROM json_each(?1)),
146
+ proposed AS MATERIALIZED (
147
+ SELECT edge.edge_id, edge.graph_node_id, edge.source_node_id, edge.target_node_id, edge.relation_digest, added.position
148
+ FROM added CROSS JOIN repository_semantic_edges AS edge
149
+ ON edge.repository_id = ?2 AND edge.edge_id = added.edge_id),
150
+ existing AS MATERIALIZED (
151
+ SELECT edge.edge_id, edge.graph_node_id, edge.source_node_id, edge.target_node_id, edge.relation_digest, added.position
152
+ FROM repository_semantic_edges AS edge LEFT JOIN added ON added.edge_id = edge.edge_id
153
+ WHERE edge.repository_id = ?2 AND edge.graph_node_id IN (SELECT graph_node_id FROM proposed))
154
+ SELECT proposed.edge_id, existing.edge_id AS existing_edge_id,
155
+ proposed.graph_node_id, proposed.source_node_id, proposed.target_node_id
156
+ FROM proposed JOIN existing
157
+ ON existing.graph_node_id = proposed.graph_node_id AND existing.source_node_id = proposed.source_node_id
158
+ AND existing.target_node_id = proposed.target_node_id AND existing.relation_digest = proposed.relation_digest
159
+ AND existing.edge_id <> proposed.edge_id
160
+ WHERE existing.position IS NULL OR existing.position < proposed.position
161
+ ORDER BY proposed.position, existing.position IS NOT NULL, existing.position, existing.edge_id
162
+ LIMIT 1`), JSON.stringify(added), repositoryId);
163
+ if (row === undefined)
164
+ return;
165
+ const details = {
166
+ edge_id: asString(row.edge_id), existing_edge_id: asString(row.existing_edge_id),
167
+ graph_node_id: asString(row.graph_node_id), source_node_id: asString(row.source_node_id), target_node_id: asString(row.target_node_id),
168
+ };
169
+ throw new RepositoryServiceError(`Semantic edge ${details.edge_id} duplicates edge ${details.existing_edge_id}: graph ${details.graph_node_id} already has an edge from ${details.source_node_id} to ${details.target_node_id} for this relation. The repository head and pending batch are unchanged.`, {
170
+ code: "repository_semantic_edge_duplicate",
171
+ details,
172
+ nextAction: `Keep using edge ${details.existing_edge_id}, or remove it with repo:edge:remove ${details.existing_edge_id} before adding a replacement edge for the same relation.`,
173
+ });
174
+ }
89
175
  //# sourceMappingURL=rules.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../../../src/local/store/projection/rules.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../../../src/local/store/projection/rules.ts"],"names":[],"mappings":"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"}
@@ -1,21 +1,60 @@
1
- import { assertAcyclicRelation, assertAllSemanticEdgesValid, assertLiveNodes, } from "../projection/rules.js";
1
+ import { assertAllSemanticEdgesValid, } from "../projection/rules.js";
2
2
  import { RepositoryStoreError } from "../sqlite/errors.js";
3
- import { allRows, runSql } from "../sqlite/rows.js";
3
+ import { allRows, iterateRows, runSql } from "../sqlite/rows.js";
4
4
  import { SNAPSHOT_DELETE_ORDER, SNAPSHOT_TABLES } from "./schema.js";
5
5
  import { validateSnapshotTables } from "./validate.js";
6
- export function assertProjectionInvariants(database, repositoryId) {
7
- for (const row of allRows(database.prepare("SELECT parent_repository_id, parent_node_id, child_node_id FROM repository_lineage WHERE repository_id = ?"), repositoryId)) {
8
- const parentRepositoryId = row.parent_repository_id;
9
- const parentNodeId = row.parent_node_id;
10
- const childNodeId = row.child_node_id;
11
- assertLiveNodes(database, repositoryId, parentRepositoryId === repositoryId ? [parentNodeId, childNodeId] : [childNodeId]);
12
- if (parentRepositoryId === repositoryId) {
13
- assertAcyclicRelation(database, repositoryId, parentNodeId, childNodeId, "repository_lineage");
6
+ /**
7
+ * Validate one whole relation in O(V + E) time, retaining O(V + E) graph state
8
+ * until this check returns. This trades memory for avoiding repeated descendant
9
+ * walks for every edge; V and E are the local relation's vertices and edges.
10
+ */
11
+ function assertAcyclicGraph(database, repositoryId, relation) {
12
+ const rows = iterateRows(database.prepare(relation === "lineage"
13
+ ? "SELECT parent_node_id AS parent, child_node_id AS child FROM repository_lineage WHERE repository_id = ? AND parent_repository_id = repository_id"
14
+ : "SELECT container_node_id AS parent, child_node_id AS child FROM repository_containments WHERE repository_id = ?"), repositoryId);
15
+ const children = new Map();
16
+ const incoming = new Map();
17
+ for (const row of rows) {
18
+ const parent = row.parent;
19
+ const child = row.child;
20
+ const siblings = children.get(parent);
21
+ if (siblings === undefined)
22
+ children.set(parent, [child]);
23
+ else
24
+ siblings.push(child);
25
+ if (!incoming.has(parent))
26
+ incoming.set(parent, 0);
27
+ incoming.set(child, (incoming.get(child) ?? 0) + 1);
28
+ }
29
+ const ready = [];
30
+ for (const [node, count] of incoming) {
31
+ if (count === 0)
32
+ ready.push(node);
33
+ }
34
+ for (let index = 0; index < ready.length; index++) {
35
+ const descendants = children.get(ready[index]);
36
+ if (descendants === undefined)
37
+ continue;
38
+ for (const child of descendants) {
39
+ const remaining = incoming.get(child) - 1;
40
+ incoming.set(child, remaining);
41
+ if (remaining === 0)
42
+ ready.push(child);
14
43
  }
15
44
  }
16
- for (const row of allRows(database.prepare("SELECT container_node_id, child_node_id FROM repository_containments WHERE repository_id = ?"), repositoryId)) {
17
- assertAcyclicRelation(database, repositoryId, row.container_node_id, row.child_node_id, "repository_containments");
45
+ if (ready.length !== incoming.size) {
46
+ throw new RepositoryStoreError(`${relation} cycle is invalid`);
18
47
  }
48
+ }
49
+ /**
50
+ * Invariants every stored or received projection satisfies. Lineage to a
51
+ * tombstoned node is not one of them: hosted history accepted such links, and
52
+ * clone, pull and restore must keep carrying it. New work is held to that rule
53
+ * separately by `assertTombstonesReleaseLineage`.
54
+ */
55
+ export function assertProjectionInvariants(database, repositoryId) {
56
+ assertAcyclicGraph(database, repositoryId, "lineage");
57
+ assertAcyclicGraph(database, repositoryId, "containment");
19
58
  // Migration 008 dropped the assignments→definitions foreign key to permit
20
59
  // boundary scopes; local-scoped assignments must still resolve locally.
21
60
  if (allRows(database.prepare("SELECT 1 FROM repository_tag_assignments"
@@ -1 +1 @@
1
- {"version":3,"file":"replace.js","sourceRoot":"","sources":["../../../../src/local/store/snapshot/replace.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"replace.js","sourceRoot":"","sources":["../../../../src/local/store/snapshot/replace.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,34 @@
1
1
  export class RepositoryStoreError extends Error {
2
2
  name = "RepositoryStoreError";
3
+ code;
4
+ constructor(message, options) {
5
+ super(message, options);
6
+ this.code = options?.code;
7
+ }
3
8
  }
4
9
  /** The workspace moved between capture and the atomic write; nothing was changed. */
5
10
  export class WorkspacePreconditionError extends RepositoryStoreError {
6
11
  name = "WorkspacePreconditionError";
7
12
  }
13
+ /**
14
+ * A batch tombstones a node that still has lineage when the batch ends. Names
15
+ * the first such tombstone in operation order and every link still attached
16
+ * to its node; the refused batch changed nothing.
17
+ */
18
+ export class RepositoryNodeTombstoneBlockedError extends RepositoryStoreError {
19
+ name = "RepositoryNodeTombstoneBlockedError";
20
+ repositoryId;
21
+ nodeId;
22
+ operationId;
23
+ links;
24
+ constructor(repositoryId, nodeId, operationId, links) {
25
+ super("repository_node_tombstone_blocked", { code: "repository_node_tombstone_blocked" });
26
+ this.repositoryId = repositoryId;
27
+ this.nodeId = nodeId;
28
+ this.operationId = operationId;
29
+ this.links = links;
30
+ }
31
+ }
8
32
  /** SQLite's primary result code for "database is locked"; masks off extended detail bits. */
9
33
  const SQLITE_BUSY = 5;
10
34
  const SQLITE_LOCKED = 6;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../../src/local/store/sqlite/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACpC,IAAI,GAAG,sBAAsB,CAAC;CACxC;AAED,qFAAqF;AACrF,MAAM,OAAO,0BAA2B,SAAQ,oBAAoB;IACzD,IAAI,GAAG,4BAA4B,CAAC;CAC9C;AAED,6FAA6F;AAC7F,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,MAAM,aAAa,GAAG,CAAC,CAAC;AACxB,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAOtC;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAClE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,KAAwB,CAAC;IACnD,IAAI,IAAI,KAAK,kBAAkB,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACjF,MAAM,OAAO,GAAG,OAAO,GAAG,wBAAwB,CAAC;IACnD,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AACpF,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,mBAAoB,SAAQ,oBAAoB;IAClD,IAAI,GAAG,qBAAqB,CAAC;IAC7B,UAAU,CAAS;IAE5B,YAAY,UAAkB,EAAE,KAAc;QAC5C,KAAK,CAAC,iBAAiB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AAED,sIAAsI;AACtI,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,MAAM,QAAQ,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC7C,IAAI,QAAQ,KAAK,SAAS;QAAE,MAAM,IAAI,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AAC7E,CAAC"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../../src/local/store/sqlite/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACpC,IAAI,GAAG,sBAAsB,CAAC;IAC9B,IAAI,CAAU;IAEvB,YAAY,OAAe,EAAE,OAA0C;QACrE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;IAC5B,CAAC;CACF;AAED,qFAAqF;AACrF,MAAM,OAAO,0BAA2B,SAAQ,oBAAoB;IACzD,IAAI,GAAG,4BAA4B,CAAC;CAC9C;AAQD;;;;GAIG;AACH,MAAM,OAAO,mCAAoC,SAAQ,oBAAoB;IAClE,IAAI,GAAG,qCAAqC,CAAC;IAC7C,YAAY,CAAS;IACrB,MAAM,CAAS;IACf,WAAW,CAAS;IACpB,KAAK,CAAyB;IAEvC,YAAY,YAAoB,EAAE,MAAc,EAAE,WAAmB,EAAE,KAA6B;QAClG,KAAK,CAAC,mCAAmC,EAAE,EAAE,IAAI,EAAE,mCAAmC,EAAE,CAAC,CAAC;QAC1F,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAED,6FAA6F;AAC7F,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,MAAM,aAAa,GAAG,CAAC,CAAC;AACxB,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAOtC;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAClE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,KAAwB,CAAC;IACnD,IAAI,IAAI,KAAK,kBAAkB,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACjF,MAAM,OAAO,GAAG,OAAO,GAAG,wBAAwB,CAAC;IACnD,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AACpF,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,mBAAoB,SAAQ,oBAAoB;IAClD,IAAI,GAAG,qBAAqB,CAAC;IAC7B,UAAU,CAAS;IAE5B,YAAY,UAAkB,EAAE,KAAc;QAC5C,KAAK,CAAC,iBAAiB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AAED,sIAAsI;AACtI,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,MAAM,QAAQ,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC7C,IAAI,QAAQ,KAAK,SAAS;QAAE,MAAM,IAAI,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AAC7E,CAAC"}
@@ -28,6 +28,7 @@ export function initializeRepository(state, repositoryId, clientId) {
28
28
  database.exec(loadMigration("001_initial.sql"));
29
29
  database.exec(loadMigration("007_repository_node_source_timestamps.sql"));
30
30
  database.exec(loadMigration("008_boundaries_departures_and_author.sql"));
31
+ database.exec(loadMigration("009_repository_backup_state.sql"));
31
32
  const createdAt = now();
32
33
  database.prepare("INSERT INTO repository_metadata VALUES (?, ?, 'flywheel.repository.v1', ?)").run(repositoryId, clientId, createdAt);
33
34
  database.prepare("INSERT INTO repository_heads VALUES (?, NULL, NULL, ?)").run(repositoryId, now());
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../../src/local/store/sqlite/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAEjG,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;AACnG,CAAC;AAED,SAAS,cAAc,CAAC,KAA8B;IACpD,IAAI,CAAC;QACH,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,SAAS,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACnC,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,GAAG;IACV,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,KAA8B,EAC9B,YAAoB,EACpB,QAAgB;IAEhB,MAAM,QAAQ,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACxC,mBAAmB,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,EAAE;QACtC,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC,CAAC;YAChD,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,2CAA2C,CAAC,CAAC,CAAC;YAC1E,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,0CAA0C,CAAC,CAAC,CAAC;YACzE,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;YACxB,QAAQ,CAAC,OAAO,CACd,4EAA4E,CAC7E,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;YACzC,QAAQ,CAAC,OAAO,CACd,wDAAwD,CACzD,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;YAC3B,QAAQ,CAAC,OAAO,CACd,+DAA+D,CAChE,CAAC,GAAG,CAAC,YAAY,EAAE,aAAa,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,iBAAiB,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;YAC3F,QAAQ,CAAC,OAAO,CACd;;;qDAG6C,CAC9C,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;QAC7B,CAAC;QACD,YAAY,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACvC,CAAC,EAAE,IAAI,CAAC,CAAC;AACX,CAAC"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../../src/local/store/sqlite/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAEjG,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;AACnG,CAAC;AAED,SAAS,cAAc,CAAC,KAA8B;IACpD,IAAI,CAAC;QACH,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,SAAS,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACnC,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,GAAG;IACV,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,KAA8B,EAC9B,YAAoB,EACpB,QAAgB;IAEhB,MAAM,QAAQ,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACxC,mBAAmB,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,EAAE;QACtC,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC,CAAC;YAChD,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,2CAA2C,CAAC,CAAC,CAAC;YAC1E,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,0CAA0C,CAAC,CAAC,CAAC;YACzE,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,iCAAiC,CAAC,CAAC,CAAC;YAChE,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;YACxB,QAAQ,CAAC,OAAO,CACd,4EAA4E,CAC7E,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;YACzC,QAAQ,CAAC,OAAO,CACd,wDAAwD,CACzD,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;YAC3B,QAAQ,CAAC,OAAO,CACd,+DAA+D,CAChE,CAAC,GAAG,CAAC,YAAY,EAAE,aAAa,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,iBAAiB,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;YAC3F,QAAQ,CAAC,OAAO,CACd;;;qDAG6C,CAC9C,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;QAC7B,CAAC;QACD,YAAY,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACvC,CAAC,EAAE,IAAI,CAAC,CAAC;AACX,CAAC"}
@@ -1,11 +1,12 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { applyOrdinaryAtomic } from "../apply.js";
3
- import { isUuid } from "../../domain/models/constants.js";
3
+ import { isDigest, isUuid, validateTimestamp } from "../../domain/models/constants.js";
4
4
  import { capturedRepositoryIdentityIn, commitLatestValues, committedOperationIds, listCommitsIn, loadCommitByOperationId, workspaceHeadIn } from "../commits.js";
5
5
  import { rootedObjectDigestsIn, reachableObjectDigestsIn, assertObjectBytesAvailable, objectBytesVerified } from "../gc.js";
6
6
  import { snapshotBytesFromConnection, snapshotTablesFromConnection } from "../snapshot/read.js";
7
7
  import { replaceSnapshotTables } from "../snapshot/replace.js";
8
8
  import { canonicalSnapshotBytes, snapshotLocalObjectDigests, snapshotTables } from "../snapshot/validate.js";
9
+ import { structuralDependencies } from "../projection/nodes.js";
9
10
  import { pendingRepositorySnapshot } from "../pending.js";
10
11
  import { completeSyncJournalEntry, latestPushJournalEntry, listInterruptedSyncEntries, recordSyncJournalPhase, timestamp, } from "../sync-journal.js";
11
12
  import { applySyncAtomic } from "../sync.js";
@@ -85,6 +86,31 @@ export class SQLiteRepositoryStore {
85
86
  return requireRepositoryRecord(repositoryId, row?.client_id);
86
87
  });
87
88
  }
89
+ async loadLastBackup(repositoryId) {
90
+ return withReadConnection(this.#state, database => {
91
+ verifyFormat(database, repositoryId);
92
+ const row = getRow(database.prepare("SELECT completed_at, archive_digest FROM repository_backup_state WHERE repository_id = ?"), repositoryId);
93
+ if (row === undefined)
94
+ return null;
95
+ if (!isDigest(row.archive_digest))
96
+ throw new RepositoryStoreError("repository backup record is invalid");
97
+ try {
98
+ validateTimestamp(row.completed_at, "repository backup completion time is invalid");
99
+ }
100
+ catch (error) {
101
+ throw new RepositoryStoreError("repository backup record is invalid", { cause: error });
102
+ }
103
+ return { completed_at: row.completed_at, archive_digest: row.archive_digest };
104
+ });
105
+ }
106
+ async recordLastBackup(repositoryId, archiveDigest) {
107
+ if (!isDigest(archiveDigest))
108
+ throw new RepositoryStoreError("repository backup digest is invalid");
109
+ withWriteConnection(this.#state, database => {
110
+ verifyFormat(database, repositoryId);
111
+ runSql(database.prepare("INSERT INTO repository_backup_state (repository_id, completed_at, archive_digest) VALUES (?, ?, ?) ON CONFLICT(repository_id) DO UPDATE SET completed_at = excluded.completed_at, archive_digest = excluded.archive_digest"), repositoryId, timestamp(), archiveDigest);
112
+ });
113
+ }
88
114
  async loadAuthorPrincipalId(repositoryId) {
89
115
  return withReadConnection(this.#state, database => {
90
116
  verifyFormat(database, repositoryId);
@@ -152,6 +178,17 @@ export class SQLiteRepositoryStore {
152
178
  return loadCommitByOperationId(database, repositoryId, operationId);
153
179
  });
154
180
  }
181
+ /** The node's lifecycle at the local head and every local relationship that still references it. */
182
+ async loadNodePurgeState(repositoryId, nodeId) {
183
+ return withReadConnection(this.#state, database => {
184
+ verifyFormat(database, repositoryId);
185
+ const node = getRow(database.prepare("SELECT lifecycle_state FROM repository_nodes WHERE repository_id = ? AND node_id = ?"), repositoryId, nodeId);
186
+ return {
187
+ lifecycleState: typeof node?.lifecycle_state === "string" ? node.lifecycle_state : null,
188
+ dependencies: structuralDependencies(database, repositoryId, nodeId),
189
+ };
190
+ });
191
+ }
155
192
  async listCommits(repositoryId, atHead, afterCommitId, limit) {
156
193
  return withReadConnection(this.#state, database => {
157
194
  verifyFormat(database, repositoryId);