@flancer32/skill-adsm-ctx 0.4.0 → 0.6.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.
Files changed (72) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +56 -40
  3. package/bin/adsm-ctx.mjs +1 -1
  4. package/package.json +5 -18
  5. package/skills/adsm-ctx/SKILL.md +72 -0
  6. package/{skill → skills/adsm-ctx}/references/agents-hierarchy.md +4 -2
  7. package/skills/adsm-ctx/references/context-evolution.md +59 -0
  8. package/{skill → skills/adsm-ctx}/references/context-lifecycle.md +20 -9
  9. package/{skill → skills/adsm-ctx}/references/design-questionnaire.md +3 -3
  10. package/{skill → skills/adsm-ctx}/references/document-projections.md +12 -10
  11. package/{skill → skills/adsm-ctx}/references/documentation-compression.md +5 -5
  12. package/{skill → skills/adsm-ctx}/references/documentation-quality-audit.md +6 -6
  13. package/{skill → skills/adsm-ctx}/references/orchestration-model.md +8 -6
  14. package/{skill → skills/adsm-ctx}/references/semantic-skins.md +3 -1
  15. package/{skill → skills/adsm-ctx}/references/specialized-skills.md +2 -2
  16. package/skills/adsm-ctx/references/testing-and-verification.md +12 -0
  17. package/skills/adsm-ctx/templates/AGENTS.md +23 -0
  18. package/skills/adsm-ctx/templates/ctx/AGENTS.md +46 -0
  19. package/{skill → skills/adsm-ctx}/templates/ctx/README.md +1 -1
  20. package/{skill → skills/adsm-ctx}/templates/ctx/adsm.json +1 -1
  21. package/skills/adsm-ctx/templates/ctx/agent/AGENTS.md +32 -0
  22. package/skills/adsm-ctx/templates/ctx/docs/AGENTS.md +64 -0
  23. package/{skill → skills/adsm-ctx}/templates/ctx/docs/code/testing.md +3 -1
  24. package/skills/adsm-ctx/templates/ctx/docs/verification/AGENTS.md +31 -0
  25. package/src/Cli/Command/Init.mjs +21 -5
  26. package/src/Cli/Command/InstallSkill.mjs +16 -5
  27. package/src/Cli/Command/Validate.mjs +17 -5
  28. package/src/Init/Service.mjs +26 -47
  29. package/src/Shared/Constants.mjs +4 -1
  30. package/src/Shared/CopyDirectory.mjs +9 -9
  31. package/src/Shared/Metadata.mjs +1 -1
  32. package/src/Skill/Installer.mjs +5 -5
  33. package/src/Validate/Service.mjs +159 -149
  34. package/types.d.ts +31 -4
  35. package/migrations/README.md +0 -13
  36. package/skill/SKILL.md +0 -48
  37. package/skill/references/upgrade-policy.md +0 -29
  38. package/skill/templates/AGENTS.md +0 -120
  39. package/skill/templates/ai/AGENTS.md +0 -59
  40. package/skill/templates/ctx/AGENTS.md +0 -45
  41. package/skill/templates/ctx/agent/AGENTS.md +0 -36
  42. package/skill/templates/ctx/docs/AGENTS.md +0 -58
  43. package/src/Cli/Command/Design.mjs +0 -17
  44. package/src/Cli/Command/Upgrade.mjs +0 -19
  45. package/src/Design/Service.mjs +0 -38
  46. package/src/Upgrade/Service.mjs +0 -44
  47. /package/{skill/templates/work → skills/adsm-ctx/assets}/context/semantic-skin.md +0 -0
  48. /package/{skill/templates/work → skills/adsm-ctx/assets}/report/documentation-compression.md +0 -0
  49. /package/{skill/templates/work → skills/adsm-ctx/assets}/report/documentation-quality-audit.md +0 -0
  50. /package/{skill → skills/adsm-ctx}/templates/ctx/assets/.gitkeep +0 -0
  51. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/ai-intro.md +0 -0
  52. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/AGENTS.md +0 -0
  53. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/behavior.md +0 -0
  54. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/checklists.md +0 -0
  55. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/constraints.md +0 -0
  56. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/decisions.md +0 -0
  57. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/integration.md +0 -0
  58. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/overview.md +0 -0
  59. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/state.md +0 -0
  60. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/structure.md +0 -0
  61. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/supervision.md +0 -0
  62. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/code/AGENTS.md +0 -0
  63. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/code/overview.md +0 -0
  64. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/environment/AGENTS.md +0 -0
  65. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/environment/overview.md +0 -0
  66. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/filesystem.md +0 -0
  67. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/product/AGENTS.md +0 -0
  68. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/product/domain.md +0 -0
  69. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/product/glossary.md +0 -0
  70. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/product/overview.md +0 -0
  71. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/product/roles.md +0 -0
  72. /package/{skill → skills/adsm-ctx}/templates/ctx/docs/product/use-cases.md +0 -0
@@ -21,30 +21,9 @@ export default class Validate {
21
21
  /**
22
22
  * Validates context structure.
23
23
  *
24
- * @param {object} params
25
- * @param {string} params.targetPath
26
- * @returns {Promise<{
27
- * errorCount: number,
28
- * findings: {
29
- * message: string,
30
- * path: string,
31
- * ruleId: string,
32
- * severity: "error" | "warning"
33
- * }[],
34
- * metadata: {capabilities?: string[], schema: string, version: string, initializedAt?: string} | null,
35
- * missingPaths: string[],
36
- * ok: boolean,
37
- * projectRoot: string,
38
- * projection: {
39
- * assets: string[],
40
- * bodies: string[],
41
- * orphanSkins: string[],
42
- * pairs: {body: string, skin: string}[],
43
- * skins: string[],
44
- * verification: {categories: string[], present: boolean}
45
- * },
46
- * warningCount: number
47
- * }>}
24
+ * @param {object} deps
25
+ * @param {string} deps.targetPath
26
+ * @returns {Promise<Fl32_Skill_Adsm_Ctx_Validate_Result>}
48
27
  */
49
28
  this.execute = async function ({targetPath}) {
50
29
  const projectRoot = pathService.resolve(targetPath);
@@ -59,11 +38,22 @@ export default class Validate {
59
38
  const projection = inspectProjection({
60
39
  constants,
61
40
  fs,
62
- metadata: metadataResult.metadata,
41
+ metadata: metadataResult.ok ? metadataResult.metadata : null,
63
42
  pathService,
64
43
  projectRoot,
65
44
  });
66
45
 
46
+ for (const entry of constants.REQUIRED_PATHS) {
47
+ const absolute = pathService.join(projectRoot, entry);
48
+ if (!fs.existsSync(absolute) || typeof fs.statSync !== "function") continue;
49
+ const stat = fs.statSync(absolute);
50
+ const file = entry.endsWith(".md") || entry.endsWith(".json");
51
+ if (file ? !stat.isFile() : !stat.isDirectory()) findings.push(createFinding({
52
+ message: `Required path has wrong filesystem type: ${entry}`,
53
+ path: entry, ruleId: "required-path-type", severity: "error",
54
+ }));
55
+ }
56
+ findings.push(...inspectAgentsHierarchy({fs, pathService, projectRoot}));
67
57
  findings.push(...metadataResult.findings);
68
58
  findings.push(...projection.findings);
69
59
 
@@ -73,7 +63,7 @@ export default class Validate {
73
63
  return {
74
64
  errorCount,
75
65
  findings,
76
- metadata: metadataResult.ok ? metadataResult.metadata : null,
66
+ metadata: metadataResult.metadata,
77
67
  missingPaths,
78
68
  ok: errorCount === 0,
79
69
  projectRoot,
@@ -85,20 +75,8 @@ export default class Validate {
85
75
  /**
86
76
  * Formats validation result for CLI output.
87
77
  *
88
- * @param {object} params
89
- * @param {{
90
- * errorCount: number,
91
- * findings: {
92
- * message: string,
93
- * path: string,
94
- * ruleId: string,
95
- * severity: "error" | "warning"
96
- * }[],
97
- * metadata: {version: string} | null,
98
- * ok: boolean,
99
- * projectRoot: string,
100
- * warningCount: number
101
- * }} params.result
78
+ * @param {object} deps
79
+ * @param {Fl32_Skill_Adsm_Ctx_Validate_Result} deps.result
102
80
  * @returns {string}
103
81
  */
104
82
  this.format = function ({result}) {
@@ -111,7 +89,8 @@ export default class Validate {
111
89
  const lines = [
112
90
  status,
113
91
  `Project root: ${result.projectRoot}`,
114
- `Context version: ${result.metadata?.version ?? "unknown"}`,
92
+ `Context schema version: ${result.metadata?.version ?? "unknown"}`,
93
+ `Supported context schema version: ${constants.CONTEXT_VERSION}`,
115
94
  `Errors: ${result.errorCount}`,
116
95
  `Warnings: ${result.warningCount}`,
117
96
  ];
@@ -128,12 +107,12 @@ export default class Validate {
128
107
  }
129
108
 
130
109
  /**
131
- * @param {object} params
132
- * @param {string} params.message
133
- * @param {string} params.path
134
- * @param {string} params.ruleId
135
- * @param {"error" | "warning"} params.severity
136
- * @returns {{message: string, path: string, ruleId: string, severity: "error" | "warning"}}
110
+ * @param {object} deps
111
+ * @param {string} deps.message
112
+ * @param {string} deps.path
113
+ * @param {string} deps.ruleId
114
+ * @param {Fl32_Skill_Adsm_Ctx_Finding_Severity} deps.severity
115
+ * @returns {Fl32_Skill_Adsm_Ctx_Finding}
137
116
  */
138
117
  function createFinding({message, path, ruleId, severity}) {
139
118
  return {message, path, ruleId, severity};
@@ -143,7 +122,7 @@ function createFinding({message, path, ruleId, severity}) {
143
122
  * Classifies a semantic-skin filename and derives its canonical agent document.
144
123
  *
145
124
  * @param {string} file
146
- * @returns {{body: string, language: string | null, markerError: string | null} | null}
125
+ * @returns {Fl32_Skill_Adsm_Ctx_SkinInfo_Optional}
147
126
  */
148
127
  function parseSkinFilename(file) {
149
128
  const explicitMatch = file.match(EXPLICIT_SKIN_FILENAME);
@@ -173,18 +152,12 @@ function parseSkinFilename(file) {
173
152
  }
174
153
 
175
154
  /**
176
- * @param {object} params
177
- * @param {Fl32_Skill_Adsm_Ctx_Shared_Constants} params.constants
178
- * @param {typeof import("node:fs")} params.fs
179
- * @param {Fl32_Skill_Adsm_Ctx_Shared_Path} params.pathService
180
- * @param {string} params.projectRoot
181
- * @returns {{
182
- * ok: false,
183
- * finding: {message: string, path: string, ruleId: string, severity: "error" | "warning"}
184
- * } | {
185
- * ok: true,
186
- * metadata: {schema: string, version: string, initializedAt?: string}
187
- * }}
155
+ * @param {object} deps
156
+ * @param {Fl32_Skill_Adsm_Ctx_Shared_Constants} deps.constants
157
+ * @param {typeof import("node:fs")} deps.fs
158
+ * @param {Fl32_Skill_Adsm_Ctx_Shared_Path} deps.pathService
159
+ * @param {string} deps.projectRoot
160
+ * @returns {Fl32_Skill_Adsm_Ctx_Metadata_ReadResult}
188
161
  */
189
162
  function readMetadata({constants, fs, pathService, projectRoot}) {
190
163
  const findings = [];
@@ -209,9 +182,9 @@ function readMetadata({constants, fs, pathService, projectRoot}) {
209
182
  severity: "error",
210
183
  }));
211
184
  }
212
- if (!parsed.version) {
185
+ if (parsed.version !== constants.CONTEXT_VERSION) {
213
186
  findings.push(createFinding({
214
- message: "Missing metadata version",
187
+ message: `Unsupported metadata version: ${parsed.version}; target schema: ${constants.CONTEXT_VERSION}. Investigate with skill adsm-ctx before changing schema metadata.`,
215
188
  path: "ctx/adsm.json",
216
189
  ruleId: "metadata-version",
217
190
  severity: "error",
@@ -252,7 +225,7 @@ function readMetadata({constants, fs, pathService, projectRoot}) {
252
225
  }
253
226
 
254
227
  const ok = findings.every((entry) => entry.severity !== "error");
255
- return {findings, metadata: ok ? parsed : null, ok};
228
+ return {findings, metadata: parsed, ok};
256
229
  } catch (error) {
257
230
  findings.push(createFinding({
258
231
  message: `Invalid metadata JSON: ${error instanceof Error ? error.message : "Unknown error"}`,
@@ -265,26 +238,13 @@ function readMetadata({constants, fs, pathService, projectRoot}) {
265
238
  }
266
239
 
267
240
  /**
268
- * @param {object} params
269
- * @param {Fl32_Skill_Adsm_Ctx_Shared_Constants} params.constants
270
- * @param {typeof import("node:fs")} params.fs
271
- * @param {Fl32_Skill_Adsm_Ctx_Shared_Path} params.pathService
272
- * @param {string} params.projectRoot
273
- * @returns {{
274
- * findings: {
275
- * message: string,
276
- * path: string,
277
- * ruleId: string,
278
- * severity: "error" | "warning"
279
- * }[],
280
- * summary: {
281
- * assets: string[],
282
- * bodies: string[],
283
- * orphanSkins: string[],
284
- * pairs: {body: string, skin: string}[],
285
- * skins: string[]
286
- * }
287
- * }}
241
+ * @param {object} deps
242
+ * @param {Fl32_Skill_Adsm_Ctx_Shared_Constants} deps.constants
243
+ * @param {typeof import("node:fs")} deps.fs
244
+ * @param {Fl32_Skill_Adsm_Ctx_Shared_Path} deps.pathService
245
+ * @param {string} deps.projectRoot
246
+ * @param {Fl32_Skill_Adsm_Ctx_Metadata_Optional} deps.metadata
247
+ * @returns {Fl32_Skill_Adsm_Ctx_Projection_Result}
288
248
  */
289
249
  function inspectProjection({constants, fs, metadata, pathService, projectRoot}) {
290
250
  const docsRoot = pathService.join(projectRoot, "ctx", "docs");
@@ -424,19 +384,16 @@ function inspectProjection({constants, fs, metadata, pathService, projectRoot})
424
384
  }
425
385
 
426
386
  /**
427
- * Inspects optional Verification Layer adoption without treating it as a fifth
387
+ * Inspects the cross-cutting Verification Layer without treating it as a fifth
428
388
  * declarative documentation level.
429
389
  *
430
- * @param {object} params
431
- * @param {Fl32_Skill_Adsm_Ctx_Shared_Constants} params.constants
432
- * @param {Map<string, {name: string, isDirectory: () => boolean, isFile: () => boolean}>} params.docsEntryMap
433
- * @param {typeof import("node:fs")} params.fs
434
- * @param {Fl32_Skill_Adsm_Ctx_Shared_Path} params.pathService
435
- * @param {string} params.projectRoot
436
- * @returns {{
437
- * findings: {message: string, path: string, ruleId: string, severity: "error" | "warning"}[],
438
- * summary: {categories: string[], present: boolean}
439
- * }}
390
+ * @param {object} deps
391
+ * @param {Fl32_Skill_Adsm_Ctx_Shared_Constants} deps.constants
392
+ * @param {Fl32_Skill_Adsm_Ctx_DirectoryEntryMap} deps.docsEntryMap
393
+ * @param {typeof import("node:fs")} deps.fs
394
+ * @param {Fl32_Skill_Adsm_Ctx_Shared_Path} deps.pathService
395
+ * @param {string} deps.projectRoot
396
+ * @returns {Fl32_Skill_Adsm_Ctx_Verification_Result}
440
397
  */
441
398
  function inspectVerificationBlock({constants, docsEntryMap, fs, pathService, projectRoot}) {
442
399
  const findings = [];
@@ -529,15 +486,6 @@ function inspectVerificationBlock({constants, docsEntryMap, fs, pathService, pro
529
486
  }
530
487
  }
531
488
 
532
- if (summary.categories.length === 0) {
533
- findings.push(createFinding({
534
- message: `Verification block has no populated primary-target category: ${verificationPath}`,
535
- path: verificationPath,
536
- ruleId: "verification-empty-block",
537
- severity: "error",
538
- }));
539
- }
540
-
541
489
  return {findings, summary};
542
490
  }
543
491
 
@@ -545,13 +493,13 @@ function inspectVerificationBlock({constants, docsEntryMap, fs, pathService, pro
545
493
  * Warns when a documentation level exceeds the recommended direct-entry capacity
546
494
  * and requires its local AGENTS.md to make an intentional exception explicit.
547
495
  *
548
- * @param {object} params
549
- * @param {Fl32_Skill_Adsm_Ctx_Shared_Constants} params.constants
550
- * @param {Map<string, {name: string, isDirectory: () => boolean, isFile: () => boolean}>} params.docsEntryMap
551
- * @param {typeof import("node:fs")} params.fs
552
- * @param {Fl32_Skill_Adsm_Ctx_Shared_Path} params.pathService
553
- * @param {string} params.projectRoot
554
- * @returns {{message: string, path: string, ruleId: string, severity: "error" | "warning"}[]}
496
+ * @param {object} deps
497
+ * @param {Fl32_Skill_Adsm_Ctx_Shared_Constants} deps.constants
498
+ * @param {Fl32_Skill_Adsm_Ctx_DirectoryEntryMap} deps.docsEntryMap
499
+ * @param {typeof import("node:fs")} deps.fs
500
+ * @param {Fl32_Skill_Adsm_Ctx_Shared_Path} deps.pathService
501
+ * @param {string} deps.projectRoot
502
+ * @returns {Array<Fl32_Skill_Adsm_Ctx_Finding>}
555
503
  */
556
504
  function validateDocumentationLevelCapacity({constants, docsEntryMap, fs, pathService, projectRoot}) {
557
505
  const findings = [];
@@ -617,12 +565,12 @@ function validateDocumentationLevelCapacity({constants, docsEntryMap, fs, pathSe
617
565
  }
618
566
 
619
567
  /**
620
- * @param {object} params
621
- * @param {typeof import("node:fs")} params.fs
622
- * @param {Fl32_Skill_Adsm_Ctx_Shared_Path} params.pathService
623
- * @param {string} params.root
624
- * @param {string} params.prefix
625
- * @returns {string[]}
568
+ * @param {object} deps
569
+ * @param {typeof import("node:fs")} deps.fs
570
+ * @param {Fl32_Skill_Adsm_Ctx_Shared_Path} deps.pathService
571
+ * @param {string} deps.root
572
+ * @param {string} deps.prefix
573
+ * @returns {Array<string>}
626
574
  */
627
575
  function listFiles({fs, pathService, root, prefix}) {
628
576
  const result = [];
@@ -639,21 +587,20 @@ function listFiles({fs, pathService, root, prefix}) {
639
587
  }
640
588
 
641
589
  /**
642
- * @param {object} params
643
- * @param {typeof import("node:fs")} params.fs
644
- * @param {string} params.root
645
- * @returns {{name: string, isDirectory: () => boolean, isFile: () => boolean}[]}
590
+ * @param {object} deps
591
+ * @param {typeof import("node:fs")} deps.fs
592
+ * @param {string} deps.root
593
+ * @returns {Array<Fl32_Skill_Adsm_Ctx_DirectoryEntry>}
646
594
  */
647
595
  function listEntries({fs, root}) {
648
596
  return fs.readdirSync(root, {withFileTypes: true});
649
597
  }
650
598
 
651
599
  /**
652
- * @param {object} params
653
- * @param {string} params.file
654
- * @param {{body: string, language: string | null, markerError: string | null}} params.skinInfo
655
- * @param {string} params.text
656
- * @returns {{message: string, path: string, ruleId: string, severity: "error" | "warning"}[]}
600
+ * @param {object} deps
601
+ * @param {string} deps.file
602
+ * @param {string} deps.text
603
+ * @returns {Array<Fl32_Skill_Adsm_Ctx_Finding>}
657
604
  */
658
605
  function validateDocumentMetadata({file, text}) {
659
606
  const findings = [];
@@ -695,13 +642,13 @@ function validateDocumentMetadata({file, text}) {
695
642
  }
696
643
 
697
644
  /**
698
- * @param {object} params
699
- * @param {string} params.file
700
- * @param {typeof import("node:fs")} params.fs
701
- * @param {Fl32_Skill_Adsm_Ctx_Shared_Path} params.pathService
702
- * @param {string} params.projectRoot
703
- * @param {string} params.text
704
- * @returns {{message: string, path: string, ruleId: string, severity: "error" | "warning"}[]}
645
+ * @param {object} deps
646
+ * @param {string} deps.file
647
+ * @param {typeof import("node:fs")} deps.fs
648
+ * @param {Fl32_Skill_Adsm_Ctx_Shared_Path} deps.pathService
649
+ * @param {string} deps.projectRoot
650
+ * @param {string} deps.text
651
+ * @returns {Array<Fl32_Skill_Adsm_Ctx_Finding>}
705
652
  */
706
653
  function validateLocalMarkdownLinks({file, fs, pathService, projectRoot, text}) {
707
654
  const findings = [];
@@ -733,12 +680,13 @@ function validateLocalMarkdownLinks({file, fs, pathService, projectRoot, text})
733
680
  }
734
681
 
735
682
  /**
736
- * @param {object} params
737
- * @param {Set<string>} params.bodySet
738
- * @param {Fl32_Skill_Adsm_Ctx_Shared_Constants} params.constants
739
- * @param {string} params.file
740
- * @param {string} params.text
741
- * @returns {{message: string, path: string, ruleId: string, severity: "error" | "warning"}[]}
683
+ * @param {object} deps
684
+ * @param {Fl32_Skill_Adsm_Ctx_StringSet} deps.bodySet
685
+ * @param {Fl32_Skill_Adsm_Ctx_Shared_Constants} deps.constants
686
+ * @param {string} deps.file
687
+ * @param {Fl32_Skill_Adsm_Ctx_SkinInfo} deps.skinInfo
688
+ * @param {string} deps.text
689
+ * @returns {Array<Fl32_Skill_Adsm_Ctx_Finding>}
742
690
  */
743
691
  function validateSkinDocument({bodySet, constants, file, skinInfo, text}) {
744
692
  const findings = [];
@@ -762,9 +710,9 @@ function validateSkinDocument({bodySet, constants, file, skinInfo, text}) {
762
710
  }
763
711
 
764
712
  /**
765
- * @param {object} params
766
- * @param {string} params.sectionName
767
- * @param {string} params.text
713
+ * @param {object} deps
714
+ * @param {string} deps.sectionName
715
+ * @param {string} deps.text
768
716
  * @returns {string}
769
717
  */
770
718
  function extractSectionBody({sectionName, text}) {
@@ -784,10 +732,10 @@ function extractSectionBody({sectionName, text}) {
784
732
  }
785
733
 
786
734
  /**
787
- * @param {object} params
788
- * @param {string} params.file
789
- * @param {string} params.link
790
- * @returns {{fragment: string | null, path: string} | null}
735
+ * @param {object} deps
736
+ * @param {string} deps.file
737
+ * @param {string} deps.link
738
+ * @returns {Fl32_Skill_Adsm_Ctx_Validate_Link_Optional}
791
739
  */
792
740
  function normalizeLocalMarkdownLink({file, link}) {
793
741
  const trimmed = link.trim();
@@ -814,8 +762,8 @@ function normalizeLocalMarkdownLink({file, link}) {
814
762
  }
815
763
 
816
764
  /**
817
- * @param {string[]} parts
818
- * @returns {string[]}
765
+ * @param {Array<string>} parts
766
+ * @returns {Array<string>}
819
767
  */
820
768
  function normalizeRelativeSegments(parts) {
821
769
  const result = [];
@@ -830,8 +778,70 @@ function normalizeRelativeSegments(parts) {
830
778
  return result;
831
779
  }
832
780
 
833
- export const __deps__ = Object.freeze({
781
+ /**
782
+ * Checks context-side routing sections; root repository instructions have a separate shape.
783
+ * @param {object} deps
784
+ * @param {typeof import("node:fs")} deps.fs
785
+ * @param {Fl32_Skill_Adsm_Ctx_Shared_Path} deps.pathService
786
+ * @param {string} deps.projectRoot
787
+ * @returns {Array<Fl32_Skill_Adsm_Ctx_Finding>}
788
+ */
789
+ function inspectAgentsHierarchy({fs, pathService, projectRoot}) {
790
+ const findings = [];
791
+ const root = pathService.join(projectRoot, "ctx");
792
+ if (!fs.existsSync(root)) return findings;
793
+ /**
794
+ * @param {string} directory
795
+ * @param {string} relative
796
+ * @returns {void}
797
+ */
798
+ const visit = (directory, relative) => {
799
+ let entries;
800
+ try { entries = listEntries({fs, root: directory}); }
801
+ catch (error) {
802
+ findings.push(createFinding({message: `Cannot inspect context routing: ${error.message}`, path: relative, ruleId: "agents-readable", severity: "error"}));
803
+ return;
804
+ }
805
+ for (const entry of entries) {
806
+ const absolute = pathService.join(directory, entry.name);
807
+ const file = `${relative}/${entry.name}`;
808
+ if (entry.isDirectory()) visit(absolute, file);
809
+ else if (entry.isFile() && entry.name === "AGENTS.md") {
810
+ let text;
811
+ try { text = fs.readFileSync(absolute, "utf8"); }
812
+ catch (error) {
813
+ findings.push(createFinding({message: `Cannot read context AGENTS.md: ${error.message}`, path: file, ruleId: "agents-readable", severity: "error"}));
814
+ continue;
815
+ }
816
+ // Ignore fenced examples so sample headings cannot satisfy the document structure.
817
+ const headings = new Set();
818
+ let fence = null;
819
+ for (const line of text.split(/\r?\n/)) {
820
+ const marker = /^ {0,3}(`{3,}|~{3,})/.exec(line);
821
+ if (marker) {
822
+ if (!fence) fence = marker[1];
823
+ else if (marker[1][0] === fence[0] && marker[1].length >= fence.length) fence = null;
824
+ continue;
825
+ }
826
+ if (fence) continue;
827
+ const heading = /^ {0,3}##[ \t]+(.+?)[ \t]*$/.exec(line);
828
+ if (heading) headings.add(heading[1].replace(/[ \t]+#+[ \t]*$/, ""));
829
+ }
830
+ for (const section of ["Purpose", "Level Map", "Level Boundary"]) {
831
+ if (!headings.has(section)) findings.push(createFinding({
832
+ message: `Missing required section: ## ${section}. Add it to this context-side AGENTS.md.`,
833
+ path: file, ruleId: "agents-required-section", severity: "error",
834
+ }));
835
+ }
836
+ }
837
+ }
838
+ };
839
+ visit(root, "ctx");
840
+ return findings;
841
+ }
842
+
843
+ export const __deps__ = Object.freeze({default: Object.freeze({
834
844
  constants: "Fl32_Skill_Adsm_Ctx_Shared_Constants$",
835
845
  fs: "node:fs",
836
846
  pathService: "Fl32_Skill_Adsm_Ctx_Shared_Path$",
837
- });
847
+ })});
package/types.d.ts CHANGED
@@ -1,18 +1,45 @@
1
1
  declare global {
2
- type Fl32_Skill_Adsm_Ctx_Cli_Command_Design = import("./src/Cli/Command/Design.mjs").default;
3
2
  type Fl32_Skill_Adsm_Ctx_Cli_Command_Init = import("./src/Cli/Command/Init.mjs").default;
3
+ type Fl32_Skill_Adsm_Ctx_Cli_Command_Init__Class = typeof import("./src/Cli/Command/Init.mjs").default;
4
4
  type Fl32_Skill_Adsm_Ctx_Cli_Command_InstallSkill = import("./src/Cli/Command/InstallSkill.mjs").default;
5
- type Fl32_Skill_Adsm_Ctx_Cli_Command_Upgrade = import("./src/Cli/Command/Upgrade.mjs").default;
5
+ type Fl32_Skill_Adsm_Ctx_Cli_Command_InstallSkill__Class = typeof import("./src/Cli/Command/InstallSkill.mjs").default;
6
6
  type Fl32_Skill_Adsm_Ctx_Cli_Command_Validate = import("./src/Cli/Command/Validate.mjs").default;
7
- type Fl32_Skill_Adsm_Ctx_Design_Service = import("./src/Design/Service.mjs").default;
7
+ type Fl32_Skill_Adsm_Ctx_Cli_Command_Validate__Class = typeof import("./src/Cli/Command/Validate.mjs").default;
8
+ type Fl32_Skill_Adsm_Ctx_Cli_Config = {cwd: string};
9
+ type Fl32_Skill_Adsm_Ctx_DirectoryEntry = {name: string; isDirectory: () => boolean; isFile: () => boolean};
10
+ type Fl32_Skill_Adsm_Ctx_DirectoryEntryMap = {get: (name: string) => Fl32_Skill_Adsm_Ctx_DirectoryEntry | undefined};
11
+ type Fl32_Skill_Adsm_Ctx_Finding = {message: string; path: string; ruleId: string; severity: "error" | "warning"};
12
+ type Fl32_Skill_Adsm_Ctx_Finding_Severity = "error" | "warning";
13
+ type Fl32_Skill_Adsm_Ctx_Init_Result = {created: Array<string>; ctxRoot: string; projectRoot: string; skipped: Array<string>};
8
14
  type Fl32_Skill_Adsm_Ctx_Init_Service = import("./src/Init/Service.mjs").default;
15
+ type Fl32_Skill_Adsm_Ctx_Init_Service__Class = typeof import("./src/Init/Service.mjs").default;
16
+ type Fl32_Skill_Adsm_Ctx_Metadata = {schema: string; version: string; capabilities?: Array<string>; initializedAt?: string};
17
+ type Fl32_Skill_Adsm_Ctx_Metadata_Optional = Fl32_Skill_Adsm_Ctx_Metadata | null;
18
+ type Fl32_Skill_Adsm_Ctx_Metadata_ReadResult = {findings: Array<Fl32_Skill_Adsm_Ctx_Finding>; metadata: Fl32_Skill_Adsm_Ctx_Metadata | null; ok: boolean};
19
+ type Fl32_Skill_Adsm_Ctx_Metadata_Value = {schema: string; version: string; capabilities: Array<string>};
20
+ type Fl32_Skill_Adsm_Ctx_Projection = {assets: Array<string>; bodies: Array<string>; orphanSkins: Array<string>; pairs: Array<Fl32_Skill_Adsm_Ctx_Projection_Pair>; skins: Array<string>; verification?: Fl32_Skill_Adsm_Ctx_Verification_Summary};
21
+ type Fl32_Skill_Adsm_Ctx_Projection_Pair = {body: string; skin: string};
22
+ type Fl32_Skill_Adsm_Ctx_Projection_Result = {findings: Array<Fl32_Skill_Adsm_Ctx_Finding>; summary: Fl32_Skill_Adsm_Ctx_Projection};
9
23
  type Fl32_Skill_Adsm_Ctx_Shared_Constants = import("./src/Shared/Constants.mjs").default;
24
+ type Fl32_Skill_Adsm_Ctx_Shared_Constants__Class = typeof import("./src/Shared/Constants.mjs").default;
10
25
  type Fl32_Skill_Adsm_Ctx_Shared_CopyDirectory = import("./src/Shared/CopyDirectory.mjs").default;
26
+ type Fl32_Skill_Adsm_Ctx_Shared_CopyDirectory__Class = typeof import("./src/Shared/CopyDirectory.mjs").default;
11
27
  type Fl32_Skill_Adsm_Ctx_Shared_Metadata = import("./src/Shared/Metadata.mjs").default;
28
+ type Fl32_Skill_Adsm_Ctx_Shared_Metadata__Class = typeof import("./src/Shared/Metadata.mjs").default;
12
29
  type Fl32_Skill_Adsm_Ctx_Shared_Path = import("./src/Shared/Path.mjs").default;
30
+ type Fl32_Skill_Adsm_Ctx_Shared_Path__Class = typeof import("./src/Shared/Path.mjs").default;
13
31
  type Fl32_Skill_Adsm_Ctx_Skill_Installer = import("./src/Skill/Installer.mjs").default;
14
- type Fl32_Skill_Adsm_Ctx_Upgrade_Service = import("./src/Upgrade/Service.mjs").default;
32
+ type Fl32_Skill_Adsm_Ctx_Skill_Installer__Class = typeof import("./src/Skill/Installer.mjs").default;
33
+ type Fl32_Skill_Adsm_Ctx_SkinInfo = {body: string; language: string | null; markerError: string | null};
34
+ type Fl32_Skill_Adsm_Ctx_SkinInfo_Optional = Fl32_Skill_Adsm_Ctx_SkinInfo | null;
35
+ type Fl32_Skill_Adsm_Ctx_StringSet = {has: (value: string) => boolean};
36
+ type Fl32_Skill_Adsm_Ctx_Validate_Link = {fragment: string | null; path: string};
37
+ type Fl32_Skill_Adsm_Ctx_Validate_Link_Optional = Fl32_Skill_Adsm_Ctx_Validate_Link | null;
38
+ type Fl32_Skill_Adsm_Ctx_Validate_Result = {errorCount: number; findings: Array<Fl32_Skill_Adsm_Ctx_Finding>; metadata: Fl32_Skill_Adsm_Ctx_Metadata | null; missingPaths: Array<string>; ok: boolean; projectRoot: string; projection: Fl32_Skill_Adsm_Ctx_Projection; warningCount: number};
15
39
  type Fl32_Skill_Adsm_Ctx_Validate_Service = import("./src/Validate/Service.mjs").default;
40
+ type Fl32_Skill_Adsm_Ctx_Validate_Service__Class = typeof import("./src/Validate/Service.mjs").default;
41
+ type Fl32_Skill_Adsm_Ctx_Verification_Result = {findings: Array<Fl32_Skill_Adsm_Ctx_Finding>; summary: Fl32_Skill_Adsm_Ctx_Verification_Summary};
42
+ type Fl32_Skill_Adsm_Ctx_Verification_Summary = {categories: Array<string>; present: boolean};
16
43
  }
17
44
 
18
45
  export {};
@@ -1,13 +0,0 @@
1
- # Migrations
2
-
3
- This directory is reserved for explicit context migrations. The `verification-layer` convention is capability-based and optional: it does not require a migration, `ctx/docs/verification/`, empty categories, or placeholder specifications. `adsm-ctx upgrade` therefore preserves existing contexts and reports that no automatic migrations are available.
4
-
5
- Each migration should be:
6
-
7
- - versioned;
8
- - non-destructive by default;
9
- - explicit about prerequisites and post-upgrade manual steps.
10
-
11
- ## Verification Layer Compatibility
12
-
13
- Contexts without `capabilities`, with context version `0.1.0`, or without `ctx/docs/verification/` remain valid. A project may add a structurally complete Verification Layer when it has a durable specification; it should then advertise the `verification-layer` capability in `ctx/adsm.json`. Malformed adopted structure is a validation error, while absence is not.
package/skill/SKILL.md DELETED
@@ -1,48 +0,0 @@
1
- ---
2
- name: adsm-ctx
3
- description: Use when initializing, designing, validating, auditing, compressing, or upgrading ADSM project cognitive context. This skill orchestrates generic context lifecycle work and routes agents toward specialized skills when project-specific context branches are needed.
4
- ---
5
-
6
- # ADSM Context Lifecycle
7
-
8
- Manage the lifecycle of an ADSM project cognitive context. Manage generic context structure, documentation projections, lifecycle checks, and the `ctx/agent/` boundary; do not invent project-specific product, architecture, technical, or tool-workflow meaning.
9
-
10
- Humans own direction, accepted meaning, approval, and accountability. Agents refine, check consistency, maintain documentation, and report decisions that require human authority.
11
-
12
- ## Start Here
13
-
14
- 1. Identify the target repository and the requested lifecycle mode.
15
- 2. Read the applicable `AGENTS.md` hierarchy. If `ctx/` exists, read `ctx/AGENTS.md` and `ctx/docs/filesystem.md` before deeper context work.
16
- 3. Read [document-projections.md](references/document-projections.md) for any work under `ctx/docs/`; for skin work, also read [semantic-skins.md](references/semantic-skins.md).
17
- 4. Use the routing table below, then load only the references needed for the requested mode.
18
-
19
- ## Route The Request
20
-
21
- | Request or mode | Load or run |
22
- | --- | --- |
23
- | `init` baseline | [context-lifecycle.md](references/context-lifecycle.md); use the `templates/ctx/` baseline. |
24
- | `design` or new branch | [context-lifecycle.md](references/context-lifecycle.md), [design-questionnaire.md](references/design-questionnaire.md), and [specialized-skills.md](references/specialized-skills.md). |
25
- | Verification Layer or Software Evolution Loop | [document-projections.md](references/document-projections.md), [context-lifecycle.md](references/context-lifecycle.md), [documentation-quality-audit.md](references/documentation-quality-audit.md), and [specialized-skills.md](references/specialized-skills.md). |
26
- | `validate` structure | [context-lifecycle.md](references/context-lifecycle.md), [document-projections.md](references/document-projections.md), and the repository-provided deterministic validator when available. Report errors and warnings separately. |
27
- | `quality-audit` | Run `validate` first; then load [documentation-quality-audit.md](references/documentation-quality-audit.md). Report findings; do not rewrite project meaning. |
28
- | `documentation-compression` | Load [documentation-compression.md](references/documentation-compression.md). Rewrite only with authorization and preserve accepted meaning. |
29
- | `upgrade` | Load [upgrade-policy.md](references/upgrade-policy.md) and [context-lifecycle.md](references/context-lifecycle.md). Apply only safe, explicit migrations. |
30
- | `AGENTS.md` or local context routing | Load [agents-hierarchy.md](references/agents-hierarchy.md). |
31
- | `ctx/agent/`, templates, or generic ownership boundary | Load [orchestration-model.md](references/orchestration-model.md). |
32
- | Browser, backend, data, deployment, or concrete tool workflow | Load [specialized-skills.md](references/specialized-skills.md), then use a matching available specialized skill. |
33
-
34
- `adsm-ctx install-skill <skills-root>` installs this payload from the globally installed npm package into a skills root; it is not a lifecycle mode.
35
-
36
- ## Non-Negotiable Boundaries
37
-
38
- - Treat the cognitive context as the managed object and do not invent project facts, requirements, architecture, tool semantics, or authority boundaries.
39
- - Preserve the documentation order: product → architecture → environment → code. Escalate upstream gaps instead of introducing meaning downstream.
40
- - Read a matching `*.skin.<lang>.md` before editing its agent document. Report projection drift or a required human decision instead of silently changing skin-controlled meaning.
41
- - Keep `ctx/agent/` project-local: install only its boundary `AGENTS.md`; do not impose tool-specific structure, labels, prompts, roles, or executable profiles.
42
- - Keep assets under `ctx/assets/**`; they may illustrate, but never define, authoritative meaning.
43
- - Preserve the four ordered declarative documentation levels under `ctx/docs/`: `product`, `architecture`, `environment`, and `code`. Allow an optional cross-cutting `verification/` block only as defined in [document-projections.md](references/document-projections.md); it is never a fifth level.
44
- - Keep each documentation level to no more than nine direct directories and nine direct ordinary files, excluding `AGENTS.md` and paired `*.skin.<lang>.md` files, where practical; an intentional excess must be stated explicitly in that level's `AGENTS.md`.
45
-
46
- ## Completion
47
-
48
- Finish with explicit validation results, Verification Layer adoption state when relevant, specialization gaps, human decisions, and any preserved project-specific content. Use the relevant templates under `templates/ctx/` for initialization and `templates/work/` only when a working report is requested.
@@ -1,29 +0,0 @@
1
- # Upgrade Policy
2
-
3
- - Path: `skill/references/upgrade-policy.md`
4
- - Changed: `20260917`
5
-
6
- Upgrades must be non-destructive by default.
7
-
8
- ## Verification Layer Compatibility
9
-
10
- The `verification-layer` context convention capability is optional. Existing contexts without `capabilities`, with context version `0.1.0`, or without `ctx/docs/verification/` remain valid.
11
-
12
- Safe adoption may add `"verification-layer"` to `ctx/adsm.json` and add a structurally complete verification block only when the project has a real durable specification. It must not create `verification/`, empty categories, placeholder specifications, or copied specifications merely because an upgrade ran.
13
-
14
- Partial adoption is valid. Structural validation distinguishes absence from malformed adoption. An adopted block requires its root `AGENTS.md`; each created primary-target category must be a directory containing a durable specification. Unknown or unsupported categories and malformed capability metadata are validation findings.
15
-
16
- ## General Upgrade Boundaries
17
-
18
- Safe upgrade behavior includes:
19
-
20
- - adding missing files and directories only when migration rules explicitly require them;
21
- - updating metadata when rules are explicit;
22
- - preserving project-authored content unless replacement is proven safe;
23
- - detecting agent/skin pairs, orphan skins, and projection drift according to `skill/references/document-projections.md`;
24
- - preserving project-specific nested subdirectories and adopted verification specifications;
25
- - keeping visual, generated, rendered, and auxiliary artifacts under `ctx/assets/**`.
26
-
27
- Unsafe cases should be reported for manual follow-up instead of applied automatically.
28
-
29
- Upgrade must not introduce required `README.md` files inside `ctx/docs/`, automatically rewrite human-controlled skins when meaning is unclear, or claim that adoption provides verification coverage or runtime conformity.