agentxchain 2.1.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,11 +8,11 @@ Legacy IDE-window coordination is still shipped as a compatibility mode for team
8
8
 
9
9
  ## Docs
10
10
 
11
- - [Quickstart](https://agentxchain.dev/docs/quickstart.html)
12
- - [CLI reference](https://agentxchain.dev/docs/cli.html)
13
- - [Adapter reference](https://agentxchain.dev/docs/adapters.html)
14
- - [Protocol spec (v6)](https://agentxchain.dev/docs/protocol.html)
15
- - [Why governed multi-agent delivery matters](https://agentxchain.dev/why.html)
11
+ - [Quickstart](https://agentxchain.dev/docs/quickstart/)
12
+ - [CLI reference](https://agentxchain.dev/docs/cli/)
13
+ - [Adapter reference](https://agentxchain.dev/docs/adapters/)
14
+ - [Protocol spec (v6)](https://agentxchain.dev/docs/protocol/)
15
+ - [Why governed multi-agent delivery matters](https://agentxchain.dev/why/)
16
16
 
17
17
  ## Install
18
18
 
@@ -90,6 +90,7 @@ agentxchain step
90
90
  | `approve-transition` | Approve a pending human-gated phase transition |
91
91
  | `approve-completion` | Approve a pending human-gated run completion |
92
92
  | `validate` | Validate governed kickoff wiring, a staged turn, or both |
93
+ | `verify protocol` | Run the shipped protocol conformance suite against a target implementation |
93
94
  | `dashboard` | Open the read-only governance dashboard in your browser for repo-local runs or multi-repo coordinator initiatives |
94
95
  | `plugin install|list|remove` | Install, inspect, or remove governed hook plugins backed by `agentxchain-plugin.json` manifests |
95
96
 
@@ -124,6 +125,21 @@ agentxchain step
124
125
  4. The assigned role writes `.agentxchain/staging/<turn_id>/turn-result.json`.
125
126
  5. The orchestrator validates and either accepts, rejects, advances phase, pauses for approval, or completes the run.
126
127
 
128
+ ## Protocol Conformance
129
+
130
+ AgentXchain ships a conformance kit under `.agentxchain-conformance/`. Use it to prove a runner or fork still implements the governed workflow contract:
131
+
132
+ ```bash
133
+ agentxchain verify protocol --tier 3 --target .
134
+ ```
135
+
136
+ Useful flags:
137
+
138
+ - `--tier 1|2|3`: maximum conformance tier to verify
139
+ - `--surface <name>`: isolate one surface such as `state_machine`, `dispatch_manifest`, or `coordinator`
140
+ - `--format json`: emit a machine-readable report for CI
141
+ - `--target <path>`: point at the root containing `.agentxchain-conformance/capabilities.json`
142
+
127
143
  Important governed files:
128
144
 
129
145
  ```text
@@ -175,10 +191,10 @@ Requires:
175
191
  ## Links
176
192
 
177
193
  - [agentxchain.dev](https://agentxchain.dev)
178
- - [Quickstart](https://agentxchain.dev/docs/quickstart.html)
179
- - [CLI reference](https://agentxchain.dev/docs/cli.html)
180
- - [Adapter reference](https://agentxchain.dev/docs/adapters.html)
181
- - [Protocol spec (v6)](https://agentxchain.dev/docs/protocol.html)
194
+ - [Quickstart](https://agentxchain.dev/docs/quickstart/)
195
+ - [CLI reference](https://agentxchain.dev/docs/cli/)
196
+ - [Adapter reference](https://agentxchain.dev/docs/adapters/)
197
+ - [Protocol spec (v6)](https://agentxchain.dev/docs/protocol/)
182
198
  - [GitHub](https://github.com/shivamtiwari93/agentXchain.dev)
183
199
  - [Legacy Protocol v3 spec](https://github.com/shivamtiwari93/agentXchain.dev/blob/main/PROTOCOL-v3.md)
184
200
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentxchain",
3
- "version": "2.1.1",
3
+ "version": "2.2.0",
4
4
  "description": "CLI for AgentXchain — governed multi-agent software delivery",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,6 +13,9 @@ import { validateStagedTurnResult } from './turn-result-validator.js';
13
13
  import { finalizeDispatchManifest, verifyDispatchManifest } from './dispatch-manifest.js';
14
14
  import { getDispatchTurnDir } from './turn-paths.js';
15
15
  import { runHooks } from './hook-runner.js';
16
+ import { validateCoordinatorConfig, normalizeCoordinatorConfig } from './coordinator-config.js';
17
+ import { projectRepoAcceptance, evaluateBarriers } from './coordinator-acceptance.js';
18
+ import { readBarriers, saveCoordinatorState, readCoordinatorHistory } from './coordinator-state.js';
16
19
 
17
20
  const VALID_DECISION_CATEGORIES = ['implementation', 'architecture', 'scope', 'process', 'quality', 'release'];
18
21
  const FULL_STAGE_PIPELINE = ['schema', 'assignment', 'artifact', 'verification', 'protocol'];
@@ -213,6 +216,69 @@ function materializeFixtureWorkspace(fixture) {
213
216
  };
214
217
  }
215
218
 
219
+ // ── Tier 3: Multi-workspace materialization ─────────────────────────────────
220
+
221
+ function materializeTier3Workspace(fixture) {
222
+ const root = mkdtempSync(join(tmpdir(), 'agentxchain-conformance-multi-'));
223
+ const setup = fixture.setup || {};
224
+
225
+ // Write coordinator config
226
+ if (setup.coordinator_config) {
227
+ writeJson(join(root, 'agentxchain-multi.json'), setup.coordinator_config);
228
+ }
229
+
230
+ // Materialize governed repo roots
231
+ for (const [repoId, repoSetup] of Object.entries(setup.repos || {})) {
232
+ const repoPath = join(root, repoSetup.path || `./repos/${repoId}`);
233
+ mkdirSync(join(repoPath, '.agentxchain'), { recursive: true });
234
+
235
+ // Write repo-local agentxchain.json
236
+ if (repoSetup.config) {
237
+ writeJson(join(repoPath, 'agentxchain.json'), repoSetup.config);
238
+ }
239
+
240
+ // Write repo-local state
241
+ if (repoSetup.state) {
242
+ const repoConfig = repoSetup.config || {};
243
+ const inflatedRepoConfig = inflateConfig(repoConfig);
244
+ const repoState = inflateState(repoSetup.state, inflatedRepoConfig);
245
+ writeJson(join(repoPath, '.agentxchain', 'state.json'), repoState);
246
+ }
247
+
248
+ // Write repo-local history
249
+ if (repoSetup.history) {
250
+ writeJsonl(join(repoPath, '.agentxchain', 'history.jsonl'), repoSetup.history);
251
+ }
252
+
253
+ // Write repo-local files
254
+ for (const [filePath, content] of Object.entries(repoSetup.files || {})) {
255
+ const absPath = join(repoPath, filePath);
256
+ mkdirSync(dirname(absPath), { recursive: true });
257
+ writeFileSync(absPath, content);
258
+ }
259
+ }
260
+
261
+ // Write coordinator multirepo state if provided
262
+ if (setup.coordinator_state || setup.barriers) {
263
+ const multiDir = join(root, '.agentxchain', 'multirepo');
264
+ mkdirSync(multiDir, { recursive: true });
265
+
266
+ if (setup.coordinator_state) {
267
+ writeJson(join(multiDir, 'state.json'), setup.coordinator_state);
268
+ }
269
+
270
+ if (setup.barriers) {
271
+ writeJson(join(multiDir, 'barriers.json'), setup.barriers);
272
+ }
273
+
274
+ // Write coordinator history
275
+ writeJsonl(join(multiDir, 'history.jsonl'), setup.coordinator_history || []);
276
+ writeJsonl(join(multiDir, 'barrier-ledger.jsonl'), setup.barrier_ledger || []);
277
+ }
278
+
279
+ return root;
280
+ }
281
+
216
282
  function isAssertionObject(value) {
217
283
  return value && typeof value === 'object' && !Array.isArray(value) && typeof value.assert === 'string';
218
284
  }
@@ -699,6 +765,74 @@ function executeFixtureOperation(workspace, fixture) {
699
765
  }
700
766
  }
701
767
 
768
+ function executeTier3Operation(fixture) {
769
+ const root = materializeTier3Workspace(fixture);
770
+ try {
771
+ const operation = fixture.input.operation;
772
+
773
+ if (operation === 'validate_coordinator_config') {
774
+ const configPath = join(root, 'agentxchain-multi.json');
775
+ const raw = JSON.parse(readFileSync(configPath, 'utf8'));
776
+ const validation = validateCoordinatorConfig(raw);
777
+ if (!validation.ok) {
778
+ const firstError = validation.errors[0] || '';
779
+ let errorType = 'invalid_coordinator_config';
780
+ if (firstError.startsWith('workstream_cycle:')) {
781
+ errorType = 'workstream_cycle';
782
+ }
783
+ return { result: 'error', error_type: errorType, errors: validation.errors };
784
+ }
785
+ return { result: 'success', errors: [] };
786
+ }
787
+
788
+ if (operation === 'project_repo_acceptance') {
789
+ const args = fixture.input.args;
790
+ const configPath = join(root, 'agentxchain-multi.json');
791
+ const raw = JSON.parse(readFileSync(configPath, 'utf8'));
792
+ const normalized = normalizeCoordinatorConfig(raw);
793
+
794
+ // Resolve repo paths against the materialized workspace
795
+ for (const [repoId, repo] of Object.entries(normalized.repos)) {
796
+ const resolvedPath = join(root, repo.path);
797
+ normalized.repos[repoId] = { ...repo, resolved_path: resolvedPath };
798
+ }
799
+ normalized.repo_order = Object.keys(normalized.repos);
800
+
801
+ const stateDir = join(root, '.agentxchain', 'multirepo');
802
+ const state = JSON.parse(readFileSync(join(stateDir, 'state.json'), 'utf8'));
803
+
804
+ const projectionResult = projectRepoAcceptance(
805
+ root, state, normalized,
806
+ args.repo_id, args.accepted_turn, args.workstream_id,
807
+ );
808
+
809
+ if (!projectionResult.ok) {
810
+ let errorType = 'projection_failed';
811
+ if (projectionResult.error && projectionResult.error.includes('Cross-repo write violation')) {
812
+ errorType = 'cross_repo_write_violation';
813
+ }
814
+ return { result: 'error', error_type: errorType, error: projectionResult.error };
815
+ }
816
+
817
+ // Evaluate barriers after projection
818
+ const barrierResult = evaluateBarriers(root, state, normalized);
819
+
820
+ return {
821
+ result: 'success',
822
+ projection_ref: projectionResult.projection_ref,
823
+ barrier_effects: projectionResult.barrier_effects || [],
824
+ barrier_snapshot: Object.fromEntries(
825
+ Object.entries(barrierResult.barriers).map(([id, b]) => [id, { status: b.status }]),
826
+ ),
827
+ };
828
+ }
829
+
830
+ return { result: 'error', error_type: 'unsupported_operation', operation };
831
+ } finally {
832
+ rmSync(root, { recursive: true, force: true });
833
+ }
834
+ }
835
+
702
836
  function compareActualToExpected(fixture, actual) {
703
837
  if (matchExpected(fixture.expected, actual)) {
704
838
  return buildPass(actual);
@@ -707,6 +841,13 @@ function compareActualToExpected(fixture, actual) {
707
841
  }
708
842
 
709
843
  export function runReferenceFixture(fixture) {
844
+ // Tier 3 fixtures use multi-workspace materialization; route before creating a Tier 1/2 workspace
845
+ const operation = fixture.input?.operation;
846
+ if (operation === 'validate_coordinator_config' || operation === 'project_repo_acceptance') {
847
+ const actual = executeTier3Operation(fixture);
848
+ return compareActualToExpected(fixture, actual);
849
+ }
850
+
710
851
  const workspace = materializeFixtureWorkspace(fixture);
711
852
  try {
712
853
  const actual = executeFixtureOperation(workspace, fixture);