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.

What ships today

The current CLI surface is eight commands:

agentxchain intake record
agentxchain intake triage
agentxchain intake approve
agentxchain intake plan
agentxchain intake start
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

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

manual is valid for intake record. It is intentionally excluded from intake scan.

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

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,
"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, and web-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.

intake start

Use intake start to bridge one planned intent into the existing governed run engine.

agentxchain intake start \
--intent intent_1712173200000_c3d4 \
--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
  • the run is paused on pending_phase_transition or pending_run_completion

Do not blur that last rule. Under the current governed-state contract, paused is an approval-held state, not a generic resumable idle state for intake.

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 \
--json

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.

Run-outcome mapping

Governed run statusIntent transitionNotes
blockedexecuting -> blockedCopies run_blocked_on, run_blocked_reason, and run_blocked_recovery onto the intent
completedexecuting -> completedCopies run_completed_at, run_final_turn, and creates .agentxchain/intake/observations/<intent_id>/
failedexecuting -> failedRecords failure-linked run fields without reopening the run
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

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"
}
}

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 the run blocked and the operator decides to continue, the next step is agentxchain intake approve --intent <id> followed by re-planning and a new intake start.

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.

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
executing -> blocked
executing -> completed
executing -> failed
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

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 resolve reads governed 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 nor intake start 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.