Praxis API, CLI and web controls
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.
The engine source now exposes the composed coding workflow through a common HTTPS API, CLI client and web control page. A trusted host supplies identity verification and TLS configuration. Approval, pause, resume, cancellation requests and acceptance use the same transaction boundary regardless of interface.
This is the aiws-local-coding-controls/1 implementation profile of the checked-in engine wire schema 1.1.0. M5 remains in progress. The profile operates existing host-created local workflows; it is not the complete engine command catalog, a standalone enrollment installer, or a released SDK package.
An interactive control API decision lifecycle diagram traces inspect, approval challenge, command, receipt and exact-retry replay.
What is available
Section titled “What is available”| Interface | Implemented behavior |
|---|---|
| Capabilities | Authenticated codec/storage/approval capabilities; exact schema and profile headers |
| Queries | Inspect a pinned work-order revision; list a single complete inventory page; retrieve your durable command receipt |
| Approval challenge | Recently verified human, exact proposal/material, principal and session binding, two-minute maximum expiry |
| Commands | Approve a plan/correction, accept validated work, pause, resume and request cancellation |
| Artifacts | Authorized download of the current projection, plan and deliverable manifest/files |
| CLI | Verified loopback TLS, credential input over a protected pipe, persisted request JSON, structured responses |
| Web | Inspect plan/evidence, see current revision and status, make explicit decisions, retry the same uncertain command |
| Local host | Starts HTTPS and polls configured workflows sequentially; no execution before approval |
Acceptance is an approve command over the current acceptance proposal, not an extra unversioned wire command. APPROVAL and WORK_ORDER references share the local work-order ID in this profile, with distinct kinds and an exact workflow revision. Inspect details supplies the authoritative proposal reference and binding. The immutable local execution contract is the approved plan identified by local-plan:<planDigest>; general definition/contract registration and additional runs are not exposed here.
GET /engine/v1/capabilities returns only installed profile features. Every response includes AIWS-Schema-Version: 1.1.0 and AIWS-Control-Profile: aiws-local-coding-controls/1. Unsupported commands, enrollment, historical codecs, event streaming and pagination continuations fail explicitly. Advertising the codec means its shapes are understood; it does not mean every catalog operation is implemented.
Start a configured host
Section titled “Start a configured host”The source requires Node 24. Supply a trusted configuration module, outside request-controlled workspaces. It exports a ControlHostOptions object:
// host-config.ts — schematic wiring; your adapter must verify real identities.import { readFile } from 'node:fs/promises';import type { ControlHostOptions } from './engine/src/control-host.ts';import { identityAdapter } from './your-verified-identity-adapter.ts';
export default { database: '/protected/aiws/engine.sqlite', workspaceRoot: '/work/aiws', artifactRoot: '/protected/aiws/artifacts', namespace: 'local', tlsKeyFile: '/protected/aiws/tls-key.pem', tlsCertificateFile: '/protected/aiws/tls-cert.pem', port: 7443, identity: identityAdapter, plans: JSON.parse(await readFile('/protected/aiws/plans.json', 'utf8')),} satisfies ControlHostOptions;node engine/src/control-host.ts ./host-config.tsPaths above are placeholders. Use native protected paths and OS ACLs for your platform. The host binds 127.0.0.1 only, requires TLS key/certificate files and serves the controls at its printed HTTPS origin. It does not disable certificate verification or install a certificate authority. Configure browser trust explicitly; the CLI receives the pinned installation certificate/trust file separately. Remote gateways, IPv6 listener qualification and certificate rollover are not implemented in this slice.
The host creates only the configured immutable plans. Reopening the same work-order identity preserves its plan and accounting. The loop waits for a recorded approval and executes one local step at a time; paused, held or unapproved work cannot bypass admission. After restart, log in again and use the human resume decision before continuing eligible work. This sequential runner is an implementation slice, not a product concurrency ceiling.
The identity adapter is a trust boundary
Section titled “The identity adapter is a trust boundary”ControlIdentityAdapter lives in engine/src/control-service.ts. The host installs it directly; public callers cannot choose the provider or submit trusted identity facts.
| Method or field | Host obligation |
|---|---|
authenticate(credential, context) |
Verify the protected Authorization header or browser cookie against the configured issuer, audience, signature, revocation and session policy; return a verified human session or null |
authorize(session, action, workOrderId, context) |
Evaluate the exact operation and target under current host policy; inventory access needs namespace-wide list permission and inspect permission for every returned work order |
authMethod |
Identify the installed local user-verification or OIDC/PKCE method |
Optional handleLogin(request, response, context) |
Implement /auth/start and /auth/callback GET routes, including interactive verification, PKCE/state/nonce checks and protected session-cookie issuance |
The engine validates session expiry, verified-human evidence, installation boot epoch and durable auth epoch. Elevated approval/resume decisions require verification within five minutes. Authorization leases last at most five seconds and are checked again inside the SQLite transaction. A host can revoke all current control authority through the internal controlRevoke operation; the new auth epoch invalidates earlier sessions/challenges. Provider-specific logout, per-session revocation and refresh policy remain the adapter’s responsibility.
The adapter must independently establish human identity. A bearer token, a test fixture string, or an object containing kind: "HUMAN" is not sufficient proof. Session and CSRF secrets never enter command JSON, workflow state or command receipts. Browser cookies must be Secure, HttpOnly, host-only and SameSite=Strict. Cookie-authenticated POSTs require exact Origin and session-bound X-AIWS-CSRF; Authorization and cookie credentials cannot be combined.
Owner enrollment, invitation flows, recovery enrollment and production provider implementations remain open. startControlHost is for integration with an already provisioned trusted host. It does not claim to implement the entire M4 authentication design. Tests use explicit simulated identity providers and real HTTPS/SQLite/subprocesses.
Inspect before deciding
Section titled “Inspect before deciding”All POST bodies use the selected envelope, including installation ID from capabilities, namespace and a fresh request ID. Quantities and revisions use canonical decimal strings. The server rejects unknown fields, duplicate JSON keys, malformed UTF-8, unpaired surrogates, unsafe numbers, excessive depth and unsupported versions.
An inventory query discovers current references without guessing their revisions:
{ "protocol": "aiws-engine/1", "schemaVersion": "1.1.0", "kind": "query", "installationId": "INSTALLATION_ID_FROM_CAPABILITIES", "namespace": "local", "requestId": "inventory-request-1", "query": { "name": "list", "payload": { "kind": "WORK_ORDER", "parent": null, "pageCursor": null, "pageSize": 1000 } }}This initial inventory implementation returns a complete page or rejects the request if it cannot fit. It never silently truncates. More than 1,000 stored work orders can exist; multi-page inventory queries remain unimplemented. inspect takes the exact returned WORK_ORDER reference. A stale revision receives STALE_REVISION; refresh inventory and review changed material.
A record’s details blob contains the complete local workflow projection, current controls, attempts, scope exposure, handoffs and holds. Its approvalSubject and binding define the decision material. Download it using:
GET /engine/v1/artifacts/<encoded-work-order-id>/<details-digest>The download rechecks work-order authorization and permits only currently referenced artifacts. Old projection/archive retrieval is not advertised; refresh the inventory if the current projection changed. A digest does not grant read access. Work orders project as OPEN, SUSPENDED or CLOSED, and close as COMPLETED only after acceptance. Cancellation remains CANCEL_PENDING until the remaining responsibility is resolved; it never asserts that a running process stopped.
Make a human decision
Section titled “Make a human decision”For initial/correction approval or acceptance:
- Inspect the current work order, its plan, validation and deliverable manifest.
- POST
ApprovalChallengeRequestto/engine/v1/approval-challenges, copying the currentAPPROVALsubject and binding withaction: "approve". - Persist an exact
CommandRequestwithcommand.name: "approve", the proposal, binding and returned challenge ID.expectedRevisionscontains the correspondingWORK_ORDERreference. - POST that file to
/engine/v1/commands. The server consumes the challenge, applies the decision, records audit state and stores the command receipt in one transaction.
The challenge expires within two minutes and cannot move to another session, principal, revision or material. Execution approval lasts at most five minutes and no longer than the verified session returned by the adapter. A later expiry blocks new admissions; renewal/remediation is not implemented by silently creating a new identity.
For pause, send the pinned target; for resume, send the target and its current binding; for cancel, send the target and a reason code. These commands use the same expected-revision and durable-receipt rules. Resume requires recent human verification and refuses unresolved uncertain actions or terminal/canceling work. Pause prevents new admissions; existing execution evidence remains available for settlement. Cancellation is a request, not forceful process termination.
CLI usage and uncertain responses
Section titled “CLI usage and uncertain responses”# The trusted login helper writes {"authorization":"Bearer ..."} to its pipe.# Never put a real credential into this command line or a request file.verified-login-helper | node engine/src/control-cli.ts \ https://127.0.0.1:7443 /protected/aiws/tls-cert.pem queries ./inspect.json
verified-login-helper | node engine/src/control-cli.ts \ https://127.0.0.1:7443 /protected/aiws/tls-cert.pem commands ./decision.jsonverified-login-helper is an integration placeholder for your configured authenticator, not a bundled utility. The CLI validates TLS, sends the credential in the Authorization header, prints the structured response and returns a nonzero exit status for engine errors. It requires a persisted request file for mutations and does not invent another request ID after a timeout.
A receipt means the database accepted the decision, not that execution finished. If the response is lost or commitStatus is UNKNOWN, query commandResult with the original request ID and the same verified issuer/subject. You may retry the identical request file. The engine checks the durable key/digest before stale revisions or consumed challenges; an exact retry returns REPLAYED, while changed material under that ID returns REQUEST_ID_CONFLICT. Canonical request bytes use RFC 8785 key ordering without changing historical SDK/domain digests.
The web page uses these same commands and a separate explicit confirmation before each decision. It retains an uncertain request in memory for exact retry and warns before leaving the page. It does not persist sessions in browser storage. For recoverability across closing/reloading the page, use the CLI with a persisted request file; durable browser request recovery is still open. No command receipt or lookup from another principal is disclosed.
Verification and remaining scope
Section titled “Verification and remaining scope”All 105 engine tests pass, including 18 control API/codec/host checks. The control tests exercise the selected wire schema, real loopback TLS, command transactions, CLI subprocess, host execution, CSRF/origin/Host checks, authorization expiry/revocation, session-bound challenges, artifact changes, command replay and database reopen. The runtime codec checks all 429 current/historical shape fixtures; the runtime advertises only 1.1.0.
The control page’s static assets and HTTP boundaries are tested. Visual browser verification is unclaimed because the available browser could not reach the local checkout. Full enrollment/provider integration, streamed artifact IO, event/paged history, dynamic policies, cancellation finalization, held-work remediation, retention, capacity and platform qualification remain future work. Continue with the composed workflow and persistence evidence.