@knpkv/herdr-fleet 0.4.0 → 0.5.1

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
 
@@ -1 +1 @@
1
- {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAa,MAAM,EAAU,MAAM,QAAQ,CAAA;AAC1D,OAAO,KAAK,KAAK,kBAAkB,MAAM,gCAAgC,CAAA;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAGpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AASvD,eAAO,MAAM,mBAAmB,+HAqC9B,CAAA;AAEF,eAAO,MAAM,yBAAyB,GAAmD,CAAC,wLAgBxF,CAAA"}
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAa,MAAM,EAAE,MAAM,QAAQ,CAAA;AAClD,OAAO,KAAK,KAAK,kBAAkB,MAAM,gCAAgC,CAAA;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAGpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAEvD,eAAO,MAAM,mBAAmB,+HAqB9B,CAAA;AAEF,eAAO,MAAM,yBAAyB,GAAmD,CAAC,wLAgBxF,CAAA"}
package/dist/response.js CHANGED
@@ -1,31 +1,21 @@
1
- import { Effect, Predicate, Schema, Stream } from "effect";
1
+ import { collectBounded } from "@knpkv/bounded-io";
2
+ import { Effect, Predicate, Schema } from "effect";
2
3
  import { FleetResponseBodyError } from "./errors.js";
3
4
  import { fleetResponseBodyMaxBytes } from "./limits.js";
4
5
  export { fleetResponseBodyMaxBytes } from "./limits.js";
5
- const emptyResponseBody = () => ({ bytes: 0, chunks: [] });
6
6
  export const boundedResponseText = Effect.fn("FleetResponse.boundedText")(function* (response, maximumBytes = fleetResponseBodyMaxBytes) {
7
- const collected = yield* response.stream.pipe(Stream.runFoldEffect(emptyResponseBody, (state, chunk) => {
8
- const bytes = state.bytes + chunk.byteLength;
9
- return bytes > maximumBytes
10
- ? Effect.fail(new FleetResponseBodyError({
11
- cause: bytes,
12
- detail: `response body exceeded ${maximumBytes} bytes`,
13
- reason: "too_large"
14
- }))
15
- : Effect.succeed({ bytes, chunks: [...state.chunks, chunk] });
16
- }), Effect.mapError((cause) => Predicate.isTagged(cause, "FleetResponseBodyError")
17
- ? cause
7
+ // A whole-body decode, as before: a truncated trailing sequence becomes U+FFFD.
8
+ const body = yield* collectBounded(response.stream, maximumBytes).pipe(Effect.mapError((cause) => Predicate.isTagged(cause, "ByteLimitExceeded")
9
+ ? new FleetResponseBodyError({
10
+ cause: cause.observedBytes,
11
+ detail: `response body exceeded ${maximumBytes} bytes`,
12
+ reason: "too_large"
13
+ })
18
14
  : new FleetResponseBodyError({
19
15
  cause,
20
16
  detail: String(cause),
21
17
  reason: "transport"
22
18
  })));
23
- const body = new Uint8Array(collected.bytes);
24
- let offset = 0;
25
- for (const chunk of collected.chunks) {
26
- body.set(chunk, offset);
27
- offset += chunk.byteLength;
28
- }
29
19
  return new TextDecoder().decode(body);
30
20
  });
31
21
  export const decodeBoundedResponseJson = Effect.fn("FleetResponse.decodeJson")(function* (response, schema, maximumBytes = fleetResponseBodyMaxBytes) {
@@ -1 +1 @@
1
- {"version":3,"file":"response.js","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAEvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAOvD,MAAM,iBAAiB,GAAG,GAAsB,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAA;AAE7E,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,EAAE,CAAC,2BAA2B,CAAC,CAAC,QAAQ,CAAC,EACjF,QAA+C,EAC/C,YAAY,GAAG,yBAAyB;IAExC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAC3C,MAAM,CAAC,aAAa,CAClB,iBAAiB,EACjB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACf,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,UAAU,CAAA;QAC5C,OAAO,KAAK,GAAG,YAAY;YACzB,CAAC,CAAC,MAAM,CAAC,IAAI,CACX,IAAI,sBAAsB,CAAC;gBACzB,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,0BAA0B,YAAY,QAAQ;gBACtD,MAAM,EAAE,WAAW;aACpB,CAAC,CACH;YACD,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,CAAA;IACjE,CAAC,CACF,EACD,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CACxB,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,wBAAwB,CAAC;QACjD,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,IAAI,sBAAsB,CAAC;YAC3B,KAAK;YACL,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC;YACrB,MAAM,EAAE,WAAW;SACpB,CAAC,CACL,CACF,CAAA;IACD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC5C,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;QACrC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QACvB,MAAM,IAAI,KAAK,CAAC,UAAU,CAAA;IAC5B,CAAC;IACD,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;AACvC,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,EAAE,CAAC,0BAA0B,CAAC,CAAC,QAAQ,CAAC,EACtF,QAA+C,EAC/C,MAA8C,EAC9C,YAAY,GAAG,yBAAyB;IAExC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;IAC/D,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAChF,MAAM,CAAC,QAAQ,CACb,CAAC,KAAK,EAAE,EAAE,CACR,IAAI,sBAAsB,CAAC;QACzB,KAAK;QACL,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC;QACrB,MAAM,EAAE,QAAQ;KACjB,CAAC,CACL,CACF,CAAA;AACH,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"response.js","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAElD,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAEvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAEvD,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,EAAE,CAAC,2BAA2B,CAAC,CAAC,QAAQ,CAAC,EACjF,QAA+C,EAC/C,YAAY,GAAG,yBAAyB;IAExC,gFAAgF;IAChF,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,IAAI,CACpE,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CACxB,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC;QAC5C,CAAC,CAAC,IAAI,sBAAsB,CAAC;YAC3B,KAAK,EAAE,KAAK,CAAC,aAAa;YAC1B,MAAM,EAAE,0BAA0B,YAAY,QAAQ;YACtD,MAAM,EAAE,WAAW;SACpB,CAAC;QACF,CAAC,CAAC,IAAI,sBAAsB,CAAC;YAC3B,KAAK;YACL,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC;YACrB,MAAM,EAAE,WAAW;SACpB,CAAC,CACL,CACF,CAAA;IACD,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;AACvC,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,EAAE,CAAC,0BAA0B,CAAC,CAAC,QAAQ,CAAC,EACtF,QAA+C,EAC/C,MAA8C,EAC9C,YAAY,GAAG,yBAAyB;IAExC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;IAC/D,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAChF,MAAM,CAAC,QAAQ,CACb,CAAC,KAAK,EAAE,EAAE,CACR,IAAI,sBAAsB,CAAC;QACzB,KAAK;QACL,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC;QACrB,MAAM,EAAE,QAAQ;KACjB,CAAC,CACL,CACF,CAAA;AACH,CAAC,CAAC,CAAA"}
@@ -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;
@@ -20,20 +20,11 @@ export declare class JobStore {
20
20
  readonly expiredAt?: number | null;
21
21
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
22
22
  readonly payload: {
23
- readonly kind: "nix.check";
24
- } | {
25
- readonly kind: "nix.apply";
26
- readonly ref: string;
27
- } | {
28
23
  readonly kind: "agent.delegate";
29
24
  readonly repository: string;
30
25
  readonly prompt: string;
31
26
  readonly mode: "consult" | "review" | "transition_summary" | "work";
32
27
  readonly channel?: "coordinator_chat";
33
- } | {
34
- readonly kind: "agent.message";
35
- readonly session: string;
36
- readonly message: string;
37
28
  } | {
38
29
  readonly kind: "work.reconcile";
39
30
  readonly repository: string;
@@ -160,6 +151,15 @@ export declare class JobStore {
160
151
  readonly expectedGoalUpdatedAt: number;
161
152
  } | {
162
153
  readonly kind: "browser.mcp.recover";
154
+ } | {
155
+ readonly kind: "nix.check";
156
+ } | {
157
+ readonly kind: "nix.apply";
158
+ readonly ref: string;
159
+ } | {
160
+ readonly kind: "agent.message";
161
+ readonly session: string;
162
+ readonly message: string;
163
163
  };
164
164
  readonly result: string | null;
165
165
  readonly acceptedReceipt?: string | null;
@@ -196,20 +196,11 @@ export declare class JobStore {
196
196
  readonly expiredAt?: number | null;
197
197
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
198
198
  readonly payload: {
199
- readonly kind: "nix.check";
200
- } | {
201
- readonly kind: "nix.apply";
202
- readonly ref: string;
203
- } | {
204
199
  readonly kind: "agent.delegate";
205
200
  readonly repository: string;
206
201
  readonly prompt: string;
207
202
  readonly mode: "consult" | "review" | "transition_summary" | "work";
208
203
  readonly channel?: "coordinator_chat";
209
- } | {
210
- readonly kind: "agent.message";
211
- readonly session: string;
212
- readonly message: string;
213
204
  } | {
214
205
  readonly kind: "work.reconcile";
215
206
  readonly repository: string;
@@ -336,6 +327,15 @@ export declare class JobStore {
336
327
  readonly expectedGoalUpdatedAt: number;
337
328
  } | {
338
329
  readonly kind: "browser.mcp.recover";
330
+ } | {
331
+ readonly kind: "nix.check";
332
+ } | {
333
+ readonly kind: "nix.apply";
334
+ readonly ref: string;
335
+ } | {
336
+ readonly kind: "agent.message";
337
+ readonly session: string;
338
+ readonly message: string;
339
339
  };
340
340
  readonly result: string | null;
341
341
  readonly acceptedReceipt?: string | null;
@@ -373,20 +373,11 @@ export declare class JobStore {
373
373
  readonly expiredAt?: number | null;
374
374
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
375
375
  readonly payload: {
376
- readonly kind: "nix.check";
377
- } | {
378
- readonly kind: "nix.apply";
379
- readonly ref: string;
380
- } | {
381
376
  readonly kind: "agent.delegate";
382
377
  readonly repository: string;
383
378
  readonly prompt: string;
384
379
  readonly mode: "consult" | "review" | "transition_summary" | "work";
385
380
  readonly channel?: "coordinator_chat";
386
- } | {
387
- readonly kind: "agent.message";
388
- readonly session: string;
389
- readonly message: string;
390
381
  } | {
391
382
  readonly kind: "work.reconcile";
392
383
  readonly repository: string;
@@ -513,6 +504,15 @@ export declare class JobStore {
513
504
  readonly expectedGoalUpdatedAt: number;
514
505
  } | {
515
506
  readonly kind: "browser.mcp.recover";
507
+ } | {
508
+ readonly kind: "nix.check";
509
+ } | {
510
+ readonly kind: "nix.apply";
511
+ readonly ref: string;
512
+ } | {
513
+ readonly kind: "agent.message";
514
+ readonly session: string;
515
+ readonly message: string;
516
516
  };
517
517
  readonly result: string | null;
518
518
  readonly acceptedReceipt?: string | null;
@@ -549,20 +549,11 @@ export declare class JobStore {
549
549
  readonly expiredAt?: number | null;
550
550
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
551
551
  readonly payload: {
552
- readonly kind: "nix.check";
553
- } | {
554
- readonly kind: "nix.apply";
555
- readonly ref: string;
556
- } | {
557
552
  readonly kind: "agent.delegate";
558
553
  readonly repository: string;
559
554
  readonly prompt: string;
560
555
  readonly mode: "consult" | "review" | "transition_summary" | "work";
561
556
  readonly channel?: "coordinator_chat";
562
- } | {
563
- readonly kind: "agent.message";
564
- readonly session: string;
565
- readonly message: string;
566
557
  } | {
567
558
  readonly kind: "work.reconcile";
568
559
  readonly repository: string;
@@ -689,6 +680,15 @@ export declare class JobStore {
689
680
  readonly expectedGoalUpdatedAt: number;
690
681
  } | {
691
682
  readonly kind: "browser.mcp.recover";
683
+ } | {
684
+ readonly kind: "nix.check";
685
+ } | {
686
+ readonly kind: "nix.apply";
687
+ readonly ref: string;
688
+ } | {
689
+ readonly kind: "agent.message";
690
+ readonly session: string;
691
+ readonly message: string;
692
692
  };
693
693
  readonly result: string | null;
694
694
  readonly acceptedReceipt?: string | null;
@@ -725,20 +725,11 @@ export declare class JobStore {
725
725
  readonly expiredAt?: number | null;
726
726
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
727
727
  readonly payload: {
728
- readonly kind: "nix.check";
729
- } | {
730
- readonly kind: "nix.apply";
731
- readonly ref: string;
732
- } | {
733
728
  readonly kind: "agent.delegate";
734
729
  readonly repository: string;
735
730
  readonly prompt: string;
736
731
  readonly mode: "consult" | "review" | "transition_summary" | "work";
737
732
  readonly channel?: "coordinator_chat";
738
- } | {
739
- readonly kind: "agent.message";
740
- readonly session: string;
741
- readonly message: string;
742
733
  } | {
743
734
  readonly kind: "work.reconcile";
744
735
  readonly repository: string;
@@ -865,6 +856,15 @@ export declare class JobStore {
865
856
  readonly expectedGoalUpdatedAt: number;
866
857
  } | {
867
858
  readonly kind: "browser.mcp.recover";
859
+ } | {
860
+ readonly kind: "nix.check";
861
+ } | {
862
+ readonly kind: "nix.apply";
863
+ readonly ref: string;
864
+ } | {
865
+ readonly kind: "agent.message";
866
+ readonly session: string;
867
+ readonly message: string;
868
868
  };
869
869
  readonly result: string | null;
870
870
  readonly acceptedReceipt?: string | null;
@@ -902,20 +902,11 @@ export declare class JobStore {
902
902
  readonly expiredAt?: number | null;
903
903
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
904
904
  readonly payload: {
905
- readonly kind: "nix.check";
906
- } | {
907
- readonly kind: "nix.apply";
908
- readonly ref: string;
909
- } | {
910
905
  readonly kind: "agent.delegate";
911
906
  readonly repository: string;
912
907
  readonly prompt: string;
913
908
  readonly mode: "consult" | "review" | "transition_summary" | "work";
914
909
  readonly channel?: "coordinator_chat";
915
- } | {
916
- readonly kind: "agent.message";
917
- readonly session: string;
918
- readonly message: string;
919
910
  } | {
920
911
  readonly kind: "work.reconcile";
921
912
  readonly repository: string;
@@ -1042,6 +1033,15 @@ export declare class JobStore {
1042
1033
  readonly expectedGoalUpdatedAt: number;
1043
1034
  } | {
1044
1035
  readonly kind: "browser.mcp.recover";
1036
+ } | {
1037
+ readonly kind: "nix.check";
1038
+ } | {
1039
+ readonly kind: "nix.apply";
1040
+ readonly ref: string;
1041
+ } | {
1042
+ readonly kind: "agent.message";
1043
+ readonly session: string;
1044
+ readonly message: string;
1045
1045
  };
1046
1046
  readonly result: string | null;
1047
1047
  readonly acceptedReceipt?: string | null;
@@ -1079,20 +1079,11 @@ export declare class JobStore {
1079
1079
  readonly expiredAt?: number | null;
1080
1080
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
1081
1081
  readonly payload: {
1082
- readonly kind: "nix.check";
1083
- } | {
1084
- readonly kind: "nix.apply";
1085
- readonly ref: string;
1086
- } | {
1087
1082
  readonly kind: "agent.delegate";
1088
1083
  readonly repository: string;
1089
1084
  readonly prompt: string;
1090
1085
  readonly mode: "consult" | "review" | "transition_summary" | "work";
1091
1086
  readonly channel?: "coordinator_chat";
1092
- } | {
1093
- readonly kind: "agent.message";
1094
- readonly session: string;
1095
- readonly message: string;
1096
1087
  } | {
1097
1088
  readonly kind: "work.reconcile";
1098
1089
  readonly repository: string;
@@ -1219,6 +1210,15 @@ export declare class JobStore {
1219
1210
  readonly expectedGoalUpdatedAt: number;
1220
1211
  } | {
1221
1212
  readonly kind: "browser.mcp.recover";
1213
+ } | {
1214
+ readonly kind: "nix.check";
1215
+ } | {
1216
+ readonly kind: "nix.apply";
1217
+ readonly ref: string;
1218
+ } | {
1219
+ readonly kind: "agent.message";
1220
+ readonly session: string;
1221
+ readonly message: string;
1222
1222
  };
1223
1223
  readonly result: string | null;
1224
1224
  readonly acceptedReceipt?: string | null;
@@ -1259,20 +1259,11 @@ export declare class JobStore {
1259
1259
  readonly expiredAt?: number | null;
1260
1260
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
1261
1261
  readonly payload: {
1262
- readonly kind: "nix.check";
1263
- } | {
1264
- readonly kind: "nix.apply";
1265
- readonly ref: string;
1266
- } | {
1267
1262
  readonly kind: "agent.delegate";
1268
1263
  readonly repository: string;
1269
1264
  readonly prompt: string;
1270
1265
  readonly mode: "consult" | "review" | "transition_summary" | "work";
1271
1266
  readonly channel?: "coordinator_chat";
1272
- } | {
1273
- readonly kind: "agent.message";
1274
- readonly session: string;
1275
- readonly message: string;
1276
1267
  } | {
1277
1268
  readonly kind: "work.reconcile";
1278
1269
  readonly repository: string;
@@ -1399,6 +1390,15 @@ export declare class JobStore {
1399
1390
  readonly expectedGoalUpdatedAt: number;
1400
1391
  } | {
1401
1392
  readonly kind: "browser.mcp.recover";
1393
+ } | {
1394
+ readonly kind: "nix.check";
1395
+ } | {
1396
+ readonly kind: "nix.apply";
1397
+ readonly ref: string;
1398
+ } | {
1399
+ readonly kind: "agent.message";
1400
+ readonly session: string;
1401
+ readonly message: string;
1402
1402
  };
1403
1403
  readonly result: string | null;
1404
1404
  readonly acceptedReceipt?: string | null;
@@ -1439,20 +1439,11 @@ export declare class JobStore {
1439
1439
  readonly expiredAt?: number | null;
1440
1440
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
1441
1441
  readonly payload: {
1442
- readonly kind: "nix.check";
1443
- } | {
1444
- readonly kind: "nix.apply";
1445
- readonly ref: string;
1446
- } | {
1447
1442
  readonly kind: "agent.delegate";
1448
1443
  readonly repository: string;
1449
1444
  readonly prompt: string;
1450
1445
  readonly mode: "consult" | "review" | "transition_summary" | "work";
1451
1446
  readonly channel?: "coordinator_chat";
1452
- } | {
1453
- readonly kind: "agent.message";
1454
- readonly session: string;
1455
- readonly message: string;
1456
1447
  } | {
1457
1448
  readonly kind: "work.reconcile";
1458
1449
  readonly repository: string;
@@ -1579,6 +1570,15 @@ export declare class JobStore {
1579
1570
  readonly expectedGoalUpdatedAt: number;
1580
1571
  } | {
1581
1572
  readonly kind: "browser.mcp.recover";
1573
+ } | {
1574
+ readonly kind: "nix.check";
1575
+ } | {
1576
+ readonly kind: "nix.apply";
1577
+ readonly ref: string;
1578
+ } | {
1579
+ readonly kind: "agent.message";
1580
+ readonly session: string;
1581
+ readonly message: string;
1582
1582
  };
1583
1583
  readonly result: string | null;
1584
1584
  readonly acceptedReceipt?: string | null;
@@ -1616,20 +1616,11 @@ export declare class JobStore {
1616
1616
  readonly expiredAt?: number | null;
1617
1617
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
1618
1618
  readonly payload: {
1619
- readonly kind: "nix.check";
1620
- } | {
1621
- readonly kind: "nix.apply";
1622
- readonly ref: string;
1623
- } | {
1624
1619
  readonly kind: "agent.delegate";
1625
1620
  readonly repository: string;
1626
1621
  readonly prompt: string;
1627
1622
  readonly mode: "consult" | "review" | "transition_summary" | "work";
1628
1623
  readonly channel?: "coordinator_chat";
1629
- } | {
1630
- readonly kind: "agent.message";
1631
- readonly session: string;
1632
- readonly message: string;
1633
1624
  } | {
1634
1625
  readonly kind: "work.reconcile";
1635
1626
  readonly repository: string;
@@ -1756,6 +1747,15 @@ export declare class JobStore {
1756
1747
  readonly expectedGoalUpdatedAt: number;
1757
1748
  } | {
1758
1749
  readonly kind: "browser.mcp.recover";
1750
+ } | {
1751
+ readonly kind: "nix.check";
1752
+ } | {
1753
+ readonly kind: "nix.apply";
1754
+ readonly ref: string;
1755
+ } | {
1756
+ readonly kind: "agent.message";
1757
+ readonly session: string;
1758
+ readonly message: string;
1759
1759
  };
1760
1760
  readonly result: string | null;
1761
1761
  readonly acceptedReceipt?: string | null;
@@ -1793,20 +1793,11 @@ export declare class JobStore {
1793
1793
  readonly expiredAt?: number | null;
1794
1794
  readonly status: "expired" | "failed" | "interrupted" | "pending_approval" | "queued" | "rejected" | "running" | "succeeded";
1795
1795
  readonly payload: {
1796
- readonly kind: "nix.check";
1797
- } | {
1798
- readonly kind: "nix.apply";
1799
- readonly ref: string;
1800
- } | {
1801
1796
  readonly kind: "agent.delegate";
1802
1797
  readonly repository: string;
1803
1798
  readonly prompt: string;
1804
1799
  readonly mode: "consult" | "review" | "transition_summary" | "work";
1805
1800
  readonly channel?: "coordinator_chat";
1806
- } | {
1807
- readonly kind: "agent.message";
1808
- readonly session: string;
1809
- readonly message: string;
1810
1801
  } | {
1811
1802
  readonly kind: "work.reconcile";
1812
1803
  readonly repository: string;
@@ -1933,6 +1924,15 @@ export declare class JobStore {
1933
1924
  readonly expectedGoalUpdatedAt: number;
1934
1925
  } | {
1935
1926
  readonly kind: "browser.mcp.recover";
1927
+ } | {
1928
+ readonly kind: "nix.check";
1929
+ } | {
1930
+ readonly kind: "nix.apply";
1931
+ readonly ref: string;
1932
+ } | {
1933
+ readonly kind: "agent.message";
1934
+ readonly session: string;
1935
+ readonly message: string;
1936
1936
  };
1937
1937
  readonly result: string | null;
1938
1938
  readonly acceptedReceipt?: string | null;
@@ -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.1",
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": [
@@ -38,7 +42,8 @@
38
42
  "node": ">=26"
39
43
  },
40
44
  "dependencies": {
41
- "effect": "4.0.0"
45
+ "effect": "4.0.0",
46
+ "@knpkv/bounded-io": "^0.2.0"
42
47
  },
43
48
  "devDependencies": {
44
49
  "@effect/platform-node": "4.0.0",