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 +25 -9
- package/package.json +1 -1
- package/src/lib/reference-conformance-adapter.js +141 -0
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
|
|
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
|
|
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
|
|
179
|
-
- [CLI reference](https://agentxchain.dev/docs/cli
|
|
180
|
-
- [Adapter reference](https://agentxchain.dev/docs/adapters
|
|
181
|
-
- [Protocol spec (v6)](https://agentxchain.dev/docs/protocol
|
|
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
|
@@ -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);
|