@rulvar/plan 1.0.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 +202 -0
- package/dist/index.d.ts +1338 -0
- package/dist/index.js +6700 -0
- package/package.json +48 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1338 @@
|
|
|
1
|
+
import { AdmissionDecision, AgentResult, CanonicalLadderSpec, ChatRequest, Effort, Engine, EntryRef, EscalationDecision, EscalationOptions, HashVersion, IsolationSpec, JournalEntry, JournalStore, Json, KeyDeriver, LadderSpec, LeasableStore, LineageStats, LogicalTaskId, NodeId, OrchestrateOptions, OrchestratorExtension, ProviderAdapter, ReuseConfig, RunHandle, SchemaSpec, SpawnLineageOpt, TerminationAccountSnapshot, TerminationLimits, ToolDef, TriggerClass, UsageLimits, WireError } from "@rulvar/core";
|
|
2
|
+
|
|
3
|
+
//#region src/plan-state.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* The single sequential scope holding every plan-mutating entry, inside
|
|
6
|
+
* the orchestrator's run scope (docs/07, 3.2): total order = ordinal
|
|
7
|
+
* order = durable append order. Child node scopes are `plan/NodeId`
|
|
8
|
+
* (core `planNodeScope`; grammar in docs/03, section 2.1).
|
|
9
|
+
*/
|
|
10
|
+
declare const PLAN_SCOPE = "plan";
|
|
11
|
+
/** The closed status machine (docs/07, 3.1); `skipped` is fold-derived for entries but first-class for plan nodes. */
|
|
12
|
+
type PlanNodeStatus = "pending" | "ready" | "running" | "parked" | "escalated" | "done" | "failed" | "cancelled" | "skipped";
|
|
13
|
+
/**
|
|
14
|
+
* Canonical per-node fields entering planHash, exactly the docs/07 3.1
|
|
15
|
+
* record. `deps` are sorted in the hash (not necessarily in state);
|
|
16
|
+
* `checkpointRef`/`escalationRef` participate as absent when absent.
|
|
17
|
+
*/
|
|
18
|
+
interface PlanNode {
|
|
19
|
+
/** ULID minted inside plan.revision. */
|
|
20
|
+
nodeId: NodeId;
|
|
21
|
+
/** Lineage identity across rebirths (section 8, DEF-3). */
|
|
22
|
+
logicalTaskId: LogicalTaskId;
|
|
23
|
+
status: PlanNodeStatus;
|
|
24
|
+
deps: NodeId[];
|
|
25
|
+
waivedDeps: NodeId[];
|
|
26
|
+
/** Set by park_task on a running node; the park lands at the turn boundary. */
|
|
27
|
+
parkRequested: boolean;
|
|
28
|
+
/** Set by cancel_task on a running node; the cancel lands via plan.decision. */
|
|
29
|
+
cancelRequested: boolean;
|
|
30
|
+
priority: number;
|
|
31
|
+
promptSpecHash: string;
|
|
32
|
+
checkpointRef?: EntryRef;
|
|
33
|
+
escalationRef?: EntryRef;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* TaskPlan: typed data owned by the engine, never prose in a transcript
|
|
37
|
+
* (docs/07, 3.1). The guard fold counters ride the same record because
|
|
38
|
+
* they enter planHash (docs/07, 3.4): `revisionCount` counts journaled
|
|
39
|
+
* plan.revision entries; `droppedRevisionStreak` counts consecutive
|
|
40
|
+
* fully-dropped revisions (RevisionGuards, docs/07, 3.8).
|
|
41
|
+
*/
|
|
42
|
+
interface TaskPlan {
|
|
43
|
+
nodes: Readonly<Record<NodeId, PlanNode>>;
|
|
44
|
+
revisionCount: number;
|
|
45
|
+
droppedRevisionStreak: number;
|
|
46
|
+
}
|
|
47
|
+
/** The empty plan every fold starts from. */
|
|
48
|
+
declare function emptyPlan(): TaskPlan;
|
|
49
|
+
declare function isTerminalPlanStatus(status: PlanNodeStatus): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Asserts one status transition against the closed machine. Op-level
|
|
52
|
+
* legality (which ops may request which transitions in which state) is
|
|
53
|
+
* the rebase conflict table's job (docs/07, 3.6; M7-T04); the machine
|
|
54
|
+
* itself enforces exactly the structural rules:
|
|
55
|
+
*
|
|
56
|
+
* - nothing leaves a terminal status (`done` is immutable; failed,
|
|
57
|
+
* cancelled, skipped are final),
|
|
58
|
+
* - `running` is entered only from `ready` (the engine schedules ready
|
|
59
|
+
* nodes; docs/07, 3.1),
|
|
60
|
+
* - a transition never restates the current status (the engine writes no
|
|
61
|
+
* no-op set_node_status).
|
|
62
|
+
*
|
|
63
|
+
* A violation is an engine bug and raises the typed PlanInvariantError
|
|
64
|
+
* (docs/07, 3.4: never a silent brick).
|
|
65
|
+
*/
|
|
66
|
+
declare function assertPlanTransition(node: PlanNode, to: PlanNodeStatus): void;
|
|
67
|
+
/**
|
|
68
|
+
* Dependency satisfaction, derived purely in the fold and NEVER a record
|
|
69
|
+
* (docs/07, 3.3): a dep is satisfied when waived or when its upstream
|
|
70
|
+
* node is `done`. Terminally unsuccessful upstreams (cancelled, failed)
|
|
71
|
+
* keep blocking: such edges "remain blocking" per the rewire_deps row of
|
|
72
|
+
* the conflict table, and waive_dep exists exactly to unblock them.
|
|
73
|
+
*/
|
|
74
|
+
declare function depsSatisfied(plan: TaskPlan, node: PlanNode): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Recomputes the derived pending/ready boundary after a fold step: every
|
|
77
|
+
* schedulable node (currently pending or ready) becomes `ready` when its
|
|
78
|
+
* deps are satisfied and `pending` otherwise. rewire_deps may regress a
|
|
79
|
+
* ready node to pending; upstream `done` transitions and waives promote
|
|
80
|
+
* pending to ready. All other statuses are untouched. Returns the same
|
|
81
|
+
* plan object when nothing changed, so fold steps stay cheap.
|
|
82
|
+
*/
|
|
83
|
+
declare function recomputePlanReadiness(plan: TaskPlan): TaskPlan;
|
|
84
|
+
/**
|
|
85
|
+
* Cycle check for rewire_deps (docs/07, 3.6: a resulting cycle drops the
|
|
86
|
+
* WHOLE op with dep_cycle; rewire_deps is atomic). Answers whether the
|
|
87
|
+
* graph with `nodeId`'s deps replaced by `deps` contains a cycle
|
|
88
|
+
* reachable from `nodeId`. add_task cannot create cycles (nothing depends
|
|
89
|
+
* on a node that does not exist yet), so the check is rewire-only.
|
|
90
|
+
*/
|
|
91
|
+
declare function wouldCreateDepCycle(plan: TaskPlan, nodeId: NodeId, deps: readonly NodeId[]): boolean;
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region src/plan-hash.d.ts
|
|
94
|
+
/** The hashVersion whose profile computes planHash today. */
|
|
95
|
+
declare const PLAN_HASH_VERSION: HashVersion;
|
|
96
|
+
/**
|
|
97
|
+
* The canonical JSON projection of PlanState: nodes sorted by NodeId plus
|
|
98
|
+
* the guard fold counters, nothing else (docs/07, 3.4).
|
|
99
|
+
*/
|
|
100
|
+
declare function canonicalPlanState(plan: TaskPlan): Record<string, unknown>;
|
|
101
|
+
/**
|
|
102
|
+
* planHash under one deriver profile (default: the current hashVersion 2
|
|
103
|
+
* profile). Replay recomputes each entry's planHashAfter with the
|
|
104
|
+
* predicate of that entry's OWN hashVersion (docs/07, 3.4), so the
|
|
105
|
+
* deriver is a parameter, not an ambient.
|
|
106
|
+
*/
|
|
107
|
+
declare function planHash(plan: TaskPlan, deriver?: KeyDeriver): string;
|
|
108
|
+
/**
|
|
109
|
+
* The append-time head assertion (docs/07, 3.4): planHashBefore of the
|
|
110
|
+
* entry being appended MUST equal the current fold head. A failure is an
|
|
111
|
+
* engine bug and raises the typed PlanInvariantError; the run finishes
|
|
112
|
+
* with outcome error, never a silent brick.
|
|
113
|
+
*/
|
|
114
|
+
declare function assertPlanHead(plan: TaskPlan, expectedPlanHash: string, context?: {
|
|
115
|
+
entryRef?: EntryRef;
|
|
116
|
+
operation?: string;
|
|
117
|
+
}): void;
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/write-lock.d.ts
|
|
120
|
+
/**
|
|
121
|
+
* PlanWriteLock (M7-T01): the in-process FIFO mutex serializing live
|
|
122
|
+
* appends to the sequential scope "plan".
|
|
123
|
+
*
|
|
124
|
+
* Owning spec: docs/07-adaptive-orchestration-spec.md, section 3.2
|
|
125
|
+
* (DEF-8, XF-07). The lock serializes ONLY plan-scope appends (acquire,
|
|
126
|
+
* read the fold head, evaluate, append, release); it MUST NOT substitute
|
|
127
|
+
* for resolution arbitration, which is owned by the ResolutionArbiter
|
|
128
|
+
* (docs/03, section "Suspension and resolutions (DEF-4)"). In queue mode
|
|
129
|
+
* the lease fencing epoch applies on top. Wall clock influences only
|
|
130
|
+
* WHICH order gets recorded live; replay reads the recorded order and
|
|
131
|
+
* never takes the lock.
|
|
132
|
+
*/
|
|
133
|
+
declare class PlanWriteLock {
|
|
134
|
+
private tail;
|
|
135
|
+
private held;
|
|
136
|
+
/** True while a critical section is running (diagnostics only). */
|
|
137
|
+
get isHeld(): boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Runs `fn` exclusively, in strict acquisition (FIFO) order. The lock
|
|
140
|
+
* releases on settlement either way; a rejection propagates to THIS
|
|
141
|
+
* caller and never poisons later acquisitions.
|
|
142
|
+
*/
|
|
143
|
+
runExclusive<T>(fn: () => Promise<T> | T): Promise<T>;
|
|
144
|
+
}
|
|
145
|
+
//#endregion
|
|
146
|
+
//#region src/task-spec.d.ts
|
|
147
|
+
interface TaskSpec {
|
|
148
|
+
/** Registered agent profile name; models are never named here. */
|
|
149
|
+
agentType: string;
|
|
150
|
+
prompt: string;
|
|
151
|
+
/** Registered SchemaSpec name (docs/08); registry lands in M7-T05. */
|
|
152
|
+
outputSchemaRef?: string;
|
|
153
|
+
/** Registered tool profile name (docs/08); registry lands in M7-T05. */
|
|
154
|
+
toolsetRef?: string;
|
|
155
|
+
isolation?: IsolationSpec;
|
|
156
|
+
usageLimits?: Partial<UsageLimits>;
|
|
157
|
+
/** Clamped by childBudgetFraction at admission. */
|
|
158
|
+
budgetUsd?: number;
|
|
159
|
+
/** The ONLY model influence the orchestrator has (docs/07, 4.1). */
|
|
160
|
+
model_hint?: {
|
|
161
|
+
startTier: number;
|
|
162
|
+
};
|
|
163
|
+
/** Slug entering approachSig, at most 32 chars after normalization. */
|
|
164
|
+
approach?: string;
|
|
165
|
+
/** Absence means a new lineage root (docs/07, 8.1). */
|
|
166
|
+
lineage?: SpawnLineageOpt;
|
|
167
|
+
/** Default 'unclassified' (taskClass binding OQ, docs/14). */
|
|
168
|
+
taskClass?: string;
|
|
169
|
+
/** Absence means the child cannot escalate (docs/07, 6.4). */
|
|
170
|
+
escalation?: EscalationOptions;
|
|
171
|
+
}
|
|
172
|
+
/** The amend_task patch form: every field optional (docs/07, 4.7). */
|
|
173
|
+
type TaskSpecPatch = Partial<TaskSpec>;
|
|
174
|
+
/**
|
|
175
|
+
* The deterministic spec digest entering PlanNode.promptSpecHash
|
|
176
|
+
* (docs/07, 3.1): the canonical JSON of the full TaskSpec through the
|
|
177
|
+
* frozen hashVersion 2 canonicalization. A plan-internal digest, not a
|
|
178
|
+
* kernel content key: the paid-call identity stays with the child's own
|
|
179
|
+
* spawn entry.
|
|
180
|
+
*/
|
|
181
|
+
declare function promptSpecHashOf(spec: TaskSpec): string;
|
|
182
|
+
/** Applies an amend_task patch onto a spec (undefined fields untouched). */
|
|
183
|
+
declare function applyTaskSpecPatch(spec: TaskSpec, patch: TaskSpecPatch): TaskSpec;
|
|
184
|
+
//#endregion
|
|
185
|
+
//#region src/plan-entries.d.ts
|
|
186
|
+
/** The orchestrator-facing PlanOp union (docs/07, 4.7). */
|
|
187
|
+
type PlanOp = {
|
|
188
|
+
op: "add_task";
|
|
189
|
+
spec: TaskSpec;
|
|
190
|
+
deps?: NodeId[];
|
|
191
|
+
priority?: number;
|
|
192
|
+
lineage?: SpawnLineageOpt;
|
|
193
|
+
approach?: string; /** Forbids reuse-by-reference for this addition (DEF-5). */
|
|
194
|
+
fresh?: boolean;
|
|
195
|
+
} | {
|
|
196
|
+
op: "amend_task";
|
|
197
|
+
nodeId: NodeId;
|
|
198
|
+
spec: TaskSpecPatch;
|
|
199
|
+
} | {
|
|
200
|
+
op: "park_task";
|
|
201
|
+
nodeId: NodeId;
|
|
202
|
+
} | {
|
|
203
|
+
op: "unpark_task";
|
|
204
|
+
nodeId: NodeId;
|
|
205
|
+
} | {
|
|
206
|
+
op: "cancel_task";
|
|
207
|
+
nodeId: NodeId;
|
|
208
|
+
reason?: string;
|
|
209
|
+
} | {
|
|
210
|
+
op: "reprioritize";
|
|
211
|
+
nodeId: NodeId;
|
|
212
|
+
priority: number;
|
|
213
|
+
} | {
|
|
214
|
+
op: "rewire_deps";
|
|
215
|
+
nodeId: NodeId;
|
|
216
|
+
deps: NodeId[];
|
|
217
|
+
} | {
|
|
218
|
+
op: "waive_dep";
|
|
219
|
+
nodeId: NodeId;
|
|
220
|
+
dep: NodeId;
|
|
221
|
+
};
|
|
222
|
+
/**
|
|
223
|
+
* Applied forms the fold consumes. cancel_task gains the engine-computed
|
|
224
|
+
* cascade (docs/07, 3.6: computed at apply time, never a parameter);
|
|
225
|
+
* park/cancel against running nodes apply as flag requests landing later
|
|
226
|
+
* via plan.decision (park-landed, cancel-landed).
|
|
227
|
+
*/
|
|
228
|
+
type AppliedPlanOp = (Extract<PlanOp, {
|
|
229
|
+
op: "add_task";
|
|
230
|
+
}> & {
|
|
231
|
+
nodeId: NodeId;
|
|
232
|
+
}) | Extract<PlanOp, {
|
|
233
|
+
op: "amend_task";
|
|
234
|
+
}> | {
|
|
235
|
+
op: "park_task";
|
|
236
|
+
nodeId: NodeId;
|
|
237
|
+
requestOnly?: boolean;
|
|
238
|
+
} | {
|
|
239
|
+
op: "unpark_task";
|
|
240
|
+
nodeId: NodeId;
|
|
241
|
+
restart?: boolean;
|
|
242
|
+
} | {
|
|
243
|
+
op: "cancel_task";
|
|
244
|
+
nodeId: NodeId;
|
|
245
|
+
reason?: string;
|
|
246
|
+
requestOnly?: boolean;
|
|
247
|
+
cascadeNodeIds?: NodeId[];
|
|
248
|
+
} | Extract<PlanOp, {
|
|
249
|
+
op: "reprioritize";
|
|
250
|
+
}> | {
|
|
251
|
+
op: "rewire_deps";
|
|
252
|
+
nodeId: NodeId;
|
|
253
|
+
deps: NodeId[];
|
|
254
|
+
} | Extract<PlanOp, {
|
|
255
|
+
op: "waive_dep";
|
|
256
|
+
}>;
|
|
257
|
+
/** The complete machine reason vocabulary, normative and closed (docs/07, 3.5). */
|
|
258
|
+
type RebaseReasonCode = "admission_denied" | "node_already_done" | "dep_already_resolved" | "node_escalated" | "node_running" | "terminal_status" | "dep_cycle" | "already_parked" | "not_parked" | "no_such_dep" | "already_waived" | "bad_base" | "lineage_exhausted" | "lineage_busy" | "plan_frozen" | "checkpoint_discarded" | "reuse_by_reference" | "resolved_escalation" | "immediate_satisfaction";
|
|
259
|
+
type RebaseOutcome = {
|
|
260
|
+
kind: "applied";
|
|
261
|
+
op: AppliedPlanOp;
|
|
262
|
+
} | {
|
|
263
|
+
kind: "transformed";
|
|
264
|
+
requested: PlanOp;
|
|
265
|
+
applied: AppliedPlanOp;
|
|
266
|
+
reason: RebaseReasonCode;
|
|
267
|
+
} | {
|
|
268
|
+
kind: "dropped";
|
|
269
|
+
requested: PlanOp;
|
|
270
|
+
reason: RebaseReasonCode;
|
|
271
|
+
blockingRef?: EntryRef;
|
|
272
|
+
};
|
|
273
|
+
interface PlanSnapshotRef {
|
|
274
|
+
/** Ordinal of the WakeDigest that plan_view is pinned to. */
|
|
275
|
+
digestSeq: number;
|
|
276
|
+
/** Plan hash recorded in that WakeDigest. */
|
|
277
|
+
planHash: string;
|
|
278
|
+
}
|
|
279
|
+
interface PlanReviseRequest {
|
|
280
|
+
/** Mandatory; the call is rejected without it (docs/07, 3.5). */
|
|
281
|
+
base: PlanSnapshotRef;
|
|
282
|
+
ops: PlanOp[];
|
|
283
|
+
rationale: string;
|
|
284
|
+
}
|
|
285
|
+
/** The canonical result form (XF-11): DEF-8 shape plus the DEF-2 balance. */
|
|
286
|
+
interface PlanReviseResult {
|
|
287
|
+
outcomes: RebaseOutcome[];
|
|
288
|
+
assignedNodeIds: Record<number, NodeId>;
|
|
289
|
+
planHashAfter: string;
|
|
290
|
+
droppedAll: boolean;
|
|
291
|
+
revisionUnitsRemaining: number;
|
|
292
|
+
}
|
|
293
|
+
type PlanReviseErrorCode = "revision_budget_exhausted" | RebaseReasonCode;
|
|
294
|
+
/** One embedded admission beside its op (docs/07, 3.3; DEF-2/DEF-3 folds read it). */
|
|
295
|
+
interface PlanRevisionAdmission {
|
|
296
|
+
opIndex: number;
|
|
297
|
+
nodeId?: NodeId;
|
|
298
|
+
decision: AdmissionDecision;
|
|
299
|
+
/** Reuse placement recorded beside a reuse_full/admit_graft verdict (DEF-5). */
|
|
300
|
+
reuse?: {
|
|
301
|
+
donorScope: string;
|
|
302
|
+
chain: string[];
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
/** The value payload of a plan.revision entry (docs/07, 3.3; XF-11). */
|
|
306
|
+
interface PlanRevisionValue {
|
|
307
|
+
base: PlanSnapshotRef;
|
|
308
|
+
requestedOps: PlanOp[];
|
|
309
|
+
/** Same length and order as requestedOps. */
|
|
310
|
+
outcomes: RebaseOutcome[];
|
|
311
|
+
assignedNodeIds: Record<number, NodeId>;
|
|
312
|
+
admissions: PlanRevisionAdmission[];
|
|
313
|
+
planHashBefore: string;
|
|
314
|
+
planHashAfter: string;
|
|
315
|
+
hashVersion: HashVersion;
|
|
316
|
+
/** Cosmetic: never enters the content key. */
|
|
317
|
+
rationale: string;
|
|
318
|
+
/** DEF-2 extensions. */
|
|
319
|
+
revisionUnitsAfter?: number;
|
|
320
|
+
debits?: Array<{
|
|
321
|
+
resource: string;
|
|
322
|
+
logicalTaskId?: LogicalTaskId;
|
|
323
|
+
balanceAfter: number;
|
|
324
|
+
}>;
|
|
325
|
+
}
|
|
326
|
+
/** Engine authorship origins of plan.decision entries (docs/07, 3.3). */
|
|
327
|
+
type PlanDecisionOrigin = "escalation-default" | "escalation-class" | "escalation-live" | "no-progress" | "child-result" | "park-landed" | "cancel-landed";
|
|
328
|
+
/** The closed EnginePlanOp set (docs/07, 3.3). */
|
|
329
|
+
type EnginePlanOp = {
|
|
330
|
+
kind: "set_node_status";
|
|
331
|
+
nodeId: NodeId;
|
|
332
|
+
from: PlanNodeStatus;
|
|
333
|
+
to: PlanNodeStatus;
|
|
334
|
+
cause: "child-result" | "no-progress" | "park-landed" | "cancel-landed";
|
|
335
|
+
causeRef: EntryRef; /** The retained checkpoint anchor recorded at park landing (M7-T08). */
|
|
336
|
+
checkpointRef?: EntryRef;
|
|
337
|
+
} | {
|
|
338
|
+
kind: "resolve_escalation";
|
|
339
|
+
nodeId: NodeId;
|
|
340
|
+
decision: EscalationDecision;
|
|
341
|
+
resolvedBy: "default" | "class" | "live" | "revision-transform";
|
|
342
|
+
escalationRef: EntryRef;
|
|
343
|
+
} | {
|
|
344
|
+
kind: "spawn_admitted";
|
|
345
|
+
nodes: Array<{
|
|
346
|
+
nodeId: NodeId;
|
|
347
|
+
logicalTaskId: LogicalTaskId;
|
|
348
|
+
spec: TaskSpec;
|
|
349
|
+
}>;
|
|
350
|
+
admission: AdmissionDecision;
|
|
351
|
+
};
|
|
352
|
+
/** The value payload of a plan.decision entry (docs/07, 3.3). */
|
|
353
|
+
interface PlanDecisionValue {
|
|
354
|
+
origin: PlanDecisionOrigin;
|
|
355
|
+
ops: EnginePlanOp[];
|
|
356
|
+
causeRef: EntryRef;
|
|
357
|
+
planHashBefore: string;
|
|
358
|
+
planHashAfter: string;
|
|
359
|
+
hashVersion: HashVersion;
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Content keys (docs/07, 3.3): plan.revision keys over {kind, base,
|
|
363
|
+
* requestedOps}; plan.decision over {kind, origin, ops, causeRef}.
|
|
364
|
+
* Cosmetics (rationale) never enter a key; ordinal within scope "plan"
|
|
365
|
+
* distinguishes repeats, so forward-matching works without kernel
|
|
366
|
+
* changes.
|
|
367
|
+
*/
|
|
368
|
+
declare function planRevisionKey(base: PlanSnapshotRef, requestedOps: readonly PlanOp[]): string;
|
|
369
|
+
declare function planDecisionKey(origin: PlanDecisionOrigin, ops: readonly EnginePlanOp[], causeRef: EntryRef): string;
|
|
370
|
+
/**
|
|
371
|
+
* The working state the applier threads: the hashed TaskPlan plus the
|
|
372
|
+
* resolved spec table. Specs stay OUT of planHash by construction (the
|
|
373
|
+
* hashed projection is promptSpecHash per node, docs/07 3.1) but are
|
|
374
|
+
* themselves a pure fold of add_task specs, amend patches, and
|
|
375
|
+
* decomposition specs, so live and replay converge byte-identically.
|
|
376
|
+
*/
|
|
377
|
+
interface PlanWorking {
|
|
378
|
+
plan: TaskPlan;
|
|
379
|
+
specs: Readonly<Record<NodeId, TaskSpec>>;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* The plan fold state: the working state plus fold-side records that
|
|
383
|
+
* deliberately stay OUT of planHash. `badBaseStreak` reconciles two
|
|
384
|
+
* normative clauses: a bad_base revision leaves the hashed state
|
|
385
|
+
* byte-identical (docs/07, 3.5 step 2: planHashAfter == planHashBefore)
|
|
386
|
+
* yet still lengthens the guard streak (docs/07, 3.6 last row): the
|
|
387
|
+
* guards therefore consume `effectiveDroppedStreak`, the hashed counter
|
|
388
|
+
* plus the trailing bad_base entries. `doneRefs` remembers which entry
|
|
389
|
+
* resolved each done node so waive_dep drops can point blockingRef at
|
|
390
|
+
* it.
|
|
391
|
+
*/
|
|
392
|
+
interface PlanFoldState extends PlanWorking {
|
|
393
|
+
badBaseStreak: number;
|
|
394
|
+
doneRefs: Record<NodeId, EntryRef>;
|
|
395
|
+
}
|
|
396
|
+
declare function emptyPlanFold(plan: TaskPlan): PlanFoldState;
|
|
397
|
+
/** The streak RevisionGuards consume (docs/07, 3.8). */
|
|
398
|
+
declare function effectiveDroppedStreak(state: PlanFoldState): number;
|
|
399
|
+
/**
|
|
400
|
+
* Applies ONE applied op to the working state. The applier consumes
|
|
401
|
+
* recorded outcomes; op-level legality was decided at rebase time and is
|
|
402
|
+
* never re-evaluated here. Exported for the rebase engine, which applies
|
|
403
|
+
* each op of a revision against the state already changed by the earlier
|
|
404
|
+
* applied ops of the same revision (docs/07, 3.5, step 3).
|
|
405
|
+
*/
|
|
406
|
+
declare function applyAppliedOp(working: PlanWorking, op: AppliedPlanOp, context: {
|
|
407
|
+
seq: number;
|
|
408
|
+
opIndex?: number;
|
|
409
|
+
lineageOf?: (opIndex: number) => LogicalTaskId | undefined;
|
|
410
|
+
}): PlanWorking;
|
|
411
|
+
/** Reads a plan.revision entry's payload (tolerant of foreign journals). */
|
|
412
|
+
declare function readPlanRevision(entry: JournalEntry): PlanRevisionValue | undefined;
|
|
413
|
+
/** Reads a plan.decision entry's payload. */
|
|
414
|
+
declare function readPlanDecision(entry: JournalEntry): PlanDecisionValue | undefined;
|
|
415
|
+
/**
|
|
416
|
+
* THE single applier (docs/07, 3.2): folds one plan-scope entry into the
|
|
417
|
+
* state. Replay consumes recorded outcomes (the APPLIED diff), never
|
|
418
|
+
* re-runs rebase, and timers do not run; hash verification runs under
|
|
419
|
+
* the entry's own hashVersion profile.
|
|
420
|
+
*/
|
|
421
|
+
declare function applyPlanEntry(state: PlanFoldState, entry: JournalEntry, options?: {
|
|
422
|
+
deriverFor?: (hashVersion: HashVersion) => KeyDeriver | undefined;
|
|
423
|
+
}): PlanFoldState;
|
|
424
|
+
/**
|
|
425
|
+
* The shared plan.decision applier core: engine authorship happens at
|
|
426
|
+
* the fold head under PlanWriteLock (docs/07, 3.3), so the producer can
|
|
427
|
+
* PREVIEW the resulting state (and its planHashAfter) before appending,
|
|
428
|
+
* and the fold re-applies the recorded ops identically on replay.
|
|
429
|
+
*/
|
|
430
|
+
declare function applyDecisionOps(state: Pick<PlanFoldState, "plan" | "specs" | "doneRefs">, ops: readonly EnginePlanOp[], seq: number): {
|
|
431
|
+
plan: TaskPlan;
|
|
432
|
+
specs: PlanWorking["specs"];
|
|
433
|
+
doneRefs: Record<NodeId, EntryRef>;
|
|
434
|
+
};
|
|
435
|
+
//#endregion
|
|
436
|
+
//#region src/rebase.d.ts
|
|
437
|
+
/** The reuse-by-reference transform hook (DEF-5; M7-T07). */
|
|
438
|
+
interface ReuseTransform {
|
|
439
|
+
applied: AppliedPlanOp;
|
|
440
|
+
admission: AdmissionDecision;
|
|
441
|
+
nodeId: NodeId;
|
|
442
|
+
/** Donor placement recorded beside the verdict (docs/03, 9.5). */
|
|
443
|
+
reuse: {
|
|
444
|
+
donorScope: string;
|
|
445
|
+
chain: string[];
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
interface RebaseContext {
|
|
449
|
+
/** The fold head (docs/07, 3.5 step 3). */
|
|
450
|
+
state: PlanFoldState;
|
|
451
|
+
/** The plan hash recorded in the WakeDigest the base references. */
|
|
452
|
+
digestPlanHashFor: (digestSeq: number) => string | undefined;
|
|
453
|
+
/** Engine NodeId minting (ULIDs; never the model). */
|
|
454
|
+
mintNodeId: () => NodeId;
|
|
455
|
+
/** The plan is frozen for adaptation by orchestrator_budget_cap (DEF-7). */
|
|
456
|
+
frozen?: boolean;
|
|
457
|
+
/** Embedded admission for add_task (docs/07, 3.6); absent admits nothing. */
|
|
458
|
+
admitAdd?: (op: Extract<PlanOp, {
|
|
459
|
+
op: "add_task";
|
|
460
|
+
}>, nodeId: NodeId, opIndex: number) => AdmissionDecision;
|
|
461
|
+
/** Embedded admission reserve for unpark_task (docs/07, 3.6). */
|
|
462
|
+
admitUnpark?: (op: Extract<PlanOp, {
|
|
463
|
+
op: "unpark_task";
|
|
464
|
+
}>, node: PlanNode, opIndex: number) => AdmissionDecision;
|
|
465
|
+
/** Lineage-at-head check for add_task lineage blocks (DEF-3). */
|
|
466
|
+
lineageCheck?: (continues: LogicalTaskId) => "ok" | "lineage_busy" | "lineage_exhausted";
|
|
467
|
+
/** Reuse-by-reference dedup at the fold head (DEF-5; M7-T07). */
|
|
468
|
+
dedup?: (op: Extract<PlanOp, {
|
|
469
|
+
op: "add_task";
|
|
470
|
+
}>, opIndex: number) => ReuseTransform | undefined;
|
|
471
|
+
}
|
|
472
|
+
interface RebaseEvaluation {
|
|
473
|
+
outcomes: RebaseOutcome[];
|
|
474
|
+
assignedNodeIds: Record<number, NodeId>;
|
|
475
|
+
admissions: PlanRevisionAdmission[];
|
|
476
|
+
planHashBefore: string;
|
|
477
|
+
planHashAfter: string;
|
|
478
|
+
droppedAll: boolean;
|
|
479
|
+
badBase: boolean;
|
|
480
|
+
/** The post-revision working state (counters updated, readiness recomputed). */
|
|
481
|
+
working: PlanWorking;
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Steps 2-4 of the committed algorithm (docs/07, 3.5): base validation,
|
|
485
|
+
* sequential per-op conflict resolution against the mutating head, and
|
|
486
|
+
* the post-revision counter update. Pure: the caller owns the lock, the
|
|
487
|
+
* append, and every effect.
|
|
488
|
+
*/
|
|
489
|
+
declare function rebasePlanRevision(request: PlanReviseRequest, context: RebaseContext): RebaseEvaluation;
|
|
490
|
+
//#endregion
|
|
491
|
+
//#region src/guards.d.ts
|
|
492
|
+
/** RevisionGuards configuration (docs/07, 3.8). */
|
|
493
|
+
interface RevisionGuardsOptions {
|
|
494
|
+
/** Default 'finish-with-partial'; the chain is non-HITL and terminating. */
|
|
495
|
+
fallback?: "reject-revision" | "finish-with-partial" | "fail-run";
|
|
496
|
+
/** Default 3 consecutive fully-dropped revisions. */
|
|
497
|
+
droppedRevisionLimit?: number;
|
|
498
|
+
/** Optional netLostUsd trigger as a fraction of the starting budget (DEF-5). */
|
|
499
|
+
maxAbandonedNetUsdFraction?: number;
|
|
500
|
+
}
|
|
501
|
+
type GuardFallback = NonNullable<RevisionGuardsOptions["fallback"]>;
|
|
502
|
+
/** The journaled guard verdict payload (kind 'decision'). */
|
|
503
|
+
interface GuardVerdictValue {
|
|
504
|
+
decisionType: "guard-verdict";
|
|
505
|
+
guard: "dropped-revision-streak" | "oscillation-freeze" | "stall-replan-cap" | "net-lost";
|
|
506
|
+
fallback: GuardFallback | "freeze-key";
|
|
507
|
+
/** The streak at trip time (dropped-revision-streak). */
|
|
508
|
+
streak?: number;
|
|
509
|
+
/** The frozen coarse signature (oscillation-freeze). */
|
|
510
|
+
approachSigCoarse?: string;
|
|
511
|
+
oscillationCount?: number;
|
|
512
|
+
/** The capped counter (stall-replan-cap). */
|
|
513
|
+
stallReplans?: number;
|
|
514
|
+
netLostUsd?: number;
|
|
515
|
+
}
|
|
516
|
+
/** Appendix A: osc_guard reject threshold per key (shared default). */
|
|
517
|
+
declare const DEFAULT_MAX_OSCILLATIONS_PER_KEY = 2;
|
|
518
|
+
/** The hard per-run stall replan bound (docs/07, 9.3). */
|
|
519
|
+
declare const DEFAULT_STALL_REPLAN_CAP = 4;
|
|
520
|
+
declare const DEFAULT_DROPPED_REVISION_LIMIT = 3;
|
|
521
|
+
interface GuardsState {
|
|
522
|
+
/** The engaged terminating fallback, once tripped (single-shot). */
|
|
523
|
+
engaged?: GuardFallback;
|
|
524
|
+
/** Coarse signatures whose re-adds are frozen. */
|
|
525
|
+
frozenSignatures: ReadonlySet<string>;
|
|
526
|
+
stallReplansUsed: number;
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* The guard state machine. All counting inputs arrive from pure folds
|
|
530
|
+
* (the caller feeds landed revisions, severs, and re-adds in journal
|
|
531
|
+
* order), so live and replay converge on identical verdicts; the caller
|
|
532
|
+
* journals each verdict BEFORE applying its effects.
|
|
533
|
+
*/
|
|
534
|
+
declare class RevisionGuards {
|
|
535
|
+
private readonly fallback;
|
|
536
|
+
private readonly droppedRevisionLimit;
|
|
537
|
+
private readonly maxOscillationsPerKey;
|
|
538
|
+
private readonly stallReplanCap;
|
|
539
|
+
private engaged?;
|
|
540
|
+
/** Severed (cancelled/abandoned) spend per coarse signature. */
|
|
541
|
+
private readonly severedSignatures;
|
|
542
|
+
/** Oscillation counts per coarse signature, across LTID boundaries. */
|
|
543
|
+
private readonly oscillations;
|
|
544
|
+
private readonly frozen;
|
|
545
|
+
private stallReplans;
|
|
546
|
+
constructor(options?: RevisionGuardsOptions & {
|
|
547
|
+
maxOscillationsPerKey?: number;
|
|
548
|
+
stallReplanCap?: number;
|
|
549
|
+
});
|
|
550
|
+
get state(): GuardsState;
|
|
551
|
+
/** True once a terminating fallback engaged: the plan is frozen for adaptation. */
|
|
552
|
+
get planFrozen(): boolean;
|
|
553
|
+
/** True when further plan_revise calls are rejected outright. */
|
|
554
|
+
get revisionsRejected(): boolean;
|
|
555
|
+
/**
|
|
556
|
+
* Feeds one landed revision's effective streak; returns the verdict to
|
|
557
|
+
* journal when the limit is reached (single-shot).
|
|
558
|
+
*/
|
|
559
|
+
onRevisionLanded(effectiveDroppedStreak: number): GuardVerdictValue | undefined;
|
|
560
|
+
/** Feeds a severing cancel/abandon of a node with this coarse signature. */
|
|
561
|
+
onSevered(approachSigCoarse: string): void;
|
|
562
|
+
/**
|
|
563
|
+
* Feeds one admitted add of this coarse signature; a re-add after a
|
|
564
|
+
* sever counts one oscillation ACROSS LTID boundaries. Returns the
|
|
565
|
+
* freeze verdict to journal when the per-key limit is reached.
|
|
566
|
+
*/
|
|
567
|
+
onReAdd(approachSigCoarse: string): GuardVerdictValue | undefined;
|
|
568
|
+
/** True when further re-adds of this coarse signature are frozen. */
|
|
569
|
+
isFrozenSignature(approachSigCoarse: string): boolean;
|
|
570
|
+
oscillationCountOf(approachSigCoarse: string): number;
|
|
571
|
+
/**
|
|
572
|
+
* Consumes one stall-triggered replan slot; returns the cap verdict
|
|
573
|
+
* when the hard per-run bound is exhausted (single-shot per call site).
|
|
574
|
+
*/
|
|
575
|
+
onStallReplan(): GuardVerdictValue | undefined;
|
|
576
|
+
get stallReplanExhausted(): boolean;
|
|
577
|
+
/** Rebuilds guard state from a journaled verdict (replay path). */
|
|
578
|
+
absorbVerdict(value: GuardVerdictValue): void;
|
|
579
|
+
/** Serializes a verdict for the journal append. */
|
|
580
|
+
static verdictJson(value: GuardVerdictValue): Json;
|
|
581
|
+
}
|
|
582
|
+
//#endregion
|
|
583
|
+
//#region src/park.d.ts
|
|
584
|
+
/** Appendix A: the single pin cap shared by park/unpark and retainWorktree. */
|
|
585
|
+
declare const DEFAULT_MAX_PINNED_WORKTREES = 4;
|
|
586
|
+
/**
|
|
587
|
+
* The worktree pin ledger: a pure fold counting live pins from abandon
|
|
588
|
+
* entries carrying `retainWorktree: true` (park pinning and DEF-5
|
|
589
|
+
* retention share the cap by construction; docs/08).
|
|
590
|
+
*/
|
|
591
|
+
declare class PinLedger {
|
|
592
|
+
private readonly pinnedTargets;
|
|
593
|
+
private readonly byNode;
|
|
594
|
+
static fold(entries: readonly JournalEntry[]): PinLedger;
|
|
595
|
+
get count(): number;
|
|
596
|
+
hasCapacity(maxPinnedWorktrees?: number): boolean;
|
|
597
|
+
isPinnedNode(nodeId: string): boolean;
|
|
598
|
+
}
|
|
599
|
+
/** The park disposition computed at landing time (docs/03, 11.2). */
|
|
600
|
+
interface ParkDisposition {
|
|
601
|
+
/** Checkpoints are always retained on park. */
|
|
602
|
+
retainCheckpoint: true;
|
|
603
|
+
/** True only for worktree isolation with pin capacity left. */
|
|
604
|
+
retainWorktree: boolean;
|
|
605
|
+
}
|
|
606
|
+
declare function parkDispositionOf(isolation: IsolationSpec | undefined, pins: PinLedger, maxPinnedWorktrees?: number): ParkDisposition;
|
|
607
|
+
/** The unpark placement (docs/03, 11.2): continuation or restart. */
|
|
608
|
+
interface UnparkPlacement {
|
|
609
|
+
/** True when the agent must restart (no checkpoint, or tree dropped). */
|
|
610
|
+
restart: boolean;
|
|
611
|
+
/** The retained checkpoint the continuation boots from. */
|
|
612
|
+
bootCheckpointRef?: string;
|
|
613
|
+
}
|
|
614
|
+
declare function unparkPlacementOf(input: {
|
|
615
|
+
/** The parked node's recorded checkpoint anchor (root dispatch seq). */checkpointRef?: number; /** The retained transcript ref derived from the anchor, when any. */
|
|
616
|
+
transcriptRef?: string;
|
|
617
|
+
isolation?: IsolationSpec;
|
|
618
|
+
worktreePinned: boolean;
|
|
619
|
+
}): UnparkPlacement;
|
|
620
|
+
//#endregion
|
|
621
|
+
//#region src/ledger.d.ts
|
|
622
|
+
/** The CLOSED authored op vocabulary (docs/07, 9.2). */
|
|
623
|
+
type LedgerOp = {
|
|
624
|
+
op: "brief_set";
|
|
625
|
+
text: string;
|
|
626
|
+
} | {
|
|
627
|
+
op: "fact_add";
|
|
628
|
+
factId: string;
|
|
629
|
+
text: string;
|
|
630
|
+
provenance: EntryRef[];
|
|
631
|
+
confidence: "low" | "medium" | "high";
|
|
632
|
+
} | {
|
|
633
|
+
op: "fact_supersede";
|
|
634
|
+
factId: string;
|
|
635
|
+
supersededBy: string;
|
|
636
|
+
text: string;
|
|
637
|
+
provenance: EntryRef[];
|
|
638
|
+
confidence: "low" | "medium" | "high";
|
|
639
|
+
} | {
|
|
640
|
+
op: "lesson_add";
|
|
641
|
+
key: {
|
|
642
|
+
logicalTaskId: LogicalTaskId;
|
|
643
|
+
approachSig: string;
|
|
644
|
+
};
|
|
645
|
+
text: string;
|
|
646
|
+
} | {
|
|
647
|
+
op: "observation_add";
|
|
648
|
+
taskClass: string;
|
|
649
|
+
logicalTaskId: LogicalTaskId;
|
|
650
|
+
tierObserved?: number;
|
|
651
|
+
outcomeClass?: string;
|
|
652
|
+
note: string;
|
|
653
|
+
evidenceRefs: EntryRef[];
|
|
654
|
+
};
|
|
655
|
+
/** Appendix A per-section caps. */
|
|
656
|
+
declare const LEDGER_SECTION_CAPS: {
|
|
657
|
+
readonly facts: 64;
|
|
658
|
+
readonly lessons: 32;
|
|
659
|
+
readonly observations: 16;
|
|
660
|
+
};
|
|
661
|
+
/** The content key of one authored op (ordinal distinguishes repeats). */
|
|
662
|
+
declare function ledgerOpKey(op: LedgerOp): string;
|
|
663
|
+
interface LedgerFact {
|
|
664
|
+
factId: string;
|
|
665
|
+
text: string;
|
|
666
|
+
provenance: EntryRef[];
|
|
667
|
+
confidence: "low" | "medium" | "high";
|
|
668
|
+
supersededBy?: string;
|
|
669
|
+
entryRef: EntryRef;
|
|
670
|
+
}
|
|
671
|
+
interface LedgerLesson {
|
|
672
|
+
key: {
|
|
673
|
+
logicalTaskId: LogicalTaskId;
|
|
674
|
+
approachSig: string;
|
|
675
|
+
};
|
|
676
|
+
text: string;
|
|
677
|
+
entryRef: EntryRef;
|
|
678
|
+
}
|
|
679
|
+
interface LedgerObservation {
|
|
680
|
+
taskClass: string;
|
|
681
|
+
logicalTaskId: LogicalTaskId;
|
|
682
|
+
tierObserved?: number;
|
|
683
|
+
outcomeClass?: string;
|
|
684
|
+
note: string;
|
|
685
|
+
evidenceRefs: EntryRef[];
|
|
686
|
+
entryRef: EntryRef;
|
|
687
|
+
}
|
|
688
|
+
/** One auto-derived revision history row (fold join, never authored). */
|
|
689
|
+
interface LedgerRevisionRow {
|
|
690
|
+
entryRef: EntryRef;
|
|
691
|
+
rationale: string;
|
|
692
|
+
applied: number;
|
|
693
|
+
dropped: number;
|
|
694
|
+
}
|
|
695
|
+
/** The pure ledger fold (docs/07, 9.3). */
|
|
696
|
+
interface LedgerView {
|
|
697
|
+
brief?: {
|
|
698
|
+
text: string;
|
|
699
|
+
entryRef: EntryRef;
|
|
700
|
+
};
|
|
701
|
+
facts: LedgerFact[];
|
|
702
|
+
lessons: LedgerLesson[];
|
|
703
|
+
observations: LedgerObservation[];
|
|
704
|
+
/** Auto-derived: plan revision history with rationale. */
|
|
705
|
+
revisionHistory: LedgerRevisionRow[];
|
|
706
|
+
/** Auto-derived: task digests ordered by spawn ordinal (root seq). */
|
|
707
|
+
taskDigests: Array<{
|
|
708
|
+
nodeId?: string;
|
|
709
|
+
scope: string;
|
|
710
|
+
status: string;
|
|
711
|
+
entryRef: EntryRef;
|
|
712
|
+
}>;
|
|
713
|
+
/** Auto-derived: the world-delta index from terminal artifacts. */
|
|
714
|
+
worldDelta: Array<{
|
|
715
|
+
scope: string;
|
|
716
|
+
entryRef: EntryRef;
|
|
717
|
+
artifacts: number;
|
|
718
|
+
}>;
|
|
719
|
+
/** Journal-vs-ledger contradictions, flagged and never resolved here. */
|
|
720
|
+
discrepancies: string[];
|
|
721
|
+
}
|
|
722
|
+
/** Fold every ledger.op plus the auto-derived joins up to `uptoSeq`. */
|
|
723
|
+
declare function foldLedger(entries: readonly JournalEntry[], options?: {
|
|
724
|
+
ledgerScope?: string;
|
|
725
|
+
planScope?: string;
|
|
726
|
+
uptoSeq?: number;
|
|
727
|
+
}): LedgerView;
|
|
728
|
+
/**
|
|
729
|
+
* The committed ledger_read render budget (docs/06, Appendix A: 65536
|
|
730
|
+
* chars over the serialized view, the character measure; OQ-04 closed
|
|
731
|
+
* at M10 entry). The section caps stay the primary bound; under the
|
|
732
|
+
* default termination limits this belt never engages.
|
|
733
|
+
*/
|
|
734
|
+
declare const LEDGER_RENDER_BUDGET_CHARS = 65536;
|
|
735
|
+
/**
|
|
736
|
+
* Deterministic render bound (docs/07, 9.3): over budget, rows drop
|
|
737
|
+
* oldest-first, auto-derived joins before authored sections, and the
|
|
738
|
+
* mission brief slices last; every drop is a FLAGGED discrepancy line.
|
|
739
|
+
* A pure function of (view, budget): a re-executed wake turn renders
|
|
740
|
+
* byte-identical bounded bytes from the same pinned fold.
|
|
741
|
+
*/
|
|
742
|
+
declare function boundLedgerRender(view: LedgerView, budgetChars?: number): LedgerView;
|
|
743
|
+
/** Section-cap check for one authored op (docs/06, Appendix A). */
|
|
744
|
+
declare function ledgerCapViolation(view: LedgerView, op: LedgerOp): string | undefined;
|
|
745
|
+
/**
|
|
746
|
+
* Compaction sufficiency (docs/07, 9.3): the orchestrate role may
|
|
747
|
+
* compact aggressively only when the ledger measurably suffices (at
|
|
748
|
+
* least one authored revision recorded and a minimum fact count);
|
|
749
|
+
* otherwise the engine falls back to conservative summarize.
|
|
750
|
+
*/
|
|
751
|
+
declare function ledgerSufficiency(view: LedgerView, minimumFacts?: number): boolean;
|
|
752
|
+
/** The draft-versioned outward seam (docs/07, 9.3; OQ in docs/14). */
|
|
753
|
+
interface LedgerExport {
|
|
754
|
+
ledgerExportVersion: "draft-1";
|
|
755
|
+
brief?: string;
|
|
756
|
+
facts: Array<Omit<LedgerFact, "entryRef">>;
|
|
757
|
+
lessons: Array<Omit<LedgerLesson, "entryRef">>;
|
|
758
|
+
observations: Array<Omit<LedgerObservation, "entryRef">>;
|
|
759
|
+
revisionHistory: LedgerRevisionRow[];
|
|
760
|
+
}
|
|
761
|
+
declare function exportLedger(view: LedgerView): LedgerExport;
|
|
762
|
+
//#endregion
|
|
763
|
+
//#region src/ladder.d.ts
|
|
764
|
+
/**
|
|
765
|
+
* Extracts the declared ladder from an agent profile: the ModelSpec union
|
|
766
|
+
* carries it (`model: { ladder }`), or the loop-role routing entry
|
|
767
|
+
* (docs/04, section 12). The same declaration points feed ladderLengthOf
|
|
768
|
+
* and the frozen kMax, so admission and execution can never disagree on
|
|
769
|
+
* the ladder length.
|
|
770
|
+
*/
|
|
771
|
+
declare function ladderOfProfile(profile: unknown): LadderSpec | undefined;
|
|
772
|
+
/** The profile's chain effort feeding canonicalization, when declared. */
|
|
773
|
+
declare function chainEffortOf(profile: unknown): Effort | undefined;
|
|
774
|
+
/** Canonicalizes the profile's declared ladder once per dispatch site. */
|
|
775
|
+
declare function canonicalLadderOf(profile: unknown): CanonicalLadderSpec | undefined;
|
|
776
|
+
/**
|
|
777
|
+
* Clamps the orchestrator's `model_hint.startTier` to the declared ladder
|
|
778
|
+
* (docs/07, section 4.2): the hint is the ONLY model influence the
|
|
779
|
+
* orchestrator has, and it never names a model.
|
|
780
|
+
*/
|
|
781
|
+
declare function clampStartTier(ladder: CanonicalLadderSpec, hint?: number): number;
|
|
782
|
+
/**
|
|
783
|
+
* The rung an attempt executes on: the clamped start tier plus the
|
|
784
|
+
* journaled raise count, hard-clamped at the top rung. `rungIndex` per
|
|
785
|
+
* lineage is strictly monotone; there are no demotions (docs/07, 10).
|
|
786
|
+
*/
|
|
787
|
+
declare function executingRungOf(ladder: CanonicalLadderSpec, startTier: number, raises: number): number;
|
|
788
|
+
/**
|
|
789
|
+
* Classifies a settled attempt into the typed transition trigger
|
|
790
|
+
* (docs/04, section 12): schema-mismatch errors are 'schema-exhausted';
|
|
791
|
+
* the engine's no-progress abort is first-class 'no-progress' (it rides
|
|
792
|
+
* status 'limit' with the dedicated abort class, distinct from user
|
|
793
|
+
* cancellation by construction); cancelled, escalated, and skipped never
|
|
794
|
+
* trigger. 'verify-failed' comes from the acceptance gates, never from
|
|
795
|
+
* the terminal status.
|
|
796
|
+
*/
|
|
797
|
+
declare function ladderTriggerOf(settled: Pick<AgentResult<unknown>, "status"> & {
|
|
798
|
+
error?: {
|
|
799
|
+
kind?: string;
|
|
800
|
+
};
|
|
801
|
+
abortClass?: string;
|
|
802
|
+
}): Exclude<TriggerClass, "verify-failed"> | undefined;
|
|
803
|
+
/** One journaled acceptance-gate evaluation (docs/07, section 10). */
|
|
804
|
+
interface GateVerdictValue {
|
|
805
|
+
decisionType: "gate-verdict";
|
|
806
|
+
logicalTaskId: LogicalTaskId;
|
|
807
|
+
nodeId: string;
|
|
808
|
+
/** The judged attempt's root dispatch seq. */
|
|
809
|
+
attemptRef: EntryRef;
|
|
810
|
+
gate: "mechanical" | "judge" | "spot-check";
|
|
811
|
+
/** The registered profile name (mechanical gates). */
|
|
812
|
+
profile?: string;
|
|
813
|
+
/** The executing rung of the judged attempt. */
|
|
814
|
+
rung: number;
|
|
815
|
+
pass: boolean;
|
|
816
|
+
detail?: string;
|
|
817
|
+
/** Spot-check only: the journaled draw and fraction behind `pass`. */
|
|
818
|
+
spotCheck?: {
|
|
819
|
+
draw: number;
|
|
820
|
+
fraction: number;
|
|
821
|
+
selected: boolean;
|
|
822
|
+
};
|
|
823
|
+
}
|
|
824
|
+
/** Content key of one gate verdict: attempt plus gate position. */
|
|
825
|
+
declare function gateVerdictKey(attemptRef: EntryRef, gateIndex: number): string;
|
|
826
|
+
/**
|
|
827
|
+
* The ladder verdict decision entry (docs/07, sections 10 and 11.3): the
|
|
828
|
+
* producer contract both folds already consume. A RAISING verdict debits
|
|
829
|
+
* one rung unit (rungIndexAfter/rungsRemainingAfter embedded, checked by
|
|
830
|
+
* foldTermination) and carries the rung RESPAWN's embedded admission
|
|
831
|
+
* (spawn debit) plus `nextAttempt` (the lineage registration: relation
|
|
832
|
+
* 'rung-retry', docs/03 10.1 row 4). A non-raising verdict records the
|
|
833
|
+
* ladder's end (exhausted rungs, top rung, or a denied respawn) and
|
|
834
|
+
* authorizes nothing.
|
|
835
|
+
*/
|
|
836
|
+
interface LadderVerdictValue {
|
|
837
|
+
decisionType: "ladder-verdict";
|
|
838
|
+
logicalTaskId: LogicalTaskId;
|
|
839
|
+
nodeId: string;
|
|
840
|
+
trigger: TriggerClass;
|
|
841
|
+
/** The judged attempt's root dispatch seq. */
|
|
842
|
+
attemptRef: EntryRef;
|
|
843
|
+
raisesRung: boolean;
|
|
844
|
+
rungIndexAfter?: number;
|
|
845
|
+
rungsRemainingAfter?: number;
|
|
846
|
+
/** Present exactly when raising: the authorized next rung attempt. */
|
|
847
|
+
nextAttempt?: {
|
|
848
|
+
childScope: string; /** The full admission-computed lineage block (registerAttempt input). */
|
|
849
|
+
lineage: Json; /** The concrete rung the next attempt executes on. */
|
|
850
|
+
rungIndex: number;
|
|
851
|
+
};
|
|
852
|
+
/** The embedded respawn admission (the spawn debit; docs/07, 11.3 b). */
|
|
853
|
+
admissions?: Json[];
|
|
854
|
+
/** Non-raising verdicts: why the ladder ended here. */
|
|
855
|
+
reason?: "rungs_exhausted" | "top_rung" | "respawn_denied" | "trigger_not_declared";
|
|
856
|
+
}
|
|
857
|
+
/** Content key of one ladder verdict: the judged attempt is unique. */
|
|
858
|
+
declare function ladderVerdictKey(attemptRef: EntryRef): string;
|
|
859
|
+
/** The forced verdict schema of the judge gate (docs/07, section 10). */
|
|
860
|
+
declare const JUDGE_VERDICT_SCHEMA: {
|
|
861
|
+
readonly type: "object";
|
|
862
|
+
readonly properties: {
|
|
863
|
+
readonly pass: {
|
|
864
|
+
readonly type: "boolean";
|
|
865
|
+
};
|
|
866
|
+
readonly reason: {
|
|
867
|
+
readonly type: "string";
|
|
868
|
+
};
|
|
869
|
+
};
|
|
870
|
+
readonly required: readonly ["pass", "reason"];
|
|
871
|
+
readonly additionalProperties: false;
|
|
872
|
+
};
|
|
873
|
+
/**
|
|
874
|
+
* The judge prompt: artifact-grounded, assembled from journaled values
|
|
875
|
+
* only (the attempt's output summary and artifact index), so a replayed
|
|
876
|
+
* judge dispatch hashes identically.
|
|
877
|
+
*/
|
|
878
|
+
declare function judgePrompt(input: {
|
|
879
|
+
taskPrompt: string;
|
|
880
|
+
outputSummary: string;
|
|
881
|
+
artifactIds: readonly string[];
|
|
882
|
+
}): string;
|
|
883
|
+
//#endregion
|
|
884
|
+
//#region src/escalation.d.ts
|
|
885
|
+
/** One per-lineage debit row of a class-level decision (docs/07, 6.5). */
|
|
886
|
+
interface EscalationDebitRow {
|
|
887
|
+
logicalTaskId: LogicalTaskId;
|
|
888
|
+
escalationUnitsAfter: number;
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* The authoritative escalation-decision entry value (docs/07, 6.5; the
|
|
892
|
+
* producer contract of LineageIndex and foldTermination). Exactly one
|
|
893
|
+
* such entry per report; the debit is atomic with the append and the
|
|
894
|
+
* balance-after is embedded (DEF-2). A decision whose counting debit was
|
|
895
|
+
* DENIED carries `countsAgainstLimit: false` plus `capExceeded: true`:
|
|
896
|
+
* the termination.denied entry written strictly before is the counting
|
|
897
|
+
* record, and the folds stay replay-strict.
|
|
898
|
+
*/
|
|
899
|
+
interface EscalationDecisionValue {
|
|
900
|
+
decisionType: "escalation-decision";
|
|
901
|
+
/** Single-target form; the class form carries `debits` instead. */
|
|
902
|
+
logicalTaskId?: LogicalTaskId;
|
|
903
|
+
nodeId?: string;
|
|
904
|
+
decision: EscalationDecision;
|
|
905
|
+
/** Seq of the terminal escalated entry or the suspended escalate entry. */
|
|
906
|
+
reportRef: EntryRef;
|
|
907
|
+
countsAgainstLimit: boolean;
|
|
908
|
+
/** Present exactly when a counting debit executed (fold-asserted). */
|
|
909
|
+
escalationUnitsAfter?: number;
|
|
910
|
+
/** How the decision was reached (docs/07, 3.3 plan.decision origins). */
|
|
911
|
+
resolvedBy: "default" | "class" | "live" | "revision-transform";
|
|
912
|
+
/** Class-level form: one entry, an array of per-lineage debits. */
|
|
913
|
+
debits?: EscalationDebitRow[];
|
|
914
|
+
/** Decomposition admissions (spawn debits ride this entry; 11.3 b). */
|
|
915
|
+
admissions?: Json[];
|
|
916
|
+
/** The counting debit was denied: the cap is the message (docs/07, 6.5). */
|
|
917
|
+
capExceeded?: boolean;
|
|
918
|
+
}
|
|
919
|
+
/** Content key: one authoritative decision per report (decide-once). */
|
|
920
|
+
declare function escalationDecisionKey(reportRef: EntryRef): string;
|
|
921
|
+
/** Maps a resolution `by` value onto the decision's resolvedBy field. */
|
|
922
|
+
declare function resolvedByOf(by: string): "default" | "class" | "live";
|
|
923
|
+
/** The plan.decision origin of one resolvedBy value (docs/07, 3.3). */
|
|
924
|
+
declare function decisionOriginOf(resolvedBy: "default" | "class" | "live" | "revision-transform"): "escalation-default" | "escalation-class" | "escalation-live";
|
|
925
|
+
//#endregion
|
|
926
|
+
//#region src/plan-runner.d.ts
|
|
927
|
+
/** docs/07, 3.8. */
|
|
928
|
+
interface PlanRunnerOptions {
|
|
929
|
+
/** Absolute, non-replenishable; default 32 (DEF-2). */
|
|
930
|
+
maxRevisionsPerRun?: number;
|
|
931
|
+
guards?: RevisionGuardsOptions;
|
|
932
|
+
/** Out-of-vocabulary tags get a typed tool error with bounded re-prompt (DEF-3). */
|
|
933
|
+
approachVocabulary?: string[];
|
|
934
|
+
/** Reuse-by-reference configuration (DEF-5; docs/03, 9.9). */
|
|
935
|
+
reuse?: ReuseConfig;
|
|
936
|
+
/** Frozen termination knobs beyond the revision budget (DEF-2). */
|
|
937
|
+
limits?: Partial<Pick<TerminationLimits, "maxTotalSpawns" | "maxEscalationsPerLogicalTask" | "maxDepth">>;
|
|
938
|
+
}
|
|
939
|
+
/**
|
|
940
|
+
* Builds the PlanRunner orchestrator extension (docs/07, section 3).
|
|
941
|
+
* Attach via `orchestrate(engine, goal, { extension: planRunner(o) })` or
|
|
942
|
+
* the `orchestratePlanned` convenience surface.
|
|
943
|
+
*/
|
|
944
|
+
declare function planRunner(options?: PlanRunnerOptions): OrchestratorExtension;
|
|
945
|
+
/** The PlanRunner entry surface: mode (c) plus the extension in one call. */
|
|
946
|
+
declare function orchestratePlanned(engine: Engine, goal: string, opts?: OrchestrateOptions & {
|
|
947
|
+
plan?: PlanRunnerOptions;
|
|
948
|
+
}): RunHandle<unknown>;
|
|
949
|
+
//#endregion
|
|
950
|
+
//#region src/cassettes.d.ts
|
|
951
|
+
/** One normalized-cassette fixture file (cassettes/<id>.json). */
|
|
952
|
+
interface M7CassetteFixture {
|
|
953
|
+
id: string;
|
|
954
|
+
note: string;
|
|
955
|
+
entries: JournalEntry[];
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Normalizes one journal for cassette comparison: ULIDs and sha256
|
|
959
|
+
* strings map to first-appearance placeholders; wall clock, spans, and
|
|
960
|
+
* transcript refs collapse to fixtures. Deterministic given a
|
|
961
|
+
* deterministic entry stream.
|
|
962
|
+
*/
|
|
963
|
+
declare function normalizeAdaptiveJournal(entries: readonly JournalEntry[]): JournalEntry[];
|
|
964
|
+
/** A minimal scripted adapter over the PUBLIC provider SPI. */
|
|
965
|
+
interface CassetteTurn {
|
|
966
|
+
text?: string;
|
|
967
|
+
toolCall?: {
|
|
968
|
+
name: string;
|
|
969
|
+
args: unknown;
|
|
970
|
+
};
|
|
971
|
+
hangUntilAborted?: boolean;
|
|
972
|
+
/** Await this promise before emitting (cross-agent sequencing). */
|
|
973
|
+
awaitPromise?: Promise<void>;
|
|
974
|
+
/** The stream terminates with this typed wire error (M9 DEF-2/3 rows). */
|
|
975
|
+
wireError?: WireError;
|
|
976
|
+
}
|
|
977
|
+
declare function cassetteAdapter(script: (req: ChatRequest) => CassetteTurn): ProviderAdapter & {
|
|
978
|
+
calls: ChatRequest[];
|
|
979
|
+
};
|
|
980
|
+
declare function agentTypeOfRequest(req: ChatRequest): string;
|
|
981
|
+
declare const EMPTY_PLAN_HASH: string;
|
|
982
|
+
declare function engineWith(adapter: ProviderAdapter, store: JournalStore, profiles: Record<string, unknown>, extras?: {
|
|
983
|
+
schemas?: Record<string, unknown>;
|
|
984
|
+
lineage?: Record<string, number>;
|
|
985
|
+
isolation?: unknown; /** ModelKnowledge store for the M10 kb cassettes (docs/05). */
|
|
986
|
+
knowledge?: unknown;
|
|
987
|
+
}): Engine;
|
|
988
|
+
declare const BUDGET: {
|
|
989
|
+
readonly capUsd: 5;
|
|
990
|
+
readonly finalizeReserveUsd: 1;
|
|
991
|
+
};
|
|
992
|
+
declare function settled(handle: RunHandle<unknown>): Promise<void>;
|
|
993
|
+
/**
|
|
994
|
+
* revise-mid-run: a plan revision arrives while a worker subtree is
|
|
995
|
+
* mid-flight (docs/09 round-2). The first worker HANGS until the
|
|
996
|
+
* revision cancels it; the added replacement completes.
|
|
997
|
+
*/
|
|
998
|
+
declare function runReviseMidRun(): Promise<JournalEntry[]>;
|
|
999
|
+
/**
|
|
1000
|
+
* crash-during-revision: process death INSIDE the revision window, at
|
|
1001
|
+
* the pre-append kill point (docs/09 round-2): life 1 is truncated
|
|
1002
|
+
* strictly BEFORE the second plan.revision entry; life 2 re-issues the
|
|
1003
|
+
* revision live and rolls its effects forward.
|
|
1004
|
+
*/
|
|
1005
|
+
declare function runCrashDuringRevision(): Promise<JournalEntry[]>;
|
|
1006
|
+
/**
|
|
1007
|
+
* oscillation-freeze: the coarse-signature oscillation detector freezes
|
|
1008
|
+
* further re-adds under hysteresis (docs/09 round-2; distinct from the
|
|
1009
|
+
* per-key osc_guard reject).
|
|
1010
|
+
*/
|
|
1011
|
+
declare function runOscillationFreeze(options?: PlanRunnerOptions): Promise<JournalEntry[]>;
|
|
1012
|
+
/**
|
|
1013
|
+
* park-unpark: park of a running node with checkpoint retention, later
|
|
1014
|
+
* unpark and continuation (docs/09 round-2; docs/03 11.2). The worker
|
|
1015
|
+
* pays one tool turn, hangs in its second, parks at the boundary, and
|
|
1016
|
+
* the unparked continuation resumes from the retained checkpoint (the
|
|
1017
|
+
* booted history carries the paid turn).
|
|
1018
|
+
*/
|
|
1019
|
+
declare function runParkUnpark(): Promise<JournalEntry[]>;
|
|
1020
|
+
/**
|
|
1021
|
+
* half-escalated-ladder: some rungs terminal, the active rung dangling
|
|
1022
|
+
* mid-attempt at the crash; resume continues the ladder without
|
|
1023
|
+
* repaying completed rungs (docs/09 round-2).
|
|
1024
|
+
*/
|
|
1025
|
+
declare function runHalfEscalatedLadder(): Promise<JournalEntry[]>;
|
|
1026
|
+
/**
|
|
1027
|
+
* budget-denied-rung: the budget guard denies the rung respawn; the
|
|
1028
|
+
* denial journals as termination.denied strictly before the verdict and
|
|
1029
|
+
* the ladder takes its declared fallback path (docs/09 round-2).
|
|
1030
|
+
*/
|
|
1031
|
+
declare function runBudgetDeniedRung(): Promise<JournalEntry[]>;
|
|
1032
|
+
/**
|
|
1033
|
+
* cap-freeze-then-finish (DEF-7): the soft boundary crossed with live
|
|
1034
|
+
* children; the cap decision precedes its effects; admitted nodes run to
|
|
1035
|
+
* completion; the final quiescence wake gets the finish-only toolset;
|
|
1036
|
+
* outcome ok with forcedFinish (docs/09).
|
|
1037
|
+
*/
|
|
1038
|
+
declare function runCapFreezeThenFinish(): Promise<JournalEntry[]>;
|
|
1039
|
+
/**
|
|
1040
|
+
* crash-between-cap-and-effects (DEF-7): process death right after the
|
|
1041
|
+
* cap decision entry, before any of its effects; resume re-derives the
|
|
1042
|
+
* frozen state from the entry and rolls the forced finish forward.
|
|
1043
|
+
*/
|
|
1044
|
+
declare function runCrashBetweenCapAndEffects(): Promise<JournalEntry[]>;
|
|
1045
|
+
/**
|
|
1046
|
+
* finalize-fallback-synthesized (DEF-7): the final finish fails inside
|
|
1047
|
+
* its turn limit; the engine journals orchestrator_finalize_fallback and
|
|
1048
|
+
* synthesizes the deterministic partial by pure fold; outcome exhausted
|
|
1049
|
+
* with the non-null value.
|
|
1050
|
+
*/
|
|
1051
|
+
declare function runFinalizeFallbackSynthesized(): Promise<JournalEntry[]>;
|
|
1052
|
+
/**
|
|
1053
|
+
* escalation-storm-frozen (DEF-7 set): three Flavor B escalations while
|
|
1054
|
+
* the plan is frozen at the cap; each resolves through its journaled
|
|
1055
|
+
* defaultDecision and the lineage counters hold. The branches CHAIN via
|
|
1056
|
+
* dependencies so exactly one deadline timer is live at a time: the
|
|
1057
|
+
* journal byte order stays deterministic (DEF-4 already guarantees the
|
|
1058
|
+
* fold; the cassette asserts bytes).
|
|
1059
|
+
*/
|
|
1060
|
+
declare function runEscalationStormFrozen(): Promise<JournalEntry[]>;
|
|
1061
|
+
/**
|
|
1062
|
+
* revision-exhaustion (DEF-2): the absolute revision budget hits zero;
|
|
1063
|
+
* termination.denied precedes the typed error; the guards chain closes
|
|
1064
|
+
* the run without HITL.
|
|
1065
|
+
*/
|
|
1066
|
+
declare function runRevisionExhaustion(): Promise<JournalEntry[]>;
|
|
1067
|
+
/**
|
|
1068
|
+
* rung-retry-lineage (DEF-3): the ladder raise continues the SAME
|
|
1069
|
+
* logical task with relation rung-retry; attemptsUsed counts both rungs.
|
|
1070
|
+
*/
|
|
1071
|
+
declare function runRungRetryLineage(): Promise<JournalEntry[]>;
|
|
1072
|
+
/**
|
|
1073
|
+
* decompose-mints-children (DEF-3): an escalation decomposition mints
|
|
1074
|
+
* FRESH logical tasks inside the decision entry; the spawn debits ride
|
|
1075
|
+
* the same entry (docs/07, 8.1 rule 6, 11.3 b).
|
|
1076
|
+
*/
|
|
1077
|
+
declare function runDecomposeMintsChildren(): Promise<JournalEntry[]>;
|
|
1078
|
+
/**
|
|
1079
|
+
* queue-failover-during-forced-finish (the DEF-7 final cassette;
|
|
1080
|
+
* docs/09, section 6.9; M8-T03): worker A loses its lease strictly
|
|
1081
|
+
* between the cap decision and the final wake; worker B reclaims with a
|
|
1082
|
+
* bumped fencing epoch and rolls the forced finish forward. The stale
|
|
1083
|
+
* writer's appends are rejected and invisible, exactly one cap decision
|
|
1084
|
+
* exists, and finalization is paid once.
|
|
1085
|
+
*
|
|
1086
|
+
* The LeasableStore is INJECTED so this package stays core-only: the
|
|
1087
|
+
* replay test and the record script supply the reference SqliteStore
|
|
1088
|
+
* (docs/03, 12.6). One deterministic clock drives lease expiry.
|
|
1089
|
+
*/
|
|
1090
|
+
interface QueueFailoverDeps {
|
|
1091
|
+
/** A fresh LeasableStore over the injected clock (SqliteStore ':memory:' in the suite). */
|
|
1092
|
+
makeStore: (now: () => number) => JournalStore & LeasableStore;
|
|
1093
|
+
}
|
|
1094
|
+
declare function runQueueFailoverDuringForcedFinish(deps: QueueFailoverDeps): Promise<JournalEntry[]>;
|
|
1095
|
+
//#endregion
|
|
1096
|
+
//#region src/tools.d.ts
|
|
1097
|
+
/** docs/07, 4.6: plan_view takes no parameters. */
|
|
1098
|
+
declare const PLAN_VIEW_SCHEMA: SchemaSpec;
|
|
1099
|
+
/** docs/07, 4.7: the plan_revise parameter schema (normative). */
|
|
1100
|
+
declare const PLAN_REVISE_SCHEMA: SchemaSpec;
|
|
1101
|
+
declare const PLAN_VIEW_TOOL_NAME = "plan_view";
|
|
1102
|
+
declare const PLAN_REVISE_TOOL_NAME = "plan_revise";
|
|
1103
|
+
declare const LEDGER_APPEND_TOOL_NAME = "ledger_append";
|
|
1104
|
+
declare const LEDGER_READ_TOOL_NAME = "ledger_read";
|
|
1105
|
+
/** The closed authored op vocabulary as JSON Schema (docs/07, 9.2). */
|
|
1106
|
+
declare const LEDGER_APPEND_SCHEMA: SchemaSpec;
|
|
1107
|
+
/** docs/07: ledger_read takes no parameters and pins to the turn snapshot. */
|
|
1108
|
+
declare const LEDGER_READ_SCHEMA: SchemaSpec;
|
|
1109
|
+
/** One rendered node of the pinned plan_view fold. */
|
|
1110
|
+
interface PlanViewNode {
|
|
1111
|
+
nodeId: NodeId;
|
|
1112
|
+
logicalTaskId: string;
|
|
1113
|
+
status: PlanNodeStatus;
|
|
1114
|
+
deps: NodeId[];
|
|
1115
|
+
waivedDeps: NodeId[];
|
|
1116
|
+
priority: number;
|
|
1117
|
+
lineage?: LineageStats;
|
|
1118
|
+
}
|
|
1119
|
+
/** The plan_view render (docs/07, 4.6): plan state, lineage, termination, reuse. */
|
|
1120
|
+
interface PlanViewRender {
|
|
1121
|
+
planHash: string;
|
|
1122
|
+
revisionCount: number;
|
|
1123
|
+
droppedRevisionStreak: number;
|
|
1124
|
+
nodes: PlanViewNode[];
|
|
1125
|
+
termination: TerminationAccountSnapshot;
|
|
1126
|
+
/** The abandoned-spend ledger (DEF-5); zeros until M7-T07 activates it. */
|
|
1127
|
+
abandonedSpend: {
|
|
1128
|
+
abandonedUsd: number;
|
|
1129
|
+
reclaimedUsd: number;
|
|
1130
|
+
netLostUsd: number;
|
|
1131
|
+
};
|
|
1132
|
+
/** RevisionGuards state (docs/07, 3.8; M7-T06). */
|
|
1133
|
+
guards?: {
|
|
1134
|
+
engaged?: "reject-revision" | "finish-with-partial" | "fail-run";
|
|
1135
|
+
frozenSignatures: string[];
|
|
1136
|
+
stallReplansUsed: number;
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
/** The engine seam the plan tools close over. */
|
|
1140
|
+
interface PlanToolRuntime {
|
|
1141
|
+
planView(): PlanViewRender;
|
|
1142
|
+
planRevise(request: PlanReviseRequest): Promise<PlanReviseResult>;
|
|
1143
|
+
ledgerAppend(op: LedgerOp): Promise<{
|
|
1144
|
+
entryRef: number;
|
|
1145
|
+
}>;
|
|
1146
|
+
ledgerRead(): LedgerView;
|
|
1147
|
+
}
|
|
1148
|
+
/** Builds the PlanRunner tools (appended to the mode (c) toolset). */
|
|
1149
|
+
declare function buildPlanTools(runtime: PlanToolRuntime): ToolDef[];
|
|
1150
|
+
//#endregion
|
|
1151
|
+
//#region src/m9-cassettes.d.ts
|
|
1152
|
+
/**
|
|
1153
|
+
* combined-loop-descent (DEF-2): a verify-failed gate raises the ladder
|
|
1154
|
+
* rung; the raised rung hits its turn limit at the top (trigger 'limit')
|
|
1155
|
+
* and the node fails; the failure wakes a replan that decomposes the
|
|
1156
|
+
* work into two depth-1 children; one child completes and the other
|
|
1157
|
+
* escalates until its escalationUnits deny; Phi strictly decreases on
|
|
1158
|
+
* every debiting entry and matches the embedded balances.
|
|
1159
|
+
*/
|
|
1160
|
+
declare function runCombinedLoopDescent(): Promise<JournalEntry[]>;
|
|
1161
|
+
/**
|
|
1162
|
+
* config-drift-resume (DEF-2): life 1 runs under maxRevisionsPerRun 2
|
|
1163
|
+
* and crashes at the pre-append kill point of its second revision; life
|
|
1164
|
+
* 2 resumes with the knob DOUBLED. Balances continue from the journaled
|
|
1165
|
+
* termination.init (the live config is ignored), a
|
|
1166
|
+
* termination:config-drift event fires, and nothing is repaid.
|
|
1167
|
+
*/
|
|
1168
|
+
declare function runConfigDriftResume(): Promise<JournalEntry[]>;
|
|
1169
|
+
/**
|
|
1170
|
+
* class-storm-single-turn (DEF-2): five dependency-chained workers each
|
|
1171
|
+
* escalate (Flavor A); the orchestrator resolves all five in ONE
|
|
1172
|
+
* revision; the class-level decision carries five per-lineage debits in
|
|
1173
|
+
* one entry. Store-independence (identical fold on JSONL and SQLite) is
|
|
1174
|
+
* asserted by the replay suite over the frozen bytes.
|
|
1175
|
+
*/
|
|
1176
|
+
declare function runClassStormSingleTurn(): Promise<JournalEntry[]>;
|
|
1177
|
+
/**
|
|
1178
|
+
* race-timeout-vs-live (DEF-2): a Flavor B deadline resolution and a
|
|
1179
|
+
* live class decision race on one suspension; first-wins applies the
|
|
1180
|
+
* timeout, the live attempt lands as a noop, and exactly ONE
|
|
1181
|
+
* escalationUnits debit exists. Store-independence is asserted by the
|
|
1182
|
+
* replay suite.
|
|
1183
|
+
*/
|
|
1184
|
+
declare function runRaceTimeoutVsLive(): Promise<JournalEntry[]>;
|
|
1185
|
+
/**
|
|
1186
|
+
* respawn-preserves-counter (DEF-3): the worker escalates, the
|
|
1187
|
+
* orchestrator respawns the SAME logical task with an amended prompt
|
|
1188
|
+
* (new content key, same LTID) twice; the third escalation exceeds
|
|
1189
|
+
* maxEscalationsPerLogicalTask, is denied on escalationUnits, and the
|
|
1190
|
+
* run closes through the non-HITL fallback with identical verdicts and
|
|
1191
|
+
* statsBefore on replay.
|
|
1192
|
+
*/
|
|
1193
|
+
declare function runRespawnPreservesCounter(): Promise<JournalEntry[]>;
|
|
1194
|
+
/**
|
|
1195
|
+
* reworded-lessons-collide (DEF-3): two attempts of one LTID whose
|
|
1196
|
+
* prompts differ but whose signature inputs are identical and share the
|
|
1197
|
+
* 'binary-search' tag; the engine computes equal approachSig values,
|
|
1198
|
+
* lesson_add keys once, and plan_view groups both attempts into one
|
|
1199
|
+
* approach.
|
|
1200
|
+
*/
|
|
1201
|
+
declare function runRewordedLessonsCollide(): Promise<JournalEntry[]>;
|
|
1202
|
+
/**
|
|
1203
|
+
* oscillation-bounded (DEF-2): an escalated branch is cancelled and
|
|
1204
|
+
* re-added byte-identically twice; every plan_revise call debits one
|
|
1205
|
+
* revisionUnit (including the drop on the linked done node), each link
|
|
1206
|
+
* debits one spawnUnit, the worker is paid exactly once, and the
|
|
1207
|
+
* lineage counters never reset.
|
|
1208
|
+
*/
|
|
1209
|
+
declare function runOscillationBounded(): Promise<JournalEntry[]>;
|
|
1210
|
+
/**
|
|
1211
|
+
* stall-streak-classes-and-pinning (DEF-3): four attempts of one LTID
|
|
1212
|
+
* land transient-error, task-error, no-progress, and ok; the pinned
|
|
1213
|
+
* admission snapshots show stallStreak 0, 1, 2 and the post-ok pinned
|
|
1214
|
+
* view shows 0; a wake turn re-executed after a crash reads the SAME
|
|
1215
|
+
* LineageStats from its snapshot, not a fresh fold.
|
|
1216
|
+
*/
|
|
1217
|
+
declare function runStallStreakClassesAndPinning(): Promise<JournalEntry[]>;
|
|
1218
|
+
/**
|
|
1219
|
+
* legacy-journal-resume (DEF-3): a journal whose spawns carry no lineage
|
|
1220
|
+
* records (the pre-lineage shape) resumes on the current engine; the
|
|
1221
|
+
* legacy spawns canonize onto deterministic 'legacy:' LTIDs, forward
|
|
1222
|
+
* matching pays nothing for them, and the NEW lineage-declaring spawn's
|
|
1223
|
+
* admission entry carries sigVersion 1.
|
|
1224
|
+
*/
|
|
1225
|
+
declare function runLegacyJournalResume(): Promise<JournalEntry[]>;
|
|
1226
|
+
/**
|
|
1227
|
+
* oscillation-full-reuse (DEF-5): a branch whose escalated-terminal root
|
|
1228
|
+
* is severed by cancel_task and re-added byte-identically links
|
|
1229
|
+
* reuse_full: the verdict is embedded in the plan.revision, the
|
|
1230
|
+
* node.link (mode full, claim shared) and the by-ref root are present,
|
|
1231
|
+
* the reused subtree costs zero live calls, and reclaimedUsdAtLink
|
|
1232
|
+
* equals the donor spend (docs/03, 9.4/9.5).
|
|
1233
|
+
*/
|
|
1234
|
+
declare function runOscillationFullReuse(): Promise<JournalEntry[]>;
|
|
1235
|
+
/**
|
|
1236
|
+
* graft-partial-subtree (DEF-5): the three-rung limit ladder is severed
|
|
1237
|
+
* mid-top-rung after two completed rung attempts; the byte-identical
|
|
1238
|
+
* re-add grafts (exclusive link), the completed rung attempts
|
|
1239
|
+
* forward-match through the scope alias, and only the interrupted rung
|
|
1240
|
+
* reruns live, exactly once (docs/03, 9.5).
|
|
1241
|
+
*/
|
|
1242
|
+
declare function runGraftPartialSubtree(): Promise<JournalEntry[]>;
|
|
1243
|
+
/**
|
|
1244
|
+
* crash-between-link-and-root (DEF-5): the full-reuse scenario is cut
|
|
1245
|
+
* strictly AFTER the durable node.link and BEFORE the by-ref root; the
|
|
1246
|
+
* resume rolls forward: the link forward-matches, the root is re-issued,
|
|
1247
|
+
* and nothing is paid twice (docs/03, 9.10).
|
|
1248
|
+
*/
|
|
1249
|
+
declare function runCrashBetweenLinkAndRoot(): Promise<JournalEntry[]>;
|
|
1250
|
+
/**
|
|
1251
|
+
* oscillation-guard-trip (DEF-5): the third re-add of one SpawnKey at
|
|
1252
|
+
* maxOscillationsPerKey 2 rejects osc_guard as a typed plan_revise
|
|
1253
|
+
* error; the run closes through the non-HITL path and the embedded
|
|
1254
|
+
* verdicts replay identically (docs/03, 9.4).
|
|
1255
|
+
*/
|
|
1256
|
+
declare function runOscillationGuardTrip(): Promise<JournalEntry[]>;
|
|
1257
|
+
/**
|
|
1258
|
+
* worktree-disposed-degrade (DEF-5): a worktree-isolated graft donor
|
|
1259
|
+
* whose tree was NOT retained degrades to a fresh admit with the
|
|
1260
|
+
* embedded DedupNote graft_unsafe; a second section verifies reuse_full
|
|
1261
|
+
* stays allowed for a worktree donor whose root is terminal (docs/03,
|
|
1262
|
+
* 9.4: the pin condition applies to grafts only).
|
|
1263
|
+
*/
|
|
1264
|
+
declare function runWorktreeDisposedDegrade(): Promise<JournalEntry[]>;
|
|
1265
|
+
/**
|
|
1266
|
+
* claim-exclusivity-and-chain (DEF-5): one revision adds TWO identical
|
|
1267
|
+
* tasks; the first grafts (exclusive claim), the second admits fresh;
|
|
1268
|
+
* the grafted node is severed and the key added a third time: the link
|
|
1269
|
+
* points at the chain head and the drain is transitive, oldest first;
|
|
1270
|
+
* oscillationCount for the key reaches 2 (docs/03, 9.6).
|
|
1271
|
+
*/
|
|
1272
|
+
declare function runClaimExclusivityAndChain(): Promise<JournalEntry[]>;
|
|
1273
|
+
/**
|
|
1274
|
+
* revise-racing-defaultDecision (DEF-8, mandatory): while the
|
|
1275
|
+
* orchestrator sleeps, the upstream Flavor B timeout resolves a node
|
|
1276
|
+
* done, a second node escalates, and a third completes; the wake
|
|
1277
|
+
* submits ONE stale-based revision {waive_dep, park_task, cancel_task}
|
|
1278
|
+
* whose trio drops with the exact reasons and the blockingRef pointing
|
|
1279
|
+
* at the defaultDecision resolution (docs/07, 3.5; docs/09, 6.8).
|
|
1280
|
+
*/
|
|
1281
|
+
declare function runReviseRacingDefaultDecision(): Promise<JournalEntry[]>;
|
|
1282
|
+
/**
|
|
1283
|
+
* crash-after-append-before-effects (DEF-8): the kill lands immediately
|
|
1284
|
+
* after the durable plan.revision carrying add_task x2 plus cancel_task
|
|
1285
|
+
* on a running node; the resume re-issues the effects: both children
|
|
1286
|
+
* spawn live exactly once and the cancel lands (docs/07, 3.9).
|
|
1287
|
+
*/
|
|
1288
|
+
declare function runCrashAfterAppendBeforeEffects(): Promise<JournalEntry[]>;
|
|
1289
|
+
/**
|
|
1290
|
+
* amend-vs-running-then-cancel-add (DEF-8): amend_task on a running node
|
|
1291
|
+
* drops node_running; the next revision cancels it and adds the amended
|
|
1292
|
+
* prompt as a NEW node continuing the SAME logical task; the abandon
|
|
1293
|
+
* covers the old branch and replay repays neither (docs/07, 4.7).
|
|
1294
|
+
*/
|
|
1295
|
+
declare function runAmendVsRunningThenCancelAdd(): Promise<JournalEntry[]>;
|
|
1296
|
+
/**
|
|
1297
|
+
* intra-revision-self-conflict (DEF-8): one revision {cancel_task X,
|
|
1298
|
+
* amend_task X, rewire_deps with an edge onto X} resolves strictly in
|
|
1299
|
+
* submission order per the sequential intra-revision application
|
|
1300
|
+
* semantics (docs/07, 4.7 conflict table).
|
|
1301
|
+
*/
|
|
1302
|
+
declare function runIntraRevisionSelfConflict(): Promise<JournalEntry[]>;
|
|
1303
|
+
/**
|
|
1304
|
+
* bad-base-streak-terminates (DEF-8): three consecutive revisions with a
|
|
1305
|
+
* fabricated base.planHash land as all-dropped bad-base entries; the
|
|
1306
|
+
* dropped streak reaches its limit and the non-HITL RevisionGuards
|
|
1307
|
+
* fallback (finish-with-partial) closes the run (docs/07, 3.5/3.8).
|
|
1308
|
+
*/
|
|
1309
|
+
declare function runBadBaseStreakTerminates(): Promise<JournalEntry[]>;
|
|
1310
|
+
/**
|
|
1311
|
+
* park-races-child-completion (DEF-8): park_task lands on a running node
|
|
1312
|
+
* whose terminal appends moments later; parkRequested is extinguished by
|
|
1313
|
+
* the child-result transition, no checkpoint is written, and the node is
|
|
1314
|
+
* done (docs/07, 3.6).
|
|
1315
|
+
*/
|
|
1316
|
+
declare function runParkRacesChildCompletion(): Promise<JournalEntry[]>;
|
|
1317
|
+
/**
|
|
1318
|
+
* reserve-survives-run-exhaustion (DEF-7): cheap workers eat the run
|
|
1319
|
+
* ceiling until admission rejects the spawn that would invade the
|
|
1320
|
+
* committed finalize reserve; the final wake executes from the reserve
|
|
1321
|
+
* and the rejections forward-match on replay (docs/07, 12.4).
|
|
1322
|
+
*/
|
|
1323
|
+
declare function runReserveSurvivesRunExhaustion(): Promise<JournalEntry[]>;
|
|
1324
|
+
//#endregion
|
|
1325
|
+
//#region src/m10-cassettes.d.ts
|
|
1326
|
+
/**
|
|
1327
|
+
* kb-pin-replay (docs/09, 6.11): the pin at admission and the repin at
|
|
1328
|
+
* the wake, card bytes embedded, model names withheld.
|
|
1329
|
+
*/
|
|
1330
|
+
declare function runKbPinReplay(): Promise<JournalEntry[]>;
|
|
1331
|
+
/**
|
|
1332
|
+
* kb-repin-expiry (docs/09, 6.11): the repin re-applies the docs/05
|
|
1333
|
+
* filters against a FRESH read; a claim the store dropped between the
|
|
1334
|
+
* pin and the wake stops steering, while the boot pin's bytes stand.
|
|
1335
|
+
*/
|
|
1336
|
+
declare function runKbRepinExpiry(): Promise<JournalEntry[]>;
|
|
1337
|
+
//#endregion
|
|
1338
|
+
export { AppliedPlanOp, BUDGET, CassetteTurn, DEFAULT_DROPPED_REVISION_LIMIT, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_STALL_REPLAN_CAP, EMPTY_PLAN_HASH, EnginePlanOp, EscalationDebitRow, EscalationDecisionValue, GateVerdictValue, GuardFallback, GuardVerdictValue, GuardsState, JUDGE_VERDICT_SCHEMA, LEDGER_APPEND_SCHEMA, LEDGER_APPEND_TOOL_NAME, LEDGER_READ_SCHEMA, LEDGER_READ_TOOL_NAME, LEDGER_RENDER_BUDGET_CHARS, LEDGER_SECTION_CAPS, LadderVerdictValue, LedgerExport, LedgerFact, LedgerLesson, LedgerObservation, LedgerOp, LedgerRevisionRow, LedgerView, M7CassetteFixture, PLAN_HASH_VERSION, PLAN_REVISE_SCHEMA, PLAN_REVISE_TOOL_NAME, PLAN_SCOPE, PLAN_VIEW_SCHEMA, PLAN_VIEW_TOOL_NAME, ParkDisposition, PinLedger, PlanDecisionOrigin, PlanDecisionValue, PlanFoldState, PlanNode, PlanNodeStatus, PlanOp, PlanReviseErrorCode, PlanReviseRequest, PlanReviseResult, PlanRevisionAdmission, PlanRevisionValue, PlanRunnerOptions, PlanSnapshotRef, PlanToolRuntime, PlanViewNode, PlanViewRender, PlanWorking, PlanWriteLock, QueueFailoverDeps, RebaseContext, RebaseEvaluation, RebaseOutcome, RebaseReasonCode, ReuseTransform, RevisionGuards, RevisionGuardsOptions, TaskPlan, TaskSpec, TaskSpecPatch, UnparkPlacement, agentTypeOfRequest, applyAppliedOp, applyDecisionOps, applyPlanEntry, applyTaskSpecPatch, assertPlanHead, assertPlanTransition, boundLedgerRender, buildPlanTools, canonicalLadderOf, canonicalPlanState, cassetteAdapter, chainEffortOf, clampStartTier, decisionOriginOf, depsSatisfied, effectiveDroppedStreak, emptyPlan, emptyPlanFold, engineWith, escalationDecisionKey, executingRungOf, exportLedger, foldLedger, gateVerdictKey, isTerminalPlanStatus, judgePrompt, ladderOfProfile, ladderTriggerOf, ladderVerdictKey, ledgerCapViolation, ledgerOpKey, ledgerSufficiency, normalizeAdaptiveJournal, orchestratePlanned, parkDispositionOf, planDecisionKey, planHash, planRevisionKey, planRunner, promptSpecHashOf, readPlanDecision, readPlanRevision, rebasePlanRevision, recomputePlanReadiness, resolvedByOf, runAmendVsRunningThenCancelAdd, runBadBaseStreakTerminates, runBudgetDeniedRung, runCapFreezeThenFinish, runClaimExclusivityAndChain, runClassStormSingleTurn, runCombinedLoopDescent, runConfigDriftResume, runCrashAfterAppendBeforeEffects, runCrashBetweenCapAndEffects, runCrashBetweenLinkAndRoot, runCrashDuringRevision, runDecomposeMintsChildren, runEscalationStormFrozen, runFinalizeFallbackSynthesized, runGraftPartialSubtree, runHalfEscalatedLadder, runIntraRevisionSelfConflict, runKbPinReplay, runKbRepinExpiry, runLegacyJournalResume, runOscillationBounded, runOscillationFreeze, runOscillationFullReuse, runOscillationGuardTrip, runParkRacesChildCompletion, runParkUnpark, runQueueFailoverDuringForcedFinish, runRaceTimeoutVsLive, runReserveSurvivesRunExhaustion, runRespawnPreservesCounter, runReviseMidRun, runReviseRacingDefaultDecision, runRevisionExhaustion, runRewordedLessonsCollide, runRungRetryLineage, runStallStreakClassesAndPinning, runWorktreeDisposedDegrade, settled, unparkPlacementOf, wouldCreateDepCycle };
|