@knpkv/herdr-fleet 0.4.0 → 0.5.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.
package/README.md CHANGED
@@ -15,6 +15,11 @@ The package exports:
15
15
  - `JobStore`, the local SQLite persistence boundary
16
16
  - `makeFleetService`, the approval and execution state machine
17
17
  - typed validation, storage, approval, authorization, and operation errors
18
+ - `@knpkv/herdr-fleet/sqlite`, the private on-disk database opener for the `node:sqlite` Herdr stores, and the path checks the orchestrator database reuses
19
+
20
+ The `node:sqlite` stores (Fleet jobs, approvals, coordinator chat, Connect activity and relationships, Work) open their database through `openPrivateSqlite` from `@knpkv/herdr-fleet/sqlite`. The state directory and the database, `-wal` and `-shm` files are refused, unchanged, when they are symbolic links, the wrong type, or group/other writable; otherwise the directory is restricted to `0700` (created if missing) and the files to `0600`, and WAL is enabled after the store's schema step. Symlinked ancestors such as macOS `/var` are allowed. `preparePrivateDatabasePath` does the same file-system work for other clients.
21
+
22
+ The coordinator's orchestrator database (`@effect/sql-sqlite-node`) keeps its own, different policy: it requires an existing state directory to be exactly `0700` and refuses it otherwise, refuses symbolic links through `verifyPrivatePathIdentity`, and then sets the files to `0600` with `securePrivateDatabaseFiles`. It does not refuse a group-writable database file; it restricts it.
18
23
 
19
24
  `HostConfiguration.pushAllowedOrigins` is the explicit exact-origin allowlist used by the approval runtime for browser push delivery. It has no implicit defaults; deployment configuration owns the accepted push services.
20
25
 
package/dist/service.d.ts CHANGED
@@ -74,20 +74,11 @@ type Options = {
74
74
  export declare const makeFleetService: (options: Options) => Effect.Effect<{
75
75
  submit: (request: {
76
76
  readonly payload: {
77
- readonly kind: "nix.check";
78
- } | {
79
- readonly kind: "nix.apply";
80
- readonly ref: string;
81
- } | {
82
77
  readonly kind: "agent.delegate";
83
78
  readonly repository: string;
84
79
  readonly prompt: string;
85
80
  readonly mode: "consult" | "review" | "transition_summary" | "work";
86
81
  readonly channel?: "coordinator_chat";
87
- } | {
88
- readonly kind: "agent.message";
89
- readonly session: string;
90
- readonly message: string;
91
82
  } | {
92
83
  readonly kind: "work.reconcile";
93
84
  readonly repository: string;
@@ -214,6 +205,15 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
214
205
  readonly expectedGoalUpdatedAt: number;
215
206
  } | {
216
207
  readonly kind: "browser.mcp.recover";
208
+ } | {
209
+ readonly kind: "nix.check";
210
+ } | {
211
+ readonly kind: "nix.apply";
212
+ readonly ref: string;
213
+ } | {
214
+ readonly kind: "agent.message";
215
+ readonly session: string;
216
+ readonly message: string;
217
217
  };
218
218
  }, actor: string, provenance?: SubmissionProvenance | undefined) => Effect.Effect<{
219
219
  readonly id: string;
@@ -230,20 +230,11 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
230
230
  readonly expiredAt?: number | null;
231
231
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
232
232
  readonly payload: {
233
- readonly kind: "nix.check";
234
- } | {
235
- readonly kind: "nix.apply";
236
- readonly ref: string;
237
- } | {
238
233
  readonly kind: "agent.delegate";
239
234
  readonly repository: string;
240
235
  readonly prompt: string;
241
236
  readonly mode: "consult" | "review" | "transition_summary" | "work";
242
237
  readonly channel?: "coordinator_chat";
243
- } | {
244
- readonly kind: "agent.message";
245
- readonly session: string;
246
- readonly message: string;
247
238
  } | {
248
239
  readonly kind: "work.reconcile";
249
240
  readonly repository: string;
@@ -370,6 +361,15 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
370
361
  readonly expectedGoalUpdatedAt: number;
371
362
  } | {
372
363
  readonly kind: "browser.mcp.recover";
364
+ } | {
365
+ readonly kind: "nix.check";
366
+ } | {
367
+ readonly kind: "nix.apply";
368
+ readonly ref: string;
369
+ } | {
370
+ readonly kind: "agent.message";
371
+ readonly session: string;
372
+ readonly message: string;
373
373
  };
374
374
  readonly result: string | null;
375
375
  readonly acceptedReceipt?: string | null;
@@ -407,20 +407,11 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
407
407
  readonly expiredAt?: number | null;
408
408
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
409
409
  readonly payload: {
410
- readonly kind: "nix.check";
411
- } | {
412
- readonly kind: "nix.apply";
413
- readonly ref: string;
414
- } | {
415
410
  readonly kind: "agent.delegate";
416
411
  readonly repository: string;
417
412
  readonly prompt: string;
418
413
  readonly mode: "consult" | "review" | "transition_summary" | "work";
419
414
  readonly channel?: "coordinator_chat";
420
- } | {
421
- readonly kind: "agent.message";
422
- readonly session: string;
423
- readonly message: string;
424
415
  } | {
425
416
  readonly kind: "work.reconcile";
426
417
  readonly repository: string;
@@ -547,6 +538,15 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
547
538
  readonly expectedGoalUpdatedAt: number;
548
539
  } | {
549
540
  readonly kind: "browser.mcp.recover";
541
+ } | {
542
+ readonly kind: "nix.check";
543
+ } | {
544
+ readonly kind: "nix.apply";
545
+ readonly ref: string;
546
+ } | {
547
+ readonly kind: "agent.message";
548
+ readonly session: string;
549
+ readonly message: string;
550
550
  };
551
551
  readonly result: string | null;
552
552
  readonly acceptedReceipt?: string | null;
@@ -584,20 +584,11 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
584
584
  readonly expiredAt?: number | null;
585
585
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
586
586
  readonly payload: {
587
- readonly kind: "nix.check";
588
- } | {
589
- readonly kind: "nix.apply";
590
- readonly ref: string;
591
- } | {
592
587
  readonly kind: "agent.delegate";
593
588
  readonly repository: string;
594
589
  readonly prompt: string;
595
590
  readonly mode: "consult" | "review" | "transition_summary" | "work";
596
591
  readonly channel?: "coordinator_chat";
597
- } | {
598
- readonly kind: "agent.message";
599
- readonly session: string;
600
- readonly message: string;
601
592
  } | {
602
593
  readonly kind: "work.reconcile";
603
594
  readonly repository: string;
@@ -724,6 +715,15 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
724
715
  readonly expectedGoalUpdatedAt: number;
725
716
  } | {
726
717
  readonly kind: "browser.mcp.recover";
718
+ } | {
719
+ readonly kind: "nix.check";
720
+ } | {
721
+ readonly kind: "nix.apply";
722
+ readonly ref: string;
723
+ } | {
724
+ readonly kind: "agent.message";
725
+ readonly session: string;
726
+ readonly message: string;
727
727
  };
728
728
  readonly result: string | null;
729
729
  readonly acceptedReceipt?: string | null;
@@ -761,20 +761,11 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
761
761
  readonly expiredAt?: number | null;
762
762
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
763
763
  readonly payload: {
764
- readonly kind: "nix.check";
765
- } | {
766
- readonly kind: "nix.apply";
767
- readonly ref: string;
768
- } | {
769
764
  readonly kind: "agent.delegate";
770
765
  readonly repository: string;
771
766
  readonly prompt: string;
772
767
  readonly mode: "consult" | "review" | "transition_summary" | "work";
773
768
  readonly channel?: "coordinator_chat";
774
- } | {
775
- readonly kind: "agent.message";
776
- readonly session: string;
777
- readonly message: string;
778
769
  } | {
779
770
  readonly kind: "work.reconcile";
780
771
  readonly repository: string;
@@ -901,6 +892,15 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
901
892
  readonly expectedGoalUpdatedAt: number;
902
893
  } | {
903
894
  readonly kind: "browser.mcp.recover";
895
+ } | {
896
+ readonly kind: "nix.check";
897
+ } | {
898
+ readonly kind: "nix.apply";
899
+ readonly ref: string;
900
+ } | {
901
+ readonly kind: "agent.message";
902
+ readonly session: string;
903
+ readonly message: string;
904
904
  };
905
905
  readonly result: string | null;
906
906
  readonly acceptedReceipt?: string | null;
@@ -938,20 +938,11 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
938
938
  readonly expiredAt?: number | null;
939
939
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
940
940
  readonly payload: {
941
- readonly kind: "nix.check";
942
- } | {
943
- readonly kind: "nix.apply";
944
- readonly ref: string;
945
- } | {
946
941
  readonly kind: "agent.delegate";
947
942
  readonly repository: string;
948
943
  readonly prompt: string;
949
944
  readonly mode: "consult" | "review" | "transition_summary" | "work";
950
945
  readonly channel?: "coordinator_chat";
951
- } | {
952
- readonly kind: "agent.message";
953
- readonly session: string;
954
- readonly message: string;
955
946
  } | {
956
947
  readonly kind: "work.reconcile";
957
948
  readonly repository: string;
@@ -1078,6 +1069,15 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
1078
1069
  readonly expectedGoalUpdatedAt: number;
1079
1070
  } | {
1080
1071
  readonly kind: "browser.mcp.recover";
1072
+ } | {
1073
+ readonly kind: "nix.check";
1074
+ } | {
1075
+ readonly kind: "nix.apply";
1076
+ readonly ref: string;
1077
+ } | {
1078
+ readonly kind: "agent.message";
1079
+ readonly session: string;
1080
+ readonly message: string;
1081
1081
  };
1082
1082
  readonly result: string | null;
1083
1083
  readonly acceptedReceipt?: string | null;
@@ -1115,20 +1115,11 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
1115
1115
  readonly expiredAt?: number | null;
1116
1116
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
1117
1117
  readonly payload: {
1118
- readonly kind: "nix.check";
1119
- } | {
1120
- readonly kind: "nix.apply";
1121
- readonly ref: string;
1122
- } | {
1123
1118
  readonly kind: "agent.delegate";
1124
1119
  readonly repository: string;
1125
1120
  readonly prompt: string;
1126
1121
  readonly mode: "consult" | "review" | "transition_summary" | "work";
1127
1122
  readonly channel?: "coordinator_chat";
1128
- } | {
1129
- readonly kind: "agent.message";
1130
- readonly session: string;
1131
- readonly message: string;
1132
1123
  } | {
1133
1124
  readonly kind: "work.reconcile";
1134
1125
  readonly repository: string;
@@ -1255,6 +1246,15 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
1255
1246
  readonly expectedGoalUpdatedAt: number;
1256
1247
  } | {
1257
1248
  readonly kind: "browser.mcp.recover";
1249
+ } | {
1250
+ readonly kind: "nix.check";
1251
+ } | {
1252
+ readonly kind: "nix.apply";
1253
+ readonly ref: string;
1254
+ } | {
1255
+ readonly kind: "agent.message";
1256
+ readonly session: string;
1257
+ readonly message: string;
1258
1258
  };
1259
1259
  readonly result: string | null;
1260
1260
  readonly acceptedReceipt?: string | null;
@@ -1292,20 +1292,11 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
1292
1292
  readonly expiredAt?: number | null;
1293
1293
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
1294
1294
  readonly payload: {
1295
- readonly kind: "nix.check";
1296
- } | {
1297
- readonly kind: "nix.apply";
1298
- readonly ref: string;
1299
- } | {
1300
1295
  readonly kind: "agent.delegate";
1301
1296
  readonly repository: string;
1302
1297
  readonly prompt: string;
1303
1298
  readonly mode: "consult" | "review" | "transition_summary" | "work";
1304
1299
  readonly channel?: "coordinator_chat";
1305
- } | {
1306
- readonly kind: "agent.message";
1307
- readonly session: string;
1308
- readonly message: string;
1309
1300
  } | {
1310
1301
  readonly kind: "work.reconcile";
1311
1302
  readonly repository: string;
@@ -1432,6 +1423,15 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
1432
1423
  readonly expectedGoalUpdatedAt: number;
1433
1424
  } | {
1434
1425
  readonly kind: "browser.mcp.recover";
1426
+ } | {
1427
+ readonly kind: "nix.check";
1428
+ } | {
1429
+ readonly kind: "nix.apply";
1430
+ readonly ref: string;
1431
+ } | {
1432
+ readonly kind: "agent.message";
1433
+ readonly session: string;
1434
+ readonly message: string;
1435
1435
  };
1436
1436
  readonly result: string | null;
1437
1437
  readonly acceptedReceipt?: string | null;
@@ -1472,20 +1472,11 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
1472
1472
  readonly expiredAt?: number | null;
1473
1473
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
1474
1474
  readonly payload: {
1475
- readonly kind: "nix.check";
1476
- } | {
1477
- readonly kind: "nix.apply";
1478
- readonly ref: string;
1479
- } | {
1480
1475
  readonly kind: "agent.delegate";
1481
1476
  readonly repository: string;
1482
1477
  readonly prompt: string;
1483
1478
  readonly mode: "consult" | "review" | "transition_summary" | "work";
1484
1479
  readonly channel?: "coordinator_chat";
1485
- } | {
1486
- readonly kind: "agent.message";
1487
- readonly session: string;
1488
- readonly message: string;
1489
1480
  } | {
1490
1481
  readonly kind: "work.reconcile";
1491
1482
  readonly repository: string;
@@ -1612,6 +1603,15 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
1612
1603
  readonly expectedGoalUpdatedAt: number;
1613
1604
  } | {
1614
1605
  readonly kind: "browser.mcp.recover";
1606
+ } | {
1607
+ readonly kind: "nix.check";
1608
+ } | {
1609
+ readonly kind: "nix.apply";
1610
+ readonly ref: string;
1611
+ } | {
1612
+ readonly kind: "agent.message";
1613
+ readonly session: string;
1614
+ readonly message: string;
1615
1615
  };
1616
1616
  readonly result: string | null;
1617
1617
  readonly acceptedReceipt?: string | null;
@@ -1653,20 +1653,11 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
1653
1653
  readonly expiredAt?: number | null;
1654
1654
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
1655
1655
  readonly payload: {
1656
- readonly kind: "nix.check";
1657
- } | {
1658
- readonly kind: "nix.apply";
1659
- readonly ref: string;
1660
- } | {
1661
1656
  readonly kind: "agent.delegate";
1662
1657
  readonly repository: string;
1663
1658
  readonly prompt: string;
1664
1659
  readonly mode: "consult" | "review" | "transition_summary" | "work";
1665
1660
  readonly channel?: "coordinator_chat";
1666
- } | {
1667
- readonly kind: "agent.message";
1668
- readonly session: string;
1669
- readonly message: string;
1670
1661
  } | {
1671
1662
  readonly kind: "work.reconcile";
1672
1663
  readonly repository: string;
@@ -1793,6 +1784,15 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
1793
1784
  readonly expectedGoalUpdatedAt: number;
1794
1785
  } | {
1795
1786
  readonly kind: "browser.mcp.recover";
1787
+ } | {
1788
+ readonly kind: "nix.check";
1789
+ } | {
1790
+ readonly kind: "nix.apply";
1791
+ readonly ref: string;
1792
+ } | {
1793
+ readonly kind: "agent.message";
1794
+ readonly session: string;
1795
+ readonly message: string;
1796
1796
  };
1797
1797
  readonly result: string | null;
1798
1798
  readonly acceptedReceipt?: string | null;
@@ -1839,20 +1839,11 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
1839
1839
  readonly expiredAt?: number | null;
1840
1840
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
1841
1841
  readonly payload: {
1842
- readonly kind: "nix.check";
1843
- } | {
1844
- readonly kind: "nix.apply";
1845
- readonly ref: string;
1846
- } | {
1847
1842
  readonly kind: "agent.delegate";
1848
1843
  readonly repository: string;
1849
1844
  readonly prompt: string;
1850
1845
  readonly mode: "consult" | "review" | "transition_summary" | "work";
1851
1846
  readonly channel?: "coordinator_chat";
1852
- } | {
1853
- readonly kind: "agent.message";
1854
- readonly session: string;
1855
- readonly message: string;
1856
1847
  } | {
1857
1848
  readonly kind: "work.reconcile";
1858
1849
  readonly repository: string;
@@ -1979,6 +1970,15 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
1979
1970
  readonly expectedGoalUpdatedAt: number;
1980
1971
  } | {
1981
1972
  readonly kind: "browser.mcp.recover";
1973
+ } | {
1974
+ readonly kind: "nix.check";
1975
+ } | {
1976
+ readonly kind: "nix.apply";
1977
+ readonly ref: string;
1978
+ } | {
1979
+ readonly kind: "agent.message";
1980
+ readonly session: string;
1981
+ readonly message: string;
1982
1982
  };
1983
1983
  readonly result: string | null;
1984
1984
  readonly acceptedReceipt?: string | null;
@@ -2021,20 +2021,11 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
2021
2021
  readonly expiredAt?: number | null;
2022
2022
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
2023
2023
  readonly payload: {
2024
- readonly kind: "nix.check";
2025
- } | {
2026
- readonly kind: "nix.apply";
2027
- readonly ref: string;
2028
- } | {
2029
2024
  readonly kind: "agent.delegate";
2030
2025
  readonly repository: string;
2031
2026
  readonly prompt: string;
2032
2027
  readonly mode: "consult" | "review" | "transition_summary" | "work";
2033
2028
  readonly channel?: "coordinator_chat";
2034
- } | {
2035
- readonly kind: "agent.message";
2036
- readonly session: string;
2037
- readonly message: string;
2038
2029
  } | {
2039
2030
  readonly kind: "work.reconcile";
2040
2031
  readonly repository: string;
@@ -2161,6 +2152,15 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
2161
2152
  readonly expectedGoalUpdatedAt: number;
2162
2153
  } | {
2163
2154
  readonly kind: "browser.mcp.recover";
2155
+ } | {
2156
+ readonly kind: "nix.check";
2157
+ } | {
2158
+ readonly kind: "nix.apply";
2159
+ readonly ref: string;
2160
+ } | {
2161
+ readonly kind: "agent.message";
2162
+ readonly session: string;
2163
+ readonly message: string;
2164
2164
  };
2165
2165
  readonly result: string | null;
2166
2166
  readonly acceptedReceipt?: string | null;
@@ -2250,20 +2250,11 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
2250
2250
  readonly expiredAt?: number | null;
2251
2251
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
2252
2252
  readonly payload: {
2253
- readonly kind: "nix.check";
2254
- } | {
2255
- readonly kind: "nix.apply";
2256
- readonly ref: string;
2257
- } | {
2258
2253
  readonly kind: "agent.delegate";
2259
2254
  readonly repository: string;
2260
2255
  readonly prompt: string;
2261
2256
  readonly mode: "consult" | "review" | "transition_summary" | "work";
2262
2257
  readonly channel?: "coordinator_chat";
2263
- } | {
2264
- readonly kind: "agent.message";
2265
- readonly session: string;
2266
- readonly message: string;
2267
2258
  } | {
2268
2259
  readonly kind: "work.reconcile";
2269
2260
  readonly repository: string;
@@ -2390,6 +2381,15 @@ export declare const makeFleetService: (options: Options) => Effect.Effect<{
2390
2381
  readonly expectedGoalUpdatedAt: number;
2391
2382
  } | {
2392
2383
  readonly kind: "browser.mcp.recover";
2384
+ } | {
2385
+ readonly kind: "nix.check";
2386
+ } | {
2387
+ readonly kind: "nix.apply";
2388
+ readonly ref: string;
2389
+ } | {
2390
+ readonly kind: "agent.message";
2391
+ readonly session: string;
2392
+ readonly message: string;
2393
2393
  };
2394
2394
  readonly result: string | null;
2395
2395
  readonly acceptedReceipt?: string | null;
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Private on-disk SQLite databases for Herdr stores.
3
+ *
4
+ * **Mental model**
5
+ *
6
+ * - **Refuse, never repair.** A state directory or database file that other users
7
+ * could write is refused, and left exactly as found. Repairing it would hide that
8
+ * someone could already have changed it.
9
+ * - **Owner-only once accepted.** The state directory ends `0700` and the database
10
+ * files `0600`; an existing directory is checked before it is restricted, so a
11
+ * writable one is refused rather than quietly fixed.
12
+ * - **Only the last path component is checked for a symlink.** Symlinked ancestors
13
+ * (macOS `/var`, a Nix-managed home) are normal and allowed; a database or state
14
+ * directory that is itself a link is refused.
15
+ * - **Two layers.** {@link preparePrivateDatabasePath} and
16
+ * {@link securePrivateDatabaseFiles} only touch the file system, so any SQLite
17
+ * client can use them; {@link openPrivateSqlite} adds the `node:sqlite` connection.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * const opened = yield* openPrivateSqlite(path, {
22
+ * initialize: (database) => database.exec("CREATE TABLE IF NOT EXISTS jobs (id TEXT PRIMARY KEY)")
23
+ * })
24
+ * // after each write, WAL may have created -wal/-shm:
25
+ * yield* opened.secureFiles
26
+ * ```
27
+ *
28
+ * @module
29
+ */
30
+ import { Effect, FileSystem, Path, Schema } from "effect";
31
+ import { DatabaseSync } from "node:sqlite";
32
+ declare const PrivateDatabaseError_base: Schema.Class<PrivateDatabaseError, Schema.TaggedStruct<"PrivateDatabaseError", {
33
+ readonly operation: Schema.String;
34
+ readonly cause: Schema.Defect;
35
+ }>, import("effect/Cause").YieldableError>;
36
+ /** One step of opening or securing a private database failed; `operation` names the step. */
37
+ export declare class PrivateDatabaseError extends PrivateDatabaseError_base {
38
+ }
39
+ /**
40
+ * Refuse `path` if it is itself a symlink or does not resolve to its real parent
41
+ * joined with its name; a missing component is checked through its parent.
42
+ * Failures carry `operation` (sub-steps append `.readlink`, `.exists`, …).
43
+ */
44
+ export declare const verifyPrivatePathIdentity: (path: string, operation: string) => Effect.Effect<void, PrivateDatabaseError, FileSystem.FileSystem | Path.Path>;
45
+ /**
46
+ * Make `path`'s directory and any existing database files safe to open, or refuse.
47
+ *
48
+ * Refuses a directory or file that is a symlink, the wrong type, or group/other
49
+ * writable, without changing it. Otherwise restricts the directory (created if
50
+ * missing) to `0700` and existing db/-wal/-shm files to `0600`.
51
+ */
52
+ export declare const preparePrivateDatabasePath: (path: string) => Effect.Effect<undefined, PrivateDatabaseError, FileSystem.FileSystem | Path.Path>;
53
+ /**
54
+ * Set the database file and its `-wal`/`-shm` siblings, whichever exist, to `0600`.
55
+ *
56
+ * SQLite creates the siblings lazily, so call this after writes as well as after
57
+ * opening. A sibling that has become a symlink is refused rather than followed.
58
+ */
59
+ export declare const securePrivateDatabaseFiles: (path: string) => Effect.Effect<void, PrivateDatabaseError, FileSystem.FileSystem | Path.Path>;
60
+ /** An open `node:sqlite` connection to a private database. */
61
+ export interface PrivateSqlite {
62
+ readonly database: DatabaseSync;
63
+ /** {@link securePrivateDatabaseFiles} for this database; run after writes. */
64
+ readonly secureFiles: Effect.Effect<void, PrivateDatabaseError>;
65
+ }
66
+ export interface OpenPrivateSqliteOptions {
67
+ /**
68
+ * Creates or migrates the schema; a throw closes the connection. Runs before WAL
69
+ * is enabled, so a legacy rollback-journal database migrates in its own mode first
70
+ * (Work's legacy authority-table migration fails with "database is locked" otherwise).
71
+ */
72
+ readonly initialize: (database: DatabaseSync) => void;
73
+ /** Wait up to this long for another connection's lock instead of failing at once. */
74
+ readonly busyTimeoutMillis?: number;
75
+ }
76
+ /**
77
+ * Prepare `path` (see {@link preparePrivateDatabasePath}), open it in WAL mode,
78
+ * initialize the schema and secure the files. The caller owns the returned
79
+ * connection and must close it.
80
+ */
81
+ export declare const openPrivateSqlite: (path: string, options: OpenPrivateSqliteOptions) => Effect.Effect<{
82
+ database: DatabaseSync;
83
+ secureFiles: Effect.Effect<void, PrivateDatabaseError, never>;
84
+ }, PrivateDatabaseError, FileSystem.FileSystem | Path.Path>;
85
+ export {};
86
+ //# sourceMappingURL=sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;;;;;AAE1C,6FAA6F;AAC7F,qBAAa,oBAAqB,SAAQ,yBAMzC;CAAG;AA2CJ;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,mHAOpC,CAAA;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,qGAwCrC,CAAA;AAEF;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,gGAcrC,CAAA;AAEF,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAA;IAC/B,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAA;CAChE;AAED,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAA;IACrD,qFAAqF;IACrF,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;CACpC;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;2DA8B5B,CAAA"}
package/dist/sqlite.js ADDED
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Private on-disk SQLite databases for Herdr stores.
3
+ *
4
+ * **Mental model**
5
+ *
6
+ * - **Refuse, never repair.** A state directory or database file that other users
7
+ * could write is refused, and left exactly as found. Repairing it would hide that
8
+ * someone could already have changed it.
9
+ * - **Owner-only once accepted.** The state directory ends `0700` and the database
10
+ * files `0600`; an existing directory is checked before it is restricted, so a
11
+ * writable one is refused rather than quietly fixed.
12
+ * - **Only the last path component is checked for a symlink.** Symlinked ancestors
13
+ * (macOS `/var`, a Nix-managed home) are normal and allowed; a database or state
14
+ * directory that is itself a link is refused.
15
+ * - **Two layers.** {@link preparePrivateDatabasePath} and
16
+ * {@link securePrivateDatabaseFiles} only touch the file system, so any SQLite
17
+ * client can use them; {@link openPrivateSqlite} adds the `node:sqlite` connection.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * const opened = yield* openPrivateSqlite(path, {
22
+ * initialize: (database) => database.exec("CREATE TABLE IF NOT EXISTS jobs (id TEXT PRIMARY KEY)")
23
+ * })
24
+ * // after each write, WAL may have created -wal/-shm:
25
+ * yield* opened.secureFiles
26
+ * ```
27
+ *
28
+ * @module
29
+ */
30
+ import { Effect, FileSystem, Path, Schema } from "effect";
31
+ import { DatabaseSync } from "node:sqlite";
32
+ /** One step of opening or securing a private database failed; `operation` names the step. */
33
+ export class PrivateDatabaseError extends Schema.TaggedError()("PrivateDatabaseError", {
34
+ operation: Schema.String,
35
+ cause: Schema.Defect()
36
+ }) {
37
+ }
38
+ const failWith = (operation) => (cause) => new PrivateDatabaseError({ operation, cause });
39
+ const groupOrOtherWritable = (paths, mode) => paths.sep === "/" && (mode & 0o022) !== 0;
40
+ const databaseFiles = (path) => [path, `${path}-wal`, `${path}-shm`];
41
+ // Refuses `path` when it is itself a symlink — including a dangling one — or when
42
+ // its real path is not its real parent joined with its name. A component that does
43
+ // not exist yet is checked through its parent.
44
+ const verifyPathIdentity = (path, fileSystem, paths, operation) => fileSystem.readLink(path).pipe(Effect.matchEffect({
45
+ onFailure: (cause) => cause.reason._tag === "NotFound" || cause.reason._tag === "Unknown"
46
+ ? Effect.void
47
+ : Effect.fail(new PrivateDatabaseError({ cause, operation: `${operation}.readlink` })),
48
+ onSuccess: (target) => Effect.fail(new PrivateDatabaseError({ cause: { path, target }, operation }))
49
+ }), Effect.andThen(fileSystem.exists(path).pipe(Effect.mapError(failWith(`${operation}.exists`)))), Effect.flatMap((exists) => {
50
+ const parent = paths.dirname(path);
51
+ if (!exists) {
52
+ return parent === path ? Effect.void : verifyPathIdentity(parent, fileSystem, paths, operation);
53
+ }
54
+ return Effect.all({
55
+ realPath: fileSystem.realPath(path).pipe(Effect.mapError(failWith(`${operation}.realpath`))),
56
+ realParentPath: fileSystem.realPath(parent).pipe(Effect.mapError(failWith(`${operation}.parent-realpath`)))
57
+ }).pipe(Effect.flatMap(({ realParentPath, realPath }) => {
58
+ const expectedPath = paths.join(realParentPath, paths.basename(path));
59
+ return realPath === expectedPath
60
+ ? Effect.void
61
+ : Effect.fail(new PrivateDatabaseError({ cause: { expectedPath, path, realPath }, operation }));
62
+ }));
63
+ }));
64
+ /**
65
+ * Refuse `path` if it is itself a symlink or does not resolve to its real parent
66
+ * joined with its name; a missing component is checked through its parent.
67
+ * Failures carry `operation` (sub-steps append `.readlink`, `.exists`, …).
68
+ */
69
+ export const verifyPrivatePathIdentity = Effect.fn("PrivateDatabase.verifyPathIdentity")(function* (path, operation) {
70
+ const fileSystem = yield* FileSystem.FileSystem;
71
+ const paths = yield* Path.Path;
72
+ yield* verifyPathIdentity(path, fileSystem, paths, operation);
73
+ });
74
+ /**
75
+ * Make `path`'s directory and any existing database files safe to open, or refuse.
76
+ *
77
+ * Refuses a directory or file that is a symlink, the wrong type, or group/other
78
+ * writable, without changing it. Otherwise restricts the directory (created if
79
+ * missing) to `0700` and existing db/-wal/-shm files to `0600`.
80
+ */
81
+ export const preparePrivateDatabasePath = Effect.fn("PrivateDatabase.prepare")(function* (path) {
82
+ const fileSystem = yield* FileSystem.FileSystem;
83
+ const paths = yield* Path.Path;
84
+ const directory = paths.dirname(path);
85
+ yield* fileSystem.makeDirectory(directory, { recursive: true, mode: 0o700 }).pipe(Effect.mapError(failWith("open.directory")));
86
+ const directoryInfo = yield* fileSystem.stat(directory).pipe(Effect.mapError(failWith("open.directory.stat")));
87
+ if (directoryInfo.type !== "Directory" || groupOrOtherWritable(paths, directoryInfo.mode)) {
88
+ return yield* new PrivateDatabaseError({
89
+ cause: { directory, mode: directoryInfo.mode, type: directoryInfo.type },
90
+ operation: "open.directory.unsafe"
91
+ });
92
+ }
93
+ yield* verifyPathIdentity(directory, fileSystem, paths, "open.directory.path-identity");
94
+ yield* fileSystem.chmod(directory, 0o700).pipe(Effect.mapError(failWith("open.secureDirectory")));
95
+ yield* Effect.forEach(databaseFiles(path), (file) => verifyPathIdentity(file, fileSystem, paths, "open.path-identity").pipe(Effect.andThen(fileSystem.exists(file).pipe(Effect.mapError(failWith("open.file.exists")))), Effect.flatMap((exists) => {
96
+ if (!exists)
97
+ return Effect.void;
98
+ return fileSystem.stat(file).pipe(Effect.mapError(failWith("open.file.stat")), Effect.flatMap((info) => info.type !== "File" || groupOrOtherWritable(paths, info.mode)
99
+ ? Effect.fail(new PrivateDatabaseError({
100
+ cause: { file, mode: info.mode, type: info.type },
101
+ operation: "open.file.unsafe"
102
+ }))
103
+ : fileSystem.chmod(file, 0o600).pipe(Effect.mapError(failWith("open.file.secure")))));
104
+ })), { discard: true });
105
+ });
106
+ /**
107
+ * Set the database file and its `-wal`/`-shm` siblings, whichever exist, to `0600`.
108
+ *
109
+ * SQLite creates the siblings lazily, so call this after writes as well as after
110
+ * opening. A sibling that has become a symlink is refused rather than followed.
111
+ */
112
+ export const securePrivateDatabaseFiles = Effect.fn("PrivateDatabase.secureFiles")(function* (path) {
113
+ const fileSystem = yield* FileSystem.FileSystem;
114
+ const paths = yield* Path.Path;
115
+ yield* Effect.forEach(databaseFiles(path), (file) => verifyPathIdentity(file, fileSystem, paths, "secure.path-identity").pipe(Effect.andThen(fileSystem.exists(file).pipe(Effect.mapError(failWith("secure.exists")))), Effect.flatMap((exists) => exists ? fileSystem.chmod(file, 0o600).pipe(Effect.mapError(failWith("secure.chmod"))) : Effect.void)), { discard: true });
116
+ });
117
+ /**
118
+ * Prepare `path` (see {@link preparePrivateDatabasePath}), open it in WAL mode,
119
+ * initialize the schema and secure the files. The caller owns the returned
120
+ * connection and must close it.
121
+ */
122
+ export const openPrivateSqlite = Effect.fn("PrivateDatabase.openSqlite")(function* (path, options) {
123
+ const fileSystem = yield* FileSystem.FileSystem;
124
+ const paths = yield* Path.Path;
125
+ yield* preparePrivateDatabasePath(path);
126
+ const database = yield* Effect.try({
127
+ try: () => {
128
+ const database = new DatabaseSync(path);
129
+ try {
130
+ if (options.busyTimeoutMillis !== undefined) {
131
+ database.exec(`PRAGMA busy_timeout = ${options.busyTimeoutMillis}`);
132
+ }
133
+ options.initialize(database);
134
+ database.exec("PRAGMA journal_mode = WAL");
135
+ return database;
136
+ }
137
+ catch (error) {
138
+ database.close();
139
+ throw error;
140
+ }
141
+ },
142
+ catch: failWith("open.database")
143
+ });
144
+ const secureFiles = securePrivateDatabaseFiles(path).pipe(Effect.provideService(FileSystem.FileSystem, fileSystem), Effect.provideService(Path.Path, paths));
145
+ yield* secureFiles.pipe(Effect.onError(() => Effect.sync(() => database.close())));
146
+ return { database, secureFiles };
147
+ });
148
+ //# sourceMappingURL=sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"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"}
package/dist/store.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { Effect, FileSystem, Path } from "effect";
1
+ import { Effect } from "effect";
2
2
  import { FleetJobConflictError, FleetStoreError, FleetTransitionConflictError } from "./errors.js";
3
3
  export declare class JobStore {
4
4
  #private;
5
5
  readonly path: string;
6
6
  private constructor();
7
- static readonly open: (path: string) => Effect.Effect<JobStore, FleetStoreError, FileSystem.FileSystem | Path.Path>;
7
+ static readonly open: (path: string) => Effect.Effect<JobStore, FleetStoreError, import("effect/FileSystem").FileSystem | import("effect/Path").Path>;
8
8
  readonly put: (this: JobStore, record: {
9
9
  readonly id: string;
10
10
  readonly createdAt: number;
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
package/dist/store.js CHANGED
@@ -1,8 +1,9 @@
1
- import { Effect, FileSystem, Path, Schema } from "effect";
2
- import { DatabaseSync } from "node:sqlite";
1
+ import { Effect, Schema } from "effect";
3
2
  import { FleetJobConflictError, FleetStoreError, FleetTransitionConflictError } from "./errors.js";
4
3
  import { JobRecord } from "./model.js";
4
+ import { openPrivateSqlite } from "./sqlite.js";
5
5
  const storeError = (operation) => (cause) => new FleetStoreError({ operation, detail: String(cause), cause });
6
+ const fromPrivateDatabaseError = (error) => new FleetStoreError({ operation: error.operation, detail: String(error.cause), cause: error.cause });
6
7
  const decodeRecord = (text) => Effect.try({
7
8
  try: () => Schema.decodeUnknownSync(JobRecord)(JSON.parse(text)),
8
9
  catch: storeError("decode")
@@ -11,45 +12,30 @@ const encodeRecord = (record) => JSON.stringify(Schema.encodeSync(JobRecord)(rec
11
12
  const decodeRows = (operation, rows) => Effect.forEach(rows, (row) => Schema.decodeUnknownEffect(Schema.Struct({ record: Schema.String }))(row).pipe(Effect.mapError(storeError(operation)), Effect.flatMap(({ record }) => decodeRecord(record))));
12
13
  export class JobStore {
13
14
  #database;
14
- #fileSystem;
15
+ #secureFiles;
15
16
  path;
16
- constructor(path, fileSystem) {
17
+ constructor(path, opened) {
17
18
  this.path = path;
18
- this.#fileSystem = fileSystem;
19
- this.#database = new DatabaseSync(path);
20
- try {
21
- this.#database.exec(`
22
- PRAGMA journal_mode = WAL;
23
- CREATE TABLE IF NOT EXISTS jobs (
24
- id TEXT PRIMARY KEY,
25
- created_at INTEGER NOT NULL,
26
- record TEXT NOT NULL
27
- );
28
- CREATE INDEX IF NOT EXISTS jobs_record_status_idx ON jobs (
29
- CASE
30
- WHEN json_valid(record)
31
- THEN json_extract(record, '$.status')
32
- END
33
- );
34
- `);
35
- }
36
- catch (error) {
37
- this.#database.close();
38
- throw error;
39
- }
19
+ this.#database = opened.database;
20
+ this.#secureFiles = opened.secureFiles.pipe(Effect.mapError(fromPrivateDatabaseError));
40
21
  }
41
22
  static open = Effect.fn("JobStore.open")(function* (path) {
42
- const fileSystem = yield* FileSystem.FileSystem;
43
- const paths = yield* Path.Path;
44
- const directory = paths.dirname(path);
45
- yield* fileSystem.makeDirectory(directory, { recursive: true, mode: 0o700 }).pipe(Effect.mapError(storeError("open.makeDirectory")));
46
- yield* fileSystem.chmod(directory, 0o700).pipe(Effect.mapError(storeError("open.secureDirectory")));
47
- const store = yield* Effect.try({
48
- try: () => new JobStore(path, fileSystem),
49
- catch: storeError("open.database")
50
- });
51
- yield* store.secureFiles();
52
- return store;
23
+ const opened = yield* openPrivateSqlite(path, {
24
+ initialize: (database) => database.exec(`
25
+ CREATE TABLE IF NOT EXISTS jobs (
26
+ id TEXT PRIMARY KEY,
27
+ created_at INTEGER NOT NULL,
28
+ record TEXT NOT NULL
29
+ );
30
+ CREATE INDEX IF NOT EXISTS jobs_record_status_idx ON jobs (
31
+ CASE
32
+ WHEN json_valid(record)
33
+ THEN json_extract(record, '$.status')
34
+ END
35
+ );
36
+ `)
37
+ }).pipe(Effect.mapError(fromPrivateDatabaseError));
38
+ return new JobStore(path, opened);
53
39
  });
54
40
  put = Effect.fn("JobStore.put")(function* (record) {
55
41
  const database = this.#database;
@@ -196,11 +182,7 @@ export class JobStore {
196
182
  return yield* decodeRows("listWorkers", rows);
197
183
  });
198
184
  secureFiles() {
199
- const fileSystem = this.#fileSystem;
200
- const files = [this.path, `${this.path}-wal`, `${this.path}-shm`];
201
- return Effect.forEach(files, (path) => fileSystem.exists(path).pipe(Effect.mapError(storeError("secure.exists")), Effect.flatMap((exists) => exists
202
- ? fileSystem.chmod(path, 0o600).pipe(Effect.mapError(storeError("secure.chmod")))
203
- : Effect.void)), { discard: true });
185
+ return this.#secureFiles;
204
186
  }
205
187
  close() {
206
188
  this.#database.close();
package/dist/store.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knpkv/herdr-fleet",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Typed job protocol and local authority runtime for Herdr fleets",
5
5
  "license": "MIT",
6
6
  "author": "knpkv",
@@ -25,6 +25,10 @@
25
25
  "./response": {
26
26
  "types": "./dist/response.d.ts",
27
27
  "import": "./dist/response.js"
28
+ },
29
+ "./sqlite": {
30
+ "types": "./dist/sqlite.d.ts",
31
+ "import": "./dist/sqlite.js"
28
32
  }
29
33
  },
30
34
  "files": [