Skip to main content

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 step for 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 to completed. S5 only scaffolds the directory; later slices may write evidence under it.
  • loop-state.json is a cache written by intake 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:

  • manual
  • ci_failure
  • git_ref_change
  • schedule
  • vision_scan
  • vision_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 -> triaged
  • detected -> suppressed
  • triaged -> rejected

Governed triage accepts the full built-in template set:

  • generic
  • api-service
  • cli-tool
  • library
  • web-app
  • full-local-cli
  • enterprise-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 -> approved
  • blocked -> 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, and enterprise-app can generate .planning/ artifacts from the governed template manifest
  • generic is valid and may generate zero planning artifacts
  • if any target artifact already exists, planning fails atomically unless --force is 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_run
  • target_turn
  • started_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 completed and --restart-completed is not passed
  • the run has a pending_phase_transition or pending_run_completion gate

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 idle with no run_id, intake start initializes a new governed run before assigning the first turn. You do not need to run agentxchain init separately.
  • Completed restart: If the governed state is completed with no active turns, pass --restart-completed to initialize a fresh governed run for the planned intent. This creates a new run_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_workstream on the intent

On success the intent gains:

  • target_workstream.coordinator_root
  • target_workstream.workstream_id
  • target_workstream.super_run_id
  • started_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-root does not resolve to a valid agentxchain-multi.json
  • --workstream is 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_id
  • super_run_id
  • source_repo
  • source_event_id
  • source_signal_source
  • source_signal_category
  • charter
  • acceptance_contract
  • source_event_ref
  • evidence_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 statusIntent transitionNotes
blockedexecuting -> blockedCopies run_blocked_on, run_blocked_reason, and run_blocked_recovery onto the intent. All three fields are set from the governed state.
completedexecuting -> completedCopies run_completed_at, run_final_turn, and creates .agentxchain/intake/observations/<intent_id>/
failederror (exit 1)Reserved/unreached status per DEC-RUN-STATUS-001. Fails closed — operator must inspect manually.
activeno changeReturns ok: true, no_change: true; the intent stays executing
pausedno changeReturns ok: true, no_change: true; approval-held pause is not an intake outcome
idleerrorIndicates 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 stateBarrier stateIntent transitionNotes
activenot satisfiedno changeReturns ok: true, no_change: true; coordinated work is still in flight
blockednot satisfiedexecuting -> blockedPreserves recoverability instead of collapsing every coordinator issue into terminal states
active or completedsatisfiedexecuting -> completedCreates .agentxchain/intake/observations/<intent_id>/ just like repo-local completion
completednot satisfiedexecuting -> blockedThe coordinator completed without satisfying the workstream; intent is blocked with recovery guidance
failedanyerror (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_status
  • new_status
  • run_outcome
  • no_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_failure
  • git_ref_change
  • schedule

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:

  • items must be a non-empty array
  • each item must include a non-empty signal object and non-empty evidence array
  • category, repo, and ref are optional passthrough fields
  • captured_at is informational metadata in S4; it is accepted but not validated or stored
  • --source must match snapshot.source

Scan result semantics

Each snapshot item produces one deterministic result:

  • created: a new event and linked detected intent were written
  • deduplicated: the signal already existed and the existing event/intent were returned
  • rejected: 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:

  • --source is not one of ci_failure, git_ref_change, schedule
  • neither --file nor --stdin is supplied
  • both --file and --stdin are supplied
  • the snapshot file cannot be read
  • the snapshot JSON is invalid
  • snapshot.source disagrees with --source
  • items is 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 (p1p3) 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 start does create or attach one planned intent to the governed execution boundary
  • intake handoff does create a coordinator-managed execution link by writing target_workstream and a run-bound handoff ref
  • intake resolve reads governed or coordinator outcome state and updates the intent; it does not create release evidence or reopen runs
  • planned is not the same thing as executing
  • the future continuous loop still has to respect explicit approval transitions
  • neither intake scan, intake start, nor intake handoff auto-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.