Skip to content
7 min read · 1,487 words

Class: InMemoryPlanStore ​

Defined in: src/batteries/orchestration/in_memory.ts:66

The reference in-memory implementation of the PlanStore contract.

Every operation is asynchronous and returns a structured result rather than throwing for the expected, precondition-style failures the contract names — so a caller can branch on the outcome without exception handling. Lifecycle transitions and run claiming are atomic with respect to the single-threaded event loop: a plan is mutated only through these methods, so no interleaving can observe a half-applied change.

The store commits; it does not validate. Deciding whether a plan is well-formed, whether an evaluator is wired, or whether a tool is on the allowlist is battery knowledge this class has no access to, so those checks live upstream and this class only records the outcome.

Implements ​

Constructors ​

Constructor ​

ts
new InMemoryPlanStore(): InMemoryPlanStore;

Returns ​

InMemoryPlanStore

Methods ​

appendOps() ​

ts
appendOps(
   planId: string,
   ops: PlanOp[],
expectedRevision?: number): Promise<AppendResult>;

Defined in: src/batteries/orchestration/in_memory.ts:185

Append ops to a plan's log.

The plan must be editable; this is checked in the same operation as the append, which is what keeps reviewable and executable plans frozen at the only boundary that can enforce it. Without the check, ops could change a frozen plan's content and digest while its stored state stayed frozen, and an executable plan's approval would remain bound to a prior digest — a plan executable with content nobody approved.

Parameters ​

ParameterTypeDescription
planIdstringThe plan to append to.
opsPlanOp[]The ops to append.
expectedRevision?numberIf given, the log must still be at this revision (optimistic concurrency for a single author); omit it for the multi-writer CRDT case.

Returns ​

Promise<AppendResult>

A success result carrying the new revision and digest, or not_editable / revision_moved with the actual state.

Implementation of ​

PlanStore.appendOps


appendRunEvents() ​

ts
appendRunEvents(
   planId: string,
   runId: string,
events: RunEvent[]): Promise<void>;

Defined in: src/batteries/orchestration/in_memory.ts:424

Append a batch of run events atomically.

The whole array is committed as one batch, so the commit protocol can land node_settled, every edge_taken, and the new frontier_snapshot in a single commit.

A run is marked TERMINALLY settled only by run_settled{outcome: 'completed'}. aborted and halted are STOPPING POINTS, not endings: the interruption taxonomy classifies a turn abort as resumable with the frontier intact and the same digest, and a halted run is resumable once whatever halted it is addressed. Marking those terminal made claimRun(resumeRunId) answer run_already_settled and resumeRunId unusable for the exact cases it exists to serve.

A run that later resumes and completes is settled then, which is the point at which no further work can follow.

Parameters ​

ParameterTypeDescription
planIdstringThe plan the run belongs to.
runIdstringThe run to append to.
eventsRunEvent[]The events to append.

Returns ​

Promise<void>

Implementation of ​

PlanStore.appendRunEvents


claimRun() ​

ts
claimRun(
   planId: string,
   expectedDigest: string,
resumeRunId?: string): Promise<ClaimRunResult>;

Defined in: src/batteries/orchestration/in_memory.ts:370

Claim a run for a plan.

The plan must be executable at expectedDigest. Without a resume id, a run is started only if none was ever claimed; with a resume id, that specific run is re-entered only if it exists and is not settled. This is what enforces one plan, at most one run, ever.

Parameters ​

ParameterTypeDescription
planIdstringThe plan to run.
expectedDigeststringThe digest the plan must be at.
resumeRunId?stringOptional id of a run to resume.

Returns ​

Promise<ClaimRunResult>

A success result carrying the run id and whether it was resumed, or a structured failure.

Implementation of ​

PlanStore.claimRun


clonePlan() ​

ts
clonePlan(
   sourcePlanId: string,
   newPlanId: string,
atRevision?: number): Promise<CreateResult>;

Defined in: src/batteries/orchestration/in_memory.ts:122

Clone an existing plan into a new id, seeded with the source's folded state at a given revision.

The clone is minted in editable and inherits no approval and no run — it is cold by construction. Its provenance records the parent, the parent's digest, the parent's revision, and the node ids that had settled ok when the clone was taken (or [] if the source never ran). The operation is atomic: either the clone exists complete or not at all.

Parameters ​

ParameterTypeDescription
sourcePlanIdstringThe plan to clone from.
newPlanIdstringThe id for the new plan.
atRevision?numberThe source revision to clone at; defaults to the source's current revision.

Returns ​

Promise<CreateResult>

A success result carrying the clone's revision and digest, or source_missing / revision_missing / duplicate_id.

Implementation of ​

PlanStore.clonePlan


createPlan() ​

ts
createPlan(planId: string, meta?: {
  label?: string;
  provenance?: InstantiatedFrom;
}): Promise<CreateResult>;

Defined in: src/batteries/orchestration/in_memory.ts:81

Mint a new plan in the editable state at revision 0.

The op log is genuinely empty: revision 0 is the fold seed, not an implied op, so readOps returns [] and the first authoring op produces revision 1. Instantiation lineage is persisted when supplied.

Parameters ​

ParameterTypeDescription
planIdstringThe id of the new plan.
meta?{ label?: string; provenance?: InstantiatedFrom; }Optional label and instantiation lineage to attach.
meta.label?string-
meta.provenance?InstantiatedFrom-

Returns ​

Promise<CreateResult>

A success result carrying the new plan's revision and digest, or duplicate_id if the id is already taken.

Implementation of ​

PlanStore.createPlan


list() ​

ts
list(filter?: {
  state?: PlanState;
}): Promise<PlanSummary[]>;

Defined in: src/batteries/orchestration/in_memory.ts:292

List plans, optionally filtered by lifecycle state.

Parameters ​

ParameterTypeDescription
filter?{ state?: PlanState; }Optional state filter.
filter.state?PlanState-

Returns ​

Promise<PlanSummary[]>

A summary of each matching plan.

Implementation of ​

PlanStore.list


readApproval() ​

ts
readApproval(planId: string): Promise<
  | ApprovalRecord
| undefined>;

Defined in: src/batteries/orchestration/in_memory.ts:282

Read the approval record bound to a plan's current digest.

Parameters ​

ParameterTypeDescription
planIdstringThe plan to read from.

Returns ​

Promise< | ApprovalRecord | undefined>

The approval, or undefined if the plan has not been approved.

Implementation of ​

PlanStore.readApproval


readOps() ​

ts
readOps(planId: string, opts?: {
  sinceLamport?: number;
  throughRevision?: number;
}): Promise<PlanOp[]>;

Defined in: src/batteries/orchestration/in_memory.ts:224

Read the ops of a plan's log.

sinceLamport filters by clock; throughRevision bounds the result to a revision prefix (the first N ops in sorted order), which is what a historical view needs. A revision the log never reached is rejected rather than silently returning everything.

Parameters ​

ParameterTypeDescription
planIdstringThe plan to read from.
opts?{ sinceLamport?: number; throughRevision?: number; }Optional filtering options.
opts.sinceLamport?number-
opts.throughRevision?number-

Returns ​

Promise<PlanOp[]>

The matching ops.

Implementation of ​

PlanStore.readOps


readProvenance() ​

ts
readProvenance(planId: string): Promise<
  | PlanProvenance
| undefined>;

Defined in: src/batteries/orchestration/in_memory.ts:254

Read the provenance of a plan.

Parameters ​

ParameterTypeDescription
planIdstringThe plan to read from.

Returns ​

Promise< | PlanProvenance | undefined>

The provenance, or undefined for a plan that is not a clone or was not instantiated.

Implementation of ​

PlanStore.readProvenance


readRunEvents() ​

ts
readRunEvents(planId: string, runId?: string): Promise<RunEvent[]>;

Defined in: src/batteries/orchestration/in_memory.ts:446

Read the events of a run.

Parameters ​

ParameterTypeDescription
planIdstringThe plan the run belongs to.
runId?stringThe run to read; omitted reads the plan's only run.

Returns ​

Promise<RunEvent[]>

The events.

Implementation of ​

PlanStore.readRunEvents


readState() ​

ts
readState(planId: string): Promise<{
  digest: string;
  revision: number;
  state: PlanState;
}>;

Defined in: src/batteries/orchestration/in_memory.ts:264

Read the current lifecycle state, digest, and revision of a plan.

Parameters ​

ParameterTypeDescription
planIdstringThe plan to read from.

Returns ​

Promise<{ digest: string; revision: number; state: PlanState; }>

The state, digest, and revision.

Implementation of ​

PlanStore.readState


transition() ​

ts
transition(planId: string, t: TransitionRequest): Promise<TransitionResult>;

Defined in: src/batteries/orchestration/in_memory.ts:326

Perform the single atomic lifecycle transition.

The plan must be in the state t.from implies and at t.expectedDigest; the pair must be a legal transition. For reviewable → executable, the approval is persisted in the same operation. No policy is evaluated here — the battery validates, the store commits.

Parameters ​

ParameterTypeDescription
planIdstringThe plan to transition.
tTransitionRequestThe transition request.

Returns ​

Promise<TransitionResult>

A success result carrying the new revision, or state_mismatch / digest_mismatch with the actual state and digest, or illegal_transition for a request the type system did not police.

Implementation of ​

PlanStore.transition