Skip to content

Governed dynamic workflows

Praxis naming: This page documents Praxis, the AIWS workflow engine. Existing engine/* source paths, /engine/... routes, aiws-engine/* protocol identifiers, and existing script names remain unchanged for compatibility.

M7 adds governed changes to running workflows in stages. Slices 1–7 provide change preflight, a supervised registry, coding binding, preparation-task insertion and plan/dependency revisions before dispatch, plus reviewed agent replacement at settled stage boundaries and explicit effect reconciliation with stale-result rejection. See the registry guide for persistence, approval and atomic definition activation. Use the current GitHub source for these experimental engine APIs; they are not part of the published SDK 0.3.0 packages or the baseline source download.

Slice Deliverable Status
1 Revision/proposal contracts and executable validation Implemented
2 Durable proposal/revision records, approval and atomic activation Implemented for UNBOUND registry
3 Task, attempt, handoff and result revision binding Implemented for opt-in coding runs
4 Governed task insertion Implemented for a serial prefix before dispatch
5 Plan revisions and branch changes Implemented before dispatch; all tasks retained
6 Agent replacement and explicit handoff Implemented at unstarted/settled boundaries; uncertain work held
7 Stale-result handling, assessment invalidation and prior-effect reconciliation Implemented: rejection and reviewed same-stage retry; no refunds
8 SDK/client controls, examples, parity and recovery tests Planned
9 Pinned Archon integration assessment and M7 acceptance review Planned

M6 native platform and capacity/soak qualification remain separate open work. Starting M7 does not close those gates.

See agent replacement and handoff for transfer authority, adapter installation, acknowledgment and uncertain-work holds.

See held-work reconciliation for effect proofs, stale assessments and retry without replenishing accounting.

From the repository root, on Node.js 24:

Terminal window
npm run example:engine:dynamic
npm run test:engine:m7-contract

The executable example is engine/examples/dynamic-workflow.ts. It proposes inserting a lint task between implementation and verification. Its result identifies lint and verification as affected, with activation: NOT_AUTHORIZED. It does not enqueue or execute tasks.

The experimental host API lives in engine/src/dynamic-workflow.ts:

import {
workflowDefinitionDigest,
preflightWorkflowChange,
} from './engine/src/dynamic-workflow.ts';
// base is a validated aiws-dynamic/1 definition loaded by your host.
const baseDigest = workflowDefinitionDigest(base);
const candidate = structuredClone(base);
candidate.revision = base.revision + 1;
candidate.parentDigest = baseDigest;
candidate.tasks.push({
taskId: 'lint',
materialDigest: lintMaterialDigest,
agentId: 'tester',
dependsOn: ['implement'],
});
candidate.tasks.find(task => task.taskId === 'verify')!.dependsOn = ['lint'];
const review = preflightWorkflowChange(base, {
format: 'aiws-change/1',
proposalId: 'insert-lint',
baseDigest,
proposedBy: { kind: 'AGENT', principalId: 'planner' },
reason: 'Check style before validation',
candidate,
});

This integration fragment assumes base and lintMaterialDigest are host-supplied. The executable example supplies a complete definition and explicitly labeled demonstration digests. Slice 8 adds native TypeScript/Rust/Python clients and remote CLI/web controls over the optional dynamic HTTPS profile.

A definition contains a stable work-order/run identity, revision and parent digest, immutable authority/limits/acceptance digests, and tasks with material digests, agent identities and dependency lists. Task material must eventually resolve to the exact intended command, inputs, outputs and credentials. The host must verify that material and enforce current authority before execution.

Preflight rejects missing/unknown fields, invalid identities or digests, duplicate tasks/edges, missing dependencies, cycles, stale base/parent references, revision gaps, no-op edits and changes to protected policy digests. It rejects protected-policy changes even when the proposer labels itself human. A proposer label is not authentication.

Definition and proposal digests are deterministic and domain-separated. Task/dependency order does not change identity. The proposal digest binds its candidate, proposer, reason and proposal ID. Returned objects are detached from the input.

The affected set includes directly changed tasks and their downstream dependents in both the old and new graphs. Removing an edge therefore cannot hide its previous downstream impact. An independent branch is reported as structurally unaffected, but that does not establish safe reuse: shared files, external effects and other hidden dependencies still require host assessment.

All results carry resultCompatibility: REJECT_UNLESS_EXPLICITLY_APPROVED. This is a contract obligation for future consumption, not an implemented result-admission gate. Preflight does not invalidate assessments, cancel work, reconcile effects or reset resource consumption.

Successful preflight means the proposal can be reviewed. The Slice 2 registry checks the current persisted head again, verifies exact approval material, fences stale ownership epochs, and records a durable decision atomically. It leaves ledgers/holds untouched and rejects existing executable work. Slice 3 adds explicit revision binding for initial coding runs, with fresh human stage approval and immutable evidence pins. Existing coding workflows retain their immutable plans. Slice 4 adds approved serial preparation-task insertion before dispatch; Slice 5 adds plan and dependency revisions with retained nodes and sequential execution of preparation forks/joins. There is no implicit conversion into an arbitrary executing graph.

The full contract and future invariants are in spec/engine-v1/DYNAMIC-WORKFLOWS.md. Validation evidence and remaining scope are in docs/M7-DYNAMIC-CONTRACT.md.