patchwork-os 1.2.0-beta.2.canary.598 → 1.2.0-beta.2.canary.600

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.
@@ -0,0 +1,37 @@
1
+ /**
2
+ * The incumbent JSONL store, behind the ADR-0022 repository seam.
3
+ *
4
+ * This adapter holds NO logic of its own — every method forwards to
5
+ * `RecipeRunLog`. That is the point. It exists so the interface can be
6
+ * introduced with provably zero behaviour change, which is what makes the
7
+ * conformance suite meaningful: the suite is first pinned against the store
8
+ * we already trust, and only then pointed at a new one.
9
+ *
10
+ * If this file ever grows a behavioural decision, the comparison it enables
11
+ * stops being a comparison.
12
+ */
13
+ import type { RecipeRun, RunQuery, RunStepResult } from "../runLog.js";
14
+ import { RecipeRunLog, type RunLogOptions } from "../runLog.js";
15
+ import type { CompleteRunInput, RunRepository, StartRunInput } from "./runRepository.js";
16
+ export declare class JsonlRunRepository implements RunRepository {
17
+ private readonly log;
18
+ constructor(log: RecipeRunLog);
19
+ /** Convenience: build the adapter and the underlying log together. */
20
+ static open(opts: RunLogOptions): JsonlRunRepository;
21
+ /**
22
+ * Escape hatch for callers still reaching for `RecipeRunLog`-only methods
23
+ * (`record`, `appendDirect`, `readArchive`). Those are deliberately absent
24
+ * from `RunRepository` — `readArchive` in particular is a JSONL rotation
25
+ * detail with no meaning in a store that does not rotate by bytes.
26
+ *
27
+ * Every use of this is a migration debt marker, not an approved pattern.
28
+ */
29
+ get underlying(): RecipeRunLog;
30
+ startRun(input: StartRunInput): number;
31
+ updateRunSteps(seq: number, stepResults: RunStepResult[]): void;
32
+ completeRun(seq: number, input: CompleteRunInput): void;
33
+ query(q?: RunQuery): RecipeRun[];
34
+ getBySeq(seq: number): RecipeRun | null;
35
+ getChildSeqs(parentSeq: number): number[];
36
+ size(): number;
37
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * The incumbent JSONL store, behind the ADR-0022 repository seam.
3
+ *
4
+ * This adapter holds NO logic of its own — every method forwards to
5
+ * `RecipeRunLog`. That is the point. It exists so the interface can be
6
+ * introduced with provably zero behaviour change, which is what makes the
7
+ * conformance suite meaningful: the suite is first pinned against the store
8
+ * we already trust, and only then pointed at a new one.
9
+ *
10
+ * If this file ever grows a behavioural decision, the comparison it enables
11
+ * stops being a comparison.
12
+ */
13
+ import { RecipeRunLog } from "../runLog.js";
14
+ export class JsonlRunRepository {
15
+ log;
16
+ constructor(log) {
17
+ this.log = log;
18
+ }
19
+ /** Convenience: build the adapter and the underlying log together. */
20
+ static open(opts) {
21
+ return new JsonlRunRepository(new RecipeRunLog(opts));
22
+ }
23
+ /**
24
+ * Escape hatch for callers still reaching for `RecipeRunLog`-only methods
25
+ * (`record`, `appendDirect`, `readArchive`). Those are deliberately absent
26
+ * from `RunRepository` — `readArchive` in particular is a JSONL rotation
27
+ * detail with no meaning in a store that does not rotate by bytes.
28
+ *
29
+ * Every use of this is a migration debt marker, not an approved pattern.
30
+ */
31
+ get underlying() {
32
+ return this.log;
33
+ }
34
+ startRun(input) {
35
+ return this.log.startRun(input);
36
+ }
37
+ updateRunSteps(seq, stepResults) {
38
+ this.log.updateRunSteps(seq, stepResults);
39
+ }
40
+ completeRun(seq, input) {
41
+ this.log.completeRun(seq, input);
42
+ }
43
+ query(q = {}) {
44
+ return this.log.query(q);
45
+ }
46
+ getBySeq(seq) {
47
+ return this.log.getBySeq(seq);
48
+ }
49
+ getChildSeqs(parentSeq) {
50
+ return this.log.getChildSeqs(parentSeq);
51
+ }
52
+ size() {
53
+ return this.log.size();
54
+ }
55
+ }
56
+ //# sourceMappingURL=jsonlRunRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonlRunRepository.js","sourceRoot":"","sources":["../../src/runStore/jsonlRunRepository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,YAAY,EAAsB,MAAM,cAAc,CAAC;AAOhE,MAAM,OAAO,kBAAkB;IACA;IAA7B,YAA6B,GAAiB;QAAjB,QAAG,GAAH,GAAG,CAAc;IAAG,CAAC;IAElD,sEAAsE;IACtE,MAAM,CAAC,IAAI,CAAC,IAAmB;QAC7B,OAAO,IAAI,kBAAkB,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD,CAAC;IAED;;;;;;;OAOG;IACH,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,GAAG,CAAC;IAClB,CAAC;IAED,QAAQ,CAAC,KAAoB;QAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,cAAc,CAAC,GAAW,EAAE,WAA4B;QACtD,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC5C,CAAC;IAED,WAAW,CAAC,GAAW,EAAE,KAAuB;QAC9C,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,IAAc,EAAE;QACpB,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IAED,QAAQ,CAAC,GAAW;QAClB,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,YAAY,CAAC,SAAiB;QAC5B,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;CACF"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * The storage seam for run evidence — ADR-0022.
3
+ *
4
+ * WHY THIS EXISTS. `runs.jsonl` is the autonomy gate's trust evidence and also
5
+ * an append-only text file with no integrity properties. It failed three ways
6
+ * in eight weeks, each silently: #1324 (`seq` collides across instances — 142
7
+ * of 145 in the live log), #1340 (in-flight steps never reached disk), #1341
8
+ * (a concurrent reader made `completeRun` a no-op, recording a successful run
9
+ * as `interrupted, steps: 0`). Each was fixed; the pattern was not.
10
+ *
11
+ * This interface is the line those fixes kept crossing. It names what a run
12
+ * store must DO, so an implementation can be swapped without every caller
13
+ * learning how the bytes are laid out. `RecipeRunLog` is the incumbent
14
+ * implementation; a SQLite one follows, and dual-write compares them before
15
+ * anything flips.
16
+ *
17
+ * ## What this interface deliberately does NOT do
18
+ *
19
+ * It does not redesign what a run means. Every method mirrors a `RecipeRunLog`
20
+ * method with the same name and semantics, including ones that are arguably
21
+ * wrong (see `getBySeq`). A storage migration that also changes the domain
22
+ * model cannot be verified by comparing old against new, because there is no
23
+ * longer a fixed thing to compare — and comparison against the incumbent is
24
+ * the entire safety argument for the migration.
25
+ *
26
+ * Fixing those wrong-but-preserved parts happens AFTER the stores agree, not
27
+ * during.
28
+ */
29
+ import type { RecipeRun, RunQuery, RunStepResult, RunTrigger, TerminalRunStatus } from "../runLog.js";
30
+ /** Arguments to {@link RunRepository.startRun}. Mirrors `RecipeRunLog.startRun`. */
31
+ export interface StartRunInput {
32
+ taskId: string;
33
+ recipeName: string;
34
+ trigger: RunTrigger;
35
+ createdAt: number;
36
+ startedAt?: number;
37
+ model?: string;
38
+ parentSeq?: number;
39
+ manualRunId?: string;
40
+ /** Test seam — defaults to this process. See `RecipeRun.ownerPid`. */
41
+ ownerPid?: number;
42
+ }
43
+ /** Arguments to {@link RunRepository.completeRun}. Mirrors `RecipeRunLog.completeRun`. */
44
+ export interface CompleteRunInput {
45
+ status: TerminalRunStatus;
46
+ doneAt: number;
47
+ durationMs: number;
48
+ stepResults: RunStepResult[];
49
+ outputTail?: string;
50
+ errorMessage?: string;
51
+ assertionFailures?: RecipeRun["assertionFailures"];
52
+ inboxOutputs?: RecipeRun["inboxOutputs"];
53
+ budgetWarnings?: RecipeRun["budgetWarnings"];
54
+ tokenTotals?: RecipeRun["tokenTotals"];
55
+ budgetTotals?: RecipeRun["budgetTotals"];
56
+ }
57
+ /**
58
+ * A store of recipe runs and their steps.
59
+ *
60
+ * Implementations must be safe against a SECOND PROCESS writing the same
61
+ * store concurrently. That is not a theoretical requirement: `runs.jsonl` has
62
+ * eight construction sites, several of which write, and every one of the three
63
+ * bugs above involved two writers or a writer and a reader disagreeing.
64
+ */
65
+ export interface RunRepository {
66
+ /**
67
+ * Begin a run and return its `seq`.
68
+ *
69
+ * NOTE the returned `seq` is per-instance and therefore NOT unique across
70
+ * processes (#1324). It is preserved because callers pass it back to
71
+ * `updateRunSteps` / `completeRun` within one process, where it is
72
+ * well-defined. Cross-process identity is `taskId`.
73
+ */
74
+ startRun(input: StartRunInput): number;
75
+ /** Replace the step list of an in-flight run, persisting evidence as it arrives (#1340). */
76
+ updateRunSteps(seq: number, stepResults: RunStepResult[]): void;
77
+ /** Finish a run. Must be durable before returning. */
78
+ completeRun(seq: number, input: CompleteRunInput): void;
79
+ /** Query runs, newest first. */
80
+ query(q?: RunQuery): RecipeRun[];
81
+ /**
82
+ * Look up one run by `seq`.
83
+ *
84
+ * PRESERVED AS-IS AND KNOWN TO BE WRONG (#1360): `seq` is not unique across
85
+ * processes, so this can resolve to an arbitrary colliding run. It backs the
86
+ * `/runs/[seq]` URL contract, so correcting it is a separate, visible change
87
+ * — not something to slip in behind a storage swap.
88
+ */
89
+ getBySeq(seq: number): RecipeRun | null;
90
+ /** `seq`s of runs whose `parentSeq` is the given run. */
91
+ getChildSeqs(parentSeq: number): number[];
92
+ /** Number of runs currently retained and readable. */
93
+ size(): number;
94
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The storage seam for run evidence — ADR-0022.
3
+ *
4
+ * WHY THIS EXISTS. `runs.jsonl` is the autonomy gate's trust evidence and also
5
+ * an append-only text file with no integrity properties. It failed three ways
6
+ * in eight weeks, each silently: #1324 (`seq` collides across instances — 142
7
+ * of 145 in the live log), #1340 (in-flight steps never reached disk), #1341
8
+ * (a concurrent reader made `completeRun` a no-op, recording a successful run
9
+ * as `interrupted, steps: 0`). Each was fixed; the pattern was not.
10
+ *
11
+ * This interface is the line those fixes kept crossing. It names what a run
12
+ * store must DO, so an implementation can be swapped without every caller
13
+ * learning how the bytes are laid out. `RecipeRunLog` is the incumbent
14
+ * implementation; a SQLite one follows, and dual-write compares them before
15
+ * anything flips.
16
+ *
17
+ * ## What this interface deliberately does NOT do
18
+ *
19
+ * It does not redesign what a run means. Every method mirrors a `RecipeRunLog`
20
+ * method with the same name and semantics, including ones that are arguably
21
+ * wrong (see `getBySeq`). A storage migration that also changes the domain
22
+ * model cannot be verified by comparing old against new, because there is no
23
+ * longer a fixed thing to compare — and comparison against the incumbent is
24
+ * the entire safety argument for the migration.
25
+ *
26
+ * Fixing those wrong-but-preserved parts happens AFTER the stores agree, not
27
+ * during.
28
+ */
29
+ export {};
30
+ //# sourceMappingURL=runRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runRepository.js","sourceRoot":"","sources":["../../src/runStore/runRepository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchwork-os",
3
- "version": "1.2.0-beta.2.canary.598",
3
+ "version": "1.2.0-beta.2.canary.600",
4
4
  "description": "Your personal AI runtime, local-first. Patchwork OS gives any AI model a consistent set of tools, YAML recipes, a delegation policy with approval queue, and a durable trace memory — all on your machine, all under your policy.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",