@kernloop/workflows 0.1.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/LICENSE +21 -0
- package/dist/budget.d.ts +111 -0
- package/dist/budget.d.ts.map +1 -0
- package/dist/budget.js +146 -0
- package/dist/budget.js.map +1 -0
- package/dist/checkpoints.d.ts +40 -0
- package/dist/checkpoints.d.ts.map +1 -0
- package/dist/checkpoints.js +92 -0
- package/dist/checkpoints.js.map +1 -0
- package/dist/child-iterate-fixtures.d.ts +36 -0
- package/dist/child-iterate-fixtures.d.ts.map +1 -0
- package/dist/child-iterate-fixtures.js +86 -0
- package/dist/child-iterate-fixtures.js.map +1 -0
- package/dist/child-iterate.d.ts +71 -0
- package/dist/child-iterate.d.ts.map +1 -0
- package/dist/child-iterate.js +61 -0
- package/dist/child-iterate.js.map +1 -0
- package/dist/child-spend.d.ts +41 -0
- package/dist/child-spend.d.ts.map +1 -0
- package/dist/child-spend.js +76 -0
- package/dist/child-spend.js.map +1 -0
- package/dist/config.d.ts +43 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +90 -0
- package/dist/config.js.map +1 -0
- package/dist/engine-errors.d.ts +11 -0
- package/dist/engine-errors.d.ts.map +1 -0
- package/dist/engine-errors.js +23 -0
- package/dist/engine-errors.js.map +1 -0
- package/dist/engine-testkit.d.ts +44 -0
- package/dist/engine-testkit.d.ts.map +1 -0
- package/dist/engine-testkit.js +93 -0
- package/dist/engine-testkit.js.map +1 -0
- package/dist/engine-types.d.ts +78 -0
- package/dist/engine-types.d.ts.map +1 -0
- package/dist/engine-types.js +2 -0
- package/dist/engine-types.js.map +1 -0
- package/dist/engine.d.ts +12 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +262 -0
- package/dist/engine.js.map +1 -0
- package/dist/graph.d.ts +87 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +72 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.d.ts +19 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +41 -0
- package/dist/manifest.js.map +1 -0
- package/dist/state.d.ts +1078 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +151 -0
- package/dist/state.js.map +1 -0
- package/dist/steps.d.ts +77 -0
- package/dist/steps.d.ts.map +1 -0
- package/dist/steps.js +270 -0
- package/dist/steps.js.map +1 -0
- package/dist/verdict-disposition.d.ts +23 -0
- package/dist/verdict-disposition.d.ts.map +1 -0
- package/dist/verdict-disposition.js +28 -0
- package/dist/verdict-disposition.js.map +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
|
package/dist/state.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run state, checkpoint record shape, and typed engine errors. The state is
|
|
3
|
+
* deliberately a plain JSON-serializable object validated by zod: a resume
|
|
4
|
+
* trusts nothing it reads back from storage [CLM-0044] — a checkpoint that
|
|
5
|
+
* does not parse is a typed failure, never a silent partial resume.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import { FindingSchema, TaskContractSchema, VerdictSchema, } from '@kernloop/contracts';
|
|
9
|
+
/**
|
|
10
|
+
* Where the run is. `main` points at the NEXT main-chain node to execute;
|
|
11
|
+
* `fanout` points at the next (child, sub-node) pair; `done` is terminal.
|
|
12
|
+
* The cursor always names work not yet performed, so resuming from a
|
|
13
|
+
* checkpoint never re-runs a completed node [CLM-0044].
|
|
14
|
+
*/
|
|
15
|
+
export const CursorSchema = z.discriminatedUnion('phase', [
|
|
16
|
+
z.strictObject({ phase: z.literal('main'), node: z.string().min(1) }),
|
|
17
|
+
z.strictObject({
|
|
18
|
+
phase: z.literal('fanout'),
|
|
19
|
+
childIndex: z.number().int().nonnegative(),
|
|
20
|
+
sub: z.number().int().nonnegative(),
|
|
21
|
+
}),
|
|
22
|
+
z.strictObject({ phase: z.literal('done') }),
|
|
23
|
+
]);
|
|
24
|
+
/** Metered spend attributed to one fan-out child (tokens + usd), #56. */
|
|
25
|
+
export const ChildSpendSchema = z.strictObject({
|
|
26
|
+
tokens: z.number().nonnegative(),
|
|
27
|
+
usd: z.number().nonnegative(),
|
|
28
|
+
});
|
|
29
|
+
/**
|
|
30
|
+
* One fan-out child's honest result. A child that fails mid-implement gets
|
|
31
|
+
* `error` and no verdict; a child whose quality gate ran gets its Verdict
|
|
32
|
+
* (pass or fail — a failing verdict is a result, not an engine error). The
|
|
33
|
+
* `reviewVerdict` is the advisory review gate's verdict (recorded, never
|
|
34
|
+
* blocking). All shapes aggregate into integrate's input unfiltered.
|
|
35
|
+
*
|
|
36
|
+
* `iteration` and `findings` carry the per-child actor-critic loop [CLM-0043]:
|
|
37
|
+
* a quality reject re-runs implement, folding the gate's findings into the
|
|
38
|
+
* coder's next attempt, bounded by Kc (and the run budget). They mirror the
|
|
39
|
+
* run-level `iteration`/`findings` but scope to one child, and are
|
|
40
|
+
* checkpointed so a resume mid-child-iteration re-runs nothing finished.
|
|
41
|
+
* `escalated` marks a child that hit the Kc/budget bound still failing — it is
|
|
42
|
+
* recorded, never re-attempted, and does NOT sink its siblings or the run.
|
|
43
|
+
*/
|
|
44
|
+
export const ChildResultSchema = z.strictObject({
|
|
45
|
+
child: TaskContractSchema,
|
|
46
|
+
output: z.unknown().optional(),
|
|
47
|
+
verdict: VerdictSchema.optional(),
|
|
48
|
+
reviewVerdict: VerdictSchema.optional(),
|
|
49
|
+
/** The parsimony Check-layer gate's verdict (#9/#415): at intensity lite it is
|
|
50
|
+
* advisory (recorded, never blocking, like `reviewVerdict`); at full/ultra a
|
|
51
|
+
* REJECT drives child re-iteration. Kept in its OWN slot so the parsimony gate
|
|
52
|
+
* never clobbers the quality `verdict` (the parsimony node runs after both). */
|
|
53
|
+
parsimonyVerdict: VerdictSchema.optional(),
|
|
54
|
+
error: z.string().min(1).optional(),
|
|
55
|
+
/** How many times implement has been re-run for this child (0 on first). */
|
|
56
|
+
iteration: z.number().int().nonnegative().default(0),
|
|
57
|
+
/** Gate findings accumulated across this child's iterations, fed to the coder. */
|
|
58
|
+
findings: z.array(FindingSchema).default([]),
|
|
59
|
+
/** Set when the child hit the Kc/budget bound still failing (bounded escalation). */
|
|
60
|
+
escalated: z.boolean().optional(),
|
|
61
|
+
/**
|
|
62
|
+
* Metered model spend ATTRIBUTED to this child's sub-chain (#56): the
|
|
63
|
+
* run-global meter sliced by the SEQUENTIAL child boundary, summed across all
|
|
64
|
+
* of the child's Kc iterations. Set as the fan-out runs the child when the
|
|
65
|
+
* composition root injected a `meteredSpend` seam; absent on an unmetered run.
|
|
66
|
+
* Per-PROCESS, like the meter it reads (#212): a resume re-attributes from the
|
|
67
|
+
* fresh meter and DROPS any pre-resume spend, so a child finished before a
|
|
68
|
+
* resume reports none — keeping the sum within the (also per-process) run cost.
|
|
69
|
+
*/
|
|
70
|
+
spend: ChildSpendSchema.optional(),
|
|
71
|
+
});
|
|
72
|
+
/** One executed node in the run's trace (deterministic order, child-tagged). */
|
|
73
|
+
export const TraceEntrySchema = z.strictObject({
|
|
74
|
+
seq: z.number().int().positive(),
|
|
75
|
+
node: z.string().min(1),
|
|
76
|
+
iteration: z.number().int().nonnegative(),
|
|
77
|
+
childId: z.string().min(1).optional(),
|
|
78
|
+
});
|
|
79
|
+
/**
|
|
80
|
+
* The complete serializable state of one run. Self-contained: a checkpoint's
|
|
81
|
+
* state plus the injected executors is everything a resume needs.
|
|
82
|
+
*/
|
|
83
|
+
export const RunStateSchema = z.strictObject({
|
|
84
|
+
task: TaskContractSchema,
|
|
85
|
+
status: z.enum(['running', 'escalated', 'completed']),
|
|
86
|
+
cursor: CursorSchema,
|
|
87
|
+
/**
|
|
88
|
+
* Why an escalated run halted: `vote` (the K vote-iterate bound — resume
|
|
89
|
+
* re-plans with a fresh K after the human edit [CLM-0043]); `vote-escalation`
|
|
90
|
+
* (a vote gate ruled `escalate` — a deadlocked panel asking a human, #192 —
|
|
91
|
+
* distinct from `vote` so an operator tells a deadlock from K-exhaustion;
|
|
92
|
+
* resume re-plans the same way); or `budget` (the run exceeded its budget in
|
|
93
|
+
* enforce mode — resume continues from the cursor once the human raises the
|
|
94
|
+
* budget or re-runs unlimited [CLM-0077]). Absent while running/completed.
|
|
95
|
+
*/
|
|
96
|
+
haltReason: z.enum(['vote', 'vote-escalation', 'budget']).optional(),
|
|
97
|
+
/** Vote-iterate count: how many times the rejected edge re-entered plan. */
|
|
98
|
+
iteration: z.number().int().nonnegative(),
|
|
99
|
+
/** Last emission per node name — the values that flow along edges. */
|
|
100
|
+
values: z.record(z.string(), z.unknown()),
|
|
101
|
+
/** Findings accumulated from rejecting vote Verdicts, fed back to plan. */
|
|
102
|
+
findings: z.array(FindingSchema),
|
|
103
|
+
/** Decomposed (plus overlay-added specialist) children, set at fan-out. */
|
|
104
|
+
children: z.array(TaskContractSchema),
|
|
105
|
+
/** Per-child results accumulated as the fan-out progresses. */
|
|
106
|
+
childResults: z.array(ChildResultSchema),
|
|
107
|
+
trace: z.array(TraceEntrySchema),
|
|
108
|
+
/**
|
|
109
|
+
* Largest single-NODE metered spend seen this run (#342). The pre-node budget
|
|
110
|
+
* guard reserves at least this much so an enforce-mode cap is not overshot by
|
|
111
|
+
* one node's spend. PERSISTED in the checkpoint, so a resume RESTORES the
|
|
112
|
+
* learned max — conservative: the prior worst node still bounds the reserve
|
|
113
|
+
* even though the per-process `spent()` meter restarts. Defaulted so a pre-#342
|
|
114
|
+
* checkpoint (which lacks the field) resumes cleanly.
|
|
115
|
+
*/
|
|
116
|
+
observedMaxNodeSpend: ChildSpendSchema.default({ tokens: 0, usd: 0 }),
|
|
117
|
+
});
|
|
118
|
+
/**
|
|
119
|
+
* One checkpoint row, persisted through the injected store after EVERY node
|
|
120
|
+
* completion [CLM-0044]: `{runId, seq, node, iteration, state}` where `node`
|
|
121
|
+
* is the node that just completed and `state` already points past it.
|
|
122
|
+
*/
|
|
123
|
+
export const CheckpointRecordSchema = z.strictObject({
|
|
124
|
+
runId: z.string().min(1),
|
|
125
|
+
seq: z.number().int().positive(),
|
|
126
|
+
node: z.string().min(1),
|
|
127
|
+
iteration: z.number().int().nonnegative(),
|
|
128
|
+
state: RunStateSchema,
|
|
129
|
+
createdAt: z.string().min(1),
|
|
130
|
+
});
|
|
131
|
+
/**
|
|
132
|
+
* Typed engine failure. Edge-contract failures name the node and the
|
|
133
|
+
* contract the emission violated [CLM-0042].
|
|
134
|
+
*/
|
|
135
|
+
export class WorkflowError extends Error {
|
|
136
|
+
code;
|
|
137
|
+
/** Node involved, when one is. */
|
|
138
|
+
node;
|
|
139
|
+
/** Contract violated, for `edge_contract`. */
|
|
140
|
+
contract;
|
|
141
|
+
constructor(code, message, details = {}) {
|
|
142
|
+
super(message, details.cause === undefined ? undefined : { cause: details.cause });
|
|
143
|
+
this.name = 'WorkflowError';
|
|
144
|
+
this.code = code;
|
|
145
|
+
if (details.node !== undefined)
|
|
146
|
+
this.node = details.node;
|
|
147
|
+
if (details.contract !== undefined)
|
|
148
|
+
this.contract = details.contract;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
|
package/dist/steps.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { type Finding, type TaskContract } from '@kernloop/contracts';
|
|
2
|
+
import { type LoopGraph, type LoopNode } from './graph.js';
|
|
3
|
+
import { type RunState } from './state.js';
|
|
4
|
+
/**
|
|
5
|
+
* Loop-shaping inputs the engine resolves from its config + injected seams and
|
|
6
|
+
* threads into {@link advance}: the vote bound `K`, the child-iterate bound
|
|
7
|
+
* `Kc`, overlay specialists, the review-drives-iteration honesty flag, whether
|
|
8
|
+
* a child re-entry is within budget, and an audit hook fired on each child
|
|
9
|
+
* re-iteration (the engine wires it to the chain; workflows imports no kernel).
|
|
10
|
+
*/
|
|
11
|
+
export interface AdvanceOptions {
|
|
12
|
+
readonly k: number;
|
|
13
|
+
readonly kc: number;
|
|
14
|
+
readonly specialists: readonly string[];
|
|
15
|
+
readonly reviewDrivesIteration: boolean;
|
|
16
|
+
/** Does the parsimony gate drive child re-iteration this run (#9/#415)? True at
|
|
17
|
+
* intensity full/ultra (a rejecting parsimony verdict re-runs implement), false
|
|
18
|
+
* at lite/off (advisory or disabled). The CLI derives it from the overlay. */
|
|
19
|
+
readonly parsimonyDrivesIteration: boolean;
|
|
20
|
+
/** False when a child re-implement would exceed the run budget (Part B). */
|
|
21
|
+
readonly childWithinBudget: boolean;
|
|
22
|
+
/** Fired when a child re-enters implement: {childId, iteration, gate, findingCount}. */
|
|
23
|
+
readonly onIterate?: (event: {
|
|
24
|
+
childId: string;
|
|
25
|
+
iteration: number;
|
|
26
|
+
gate: string;
|
|
27
|
+
findingCount: number;
|
|
28
|
+
}) => void;
|
|
29
|
+
}
|
|
30
|
+
/** The next unit of work the cursor points at. */
|
|
31
|
+
export interface Step {
|
|
32
|
+
readonly node: LoopNode;
|
|
33
|
+
readonly input: unknown;
|
|
34
|
+
/** Set inside the fan-out sub-chain. */
|
|
35
|
+
readonly child?: TaskContract;
|
|
36
|
+
/**
|
|
37
|
+
* The CHILD's accumulated gate findings, inside the fan-out sub-chain — what
|
|
38
|
+
* the re-running coder must fix [CLM-0043]. Distinct from the run-level
|
|
39
|
+
* findings (vote re-entries); the engine hands these to the child's
|
|
40
|
+
* NodeContext so implement reads its own critique, not the run's.
|
|
41
|
+
*/
|
|
42
|
+
readonly childFindings?: readonly Finding[];
|
|
43
|
+
}
|
|
44
|
+
/** Build the initial state for a fresh run. */
|
|
45
|
+
export declare function initialState(task: TaskContract, entry: string): RunState;
|
|
46
|
+
/**
|
|
47
|
+
* Resolve the cursor to the node about to run and its input. Inputs follow
|
|
48
|
+
* the graph's edges: a main-chain node consumes the value its predecessor
|
|
49
|
+
* emitted (for plan re-entries that is still research's Brief — the
|
|
50
|
+
* rejecting Verdict's findings travel via NodeContext.findings); the child
|
|
51
|
+
* sub-chain consumes the child contract, then the implement output.
|
|
52
|
+
*/
|
|
53
|
+
export declare function nextStep(graph: LoopGraph, state: RunState): Step;
|
|
54
|
+
/**
|
|
55
|
+
* Validate a node's emission against its declared contract before it
|
|
56
|
+
* crosses the edge [CLM-0042]. Collection emitters (decompose's children)
|
|
57
|
+
* validate element-wise. Throws a typed error naming node + contract.
|
|
58
|
+
*/
|
|
59
|
+
export declare function validateEmission(node: LoopNode, output: unknown): unknown;
|
|
60
|
+
/**
|
|
61
|
+
* Synthesize the child contract for an overlay-added specialist (spec §6
|
|
62
|
+
* "add a specialist") [CLM-0045]. The entry adds WORK, not budget: its
|
|
63
|
+
* budget is zero so the decomposed children's budget-sum invariant (PM's
|
|
64
|
+
* job, spec §5.4) survives the addition; a composition root that wants a
|
|
65
|
+
* funded specialist makes its decompose executor slice for it.
|
|
66
|
+
*/
|
|
67
|
+
export declare function specialistChild(task: TaskContract, specialist: string): TaskContract;
|
|
68
|
+
/** Step to the next fan-out child, or back to the main chain after the last. */
|
|
69
|
+
export declare function advanceToNextChild(graph: LoopGraph, state: RunState, childIndex: number): void;
|
|
70
|
+
/**
|
|
71
|
+
* Apply one validated emission to the state and move the cursor. Mutates
|
|
72
|
+
* `state` (the engine snapshots per checkpoint). {@link AdvanceOptions} carries
|
|
73
|
+
* the vote bound K, the child-iterate bound Kc, overlay specialists, the
|
|
74
|
+
* review-drives-iteration honesty flag, the budget verdict, and the audit hook.
|
|
75
|
+
*/
|
|
76
|
+
export declare function advance(graph: LoopGraph, state: RunState, node: LoopNode, output: unknown, opts: AdvanceOptions): void;
|
|
77
|
+
//# sourceMappingURL=steps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../src/steps.ts"],"names":[],"mappings":"AAOA,OAAO,EAGL,KAAK,OAAO,EACZ,KAAK,YAAY,EAElB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAyB,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAiB,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAU1D;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,qBAAqB,EAAE,OAAO,CAAC;IACxC;;kFAE8E;IAC9E,QAAQ,CAAC,wBAAwB,EAAE,OAAO,CAAC;IAC3C,4EAA4E;IAC5E,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,wFAAwF;IACxF,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE;QAC3B,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,MAAM,CAAC;KACtB,KAAK,IAAI,CAAC;CACZ;AAED,kDAAkD;AAClD,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,wCAAwC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;CAC7C;AAED,+CAA+C;AAC/C,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAaxE;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CAoBhE;AAYD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAYzE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY,CAYpF;AAqID,gFAAgF;AAChF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAW9F;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CACrB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,QAAQ,EACf,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,cAAc,GACnB,IAAI,CAwBN"}
|
package/dist/steps.js
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Step mechanics for the loop engine: what runs next, what it consumes,
|
|
3
|
+
* how the state advances when it completes, and the edge-contract
|
|
4
|
+
* validation that rejects malformed emissions [CLM-0042]. Pure state
|
|
5
|
+
* transitions — no I/O, no executors; the engine owns those.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import { KNOWN_CONTRACTS, TaskContractSchema, } from '@kernloop/contracts';
|
|
9
|
+
import { nodeByName, successor } from './graph.js';
|
|
10
|
+
import { WorkflowError } from './state.js';
|
|
11
|
+
import { childBranch, escalateChild, foldHints, gateDrivesIteration, reiterateChild, } from './child-iterate.js';
|
|
12
|
+
import { verdictDisposition } from './verdict-disposition.js';
|
|
13
|
+
/** Build the initial state for a fresh run. */
|
|
14
|
+
export function initialState(task, entry) {
|
|
15
|
+
return {
|
|
16
|
+
task,
|
|
17
|
+
status: 'running',
|
|
18
|
+
cursor: { phase: 'main', node: entry },
|
|
19
|
+
iteration: 0,
|
|
20
|
+
values: {},
|
|
21
|
+
findings: [],
|
|
22
|
+
children: [],
|
|
23
|
+
childResults: [],
|
|
24
|
+
trace: [],
|
|
25
|
+
observedMaxNodeSpend: { tokens: 0, usd: 0 },
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolve the cursor to the node about to run and its input. Inputs follow
|
|
30
|
+
* the graph's edges: a main-chain node consumes the value its predecessor
|
|
31
|
+
* emitted (for plan re-entries that is still research's Brief — the
|
|
32
|
+
* rejecting Verdict's findings travel via NodeContext.findings); the child
|
|
33
|
+
* sub-chain consumes the child contract, then the implement output.
|
|
34
|
+
*/
|
|
35
|
+
export function nextStep(graph, state) {
|
|
36
|
+
const cursor = state.cursor;
|
|
37
|
+
if (cursor.phase === 'done') {
|
|
38
|
+
throw new WorkflowError('executor_failed', 'internal: stepping a finished run');
|
|
39
|
+
}
|
|
40
|
+
if (cursor.phase === 'fanout') {
|
|
41
|
+
const child = state.children[cursor.childIndex];
|
|
42
|
+
const node = graph.childChain[cursor.sub];
|
|
43
|
+
if (child === undefined || node === undefined) {
|
|
44
|
+
throw new WorkflowError('corrupt_checkpoint', 'fan-out cursor points outside the run state');
|
|
45
|
+
}
|
|
46
|
+
const result = state.childResults[cursor.childIndex];
|
|
47
|
+
const input = cursor.sub === 0 ? child : result?.output;
|
|
48
|
+
return { node, input, child, childFindings: result?.findings ?? [] };
|
|
49
|
+
}
|
|
50
|
+
const node = nodeByName(graph, cursor.node);
|
|
51
|
+
if (node === undefined) {
|
|
52
|
+
throw new WorkflowError('corrupt_checkpoint', `cursor names unknown node "${cursor.node}"`);
|
|
53
|
+
}
|
|
54
|
+
return { node, input: mainInput(graph, node, state) };
|
|
55
|
+
}
|
|
56
|
+
/** The primary input of a main-chain node (see {@link nextStep}). */
|
|
57
|
+
function mainInput(graph, node, state) {
|
|
58
|
+
if (node.name === graph.entry)
|
|
59
|
+
return state.task;
|
|
60
|
+
if (node.kind === 'integrate')
|
|
61
|
+
return state.childResults;
|
|
62
|
+
const incoming = graph.edges.find((e) => e.to === node.name && e.when === undefined) ??
|
|
63
|
+
graph.edges.find((e) => e.to === node.name);
|
|
64
|
+
return incoming === undefined ? undefined : state.values[incoming.from];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Validate a node's emission against its declared contract before it
|
|
68
|
+
* crosses the edge [CLM-0042]. Collection emitters (decompose's children)
|
|
69
|
+
* validate element-wise. Throws a typed error naming node + contract.
|
|
70
|
+
*/
|
|
71
|
+
export function validateEmission(node, output) {
|
|
72
|
+
const schema = KNOWN_CONTRACTS[node.emits];
|
|
73
|
+
const checked = node.kind === 'decompose' ? z.array(schema).safeParse(output) : schema.safeParse(output);
|
|
74
|
+
if (!checked.success) {
|
|
75
|
+
throw new WorkflowError('edge_contract', `node "${node.name}" emitted a malformed ${node.emits}: ${z.prettifyError(checked.error)}`, { node: node.name, contract: node.emits });
|
|
76
|
+
}
|
|
77
|
+
return checked.data;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Synthesize the child contract for an overlay-added specialist (spec §6
|
|
81
|
+
* "add a specialist") [CLM-0045]. The entry adds WORK, not budget: its
|
|
82
|
+
* budget is zero so the decomposed children's budget-sum invariant (PM's
|
|
83
|
+
* job, spec §5.4) survives the addition; a composition root that wants a
|
|
84
|
+
* funded specialist makes its decompose executor slice for it.
|
|
85
|
+
*/
|
|
86
|
+
export function specialistChild(task, specialist) {
|
|
87
|
+
return TaskContractSchema.parse({
|
|
88
|
+
id: `${task.id}.${specialist}`,
|
|
89
|
+
parent: task.id,
|
|
90
|
+
goal: `specialist ${specialist}: ${task.goal}`,
|
|
91
|
+
constraints: task.constraints,
|
|
92
|
+
budget: { tokens: 0, usd: 0, wallClockMin: 0 },
|
|
93
|
+
evidence: [],
|
|
94
|
+
definitionOfDone: [],
|
|
95
|
+
authorityCeiling: task.authorityCeiling,
|
|
96
|
+
overlay: task.overlay,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/** Move the cursor into the fan-out, or past it when there are no children. */
|
|
100
|
+
function enterFanout(graph, state, from) {
|
|
101
|
+
const next = successor(graph, from);
|
|
102
|
+
if (state.children.length > 0) {
|
|
103
|
+
state.cursor = { phase: 'fanout', childIndex: 0, sub: 0 };
|
|
104
|
+
}
|
|
105
|
+
else if (next !== undefined) {
|
|
106
|
+
state.cursor = { phase: 'main', node: successor(graph, next.to)?.to ?? next.to };
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/** Apply a completed VOTE: branch on the Verdict, bounded by K [CLM-0043]. */
|
|
110
|
+
function advanceVote(graph, state, node, k) {
|
|
111
|
+
const verdict = state.values[node.name];
|
|
112
|
+
const disposition = verdictDisposition(verdict.result);
|
|
113
|
+
if (disposition === 'advance') {
|
|
114
|
+
const edge = successor(graph, node.name, 'approved');
|
|
115
|
+
if (edge !== undefined)
|
|
116
|
+
state.cursor = { phase: 'main', node: edge.to };
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
state.findings.push(...verdict.findings);
|
|
120
|
+
if (disposition === 'escalate') {
|
|
121
|
+
// The gate ruled "a human must decide" (#192): HALT as escalated IMMEDIATELY,
|
|
122
|
+
// regardless of K — not a re-iterate. A distinct haltReason lets an operator
|
|
123
|
+
// tell a deadlock from K-exhaustion. Cursor parks on the rejected edge so a
|
|
124
|
+
// resume after the human rules continues from plan [CLM-0043].
|
|
125
|
+
const edge = successor(graph, node.name, 'rejected');
|
|
126
|
+
if (edge !== undefined)
|
|
127
|
+
state.cursor = { phase: 'main', node: edge.to };
|
|
128
|
+
state.status = 'escalated';
|
|
129
|
+
state.haltReason = 'vote-escalation';
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (state.iteration >= k) {
|
|
133
|
+
// K re-entries exhausted: HALT as escalated, cursor parked at plan so a
|
|
134
|
+
// resume after the human edits continues from there [CLM-0043].
|
|
135
|
+
const edge = successor(graph, node.name, 'rejected');
|
|
136
|
+
if (edge !== undefined)
|
|
137
|
+
state.cursor = { phase: 'main', node: edge.to };
|
|
138
|
+
state.status = 'escalated';
|
|
139
|
+
state.haltReason = 'vote';
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
state.iteration += 1;
|
|
143
|
+
const edge = successor(graph, node.name, 'rejected');
|
|
144
|
+
if (edge !== undefined)
|
|
145
|
+
state.cursor = { phase: 'main', node: edge.to };
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Advance the fan-out cursor after one child sub-node completed — branch-aware,
|
|
149
|
+
* MIRRORING {@link advanceVote}. A driving gate (quality always; review only
|
|
150
|
+
* when promoted to enforce, the honesty guard) that rejects re-runs implement
|
|
151
|
+
* within Kc and budget [CLM-0043], or escalates the child at the bound; a
|
|
152
|
+
* passing gate (and any non-driving gate, whose findings fold in as hints)
|
|
153
|
+
* advances the sub-chain, then to the next child.
|
|
154
|
+
*/
|
|
155
|
+
function advanceChild(graph, state, output, opts) {
|
|
156
|
+
if (state.cursor.phase !== 'fanout')
|
|
157
|
+
return;
|
|
158
|
+
const { childIndex, sub } = state.cursor;
|
|
159
|
+
const result = state.childResults[childIndex];
|
|
160
|
+
if (result === undefined)
|
|
161
|
+
return;
|
|
162
|
+
// Route the sub-node's output to the right slot by its role, not its index,
|
|
163
|
+
// so the chain can grow (quality → review) without positional assumptions.
|
|
164
|
+
const subNode = graph.childChain[sub];
|
|
165
|
+
if (subNode?.gate === 'review') {
|
|
166
|
+
result.reviewVerdict = output;
|
|
167
|
+
}
|
|
168
|
+
else if (subNode?.gate === 'parsimony') {
|
|
169
|
+
result.parsimonyVerdict = output;
|
|
170
|
+
}
|
|
171
|
+
else if (subNode?.kind === 'gate') {
|
|
172
|
+
result.verdict = output;
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
result.output = output;
|
|
176
|
+
}
|
|
177
|
+
if (subNode?.kind === 'gate' &&
|
|
178
|
+
advanceChildGate(graph, state, subNode, output, opts)) {
|
|
179
|
+
return; // the gate branched (re-iterate or escalate); cursor already moved.
|
|
180
|
+
}
|
|
181
|
+
if (sub + 1 < graph.childChain.length) {
|
|
182
|
+
state.cursor = { phase: 'fanout', childIndex, sub: sub + 1 };
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
advanceToNextChild(graph, state, childIndex);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Apply a completed child gate: drive the iteration back-edge (quality, or
|
|
190
|
+
* review at enforce), or fold a non-driving gate's findings as hints. Returns
|
|
191
|
+
* true when the cursor branched (re-iterate or escalate at the bound) so the
|
|
192
|
+
* caller does not also advance the sub-chain — exactly as advanceVote owns the
|
|
193
|
+
* cursor on the rejected edge.
|
|
194
|
+
*/
|
|
195
|
+
function advanceChildGate(graph, state, gateNode, verdict, opts) {
|
|
196
|
+
if (state.cursor.phase !== 'fanout')
|
|
197
|
+
return false;
|
|
198
|
+
const result = state.childResults[state.cursor.childIndex];
|
|
199
|
+
if (result === undefined)
|
|
200
|
+
return false;
|
|
201
|
+
if (!gateDrivesIteration(gateNode, {
|
|
202
|
+
reviewDrives: opts.reviewDrivesIteration,
|
|
203
|
+
parsimonyDrives: opts.parsimonyDrivesIteration,
|
|
204
|
+
})) {
|
|
205
|
+
foldHints(result, verdict.findings);
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
const branch = childBranch(verdict, result, opts.kc, opts.childWithinBudget);
|
|
209
|
+
if (branch === 'pass')
|
|
210
|
+
return false;
|
|
211
|
+
if (branch === 'escalate') {
|
|
212
|
+
escalateChild(result, verdict.findings);
|
|
213
|
+
advanceToNextChild(graph, state, state.cursor.childIndex);
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
reiterateChild(state, result, verdict.findings);
|
|
217
|
+
opts.onIterate?.({
|
|
218
|
+
childId: result.child.id,
|
|
219
|
+
iteration: result.iteration,
|
|
220
|
+
gate: gateNode.gate ?? gateNode.name,
|
|
221
|
+
findingCount: result.findings.length,
|
|
222
|
+
});
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
/** Step to the next fan-out child, or back to the main chain after the last. */
|
|
226
|
+
export function advanceToNextChild(graph, state, childIndex) {
|
|
227
|
+
if (childIndex + 1 < state.children.length) {
|
|
228
|
+
state.cursor = { phase: 'fanout', childIndex: childIndex + 1, sub: 0 };
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
const fanout = graph.nodes.find((n) => n.kind === 'fanout');
|
|
232
|
+
const edge = fanout === undefined ? undefined : successor(graph, fanout.name);
|
|
233
|
+
// Integrate's input is the honest per-child aggregate (childResults):
|
|
234
|
+
// verdicts element-wise validated at the quality edge, failures carried
|
|
235
|
+
// alongside as error records — see mainInput's integrate special case.
|
|
236
|
+
state.cursor = edge === undefined ? { phase: 'done' } : { phase: 'main', node: edge.to };
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Apply one validated emission to the state and move the cursor. Mutates
|
|
241
|
+
* `state` (the engine snapshots per checkpoint). {@link AdvanceOptions} carries
|
|
242
|
+
* the vote bound K, the child-iterate bound Kc, overlay specialists, the
|
|
243
|
+
* review-drives-iteration honesty flag, the budget verdict, and the audit hook.
|
|
244
|
+
*/
|
|
245
|
+
export function advance(graph, state, node, output, opts) {
|
|
246
|
+
if (state.cursor.phase === 'fanout') {
|
|
247
|
+
advanceChild(graph, state, output, opts);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
state.values[node.name] = output;
|
|
251
|
+
if (node.kind === 'gate') {
|
|
252
|
+
advanceVote(graph, state, node, opts.k);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (node.kind === 'decompose') {
|
|
256
|
+
const children = output;
|
|
257
|
+
state.children = [...children, ...opts.specialists.map((s) => specialistChild(state.task, s))];
|
|
258
|
+
state.childResults = state.children.map((child) => ({ child, iteration: 0, findings: [] }));
|
|
259
|
+
enterFanout(graph, state, node.name);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
if (node.kind === 'retrospect') {
|
|
263
|
+
state.cursor = { phase: 'done' };
|
|
264
|
+
state.status = 'completed';
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
const edge = successor(graph, node.name);
|
|
268
|
+
state.cursor = edge === undefined ? { phase: 'done' } : { phase: 'main', node: edge.to };
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=steps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steps.js","sourceRoot":"","sources":["../src/steps.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,eAAe,EACf,kBAAkB,GAInB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAiC,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,aAAa,EAAiB,MAAM,YAAY,CAAC;AAC1D,OAAO,EACL,WAAW,EACX,aAAa,EACb,SAAS,EACT,mBAAmB,EACnB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AA4C9D,+CAA+C;AAC/C,MAAM,UAAU,YAAY,CAAC,IAAkB,EAAE,KAAa;IAC5D,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE;QACtC,SAAS,EAAE,CAAC;QACZ,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE,EAAE;QACZ,QAAQ,EAAE,EAAE;QACZ,YAAY,EAAE,EAAE;QAChB,KAAK,EAAE,EAAE;QACT,oBAAoB,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;KAC5C,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAgB,EAAE,KAAe;IACxD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC5B,IAAI,MAAM,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;QAC5B,MAAM,IAAI,aAAa,CAAC,iBAAiB,EAAE,mCAAmC,CAAC,CAAC;IAClF,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9C,MAAM,IAAI,aAAa,CAAC,oBAAoB,EAAE,6CAA6C,CAAC,CAAC;QAC/F,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC;QACxD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,IAAI,EAAE,EAAE,CAAC;IACvE,CAAC;IACD,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,IAAI,aAAa,CAAC,oBAAoB,EAAE,8BAA8B,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;IAC9F,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;AACxD,CAAC;AAED,qEAAqE;AACrE,SAAS,SAAS,CAAC,KAAgB,EAAE,IAAc,EAAE,KAAe;IAClE,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC;IACjD,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC,YAAY,CAAC;IACzD,MAAM,QAAQ,GACZ,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC;QACnE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC1E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAc,EAAE,MAAe;IAC9D,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,OAAO,GACX,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC3F,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,aAAa,CACrB,eAAe,EACf,SAAS,IAAI,CAAC,IAAI,yBAAyB,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,EAC1F,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE,CAC1C,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,CAAC;AACtB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAkB,EAAE,UAAkB;IACpE,OAAO,kBAAkB,CAAC,KAAK,CAAC;QAC9B,EAAE,EAAE,GAAG,IAAI,CAAC,EAAE,IAAI,UAAU,EAAE;QAC9B,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,IAAI,EAAE,cAAc,UAAU,KAAK,IAAI,CAAC,IAAI,EAAE;QAC9C,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE;QAC9C,QAAQ,EAAE,EAAE;QACZ,gBAAgB,EAAE,EAAE;QACpB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;QACvC,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC;AACL,CAAC;AAED,+EAA+E;AAC/E,SAAS,WAAW,CAAC,KAAgB,EAAE,KAAe,EAAE,IAAY;IAClE,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACpC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,KAAK,CAAC,MAAM,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IAC5D,CAAC;SAAM,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,KAAK,CAAC,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;IACnF,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,SAAS,WAAW,CAAC,KAAgB,EAAE,KAAe,EAAE,IAAc,EAAE,CAAS;IAC/E,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAY,CAAC;IACnD,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACrD,IAAI,IAAI,KAAK,SAAS;YAAE,KAAK,CAAC,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;QACxE,OAAO;IACT,CAAC;IACD,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,WAAW,KAAK,UAAU,EAAE,CAAC;QAC/B,8EAA8E;QAC9E,6EAA6E;QAC7E,4EAA4E;QAC5E,+DAA+D;QAC/D,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACrD,IAAI,IAAI,KAAK,SAAS;YAAE,KAAK,CAAC,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;QACxE,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC;QAC3B,KAAK,CAAC,UAAU,GAAG,iBAAiB,CAAC;QACrC,OAAO;IACT,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,IAAI,CAAC,EAAE,CAAC;QACzB,wEAAwE;QACxE,gEAAgE;QAChE,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACrD,IAAI,IAAI,KAAK,SAAS;YAAE,KAAK,CAAC,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;QACxE,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC;QAC3B,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC;QAC1B,OAAO;IACT,CAAC;IACD,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC;IACrB,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACrD,IAAI,IAAI,KAAK,SAAS;QAAE,KAAK,CAAC,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;AAC1E,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,YAAY,CACnB,KAAgB,EAChB,KAAe,EACf,MAAe,EACf,IAAoB;IAEpB,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO;IAC5C,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC;IACzC,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;IAC9C,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO;IACjC,4EAA4E;IAC5E,2EAA2E;IAC3E,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,OAAO,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,aAAa,GAAG,MAAiB,CAAC;IAC3C,CAAC;SAAM,IAAI,OAAO,EAAE,IAAI,KAAK,WAAW,EAAE,CAAC;QACzC,MAAM,CAAC,gBAAgB,GAAG,MAAiB,CAAC;IAC9C,CAAC;SAAM,IAAI,OAAO,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;QACpC,MAAM,CAAC,OAAO,GAAG,MAAiB,CAAC;IACrC,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;IACD,IACE,OAAO,EAAE,IAAI,KAAK,MAAM;QACxB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAiB,EAAE,IAAI,CAAC,EAChE,CAAC;QACD,OAAO,CAAC,oEAAoE;IAC9E,CAAC;IACD,IAAI,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;QACtC,KAAK,CAAC,MAAM,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC;IAC/D,CAAC;SAAM,CAAC;QACN,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,gBAAgB,CACvB,KAAgB,EAChB,KAAe,EACf,QAAkB,EAClB,OAAgB,EAChB,IAAoB;IAEpB,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAClD,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3D,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACvC,IACE,CAAC,mBAAmB,CAAC,QAAQ,EAAE;QAC7B,YAAY,EAAE,IAAI,CAAC,qBAAqB;QACxC,eAAe,EAAE,IAAI,CAAC,wBAAwB;KAC/C,CAAC,EACF,CAAC;QACD,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QACpC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC7E,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACpC,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QACxC,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE;QACxB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI;QACpC,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM;KACrC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,kBAAkB,CAAC,KAAgB,EAAE,KAAe,EAAE,UAAkB;IACtF,IAAI,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC3C,KAAK,CAAC,MAAM,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IACzE,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;QAC5D,MAAM,IAAI,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9E,sEAAsE;QACtE,wEAAwE;QACxE,uEAAuE;QACvE,KAAK,CAAC,MAAM,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;IAC3F,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CACrB,KAAgB,EAChB,KAAe,EACf,IAAc,EACd,MAAe,EACf,IAAoB;IAEpB,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACpC,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QACzC,OAAO;IACT,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;IACjC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QACxC,OAAO;IACT,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,MAAwB,CAAC;QAC1C,KAAK,CAAC,QAAQ,GAAG,CAAC,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/F,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5F,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,OAAO;IACT,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QAC/B,KAAK,CAAC,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QACjC,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC;QAC3B,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,KAAK,CAAC,MAAM,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;AAC3F,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single routing classifier for a {@link VerdictResult} (#192). Every place
|
|
3
|
+
* the canonical loop branches on a gate's verdict goes through this function, so
|
|
4
|
+
* that growing the Frozen-Five `VerdictResult` enum is a COMPILE error here (the
|
|
5
|
+
* `never`-exhaustiveness guard in the `default` arm) rather than a silent
|
|
6
|
+
* mis-route at a scattered `=== 'pass'` comparison — the latent-defect class the
|
|
7
|
+
* #192 consumer audit found.
|
|
8
|
+
*
|
|
9
|
+
* Three dispositions:
|
|
10
|
+
* - `advance` — the gate cleared (`approve`/`pass`): proceed.
|
|
11
|
+
* - `escalate` — the gate ruled "a human must decide" (`escalate`, #192): the
|
|
12
|
+
* loop HALTS as escalated and surfaces to the operator (never a silent pass,
|
|
13
|
+
* never an automatic reject). Not a synchronous prompt — an autonomous loop
|
|
14
|
+
* has no human present at the moment of escalation.
|
|
15
|
+
* - `block` — the gate did not clear (`reject`/`fail`/`abstain`): re-iterate
|
|
16
|
+
* within bounds, else escalate at the bound (the pre-existing behavior).
|
|
17
|
+
*/
|
|
18
|
+
import type { VerdictResult } from '@kernloop/contracts';
|
|
19
|
+
/** How the loop routes a verdict — see {@link verdictDisposition}. */
|
|
20
|
+
export type VerdictDisposition = 'advance' | 'escalate' | 'block';
|
|
21
|
+
/** Classify a {@link VerdictResult} into its loop routing disposition (#192). */
|
|
22
|
+
export declare function verdictDisposition(result: VerdictResult): VerdictDisposition;
|
|
23
|
+
//# sourceMappingURL=verdict-disposition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verdict-disposition.d.ts","sourceRoot":"","sources":["../src/verdict-disposition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,sEAAsE;AACtE,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AAElE,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,kBAAkB,CAgB5E"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Classify a {@link VerdictResult} into its loop routing disposition (#192). */
|
|
2
|
+
export function verdictDisposition(result) {
|
|
3
|
+
switch (result) {
|
|
4
|
+
case 'approve':
|
|
5
|
+
case 'pass':
|
|
6
|
+
return 'advance';
|
|
7
|
+
case 'escalate':
|
|
8
|
+
return 'escalate';
|
|
9
|
+
case 'reject':
|
|
10
|
+
case 'fail':
|
|
11
|
+
case 'abstain':
|
|
12
|
+
return 'block';
|
|
13
|
+
/* v8 ignore next 2 -- unreachable: every VerdictResult is handled above; the
|
|
14
|
+
default exists only as the compile-time exhaustiveness guard (see below). */
|
|
15
|
+
default:
|
|
16
|
+
return assertUnreachableResult(result);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Compile-time exhaustiveness guard: if a new `VerdictResult` value is added
|
|
21
|
+
* without a `case` above, `result` is no longer `never` here and this fails to
|
|
22
|
+
* typecheck — forcing the new disposition to be handled, not silently dropped.
|
|
23
|
+
*/
|
|
24
|
+
/* v8 ignore next 3 -- the guard never runs while the switch is exhaustive */
|
|
25
|
+
function assertUnreachableResult(result) {
|
|
26
|
+
throw new Error(`unhandled VerdictResult: ${String(result)}`);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=verdict-disposition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verdict-disposition.js","sourceRoot":"","sources":["../src/verdict-disposition.ts"],"names":[],"mappings":"AAsBA,iFAAiF;AACjF,MAAM,UAAU,kBAAkB,CAAC,MAAqB;IACtD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,SAAS,CAAC;QACf,KAAK,MAAM;YACT,OAAO,SAAS,CAAC;QACnB,KAAK,UAAU;YACb,OAAO,UAAU,CAAC;QACpB,KAAK,QAAQ,CAAC;QACd,KAAK,MAAM,CAAC;QACZ,KAAK,SAAS;YACZ,OAAO,OAAO,CAAC;QACjB;uFAC+E;QAC/E;YACE,OAAO,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,6EAA6E;AAC7E,SAAS,uBAAuB,CAAC,MAAa;IAC5C,MAAM,IAAI,KAAK,CAAC,4BAA4B,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAChE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kernloop/workflows",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Kernloop Layer 3 — the canonical loop as data plus the execution engine (spec §6): one blessed graph, per-node checkpoint/resume, and the K-bounded vote-iterate cycle. All real work (model calls, gates, memory) arrives as injected node executors; checkpoint persistence arrives as an injected storage interface — this package imports contracts and zod only.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"zod": "^4.4.3",
|
|
20
|
+
"@kernloop/contracts": "0.1.0"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/node": "^25.9.3"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git+https://github.com/kernloop/kernloop.git",
|
|
31
|
+
"directory": "packages/workflows"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsc -p tsconfig.json",
|
|
35
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
36
|
+
"test": "vitest run --coverage"
|
|
37
|
+
}
|
|
38
|
+
}
|