Command
incubatingStatus of this Document
This report was published by the User Journal Graph Community Group . It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups .
Title: org.openuji.specs.ujg.command.v1
Status: incubating implementation extension for self-contained command, mutation, and action contracts carried in UJG Core extensions.
1. Namespace
Canonical namespace string:
org.openuji.specs.ujg.command.v1Payload location:
extensions["org.openuji.specs.ujg.command.v1"]Published JSON Schema:
https://ujg.specs.openuji.org/ed/ns/command.schema.json
2. Purpose
This extension describes the action or mutation side of implementation generation.
It exists so that a generator can understand a command directly from one self-contained payload:
what command is being invoked,
which parameters it expects,
which preconditions apply,
how results and errors behave,
whether retry or idempotency matter,
which trigger kinds are meaningful,
where outputs or result payloads should land,
which follow-up outcomes such as navigation or emitted events should occur.
This extension is the action counterpart to form, record, and collection payloads. It intentionally absorbs trigger and outcome semantics instead of requiring a separate generic exec model.
3. Scope
This extension covers:
command identity,
parameters,
preconditions,
result and error semantics,
retry posture,
idempotency hints,
trigger kinds,
output destinations,
follow-up outcomes.
The extension is self-contained. It may refer to UJG node IDs for navigation outcomes, but it does not depend on private objects from form, record, collection, or access payloads.
4. Non-goals
This extension does not standardize:
transport protocols,
API endpoints,
queue names,
cron syntax,
framework event handlers,
backend worker code,
build or deployment pipelines.
5. Primary Attachment Targets
Transition
Transition is the preferred host because commands most often correspond to explicit graph actions.
6. Secondary Attachment Targets
Statefor command surfaces that do not map one-to-one to a specific transitionOutgoingTransitionGroupfor reusable command defaults shared across many outgoing transitions
7. Discouraged Or Disallowed Attachment Targets
Templateis discouraged because command contracts are behavioral rather than structural.CompositeStateis discouraged except for sparse defaults inherited by nested transitions.Routeis discouraged because routing metadata belongs in Routing.MessageBundleis disallowed in normal use.UJGDocumentis disallowed because Core extensions are node-scoped.
8. Inheritance Model
For a transition-level command, generators should apply inheritance in this order:
Journeyeach enclosing
CompositeState, from outermost to innermostsource
Stateany applicable
OutgoingTransitionGroupthe local
Transition
For a state-level command surface that has no explicit transition host, generators should use:
Journeyenclosing
CompositeStatelocal
State
9. Precedence And Override Rules
For transition-level commands, use this precedence order:
TransitionOutgoingTransitionGroupsource
Stateinnermost
CompositeStateouter
CompositeStateJourney
For state-level command surfaces, use:
Stateinnermost
CompositeStateouter
CompositeStateJourney
Merge and replacement rules:
commandRef,result,error,retry, andidempotencyare singular values or objects. The more specific value replaces the inherited one.parameters,preconditions,triggerKinds,outputDestinations, andemitEventscombine by identity or duplicate removal.outcomesmerges by key, with the more specific value winning on collision.
10. Property Vocabulary
commandRef: identity of the command or mutation. Expected shape: string. Allowed categories: published contract IDs, operation IDs, or opaque external identifiers. Implementation intent: tells generators which action is being performed.parameters: expected command parameters. Expected shape: array of parameter objects withname,kind, and optionalrequired,source, anddefaultValueHint. Allowed categories forkind:scalar,structured,entity-ref,selection,file,secret. Allowed categories forsource:user,form,record,collection,route,context,argv,stdin,event. Implementation intent: lets generators gather parameters without transport-specific code.preconditions: command preconditions. Expected shape: array of objects withkindand optionalreforvalue. Allowed categories:selection-required,non-empty,confirmed,validated,reachable,custom. Implementation intent: gives generators a portable way to gate execution.result: result semantics. Expected shape: object with optionalmodeanddestination. Allowed categories formode:none,replace,append,emit,download,preview. Allowed categories fordestination:current-node,next-node,stdout,stderr,artifact,event. Implementation intent: tells generators what kind of successful effect to expect.error: error semantics. Expected shape: object with optionalmodeanddestination. Allowed categories formode:inline,summary,global,retry,fallback. Allowed categories fordestination: same generic destination categories asresult. Implementation intent: tells generators how to surface failure.retry: retry posture. Expected shape: string. Allowed categories:none,manual,automatic. Implementation intent: tells generators whether to surface retry affordances or automatic re-invocation.idempotency: idempotency hint. Expected shape: string. Allowed categories:unknown,idempotent,non-idempotent. Implementation intent: helps generators choose safe retry or duplicate-submission behavior.triggerKinds: supported trigger kinds. Expected shape: array of strings. Allowed categories:submit,tap,shortcut,deep-link,timer,webhook,cli-argv,stdin-line,background,job,auto. Implementation intent: tells generators which trigger channels are meaningful.outputDestinations: expected output destinations. Expected shape: array of strings. Allowed categories:current-node,next-node,stdout,stderr,artifact,event,download. Implementation intent: declares where result material should go.outcomes: follow-up outcomes. Expected shape: object with optionalsuccessNodeRef,errorNodeRef, andemitEvents. Allowed references: UJG node IDs forsuccessNodeRefanderrorNodeRef; strings for event names. Implementation intent: gives generators a portable post-command outcome model.
11. Recommended Controlled Values
Recommended parameter kind values:
scalarstructuredentity-refselectionfilesecret
Recommended triggerKinds values:
submittapshortcutdeep-linktimerwebhookcli-argvstdin-linebackgroundjobauto
Recommended retry values:
nonemanualautomatic
12. Processing Model
A generator implementing this extension should:
Resolve the effective command payload using the inheritance and precedence rules above.
Normalize parameters, preconditions, result and error posture, retry, idempotency, and trigger kinds.
Resolve any UJG node outcome references contained in
outcomes.Combine the resulting command contract with Graph transitions, with Routing when deep links are relevant, and with L10n when result or error messaging is localized through the host node.
Materialize target-specific action handlers without changing graph semantics.
When attached to a Transition, this extension describes how that transition is invoked and what
implementation-facing outcomes it produces. It does not redefine the graph edge itself.
13. Cross-Stack Interpretation Notes
Web: map to button clicks, submits, route arrivals, timer callbacks, or webhook handlers.
Native: map to taps, gestures, shortcuts, deep links, and background actions.
CMS: map to save, publish, review, or approve actions without standardizing editorial engine code.
Commerce: map to add-to-cart, recalculate, authorize payment, capture, refund, or export actions.
CLI or headless or background: map to argv commands, stdin-driven commands, cron-like invocations, service webhooks, and long-running jobs.
14. Published JSON Schema
The published schema for this extension is defined below and is published at
https://ujg.specs.openuji.org/ed/ns/command.schema.json.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ujg.specs.openuji.org/ed/ns/command.schema.json",
"title": "UJG Command Extension Payload",
"type": "object",
"additionalProperties": false,
"properties": {
"commandRef": { "type": "string" },
"parameters": {
"type": "array",
"items": { "$ref": "#/$defs/parameter" }
},
"preconditions": {
"type": "array",
"items": { "$ref": "#/$defs/precondition" }
},
"result": { "$ref": "#/$defs/resultLike" },
"error": { "$ref": "#/$defs/resultLike" },
"retry": {
"type": "string",
"enum": ["none", "manual", "automatic"]
},
"idempotency": {
"type": "string",
"enum": ["unknown", "idempotent", "non-idempotent"]
},
"triggerKinds": {
"type": "array",
"items": {
"type": "string",
"enum": ["submit", "tap", "shortcut", "deep-link", "timer", "webhook", "cli-argv", "stdin-line", "background", "job", "auto"]
}
},
"outputDestinations": {
"type": "array",
"items": {
"type": "string",
"enum": ["current-node", "next-node", "stdout", "stderr", "artifact", "event", "download"]
}
},
"outcomes": { "$ref": "#/$defs/outcomes" }
},
"$defs": {
"parameter": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"kind": {
"type": "string",
"enum": ["scalar", "structured", "entity-ref", "selection", "file", "secret"]
},
"required": { "type": "boolean" },
"source": {
"type": "string",
"enum": ["user", "form", "record", "collection", "route", "context", "argv", "stdin", "event"]
},
"defaultValueHint": {
"oneOf": [
{ "type": "string" },
{ "type": "number" },
{ "type": "integer" },
{ "type": "boolean" },
{ "type": "object" },
{ "type": "array" }
]
}
},
"required": ["name", "kind"]
},
"precondition": {
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"type": "string",
"enum": ["selection-required", "non-empty", "confirmed", "validated", "reachable", "custom"]
},
"ref": { "type": "string" },
"value": {
"oneOf": [
{ "type": "string" },
{ "type": "number" },
{ "type": "integer" },
{ "type": "boolean" }
]
}
},
"required": ["kind"]
},
"resultLike": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"type": "string",
"enum": ["none", "replace", "append", "emit", "download", "preview", "inline", "summary", "global", "retry", "fallback"]
},
"destination": {
"type": "string",
"enum": ["current-node", "next-node", "stdout", "stderr", "artifact", "event", "download"]
}
}
},
"outcomes": {
"type": "object",
"additionalProperties": false,
"properties": {
"successNodeRef": { "type": "string" },
"errorNodeRef": { "type": "string" },
"emitEvents": {
"type": "array",
"items": { "type": "string" }
}
}
}
}
} {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ujg.specs.openuji.org/ed/ns/command.schema.json",
"title": "UJG Command Extension Payload",
"type": "object",
"additionalProperties": false,
"properties": {
"commandRef": { "type": "string" },
"parameters": {
"type": "array",
"items": { "$ref": "#/$defs/parameter" }
},
"preconditions": {
"type": "array",
"items": { "$ref": "#/$defs/precondition" }
},
"result": { "$ref": "#/$defs/resultLike" },
"error": { "$ref": "#/$defs/resultLike" },
"retry": {
"type": "string",
"enum": ["none", "manual", "automatic"]
},
"idempotency": {
"type": "string",
"enum": ["unknown", "idempotent", "non-idempotent"]
},
"triggerKinds": {
"type": "array",
"items": {
"type": "string",
"enum": ["submit", "tap", "shortcut", "deep-link", "timer", "webhook", "cli-argv", "stdin-line", "background", "job", "auto"]
}
},
"outputDestinations": {
"type": "array",
"items": {
"type": "string",
"enum": ["current-node", "next-node", "stdout", "stderr", "artifact", "event", "download"]
}
},
"outcomes": { "$ref": "#/$defs/outcomes" }
},
"$defs": {
"parameter": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"kind": {
"type": "string",
"enum": ["scalar", "structured", "entity-ref", "selection", "file", "secret"]
},
"required": { "type": "boolean" },
"source": {
"type": "string",
"enum": ["user", "form", "record", "collection", "route", "context", "argv", "stdin", "event"]
},
"defaultValueHint": {
"oneOf": [
{ "type": "string" },
{ "type": "number" },
{ "type": "integer" },
{ "type": "boolean" },
{ "type": "object" },
{ "type": "array" }
]
}
},
"required": ["name", "kind"]
},
"precondition": {
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"type": "string",
"enum": ["selection-required", "non-empty", "confirmed", "validated", "reachable", "custom"]
},
"ref": { "type": "string" },
"value": {
"oneOf": [
{ "type": "string" },
{ "type": "number" },
{ "type": "integer" },
{ "type": "boolean" }
]
}
},
"required": ["kind"]
},
"resultLike": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"type": "string",
"enum": ["none", "replace", "append", "emit", "download", "preview", "inline", "summary", "global", "retry", "fallback"]
},
"destination": {
"type": "string",
"enum": ["current-node", "next-node", "stdout", "stderr", "artifact", "event", "download"]
}
}
},
"outcomes": {
"type": "object",
"additionalProperties": false,
"properties": {
"successNodeRef": { "type": "string" },
"errorNodeRef": { "type": "string" },
"emitEvents": {
"type": "array",
"items": { "type": "string" }
}
}
}
}
} 15. Minimal Example Payload
{
"@id": "urn:transition:submit-payment",
"@type": "Transition",
"extensions": {
"org.openuji.specs.ujg.command.v1": {
"commandRef": "urn:command:payment-authorize",
"parameters": [
{ "name": "paymentMethod", "kind": "structured", "required": true, "source": "form" }
],
"preconditions": [
{ "kind": "validated" },
{ "kind": "confirmed" }
],
"result": { "mode": "replace", "destination": "next-node" },
"error": { "mode": "summary", "destination": "current-node" },
"retry": "manual",
"idempotency": "non-idempotent",
"triggerKinds": ["submit", "tap", "shortcut", "cli-argv"],
"outputDestinations": ["next-node", "event"],
"outcomes": {
"successNodeRef": "urn:state:confirmation",
"errorNodeRef": "urn:state:payment",
"emitEvents": ["payment.authorized"]
}
}
}
} {
"@id": "urn:transition:submit-payment",
"@type": "Transition",
"extensions": {
"org.openuji.specs.ujg.command.v1": {
"commandRef": "urn:command:payment-authorize",
"parameters": [
{ "name": "paymentMethod", "kind": "structured", "required": true, "source": "form" }
],
"preconditions": [
{ "kind": "validated" },
{ "kind": "confirmed" }
],
"result": { "mode": "replace", "destination": "next-node" },
"error": { "mode": "summary", "destination": "current-node" },
"retry": "manual",
"idempotency": "non-idempotent",
"triggerKinds": ["submit", "tap", "shortcut", "cli-argv"],
"outputDestinations": ["next-node", "event"],
"outcomes": {
"successNodeRef": "urn:state:confirmation",
"errorNodeRef": "urn:state:payment",
"emitEvents": ["payment.authorized"]
}
}
}
} 16. Graduation Guidance
Thin parts that may later graduate into optional modules or shared references include:
a command reference,
a parameter-kind reference,
a trigger-kind reference.
The following should remain extension-only:
parameter collection posture,
result and error handling semantics,
retry and idempotency hints,
follow-up outcome wiring.