@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.
- package/CHANGELOG.md +18 -0
- package/README.md +56 -40
- package/bin/adsm-ctx.mjs +1 -1
- package/package.json +5 -18
- package/skills/adsm-ctx/SKILL.md +72 -0
- package/{skill → skills/adsm-ctx}/references/agents-hierarchy.md +4 -2
- package/skills/adsm-ctx/references/context-evolution.md +59 -0
- package/{skill → skills/adsm-ctx}/references/context-lifecycle.md +20 -9
- package/{skill → skills/adsm-ctx}/references/design-questionnaire.md +3 -3
- package/{skill → skills/adsm-ctx}/references/document-projections.md +12 -10
- package/{skill → skills/adsm-ctx}/references/documentation-compression.md +5 -5
- package/{skill → skills/adsm-ctx}/references/documentation-quality-audit.md +6 -6
- package/{skill → skills/adsm-ctx}/references/orchestration-model.md +8 -6
- package/{skill → skills/adsm-ctx}/references/semantic-skins.md +3 -1
- package/{skill → skills/adsm-ctx}/references/specialized-skills.md +2 -2
- package/skills/adsm-ctx/references/testing-and-verification.md +12 -0
- package/skills/adsm-ctx/templates/AGENTS.md +23 -0
- package/skills/adsm-ctx/templates/ctx/AGENTS.md +46 -0
- package/{skill → skills/adsm-ctx}/templates/ctx/README.md +1 -1
- package/{skill → skills/adsm-ctx}/templates/ctx/adsm.json +1 -1
- package/skills/adsm-ctx/templates/ctx/agent/AGENTS.md +32 -0
- package/skills/adsm-ctx/templates/ctx/docs/AGENTS.md +64 -0
- package/{skill → skills/adsm-ctx}/templates/ctx/docs/code/testing.md +3 -1
- package/skills/adsm-ctx/templates/ctx/docs/verification/AGENTS.md +31 -0
- package/src/Cli/Command/Init.mjs +21 -5
- package/src/Cli/Command/InstallSkill.mjs +16 -5
- package/src/Cli/Command/Validate.mjs +17 -5
- package/src/Init/Service.mjs +26 -47
- package/src/Shared/Constants.mjs +4 -1
- package/src/Shared/CopyDirectory.mjs +9 -9
- package/src/Shared/Metadata.mjs +1 -1
- package/src/Skill/Installer.mjs +5 -5
- package/src/Validate/Service.mjs +159 -149
- package/types.d.ts +31 -4
- package/migrations/README.md +0 -13
- package/skill/SKILL.md +0 -48
- package/skill/references/upgrade-policy.md +0 -29
- package/skill/templates/AGENTS.md +0 -120
- package/skill/templates/ai/AGENTS.md +0 -59
- package/skill/templates/ctx/AGENTS.md +0 -45
- package/skill/templates/ctx/agent/AGENTS.md +0 -36
- package/skill/templates/ctx/docs/AGENTS.md +0 -58
- package/src/Cli/Command/Design.mjs +0 -17
- package/src/Cli/Command/Upgrade.mjs +0 -19
- package/src/Design/Service.mjs +0 -38
- package/src/Upgrade/Service.mjs +0 -44
- /package/{skill/templates/work → skills/adsm-ctx/assets}/context/semantic-skin.md +0 -0
- /package/{skill/templates/work → skills/adsm-ctx/assets}/report/documentation-compression.md +0 -0
- /package/{skill/templates/work → skills/adsm-ctx/assets}/report/documentation-quality-audit.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/assets/.gitkeep +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/ai-intro.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/AGENTS.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/behavior.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/checklists.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/constraints.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/decisions.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/integration.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/overview.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/state.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/structure.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/architecture/supervision.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/code/AGENTS.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/code/overview.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/environment/AGENTS.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/environment/overview.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/filesystem.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/product/AGENTS.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/product/domain.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/product/glossary.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/product/overview.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/product/roles.md +0 -0
- /package/{skill → skills/adsm-ctx}/templates/ctx/docs/product/use-cases.md +0 -0
package/src/Validate/Service.mjs
CHANGED
|
@@ -21,30 +21,9 @@ export default class Validate {
|
|
|
21
21
|
/**
|
|
22
22
|
* Validates context structure.
|
|
23
23
|
*
|
|
24
|
-
* @param {object}
|
|
25
|
-
* @param {string}
|
|
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.
|
|
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}
|
|
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}
|
|
132
|
-
* @param {string}
|
|
133
|
-
* @param {string}
|
|
134
|
-
* @param {string}
|
|
135
|
-
* @param {
|
|
136
|
-
* @returns {
|
|
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 {
|
|
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}
|
|
177
|
-
* @param {Fl32_Skill_Adsm_Ctx_Shared_Constants}
|
|
178
|
-
* @param {typeof import("node:fs")}
|
|
179
|
-
* @param {Fl32_Skill_Adsm_Ctx_Shared_Path}
|
|
180
|
-
* @param {string}
|
|
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 (
|
|
185
|
+
if (parsed.version !== constants.CONTEXT_VERSION) {
|
|
213
186
|
findings.push(createFinding({
|
|
214
|
-
message:
|
|
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:
|
|
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}
|
|
269
|
-
* @param {Fl32_Skill_Adsm_Ctx_Shared_Constants}
|
|
270
|
-
* @param {typeof import("node:fs")}
|
|
271
|
-
* @param {Fl32_Skill_Adsm_Ctx_Shared_Path}
|
|
272
|
-
* @param {string}
|
|
273
|
-
* @
|
|
274
|
-
*
|
|
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
|
|
387
|
+
* Inspects the cross-cutting Verification Layer without treating it as a fifth
|
|
428
388
|
* declarative documentation level.
|
|
429
389
|
*
|
|
430
|
-
* @param {object}
|
|
431
|
-
* @param {Fl32_Skill_Adsm_Ctx_Shared_Constants}
|
|
432
|
-
* @param {
|
|
433
|
-
* @param {typeof import("node:fs")}
|
|
434
|
-
* @param {Fl32_Skill_Adsm_Ctx_Shared_Path}
|
|
435
|
-
* @param {string}
|
|
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}
|
|
549
|
-
* @param {Fl32_Skill_Adsm_Ctx_Shared_Constants}
|
|
550
|
-
* @param {
|
|
551
|
-
* @param {typeof import("node:fs")}
|
|
552
|
-
* @param {Fl32_Skill_Adsm_Ctx_Shared_Path}
|
|
553
|
-
* @param {string}
|
|
554
|
-
* @returns {
|
|
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}
|
|
621
|
-
* @param {typeof import("node:fs")}
|
|
622
|
-
* @param {Fl32_Skill_Adsm_Ctx_Shared_Path}
|
|
623
|
-
* @param {string}
|
|
624
|
-
* @param {string}
|
|
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}
|
|
643
|
-
* @param {typeof import("node:fs")}
|
|
644
|
-
* @param {string}
|
|
645
|
-
* @returns {
|
|
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}
|
|
653
|
-
* @param {string}
|
|
654
|
-
* @param {
|
|
655
|
-
* @
|
|
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}
|
|
699
|
-
* @param {string}
|
|
700
|
-
* @param {typeof import("node:fs")}
|
|
701
|
-
* @param {Fl32_Skill_Adsm_Ctx_Shared_Path}
|
|
702
|
-
* @param {string}
|
|
703
|
-
* @param {string}
|
|
704
|
-
* @returns {
|
|
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}
|
|
737
|
-
* @param {
|
|
738
|
-
* @param {Fl32_Skill_Adsm_Ctx_Shared_Constants}
|
|
739
|
-
* @param {string}
|
|
740
|
-
* @param {
|
|
741
|
-
* @
|
|
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}
|
|
766
|
-
* @param {string}
|
|
767
|
-
* @param {string}
|
|
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}
|
|
788
|
-
* @param {string}
|
|
789
|
-
* @param {string}
|
|
790
|
-
* @returns {
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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 {};
|
package/migrations/README.md
DELETED
|
@@ -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.
|