Create or update primitive and composite actions using bundled action-contract rules. Use when Codex needs to add an action, refactor logic into package-local actions, repair `action.json`, define bindings, conditions, or JSON Schema contracts, or make an action valid under the local runtime and validator.
This skill provides guidance for authoring a single action or a small set of tightly related actions.
Actions are deterministic execution units declared by manifest, not inferred from scripts or prose.
Two action kinds exist:
In this repo, action authoring spans three surfaces:
actions/<action-dir>/action.json: executable contractskill.json: only when entry_action changesDecide the smallest stable unit of work before editing files. Split when ordering or reuse matters. Keep one action when the behavior is truly atomic.
Define input_schema and output_schema first.
Every reachable binding must resolve against a real schema path. Do not rely on implied fields.
returns As RequiredThe current RFC and runtime schema require composite actions to declare returns.
Do not copy older guidance that treats last-step output as a valid fallback.
Composite steps[].action values must reference package-local action_id values only.
Runtime-global URIs and filesystem-like references are validation failures for nested calls.
Primitive executor binding is runtime behavior.
Do not try to encode handler-module paths or runtime wiring in action.json.
If the task is really about creating or repairing a whole skill package, switch to or also use action-skill-creator.
If the task is a new package action set, let action-skill-creator scaffold the package first instead of inventing manifests from scratch.
Reduce the request to a concrete contract:
If the action boundary is ambiguous, resolve that before touching schemas.
Read the neighboring files before editing:
skill.jsonaction.jsonKeep action_id stable unless the user explicitly wants a rename.
Use primitive when one handler can perform the work directly.
Use composite when the workflow is deterministic, ordered, and should stay declarative.
For primitive actions:
idempotent conservativelyFor composite actions:
steps$input.foo and $steps.step_id.output.barif expressions deterministic and side-effect freereturns explicitly and make it match output_schemaUpdate all affected files in one pass:
actions/<action-dir>/action.jsonskill.json when the package entry_action changesCheck every edge before finishing:
$steps.<step_id>.output.* path is backed by the producer output_schemareturns field resolves to a JSON object compatible with output_schemaaction reference resolves within the same packagePrefer the repo CLI for package checks:
skill-action-runtime validate-skill-package --skill-package <path-to-skill> --output json
If the action is executable, also use resolve-action, validate-action-input, or execute-action as needed.
When primitive execution is involved, provide a handler module only if the runtime actually needs one.
If the action is tricky, test the real call path instead of only reading JSON:
[A-Za-z_][A-Za-z0-9_]*.==, !=, >, <, >=, <=, &&, ||, !.action-skill-creator.action-runner.