@incito-labs/project-run-engine
v0.5.0
Published
Provider-agnostic agent orchestration engine for portable workflow execution
Downloads
941
Readme
project-run-engine
A provider-agnostic, runtime-neutral agent orchestration engine for portable workflow execution.
project-run-engine automates multi-agent software engineering lifecycles (Specification, Architecture, Implementation, Independent Review, Remediation, and Convergence) without coupling to any specific LLM provider, SDK, or host runtime.
Status: Phases 0–4, Phase 4 Closure, the ENG-001/002/003 remediation and Phase 5 (persistence hardening: durable decision history, atomic checkpoints, per-execution locking) are complete (current release 0.5.0). 0.5.0 fixes executions suspended after a BLOCKED result that could not be resumed (the responsible agent is now re-dispatched) and validates humanAnswers (new failure code INVALID_HUMAN_ANSWERS) — see CONSUMER-GUIDE.md §12. 0.4.0 reports failed checkpoint writes instead of swallowing them (CHECKPOINT_WRITE_FAILED), gives the storage contract revisioned compare-and-swap writes (CHECKPOINT_CONFLICT), and fixes a crash-recovery bug at the final READY_FOR_PR transition — see CONSUMER-GUIDE.md §11. See docs/phase-reports.md for phase history and docs/backlog.md for deferred work and known limitations. Upgrading from 0.2.x? ProjectRunHostResponse.history changes type in 0.3 — see CONSUMER-GUIDE.md §10.
Key Principles
- Zero Provider SDKs: Contains no dependencies on OpenRouter, OpenAI, Anthropic, Vercel AI SDK, or model-specific APIs.
- Runtime Neutral & Extensible: Executes across standard host runtimes (
ANTIGRAVITY,CLAUDE,CURSOR,MOCK) as well as consumer-provided custom runtimes (e.g.CI_AGENT, cluster workers) through theHostDispatchAdapter/AgentRuntimeAdapterboundary. - Pure Deterministic State Machine: The
CoordinatorDecisionEnginegoverns state transitions, iterations, and control flow without side effects. - Skill Contracts, Not Downloads: Enforces declarative skill requirements per agent role (such as Spec-Kit workflows). The engine verifies skill presence locally before dispatch; it never downloads external code automatically.
- Single User Entry Point: Coordinates the entire workflow through
/project-run. Review, remediation, re-review, and convergence are fully automated. - Execution Continuity & Checkpointing: Persists execution state at key milestones and supports resuming runs blocked on human intervention without restarting completed agents.
- Structured Finding Contracts: Formal typed model for findings, evidence, and actionable severity routing.
Installation
npm install @incito-labs/project-run-engine(Or from a local workspace path during development: "@incito-labs/project-run-engine": "file:../path/to/packages/project-run-engine")
CLI Usage
project-run-engine provides a built-in CLI for deterministic project scaffolding, diagnostics, execution, and execution resumption:
# 1. Bootstrap project configuration and canonical Spec-Kit skills
npx project-run init
# 2. Verify workspace configuration and skill availability
npx project-run doctor
# 3. Execute the workflow (auto-discovers git branch and feature)
npx project-run
# 4. Resume an execution after human intervention
npx project-run resume --execution-id <execution_id>CLI Command Options
project-run init [--project <name>] [--force]- Scaffolds
.project-run/config.jsonand canonical offline Spec-Kit skills into.agents/skills/. - Idempotent: does not overwrite existing files unless
--forceis specified.
- Scaffolds
project-run doctor [--project-root <path>]- Validates configuration, required agent roles, skill search paths, and skill presence on disk.
project-run [run] [--feature <name>] [--branch <branch>] [--runtime <runtime>]- Runs the orchestration workflow.
- Automatically discovers git branch from
.git/HEAD(or git worktree pointers). - Automatically discovers feature from active branch name (
feat/<feature>,feature/<feature>),.project-run/config.json, or specs directories.
project-run resume --execution-id <execution_id>- Resumes an execution that paused in
HUMAN_INTERVENTION_REQUIRED. - Restores the exact checkpointed state and continues without re-executing completed agents.
- Resumes an execution that paused in
Context Auto-Discovery (G-1)
When running without explicit flags, project-run-engine deterministically discovers the workspace context without guessing or inventing synthetic values:
- Git Branch Discovery:
- Inspects
.git/HEADdirectly on disk (supporting standard git repositories as well as worktrees and submodules withgitdir:pointers). - If not in a git repository or HEAD is detached without a branch, fails explicitly with
ProjectNotGitRepositoryError.
- Inspects
- Feature Discovery:
- Priority 1: Git branch naming convention (e.g.
feat/004-user-auth->004-user-auth). - Priority 2: Configured
feature_directoryin.project-run/config.json. - Priority 3: Single feature directory found in
.specs/orspecs/. - If the feature cannot be determined unambiguously, fails explicitly with
FeatureNotDiscoveredError.
- Priority 1: Git branch naming convention (e.g.
Zero LLM calls or synthetic fabrications are made.
Execution State Persistence (G-2)
The engine is written against an ExecutionStateStore abstraction; the default is FileExecutionStateStore
(single machine, local filesystem). Any store that satisfies the contract can hold executions:
export interface ExecutionStateStore {
save(state: PersistedExecutionState, options?: { expectedRevision?: number }): Promise<void | { revision: number }>;
load(executionId: string): Promise<PersistedExecutionState | null>;
exists(executionId: string): Promise<boolean>;
list?(): Promise<PersistedExecutionState[]>;
withLock?<T>(executionId: string, fn: () => Promise<T>, options?: ExecutionLockOptions): Promise<T>;
}save resolves only once the checkpoint is durable. expectedRevision (compare-and-swap) and revision are
the optimistic-concurrency part of the contract (added in 0.4.0 — ARCHITECTURE.md §4.17.2).
Persisted runs are saved to .project-run/runs/<execution_id>.json.
Persisted State Schema
version: state schema version (currently1).execution_id,project,feature,branch,preset,runtime: identity of the run.state: the activeCoordinatorState;lifecycle_status:IN_PROGRESS,AWAITING_AGENT_ACTION,HUMAN_INTERVENTION_REQUIRED,COMPLETEDorFAILED;suspended_from,terminal_reason.iteration,remediation_iteration: loop counters.last_result(the lastAgentResult),findings(the latest result's),context.history(DecisionRecord[], what the engine decided) andstep_log(what happened: agent steps and human suspensions).human_intervention(the latest suspension),human_answers(append-only),pending_action(the outstanding pull-mode step).revision: store-assigned write counter (since0.4.0);created_at/updated_atISO-8601 strings.
Secret Scrubbing & Privacy
All persisted contexts pass through automated secret scrubbing. Sensitive environment variables, auth tokens, passwords, and API keys are replaced with [REDACTED] prior to disk writes.
Checkpoint Milestones
The Coordinator persists state automatically at 6 deterministic lifecycle milestones:
- Execution Start: Immediately upon run initialization.
- After Agent Result: After every host agent dispatch completes.
- State Transition: After every state machine transition evaluated by the
CoordinatorDecisionEngine. - Human Intervention: Before pausing execution in
HUMAN_INTERVENTION_REQUIRED. - Terminal Success: When execution successfully reaches
READY_FOR_PR. - Terminal Failure: When execution terminates due to fatal errors or maximum remediation limits.
Structured Finding Contract (G-4)
The engine formalizes findings into a strong, deterministic contract:
export type FindingSeverity = "CRITICAL" | "HIGH" | "MEDIUM" | "LOW" | "ADVISORY";
export type FindingStatus = "OPEN" | "RESOLVED" | "ACCEPTED";
export interface FindingLocation {
file?: string;
line?: number;
column?: number;
}
export interface StructuredFinding {
id: string;
severity: FindingSeverity;
category: string;
location?: FindingLocation;
evidence: string;
expected: string;
actual: string;
required_remediation: string;
status: FindingStatus;
advisory?: boolean;
blocking?: boolean;
}Actionability & Decision Engine Routing
The CoordinatorDecisionEngine evaluates findings through a deterministic 3-tier model (severity → actionability → blocking status):
- Actionability: Open findings with
status: "OPEN"(excludingADVISORYoradvisory: true) are actionable—they are preserved in context, evidence, and run summaries for full observability. Findings withstatus: "RESOLVED"or"ACCEPTED"are non-actionable. - Blocking Status: Only blocking findings trigger the
REMEDIATIONstate:CRITICAL,HIGH, andMEDIUMseverities default to blocking (blocking: true).LOWseverity findings default to non-blocking (blocking: false). They do not triggerREMEDIATIONor halt the workflow unless explicitly markedblocking: true.- Explicit
blockingflags (true/false) take precedence over severity defaults.
- Iteration counters and maximum remediation limits are strictly enforced for blocking finding remediation cycles.
Human Intervention Resume Protocol (G-5)
When an execution pauses in HUMAN_INTERVENTION_REQUIRED (e.g. maximum remediation limit reached, blocked dependency, or manual approval gate), the operator addresses the issue and resumes execution:
npx project-run resume --execution-id <execution_id>Resume Semantics
- Loads persisted state from
.project-run/runs/<execution_id>.json. - Verifies execution existence (
ExecutionNotFoundErrorif absent). - Verifies resumability (
ExecutionNotResumableErrorif already terminal such asREADY_FOR_PR). - Reconstructs
Coordinatorexecution context, iterations, findings, and completed step history. - Continues execution from the preserved state without re-dispatching already completed agents.
- Subsequent milestones continue to checkpoint state normally.
Provider & Host Agnosticism
project-run-engine strictly defines the boundaries between orchestration and host execution:
| Responsibility | Handled By project-run-engine | Handled By Consumer / Host |
|---|---|---|
| Workflow state machine & transitions | Yes | No |
| Skill requirement declarations & validation | Yes | No |
| Checkpoint persistence & resumption | Yes | No |
| Workspace context discovery | Yes | No |
| Finding structure & actionability rules | Yes | No |
| Physical LLM API calls | No (Forbidden) | Yes |
| Host tool execution (file editing, shells) | No (Forbidden) | Yes |
| Provider-specific prompts or agent subagents | No (Forbidden) | Yes |
| Concrete host bridges (Antigravity, Claude, Cursor) | No (Interface only) | Yes |
Consumers implement the HostAgentDispatcher interface for their chosen runtime and pass it to the engine.
Programmatic API Example
import {
executeProjectRun,
executeProjectResume,
HostDispatchAdapter,
FileExecutionStateStore,
type HostAgentDispatcher,
type AgentDispatchRequest,
type AgentResult,
} from "@incito-labs/project-run-engine";
// 1. Consumer provides runtime dispatcher
const customDispatcher: HostAgentDispatcher = {
async dispatch(request: AgentDispatchRequest): Promise<AgentResult> {
return {
execution_id: request.execution_id,
agent: request.role,
state: request.state,
status: "PASS",
evidence: ["Completed verification checks"],
findings: [],
};
},
};
const adapter = new HostDispatchAdapter("CI_AGENT", customDispatcher);
// 2. Start a new workflow run
const runResult = await executeProjectRun({
projectRoot: process.cwd(),
runtime: "CI_AGENT",
adapters: [adapter],
});
// 3. Or resume an interrupted run
const resumeResult = await executeProjectResume({
projectRoot: process.cwd(),
executionId: "exec-12345",
adapters: [adapter],
});Public API Export Map
| Module | Exports |
|---|---|
| @incito-labs/project-run-engine | Main barrel export exposing all public API components |
| @incito-labs/project-run-engine/domain | CoordinatorState, AgentRole, AgentRuntime, StructuredFinding, AgentResult, AgentSkillRequirement, ExecutionStepRecord, countAgentSteps, domain error classes (including ExecutionLockError, ExecutionLockTimeoutError, ExecutionLockUnavailableError, isExecutionLockFailure; since 0.4.0: CheckpointWriteError, CheckpointConflictError, ExecutionFailureCode, PersistenceFailureCode) |
| @incito-labs/project-run-engine/coordinator | Coordinator, CoordinatorOptions, CoordinatorRunResult, StepRecord (the live, per-call record — not the durable history) |
| (no /decision subpath) | The decision layer — CoordinatorDecisionEngine, CoordinatorDecision, CoordinatorExecutionContext, isFindingActionable, and the durable-history types DecisionRecord, RecordedDecision, DispatchDecisionSummary — is exported from the root barrel only |
| @incito-labs/project-run-engine/runtime | HostDispatchAdapter, HostAgentDispatcher, MockRuntimeAdapter, executeWithHostGuards |
| @incito-labs/project-run-engine/skills | SkillResolver, SkillValidator, SkillValidationError |
| @incito-labs/project-run-engine/presets | Spec-Kit preset definitions (ROLE_SKILLS_MAP, getSkillsForRole, etc.) |
| @incito-labs/project-run-engine/project | executeProjectRun, executeProjectResume, discoverProjectContext, FileExecutionStateStore (including withLock and its lock-default options), ExecutionStateStore (optional withLock; since 0.4.0: revisioned save), ExecutionLockOptions, withExecutionLock, PersistedExecutionState, since 0.4.0: ExecutionSaveOptions, ExecutionSaveReceipt, runProjectDoctor, loadProjectConfig |
| @incito-labs/project-run-engine/host | startProjectRun, resumeProjectRun, statusProjectRun, nextProjectRunStep, submitProjectRunStep, projectEngineRun, and the ProjectRunHostResponse / ProjectRunStepResponse types |
License
Apache-2.0
