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.
- package/dist/runStore/jsonlRunRepository.d.ts +37 -0
- package/dist/runStore/jsonlRunRepository.js +56 -0
- package/dist/runStore/jsonlRunRepository.js.map +1 -0
- package/dist/runStore/runRepository.d.ts +94 -0
- package/dist/runStore/runRepository.js +30 -0
- package/dist/runStore/runRepository.js.map +1 -0
- package/package.json +1 -1
|
@@ -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.
|
|
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",
|