Skip to content

Records, commands and strict input

The shared schema is JSON Schema Draft 2020-12 in spec/schema.json. Its closed records are the cross-language wire contract. The generated wire reference lists every record, command and field. The API reference maps the native entry points.

Parse untrusted JSON and canonicalize action material · Executable example

import assert from 'node:assert/strict';
import {parseStrict, fingerprint} from '@aiws/sdk';
assert.throws(() => parseStrict('{"id":"a","id":"b"}'), (e: any) => e.code === 'DUPLICATE_KEY');
const action = {capability:'write',resource:'doc',payload:{value:1},preconditions:{revision:1}};
console.log(fingerprint(action));

This example intentionally rejects duplicate JSON keys and verifies canonical action fingerprinting. Parsing with an ordinary JSON decoder first can discard duplicate-key evidence. Hand the original text to parseContract/Contract::parse/parse_contract or parseCommand/Command::parse/parse_command. Validate already-trusted native values with checked record constructors before using them.

The strict parser bounds input to 1 MiB, nesting to 64, and JSON integer literals to the interoperable safe-integer range. Decimal accounting values and timestamps are strings, not floating-point numbers. Canonical unsigned decimal strings have no plus sign, leading zeroes or decimal point; the general quantity schema permits up to 100 digits. Specific telemetry APIs have tighter numeric limits.

Family Commands What the family does not do
Mission/run startRun, continueRun, activatePlan, missionState, transition Start a process or change an attached graph
Authority grant, revokeGrant, approve, withdrawApproval Authenticate a person or silently elevate an agent
Effects admit, dispatch, settle, retry Prove an external effect without adapter evidence
Waits wait, resume, join Send notifications or run a background timer
Outcomes verify, accept, invalidate Execute the tests named in an evidence record
Triggers registerTrigger, fireTrigger, tickTrigger Operate an ingress server or cron daemon
Graph registerGraph, attachGraph, completeNode Automatically schedule ready nodes

Every command optionally carries observation context; the coordinator replaces it with trusted authorizer attribution. The wire schema alone does not prove permission. The reducer also enforces state-dependent invariants not expressible by the structural schema.

Node inputSchema and outputSchema validate data supplied to the relevant checkpoint. The supported subset deliberately excludes remote reference fetching and unsupported constructs. A schema that is invalid or outside the supported subset is an error, not a best-effort validation request. Review data_validator/validate_data in the selected SDK and pin fixtures for the schemas your application relies on.

Validate task input before dispatch · Executable control simulation

import assert from 'node:assert/strict';
import { createMission, parseContract, parseCommand, reduce } from '@aiws/sdk';
// Trusted simulation: this example makes no external calls.
const contract = parseContract(JSON.stringify({
"id": "c",
"missionId": "m",
"aiwsEdition": "0.4",
"profile": "finite-v1",
"budget": "100",
"deadline": "10000",
"criteria": [
"review"
],
"actions": [
"write"
],
"resources": [
"doc"
],
"requiresApproval": false,
"maxAttempts": "2",
"maxAuthorizationAgeMs": "10",
"features": [
"triggers",
"graphs"
]
}));
let state = createMission(contract);
// Step 1
state = reduce(state, parseCommand(JSON.stringify({
"type": "startRun",
"runId": "r"
})), '10');
// Step 2
state = reduce(state, parseCommand(JSON.stringify({
"type": "registerGraph",
"graph": {
"id": "graph",
"revision": "1",
"nodes": [
{
"id": "task",
"kind": "TASK",
"dependsOn": [],
"config": {
"executionKind": "FUNCTION"
},
"inputSchema": {
"type": "object",
"required": [
"requiredField"
]
}
},
{
"id": "end",
"kind": "END",
"dependsOn": [
"task"
],
"config": {}
}
]
}
})), '10');
// Step 3
state = reduce(state, parseCommand(JSON.stringify({
"type": "attachGraph",
"runId": "r",
"graphId": "graph"
})), '10');
// Step 4
state = reduce(state, parseCommand(JSON.stringify({
"type": "grant",
"grant": {
"id": "g",
"subject": "agent",
"profile": "finite-v1",
"actions": [
"write"
],
"resources": [
"doc"
],
"notBefore": "0",
"expiresAt": "10000",
"limit": "100",
"canDelegate": true,
"depth": "2"
}
})), '10');
// Step 5
state = reduce(state, parseCommand(JSON.stringify({
"type": "admit",
"runId": "r",
"operationId": "o",
"attemptId": "a",
"grantId": "g",
"subject": "agent",
"action": {
"capability": "write",
"resource": "doc",
"payload": {
"value": 1
},
"preconditions": {
"revision": 1
}
},
"amount": "10",
"authorizationCheckedAt": "10",
"policy": "ALLOW",
"mandatoryChecksOk": true
})), '10');
// Step 6
assert.throws(() => reduce(state, parseCommand(JSON.stringify({
"type": "dispatch",
"attemptId": "a",
"authorizationCheckedAt": "10",
"policy": "ALLOW",
"mandatoryChecksOk": true,
"nodeId": "task"
})), '10'), (error: any) => error.code === 'DATA_SCHEMA');
console.log('PASS: node-schema');

The example checks that a bad node input is rejected before the effect is dispatched. Schema validation establishes shape, not safety of executing a shell command contained in a string, authenticity of a URI or integrity of the bytes stored at that URI.

Unknown commands, fields, features and editions are rejected. Do not monkey-patch the schema to make an engine proposal appear available. Keep application handoff manifests outside closed SDK commands; store their references in permitted result material. A schema/profile change requires compatible implementations and shared fixtures in all three languages.