Continuous Delivery Intake
Continuous governed delivery starts before any agent writes code. The intake surface turns delivery signals into repo-native artifacts that can be triaged, challenged, and governed without inventing a hosted control plane.
This is the v3 entrypoint that exists today. It records signals, creates delivery intents, exposes triage and approval workflows, and generates execution-ready planning artifacts. It does not auto-start implementation or bypass human authority.
Workspace boundary
Intake is a repo-local command family. Run it inside a governed project rooted by agentxchain.json.
It is not a coordinator-root command family. If your current workspace is rooted by agentxchain-multi.json, the CLI rejects agentxchain intake ... explicitly and tells you to:
- run intake inside the child governed repo that owns the signal
- use
agentxchain multi stepfor cross-repo orchestration
If both config files exist in the same directory, governed-project detection wins and intake stays repo-local. AgentXchain now ships explicit intake handoff; it does not auto-escalate intake into coordinator state.
What ships today
The current CLI surface is nine commands:
agentxchain intake record
agentxchain intake triage
agentxchain intake approve
agentxchain intake plan
agentxchain intake start
agentxchain intake handoff
agentxchain intake resolve
agentxchain intake scan
agentxchain intake status
Artifact layout
All intake state lives under the repo-local .agentxchain/intake/ directory:
.agentxchain/intake/
events/
<event_id>.json
intents/
<intent_id>.json
observations/
<intent_id>/
loop-state.json
events/stores the raw trigger signal.intents/stores the governed delivery intent derived from that event.observations/is created when an intent resolves tocompleted. S5 only scaffolds the directory; later slices may write evidence under it.loop-state.jsonis a cache written byintake status. It is not the source of truth.
Concrete artifact paths:
.agentxchain/intake/events/<event_id>.json.agentxchain/intake/intents/<intent_id>.json.agentxchain/intake/observations/<intent_id>/.agentxchain/intake/loop-state.json
When an operator escalates a planned intent into a coordinator workspace, AgentXchain also writes a read-only handoff ref under the coordinator root:
.agentxchain/multirepo/handoffs/<intent_id>.json
intake record
Use intake record to ingest a signal from a file, stdin, or inline flags.
# inline manual signal
agentxchain intake record \
--source manual \
--signal '{"description":"release smoke failed"}' \
--evidence '{"type":"text","value":"release-postflight.sh failed on tarball smoke"}'
# file-driven CI signal
agentxchain intake record --file ./failed-run.json --json
# stdin-driven schedule signal
cat stale-release-check.json | agentxchain intake record --stdin --json
Supported sources today:
manualci_failuregit_ref_changeschedulevision_scanvision_idle_expansion
manual is valid for intake record. It is intentionally excluded from intake scan. vision_scan is used by run --continuous to record intents derived from VISION.md during vision-driven operation. vision_idle_expansion is used by run --continuous --on-idle perpetual to record intents synthesized by the PM idle-expansion turn when the vision-scan queue is exhausted.
Event schema
intake record writes an event file like this:
{
"schema_version": "1.0",
"event_id": "evt_1712173200000_a1b2",
"source": "ci_failure",
"category": "ci_failure_signal",
"created_at": "2026-04-03T20:10:00Z",
"repo": null,
"ref": null,
"signal": {
"workflow": "publish-npm-on-tag",
"run_id": "23944719936"
},
"evidence": [
{
"type": "url",
"value": "https://github.com/shivamtiwari93/agentXchain.dev/actions/runs/23944719936"
}
],
"dedup_key": "ci_failure:6e544bb0df4c4b11"
}
The command also creates a linked intent in detected state.
Deduplication is deterministic
The intake surface is idempotent by contract. Duplicate signals do not create duplicate backlog noise.
Dedup key:
${source}:${sha256(JSON.stringify(sortedSignal)).slice(0, 16)}
Implications:
- signal keys are sorted before hashing
- repeated records for the same source + signal return the existing event
- the linked intent is reused instead of creating a second one
If your intake layer cannot answer "did we already see this signal?" deterministically, it is not governed delivery. It is chaos with JSON files.
intake triage
Use intake triage to turn a detected intent into governed, reviewable work.
agentxchain intake triage \
--intent intent_1712173200000_c3d4 \
--priority p1 \
--template cli-tool \
--charter "Stabilize the published install smoke contract" \
--acceptance "tarball installs by explicit path,docs match release proof"
Current triage actions:
detected -> triageddetected -> suppressedtriaged -> rejected
Governed triage accepts the full built-in template set:
genericapi-servicecli-toollibraryweb-appfull-local-clienterprise-app
Use the product-shape templates (api-service, cli-tool, library, web-app) when the planning artifact bundle should mirror the repo you are about to change. Use full-local-cli when the intent is targeting the human-gated all-automation posture, and enterprise-app when the governed repo needs the heavier multi-role planning scaffold from the start.
Examples:
# suppress a noisy or already-handled signal
agentxchain intake triage \
--intent intent_1712173200000_c3d4 \
--suppress \
--reason "duplicate of active release fix"
# reject a triaged intent after review
agentxchain intake triage \
--intent intent_1712173200000_c3d4 \
--reject \
--reason "not worth automated follow-up"
Intent schema
{
"schema_version": "1.0",
"intent_id": "intent_1712173200000_c3d4",
"event_id": "evt_1712173200000_a1b2",
"status": "planned",
"priority": "p1",
"template": "cli-tool",
"charter": "Stabilize the published install smoke contract",
"acceptance_contract": [
"tarball installs by explicit path",
"docs match release proof"
],
"approved_by": "release-manager",
"planning_artifacts": [
".planning/command-surface.md",
".planning/platform-support.md",
".planning/distribution-checklist.md"
],
"requires_human_start": true,
"target_run": null,
"target_workstream": null,
"created_at": "2026-04-03T20:10:00Z",
"updated_at": "2026-04-03T20:18:00Z",
"history": [
{
"from": null,
"to": "detected",
"at": "2026-04-03T20:10:00Z",
"reason": "event ingested"
},
{
"from": "detected",
"to": "triaged",
"at": "2026-04-03T20:15:00Z",
"reason": "triage completed"
},
{
"from": "triaged",
"to": "approved",
"at": "2026-04-03T20:16:00Z",
"reason": "critical release regression",
"approver": "release-manager"
},
{
"from": "approved",
"to": "planned",
"at": "2026-04-03T20:18:00Z",
"reason": "generated 3 planning artifact(s) from template \"cli-tool\"",
"artifacts": [
".planning/command-surface.md",
".planning/platform-support.md",
".planning/distribution-checklist.md"
]
}
]
}
intake approve
Use intake approve to move a triaged intent through the authorization gate.
agentxchain intake approve \
--intent intent_1712173200000_c3d4 \
--approver release-manager \
--reason "critical release regression"
Approval is not triage with different wording. It is the explicit transition from classified work to authorized work.
Current approval actions:
triaged -> approvedblocked -> approved
approved still does not start a governed run. It only means the intent may proceed to planning.
intake plan
Use intake plan to materialize template-backed planning artifacts and transition an approved intent to planned.
agentxchain intake plan \
--intent intent_1712173200000_c3d4 \
--project-name AgentXchain \
--json
Current planning action:
approved -> planned
Planning behavior is template-aware:
cli-tool,api-service,library,web-app, andenterprise-appcan generate.planning/artifacts from the governed template manifestgenericis valid and may generate zero planning artifacts- if any target artifact already exists, planning fails atomically unless
--forceis supplied
planned means execution-ready. It does not mean execution has started until intake start links the intent to a governed run or intake handoff links it to a coordinator workstream.
intake start
Use intake start to bridge one planned intent into the existing governed run engine.
agentxchain intake start \
--intent intent_1712173200000_c3d4 \
[--restart-completed] \
--role dev \
--json
Current start action:
planned -> executing
Success output includes:
- the resolved
run_id - the first assigned
turn_id - the chosen role
- the dispatch directory for the new governed turn
On success the intent gains:
target_runtarget_turnstarted_at
intake start is a governed handoff, not a second execution engine. It reuses the same governed state, turn-assignment, and dispatch-bundle machinery as the rest of the CLI.
Start constraints
intake start rejects deterministically when:
- the intent is not in
planned - any recorded planning artifact is missing on disk
- another governed turn is already active
- the run is
blocked - the run is
completedand--restart-completedis not passed - the run has a
pending_phase_transitionorpending_run_completiongate
Bootstrap and resume behavior
intake start can also handle two non-rejection special cases that operators should understand:
- Idle bootstrap: If the governed state is
idlewith norun_id,intake startinitializes a new governed run before assigning the first turn. You do not need to runagentxchain initseparately. - Completed restart: If the governed state is
completedwith no active turns, pass--restart-completedto initialize a fresh governed run for the planned intent. This creates a newrun_id; it does not reopen the historical completed run in place.
If the governed state is paused, intake start always rejects — regardless of whether pending_phase_transition or pending_run_completion is set. In the governed schema, paused is an approval-held state. Resolve the blocking gate with approve-transition or approve-completion before starting new intake work.
intake handoff
Use intake handoff when the source repo owns the signal, but the resulting work belongs to a coordinated multi-repo workstream.
agentxchain intake handoff \
--intent intent_1712173200000_c3d4 \
--coordinator-root ../workspace \
--workstream delivery \
--json
Current handoff action:
planned -> executing
Success output includes:
- the handoff ref path under
.agentxchain/multirepo/handoffs/ - the coordinator
super_run_id target_workstreamon the intent
On success the intent gains:
target_workstream.coordinator_roottarget_workstream.workstream_idtarget_workstream.super_run_idstarted_at
The handoff ref is run-bound on purpose. super_run_id prevents a stale handoff file from contaminating a later coordinator run in the same workspace.
Handoff constraints
intake handoff rejects deterministically when:
- the intent is not in
planned --coordinator-rootdoes not resolve to a validagentxchain-multi.json--workstreamis not declared in the coordinator config- the source repo is not listed in that workstream's
repos - the coordinator run is not
active
Handoff artifact shape
The coordinator handoff ref is read-only context. It carries enough information for coordinator dispatch to explain why the workstream exists without granting the coordinator authority over the source repo's intake state.
Key fields:
intent_idsuper_run_idsource_reposource_event_idsource_signal_sourcesource_signal_categorycharteracceptance_contractsource_event_refevidence_refs
intake handoff does not trigger multi step automatically. The operator still runs agentxchain multi step explicitly after the handoff.
intake resolve
Use intake resolve to close the loop between a governed run outcome and the linked intake intent.
agentxchain intake resolve \
--intent intent_1712173200000_c3d4 \
--outcome completed \
--json
intake resolve supports two execution backends:
- repo-local governed execution via
target_run - coordinator-mediated execution via
target_workstream
For repo-local execution, intake resolve reads .agentxchain/state.json, verifies that the governed run_id still matches the intent's target_run, and then maps the run outcome back onto intake state truth.
--outcome completed is the explicit operator override for retained-turn deadlocks. Use it when the retained turn's artifacts and verification already satisfy the contract but the intent is still stuck in executing. The command transitions executing -> completed atomically without manual .agentxchain/ surgery.
Run-outcome mapping
| Governed run status | Intent transition | Notes |
|---|---|---|
blocked | executing -> blocked | Copies run_blocked_on, run_blocked_reason, and run_blocked_recovery onto the intent. All three fields are set from the governed state. |
completed | executing -> completed | Copies run_completed_at, run_final_turn, and creates .agentxchain/intake/observations/<intent_id>/ |
failed | error (exit 1) | Reserved/unreached status per DEC-RUN-STATUS-001. Fails closed — operator must inspect manually. |
active | no change | Returns ok: true, no_change: true; the intent stays executing |
paused | no change | Returns ok: true, no_change: true; approval-held pause is not an intake outcome |
idle | error | Indicates the governed state was reset or no longer matches the started intent |
Coordinator-backed outcome mapping
If the intent carries target_workstream, intake resolve reads coordinator state from target_workstream.coordinator_root, verifies that super_run_id still matches, and then checks the workstream's completion barrier.
| Coordinator state | Barrier state | Intent transition | Notes |
|---|---|---|---|
active | not satisfied | no change | Returns ok: true, no_change: true; coordinated work is still in flight |
blocked | not satisfied | executing -> blocked | Preserves recoverability instead of collapsing every coordinator issue into terminal states |
active or completed | satisfied | executing -> completed | Creates .agentxchain/intake/observations/<intent_id>/ just like repo-local completion |
completed | not satisfied | executing -> blocked | The coordinator completed without satisfying the workstream; intent is blocked with recovery guidance |
failed | any | error (exit 1) | Reserved/unreached status per DEC-RUN-STATUS-001. Fails closed. |
Coordinator-backed intents also record target_workstream.super_run_id. If the coordinator workspace is reinitialized and the super_run_id no longer matches, intake resolve fails fast instead of silently attaching the old intent to a new super-run.
Resolve result shape
Structured output includes:
previous_statusnew_statusrun_outcomeno_change- the updated
intent
Example success result:
{
"ok": true,
"previous_status": "executing",
"new_status": "blocked",
"run_outcome": "blocked",
"no_change": false,
"intent": {
"intent_id": "intent_1712173200000_c3d4",
"status": "blocked",
"target_run": "run_20260403_001",
"run_blocked_on": "human_approval",
"run_blocked_reason": "pending_review",
"run_blocked_recovery": "approve_phase_transition"
}
}
Operator override for retained turns
If a retained turn is already staged and you need to retire the linked intent before rerunning accept-turn, use:
agentxchain intake resolve \
--intent intent_1712173200000_c3d4 \
--outcome completed \
--json
This is intentionally narrow:
- valid only when the intent is currently
executing - records a history entry explaining the operator-forced completion
- exists to replace manual
.agentxchain/state edits, not to bypass normal governed execution
Re-approval after a block
S5 makes the recovery path explicit:
planned -> executing -> blocked -> approved -> planned -> executing
intake resolve does not restart work by itself. It records the outcome. If a repo-local governed run blocked and the operator decides to restart from intake state, the next step is agentxchain intake approve --intent <id> followed by re-planning and a new intake start or intake handoff. If a coordinator-backed workstream blocked but the operator is continuing the same workstream, fix the coordinator cause, run agentxchain multi resume, and then rerun agentxchain intake resolve after the coordinator advances.
intake scan
Use intake scan to ingest a deterministic source snapshot through the existing recordEvent() path.
agentxchain intake scan \
--source ci_failure \
--file ./ci-failures.snapshot.json \
--json
cat release-checks.snapshot.json | \
agentxchain intake scan --source schedule --stdin --json
Supported scan sources:
ci_failuregit_ref_changeschedule
manual is excluded on purpose. Manual one-off intake already has agentxchain intake record, and scan is not a generic batch wrapper for every source type.
Snapshot contract
intake scan consumes one source-specific snapshot object:
{
"source": "ci_failure",
"captured_at": "2026-04-03T23:00:00Z",
"items": [
{
"signal": {
"workflow": "publish-npm-on-tag",
"run_id": "23944719936",
"status": "failed"
},
"evidence": [
{
"type": "url",
"value": "https://github.com/shivamtiwari93/agentXchain.dev/actions/runs/23944719936"
}
],
"category": "delivery_regression"
}
]
}
Contract notes:
itemsmust be a non-empty array- each item must include a non-empty
signalobject and non-emptyevidencearray category,repo, andrefare optional passthrough fieldscaptured_atis informational metadata in S4; it is accepted but not validated or stored--sourcemust matchsnapshot.source
Scan result semantics
Each snapshot item produces one deterministic result:
created: a new event and linkeddetectedintent were writtendeduplicated: the signal already existed and the existing event/intent were returnedrejected: the item failed validation and was not recorded
Machine-readable output includes aggregate counts plus per-item results:
{
"ok": true,
"source": "ci_failure",
"scanned": 2,
"created": 1,
"deduplicated": 1,
"rejected": 0,
"results": [
{
"status": "created",
"event_id": "evt_1712273200000_a1b2",
"intent_id": "intent_1712273200100_c3d4"
},
{
"status": "deduplicated",
"event_id": "evt_1712273199000_e5f6",
"intent_id": "intent_1712273199100_a7b8"
}
]
}
Scan failure rules
intake scan rejects deterministically when:
--sourceis not one ofci_failure,git_ref_change,schedule- neither
--filenor--stdinis supplied - both
--fileand--stdinare supplied - the snapshot file cannot be read
- the snapshot JSON is invalid
snapshot.sourcedisagrees with--sourceitemsis missing or empty
Mixed snapshots are processed per item. One bad item does not roll back valid siblings.
If every item in the snapshot is rejected (zero created, zero deduplicated), the entire scan fails with ok: false and exit code 1. Partial success (at least one created or deduplicated item) returns ok: true even if some items were rejected.
State machine: shipped vs deferred
The broader v3 direction defines a larger intake lifecycle. The shipped CLI surface now covers S1 through S5.
Implemented now
detected -> triaged
detected -> suppressed
triaged -> approved
triaged -> rejected
approved -> planned
planned -> executing
planned -> executing (coordinator handoff)
executing -> blocked
executing -> completed
blocked -> approved
Deferred beyond the shipped intake surface
completed -> awaiting_release_approval
awaiting_release_approval -> released
released -> observing
observing -> reopened
reopened -> planned
That distinction still matters. The repo continues to store requires_human_start: true. Approval and planning prepare work; intake start is the explicit human-authorized bridge that turns prepared work into governed execution. intake resolve closes the loop after execution without creating release authority or post-release observation evidence. intake scan only widens ingestion. It does not widen execution authority.
intake status
Use intake status to inspect backlog state or one specific intent.
# summary
agentxchain intake status
# machine-readable summary
agentxchain intake status --json
# one intent plus linked event
agentxchain intake status --intent intent_1712173200000_c3d4 --json
Summary mode reports:
- total events
- total intents
- counts by status
- recent intents ordered by
updated_at
Detail mode returns:
- the selected intent
- linked source event
- full transition history
inject — operator priority shortcut
agentxchain inject "Fix the sidebar ordering" --priority p0
agentxchain inject "Low priority cleanup" --priority p2
agentxchain inject "Draft work" --no-approve
inject composes intake record + intake triage + intake approve into one atomic command. It exists so an operator can express "do this next" without running three separate commands.
When priority is p0, a preemption marker is written to .agentxchain/intake/injected-priority.json. The run loop checks for this marker at the top of each iteration and, if no turns are active, yields with stop_reason: "priority_preempted". A continuous owner such as schedule daemon then consumes that marker, promotes the injected intent through approved -> planned -> executing, and clears the marker once the new governed turn is assigned.
Non-p0 injections (p1–p3) enter the queue for normal priority ordering without triggering preemption.
Use --no-approve to stop at triaged state if you want human review before the injected intent enters planning.
agentxchain status shows a prominent banner when a preemption marker is pending.
Governance boundary
Intake is an entrypoint, not a loophole.
- recording an event does not create a governed run
- approving or planning an intent does not create a governed run
- scanning a snapshot does not triage, approve, plan, or start anything
intake startdoes create or attach one planned intent to the governed execution boundaryintake handoffdoes create a coordinator-managed execution link by writingtarget_workstreamand a run-bound handoff refintake resolvereads governed or coordinator outcome state and updates the intent; it does not create release evidence or reopen runsplannedis not the same thing asexecuting- the future continuous loop still has to respect explicit approval transitions
- neither
intake scan,intake start, norintake handoffauto-triages, auto-approves, or auto-starts from raw signals
If you want automatic code-writing execution from repo signals, that is a later governance decision, not a default.