@ddse/acm-runtime
v0.5.0
Published
ACM v0.5 Runtime - Plan execution engine
Readme
@ddse/acm-runtime
ACM v0.5 execution engine with guards, retries, policy hooks, and memory ledger.
Overview
The runtime package provides deterministic plan execution with full ACM v0.5 semantics including guard evaluation, retry logic, policy enforcement, verification, and decision logging.
Installation
pnpm add @ddse/acm-runtime @ddse/acm-sdkFeatures
- ✅ Task graph execution with topological ordering
- ✅ Guard expression evaluation
- ✅ Configurable retry with exponential backoff
- ✅ Policy pre/post hooks
- ✅ Verification assertions
- ✅ Memory ledger (append-only decision log)
- ✅ Streaming progress updates
- ✅ Error handling and compensation
- ✅ Resumable execution with checkpointing (NEW in Phase 2)
Usage
Basic Execution
import { executePlan, MemoryLedger } from '@ddse/acm-runtime';
import type { Goal, Context, Plan } from '@ddse/acm-sdk';
const result = await executePlan({
goal: { id: 'g1', intent: 'Process order' },
context: { id: 'ctx1', facts: { orderId: 'O123' } },
plan: myPlan,
capabilityRegistry: myCapabilities,
toolRegistry: myTools,
});
const taskRecord = result.outputsByTask['task-1'];
console.log('Task output:', taskRecord?.output);
console.log('Narrative:', taskRecord?.narrative);
console.log('Ledger entries:', result.ledger.length);With Policy Enforcement
import { PolicyEngine, type PolicyDecision } from '@ddse/acm-sdk';
class MyPolicyEngine implements PolicyEngine {
async evaluate(action: string, payload: any): Promise<PolicyDecision> {
if (action === 'task.pre' && payload.riskLevel === 'HIGH') {
return { allow: false, reason: 'Risk too high' };
}
return { allow: true };
}
}
const result = await executePlan({
goal,
context,
plan,
capabilityRegistry,
toolRegistry,
policy: new MyPolicyEngine(),
});With Verification
const verify = async (taskId: string, output: any, expressions: string[]): Promise<boolean> => {
for (const expr of expressions) {
const func = new Function('output', `return ${expr};`);
if (!func(output)) {
console.error(`Verification failed: ${expr}`);
return false;
}
}
return true;
};
const result = await executePlan({
goal,
context,
plan,
capabilityRegistry,
toolRegistry,
verify,
});With Streaming
import { DefaultStreamSink } from '@ddse/acm-sdk';
const stream = new DefaultStreamSink();
stream.attach('task', (update) => {
console.log(`[${update.taskId}] ${update.status}`);
});
const result = await executePlan({
goal,
context,
plan,
capabilityRegistry,
toolRegistry,
stream,
});Memory Ledger
import { MemoryLedger } from '@ddse/acm-runtime';
const ledger = new MemoryLedger();
const result = await executePlan({
goal,
context,
plan,
capabilityRegistry,
toolRegistry,
ledger,
});
// Inspect decisions
for (const entry of ledger.getEntries()) {
console.log(`${entry.type} at ${entry.ts}:`, entry.details);
}Resumable Execution (Phase 2)
Execute plans with automatic checkpointing and resume support:
import { executeResumablePlan, FileCheckpointStore } from '@ddse/acm-runtime';
// Setup checkpoint storage
const checkpointStore = new FileCheckpointStore('./checkpoints');
const runId = 'my-run-123';
// Execute with checkpointing
const result = await executeResumablePlan({
goal,
context,
plan,
capabilityRegistry,
toolRegistry,
runId,
checkpointStore,
checkpointInterval: 1, // Checkpoint after each task
});Resume from a previous execution:
// Resume from checkpoint
const result = await executeResumablePlan({
goal,
context,
plan,
capabilityRegistry,
toolRegistry,
runId: 'my-run-123',
resumeFrom: 'checkpoint-xyz', // Resume from specific checkpoint
checkpointStore,
});Using the ResumableExecutor class:
import { ResumableExecutor, FileCheckpointStore } from '@ddse/acm-runtime';
const executor = new ResumableExecutor(
new FileCheckpointStore('./checkpoints')
);
// Execute with checkpointing
const result = await executor.execute({
goal,
context,
plan,
capabilityRegistry,
toolRegistry,
runId: 'my-run-123',
});
// List checkpoints
const checkpoints = await executor.listCheckpoints('my-run-123');
console.log(`Available checkpoints: ${checkpoints.length}`);
// Resume from latest checkpoint
const latest = await executor.getCheckpoint('my-run-123');
const resumed = await executor.execute({
goal,
context,
plan,
capabilityRegistry,
toolRegistry,
runId: 'my-run-123',
resumeFrom: latest?.id,
});API Reference
executePlan(options)
Execute a plan with full ACM v0.5 semantics.
Options:
goal: Goal- The goal being pursuedcontext: Context- Immutable context packetplan: Plan- The plan to executecapabilityRegistry: CapabilityRegistry- Task registrytoolRegistry: ToolRegistry- Tool registrypolicy?: PolicyEngine- Optional policy enforcementverify?: (taskId, output, expressions) => Promise<boolean>- Optional verificationstream?: StreamSink- Optional streaming sinkledger?: MemoryLedger- Optional ledger (created if not provided)
Returns:
{
outputsByTask: Record<string, TaskExecutionRecord>;
ledger: readonly LedgerEntry[];
}Each TaskExecutionRecord captures:
taskId: string– Identifier for the executed task.title: string– Task title from the structured plan.objective?: string– Optional objective provided by the planner.successCriteria?: string[]– Optional success criteria checklist.metadata?: TaskMetadata– Arbitrary TaskSpec metadata.narrative?: TaskNarrative– { start, checkpoints, completion } narrative emitted by the Nucleus.output?: unknown– The task's output payload, when present.
evaluateGuard(expr, context)
Evaluate a guard expression.
Parameters:
expr: string- JavaScript boolean expressioncontext: { context, outputs, policy }- Evaluation context
Returns: boolean
withRetry(fn, config)
Execute a function with retry logic.
Parameters:
fn: () => Promise<T>- Function to retryconfig: { attempts, backoff, baseMs?, jitter? }- Retry configuration
Returns: Promise<T>
MemoryLedger
Append-only decision log.
Methods:
append(type, details)- Add entrygetEntries()- Get all entriesclear()- Clear ledger (for testing)
executeResumablePlan(options)
Execute a plan with checkpoint and resume support.
Additional Options (extends executePlan):
runId?: string- Unique run identifier (generated if not provided)checkpointStore?: CheckpointStore- Storage backend (default: MemoryCheckpointStore)checkpointInterval?: number- Checkpoint after N tasks (default: 1)resumeFrom?: string- Checkpoint ID to resume from
Returns: Same as executePlan
CheckpointStore
Interface for checkpoint storage backends.
Implementations:
MemoryCheckpointStore- In-memory storage (for testing)FileCheckpointStore(basePath)- File-based storage
Methods:
put(runId, checkpoint)- Store a checkpointget(runId, checkpointId?)- Retrieve checkpoint (latest if no ID)list(runId)- List all checkpoints for a runprune(runId, keepLast)- Remove old checkpoints
ResumableExecutor
High-level class for managing resumable executions.
Constructor:
new ResumableExecutor(checkpointStore?)- Create executor with optional store
Methods:
execute(options)- Execute with checkpointinglistCheckpoints(runId)- List available checkpointsgetCheckpoint(runId, checkpointId?)- Get specific checkpointpruneCheckpoints(runId, keepLast)- Clean up old checkpoints
Guard Expressions
Guards are JavaScript boolean expressions evaluated with:
context: The Context Packet factsoutputs: Task outputs so farpolicy: Policy decisions
Examples:
// Simple fact check
'context.region === "EU"'
// Output dependency
'outputs.t1.riskTier !== "HIGH"'
// Policy check
'policy.t1.allow === true'
// Combined
'context.amount > 100 && outputs.t2.approved === true'Retry Configuration
{
attempts: 3,
backoff: 'exp', // or 'fixed'
baseMs: 1000,
jitter: true
}Backoff strategies:
- fixed: Always wait
baseMs - exp: Wait
baseMs * 2^attempt - jitter: Add random variation (50-100% of delay)
Ledger Entry Types
PLAN_SELECTED- Plan chosen for executionGUARD_EVAL- Guard evaluation resultTASK_START- Task execution startedTASK_END- Task execution completedPOLICY_PRE- Policy pre-checkPOLICY_POST- Policy post-checkVERIFICATION- Verification resultERROR- Error occurredCOMPENSATION- Compensation triggered
ACM v0.5 Compliance
- ✅ Section 6.1: Task execution ordering
- ✅ Section 6.2: Guard evaluation (deterministic)
- ✅ Section 6.3: Retry and backoff
- ✅ Section 6.4: Policy enforcement hooks
- ✅ Section 6.5: Verification hooks
- ✅ Section 5.8: Memory Ledger
License
Apache-2.0
