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 reviewableexecutable, 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