@pieai/doc-gov 0.5.4 → 0.7.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/cli-guide.md +3 -2
- package/dist/cli.js +123 -39
- package/package.json +1 -1
package/cli-guide.md
CHANGED
|
@@ -56,8 +56,9 @@ pnpm doc-gov migrate --profile doc-only --check
|
|
|
56
56
|
`docs/governance/agents-routing/`, and `profiles/` stay connected in the
|
|
57
57
|
expected order.
|
|
58
58
|
- In a downstream project, it verifies the project router block,
|
|
59
|
-
`docs/governance/ssot-v1.
|
|
60
|
-
|
|
59
|
+
`docs/governance/ssot-v1.1.md`, the selected agents-routing file, the exact
|
|
60
|
+
`CLAUDE.md -> AGENTS.md` and `.claude/skills -> ../.agents/skills`
|
|
61
|
+
compatibility links, and old shared SSOT/task-routing leftovers.
|
|
61
62
|
- It also checks that local paths written in backticks inside router-facing
|
|
62
63
|
files such as `AGENTS.md`, `CLAUDE.md`, `README.md`, and the starter
|
|
63
64
|
`AGENTS.template.md` can actually be opened, which catches stale startup
|
package/dist/cli.js
CHANGED
|
@@ -895,13 +895,22 @@ import { existsSync as existsSync7, readFileSync as readFileSync7 } from "node:f
|
|
|
895
895
|
import { isAbsolute, join as join9, resolve as resolve2 } from "node:path";
|
|
896
896
|
|
|
897
897
|
// src/core/router-integrity.ts
|
|
898
|
-
import {
|
|
898
|
+
import {
|
|
899
|
+
existsSync as existsSync6,
|
|
900
|
+
lstatSync as lstatSync2,
|
|
901
|
+
readlinkSync,
|
|
902
|
+
readdirSync as readdirSync5,
|
|
903
|
+
readFileSync as readFileSync6
|
|
904
|
+
} from "node:fs";
|
|
899
905
|
import { join as join8, relative as relative2 } from "node:path";
|
|
900
906
|
var CENTRAL_REQUIRED_FILES = [
|
|
901
907
|
"AGENTS.md",
|
|
908
|
+
"CLAUDE.md",
|
|
909
|
+
".agents/skills",
|
|
910
|
+
".claude/skills",
|
|
902
911
|
"README.md",
|
|
903
912
|
"docs/governance/boundary.md",
|
|
904
|
-
"docs/governance/ssot-v1.
|
|
913
|
+
"docs/governance/ssot-v1.1.md",
|
|
905
914
|
"docs/governance/templates/adr.md",
|
|
906
915
|
"docs/governance/templates/spec.md",
|
|
907
916
|
"docs/governance/templates/plan.md",
|
|
@@ -909,23 +918,23 @@ var CENTRAL_REQUIRED_FILES = [
|
|
|
909
918
|
"docs/governance/templates/reference.md",
|
|
910
919
|
"docs/governance/templates/policy.md",
|
|
911
920
|
"docs/governance/templates/archive.md",
|
|
912
|
-
"docs/governance/agents-routing/engineering-runtime-v1.
|
|
913
|
-
"docs/governance/agents-routing/doc-only-v1.
|
|
921
|
+
"docs/governance/agents-routing/engineering-runtime-v1.1.md",
|
|
922
|
+
"docs/governance/agents-routing/doc-only-v1.1.md",
|
|
914
923
|
"integrations/mattpocock-skills.md",
|
|
915
924
|
"profiles/engineering-runtime/profile.md",
|
|
916
925
|
"profiles/engineering-runtime/manifest.yml",
|
|
917
926
|
"profiles/doc-only/profile.md",
|
|
918
927
|
"profiles/doc-only/manifest.yml",
|
|
928
|
+
"starter/.agents/skills/.gitkeep",
|
|
919
929
|
"starter/AGENTS.template.md",
|
|
920
|
-
"starter/CLAUDE.template.md",
|
|
921
930
|
"starter/lefthook.template.yml",
|
|
922
931
|
"starter/.github/workflows/docs-check.yml",
|
|
923
932
|
"starter/docs/reference/execution/current-work.md",
|
|
924
933
|
"starter/docs/policy/best-practice-for-this-project.md",
|
|
925
934
|
"starter/docs/governance/boundary.md",
|
|
926
|
-
"starter/docs/governance/ssot-v1.
|
|
927
|
-
"starter/docs/governance/agents-routing/engineering-runtime-v1.
|
|
928
|
-
"starter/docs/governance/agents-routing/doc-only-v1.
|
|
935
|
+
"starter/docs/governance/ssot-v1.1.md",
|
|
936
|
+
"starter/docs/governance/agents-routing/engineering-runtime-v1.1.md",
|
|
937
|
+
"starter/docs/governance/agents-routing/doc-only-v1.1.md",
|
|
929
938
|
"starter/docs/governance/doc-agent-rules.md",
|
|
930
939
|
"starter/docs/governance/doc-types.md",
|
|
931
940
|
"starter/docs/governance/templates/adr.md",
|
|
@@ -939,15 +948,17 @@ var CENTRAL_REQUIRED_FILES = [
|
|
|
939
948
|
var PROJECT_REQUIRED_FILES = [
|
|
940
949
|
"AGENTS.md",
|
|
941
950
|
"CLAUDE.md",
|
|
951
|
+
".agents/skills",
|
|
952
|
+
".claude/skills",
|
|
942
953
|
"docs/governance/boundary.md",
|
|
943
|
-
"docs/governance/ssot-v1.
|
|
954
|
+
"docs/governance/ssot-v1.1.md",
|
|
944
955
|
"docs/governance/doc-agent-rules.md",
|
|
945
956
|
"docs/governance/doc-types.md",
|
|
946
957
|
"docs/reference/execution/current-work.md"
|
|
947
958
|
];
|
|
948
959
|
var PROJECT_AGENTS_ROUTING_FILES = [
|
|
949
|
-
"docs/governance/agents-routing/engineering-runtime-v1.
|
|
950
|
-
"docs/governance/agents-routing/doc-only-v1.
|
|
960
|
+
"docs/governance/agents-routing/engineering-runtime-v1.1.md",
|
|
961
|
+
"docs/governance/agents-routing/doc-only-v1.1.md"
|
|
951
962
|
];
|
|
952
963
|
var FORBIDDEN_LEGACY_PATHS = [
|
|
953
964
|
"governance",
|
|
@@ -960,9 +971,14 @@ var FORBIDDEN_PROJECT_PATHS = [
|
|
|
960
971
|
"docs/policy/shared-rules/ssot.md",
|
|
961
972
|
"docs/policy/shared-rules/task-routing.md"
|
|
962
973
|
];
|
|
974
|
+
var SUPERSEDED_PROJECT_CONTRACT_PATHS = [
|
|
975
|
+
"docs/governance/ssot-v1.0.md",
|
|
976
|
+
"docs/governance/agents-routing/engineering-runtime-v1.0.md",
|
|
977
|
+
"docs/governance/agents-routing/doc-only-v1.0.md"
|
|
978
|
+
];
|
|
963
979
|
var FORBIDDEN_PROJECT_ROOTS = ["integrations"];
|
|
964
980
|
var FORBIDDEN_CENTRAL_ROOTS = ["shared-rules"];
|
|
965
|
-
var ROUTER_BLOCK_BEGIN = "<!-- PGS-ROUTER:BEGIN v1.
|
|
981
|
+
var ROUTER_BLOCK_BEGIN = "<!-- PGS-ROUTER:BEGIN v1.1 -->";
|
|
966
982
|
var ROUTER_BLOCK_END = "<!-- PGS-ROUTER:END -->";
|
|
967
983
|
var EXTERNAL_ROUTER_MARKERS = [
|
|
968
984
|
"## gstack",
|
|
@@ -992,8 +1008,8 @@ var CENTRAL_REQUIRED_NEEDLES = [
|
|
|
992
1008
|
},
|
|
993
1009
|
{
|
|
994
1010
|
file: "AGENTS.md",
|
|
995
|
-
needle: "docs/governance/ssot-v1.
|
|
996
|
-
message: "AGENTS.md must mention docs/governance/ssot-v1.
|
|
1011
|
+
needle: "docs/governance/ssot-v1.1.md",
|
|
1012
|
+
message: "AGENTS.md must mention docs/governance/ssot-v1.1.md."
|
|
997
1013
|
},
|
|
998
1014
|
{
|
|
999
1015
|
file: "AGENTS.md",
|
|
@@ -1007,13 +1023,13 @@ var CENTRAL_REQUIRED_NEEDLES = [
|
|
|
1007
1023
|
},
|
|
1008
1024
|
{
|
|
1009
1025
|
file: "AGENTS.md",
|
|
1010
|
-
needle: "docs/governance/agents-routing/engineering-runtime-v1.
|
|
1011
|
-
message: "AGENTS.md must mention docs/governance/agents-routing/engineering-runtime-v1.
|
|
1026
|
+
needle: "docs/governance/agents-routing/engineering-runtime-v1.1.md",
|
|
1027
|
+
message: "AGENTS.md must mention docs/governance/agents-routing/engineering-runtime-v1.1.md."
|
|
1012
1028
|
},
|
|
1013
1029
|
{
|
|
1014
1030
|
file: "AGENTS.md",
|
|
1015
|
-
needle: "docs/governance/agents-routing/doc-only-v1.
|
|
1016
|
-
message: "AGENTS.md must mention docs/governance/agents-routing/doc-only-v1.
|
|
1031
|
+
needle: "docs/governance/agents-routing/doc-only-v1.1.md",
|
|
1032
|
+
message: "AGENTS.md must mention docs/governance/agents-routing/doc-only-v1.1.md."
|
|
1017
1033
|
},
|
|
1018
1034
|
{
|
|
1019
1035
|
file: "AGENTS.md",
|
|
@@ -1031,12 +1047,12 @@ var CENTRAL_REQUIRED_NEEDLES = [
|
|
|
1031
1047
|
message: "README.md must point readers to agents-routing under docs/governance/."
|
|
1032
1048
|
},
|
|
1033
1049
|
{
|
|
1034
|
-
file: "docs/governance/agents-routing/engineering-runtime-v1.
|
|
1050
|
+
file: "docs/governance/agents-routing/engineering-runtime-v1.1.md",
|
|
1035
1051
|
needle: "current-work.md",
|
|
1036
1052
|
message: "Engineering routing must separate routing from current-work.md."
|
|
1037
1053
|
},
|
|
1038
1054
|
{
|
|
1039
|
-
file: "docs/governance/agents-routing/doc-only-v1.
|
|
1055
|
+
file: "docs/governance/agents-routing/doc-only-v1.1.md",
|
|
1040
1056
|
needle: "does not use engineering test workflows by default",
|
|
1041
1057
|
message: "Doc-only routing must exclude engineering test workflows by default."
|
|
1042
1058
|
},
|
|
@@ -1057,7 +1073,7 @@ var CENTRAL_REQUIRED_NEEDLES = [
|
|
|
1057
1073
|
},
|
|
1058
1074
|
{
|
|
1059
1075
|
file: "profiles/engineering-runtime/manifest.yml",
|
|
1060
|
-
needle: "docs/governance/agents-routing/engineering-runtime-v1.
|
|
1076
|
+
needle: "docs/governance/agents-routing/engineering-runtime-v1.1.md",
|
|
1061
1077
|
message: "Engineering profile manifest must point to engineering routing."
|
|
1062
1078
|
},
|
|
1063
1079
|
{
|
|
@@ -1067,7 +1083,7 @@ var CENTRAL_REQUIRED_NEEDLES = [
|
|
|
1067
1083
|
},
|
|
1068
1084
|
{
|
|
1069
1085
|
file: "profiles/doc-only/manifest.yml",
|
|
1070
|
-
needle: "docs/governance/agents-routing/doc-only-v1.
|
|
1086
|
+
needle: "docs/governance/agents-routing/doc-only-v1.1.md",
|
|
1071
1087
|
message: "Doc-only profile manifest must point to doc-only routing."
|
|
1072
1088
|
},
|
|
1073
1089
|
{
|
|
@@ -1092,8 +1108,8 @@ var CENTRAL_REQUIRED_NEEDLES = [
|
|
|
1092
1108
|
},
|
|
1093
1109
|
{
|
|
1094
1110
|
file: "starter/AGENTS.template.md",
|
|
1095
|
-
needle: "docs/governance/ssot-v1.
|
|
1096
|
-
message: "Starter AGENTS template must point agents to docs/governance/ssot-v1.
|
|
1111
|
+
needle: "docs/governance/ssot-v1.1.md",
|
|
1112
|
+
message: "Starter AGENTS template must point agents to docs/governance/ssot-v1.1.md."
|
|
1097
1113
|
},
|
|
1098
1114
|
{
|
|
1099
1115
|
file: "starter/AGENTS.template.md",
|
|
@@ -1179,8 +1195,8 @@ var PROJECT_REQUIRED_NEEDLES = [
|
|
|
1179
1195
|
},
|
|
1180
1196
|
{
|
|
1181
1197
|
file: "AGENTS.md",
|
|
1182
|
-
needle: "docs/governance/ssot-v1.
|
|
1183
|
-
message: "AGENTS.md must mention docs/governance/ssot-v1.
|
|
1198
|
+
needle: "docs/governance/ssot-v1.1.md",
|
|
1199
|
+
message: "AGENTS.md must mention docs/governance/ssot-v1.1.md."
|
|
1184
1200
|
},
|
|
1185
1201
|
{
|
|
1186
1202
|
file: "AGENTS.md",
|
|
@@ -1208,7 +1224,7 @@ var PROJECT_REQUIRED_NEEDLES = [
|
|
|
1208
1224
|
message: "Governance boundary must preserve the product artifact boundary."
|
|
1209
1225
|
},
|
|
1210
1226
|
{
|
|
1211
|
-
file: "docs/governance/ssot-v1.
|
|
1227
|
+
file: "docs/governance/ssot-v1.1.md",
|
|
1212
1228
|
needle: "automatically govern every Markdown file",
|
|
1213
1229
|
message: "SSOT rule must state that not every Markdown file is governed."
|
|
1214
1230
|
},
|
|
@@ -1240,6 +1256,7 @@ function checkRouterIntegrity(rootDir = process.cwd()) {
|
|
|
1240
1256
|
if (!isCentral) {
|
|
1241
1257
|
issues.push(...validateProjectAgentsRouting(rootDir));
|
|
1242
1258
|
}
|
|
1259
|
+
issues.push(...validateHostSsot(rootDir));
|
|
1243
1260
|
for (const file of FORBIDDEN_LEGACY_PATHS) {
|
|
1244
1261
|
if (existsSync6(join8(rootDir, file))) {
|
|
1245
1262
|
issues.push({
|
|
@@ -1259,6 +1276,15 @@ function checkRouterIntegrity(rootDir = process.cwd()) {
|
|
|
1259
1276
|
});
|
|
1260
1277
|
}
|
|
1261
1278
|
}
|
|
1279
|
+
for (const file of SUPERSEDED_PROJECT_CONTRACT_PATHS) {
|
|
1280
|
+
if (existsSync6(join8(rootDir, file))) {
|
|
1281
|
+
issues.push({
|
|
1282
|
+
file,
|
|
1283
|
+
code: "superseded-project-contract",
|
|
1284
|
+
message: `Superseded governance contract must not remain installed in a project: ${file}. Sync the current v1.1 contract instead.`
|
|
1285
|
+
});
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1262
1288
|
for (const file of FORBIDDEN_PROJECT_ROOTS) {
|
|
1263
1289
|
if (existsSync6(join8(rootDir, file))) {
|
|
1264
1290
|
issues.push({
|
|
@@ -1303,7 +1329,6 @@ function checkRouterIntegrity(rootDir = process.cwd()) {
|
|
|
1303
1329
|
issues.push(...validateRouterBlock(rootDir, file));
|
|
1304
1330
|
}
|
|
1305
1331
|
issues.push(...validateBacktickedLocalPaths(rootDir, "AGENTS.md"));
|
|
1306
|
-
issues.push(...validateBacktickedLocalPaths(rootDir, "CLAUDE.md"));
|
|
1307
1332
|
issues.push(...validateBacktickedLocalPaths(rootDir, "README.md"));
|
|
1308
1333
|
if (isCentral) {
|
|
1309
1334
|
issues.push(...validateBacktickedLocalPaths(rootDir, "starter/AGENTS.template.md", "starter"));
|
|
@@ -1312,15 +1337,13 @@ function checkRouterIntegrity(rootDir = process.cwd()) {
|
|
|
1312
1337
|
"AGENTS.md",
|
|
1313
1338
|
"README.md",
|
|
1314
1339
|
"starter/AGENTS.template.md",
|
|
1315
|
-
"
|
|
1316
|
-
"docs/governance/agents-routing/
|
|
1317
|
-
"docs/governance/agents-routing/doc-only-v1.0.md"
|
|
1340
|
+
"docs/governance/agents-routing/engineering-runtime-v1.1.md",
|
|
1341
|
+
"docs/governance/agents-routing/doc-only-v1.1.md"
|
|
1318
1342
|
] : [
|
|
1319
1343
|
"AGENTS.md",
|
|
1320
|
-
"CLAUDE.md",
|
|
1321
1344
|
"README.md",
|
|
1322
|
-
"docs/governance/agents-routing/engineering-runtime-v1.
|
|
1323
|
-
"docs/governance/agents-routing/doc-only-v1.
|
|
1345
|
+
"docs/governance/agents-routing/engineering-runtime-v1.1.md",
|
|
1346
|
+
"docs/governance/agents-routing/doc-only-v1.1.md"
|
|
1324
1347
|
];
|
|
1325
1348
|
for (const file of portableRouterFiles) {
|
|
1326
1349
|
issues.push(...validatePortableRouterText(rootDir, file));
|
|
@@ -1330,6 +1353,62 @@ function checkRouterIntegrity(rootDir = process.cwd()) {
|
|
|
1330
1353
|
issues
|
|
1331
1354
|
};
|
|
1332
1355
|
}
|
|
1356
|
+
function validateHostSsot(rootDir) {
|
|
1357
|
+
const issues = [];
|
|
1358
|
+
validateRegularFile("AGENTS.md");
|
|
1359
|
+
validateExactSymlink("CLAUDE.md", "AGENTS.md");
|
|
1360
|
+
validateDirectory(".agents/skills");
|
|
1361
|
+
validateExactSymlink(".claude/skills", "../.agents/skills");
|
|
1362
|
+
return issues;
|
|
1363
|
+
function validateRegularFile(file) {
|
|
1364
|
+
const stat = safeLstat(join8(rootDir, file));
|
|
1365
|
+
if (!stat || stat.isFile()) return;
|
|
1366
|
+
issues.push({
|
|
1367
|
+
file,
|
|
1368
|
+
code: "invalid-host-ssot-source",
|
|
1369
|
+
message: `${file} must be a regular file and the single source of truth for project instructions.`
|
|
1370
|
+
});
|
|
1371
|
+
}
|
|
1372
|
+
function validateDirectory(file) {
|
|
1373
|
+
const stat = safeLstat(join8(rootDir, file));
|
|
1374
|
+
if (!stat || stat.isDirectory()) return;
|
|
1375
|
+
issues.push({
|
|
1376
|
+
file,
|
|
1377
|
+
code: "invalid-host-ssot-source",
|
|
1378
|
+
message: `${file} must be a real directory and the single source of truth for project skills.`
|
|
1379
|
+
});
|
|
1380
|
+
}
|
|
1381
|
+
function validateExactSymlink(file, expectedRawTarget) {
|
|
1382
|
+
const path = join8(rootDir, file);
|
|
1383
|
+
const stat = safeLstat(path);
|
|
1384
|
+
if (!stat) return;
|
|
1385
|
+
if (!stat.isSymbolicLink()) {
|
|
1386
|
+
issues.push({
|
|
1387
|
+
file,
|
|
1388
|
+
code: "invalid-host-ssot-adapter",
|
|
1389
|
+
message: `${file} must be a symbolic link with the exact relative target ${expectedRawTarget}.`
|
|
1390
|
+
});
|
|
1391
|
+
return;
|
|
1392
|
+
}
|
|
1393
|
+
const rawTarget = readlinkSync(path);
|
|
1394
|
+
if (rawTarget !== expectedRawTarget) {
|
|
1395
|
+
issues.push({
|
|
1396
|
+
file,
|
|
1397
|
+
code: "noncanonical-host-ssot-adapter",
|
|
1398
|
+
message: `${file} must use the exact relative symlink target ${expectedRawTarget}; found ${rawTarget}.`
|
|
1399
|
+
});
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
function safeLstat(path) {
|
|
1404
|
+
try {
|
|
1405
|
+
return lstatSync2(path);
|
|
1406
|
+
} catch (error) {
|
|
1407
|
+
const code = error.code;
|
|
1408
|
+
if (code === "ENOENT" || code === "ENOTDIR") return void 0;
|
|
1409
|
+
throw error;
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1333
1412
|
function isCentralRepository(rootDir) {
|
|
1334
1413
|
const packageJsonPath = join8(rootDir, "package.json");
|
|
1335
1414
|
if (!existsSync6(packageJsonPath)) return false;
|
|
@@ -1445,8 +1524,12 @@ function validatePortableRouterText(rootDir, file) {
|
|
|
1445
1524
|
];
|
|
1446
1525
|
}
|
|
1447
1526
|
function hasNonPortablePath(content) {
|
|
1527
|
+
const withoutCanonicalSkillCompatibilityTarget = content.replace(
|
|
1528
|
+
/(^|[\s`'"])\.\.\/\.agents\/skills(?=$|[\s`'"),.;:\]}])/gm,
|
|
1529
|
+
"$1"
|
|
1530
|
+
);
|
|
1448
1531
|
return /(^|[\s`'"])(\/Users\/|~\/|\$HOME(?:\/|\b)|%USERPROFILE%|[A-Za-z]:\\|\.\.\/)/.test(
|
|
1449
|
-
|
|
1532
|
+
withoutCanonicalSkillCompatibilityTarget
|
|
1450
1533
|
) || /\b(OneDrive|CloudStorage)\b/.test(content);
|
|
1451
1534
|
}
|
|
1452
1535
|
function findGovernedReadmes(rootDir) {
|
|
@@ -1935,8 +2018,9 @@ function runInit(args2) {
|
|
|
1935
2018
|
console.log(`
|
|
1936
2019
|
Next steps for a brand-new project:`);
|
|
1937
2020
|
console.log(` 1. Copy starter/AGENTS.template.md to AGENTS.md and fill the project name.`);
|
|
1938
|
-
console.log(`
|
|
1939
|
-
console.log(`
|
|
2021
|
+
console.log(` Create .agents/skills as the canonical project skill directory.`);
|
|
2022
|
+
console.log(` Link CLAUDE.md -> AGENTS.md and .claude/skills -> ../.agents/skills.`);
|
|
2023
|
+
console.log(` 2. Copy starter/docs/governance/boundary.md, ssot-v1.1.md,`);
|
|
1940
2024
|
console.log(` doc-agent-rules.md, doc-types.md, and one agents-routing file.`);
|
|
1941
2025
|
console.log(` 3. Copy starter/docs/policy/best-practice-for-this-project.md and replace`);
|
|
1942
2026
|
console.log(` placeholder policy with this project's real AI/development rules.`);
|
|
@@ -1975,8 +2059,8 @@ function runLinks() {
|
|
|
1975
2059
|
import { existsSync as existsSync10, readFileSync as readFileSync9 } from "node:fs";
|
|
1976
2060
|
import { join as join12 } from "node:path";
|
|
1977
2061
|
var PROFILE_ROUTES = {
|
|
1978
|
-
"engineering-runtime": "docs/governance/agents-routing/engineering-runtime-v1.
|
|
1979
|
-
"doc-only": "docs/governance/agents-routing/doc-only-v1.
|
|
2062
|
+
"engineering-runtime": "docs/governance/agents-routing/engineering-runtime-v1.1.md",
|
|
2063
|
+
"doc-only": "docs/governance/agents-routing/doc-only-v1.1.md"
|
|
1980
2064
|
};
|
|
1981
2065
|
function runMigrate(args2) {
|
|
1982
2066
|
const checkOnly = args2.includes("--check");
|