create-agdf 0.1.8 → 0.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
@@ -1,6 +1,6 @@
1
1
  # create-agdf
2
2
 
3
- Bootstrap AGDF repository instructions for one repository.
3
+ Bootstrap AGDF repository instructions and a machine-checkable control loop for one repository.
4
4
 
5
5
  ## Usage
6
6
 
@@ -10,6 +10,7 @@ npm create agdf@latest copilot
10
10
  npm create agdf@latest both
11
11
  npm create agdf@latest init
12
12
  npm create agdf@latest doctor
13
+ npm create agdf@latest gate-check
13
14
  ```
14
15
 
15
16
  Optional flags:
@@ -62,6 +63,17 @@ npm create agdf@latest doctor --json
62
63
 
63
64
  The doctor reports missing live control files, missing current gate, missing next allowed action, empty evidence, empty backlog pointer, empty source-of-truth registry, duplicate active SoT rows and invalid quality contracts. It exits non-zero only for blocking control failures.
64
65
 
66
+ Use `gate-check` to derive the next process decision from the doctor result and `AGDF_RUN.md`:
67
+
68
+ ```bash
69
+ npm create agdf@latest gate-check
70
+ npm create agdf@latest gate-check --json
71
+ ```
72
+
73
+ The gate check reports `open | blocked`, the current gate, blocking reason, missing exact approval, allowed outputs, forbidden outputs, next allowed action, evidence references and the embedded doctor report.
74
+
75
+ Together, `init`, `doctor` and `gate-check --json` turn AGDF from an instruction layer into a repository control system: the agent can be guided by rules, and the repository state can be checked before the next governed step.
76
+
65
77
  ## Single source of truth
66
78
 
67
79
  The repository-facing AGDF sources are maintained in:
@@ -11,8 +11,9 @@ const generatedRoot = join(packageRoot, "generated");
11
11
  const pluginDefinitionPath = join(generatedRoot, "plugins", "agdf", "meta", "agdf-plugin.definition.json");
12
12
  const pluginDefinition = JSON.parse(readFileSync(pluginDefinitionPath, "utf8"));
13
13
  const pluginInstallCommand = "claude plugin add arndtgold/ai-native-governance-delivery-framework";
14
- const allowedTargets = new Set(["codex", "copilot", "both", "init", "doctor"]);
14
+ const allowedTargets = new Set(["codex", "copilot", "both", "init", "doctor", "gate-check"]);
15
15
  const agdfFragmentPath = "AGENTS.agdf.md";
16
+ const userGateOrder = ["UR", "PRD", "SD", "TP", "QA", "UAT"];
16
17
  const codexSkillNames = pluginDefinition.skillSet.map((skill) => `${pluginDefinition.codex.skillPrefix}${skill.slug}`);
17
18
  const copilotSkillNames = pluginDefinition.skillSet.map((skill) => `${pluginDefinition.copilot.skillPrefix}${skill.slug}`);
18
19
  const codexPluginFiles = [
@@ -89,11 +90,12 @@ Usage:
89
90
  npm create agdf@latest both
90
91
  npm create agdf@latest init
91
92
  npm create agdf@latest doctor
93
+ npm create agdf@latest gate-check
92
94
 
93
95
  Options:
94
96
  --dir <path> Write files into a specific directory
95
97
  --force Overwrite existing generated files
96
- --json Print doctor output as JSON
98
+ --json Print doctor or gate-check output as JSON
97
99
  --help Show this help
98
100
  `);
99
101
  }
@@ -156,7 +158,7 @@ function parseArgs(argv) {
156
158
  }
157
159
 
158
160
  if (!target || !allowedTargets.has(target)) {
159
- console.error("Please choose one target: codex, copilot, both, init or doctor.");
161
+ console.error("Please choose one target: codex, copilot, both, init, doctor or gate-check.");
160
162
  printUsage();
161
163
  process.exit(1);
162
164
  }
@@ -517,6 +519,163 @@ function printDoctorReport(report, json) {
517
519
  }
518
520
  }
519
521
 
522
+ function extractField(content, field) {
523
+ const pattern = new RegExp(`^- ${field}:[^\\S\\r\\n]*(.*)$`, "m");
524
+ return content.match(pattern)?.[1]?.trim() ?? "";
525
+ }
526
+
527
+ function cleanStatusCell(value) {
528
+ return value.replace(/^`|`$/g, "").trim();
529
+ }
530
+
531
+ function readRunState(targetDir) {
532
+ const runPath = join(".agdf", "control", "AGDF_RUN.md");
533
+ if (!existsSync(join(targetDir, runPath))) {
534
+ return {
535
+ path: runPath,
536
+ content: "",
537
+ current_gate: "",
538
+ next_allowed_action: "",
539
+ approvals: new Map(),
540
+ evidence_refs: [],
541
+ };
542
+ }
543
+
544
+ const content = readTargetFile(targetDir, runPath);
545
+ const approvalsSection = content.match(/## Approvals([\s\S]*?)(?:\n## |\n# |$)/)?.[1] ?? "";
546
+ const approvals = new Map();
547
+ for (const cells of tableRows(approvalsSection)) {
548
+ const [gate, status, evidence] = cells;
549
+ if (!userGateOrder.includes(gate)) continue;
550
+ approvals.set(gate, {
551
+ status: cleanStatusCell(status ?? ""),
552
+ evidence: evidence ?? "",
553
+ });
554
+ }
555
+
556
+ const evidenceSection = content.match(/## Evidence([\s\S]*?)(?:\n## |\n# |$)/)?.[1] ?? "";
557
+ const evidence_refs = tableRows(evidenceSection)
558
+ .filter((cells) => cells[0] !== "Evidence")
559
+ .filter((cells) => Boolean(cells[0] || cells[1] || cells[2]))
560
+ .map((cells) => ({
561
+ evidence: cells[0] ?? "",
562
+ source: cells[1] ?? "",
563
+ covers: cells[2] ?? "",
564
+ strength: cleanStatusCell(cells[3] ?? ""),
565
+ }));
566
+
567
+ return {
568
+ path: runPath,
569
+ content,
570
+ current_gate: extractField(content, "current_gate"),
571
+ next_allowed_action: extractField(content, "next_allowed_action"),
572
+ approvals,
573
+ evidence_refs,
574
+ };
575
+ }
576
+
577
+ function firstUnapprovedGate(approvals) {
578
+ for (const gate of userGateOrder) {
579
+ const status = approvals.get(gate)?.status ?? "";
580
+ if (status !== "approved" && status !== "not_applicable") return gate;
581
+ }
582
+ return "OR";
583
+ }
584
+
585
+ function normalizeCurrentGate(value, fallbackGate) {
586
+ if (isPlaceholderValue(value)) return fallbackGate;
587
+ const normalized = value.replace(/`/g, "").trim();
588
+ return normalized || fallbackGate;
589
+ }
590
+
591
+ function gateApprovalStatus(runState, gate) {
592
+ if (!userGateOrder.includes(gate)) return "not_applicable";
593
+ return runState.approvals.get(gate)?.status ?? "";
594
+ }
595
+
596
+ function evaluateGateCheck(targetDir) {
597
+ const doctorReport = evaluateDoctor(targetDir);
598
+ const runState = readRunState(targetDir);
599
+ const fallbackGate = firstUnapprovedGate(runState.approvals);
600
+ const currentGate = normalizeCurrentGate(runState.current_gate, fallbackGate);
601
+ const currentApprovalStatus = gateApprovalStatus(runState, currentGate);
602
+ const doctorBlocker = doctorReport.findings.find((finding) => finding.severity === "block");
603
+ const doctorRevise = doctorReport.findings.find((finding) => finding.severity === "revise");
604
+
605
+ let status = "open";
606
+ let blockingReason = "none";
607
+ let missingApproval = "none";
608
+ let allowed = [
609
+ "continue with the documented next allowed action",
610
+ "update evidence when new facts are observed",
611
+ "run doctor or gate-check again after control changes",
612
+ ];
613
+ let forbidden = [
614
+ "bypass the documented gate state",
615
+ "treat warnings as resolved without evidence",
616
+ ];
617
+ let nextAllowedAction = isPlaceholderValue(runState.next_allowed_action)
618
+ ? "Continue with the current documented gate only after setting next_allowed_action."
619
+ : runState.next_allowed_action;
620
+
621
+ if (doctorBlocker) {
622
+ status = "blocked";
623
+ blockingReason = doctorBlocker.code;
624
+ allowed = ["repair the AGDF control scaffold", "run doctor again"];
625
+ forbidden = ["continue governed delivery", "create later-gate artefacts", "implement gated work"];
626
+ nextAllowedAction = doctorBlocker.next_step;
627
+ } else if (doctorRevise) {
628
+ status = "blocked";
629
+ blockingReason = doctorRevise.code;
630
+ allowed = ["repair the incomplete control state", "run doctor again"];
631
+ forbidden = ["continue governed delivery", "create later-gate artefacts", "implement gated work"];
632
+ nextAllowedAction = doctorRevise.next_step;
633
+ } else if (userGateOrder.includes(currentGate) && currentApprovalStatus !== "approved" && currentApprovalStatus !== "not_applicable") {
634
+ status = "blocked";
635
+ blockingReason = "missing_exact_approval";
636
+ missingApproval = `Approval: ${currentGate}`;
637
+ allowed = ["clarify the current gate", "record evidence", "write OR-lite status", "request exact approval"];
638
+ forbidden = ["create later-gate artefacts", "implement gated work", "mark QA or UAT as passed"];
639
+ nextAllowedAction = `Request exact approval: Approval: ${currentGate}`;
640
+ }
641
+
642
+ return {
643
+ schema_version: "1",
644
+ status,
645
+ current_gate: currentGate,
646
+ blocking_reason: blockingReason,
647
+ missing_approval: missingApproval,
648
+ allowed,
649
+ forbidden,
650
+ next_allowed_action: nextAllowedAction,
651
+ doctor_status: doctorReport.status,
652
+ doctor_summary: doctorReport.summary,
653
+ evidence_refs: runState.evidence_refs,
654
+ doctor_report: doctorReport,
655
+ };
656
+ }
657
+
658
+ function printGateCheckReport(report, json) {
659
+ if (json) {
660
+ console.log(JSON.stringify(report, null, 2));
661
+ return;
662
+ }
663
+
664
+ console.log(`AGDF gate-check: ${report.status}`);
665
+ console.log(`Current gate: ${report.current_gate}`);
666
+ console.log(`Blocking reason: ${report.blocking_reason}`);
667
+ console.log(`Missing approval: ${report.missing_approval}`);
668
+ console.log(`Doctor: ${report.doctor_status} (${report.doctor_summary.findings} findings)`);
669
+ console.log("");
670
+ console.log("Allowed:");
671
+ for (const item of report.allowed) console.log(`- ${item}`);
672
+ console.log("");
673
+ console.log("Forbidden:");
674
+ for (const item of report.forbidden) console.log(`- ${item}`);
675
+ console.log("");
676
+ console.log(`Next allowed action: ${report.next_allowed_action}`);
677
+ }
678
+
520
679
  function main() {
521
680
  const options = parseArgs(process.argv.slice(2));
522
681
 
@@ -526,6 +685,12 @@ function main() {
526
685
  process.exit(report.status === "block" ? 2 : 0);
527
686
  }
528
687
 
688
+ if (options.target === "gate-check") {
689
+ const report = evaluateGateCheck(options.dir);
690
+ printGateCheckReport(report, options.json);
691
+ process.exit(report.status === "blocked" ? 2 : 0);
692
+ }
693
+
529
694
  const files = generatedFilesForTarget(options.target, options.dir, options.force);
530
695
  const wroteAgentsFragment = files.some(file => file.path === agdfFragmentPath);
531
696
 
@@ -39,9 +39,11 @@ Then check whether the live state is actionable:
39
39
  ```bash
40
40
  npm create agdf@latest doctor
41
41
  npm create agdf@latest doctor --json
42
+ npm create agdf@latest gate-check --json
42
43
  ```
43
44
 
44
45
  `doctor` does not replace agent judgment. It catches basic control failures: missing live files, missing current gate, missing next allowed action, empty evidence, empty backlog pointer, empty source-of-truth registry, duplicate active SoT rows and invalid quality contracts.
46
+ `gate-check` consumes the doctor result and live run state to report whether the next process step is `open` or `blocked`.
45
47
 
46
48
  ## Operating Rules
47
49
 
@@ -20,6 +20,19 @@ This skill must not create later artefacts such as PRD, SD, TP, CD, CR, QA, or U
20
20
  ## Runtime Contract
21
21
  Use `../agdf-runtime-contract.md` for gate terms, closeout discipline, and non-duplication rules.
22
22
 
23
+ ## Machine-Readable Control Path
24
+
25
+ When the target repository contains live AGDF control files, prefer the executable control path before deriving a gate decision manually:
26
+
27
+ ```bash
28
+ npm create agdf@latest doctor --json
29
+ npm create agdf@latest gate-check --json
30
+ ```
31
+
32
+ `doctor` checks whether `.agdf/control/` is actionable. `agdf-gate-check` consumes that result and `AGDF_RUN.md` to report the operative process decision: `open | blocked`, current gate, blocking reason, missing approval, allowed outputs, forbidden outputs, next allowed action and evidence references.
33
+
34
+ The CLI report is evidence for this skill, not a second rule system. If the report says `blocked`, do not continue with later-gate artefacts until the reported blocker is resolved.
35
+
23
36
  ## Rules
24
37
  1. Fail closed when a required approval or artefact status is missing.
25
38
  2. The earliest blocking gate wins.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agdf",
3
- "version": "0.1.8",
3
+ "version": "0.2.0",
4
4
  "description": "Codex-first workflow skills for gated, auditable AI-assisted software delivery.",
5
5
  "author": {
6
6
  "name": "AI-native Governance & Delivery Framework",
@@ -15,7 +15,7 @@
15
15
  "interface": {
16
16
  "displayName": "AI Governance & Delivery Framework",
17
17
  "shortDescription": "Codex-first workflow skills for gated, auditable AI-assisted delivery.",
18
- "longDescription": "AI Governance & Delivery Framework (AGDF) packages reusable Codex-first skills and control templates for gate checks, Brownfield analysis, task-plan review, solution-integrity review, QA decisions, durable run state and auditable delivery closeout.",
18
+ "longDescription": "AI Governance & Delivery Framework (AGDF) packages reusable Codex-first skills, control templates and machine-readable repository checks for gate decisions, Brownfield analysis, task-plan review, solution-integrity review, QA decisions, durable run state and auditable delivery closeout.",
19
19
  "developerName": "AI-native Governance & Delivery Framework",
20
20
  "category": "Productivity",
21
21
  "capabilities": ["Read", "Write"],
@@ -39,9 +39,11 @@ Then check whether the live state is actionable:
39
39
  ```bash
40
40
  npm create agdf@latest doctor
41
41
  npm create agdf@latest doctor --json
42
+ npm create agdf@latest gate-check --json
42
43
  ```
43
44
 
44
45
  `doctor` does not replace agent judgment. It catches basic control failures: missing live files, missing current gate, missing next allowed action, empty evidence, empty backlog pointer, empty source-of-truth registry, duplicate active SoT rows and invalid quality contracts.
46
+ `gate-check` consumes the doctor result and live run state to report whether the next process step is `open` or `blocked`.
45
47
 
46
48
  ## Operating Rules
47
49
 
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "id": "agdf",
4
- "version": "0.1.8",
4
+ "version": "0.2.0",
5
5
  "displayName": "AI Governance & Delivery Framework",
6
6
  "developerName": "AI-native Governance & Delivery Framework",
7
7
  "description": "Codex-first workflow skills for gated, auditable AI-assisted software delivery.",
8
8
  "claudeDescription": "Codex-first workflow skills and control templates for gated, auditable AI-assisted software delivery.",
9
9
  "shortDescription": "Codex-first workflow skills for gated, auditable AI-assisted delivery.",
10
- "longDescription": "AI Governance & Delivery Framework (AGDF) packages reusable Codex-first skills and control templates for gate checks, Brownfield analysis, task-plan review, solution-integrity review, QA decisions, durable run state and auditable delivery closeout.",
10
+ "longDescription": "AI Governance & Delivery Framework (AGDF) packages reusable Codex-first skills, control templates and machine-readable repository checks for gate decisions, Brownfield analysis, task-plan review, solution-integrity review, QA decisions, durable run state and auditable delivery closeout.",
11
11
  "homepage": "https://agdf.iself.eu",
12
12
  "repository": "https://github.com/arndtgold/ai-native-governance-delivery-framework",
13
13
  "license": "Apache-2.0",
@@ -20,6 +20,19 @@ This skill must not create later artefacts such as PRD, SD, TP, CD, CR, QA, or U
20
20
  ## Runtime Contract
21
21
  Use `../../meta/agdf-runtime-contract.md` for gate terms, closeout discipline, and non-duplication rules.
22
22
 
23
+ ## Machine-Readable Control Path
24
+
25
+ When the target repository contains live AGDF control files, prefer the executable control path before deriving a gate decision manually:
26
+
27
+ ```bash
28
+ npm create agdf@latest doctor --json
29
+ npm create agdf@latest gate-check --json
30
+ ```
31
+
32
+ `doctor` checks whether `.agdf/control/` is actionable. `gate-check` consumes that result and `AGDF_RUN.md` to report the operative process decision: `open | blocked`, current gate, blocking reason, missing approval, allowed outputs, forbidden outputs, next allowed action and evidence references.
33
+
34
+ The CLI report is evidence for this skill, not a second rule system. If the report says `blocked`, do not continue with later-gate artefacts until the reported blocker is resolved.
35
+
23
36
  ## Rules
24
37
  1. Fail closed when a required approval or artefact status is missing.
25
38
  2. The earliest blocking gate wins.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-agdf",
3
- "version": "0.1.8",
4
- "description": "Bootstrap AGDF repository-local Codex plugin marketplaces, Copilot instructions, skills and control templates.",
3
+ "version": "0.2.0",
4
+ "description": "Bootstrap AGDF repository-local plugin files, Copilot instructions, skills, control files and machine-readable checks.",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "bin",