Skip to main content

Protocol Implementor Guide

The protocol is only real if another implementation can prove it. This page is for runner authors, adapter authors, and compatibility-layer maintainers who want to implement AgentXchain and verify that claim against the repo's published fixture corpus.

If you want the constitutional model, start with Protocol v7. If you want the current normative boundary, read Protocol Reference v7. If you want the executable adoption contract, start here.

What protocol conformance means

AgentXchain ships a repo-native conformance corpus under .agentxchain-conformance/fixtures/. The verifier runs those fixtures against your implementation through a thin adapter boundary. You are not proving that your CLI looks like the reference CLI. You are proving that your implementation behaves the same way at the protocol surface.

The current corpus is split into three tiers:

TierFocusCurrent surfacesCurrent fixture count
1Core constitutional behaviorstate_machine, turn_result_validation, gate_semantics, decision_ledger, history, config_schema, delegation, decision_carryover, parallel_turns, event_lifecycle77
2Trust-hardening behaviordispatch_manifest, hook_audit23
3Multi-repo coordinationcoordinator8

The verifier selects every fixture up to the requested tier. --tier 2 runs Tier 1 plus Tier 2. --tier 3 runs the entire corpus.

What You Do Not Need For v7 Conformance

Do not let the reference CLI's product surface blur the protocol boundary.

A non-reference runner can still claim protocol v7 without implementing these reference-runner workflow surfaces:

  • mission hierarchy and mission plans under .agentxchain/missions/
  • dashboard APIs, ports, view names, and browser UX
  • export, report, and release operator surfaces

Those surfaces matter for the reference runner, but they are not part of the current fixture-backed protocol-v7 requirement set.

A future protocol-v8 cut needs promoted conformance or a new normative artifact/state contract. Shipping more reference-runner workflow features is not enough by itself.

Required repo contract

Your implementation target can expose either a repo-local conformance directory or a remote HTTP conformance endpoint.

Local mode:

.agentxchain-conformance/
capabilities.json
your-adapter.js

capabilities.json tells the verifier what implementation it is testing and how to invoke your adapter.

Remote mode:

  • GET /conform/capabilities
  • POST /conform/execute
  • adapter.protocol: "http-fixture-v1"

The verifier still owns the canonical local fixture corpus in remote mode. The remote endpoint receives one full fixture JSON document per POST and returns the same {status, message, actual} payload that a local stdio adapter would have emitted. For the full HTTP request/response contract, see Remote Protocol Verification.

Writing capabilities.json

This is the reference CLI's current file:

{
"implementation": "agentxchain-cli",
"version": "2.155.72",
"protocol_version": "v7",
"adapter": {
"protocol": "stdio-fixture-v1",
"command": ["node", ".agentxchain-conformance/reference-adapter.js"]
},
"tiers": [1, 2, 3],
"surfaces": {
"state_machine": true,
"turn_result_validation": true,
"gate_semantics": true,
"decision_ledger": true,
"history": true,
"config_schema": true,
"dispatch_manifest": true,
"hook_audit": true,
"coordinator": true,
"delegation": true,
"decision_carryover": true,
"parallel_turns": true,
"event_lifecycle": true
},
"metadata": {
"name": "AgentXchain Reference CLI",
"url": "https://github.com/shivamtiwari93/agentXchain.dev"
}
}

Because this example is the shipped reference CLI file, the surfaces map above must stay exhaustive for the surfaces the implementation actually claims. Leaving out a shipped surface is not harmless sample drift; it tells operators the implementation does not explicitly claim that surface.

Fields that matter today:

FieldRequiredNotes
implementationYesNon-empty string used in the report
protocol_versionNoInformational but useful for humans and release evidence
adapter.protocolYesMust be exactly stdio-fixture-v1
adapter.commandYesNon-empty command array passed to spawnSync()
tiersYesNon-empty array containing only 1, 2, or 3

For remote HTTP verification, the capabilities document is fetched from GET /conform/capabilities and adapter.protocol must instead be http-fixture-v1. In that mode there is no adapter.command; the verifier posts fixtures to POST /conform/execute.

Fields that affect verifier behavior when present:

FieldRole
surfacesWhen present, the verifier enforces surface claims: --surface X will fail fast if surfaces.X is not declared. When absent, surface filtering works without enforcement for backward compatibility.

Fields that are informative only:

FieldRole
versionHuman-readable implementation version
metadataDisplay metadata only

Surface enforcement rule: If your capabilities.json includes a surfaces map, any --surface request for an undeclared surface exits with code 2 and a clear error naming the unclaimed surface plus listing claimed ones. If you omit the surfaces map entirely, surface filtering still works but without claim enforcement — this preserves backward compatibility for implementations that predate surface declarations.

Writing a stdio-fixture-v1 adapter

The adapter contract is intentionally narrow:

  1. Read one fixture JSON object from stdin.
  2. Materialize the fixture setup in your implementation's test workspace.
  3. Execute the fixture's input.operation against your implementation.
  4. Compare the result against expected.
  5. Emit exactly one JSON result on stdout.
  6. Exit with the status code that matches the JSON result.

Adapter result shape:

{
"status": "pass",
"message": "optional human-readable note",
"actual": null
}

Valid adapter statuses:

Adapter statusMeaningRequired process exit code
passFixture behavior matched expectation0
failFixture executed but the behavior was wrong1
errorAdapter or implementation could not evaluate the fixture correctly2
not_implementedFixture surface is intentionally unsupported for now3

Minimal adapter skeleton:

#!/usr/bin/env node

import { stdin, stdout, stderr, exit } from 'node:process';

let input = '';
stdin.setEncoding('utf8');
stdin.on('data', (chunk) => {
input += chunk;
});

stdin.on('end', async () => {
try {
const fixture = JSON.parse(input);
const result = await runFixtureAgainstYourImplementation(fixture);
stdout.write(`${JSON.stringify(result)}\n`);

const code =
result.status === 'pass' ? 0 :
result.status === 'fail' ? 1 :
result.status === 'not_implemented' ? 3 :
2;

exit(code);
} catch (error) {
stderr.write(`${error.message}\n`);
stdout.write(`${JSON.stringify({
status: 'error',
message: error.message,
actual: null,
})}\n`);
exit(2);
}
});

Progressive conformance

not_implemented exists so third-party implementations can adopt the protocol incrementally without faking success or collapsing into generic adapter errors. That status is valid adapter output.

Be precise about the semantics:

  • not_implemented is counted separately from pass, fail, and error.
  • A tier can still be reported as overall pass when every selected fixture is either pass or not_implemented.
  • not_implemented is not a loophole for broken behavior. If the surface exists and behaves incorrectly, return fail.

Running protocol conformance

Typical usage:

# Run Tier 1 against the current directory
agentxchain conformance check --tier 1 --target .

# Run up to Tier 2 and isolate one surface
agentxchain conformance check --tier 2 --surface dispatch_manifest --target .

# Emit JSON for CI or a reporting pipeline
agentxchain conformance check --tier 3 --target . --format json

# Verify a remote implementation over HTTP
agentxchain conformance check --tier 1 --remote https://example.com/agentxchain --format json

agentxchain verify protocol remains supported as a compatibility alias over the same verifier.

Command options:

FlagMeaning
`--tier <12
--surface &lt;name&gt;Restrict execution to one surface
--target &lt;path&gt;Root containing .agentxchain-conformance/capabilities.json
--remote &lt;url&gt;Remote HTTP conformance endpoint base URL
--token &lt;token&gt;Bearer token for remote verification
--timeout &lt;ms&gt;Per-fixture remote HTTP timeout in milliseconds
`--format <textjson>`

Do not confuse verifier exit codes with adapter exit codes

The adapter speaks per-fixture status. The verifier speaks overall run status.

SurfaceExit codes
Adapter process0=pass, 1=fail, 2=error, 3=not_implemented
agentxchain verify protocol0=overall pass, 1=one or more fixture failures, 2=verifier or adapter error

The verifier never exits 3. not_implemented is adapter-level truth that gets folded into the final report.

Report interpretation

The JSON report includes:

  • implementation
  • protocol_version
  • tier_requested
  • target_root
  • results.tier_N
  • overall

Each tier summary tracks:

  • fixtures_run
  • fixtures_passed
  • fixtures_failed
  • fixtures_errored
  • fixtures_not_implemented
  • surfaces
  • failures[]
  • errors[]
  • not_implemented[]

That shape lets you distinguish "we have not built this yet" from "we built it and got it wrong." If your CI collapses those cases together, your adoption signal is garbage.

Fixture anatomy

Every fixture is a single JSON file under .agentxchain-conformance/fixtures/<tier>/<surface>/.

Real Tier 1 example:

{
"fixture_id": "SM-001",
"tier": 1,
"surface": "state_machine",
"description": "Completed state rejects assignment",
"type": "reject",
"setup": {
"state": {
"status": "completed",
"phase": "qa",
"run_id": "run_001",
"active_turns": {},
"pending_phase_transition": null,
"pending_run_completion": null,
"blocked_on": null
},
"config": {
"roles": {
"dev": {
"runtime": "manual"
}
}
}
},
"input": {
"operation": "assign_turn",
"args": {
"role_id": "dev"
}
},
"expected": {
"result": "error",
"error_type": "invalid_state_transition",
"state_unchanged": true
}
}

The important fields are:

FieldMeaning
fixture_idStable identifier used in reports and CI failures
tierWhich conformance tier the fixture belongs to
surfaceProtocol subsystem under test
descriptionHuman-readable contract summary
typeFixture intent such as validate, reject, or transition
setupFiles, state, config, dispatch bundles, or coordinator state to materialize
inputAbstract operation plus arguments your adapter must map onto your implementation
expectedMinimal assertion object the adapter must satisfy

The input.operation verbs are fixture abstractions, not CLI command names. Your adapter is responsible for mapping those verbs onto your implementation.

Surface reference

state_machine

Core run lifecycle rules. Tier 1 currently proves:

  • initialization moves idle to active only with valid governed config
  • human gates move active to paused, and approvals resume to active or finish to completed
  • escalations move active to blocked, and explicit resolution moves blocked back to active
  • terminal completed runs reject new assignment and approval attempts
  • illegal transitions such as idle -> paused are rejected
  • run_id is immutable after initialization

If your state machine is loose here, every higher surface becomes untrustworthy.

turn_result_validation

Validation pipeline for staged turn results. Tier 1 currently proves:

  • required fields such as summary are enforced at schema validation time
  • staged results must match the assigned run_id and turn_id
  • reserved paths in files_changed are rejected before acceptance
  • review_only turns must include at least one objection
  • decision IDs must match the DEC-NNN contract
  • phase_transition and run_completion cannot both be requested in one staged result
  • needs_human status is valid when accompanied by the required reason

These checks exist to reject malformed or incomplete artifacts before they enter history.

gate_semantics

Human approval boundaries for phase transitions and run completion. This surface proves both structural gate predicates and workflow-file semantic evaluators. The conformance corpus currently covers:

  • .planning/PM_SIGNOFF.md must contain Approved: YES before planning can exit
  • .planning/ship-verdict.md must contain an affirmative ## Verdict: before run completion
  • .planning/SYSTEM_SPEC.md must define required contract sections (e.g. ## Acceptance Tests) before planning can exit
  • .planning/IMPLEMENTATION_NOTES.md must replace scaffold placeholders with real content before implementation can exit
  • .planning/acceptance-matrix.md must contain a real passing requirement table before run completion
  • .planning/RELEASE_NOTES.md must replace scaffold placeholders with real QA content before run completion

These are not documentation preferences. They are runtime-enforced semantic checks: the gate evaluator reads the file content, parses it, and rejects phase advancement or run completion when the content is structurally insufficient. This is where AgentXchain stops pretending a model can unilaterally ship.

decision_ledger

Append-only constitutional record for decisions, objections, approvals, and rejections. Tier 1 currently proves:

  • well-formed decision entries include the required fields
  • empty decision statements are rejected
  • invalid categories are rejected
  • duplicate decision IDs within one run are rejected

If this surface is wrong, your audit trail is fiction.

history

Accepted turn-result history and its integrity constraints. Tier 1 currently proves:

  • accepting a turn appends exactly one history entry atomically with the state update
  • re-accepting the same turn is idempotent and does not duplicate history
  • accepting a non-active turn fails before history can change

This surface proves what actually happened across the run, not what a status screen claims happened.

config_schema

Validation of governed config shape, roles, runtimes, and baseline project contract. Tier 1 currently proves:

  • a minimal governed config is accepted
  • entry_role must refer to a declared role
  • roles cannot reference undeclared runtimes
  • routing cannot reference undeclared gates
  • invalid schema_version values are rejected

Broken config validation pushes protocol drift downstream where it is harder to debug.

delegation

Hierarchical authority delegation from one role to another. Tier 1 currently proves:

  • a valid delegation with all required fields (to_role, charter, scope) passes validation
  • delegation with missing charter is rejected
  • delegation with an invalid to_role pattern is rejected
  • self-delegation (delegating to your own role) is rejected
  • more than 5 delegations in a single turn result are rejected
  • delegation cannot coexist with a run_completion_request in the same turn result
  • delegation with required_decision_ids passes validation when the IDs are well-formed
  • delegation with duplicate required_decision_ids is rejected

Delegation is not a convenience feature. It is how governed authority flows through a role hierarchy without collapsing the audit trail.

decision_carryover

Cross-run decision durability and override semantics. Tier 1 currently proves:

  • a decision with durability: "repo" passes turn result validation and promotes into repo-level continuity
  • a decision with an invalid durability value (not "run" or "repo") is rejected
  • a decision with a valid overrides field pointing at an existing repo decision passes validation
  • a decision with overrides pointing at itself (self-override) is rejected
  • a decision with default durability (omitted, meaning "run") passes validation

If your implementation does not enforce durability scoping and override validity, continuation runs will inherit stale or contradictory decisions.

parallel_turns

Concurrent turn dispatch configuration. Tier 1 currently proves:

  • config with max_concurrent_turns: 2 passes validation
  • config with max_concurrent_turns: 4 passes validation (maximum allowed)
  • config with max_concurrent_turns: 1 passes validation (sequential mode, the default)
  • config with max_concurrent_turns: 0 fails validation (must be >= 1)
  • config with max_concurrent_turns: 5 fails validation (maximum is 4)
  • config with a non-integer max_concurrent_turns fails validation

The range is intentionally narrow. Unbounded parallelism in governed delivery is not a scaling feature; it is a governance collapse risk.

event_lifecycle

Structural and ordering validation for run lifecycle events in .agentxchain/events.jsonl. Tier 1 currently proves:

  • a valid run event with all required fields (event_type, timestamp, run_id) passes validation
  • an event with an invalid event_type is rejected
  • a valid event sequence with run_started first and run_completed last passes ordering validation
  • turn_accepted without a preceding turn_dispatched for the same turn fails ordering validation
  • run_completed not being the last event fails ordering validation
  • backwards timestamps (timestamp regression) fail ordering validation
  • a turn_dispatched event missing turn.turn_id fails event validation
  • a timeline not starting with run_started fails ordering validation

This surface proves that your event log is a trustworthy timeline, not just an append-only dump. Ordering and completeness constraints make the event log useful for recovery, audit, and dashboard rendering.

dispatch_manifest

Dispatch-bundle finalization and integrity verification. This is the hardening layer that proves agents received the expected assignment files and that post-finalization tampering is detectable. Tier 2 currently proves:

  • a finalized manifest with valid SHA-256 digests verifies successfully
  • an unexpected file injected after finalization fails verification
  • content tampering that changes a file's digest fails verification
  • a deleted file after finalization fails verification
  • MANIFEST.json is excluded from its own file entries
  • a size mismatch after content replacement with different-length data fails verification
  • multiple simultaneous integrity violations produce accumulated errors, not just the first
  • a missing manifest after deletion fails with a missing_manifest error
  • malformed MANIFEST.json (invalid JSON) fails with invalid_manifest
  • a manifest missing required fields fails with invalid_manifest

These are not smoke tests. They prove that the dispatch bundle is a tamper-evident envelope, not just a file list.

hook_audit

Execution and audit recording for lifecycle hooks. The important contract is not just "hooks run" but "their effects are observable and attributable." Tier 2 currently proves:

  • a process hook audit entry contains all required fields (hook_id, orchestrator_action, verdict, exit_code, duration_ms)
  • an HTTP hook records transport: "http" even on connection failure
  • an advisory hook returning verdict: "block" is downgraded to a warning (downgraded_block_to_warn)
  • a blocking hook process failure records blocked_failure and halts the phase
  • protected-file tamper detection records aborted_tamper and halts the phase with hook_ok: false, blocked: false
  • a blocking hook explicit block verdict records blocked and stops the phase
  • a blocking hook short-circuits later hooks; remaining entries are recorded as skipped
  • a blocking hook with invalid JSON output records blocked_invalid_output and halts the phase
  • an advisory hook with invalid JSON output records warned_invalid_output without blocking
  • a blocking hook timeout records blocked_timeout and halts the phase
  • an advisory hook timeout records warned_timeout without blocking
  • an advisory hook process failure records warned_failure without blocking
  • an advisory hook verdict: "warn" records warned without blocking

Your adapter's run_hooks operation must return this shape:

{
"result": "success",
"hook_ok": boolean,
"blocked": boolean,
"audit_entry": { ... } | null,
"audit_entries": [ ... ]
}

hook_ok means "can the governed pipeline proceed past this hook phase?" — not "did the hook succeed." Advisory hooks that fail, time out, or produce garbage still return hook_ok: true because advisory failures degrade to warnings without halting the pipeline. hook_ok: false means a blocking condition was encountered: either a blocking hook blocked or a protected file was tampered with.

blocked is true only when a blocking hook returned a block verdict (explicit, fail-closed, timeout, or invalid output). Tamper detection sets hook_ok: false but blocked: false — it is a different halt mechanism.

audit_entries is the ordered list of all hook execution results. Each entry includes orchestrator_action, the precise 13-value enum describing what happened:

orchestrator_actionhook_okblockedMeaning
continuedtruefalseHook returned verdict: "allow"
warnedtruefalseHook returned verdict: "warn"
downgraded_block_to_warntruefalseAdvisory hook returned block, downgraded to warn
warned_failuretruefalseAdvisory hook exited non-zero
warned_timeouttruefalseAdvisory hook exceeded timeout_ms
warned_invalid_outputtruefalseAdvisory hook produced unparseable stdout
blockedfalsetrueBlocking hook returned verdict: "block"
blocked_failurefalsetrueBlocking hook exited non-zero (fail-closed)
blocked_timeoutfalsetrueBlocking hook exceeded timeout_ms (fail-closed)
blocked_invalid_outputfalsetrueBlocking hook produced unparseable stdout (fail-closed)
aborted_tamperfalsefalseHook modified a SHA-256 protected file
skippedN/AN/APrior blocking hook blocked; remaining hooks were not executed

skipped entries appear in audit_entries (not as the primary audit_entry) with verdict: null, exit_code: null, duration_ms: 0, and no transport field.

The disambiguation signal for operators and dashboards is orchestrator_action, not hook_ok. Use hook_ok for flow control (proceed or halt). Use orchestrator_action for precise diagnosis.

coordinator

Multi-repo coordination: coordinator config validation, acceptance projection, workstream state, and barrier semantics. Tier 3 starts here because cross-repo governance is where weak protocol claims usually collapse. Tier 3 currently proves:

  • a valid coordinator config with repos and workstreams validates successfully
  • cyclic workstream dependencies are rejected at config validation time
  • the first repo acceptance transitions a barrier from pending to partially_satisfied
  • all required repos accepting transitions a barrier from partially_satisfied to satisfied
  • cross-repo write isolation is enforced: file write violations are rejected during acceptance projection
  • ordered_repo_sequence stays unsatisfied when a downstream repo accepts before the entry repo
  • shared_human_gate remains pending even after every required repo has accepted — it requires explicit human approval
  • interface_alignment requires each repo to have accepted its declared DEC-NNN decision IDs (via decision_ids_by_repo) before the barrier is satisfied
  • named_decisions requires each repo to have accepted its declared DEC-NNN decision IDs (via named_decisions.decision_ids_by_repo) before the barrier is satisfied

interface_alignment and named_decisions are not heuristic placeholders. The coordinator resolves them by checking accepted decision ledger entries per repo against declared requirements.

Fixture setup helpers you need to support

Depending on the surface, fixtures may ask your adapter to materialize:

  • Common repo-local setup: setup.config, setup.state, setup.turn_result, setup.history, setup.ledger, setup.filesystem
  • Dispatch-manifest setup: setup.dispatch_bundle, setup.post_finalize_inject, setup.post_finalize_tamper, setup.post_finalize_delete, setup.post_finalize_corrupt_manifest, setup.post_finalize_delete_manifest
  • Coordinator setup: setup.coordinator_config, setup.repos, setup.coordinator_state, setup.barriers, setup.coordinator_history

Those keys are part of the adapter contract, not implementation detail. If your adapter silently ignores one, you are not "partially compatible" with that fixture; you are evaluating the wrong setup state.

The authoritative helper list lives in .agentxchain-conformance/fixtures/README.md. Do not fork the contract in your own docs and hope it stays aligned.

  1. Implement Tier 1 first and return not_implemented for higher tiers.
  2. Add Tier 2 once your dispatch-manifest and hook-audit surfaces are real, not mocked.
  3. Add Tier 3 only when your coordinator model is actually multi-repo and barrier-aware.
  4. Run agentxchain verify protocol --format json in CI and publish the report with your release evidence.

Protocol claims without conformance evidence are marketing. AgentXchain only becomes an open protocol if independent implementations can fail publicly and fix themselves against the same corpus.