create-agdf 0.14.1 → 0.14.2
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 +8 -2
- package/generated/plugins/agdf/.claude-plugin/plugin.json +1 -1
- package/generated/plugins/agdf/.codex-plugin/plugin.json +1 -1
- package/generated/plugins/agdf/meta/agdf-plugin.definition.json +6 -1
- package/generated/plugins/agdf/meta/copilot-payload-baseline.json +7 -0
- package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/agdf-plugin.definition.json +6 -1
- package/generated/plugins/agdf/runtime/create-agdf/lib/runtime/local-validator.js +29 -17
- package/generated/plugins/agdf/runtime/create-agdf/lib/runtime/plugin-provenance.js +50 -1
- package/generated/plugins/agdf/runtime/create-agdf/package.json +1 -1
- package/generated/plugins/agdf/runtime/runtime-manifest.json +2 -2
- package/generated/plugins/agdf/scripts/check-runtime-integrity.mjs +2 -1
- package/generated/plugins/agdf/submission/openai/availability.md +1 -1
- package/generated/plugins/agdf/submission/openai/capability-matrix.json +1 -1
- package/generated/plugins/agdf/submission/openai/release-notes.md +1 -1
- package/generated/plugins/agdf/submission/openai/reviewer-cases.json +1 -1
- package/generated/plugins/copilot/agdf/.agdf-payload-inventory.json +771 -0
- package/generated/plugins/copilot/agdf/LICENSE +201 -0
- package/generated/plugins/copilot/agdf/meta/agdf-agent-router.md +129 -0
- package/generated/plugins/copilot/agdf/meta/agdf-constitution.md +329 -0
- package/generated/plugins/copilot/agdf/meta/agdf-plugin.definition.json +331 -0
- package/generated/plugins/copilot/agdf/meta/agdf-runtime-contract.md +16 -0
- package/generated/plugins/{agdf → copilot/agdf}/plugin.json +1 -1
- package/generated/plugins/copilot/agdf/runtime/agdf-local.js +18 -0
- package/generated/plugins/copilot/agdf/runtime/agdf-session-check.js +97 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/NOTICE +10 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/bin/agdf-validator.js +11 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/generated/plugins/agdf/meta/agdf-interaction-locales.json +512 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/generated/plugins/agdf/meta/agdf-plugin.definition.json +331 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/cli/command-registry.js +144 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/cli/delivery-path-search-command.js +139 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/cli/parse-args.js +173 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/cli/runtime-context.js +83 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/cli/validation-handlers.js +46 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-evaluation/delivery-map.js +301 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-evaluation/doctor.js +272 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-evaluation/gate-check.js +455 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-evaluation/gate-policy.js +305 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-evaluation/parent-reconciliation.js +284 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-evaluation/required-files.js +9 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-evaluation/run-state.js +217 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-evaluation/shared.js +345 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-evaluation/verified-change.js +156 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-state/aggregate.js +18 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-state/gate-approval-validator.js +49 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-state/index.js +7 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-state/legacy-migration.js +95 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-state/run-state-parser.js +265 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-state/run-state-repository.js +68 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-state/run-state-resolver.js +45 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-state/run-state-writer.js +97 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/delivery-path-search/candidate-policy.js +99 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/delivery-path-search/contracts.js +237 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/delivery-path-search/evaluators/claude.js +35 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/delivery-path-search/evaluators/codex.js +44 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/delivery-path-search/evaluators/opencode.js +234 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/delivery-path-search/evaluators/prompt.js +13 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/delivery-path-search/evaluators/protocol.js +13 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/delivery-path-search/generators/claude.js +40 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/delivery-path-search/generators/codex.js +38 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/delivery-path-search/generators/protocol.js +12 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/delivery-path-search/persistence.js +39 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/delivery-path-search/scoring.js +21 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/delivery-path-search/search-engine.js +155 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/delivery-path-search/state-adapter.js +161 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/delivery-path-search/surfaces/capabilities.js +27 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/delivery-path-search/transports/read-only-guard.js +43 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/interaction-presentation.js +842 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/runtime/local-validator.js +239 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/runtime/plugin-provenance.js +255 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/runtime/validator-application.js +40 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/runtime-check-consent/contract.js +73 -0
- package/generated/plugins/copilot/agdf/runtime/create-agdf/package.json +6 -0
- package/generated/plugins/copilot/agdf/runtime/runtime-manifest.json +8 -0
- package/generated/submissions/openai/agdf/.codex-plugin/plugin.json +1 -1
- package/generated/submissions/openai/agdf/meta/agdf-plugin.definition.json +6 -1
- package/generated/submissions/openai/agdf/meta/copilot-payload-baseline.json +7 -0
- package/generated/submissions/openai/agdf/submission/openai/availability.md +1 -1
- package/generated/submissions/openai/agdf/submission/openai/capability-matrix.json +1 -1
- package/generated/submissions/openai/agdf/submission/openai/inventory.json +13 -9
- package/generated/submissions/openai/agdf/submission/openai/listing.json +1 -1
- package/generated/submissions/openai/agdf/submission/openai/readiness.json +2 -2
- package/generated/submissions/openai/agdf/submission/openai/readiness.md +2 -2
- package/generated/submissions/openai/agdf/submission/openai/release-notes.md +1 -1
- package/generated/submissions/openai/agdf/submission/openai/reviewer-cases.json +1 -1
- package/lib/installers/local-marketplace.js +112 -30
- package/lib/installers/plugin-installers.js +45 -9
- package/lib/public-plugin/copilot-profile.js +126 -0
- package/lib/release/version-coherence.js +4 -1
- package/lib/runtime/local-validator.js +29 -17
- package/lib/runtime/plugin-provenance.js +50 -1
- package/package.json +3 -2
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/agdf-brownfield-analysis/SKILL.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/agdf-clean-implementation-review/SKILL.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/agdf-code-review/SKILL.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/agdf-delivery-closeout/SKILL.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/agdf-delivery-path-search/SKILL.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/agdf-gate-check/SKILL.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/agdf-interaction-locales.json +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/agdf-qa-gate/SKILL.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/agdf-release-or/SKILL.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/agdf-runtime-contract.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/agdf-task-plan-review/SKILL.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/agdf-ux-intent-definition/SKILL.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/contracts/closeout.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/contracts/context-graph.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/contracts/control-scaffold.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/contracts/gate-transition.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/contracts/interaction.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/contracts/modes.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/contracts/quality.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/copilot-skills/contracts/task-target-resolution.md +0 -0
- /package/generated/plugins/{agdf → copilot/agdf}/hooks/copilot-hooks.json +0 -0
package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-evaluation/gate-policy.js
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { extractField, verifiedChangeEscalationTargets } from './verified-change.js';
|
|
2
|
+
import { gateApprovalStatus, gateArtefactStatus, isDurableGateArtefactSatisfied, isInternalStepSatisfied, modeSliceDecision } from './run-state.js';
|
|
3
|
+
|
|
4
|
+
function durableArtefactBlock(gate, nextGate) {
|
|
5
|
+
const label = gate === "QA" ? "QA report" : `${gate} artefact`;
|
|
6
|
+
const stablePath = gate === "QA" ? ".agdf/control/artefacts/<key>/QA_REPORT.md" : `.agdf/control/artefacts/<key>/${gate}.md`;
|
|
7
|
+
return {
|
|
8
|
+
status: "blocked",
|
|
9
|
+
current_gate: gate,
|
|
10
|
+
blocking_reason: `missing_durable_${gate.toLowerCase()}_artefact`,
|
|
11
|
+
missing_approval: "none",
|
|
12
|
+
allowed: [
|
|
13
|
+
`persist the approved ${label} in a stable artefact path such as ${stablePath}`,
|
|
14
|
+
"link the artefact from the selected RUN_STATE.md and MASTER_BACKLOG.md",
|
|
15
|
+
"run gate-check again",
|
|
16
|
+
],
|
|
17
|
+
forbidden: nextGate
|
|
18
|
+
? [`create ${nextGate}`, "create later-gate artefacts", "implement gated work", "claim QA or release readiness"]
|
|
19
|
+
: ["create later-gate artefacts", "implement gated work", "claim release readiness"],
|
|
20
|
+
next_allowed_action: `Persist the approved ${label} and link it from the AGDF control state before continuing.`,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function isGateSatisfied(runState, gate) {
|
|
25
|
+
const status = gateApprovalStatus(runState, gate);
|
|
26
|
+
if (status === "not_applicable") return true;
|
|
27
|
+
if (status !== "approved") return false;
|
|
28
|
+
if (gate === "UAT") return true;
|
|
29
|
+
return isDurableGateArtefactSatisfied(runState, gate);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function qaNonPassDecision(runState) {
|
|
33
|
+
const status = gateArtefactStatus(runState, "QA").status;
|
|
34
|
+
return status === "revise" || status === "block" ? status : null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function transitionDecisionForRunState(runState, verifiedChange = null) {
|
|
38
|
+
if (gateApprovalStatus(runState, "UR") === "approved" && !isGateSatisfied(runState, "UR")) return durableArtefactBlock("UR", "PRD");
|
|
39
|
+
|
|
40
|
+
if (!isGateSatisfied(runState, "UR")) {
|
|
41
|
+
return {
|
|
42
|
+
status: "open",
|
|
43
|
+
current_gate: "UR",
|
|
44
|
+
blocking_reason: "none",
|
|
45
|
+
missing_approval: "Approval: UR",
|
|
46
|
+
allowed: ["clarify user need", "formulate and persist UR", "record evidence", "request exact UR approval"],
|
|
47
|
+
forbidden: ["create PRD", "create SD", "create TP", "run Brownfield Analysis", "implement code", "claim QA or release readiness"],
|
|
48
|
+
next_allowed_action: "Clarify the user requirement, persist the UR, and request exact approval: Approval: UR",
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (gateApprovalStatus(runState, "PRD") === "approved" && !isGateSatisfied(runState, "PRD")) return durableArtefactBlock("PRD", "SD");
|
|
53
|
+
|
|
54
|
+
if (!isGateSatisfied(runState, "PRD")) {
|
|
55
|
+
if (!isInternalStepSatisfied(runState, "Brownfield Review")) {
|
|
56
|
+
return {
|
|
57
|
+
status: "open",
|
|
58
|
+
current_gate: "Brownfield Review",
|
|
59
|
+
blocking_reason: "none",
|
|
60
|
+
missing_approval: "none",
|
|
61
|
+
allowed: [
|
|
62
|
+
"run Brownfield Review after G-00",
|
|
63
|
+
"identify existing workstream, owners, SoT, reuse risks and open PRD/SD questions",
|
|
64
|
+
"mark Brownfield Review as done or not_applicable in the selected RUN_STATE.md",
|
|
65
|
+
],
|
|
66
|
+
forbidden: ["create PRD before Brownfield Review is resolved", "create SD", "create TP", "implement code", "claim QA or release readiness"],
|
|
67
|
+
next_allowed_action: "Run Brownfield Review after G-00 before drafting PRD, or mark Brownfield Review not_applicable with evidence.",
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const modeDecision = modeSliceDecision(runState);
|
|
72
|
+
if (modeDecision === "undecided") {
|
|
73
|
+
return {
|
|
74
|
+
status: "open",
|
|
75
|
+
current_gate: "Mode/Slice Decision",
|
|
76
|
+
blocking_reason: "none",
|
|
77
|
+
missing_approval: "none",
|
|
78
|
+
allowed: [
|
|
79
|
+
"decide whether the approved UR is quick_task, verified_change, structured_slice, structured_delivery or block",
|
|
80
|
+
"record scope reason, evidence and required next gate depth in the selected RUN_STATE.md",
|
|
81
|
+
"choose the next required gate depth before drafting PRD or implementing",
|
|
82
|
+
],
|
|
83
|
+
forbidden: ["create PRD before process size is decided", "create SD", "create TP", "implement code", "claim QA or release readiness"],
|
|
84
|
+
next_allowed_action: "Record the Mode/Slice Decision from Brownfield Review with scope reason and evidence before choosing PRD depth or Quick Task execution.",
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (modeDecision === "block") {
|
|
89
|
+
return {
|
|
90
|
+
status: "blocked",
|
|
91
|
+
current_gate: "Mode/Slice Decision",
|
|
92
|
+
blocking_reason: "mode_slice_decision_blocked",
|
|
93
|
+
missing_approval: "none",
|
|
94
|
+
allowed: ["resolve ownership, SoT, evidence, impact or product-direction uncertainty", "run gate-check again"],
|
|
95
|
+
forbidden: ["create PRD", "create SD", "create TP", "implement code", "claim QA or release readiness"],
|
|
96
|
+
next_allowed_action: "Resolve the Brownfield Review blocker before choosing a delivery path.",
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (modeDecision === "quick_task") {
|
|
101
|
+
if (
|
|
102
|
+
extractField(runState.content ?? "", "lifecycle") === "completed"
|
|
103
|
+
&& runState.current_gate === "OR"
|
|
104
|
+
&& runState.artefacts.get("OR")?.status === "done"
|
|
105
|
+
) {
|
|
106
|
+
return {
|
|
107
|
+
status: "pass",
|
|
108
|
+
current_gate: "OR",
|
|
109
|
+
blocking_reason: "none",
|
|
110
|
+
missing_approval: "none",
|
|
111
|
+
allowed: ["use delivery closeout when explicitly requested"],
|
|
112
|
+
forbidden: ["repeat Quick Task execution", "commit, push, open PR or release automatically"],
|
|
113
|
+
next_allowed_action: "Use delivery closeout only when an operative VCS handoff is explicitly requested.",
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
status: "open",
|
|
118
|
+
current_gate: "Quick Task Execution",
|
|
119
|
+
blocking_reason: "none",
|
|
120
|
+
missing_approval: "none",
|
|
121
|
+
allowed: ["implement the narrow approved UR scope", "run relevant checks", "record evidence and close with OR-lite"],
|
|
122
|
+
forbidden: ["expand scope beyond the Brownfield Review decision", "create broad PRD/SD/TP artefacts by ritual", "claim QA or release readiness without evidence"],
|
|
123
|
+
next_allowed_action: "Proceed as a Quick Task within the Brownfield Review scope and record verification evidence.",
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (modeDecision === "verified_change") {
|
|
128
|
+
const state = verifiedChange?.status ?? "missing";
|
|
129
|
+
const escalationTarget = verifiedChange?.escalation_target ?? "structured_slice";
|
|
130
|
+
if (state === "executed") {
|
|
131
|
+
return {
|
|
132
|
+
status: "open",
|
|
133
|
+
current_gate: "OR",
|
|
134
|
+
blocking_reason: "none",
|
|
135
|
+
missing_approval: "none",
|
|
136
|
+
allowed: ["use the Verified Change mini-closeout", "offer delivery closeout when requested"],
|
|
137
|
+
forbidden: ["create PRD, SD, TP, QA or UAT by ritual", "commit, push, open PR or release automatically"],
|
|
138
|
+
next_allowed_action: "Close the executed Verified Change with its compact record and offer delivery closeout; do not perform VCS actions automatically.",
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
if (state === "escalated" || (state === "invalid" && verifiedChangeEscalationTargets.has(escalationTarget))) {
|
|
142
|
+
return {
|
|
143
|
+
status: "open",
|
|
144
|
+
current_gate: "PRD",
|
|
145
|
+
blocking_reason: state === "escalated" ? "verified_change_escalated" : "verified_change_invalid_escalated",
|
|
146
|
+
missing_approval: "Approval: PRD",
|
|
147
|
+
allowed: ["draft the structured PRD required by the declared escalation target", "retain the Verified Change escalation evidence"],
|
|
148
|
+
forbidden: ["implement through Verified Change", "create SD or TP before PRD approval", "claim QA or release readiness"],
|
|
149
|
+
next_allowed_action: `Proceed as ${escalationTarget}: draft the required PRD and request exact approval: Approval: PRD.`,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
if (state === "eligible") {
|
|
153
|
+
return {
|
|
154
|
+
status: "open",
|
|
155
|
+
current_gate: "Verified Change Execution",
|
|
156
|
+
blocking_reason: "none",
|
|
157
|
+
missing_approval: "none",
|
|
158
|
+
allowed: ["implement only declared source and derived paths", "run declared propagation and validation commands", "record execution evidence and mini-closeout"],
|
|
159
|
+
forbidden: ["touch unlisted paths", "add prohibited impacts", "claim QA, UAT or release readiness"],
|
|
160
|
+
next_allowed_action: "Implement only the eligible Verified Change record scope, then record passing propagation and validation evidence.",
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
status: state === "missing" || state === "draft" ? "open" : "blocked",
|
|
165
|
+
current_gate: "Verified Change Execution",
|
|
166
|
+
blocking_reason: state === "invalid" ? "verified_change_invalid" : "verified_change_record_required",
|
|
167
|
+
missing_approval: "none",
|
|
168
|
+
allowed: ["create or refine the compact Verified Change record", "capture baseline paths", "prove fail-closed eligibility with doctor and gate-check"],
|
|
169
|
+
forbidden: ["implement candidate changes", "claim validation, QA, UAT or release readiness"],
|
|
170
|
+
next_allowed_action: "Create or repair VERIFIED_CHANGE.md, capture the baseline and satisfy every eligibility check before implementation; escalate when any condition cannot be proven.",
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
status: "open",
|
|
176
|
+
current_gate: "PRD",
|
|
177
|
+
blocking_reason: "none",
|
|
178
|
+
missing_approval: "Approval: PRD",
|
|
179
|
+
allowed: ["draft or refine PRD", "define scope", "define acceptance criteria", "define non-goals", "request exact PRD approval"],
|
|
180
|
+
forbidden: ["create SD", "create TP", "run Brownfield Analysis as implementation preparation", "implement code", "claim QA or release readiness"],
|
|
181
|
+
next_allowed_action: modeDecision === "structured_slice"
|
|
182
|
+
? "Draft or refine the smallest PRD slice justified by Brownfield Review; do not implement before required artefacts are approved."
|
|
183
|
+
: "Draft or refine the PRD; do not implement before PRD, SD and TP are approved.",
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (gateApprovalStatus(runState, "SD") === "approved" && !isGateSatisfied(runState, "SD")) return durableArtefactBlock("SD", "TP");
|
|
188
|
+
|
|
189
|
+
if (!isGateSatisfied(runState, "SD")) {
|
|
190
|
+
return {
|
|
191
|
+
status: "open",
|
|
192
|
+
current_gate: "SD",
|
|
193
|
+
blocking_reason: "none",
|
|
194
|
+
missing_approval: "Approval: SD",
|
|
195
|
+
allowed: ["draft or refine Solution Design", "define architecture", "define ownership", "request exact SD approval"],
|
|
196
|
+
forbidden: ["create TP", "implement code", "claim QA or release readiness"],
|
|
197
|
+
next_allowed_action: "Draft or refine the Solution Design; do not implement before SD and TP are approved.",
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (gateApprovalStatus(runState, "TP") === "approved" && !isGateSatisfied(runState, "TP")) return durableArtefactBlock("TP", "Brownfield Analysis");
|
|
202
|
+
|
|
203
|
+
if (!isGateSatisfied(runState, "TP")) {
|
|
204
|
+
return {
|
|
205
|
+
status: "open",
|
|
206
|
+
current_gate: "TP",
|
|
207
|
+
blocking_reason: "none",
|
|
208
|
+
missing_approval: "Approval: TP",
|
|
209
|
+
allowed: ["draft or refine Task/Test Plan", "define task IDs", "define test evidence", "request exact TP approval"],
|
|
210
|
+
forbidden: ["implement code", "claim QA or release readiness"],
|
|
211
|
+
next_allowed_action: "Draft or refine the Task/Test Plan; do not implement before TP is approved.",
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const implementationStepsRequired = gateApprovalStatus(runState, "TP") === "approved";
|
|
216
|
+
if (implementationStepsRequired && !isInternalStepSatisfied(runState, "Brownfield Analysis")) {
|
|
217
|
+
return {
|
|
218
|
+
status: "open",
|
|
219
|
+
current_gate: "Brownfield Analysis",
|
|
220
|
+
blocking_reason: "none",
|
|
221
|
+
missing_approval: "none",
|
|
222
|
+
allowed: ["run Brownfield Analysis for the approved TP scope", "verify existing owners, reuse paths and regression risks"],
|
|
223
|
+
forbidden: ["implement before Brownfield evidence supports the approved TP path", "claim QA or release readiness"],
|
|
224
|
+
next_allowed_action: "Run Brownfield Analysis for the approved TP scope before CD+Tests.",
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (implementationStepsRequired && !isInternalStepSatisfied(runState, "CD+Tests")) {
|
|
229
|
+
return {
|
|
230
|
+
status: "open",
|
|
231
|
+
current_gate: "CD+Tests",
|
|
232
|
+
blocking_reason: "none",
|
|
233
|
+
missing_approval: "none",
|
|
234
|
+
allowed: ["implement the approved TP tasks", "run the approved test plan", "record implementation and test evidence"],
|
|
235
|
+
forbidden: ["claim QA pass", "request UAT approval", "release"],
|
|
236
|
+
next_allowed_action: "Implement the approved TP scope, run its tests, and record CD+Tests evidence before CR.",
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (implementationStepsRequired && !isInternalStepSatisfied(runState, "CR")) {
|
|
241
|
+
return {
|
|
242
|
+
status: "open",
|
|
243
|
+
current_gate: "CR",
|
|
244
|
+
blocking_reason: "none",
|
|
245
|
+
missing_approval: "none",
|
|
246
|
+
allowed: ["run mandatory code review", "record correctness, regression, security and maintainability findings", "fix blocking review findings"],
|
|
247
|
+
forbidden: ["claim QA pass", "request UAT approval", "release"],
|
|
248
|
+
next_allowed_action: "Run Code Review for the implemented TP scope and resolve blocking findings before QA.",
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const qaNonPass = qaNonPassDecision(runState);
|
|
253
|
+
if (qaNonPass) {
|
|
254
|
+
const blocked = qaNonPass === "block";
|
|
255
|
+
return {
|
|
256
|
+
status: blocked ? "blocked" : "open",
|
|
257
|
+
current_gate: "QA",
|
|
258
|
+
blocking_reason: blocked ? "qa_blocked" : "qa_revise_required",
|
|
259
|
+
missing_approval: "none",
|
|
260
|
+
allowed: blocked
|
|
261
|
+
? ["route the blocking QA findings to their authoritative owner", "record the next permitted remediation or upstream decision", "rerun QA only after the blocker is resolved"]
|
|
262
|
+
: ["revise the implementation against the QA findings", "refresh CD+Tests and mandatory reviews", "rerun QA with refreshed evidence"],
|
|
263
|
+
forbidden: ["request QA approval", "request UAT approval", "release", "claim delivery readiness"],
|
|
264
|
+
next_allowed_action: blocked
|
|
265
|
+
? "Resolve or route the blocking QA findings through their authoritative owner, then rerun the required delivery steps. Do not request Approval: QA from a block report."
|
|
266
|
+
: "Resolve the QA revise findings, refresh CD+Tests and reviews, then rerun QA. Do not request Approval: QA from a revise report.",
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (gateApprovalStatus(runState, "QA") === "approved" && !isGateSatisfied(runState, "QA")) return durableArtefactBlock("QA", "UAT");
|
|
271
|
+
|
|
272
|
+
if (isGateSatisfied(runState, "QA") && !isGateSatisfied(runState, "UAT")) {
|
|
273
|
+
return {
|
|
274
|
+
status: "open",
|
|
275
|
+
current_gate: "UAT",
|
|
276
|
+
blocking_reason: "none",
|
|
277
|
+
missing_approval: "Approval: UAT",
|
|
278
|
+
allowed: ["request exact UAT approval", "prepare non-operative delivery summary"],
|
|
279
|
+
forbidden: ["release", "push", "open PR", "commit without explicit user instruction and required approval"],
|
|
280
|
+
next_allowed_action: "Request exact approval: Approval: UAT before delivery handoff.",
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (isGateSatisfied(runState, "UAT")) {
|
|
285
|
+
return {
|
|
286
|
+
status: "open",
|
|
287
|
+
current_gate: "OR",
|
|
288
|
+
blocking_reason: "none",
|
|
289
|
+
missing_approval: "none",
|
|
290
|
+
allowed: ["produce OR or delivery closeout", "prepare commit, push or PR handoff when requested"],
|
|
291
|
+
forbidden: ["commit, push, open PR or release automatically"],
|
|
292
|
+
next_allowed_action: "Produce delivery closeout or requested handoff; do not perform VCS actions automatically.",
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return {
|
|
297
|
+
status: "open",
|
|
298
|
+
current_gate: "QA",
|
|
299
|
+
blocking_reason: "none",
|
|
300
|
+
missing_approval: "Approval: QA",
|
|
301
|
+
allowed: ["run QA gate", "persist or refine the QA report", "request exact QA approval"],
|
|
302
|
+
forbidden: ["request UAT approval", "release", "claim delivery readiness before QA approval and report evidence"],
|
|
303
|
+
next_allowed_action: "Run the QA gate, persist the QA report, and request exact approval: Approval: QA",
|
|
304
|
+
};
|
|
305
|
+
}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { RUN_ID_PATTERN } from "../control-state/run-state-parser.js";
|
|
2
|
+
|
|
3
|
+
const parentPrefix = "parent_run:";
|
|
4
|
+
const childPrefix = "child_run:";
|
|
5
|
+
|
|
6
|
+
function filled(value) {
|
|
7
|
+
const text = String(value ?? "").trim();
|
|
8
|
+
return Boolean(text && text !== "none" && !text.includes("<"));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function exactTarget(value, prefix) {
|
|
12
|
+
const text = String(value ?? "").trim();
|
|
13
|
+
if (!text.startsWith(prefix)) return "";
|
|
14
|
+
const runId = text.slice(prefix.length);
|
|
15
|
+
return RUN_ID_PATTERN.test(runId) && `${prefix}${runId}` === text ? runId : "";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function warning(runState, code, message, nextStep) {
|
|
19
|
+
return {
|
|
20
|
+
severity: "warn",
|
|
21
|
+
code,
|
|
22
|
+
message,
|
|
23
|
+
path: runState.path,
|
|
24
|
+
next_step: nextStep,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function invalidDispositionInput(runState) {
|
|
29
|
+
const input = runState.parent_reconciliation ?? {};
|
|
30
|
+
if (!input.present) return false;
|
|
31
|
+
const counts = input.field_counts ?? {};
|
|
32
|
+
return counts.disposition !== 1
|
|
33
|
+
|| counts.next_action !== 1
|
|
34
|
+
|| !["action_required", "accepted_open"].includes(input.disposition)
|
|
35
|
+
|| !filled(input.next_action);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function openResult(runState, {
|
|
39
|
+
code = "AGDF_PARENT_RECONCILIATION_OPEN",
|
|
40
|
+
targetRunId = "",
|
|
41
|
+
evidence = "",
|
|
42
|
+
missingEvidence,
|
|
43
|
+
nextAction,
|
|
44
|
+
} = {}) {
|
|
45
|
+
const input = runState.parent_reconciliation ?? {};
|
|
46
|
+
const fieldCounts = input.field_counts ?? {};
|
|
47
|
+
const validDisposition = ["action_required", "accepted_open"].includes(input.disposition)
|
|
48
|
+
&& fieldCounts.disposition === 1;
|
|
49
|
+
const validNextAction = filled(input.next_action) && fieldCounts.next_action === 1;
|
|
50
|
+
const declaredInputInvalid = input.present && (!validDisposition || !validNextAction);
|
|
51
|
+
const action = declaredInputInvalid ? nextAction : validNextAction ? input.next_action : nextAction;
|
|
52
|
+
const finalCode = declaredInputInvalid
|
|
53
|
+
? "AGDF_PARENT_RECONCILIATION_EVIDENCE_INVALID"
|
|
54
|
+
: code;
|
|
55
|
+
return {
|
|
56
|
+
result: {
|
|
57
|
+
outcome: "open",
|
|
58
|
+
target_run_id: targetRunId,
|
|
59
|
+
disposition: validDisposition ? input.disposition : "action_required",
|
|
60
|
+
evidence,
|
|
61
|
+
missing_evidence: missingEvidence,
|
|
62
|
+
next_action: action,
|
|
63
|
+
},
|
|
64
|
+
findings: [warning(
|
|
65
|
+
runState,
|
|
66
|
+
finalCode,
|
|
67
|
+
targetRunId
|
|
68
|
+
? `Child ${runState.run_id || "run"} has an open reconciliation handoff to Parent ${targetRunId}.`
|
|
69
|
+
: `Child ${runState.run_id || "run"} has invalid or ambiguous explicit Parent relationship evidence.`,
|
|
70
|
+
action,
|
|
71
|
+
)],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function evaluateParentReconciliation(runState, { loadRun } = {}) {
|
|
76
|
+
const rows = runState.artefact_chain.filter((row) =>
|
|
77
|
+
row.from === "OR" && row.relationship === "reconciles_with"
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
if (!rows.length) {
|
|
81
|
+
return {
|
|
82
|
+
result: {
|
|
83
|
+
outcome: "not_applicable",
|
|
84
|
+
target_run_id: "",
|
|
85
|
+
disposition: "not_applicable",
|
|
86
|
+
evidence: "",
|
|
87
|
+
missing_evidence: "none",
|
|
88
|
+
next_action: "none",
|
|
89
|
+
},
|
|
90
|
+
findings: [],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (rows.length !== 1) {
|
|
95
|
+
return openResult(runState, {
|
|
96
|
+
code: "AGDF_PARENT_RECONCILIATION_EVIDENCE_INVALID",
|
|
97
|
+
missingEvidence: "Exactly one explicit Parent relationship is required.",
|
|
98
|
+
nextAction: "Retain exactly one evidenced OR reconciles_with parent_run:<run_id> relationship.",
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (invalidDispositionInput(runState)) {
|
|
103
|
+
return openResult(runState, {
|
|
104
|
+
code: "AGDF_PARENT_RECONCILIATION_EVIDENCE_INVALID",
|
|
105
|
+
missingEvidence: "The Parent reconciliation disposition or next action is invalid or duplicated.",
|
|
106
|
+
nextAction: "Record one valid disposition and exactly one concrete Parent reconciliation next action.",
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const row = rows[0];
|
|
111
|
+
const parentRunId = exactTarget(row.to, parentPrefix);
|
|
112
|
+
if (!parentRunId || parentRunId === runState.run_id || !filled(row.evidence)) {
|
|
113
|
+
return openResult(runState, {
|
|
114
|
+
code: "AGDF_PARENT_RECONCILIATION_EVIDENCE_INVALID",
|
|
115
|
+
targetRunId: parentRunId,
|
|
116
|
+
evidence: row.evidence,
|
|
117
|
+
missingEvidence: "The Parent run ID and concrete relationship evidence must be valid and unambiguous.",
|
|
118
|
+
nextAction: "Repair the explicit OR reconciles_with parent_run:<run_id> row and its evidence.",
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
let parent;
|
|
123
|
+
try {
|
|
124
|
+
parent = loadRun?.(parentRunId);
|
|
125
|
+
} catch {
|
|
126
|
+
parent = null;
|
|
127
|
+
}
|
|
128
|
+
if (!parent?.content || parent.resolution_error) {
|
|
129
|
+
return openResult(runState, {
|
|
130
|
+
targetRunId: parentRunId,
|
|
131
|
+
evidence: row.evidence,
|
|
132
|
+
missingEvidence: "The named Parent run is unavailable.",
|
|
133
|
+
nextAction: `Restore or select Parent run ${parentRunId}, then re-run Delivery Map.`,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const reciprocalRows = parent.artefact_chain.filter((candidate) =>
|
|
138
|
+
candidate.from === "Aggregate"
|
|
139
|
+
&& candidate.relationship === "includes"
|
|
140
|
+
&& candidate.to === `${childPrefix}${runState.run_id}`
|
|
141
|
+
);
|
|
142
|
+
if (reciprocalRows.length !== 1 || !filled(reciprocalRows[0]?.evidence)) {
|
|
143
|
+
return openResult(runState, {
|
|
144
|
+
targetRunId: parentRunId,
|
|
145
|
+
evidence: row.evidence,
|
|
146
|
+
missingEvidence: reciprocalRows.length > 1
|
|
147
|
+
? "The Parent contains ambiguous reciprocal Child relationships."
|
|
148
|
+
: "The Parent lacks one evidenced reciprocal Aggregate includes Child relationship.",
|
|
149
|
+
nextAction: `Reconcile Child ${runState.run_id} in Parent ${parentRunId} through the Parent's governed scope.`,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
result: {
|
|
155
|
+
outcome: "resolved",
|
|
156
|
+
target_run_id: parentRunId,
|
|
157
|
+
disposition: "not_applicable",
|
|
158
|
+
evidence: reciprocalRows[0].evidence,
|
|
159
|
+
missing_evidence: "none",
|
|
160
|
+
next_action: "none",
|
|
161
|
+
},
|
|
162
|
+
findings: [],
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function completedChild(runState, resolveFile) {
|
|
167
|
+
const orArtefact = runState?.artefacts?.get("OR");
|
|
168
|
+
return Boolean(
|
|
169
|
+
runState?.content
|
|
170
|
+
&& orArtefact?.status === "done"
|
|
171
|
+
&& filled(orArtefact.path)
|
|
172
|
+
&& resolveFile?.(orArtefact.path),
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function evaluateProgrammeAggregation(runState, { loadRun, resolveFile } = {}) {
|
|
177
|
+
const rows = runState.artefact_chain.filter((row) =>
|
|
178
|
+
row.from === "Aggregate" && row.relationship === "includes"
|
|
179
|
+
);
|
|
180
|
+
const input = runState.programme_aggregation ?? {};
|
|
181
|
+
const explicitInput = filled(input.acceptance_ref)
|
|
182
|
+
|| filled(input.evidence)
|
|
183
|
+
|| (Boolean(input.missing_evidence) && input.missing_evidence !== "none");
|
|
184
|
+
const applicable = explicitInput || rows.length > 0;
|
|
185
|
+
if (!applicable) {
|
|
186
|
+
return {
|
|
187
|
+
result: {
|
|
188
|
+
applicable: false,
|
|
189
|
+
startable: false,
|
|
190
|
+
final_ready: false,
|
|
191
|
+
acceptance_ref: "",
|
|
192
|
+
evidence: [],
|
|
193
|
+
missing_evidence: [],
|
|
194
|
+
next_action: "none",
|
|
195
|
+
},
|
|
196
|
+
findings: [],
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const invalidRows = [];
|
|
201
|
+
const seenChildRunIds = new Set();
|
|
202
|
+
for (const row of rows) {
|
|
203
|
+
const childRunId = exactTarget(row.to, childPrefix);
|
|
204
|
+
if (!childRunId || !filled(row.evidence) || seenChildRunIds.has(childRunId)) invalidRows.push(row);
|
|
205
|
+
else seenChildRunIds.add(childRunId);
|
|
206
|
+
}
|
|
207
|
+
const completedEvidence = [];
|
|
208
|
+
for (const row of rows) {
|
|
209
|
+
const childRunId = exactTarget(row.to, childPrefix);
|
|
210
|
+
if (!childRunId || !filled(row.evidence)) continue;
|
|
211
|
+
let child;
|
|
212
|
+
try {
|
|
213
|
+
child = loadRun?.(childRunId);
|
|
214
|
+
} catch {
|
|
215
|
+
child = null;
|
|
216
|
+
}
|
|
217
|
+
if (completedChild(child, resolveFile)) completedEvidence.push({ child_run_id: childRunId, evidence: row.evidence });
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const fieldCounts = input.field_counts ?? {};
|
|
221
|
+
const acceptanceRefValid = fieldCounts.acceptance_ref === 1
|
|
222
|
+
&& filled(input.acceptance_ref)
|
|
223
|
+
&& input.acceptance_ref.startsWith(".agdf/control/artefacts/")
|
|
224
|
+
&& Boolean(resolveFile?.(input.acceptance_ref));
|
|
225
|
+
const missingEvidenceValid = fieldCounts.missing_evidence === 1
|
|
226
|
+
&& input.missing_evidence === "none";
|
|
227
|
+
const evidenceFieldValid = fieldCounts.evidence === 1 && filled(input.evidence);
|
|
228
|
+
const startable = completedEvidence.length > 0;
|
|
229
|
+
const finalReady = startable && acceptanceRefValid && missingEvidenceValid && evidenceFieldValid && invalidRows.length === 0;
|
|
230
|
+
const missingEvidence = [];
|
|
231
|
+
if (!startable) missingEvidence.push("No evidenced included Child has a completed OR.");
|
|
232
|
+
if (!acceptanceRefValid) missingEvidence.push("The declared programme acceptance artefact is missing or invalid.");
|
|
233
|
+
if (!evidenceFieldValid) missingEvidence.push("Programme aggregation evidence is missing or invalid.");
|
|
234
|
+
if (!missingEvidenceValid) missingEvidence.push(input.missing_evidence || "Programme missing-evidence state is not resolved.");
|
|
235
|
+
if (invalidRows.length) missingEvidence.push("One or more Aggregate includes Child rows are invalid.");
|
|
236
|
+
const nextAction = !startable
|
|
237
|
+
? "Link at least one evidenced completed Child OR in the Parent Artefact Chain."
|
|
238
|
+
: !acceptanceRefValid
|
|
239
|
+
? "Provide one valid repository-relative programme acceptance artefact reference."
|
|
240
|
+
: !evidenceFieldValid || !missingEvidenceValid
|
|
241
|
+
? "Resolve the declared programme evidence gaps before final readiness."
|
|
242
|
+
: invalidRows.length
|
|
243
|
+
? "Repair invalid Aggregate includes child_run:<run_id> rows."
|
|
244
|
+
: "none";
|
|
245
|
+
const findings = [];
|
|
246
|
+
if (invalidRows.length) {
|
|
247
|
+
findings.push(warning(
|
|
248
|
+
runState,
|
|
249
|
+
"AGDF_PROGRAMME_AGGREGATION_EVIDENCE_INVALID",
|
|
250
|
+
"Programme aggregation contains invalid explicit Child evidence.",
|
|
251
|
+
nextAction,
|
|
252
|
+
));
|
|
253
|
+
}
|
|
254
|
+
if (!finalReady) {
|
|
255
|
+
findings.push(warning(
|
|
256
|
+
runState,
|
|
257
|
+
"AGDF_PROGRAMME_AGGREGATION_NOT_FINAL",
|
|
258
|
+
`Programme aggregation for ${runState.run_id || "run"} is ${startable ? "startable but not final-ready" : "not startable"}.`,
|
|
259
|
+
nextAction,
|
|
260
|
+
));
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
result: {
|
|
264
|
+
applicable: true,
|
|
265
|
+
startable,
|
|
266
|
+
final_ready: finalReady,
|
|
267
|
+
acceptance_ref: input.acceptance_ref,
|
|
268
|
+
evidence: completedEvidence,
|
|
269
|
+
missing_evidence: missingEvidence,
|
|
270
|
+
next_action: nextAction,
|
|
271
|
+
},
|
|
272
|
+
findings,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export function evaluateReconciliationState(runState, dependencies = {}) {
|
|
277
|
+
const parent = evaluateParentReconciliation(runState, dependencies);
|
|
278
|
+
const programme = evaluateProgrammeAggregation(runState, dependencies);
|
|
279
|
+
return {
|
|
280
|
+
parent_reconciliation: parent.result,
|
|
281
|
+
programme_aggregation: programme.result,
|
|
282
|
+
findings: [...parent.findings, ...programme.findings],
|
|
283
|
+
};
|
|
284
|
+
}
|
package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/control-evaluation/required-files.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
|
|
3
|
+
export const doctorRequiredFiles = Object.freeze([
|
|
4
|
+
join(".agdf", "control", "AGDF_RUN.md"),
|
|
5
|
+
join(".agdf", "control", "MASTER_BACKLOG.md"),
|
|
6
|
+
join(".agdf", "control", "SOT_REGISTRY.md"),
|
|
7
|
+
join(".agdf", "control", "CONTEXT_GRAPH.md"),
|
|
8
|
+
join(".agdf", "control", "AGENT_QUALITY_CONTRACTS.json"),
|
|
9
|
+
]);
|