artifact-chain-assistant 0.8.2 → 0.8.3
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +13 -0
- package/INSTALL.md +10 -10
- package/README.md +4 -4
- package/README.zh-CN.md +4 -4
- package/adapters/claude/.claude-plugin/plugin.json +1 -1
- package/adapters/claude/INSTALL.md +10 -10
- package/adapters/claude/agent-methods/catalog.yaml +1 -1
- package/adapters/claude/compatibility.json +4 -4
- package/adapters/claude/families-src/prd-feature/implementation.yaml +39 -0
- package/adapters/claude/families-src/scenario-script/implementation.yaml +39 -0
- package/adapters/claude/family-apis/catalog.json +16 -0
- package/adapters/claude/family-apis/e2e-test/api.json +205 -0
- package/adapters/claude/family-apis/schema/family-api.schema.json +235 -0
- package/adapters/claude/schemas/project-facts.schema.json +80 -0
- package/adapters/claude/scripts/check-family-api.mjs +84 -0
- package/adapters/claude/scripts/export-family-api.mjs +184 -0
- package/adapters/claude/scripts/family-compile.mjs +309 -0
- package/adapters/claude/scripts/family-help-render.mjs +214 -0
- package/adapters/claude/scripts/lib/family-api-validator.mjs +413 -0
- package/adapters/claude/scripts/lib/generated/canonical-json-v1-manifest.json +7 -0
- package/adapters/claude/scripts/lib/generated/canonical-json-v1-vectors.generated.json +50 -0
- package/adapters/claude/scripts/lib/generated/canonical-json-v1.generated.mjs +130 -0
- package/adapters/claude/scripts/lib/generated/family-api-validator.generated.mjs +1756 -0
- package/adapters/claude/scripts/lib/generated/project-facts-validator.generated.mjs +638 -0
- package/adapters/claude/scripts/lib/generated/schema-validator-manifest.json +20 -0
- package/adapters/claude/scripts/lib/method-query.mjs +177 -0
- package/adapters/claude/scripts/method-query.mjs +67 -0
- package/adapters/claude/skills/setup/SKILL.md +2 -1
- package/adapters/codex/.codex-plugin/plugin.json +1 -1
- package/adapters/codex/INSTALL.md +10 -10
- package/adapters/codex/agent-methods/catalog.yaml +1 -1
- package/adapters/codex/compatibility.json +4 -4
- package/adapters/codex/families-src/prd-feature/implementation.yaml +39 -0
- package/adapters/codex/families-src/scenario-script/implementation.yaml +39 -0
- package/adapters/codex/family-apis/catalog.json +16 -0
- package/adapters/codex/family-apis/e2e-test/api.json +205 -0
- package/adapters/codex/family-apis/schema/family-api.schema.json +235 -0
- package/adapters/codex/schemas/project-facts.schema.json +80 -0
- package/adapters/codex/scripts/check-family-api.mjs +84 -0
- package/adapters/codex/scripts/export-family-api.mjs +184 -0
- package/adapters/codex/scripts/family-compile.mjs +309 -0
- package/adapters/codex/scripts/family-help-render.mjs +214 -0
- package/adapters/codex/scripts/lib/family-api-validator.mjs +413 -0
- package/adapters/codex/scripts/lib/generated/canonical-json-v1-manifest.json +7 -0
- package/adapters/codex/scripts/lib/generated/canonical-json-v1-vectors.generated.json +50 -0
- package/adapters/codex/scripts/lib/generated/canonical-json-v1.generated.mjs +130 -0
- package/adapters/codex/scripts/lib/generated/family-api-validator.generated.mjs +1756 -0
- package/adapters/codex/scripts/lib/generated/project-facts-validator.generated.mjs +638 -0
- package/adapters/codex/scripts/lib/generated/schema-validator-manifest.json +20 -0
- package/adapters/codex/scripts/lib/method-query.mjs +177 -0
- package/adapters/codex/scripts/method-query.mjs +67 -0
- package/adapters/codex/skills/setup/SKILL.md +2 -1
- package/agent-methods/catalog.yaml +1 -1
- package/compatibility.json +4 -4
- package/families-src/prd-feature/implementation.yaml +39 -0
- package/families-src/scenario-script/implementation.yaml +39 -0
- package/family-apis/catalog.json +16 -0
- package/family-apis/e2e-test/api.json +205 -0
- package/family-apis/schema/family-api.schema.json +235 -0
- package/package.json +2 -2
- package/schemas/project-facts.schema.json +80 -0
- package/scripts/check-family-api.mjs +84 -0
- package/scripts/export-family-api.mjs +184 -0
- package/scripts/family-compile.mjs +309 -0
- package/scripts/family-help-render.mjs +214 -0
- package/scripts/generate-canonical-json-protocol.mjs +75 -0
- package/scripts/generate-schema-validators.mjs +141 -0
- package/scripts/lib/family-api-validator.mjs +413 -0
- package/scripts/lib/generated/canonical-json-v1-manifest.json +7 -0
- package/scripts/lib/generated/canonical-json-v1-vectors.generated.json +50 -0
- package/scripts/lib/generated/canonical-json-v1.generated.mjs +130 -0
- package/scripts/lib/generated/family-api-validator.generated.mjs +1756 -0
- package/scripts/lib/generated/project-facts-validator.generated.mjs +638 -0
- package/scripts/lib/generated/schema-validator-manifest.json +20 -0
- package/scripts/lib/method-query.mjs +177 -0
- package/scripts/method-query.mjs +67 -0
- package/skills/setup/SKILL.md +2 -1
- package/skills-src/setup/SKILL.md +2 -1
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// @feature ACA18 @scenario S-66 @decision D-ACA-18
|
|
2
|
+
// Dependency-free project-facts and Method Query protocol implementation.
|
|
3
|
+
// JSON Schemas are compiled at build time into the generated validators below.
|
|
4
|
+
//
|
|
5
|
+
// Registry is the sole Method Query producer. This library provides:
|
|
6
|
+
// - buildProjectFactsEnvelope / validateProjectFacts: envelope lifecycle
|
|
7
|
+
// - buildMethodQueryCandidate: produces the 5-key candidate for Registry consumption
|
|
8
|
+
//
|
|
9
|
+
// DEPRECATED: buildMethodQuery and computeQueryDigest were removed to enforce
|
|
10
|
+
// Registry as the only producer of target/contract/evidence/queryDigest.
|
|
11
|
+
import { createHash } from 'node:crypto';
|
|
12
|
+
import { canonicalStringify, cloneStrictJsonData } from './generated/canonical-json-v1.generated.mjs';
|
|
13
|
+
import validateProjectFactsSchema, { schemaDigest as projectFactsSchemaDigest } from './generated/project-facts-validator.generated.mjs';
|
|
14
|
+
|
|
15
|
+
export { projectFactsSchemaDigest };
|
|
16
|
+
|
|
17
|
+
function digestObject(value) {
|
|
18
|
+
return `sha256:${createHash('sha256').update(canonicalStringify(value)).digest('hex')}`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function computeEvidenceDigest(envelope) {
|
|
22
|
+
const clone = structuredClone(envelope);
|
|
23
|
+
delete clone.evidenceDigest;
|
|
24
|
+
return digestObject(clone);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function buildProjectFactsEnvelope(facts) {
|
|
28
|
+
const snapshot = cloneStrictJsonData(facts);
|
|
29
|
+
const contextTargets = normalizeContextTargets(snapshot.artifactGraphSummary?.contextTargets);
|
|
30
|
+
const envelope = {
|
|
31
|
+
schemaVersion: 1,
|
|
32
|
+
projectRoot: snapshot.projectRoot,
|
|
33
|
+
configDigest: snapshot.configDigest,
|
|
34
|
+
artifactGraphSummary: {
|
|
35
|
+
...snapshot.artifactGraphSummary,
|
|
36
|
+
contextTargets,
|
|
37
|
+
},
|
|
38
|
+
targetArtifact: snapshot.targetArtifact,
|
|
39
|
+
contractRevisionDigest: snapshot.contractRevisionDigest,
|
|
40
|
+
proofStatus: snapshot.proofStatus,
|
|
41
|
+
versionLockStatus: snapshot.versionLockStatus,
|
|
42
|
+
sourcesFreshness: snapshot.sourcesFreshness,
|
|
43
|
+
bindingFreshness: snapshot.bindingFreshness,
|
|
44
|
+
};
|
|
45
|
+
if (Object.hasOwn(snapshot, 'policyDigest')) envelope.policyDigest = snapshot.policyDigest;
|
|
46
|
+
envelope.evidenceDigest = computeEvidenceDigest(envelope);
|
|
47
|
+
return envelope;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function normalizeContextTargets(value) {
|
|
51
|
+
if (!Array.isArray(value) || !value.every(item => typeof item === 'string')) {
|
|
52
|
+
throw new TypeError('artifactGraphSummary.contextTargets must be a string array');
|
|
53
|
+
}
|
|
54
|
+
return [...new Set(value)].sort();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function hasCanonicalContextTargets(value) {
|
|
58
|
+
if (!Array.isArray(value) || !value.every(item => typeof item === 'string')) return false;
|
|
59
|
+
return value.every((item, index) => index === 0 || value[index - 1] < item);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function schemaErrors(validate) {
|
|
63
|
+
return (validate.errors || []).map(error => ({
|
|
64
|
+
code: 'SCHEMA_VALIDATION',
|
|
65
|
+
path: error.instancePath || '/',
|
|
66
|
+
message: error.message,
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function validateProjectFactsSync(envelope) {
|
|
71
|
+
if (!validateProjectFactsSchema(envelope)) {
|
|
72
|
+
return { ok: false, status: 'NEEDS_INPUT', errors: schemaErrors(validateProjectFactsSchema) };
|
|
73
|
+
}
|
|
74
|
+
if (!hasCanonicalContextTargets(envelope.artifactGraphSummary.contextTargets)) {
|
|
75
|
+
return {
|
|
76
|
+
ok: false,
|
|
77
|
+
status: 'NEEDS_INPUT',
|
|
78
|
+
errors: [{
|
|
79
|
+
code: 'NON_CANONICAL_CONTEXT_TARGETS',
|
|
80
|
+
path: '/artifactGraphSummary/contextTargets',
|
|
81
|
+
message: 'contextTargets must be sorted and unique',
|
|
82
|
+
}],
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const computed = computeEvidenceDigest(envelope);
|
|
86
|
+
if (computed !== envelope.evidenceDigest) {
|
|
87
|
+
return {
|
|
88
|
+
ok: false,
|
|
89
|
+
status: 'NEEDS_INPUT',
|
|
90
|
+
errors: [{
|
|
91
|
+
code: 'DIGEST_MISMATCH',
|
|
92
|
+
path: '/evidenceDigest',
|
|
93
|
+
message: 'evidenceDigest mismatch',
|
|
94
|
+
}],
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return { ok: true, status: 'READY', errors: [] };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export async function validateProjectFacts(envelope) {
|
|
101
|
+
return validateProjectFactsSync(envelope);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Build a Method Query candidate (5 top-level keys).
|
|
106
|
+
* This is the input for Registry's queryEffectiveIndex. Registry may create a
|
|
107
|
+
* process-local preparedQueryHandle for a downstream executor; this library
|
|
108
|
+
* never receives, serializes or substitutes that capability.
|
|
109
|
+
* Registry is the sole Method Query producer — do NOT use this to build a full query.
|
|
110
|
+
*/
|
|
111
|
+
export function buildMethodQueryCandidate(params) {
|
|
112
|
+
const snapshot = cloneStrictJsonData(params);
|
|
113
|
+
const allowedKeys = ['mode', 'intent', 'kind', 'projectFactsEvidence', 'authorization'];
|
|
114
|
+
const keys = Object.keys(snapshot);
|
|
115
|
+
const extraKeys = keys.filter(key => !allowedKeys.includes(key));
|
|
116
|
+
const missingKeys = allowedKeys.filter(key => !Object.hasOwn(snapshot, key));
|
|
117
|
+
if (extraKeys.length > 0 || missingKeys.length > 0) {
|
|
118
|
+
throw new TypeError(`Method Query Candidate must contain exactly 5 keys; extra=[${extraKeys.join(', ')}], missing=[${missingKeys.join(', ')}]`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// mode must be 'standard' (the only valid value)
|
|
122
|
+
if (snapshot.mode !== 'standard') {
|
|
123
|
+
throw new TypeError("mode must be 'standard'");
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// intent must be a valid Method Query intent enum
|
|
127
|
+
const VALID_INTENTS = new Set(['default', 'help', 'author', 'review', 'repair', 'route', 'audit', 'generate', 'batch']);
|
|
128
|
+
if (typeof snapshot.intent !== 'string' || !VALID_INTENTS.has(snapshot.intent)) {
|
|
129
|
+
throw new TypeError(`intent must be one of: ${[...VALID_INTENTS].join(', ')}`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// kind must be 'workflow' or 'operation'
|
|
133
|
+
if (snapshot.kind !== 'workflow' && snapshot.kind !== 'operation') {
|
|
134
|
+
throw new TypeError("kind must be 'workflow' or 'operation'");
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// authorization must have exactly sideEffectBudget and granted
|
|
138
|
+
if (!snapshot.authorization || typeof snapshot.authorization !== 'object' || Array.isArray(snapshot.authorization)) {
|
|
139
|
+
throw new TypeError('authorization must be an object');
|
|
140
|
+
}
|
|
141
|
+
const authorizationKeys = Object.keys(snapshot.authorization);
|
|
142
|
+
const AUTHORIZATION_REQUIRED = ['sideEffectBudget', 'granted'];
|
|
143
|
+
const AUTHORIZATION_ALLOWED = new Set(AUTHORIZATION_REQUIRED);
|
|
144
|
+
const extraAuthKeys = authorizationKeys.filter(k => !AUTHORIZATION_ALLOWED.has(k));
|
|
145
|
+
const missingAuthKeys = AUTHORIZATION_REQUIRED.filter(k => !authorizationKeys.includes(k));
|
|
146
|
+
if (extraAuthKeys.length > 0 || missingAuthKeys.length > 0) {
|
|
147
|
+
throw new TypeError(`authorization must have exactly sideEffectBudget and granted; extra=[${extraAuthKeys.join(', ')}], missing=[${missingAuthKeys.join(', ')}]`);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// sideEffectBudget must be a valid enum value
|
|
151
|
+
const VALID_BUDGETS = new Set(['none', 'read-only', 'write-authorized-artifacts', 'write-review-result', 'write-project-artifacts']);
|
|
152
|
+
if (!VALID_BUDGETS.has(snapshot.authorization.sideEffectBudget)) {
|
|
153
|
+
throw new TypeError(`authorization.sideEffectBudget must be one of: ${[...VALID_BUDGETS].join(', ')}`);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// granted must be boolean
|
|
157
|
+
if (typeof snapshot.authorization.granted !== 'boolean') {
|
|
158
|
+
throw new TypeError('authorization.granted must be a boolean');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (!snapshot.projectFactsEvidence || typeof snapshot.projectFactsEvidence !== 'object' || Array.isArray(snapshot.projectFactsEvidence)) {
|
|
162
|
+
throw new TypeError('projectFactsEvidence must be a valid Project Facts Evidence Envelope object');
|
|
163
|
+
}
|
|
164
|
+
const validation = validateProjectFactsSync(snapshot.projectFactsEvidence);
|
|
165
|
+
if (!validation.ok) {
|
|
166
|
+
const codes = validation.errors.map(error => error.code).join(', ');
|
|
167
|
+
throw new TypeError(`projectFactsEvidence validation failed: ${codes}`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
mode: snapshot.mode,
|
|
172
|
+
intent: snapshot.intent,
|
|
173
|
+
kind: snapshot.kind,
|
|
174
|
+
projectFactsEvidence: snapshot.projectFactsEvidence,
|
|
175
|
+
authorization: snapshot.authorization,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @feature ACA18 @scenario S-66 @decision D-ACA-18
|
|
3
|
+
// Method Query CLI: validate/build project-facts envelopes and candidates.
|
|
4
|
+
// Deterministic, fail-closed: invalid input → non-zero exit.
|
|
5
|
+
//
|
|
6
|
+
// Registry is the sole Method Query producer. This CLI provides:
|
|
7
|
+
// - validate-envelope: validate a project-facts evidence envelope
|
|
8
|
+
// - build-envelope: build and validate an envelope from raw facts
|
|
9
|
+
// - build-candidate: build a 5-key candidate for Registry consumption
|
|
10
|
+
//
|
|
11
|
+
// REMOVED: build-query, digest — these produced full Method Query/queryDigest
|
|
12
|
+
// outside Registry, violating the single-producer invariant.
|
|
13
|
+
import { readFile } from 'node:fs/promises';
|
|
14
|
+
import {
|
|
15
|
+
buildProjectFactsEnvelope,
|
|
16
|
+
validateProjectFacts,
|
|
17
|
+
buildMethodQueryCandidate,
|
|
18
|
+
} from './lib/method-query.mjs';
|
|
19
|
+
|
|
20
|
+
const command = process.argv[2];
|
|
21
|
+
|
|
22
|
+
if (!command || command === '--help') {
|
|
23
|
+
process.stderr.write(`Usage:
|
|
24
|
+
method-query.mjs validate-envelope <path> Validate a project-facts envelope
|
|
25
|
+
method-query.mjs build-envelope <path> Build envelope from raw facts JSON
|
|
26
|
+
method-query.mjs build-candidate <path> Build candidate for Registry
|
|
27
|
+
`);
|
|
28
|
+
process.exit(command ? 0 : 1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
switch (command) {
|
|
33
|
+
case 'validate-envelope': {
|
|
34
|
+
const filePath = process.argv[3];
|
|
35
|
+
if (!filePath) { process.stderr.write('Missing file path\n'); process.exit(1); }
|
|
36
|
+
const envelope = JSON.parse(await readFile(filePath, 'utf8'));
|
|
37
|
+
const result = await validateProjectFacts(envelope);
|
|
38
|
+
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
39
|
+
if (!result.ok) process.exit(1);
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
case 'build-envelope': {
|
|
43
|
+
const filePath = process.argv[3];
|
|
44
|
+
if (!filePath) { process.stderr.write('Missing file path\n'); process.exit(1); }
|
|
45
|
+
const facts = JSON.parse(await readFile(filePath, 'utf8'));
|
|
46
|
+
const envelope = buildProjectFactsEnvelope(facts);
|
|
47
|
+
const validation = await validateProjectFacts(envelope);
|
|
48
|
+
process.stdout.write(JSON.stringify({ ...validation, envelope }, null, 2) + '\n');
|
|
49
|
+
if (!validation.ok) process.exit(1);
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case 'build-candidate': {
|
|
53
|
+
const filePath = process.argv[3];
|
|
54
|
+
if (!filePath) { process.stderr.write('Missing file path\n'); process.exit(1); }
|
|
55
|
+
const params = JSON.parse(await readFile(filePath, 'utf8'));
|
|
56
|
+
const candidate = buildMethodQueryCandidate(params);
|
|
57
|
+
process.stdout.write(JSON.stringify({ ok: true, candidate }, null, 2) + '\n');
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
default:
|
|
61
|
+
process.stderr.write(`Unknown command: ${command}\n`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
} catch (err) {
|
|
65
|
+
process.stderr.write(`Error: ${err.message}\n`);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
@@ -50,7 +50,8 @@ description: 只读环境检查:插件闭包完整性、Node/CLI 可用性、d
|
|
|
50
50
|
|
|
51
51
|
**输出**:
|
|
52
52
|
- 可用 → `PASS: artifact-graph CLI 可用`
|
|
53
|
-
- 不可用 → `FAIL: artifact-graph CLI
|
|
53
|
+
- 不可用 → `FAIL: artifact-graph CLI 未找到`,读取插件根 `compatibility.json` 的
|
|
54
|
+
`artifactGraph.installSpec`,附加 `pnpm add -D <installSpec>` 精确修复建议;不得手写或猜测版本
|
|
54
55
|
|
|
55
56
|
### 4. Doctor 诊断
|
|
56
57
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "artifact-chain-assistant",
|
|
3
3
|
"displayName": "Artifact Chain Assistant",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.3",
|
|
5
5
|
"description": "Artifact-chain intake, review/repair/batch/audit workflows, diagnostics, and version-lock maintenance helpers.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Artifact Graph Maintainers"
|
|
@@ -16,7 +16,7 @@ instructions.
|
|
|
16
16
|
## Prerequisites
|
|
17
17
|
|
|
18
18
|
- Node.js `>=22.0.0`.
|
|
19
|
-
- `artifact-graph` 0.8.
|
|
19
|
+
- `artifact-graph` 0.8.3 installed in the target project.
|
|
20
20
|
- **GitHub SSH key** — Claude Code clones `source: github` entries over SSH by default. If you
|
|
21
21
|
have not configured a GitHub SSH key, set `CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1` in your shell
|
|
22
22
|
profile, or add the marketplace with an explicit `https://` URL. Codex users can check
|
|
@@ -28,24 +28,24 @@ instructions.
|
|
|
28
28
|
|
|
29
29
|
| Plugin | Verified Runtime | Install |
|
|
30
30
|
| --- | --- | --- |
|
|
31
|
-
| `artifact-chain-assistant` 0.8.
|
|
31
|
+
| `artifact-chain-assistant` 0.8.3 | `artifact-graph` 0.8.3 | `pnpm add -D artifact-graph@0.8.3` |
|
|
32
32
|
|
|
33
33
|
### Install The Runtime
|
|
34
34
|
|
|
35
35
|
The default installation path uses the npm registry with a precise version:
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
pnpm add -D artifact-graph@0.8.
|
|
38
|
+
pnpm add -D artifact-graph@0.8.3
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
If the npm registry is unavailable, use the explicit GitHub fallback pinned to the verified tag:
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
-
pnpm add -D github:ifoohoo/artifact-graph#artifact-graph-v0.8.
|
|
44
|
+
pnpm add -D github:ifoohoo/artifact-graph#artifact-graph-v0.8.3
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
> **Never** install with an unlocked range (`artifact-graph`, `artifact-graph@latest`,
|
|
48
|
-
> `artifact-graph@^0.8.
|
|
48
|
+
> `artifact-graph@^0.8.3`) or an unpinned GitHub URL (`github:ifoohoo/artifact-graph`).
|
|
49
49
|
> Unlocked installs produce non-reproducible dependency trees and break version-lock audit.
|
|
50
50
|
|
|
51
51
|
With pnpm 10+, projects that install `artifact-graph` must allow the native `better-sqlite3`
|
|
@@ -72,7 +72,7 @@ allowBuilds:
|
|
|
72
72
|
|
|
73
73
|
The plugin's `doctor` command validates the installed runtime version before running any
|
|
74
74
|
diagnostic. If it detects a version mismatch or missing CLI, it reports the exact remediation
|
|
75
|
-
command (`pnpm add -D artifact-graph@0.8.
|
|
75
|
+
command (`pnpm add -D artifact-graph@0.8.3`) and exits non-zero.
|
|
76
76
|
|
|
77
77
|
### CLI Resolution Order
|
|
78
78
|
|
|
@@ -147,7 +147,7 @@ wrappers, and Stop-hook guardrail. These assistant controls do not replace Git h
|
|
|
147
147
|
|
|
148
148
|
> **Marketplace note**: `ifoohoo/artifact-skill-set` is an external independent marketplace. The
|
|
149
149
|
> plugin payload is still published from `ifoohoo/artifact-chain-assistant`. The marketplace entry
|
|
150
|
-
> must publish and enable `artifact-chain-assistant` 0.8.
|
|
150
|
+
> must publish and enable `artifact-chain-assistant` 0.8.3 before the install commands above will
|
|
151
151
|
> succeed.
|
|
152
152
|
|
|
153
153
|
## Post-Installation Discovery
|
|
@@ -197,7 +197,7 @@ The plugin should not move these files into the plugin repository.
|
|
|
197
197
|
|
|
198
198
|
For a first-time setup, the end-to-end sequence is:
|
|
199
199
|
|
|
200
|
-
1. **Install the CLI** — `pnpm add -D artifact-graph@0.8.
|
|
200
|
+
1. **Install the CLI** — `pnpm add -D artifact-graph@0.8.3` (see Prerequisites above).
|
|
201
201
|
2. **Install the plugin** — follow the Codex or Claude Code section above.
|
|
202
202
|
3. **Run bootstrap** — ask the assistant to use the `artifact-chain-bootstrap` skill (see prompt
|
|
203
203
|
below). The skill will:
|
|
@@ -995,7 +995,7 @@ with append-only behavior; it does not overwrite local rules.
|
|
|
995
995
|
### Recovery Steps
|
|
996
996
|
|
|
997
997
|
```bash
|
|
998
|
-
# 1. Install dependencies from lockfile (gets artifact-graph@0.8.
|
|
998
|
+
# 1. Install dependencies from lockfile (gets artifact-graph@0.8.3)
|
|
999
999
|
pnpm install --frozen-lockfile
|
|
1000
1000
|
|
|
1001
1001
|
# 2. Install plugin per your host (Codex / Claude Code)
|
|
@@ -1062,7 +1062,7 @@ pnpm exec artifact-graph hooks install-git --hook all
|
|
|
1062
1062
|
### Enterprise Mirror
|
|
1063
1063
|
|
|
1064
1064
|
If the corporate environment cannot access the public npm registry or GitHub, mirror both
|
|
1065
|
-
`artifact-graph@0.8.
|
|
1065
|
+
`artifact-graph@0.8.3` and the plugin marketplace repository on an internal registry. The mirror
|
|
1066
1066
|
does not change the state ownership model: Git-tracked files remain authoritative, local caches
|
|
1067
1067
|
remain derived.
|
|
1068
1068
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "1.0",
|
|
3
|
-
"pluginVersion": "0.8.
|
|
3
|
+
"pluginVersion": "0.8.3",
|
|
4
4
|
"artifactGraph": {
|
|
5
|
-
"verifiedVersion": "0.8.
|
|
6
|
-
"installSpec": "artifact-graph@0.8.
|
|
7
|
-
"githubFallbackSpec": "github:ifoohoo/artifact-graph#artifact-graph-v0.8.
|
|
5
|
+
"verifiedVersion": "0.8.3",
|
|
6
|
+
"installSpec": "artifact-graph@0.8.3",
|
|
7
|
+
"githubFallbackSpec": "github:ifoohoo/artifact-graph#artifact-graph-v0.8.3"
|
|
8
8
|
}
|
|
9
9
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
schemaVersion: 1
|
|
2
|
+
familyImplementationId: com.github.mzdbxqh.prd-feature
|
|
3
|
+
version: "0.6.1"
|
|
4
|
+
targetApiStatus: pending
|
|
5
|
+
lifecycle:
|
|
6
|
+
ownership: bundled
|
|
7
|
+
maturity: stable
|
|
8
|
+
channel: stable
|
|
9
|
+
hostSupport:
|
|
10
|
+
codex:
|
|
11
|
+
skillPath: skills/prd-feature
|
|
12
|
+
available: true
|
|
13
|
+
claude:
|
|
14
|
+
skillPath: skills/prd-feature
|
|
15
|
+
available: true
|
|
16
|
+
bundleRoots:
|
|
17
|
+
- skills-src/prd-feature
|
|
18
|
+
services:
|
|
19
|
+
artifact.prd-feature.default:
|
|
20
|
+
skill: prd-feature
|
|
21
|
+
summary: "PRD feature default route entry"
|
|
22
|
+
artifact.prd-feature.author:
|
|
23
|
+
skill: prd-feature/author
|
|
24
|
+
summary: "PRD feature authoring entry"
|
|
25
|
+
artifact.prd-feature.review:
|
|
26
|
+
skill: prd-feature/review
|
|
27
|
+
summary: "PRD feature review entry"
|
|
28
|
+
artifact.prd-feature.repair:
|
|
29
|
+
skill: prd-feature/repair
|
|
30
|
+
summary: "PRD feature repair entry"
|
|
31
|
+
conformance:
|
|
32
|
+
deterministicAttestation: null
|
|
33
|
+
behaviorQualification: null
|
|
34
|
+
pendingApiStatus:
|
|
35
|
+
hasPublishedFamilyApi: false
|
|
36
|
+
reason: "No formal Family API published for prd-feature; migration sample only"
|
|
37
|
+
missingContracts:
|
|
38
|
+
- "artifact.prd-feature@1 (Artifact Contract not yet published)"
|
|
39
|
+
notes: "Migration sample for bundled prd-feature family. No published Family API exists yet; targetApiStatus: pending. This descriptor does not claim Family API conformance. It records current bundled service mappings for future registry v2 migration."
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
schemaVersion: 1
|
|
2
|
+
familyImplementationId: com.github.mzdbxqh.scenario-script
|
|
3
|
+
version: "0.6.1"
|
|
4
|
+
targetApiStatus: pending
|
|
5
|
+
lifecycle:
|
|
6
|
+
ownership: bundled
|
|
7
|
+
maturity: stable
|
|
8
|
+
channel: stable
|
|
9
|
+
hostSupport:
|
|
10
|
+
codex:
|
|
11
|
+
skillPath: skills/scenario-script
|
|
12
|
+
available: true
|
|
13
|
+
claude:
|
|
14
|
+
skillPath: skills/scenario-script
|
|
15
|
+
available: true
|
|
16
|
+
bundleRoots:
|
|
17
|
+
- skills-src/scenario-script
|
|
18
|
+
services:
|
|
19
|
+
artifact.scenario-script.default:
|
|
20
|
+
skill: scenario-script
|
|
21
|
+
summary: "Scenario script default route entry"
|
|
22
|
+
artifact.scenario-script.author:
|
|
23
|
+
skill: scenario-script/author
|
|
24
|
+
summary: "Scenario script authoring entry"
|
|
25
|
+
artifact.scenario-script.review:
|
|
26
|
+
skill: scenario-script/review
|
|
27
|
+
summary: "Scenario script review entry"
|
|
28
|
+
artifact.scenario-script.repair:
|
|
29
|
+
skill: scenario-script/repair
|
|
30
|
+
summary: "Scenario script repair entry"
|
|
31
|
+
conformance:
|
|
32
|
+
deterministicAttestation: null
|
|
33
|
+
behaviorQualification: null
|
|
34
|
+
pendingApiStatus:
|
|
35
|
+
hasPublishedFamilyApi: false
|
|
36
|
+
reason: "No formal Family API published for scenario-script; migration sample only"
|
|
37
|
+
missingContracts:
|
|
38
|
+
- "artifact.scenario-script@1 (Artifact Contract not yet published)"
|
|
39
|
+
notes: "Migration sample for bundled scenario-script family. No published Family API exists yet; targetApiStatus: pending. This descriptor does not claim Family API conformance. It records current bundled service mappings for future registry v2 migration."
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"catalog": {
|
|
4
|
+
"id": "artifact-chain-assistant",
|
|
5
|
+
"version": "0.8.3"
|
|
6
|
+
},
|
|
7
|
+
"families": [
|
|
8
|
+
{
|
|
9
|
+
"id": "artifact.e2e-test-family",
|
|
10
|
+
"major": 1,
|
|
11
|
+
"apiPath": "e2e-test/api.json",
|
|
12
|
+
"revisionDigest": "sha256:66cdd1098a93eb8d128c57010a9405dd1de55bee1e702ced44a93c202cc4b463",
|
|
13
|
+
"summary": "Standard E2E test skill family for authoring, reviewing, and repairing E2E test specifications"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"api": {
|
|
4
|
+
"id": "artifact.e2e-test-family",
|
|
5
|
+
"major": 1,
|
|
6
|
+
"revisionDigest": "sha256:66cdd1098a93eb8d128c57010a9405dd1de55bee1e702ced44a93c202cc4b463",
|
|
7
|
+
"displayName": "E2E Test Skill Family",
|
|
8
|
+
"summary": "Standard skill family for authoring, reviewing, and repairing E2E test specification artifacts",
|
|
9
|
+
"artifactTypes": [
|
|
10
|
+
"e2e-test"
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
"services": [
|
|
14
|
+
{
|
|
15
|
+
"id": "artifact.e2e-test.default",
|
|
16
|
+
"required": true,
|
|
17
|
+
"kind": "workflow",
|
|
18
|
+
"intents": [
|
|
19
|
+
"route"
|
|
20
|
+
],
|
|
21
|
+
"accepts": [
|
|
22
|
+
"User request or intent to work with E2E test specifications"
|
|
23
|
+
],
|
|
24
|
+
"produces": [
|
|
25
|
+
"Routed to appropriate E2E test service"
|
|
26
|
+
],
|
|
27
|
+
"sideEffectCeiling": "read-only",
|
|
28
|
+
"mixSafe": false,
|
|
29
|
+
"discoverable": {
|
|
30
|
+
"default": true
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "artifact.e2e-test.help",
|
|
35
|
+
"required": true,
|
|
36
|
+
"kind": "operation",
|
|
37
|
+
"intents": [
|
|
38
|
+
"help"
|
|
39
|
+
],
|
|
40
|
+
"accepts": [
|
|
41
|
+
"Help request for E2E test capabilities"
|
|
42
|
+
],
|
|
43
|
+
"produces": [
|
|
44
|
+
"Capability overview and adoption guidance"
|
|
45
|
+
],
|
|
46
|
+
"sideEffectCeiling": "read-only",
|
|
47
|
+
"mixSafe": false,
|
|
48
|
+
"discoverable": {
|
|
49
|
+
"help": true
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"id": "artifact.e2e-test.author",
|
|
54
|
+
"required": true,
|
|
55
|
+
"kind": "workflow",
|
|
56
|
+
"intents": [
|
|
57
|
+
"author"
|
|
58
|
+
],
|
|
59
|
+
"accepts": [
|
|
60
|
+
{
|
|
61
|
+
"protocol": "prd-feature-input",
|
|
62
|
+
"version": "1.0",
|
|
63
|
+
"input": "PRD feature artifact or user intent for E2E test authoring"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"protocol": "scenario-script-input",
|
|
67
|
+
"version": "1.0",
|
|
68
|
+
"input": "Scenario script artifact providing E2E test context"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"protocol": "e2e-raw-input-envelope",
|
|
72
|
+
"version": "1.0",
|
|
73
|
+
"input": "schemas/author-raw-input.json"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"protocol": "e2e-stage-resume",
|
|
77
|
+
"version": "1.0",
|
|
78
|
+
"input": "inputs.{inspection,assessment,matrix} resume with source and digest revalidation"
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
"produces": [
|
|
82
|
+
"artifact.e2e-test@1",
|
|
83
|
+
{
|
|
84
|
+
"protocol": "preview-manifest-v1.0",
|
|
85
|
+
"version": "1.0",
|
|
86
|
+
"input": "schemas/preview-manifest.json"
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
"sideEffectCeiling": "write-authorized-artifacts",
|
|
90
|
+
"mixSafe": false,
|
|
91
|
+
"modes": {
|
|
92
|
+
"supported": ["preview", "commit"],
|
|
93
|
+
"default": "preview"
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": "artifact.e2e-test.review",
|
|
98
|
+
"required": true,
|
|
99
|
+
"kind": "operation",
|
|
100
|
+
"intents": [
|
|
101
|
+
"review"
|
|
102
|
+
],
|
|
103
|
+
"accepts": [
|
|
104
|
+
"artifact.e2e-test@1"
|
|
105
|
+
],
|
|
106
|
+
"produces": [
|
|
107
|
+
{
|
|
108
|
+
"protocol": "review-result-v1.0",
|
|
109
|
+
"version": "1.0",
|
|
110
|
+
"input": "Review Result Protocol v1.0 JSON object"
|
|
111
|
+
}
|
|
112
|
+
],
|
|
113
|
+
"sideEffectCeiling": "write-review-result",
|
|
114
|
+
"mixSafe": false
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"id": "artifact.e2e-test.repair",
|
|
118
|
+
"required": true,
|
|
119
|
+
"kind": "workflow",
|
|
120
|
+
"intents": [
|
|
121
|
+
"repair"
|
|
122
|
+
],
|
|
123
|
+
"accepts": [
|
|
124
|
+
{
|
|
125
|
+
"protocol": "review-result-v1.0",
|
|
126
|
+
"version": "1.0",
|
|
127
|
+
"input": "Review Result Protocol v1.0 JSON with open findings"
|
|
128
|
+
},
|
|
129
|
+
"artifact.e2e-test@1"
|
|
130
|
+
],
|
|
131
|
+
"produces": [
|
|
132
|
+
"artifact.e2e-test@1",
|
|
133
|
+
{
|
|
134
|
+
"protocol": "preview-manifest-v1.0",
|
|
135
|
+
"version": "1.0",
|
|
136
|
+
"input": "schemas/preview-manifest.json"
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
"sideEffectCeiling": "write-authorized-artifacts",
|
|
140
|
+
"mixSafe": false,
|
|
141
|
+
"modes": {
|
|
142
|
+
"supported": ["preview", "commit"],
|
|
143
|
+
"default": "preview"
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
"capabilities": [
|
|
148
|
+
{
|
|
149
|
+
"id": "e2e-candidate-assessment",
|
|
150
|
+
"summary": "Risk-driven E2E candidate path identification from PRD and scenario artifacts"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"id": "e2e-matrix-design",
|
|
154
|
+
"summary": "Eight-dimensional E2E test case design model"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"id": "e2e-proof-reconciliation",
|
|
158
|
+
"summary": "Traceability from test specification through implementation to execution evidence"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"id": "e2e-finding-capability-manifest",
|
|
162
|
+
"summary": "Machine-readable E2E-F-001..012 capability states with stable blockers"
|
|
163
|
+
}
|
|
164
|
+
],
|
|
165
|
+
"dataTransferObjects": [
|
|
166
|
+
{
|
|
167
|
+
"id": "e2e-test-matrix",
|
|
168
|
+
"schemaId": "e2e-test/matrix/v1",
|
|
169
|
+
"schema": "schemas/matrix.json",
|
|
170
|
+
"version": "1.0",
|
|
171
|
+
"digestRule": "stableDigest(canonicalize key-sorted JSON) -> sha256:<64hex>",
|
|
172
|
+
"services": [
|
|
173
|
+
{ "service": "artifact.e2e-test.author", "position": "intermediate-output (run root)" },
|
|
174
|
+
{ "service": "artifact.e2e-test.review", "position": "intermediate-input (cross-validation)" },
|
|
175
|
+
{ "service": "artifact.e2e-test.repair", "position": "intermediate-input" }
|
|
176
|
+
],
|
|
177
|
+
"artifactBinding": "E2E artifact package manifest binds the minimal artifact and authoritative matrix by relative references and content digests"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"id": "e2e-finding-capability-manifest",
|
|
181
|
+
"schemaId": "e2e-test/finding-capability-manifest/v1",
|
|
182
|
+
"schema": "schemas/finding-capability-manifest.json",
|
|
183
|
+
"version": "1.0",
|
|
184
|
+
"digestRule": "stableDigest(rules) -> sha256:<64hex>",
|
|
185
|
+
"services": []
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"id": "e2e-artifact-package-manifest",
|
|
189
|
+
"schemaId": "e2e-test/artifact-package-manifest/v1",
|
|
190
|
+
"schema": "schemas/artifact-package-manifest.json",
|
|
191
|
+
"version": "1.0",
|
|
192
|
+
"digestRule": "stableDigest(manifest excluding packageDigest) -> sha256:<64hex>",
|
|
193
|
+
"services": [
|
|
194
|
+
{ "service": "artifact.e2e-test.author", "position": "formal-output" },
|
|
195
|
+
{ "service": "artifact.e2e-test.review", "position": "required-input" },
|
|
196
|
+
{ "service": "artifact.e2e-test.repair", "position": "required-input-and-output" }
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
],
|
|
200
|
+
"qualificationKinds": [
|
|
201
|
+
"operationalQualification",
|
|
202
|
+
"methodForwardQualification",
|
|
203
|
+
"releaseArtifactCertification"
|
|
204
|
+
]
|
|
205
|
+
}
|