@ryuenn3123/agentic-senior-core 3.0.15 → 3.0.16

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.
@@ -16,7 +16,26 @@
16
16
  import { readdir, readFile, stat } from 'node:fs/promises';
17
17
  import { dirname, join, relative, resolve } from 'node:path';
18
18
  import { fileURLToPath } from 'node:url';
19
- import { createHash } from 'node:crypto';
19
+ import {
20
+ ALLOWED_SEVERITIES,
21
+ OVERRIDE_WARNING_WINDOW_DAYS,
22
+ REQUIRED_STACK_RESEARCH_ENGINE_SNIPPETS,
23
+ } from './validate/config.mjs';
24
+ import {
25
+ validateDependencyFreshnessAutomationCoverage,
26
+ validateDetectionTransparencyCoverage,
27
+ validateDeterministicBoundaryEnforcementCoverage,
28
+ validateDockerRuntimeAutomationCoverage,
29
+ validateHumanWritingGovernance,
30
+ validateInstructionAdapters,
31
+ validateSkillPurgeSurface,
32
+ validateStackResearchEngineCoverage,
33
+ validateTemplateFreeBootstrapCoverage,
34
+ validateTerminologyMapping,
35
+ validateUiDesignAutomationCoverage,
36
+ validateUniversalSopConsolidationCoverage,
37
+ validateUpgradeUiContractWarningCoverage,
38
+ } from './validate/coverage-checks.mjs';
20
39
 
21
40
  const SCRIPT_FILE_PATH = fileURLToPath(import.meta.url);
22
41
  const ROOT_DIR = resolve(dirname(SCRIPT_FILE_PATH), '..');
@@ -28,393 +47,6 @@ const README_PATH = join(ROOT_DIR, 'README.md');
28
47
  const POLICY_FILE_PATH = join(ROOT_DIR, '.agent-context', 'policies', 'llm-judge-threshold.json');
29
48
  const OVERRIDE_FILE_PATH = join(ROOT_DIR, '.agent-override.md');
30
49
  const GENERATED_RULE_FILES = ['.cursorrules', '.windsurfrules'];
31
- const ALLOWED_SEVERITIES = new Set(['critical', 'high', 'medium', 'low']);
32
- const OVERRIDE_WARNING_WINDOW_DAYS = 30;
33
- const THIN_ADAPTER_PATHS = [
34
- 'AGENTS.md',
35
- '.github/copilot-instructions.md',
36
- '.gemini/instructions.md',
37
- ];
38
- const FORMAL_ARTIFACT_PATHS = [
39
- '.instructions.md',
40
- 'README.md',
41
- 'CHANGELOG.md',
42
- 'docs/deep_analysis_and_roadmap_backlog.md',
43
- '.agent-context/rules/api-docs.md',
44
- '.agent-context/review-checklists/pr-checklist.md',
45
- '.agent-context/prompts/review-code.md',
46
- 'AGENTS.md',
47
- '.github/copilot-instructions.md',
48
- '.gemini/instructions.md',
49
- ];
50
- const REQUIRED_HUMAN_WRITING_SNIPPETS = [
51
- {
52
- path: '.agent-context/rules/api-docs.md',
53
- snippets: [
54
- '## Human Writing Standard (Mandatory)',
55
- 'This applies to documentation, release notes, onboarding text, review summaries, and agent-facing explanations.',
56
- 'Style baseline findings are advisory by default and must not block endpoint-change commits that already include accurate docs/spec updates.',
57
- 'No emoji in formal artifacts.',
58
- ],
59
- },
60
- {
61
- path: '.agent-context/review-checklists/pr-checklist.md',
62
- snippets: [
63
- 'Scope applied: This applies to documentation, release notes, onboarding text, review summaries, and agent-facing explanations',
64
- 'Style scope review is advisory and does not block merge when API docs are synced in the same commit and contract details are correct',
65
- 'No emoji in formal documentation or review summaries',
66
- 'Documentation uses plain English and avoids AI cliches',
67
- ],
68
- },
69
- {
70
- path: 'docs/deep_analysis_and_roadmap_backlog.md',
71
- snippets: [
72
- '## Part 6: Documentation and Explanation Standards (Mandatory)',
73
- 'This applies to documentation, release notes, onboarding text, review summaries, and agent-facing explanations.',
74
- 'No emoji in formal artifacts. This is mandatory.',
75
- ],
76
- },
77
- ];
78
- const TERMINOLOGY_REFERENCE_PATHS = [
79
- 'README.md',
80
- 'docs/roadmap.md',
81
- ];
82
- const REQUIRED_TERMINOLOGY_ROW_PATTERNS = [
83
- {
84
- label: 'Federated Governance -> Federated Rules Operations',
85
- pattern: /\|\s*Federated Governance\s*\|\s*Federated Rules Operations\s*\|/u,
86
- },
87
- {
88
- label: 'Governance Engine -> Rules Engine',
89
- pattern: /\|\s*Governance Engine\s*\|\s*Rules Engine\s*\|/u,
90
- },
91
- {
92
- label: 'Guardrails -> Quality Checks',
93
- pattern: /\|\s*Guardrails\s*\|\s*Quality Checks\s*\|/u,
94
- },
95
- ];
96
- const REQUIRED_TERMINOLOGY_RULE_SNIPPET =
97
- 'Rule: on first mention in developer-facing docs, include canonical term in parentheses.';
98
- const TERMINOLOGY_REFERENCE_DOCUMENT_PATH = 'docs/terminology-mapping.md';
99
- const REQUIRED_DEVELOPER_FIRST_MENTION_PATTERNS = [
100
- {
101
- path: 'README.md',
102
- label: 'Rules Engine first mention includes Governance Engine',
103
- pattern: /Rules Engine\s*\(Governance Engine\)/u,
104
- },
105
- {
106
- path: 'docs/deep-dive.md',
107
- label: 'Dynamic Rules Engine first mention includes Governance Engine',
108
- pattern: /Dynamic Rules Engine\s*\(Governance Engine\)/u,
109
- },
110
- {
111
- path: 'docs/faq.md',
112
- label: 'Quality Checks first mention includes Guardrails',
113
- pattern: /Quality Checks\s*\(Guardrails\)/u,
114
- },
115
- {
116
- path: '.agent-context/prompts/init-project.md',
117
- label: 'Init prompt first mention includes Federated Governance baseline',
118
- pattern: /rules operations context\s*\(Federated Governance baseline\)/iu,
119
- },
120
- {
121
- path: 'lib/cli/commands/init.mjs',
122
- label: 'Init command wording includes Federated Governance baseline',
123
- pattern: /rules operations\s+(assets|pack)[^\n]*\(Federated Governance baseline\)/iu,
124
- },
125
- {
126
- path: 'lib/cli/commands/upgrade.mjs',
127
- label: 'Upgrade command wording includes Federated Governance baseline',
128
- pattern: /rules operations upgrade assistant\s*\(Federated Governance baseline\)/iu,
129
- },
130
- {
131
- path: 'lib/cli/utils.mjs',
132
- label: 'CLI help wording includes quality checks and guardrails',
133
- pattern: /quality checks\s*\(guardrails\)/iu,
134
- },
135
- ];
136
- const COMPLIANCE_TERMINOLOGY_BOUNDARY_PATHS = [
137
- '.agent-context/review-checklists/pr-checklist.md',
138
- '.agent-context/review-checklists/architecture-review.md',
139
- 'scripts/release-gate.mjs',
140
- 'scripts/forbidden-content-check.mjs',
141
- ];
142
- const COMPLIANCE_ALIAS_TERMS = [
143
- 'Federated Rules Operations',
144
- ];
145
- const REQUIRED_COMPLIANCE_CANONICAL_SNIPPETS = [
146
- {
147
- path: '.agent-context/review-checklists/pr-checklist.md',
148
- snippet: '### 15. Universal SOP Consolidation',
149
- label: 'PR checklist keeps consolidated Universal SOP section',
150
- },
151
- ];
152
- const REQUIRED_DETECTION_TRANSPARENCY_SNIPPETS = [
153
- {
154
- path: 'lib/cli/commands/init.mjs',
155
- snippets: [
156
- 'Existing project detection transparency:',
157
- 'Use detected setup for this existing project?',
158
- 'detectionTransparency',
159
- ],
160
- },
161
- {
162
- path: 'lib/cli/commands/upgrade.mjs',
163
- snippets: [
164
- 'Existing project detection transparency:',
165
- 'formatDetectionCandidates(projectDetection.rankedCandidates)',
166
- 'detectionTransparency',
167
- ],
168
- },
169
- {
170
- path: 'lib/cli/compiler.mjs',
171
- snippets: [
172
- 'detectionTransparency = null',
173
- 'detectionTransparency: detectionTransparency || null',
174
- ],
175
- },
176
- ];
177
- const REQUIRED_STACK_RESEARCH_ENGINE_SNIPPETS = [
178
- {
179
- path: 'lib/cli/architect.mjs',
180
- snippets: [
181
- 'ARCHITECT_RESEARCH_SNAPSHOT_FILE_PATH',
182
- 'evidenceCitations',
183
- 'designGuidance',
184
- 'copiedExternalProse: false',
185
- 'realtimeGateEnabled',
186
- 'requestedMode: requestedResearchMode',
187
- ],
188
- },
189
- {
190
- path: 'lib/cli/commands/init.mjs',
191
- snippets: [
192
- '--architect-research-mode',
193
- '--enable-realtime-research',
194
- '--architect-realtime-signal-file',
195
- 'researchMode: initOptions.architectResearchMode',
196
- 'enableRealtimeResearch: initOptions.enableRealtimeResearch',
197
- ],
198
- },
199
- ];
200
- const REQUIRED_UNIVERSAL_SOP_SNIPPETS = [
201
- {
202
- path: '.agent-context/rules/architecture.md',
203
- snippets: [
204
- '## Universal SOP Baseline (Mandatory)',
205
- 'Security and testing are non-negotiable baseline requirements.',
206
- 'If required project context docs are missing, stop implementation and bootstrap docs before writing application code.',
207
- ],
208
- },
209
- {
210
- path: '.agent-context/review-checklists/pr-checklist.md',
211
- snippets: [
212
- '### 15. Universal SOP Consolidation',
213
- 'Coding flow is blocked if `docs/architecture-decision-record.md` (or `docs/Architecture-Decision-Record.md`) is missing',
214
- 'UI implementation flow is blocked if `docs/DESIGN.md` or `docs/design-intent.json` is missing',
215
- ],
216
- },
217
- {
218
- path: '.agent-context/prompts/review-code.md',
219
- snippets: [
220
- 'Enforce Universal SOP hard gate: block coding flow when required project docs are missing (`docs/architecture-decision-record.md`, and for UI scope `docs/DESIGN.md` plus `docs/design-intent.json`).',
221
- ],
222
- },
223
- {
224
- path: '.agent-context/prompts/refactor.md',
225
- snippets: [
226
- '6. Enforce Universal SOP hard gate: stop implementation if `docs/architecture-decision-record.md` is missing, and for UI scope stop if `docs/DESIGN.md` or `docs/design-intent.json` is missing.',
227
- ],
228
- },
229
- {
230
- path: 'lib/cli/compiler.mjs',
231
- snippets: [
232
- 'Universal SOP hard block policy:',
233
- 'Hard block: do not write application code until docs/project-brief.md and docs/architecture-decision-record.md exist.',
234
- 'For UI scope: if docs/DESIGN.md or docs/design-intent.json is missing, execute bootstrap-design prompt before implementing UI surfaces.',
235
- ],
236
- },
237
- ];
238
- const REQUIRED_TEMPLATE_FREE_BOOTSTRAP_SNIPPETS = [
239
- {
240
- path: 'lib/cli/project-scaffolder.mjs',
241
- snippets: [
242
- 'resolveProjectDocTargets',
243
- 'Write project context docs from scratch (no template rendering, no placeholder boilerplate).',
244
- 'For any research-backed claim, include citation metadata (source + fetchedAt timestamp) from the Architect Engine Snapshot.',
245
- "bootstrapMode: 'ai-synthesis'",
246
- ],
247
- },
248
- {
249
- path: 'lib/cli/commands/init.mjs',
250
- snippets: [
251
- 'Project docs will be authored dynamically by your IDE assistant from these prompts.',
252
- 'bootstrap-project-context.md',
253
- 'Seed docs:',
254
- 'I prepared dynamic synthesis bootstrap prompts',
255
- ],
256
- },
257
- ];
258
- const REQUIRED_UPGRADE_UI_CONTRACT_WARNING_SNIPPETS = [
259
- {
260
- path: 'lib/cli/commands/upgrade.mjs',
261
- snippets: [
262
- 'UI/frontend scope was detected, but the dynamic design contract is incomplete:',
263
- 'docs/design-intent.json',
264
- 'Planned seed on apply: docs/design-intent.json',
265
- 'Upgrade synchronizes governance assets and can seed docs/design-intent.json, but it does not author project-specific docs/DESIGN.md automatically.',
266
- 'detectUiScopeSignals',
267
- 'seed-generated-during-upgrade',
268
- ],
269
- },
270
- ];
271
- const REQUIRED_UI_DESIGN_AUTOMATION_SNIPPETS = [
272
- {
273
- path: '.instructions.md',
274
- snippets: [
275
- 'UI Design Mode',
276
- 'bootstrap-design.md',
277
- 'frontend-architecture.md',
278
- 'do not eagerly load unrelated backend-only rules',
279
- ],
280
- },
281
- {
282
- path: '.agent-context/prompts/bootstrap-design.md',
283
- snippets: [
284
- 'UI Design Mode is context-isolated by default:',
285
- 'Responsive Strategy and Cross-Viewport Adaptation Matrix',
286
- '`colorTruth.format`',
287
- '`crossViewportAdaptation.mutationRules.mobile/tablet/desktop`',
288
- '`motionSystem`',
289
- '`componentMorphology`',
290
- 'Do not reuse a color palette, component skin, or motion signature from prior chats, memories, or unrelated projects',
291
- 'If no approved reference system exists, synthesize the design from zero using current product context, constraints, and content only.',
292
- ],
293
- },
294
- {
295
- path: 'scripts/ui-design-judge.mjs',
296
- snippets: [
297
- 'Advisory-first UI design contract judge.',
298
- 'Repo-internal workflow audit; no user-facing runtime modes.',
299
- 'Runs only in advisory mode for this repository workflow.',
300
- 'Do not reward generic SaaS defaults or popular template patterns.',
301
- 'UI design judge only evaluates changed UI surfaces.',
302
- ],
303
- },
304
- {
305
- path: 'lib/cli/project-scaffolder.mjs',
306
- snippets: [
307
- 'colorTruth',
308
- 'crossViewportAdaptation',
309
- 'motionSystem',
310
- 'componentMorphology',
311
- 'requireViewportMutationRules',
312
- 'allowHexDerivatives',
313
- ],
314
- },
315
- {
316
- path: 'lib/cli/detector.mjs',
317
- snippets: [
318
- 'hardcodedColorCount',
319
- 'propDrillingCandidateCount',
320
- 'arbitraryBreakpointCount',
321
- 'frontendEvidenceMetrics',
322
- ],
323
- },
324
- {
325
- path: 'lib/cli/compiler.mjs',
326
- snippets: [
327
- 'LAYER 5: EXECUTION PROMPTS AND UI TRIGGERS',
328
- 'bootstrap-design.md -> ui, ux, layout, screen, tailwind, frontend, redesign',
329
- 'Keep UI-only requests context-isolated',
330
- ],
331
- },
332
- ];
333
- const REQUIRED_DOCKER_RUNTIME_AUTOMATION_SNIPPETS = [
334
- {
335
- path: '.instructions.md',
336
- snippets: [
337
- 'docker-runtime.md',
338
- 'For Docker or Compose work, load `docker-runtime.md` and verify the latest official Docker docs before authoring container assets.',
339
- ],
340
- },
341
- {
342
- path: '.agent-context/rules/docker-runtime.md',
343
- snippets: [
344
- 'latest official Docker documentation first',
345
- 'Docker Compose Quickstart',
346
- 'Compose file reference',
347
- 'Dockerfile best practices',
348
- 'Prefer current `docker compose` workflows and `compose.yaml`.',
349
- 'Do not add the top-level Compose `version` field by default.',
350
- 'Prefer the latest stable compatible Docker base image',
351
- ],
352
- },
353
- {
354
- path: '.agent-context/prompts/init-project.md',
355
- snippets: [
356
- 'If Docker or Compose is in scope, load [docker-runtime.md](../rules/docker-runtime.md) and verify the latest official Docker guidance before authoring container assets.',
357
- 'If containerization is selected, Docker assets must follow [docker-runtime.md](../rules/docker-runtime.md) and the latest official Docker docs instead of stale blog-era patterns.',
358
- ],
359
- },
360
- ];
361
- const REQUIRED_DEPENDENCY_FRESHNESS_AUTOMATION_SNIPPETS = [
362
- {
363
- path: '.instructions.md',
364
- snippets: [
365
- 'prefer the latest stable compatible dependency set and official setup flow',
366
- ],
367
- },
368
- {
369
- path: '.agent-context/rules/efficiency-vs-hype.md',
370
- snippets: [
371
- 'Latest-Compatible-First Rule',
372
- 'latest stable compatible dependency version',
373
- 'official scaffolder or setup command',
374
- 'Only step down to an older dependency version after documenting',
375
- ],
376
- },
377
- {
378
- path: '.agent-context/prompts/init-project.md',
379
- snippets: [
380
- 'latest stable compatible dependency set and official framework setup flow first',
381
- 'Prefer official framework setup commands or canonical starter flows',
382
- ],
383
- },
384
- ];
385
- const FORBIDDEN_TEMPLATE_BOOTSTRAP_SNIPPETS = [
386
- {
387
- path: 'lib/cli/project-scaffolder.mjs',
388
- snippets: [
389
- '.tmpl',
390
- ],
391
- },
392
- ];
393
- const REQUIRED_DETERMINISTIC_BOUNDARY_ENFORCEMENT_SNIPPETS = [
394
- {
395
- path: 'scripts/documentation-boundary-audit.mjs',
396
- snippets: [
397
- 'reportVersion',
398
- 'violations',
399
- 'suggestedActions',
400
- 'diagnosticCode',
401
- 'autoDocsSyncScope',
402
- 'rolloutMetrics',
403
- 'precision',
404
- 'recall',
405
- ],
406
- },
407
- {
408
- path: 'scripts/release-gate.mjs',
409
- snippets: [
410
- 'documentation-boundary-hard-rule',
411
- 'documentation-boundary-diagnostics-machine-readable',
412
- 'diagnostics.documentationBoundaryAudit',
413
- 'auto-docs-sync-scope-phase1',
414
- 'auto-docs-sync-rollout-metrics',
415
- ],
416
- },
417
- ];
418
50
 
419
51
  const validationResult = {
420
52
  passed: 0,
@@ -926,347 +558,6 @@ async function validateDocumentationFlow() {
926
558
  }
927
559
  }
928
560
 
929
- async function validateTerminologyMapping() {
930
- console.log('\nChecking terminology mapping consistency...');
931
-
932
- const terminologyReferenceDocumentPath = join(ROOT_DIR, TERMINOLOGY_REFERENCE_DOCUMENT_PATH);
933
-
934
- if (!(await fileExists(terminologyReferenceDocumentPath))) {
935
- fail(`Missing terminology reference document: ${TERMINOLOGY_REFERENCE_DOCUMENT_PATH}`);
936
- } else {
937
- const terminologyReferenceContent = await readTextFile(terminologyReferenceDocumentPath);
938
-
939
- if (terminologyReferenceContent.includes('Dual-Term Mapping')) {
940
- pass(`${TERMINOLOGY_REFERENCE_DOCUMENT_PATH} includes Dual-Term Mapping section`);
941
- } else {
942
- fail(`${TERMINOLOGY_REFERENCE_DOCUMENT_PATH} must include Dual-Term Mapping section`);
943
- }
944
-
945
- for (const terminologyRowRule of REQUIRED_TERMINOLOGY_ROW_PATTERNS) {
946
- if (terminologyRowRule.pattern.test(terminologyReferenceContent)) {
947
- pass(`${TERMINOLOGY_REFERENCE_DOCUMENT_PATH} includes mapping row: ${terminologyRowRule.label}`);
948
- } else {
949
- fail(`${TERMINOLOGY_REFERENCE_DOCUMENT_PATH} is missing mapping row: ${terminologyRowRule.label}`);
950
- }
951
- }
952
-
953
- if (terminologyReferenceContent.includes('first mention must include canonical term in parentheses')) {
954
- pass(`${TERMINOLOGY_REFERENCE_DOCUMENT_PATH} defines first-mention canonical term rule`);
955
- } else {
956
- fail(`${TERMINOLOGY_REFERENCE_DOCUMENT_PATH} must define first-mention canonical term rule`);
957
- }
958
-
959
- if (terminologyReferenceContent.includes('Compliance and audit artifacts must keep canonical enterprise terminology')) {
960
- pass(`${TERMINOLOGY_REFERENCE_DOCUMENT_PATH} defines compliance terminology boundary`);
961
- } else {
962
- fail(`${TERMINOLOGY_REFERENCE_DOCUMENT_PATH} must define compliance terminology boundary`);
963
- }
964
- }
965
-
966
- for (const terminologyReferencePath of TERMINOLOGY_REFERENCE_PATHS) {
967
- const absoluteReferencePath = join(ROOT_DIR, terminologyReferencePath);
968
-
969
- if (!(await fileExists(absoluteReferencePath))) {
970
- fail(`Missing terminology reference source: ${terminologyReferencePath}`);
971
- continue;
972
- }
973
-
974
- const referenceContent = await readTextFile(absoluteReferencePath);
975
-
976
- if (referenceContent.includes('Terminology Mapping (Final)')) {
977
- pass(`${terminologyReferencePath} includes Terminology Mapping (Final)`);
978
- } else {
979
- fail(`${terminologyReferencePath} must include Terminology Mapping (Final)`);
980
- }
981
-
982
- for (const terminologyRowRule of REQUIRED_TERMINOLOGY_ROW_PATTERNS) {
983
- if (terminologyRowRule.pattern.test(referenceContent)) {
984
- pass(`${terminologyReferencePath} includes mapping row: ${terminologyRowRule.label}`);
985
- } else {
986
- fail(`${terminologyReferencePath} is missing mapping row: ${terminologyRowRule.label}`);
987
- }
988
- }
989
-
990
- if (referenceContent.includes(REQUIRED_TERMINOLOGY_RULE_SNIPPET)) {
991
- pass(`${terminologyReferencePath} includes first-mention canonical term rule`);
992
- } else {
993
- fail(`${terminologyReferencePath} must include first-mention canonical term rule`);
994
- }
995
-
996
- if (referenceContent.includes(TERMINOLOGY_REFERENCE_DOCUMENT_PATH)) {
997
- pass(`${terminologyReferencePath} links to ${TERMINOLOGY_REFERENCE_DOCUMENT_PATH}`);
998
- } else {
999
- fail(`${terminologyReferencePath} must link to ${TERMINOLOGY_REFERENCE_DOCUMENT_PATH}`);
1000
- }
1001
- }
1002
-
1003
- for (const firstMentionRule of REQUIRED_DEVELOPER_FIRST_MENTION_PATTERNS) {
1004
- const absoluteFirstMentionPath = join(ROOT_DIR, firstMentionRule.path);
1005
-
1006
- if (!(await fileExists(absoluteFirstMentionPath))) {
1007
- fail(`Missing developer-facing first-mention source: ${firstMentionRule.path}`);
1008
- continue;
1009
- }
1010
-
1011
- const firstMentionContent = await readTextFile(absoluteFirstMentionPath);
1012
- if (firstMentionRule.pattern.test(firstMentionContent)) {
1013
- pass(`${firstMentionRule.path} keeps first-mention rule: ${firstMentionRule.label}`);
1014
- } else {
1015
- fail(`${firstMentionRule.path} must keep first-mention rule: ${firstMentionRule.label}`);
1016
- }
1017
- }
1018
-
1019
- for (const compliancePath of COMPLIANCE_TERMINOLOGY_BOUNDARY_PATHS) {
1020
- const absoluteCompliancePath = join(ROOT_DIR, compliancePath);
1021
-
1022
- if (!(await fileExists(absoluteCompliancePath))) {
1023
- fail(`Missing compliance/audit artifact for terminology boundary: ${compliancePath}`);
1024
- continue;
1025
- }
1026
-
1027
- const complianceContent = await readTextFile(absoluteCompliancePath);
1028
- for (const aliasTerm of COMPLIANCE_ALIAS_TERMS) {
1029
- if (complianceContent.includes(aliasTerm)) {
1030
- fail(`${compliancePath} must not use developer-facing alias in compliance context: ${aliasTerm}`);
1031
- } else {
1032
- pass(`${compliancePath} keeps canonical terminology boundary for alias: ${aliasTerm}`);
1033
- }
1034
- }
1035
- }
1036
-
1037
- for (const complianceRule of REQUIRED_COMPLIANCE_CANONICAL_SNIPPETS) {
1038
- const absoluteComplianceRulePath = join(ROOT_DIR, complianceRule.path);
1039
-
1040
- if (!(await fileExists(absoluteComplianceRulePath))) {
1041
- fail(`Missing compliance canonical source: ${complianceRule.path}`);
1042
- continue;
1043
- }
1044
-
1045
- const complianceRuleContent = await readTextFile(absoluteComplianceRulePath);
1046
- if (complianceRuleContent.includes(complianceRule.snippet)) {
1047
- pass(`${complianceRule.path} keeps canonical terminology rule: ${complianceRule.label}`);
1048
- } else {
1049
- fail(`${complianceRule.path} must keep canonical terminology rule: ${complianceRule.label}`);
1050
- }
1051
- }
1052
- }
1053
-
1054
- async function validateDetectionTransparencyCoverage() {
1055
- console.log('\nChecking existing-project detection transparency coverage...');
1056
-
1057
- for (const transparencyRule of REQUIRED_DETECTION_TRANSPARENCY_SNIPPETS) {
1058
- const absoluteTransparencyPath = join(ROOT_DIR, transparencyRule.path);
1059
-
1060
- if (!(await fileExists(absoluteTransparencyPath))) {
1061
- fail(`Missing detection transparency source: ${transparencyRule.path}`);
1062
- continue;
1063
- }
1064
-
1065
- const transparencyContent = await readTextFile(absoluteTransparencyPath);
1066
- for (const requiredSnippet of transparencyRule.snippets) {
1067
- if (transparencyContent.includes(requiredSnippet)) {
1068
- pass(`${transparencyRule.path} includes detection transparency snippet: ${requiredSnippet}`);
1069
- } else {
1070
- fail(`${transparencyRule.path} is missing detection transparency snippet: ${requiredSnippet}`);
1071
- }
1072
- }
1073
- }
1074
- }
1075
-
1076
- async function validateStackResearchEngineCoverage() {
1077
- console.log('\nChecking stack research engine coverage...');
1078
-
1079
- for (const coverageRule of REQUIRED_STACK_RESEARCH_ENGINE_SNIPPETS) {
1080
- const absoluteCoveragePath = join(ROOT_DIR, coverageRule.path);
1081
-
1082
- if (!(await fileExists(absoluteCoveragePath))) {
1083
- fail(`Missing stack research source: ${coverageRule.path}`);
1084
- continue;
1085
- }
1086
-
1087
- const coverageContent = await readTextFile(absoluteCoveragePath);
1088
- for (const requiredSnippet of coverageRule.snippets) {
1089
- if (coverageContent.includes(requiredSnippet)) {
1090
- pass(`${coverageRule.path} includes stack research snippet: ${requiredSnippet}`);
1091
- } else {
1092
- fail(`${coverageRule.path} is missing stack research snippet: ${requiredSnippet}`);
1093
- }
1094
- }
1095
- }
1096
- }
1097
-
1098
- async function validateUniversalSopConsolidationCoverage() {
1099
- console.log('\nChecking Universal SOP consolidation coverage...');
1100
-
1101
- for (const coverageRule of REQUIRED_UNIVERSAL_SOP_SNIPPETS) {
1102
- const absoluteCoveragePath = join(ROOT_DIR, coverageRule.path);
1103
-
1104
- if (!(await fileExists(absoluteCoveragePath))) {
1105
- fail(`Missing Universal SOP source: ${coverageRule.path}`);
1106
- continue;
1107
- }
1108
-
1109
- const coverageContent = await readTextFile(absoluteCoveragePath);
1110
- for (const requiredSnippet of coverageRule.snippets) {
1111
- if (coverageContent.includes(requiredSnippet)) {
1112
- pass(`${coverageRule.path} includes Universal SOP snippet: ${requiredSnippet}`);
1113
- } else {
1114
- fail(`${coverageRule.path} is missing Universal SOP snippet: ${requiredSnippet}`);
1115
- }
1116
- }
1117
- }
1118
- }
1119
-
1120
- async function validateTemplateFreeBootstrapCoverage() {
1121
- console.log('\nChecking template-free dynamic bootstrap coverage...');
1122
-
1123
- for (const coverageRule of REQUIRED_TEMPLATE_FREE_BOOTSTRAP_SNIPPETS) {
1124
- const absoluteCoveragePath = join(ROOT_DIR, coverageRule.path);
1125
-
1126
- if (!(await fileExists(absoluteCoveragePath))) {
1127
- fail(`Missing template-free bootstrap source: ${coverageRule.path}`);
1128
- continue;
1129
- }
1130
-
1131
- const coverageContent = await readTextFile(absoluteCoveragePath);
1132
- for (const requiredSnippet of coverageRule.snippets) {
1133
- if (coverageContent.includes(requiredSnippet)) {
1134
- pass(`${coverageRule.path} includes template-free bootstrap snippet: ${requiredSnippet}`);
1135
- } else {
1136
- fail(`${coverageRule.path} is missing template-free bootstrap snippet: ${requiredSnippet}`);
1137
- }
1138
- }
1139
- }
1140
-
1141
- for (const forbiddenRule of FORBIDDEN_TEMPLATE_BOOTSTRAP_SNIPPETS) {
1142
- const absoluteForbiddenPath = join(ROOT_DIR, forbiddenRule.path);
1143
-
1144
- if (!(await fileExists(absoluteForbiddenPath))) {
1145
- fail(`Missing template-free bootstrap source: ${forbiddenRule.path}`);
1146
- continue;
1147
- }
1148
-
1149
- const forbiddenContent = await readTextFile(absoluteForbiddenPath);
1150
- for (const forbiddenSnippet of forbiddenRule.snippets) {
1151
- if (forbiddenContent.includes(forbiddenSnippet)) {
1152
- fail(`${forbiddenRule.path} must not include active template snippet: ${forbiddenSnippet}`);
1153
- } else {
1154
- pass(`${forbiddenRule.path} excludes active template snippet: ${forbiddenSnippet}`);
1155
- }
1156
- }
1157
- }
1158
- }
1159
-
1160
- async function validateUpgradeUiContractWarningCoverage() {
1161
- console.log('\nChecking upgrade UI contract warning coverage...');
1162
-
1163
- for (const coverageRule of REQUIRED_UPGRADE_UI_CONTRACT_WARNING_SNIPPETS) {
1164
- const absoluteCoveragePath = join(ROOT_DIR, coverageRule.path);
1165
-
1166
- if (!(await fileExists(absoluteCoveragePath))) {
1167
- fail(`Missing upgrade UI contract warning source: ${coverageRule.path}`);
1168
- continue;
1169
- }
1170
-
1171
- const coverageContent = await readTextFile(absoluteCoveragePath);
1172
- for (const requiredSnippet of coverageRule.snippets) {
1173
- if (coverageContent.includes(requiredSnippet)) {
1174
- pass(`${coverageRule.path} includes upgrade UI contract warning snippet: ${requiredSnippet}`);
1175
- } else {
1176
- fail(`${coverageRule.path} is missing upgrade UI contract warning snippet: ${requiredSnippet}`);
1177
- }
1178
- }
1179
- }
1180
- }
1181
-
1182
- async function validateUiDesignAutomationCoverage() {
1183
- console.log('\nChecking UI design automation coverage...');
1184
-
1185
- for (const coverageRule of REQUIRED_UI_DESIGN_AUTOMATION_SNIPPETS) {
1186
- const absoluteCoveragePath = join(ROOT_DIR, coverageRule.path);
1187
-
1188
- if (!(await fileExists(absoluteCoveragePath))) {
1189
- fail(`Missing UI design automation source: ${coverageRule.path}`);
1190
- continue;
1191
- }
1192
-
1193
- const coverageContent = await readTextFile(absoluteCoveragePath);
1194
- for (const requiredSnippet of coverageRule.snippets) {
1195
- if (coverageContent.includes(requiredSnippet)) {
1196
- pass(`${coverageRule.path} includes UI design automation snippet: ${requiredSnippet}`);
1197
- } else {
1198
- fail(`${coverageRule.path} is missing UI design automation snippet: ${requiredSnippet}`);
1199
- }
1200
- }
1201
- }
1202
- }
1203
-
1204
- async function validateDockerRuntimeAutomationCoverage() {
1205
- console.log('\nChecking Docker runtime automation coverage...');
1206
-
1207
- for (const coverageRule of REQUIRED_DOCKER_RUNTIME_AUTOMATION_SNIPPETS) {
1208
- const absoluteCoveragePath = join(ROOT_DIR, coverageRule.path);
1209
-
1210
- if (!(await fileExists(absoluteCoveragePath))) {
1211
- fail(`Missing Docker runtime automation source: ${coverageRule.path}`);
1212
- continue;
1213
- }
1214
-
1215
- const coverageContent = await readTextFile(absoluteCoveragePath);
1216
- for (const requiredSnippet of coverageRule.snippets) {
1217
- if (coverageContent.includes(requiredSnippet)) {
1218
- pass(`${coverageRule.path} includes Docker runtime automation snippet: ${requiredSnippet}`);
1219
- } else {
1220
- fail(`${coverageRule.path} is missing Docker runtime automation snippet: ${requiredSnippet}`);
1221
- }
1222
- }
1223
- }
1224
- }
1225
-
1226
- async function validateDependencyFreshnessAutomationCoverage() {
1227
- console.log('\nChecking dependency freshness automation coverage...');
1228
-
1229
- for (const coverageRule of REQUIRED_DEPENDENCY_FRESHNESS_AUTOMATION_SNIPPETS) {
1230
- const absoluteCoveragePath = join(ROOT_DIR, coverageRule.path);
1231
-
1232
- if (!(await fileExists(absoluteCoveragePath))) {
1233
- fail(`Missing dependency freshness automation source: ${coverageRule.path}`);
1234
- continue;
1235
- }
1236
-
1237
- const coverageContent = await readTextFile(absoluteCoveragePath);
1238
- for (const requiredSnippet of coverageRule.snippets) {
1239
- if (coverageContent.includes(requiredSnippet)) {
1240
- pass(`${coverageRule.path} includes dependency freshness automation snippet: ${requiredSnippet}`);
1241
- } else {
1242
- fail(`${coverageRule.path} is missing dependency freshness automation snippet: ${requiredSnippet}`);
1243
- }
1244
- }
1245
- }
1246
- }
1247
-
1248
- async function validateDeterministicBoundaryEnforcementCoverage() {
1249
- console.log('\nChecking deterministic boundary enforcement coverage...');
1250
-
1251
- for (const coverageRule of REQUIRED_DETERMINISTIC_BOUNDARY_ENFORCEMENT_SNIPPETS) {
1252
- const absoluteCoveragePath = join(ROOT_DIR, coverageRule.path);
1253
-
1254
- if (!(await fileExists(absoluteCoveragePath))) {
1255
- fail(`Missing deterministic boundary source: ${coverageRule.path}`);
1256
- continue;
1257
- }
1258
-
1259
- const coverageContent = await readTextFile(absoluteCoveragePath);
1260
- for (const requiredSnippet of coverageRule.snippets) {
1261
- if (coverageContent.includes(requiredSnippet)) {
1262
- pass(`${coverageRule.path} includes deterministic boundary snippet: ${requiredSnippet}`);
1263
- } else {
1264
- fail(`${coverageRule.path} is missing deterministic boundary snippet: ${requiredSnippet}`);
1265
- }
1266
- }
1267
- }
1268
- }
1269
-
1270
561
  function isNormalizedMetricValue(value) {
1271
562
  return Number.isFinite(Number(value)) && Number(value) >= 0 && Number(value) <= 1;
1272
563
  }
@@ -1380,123 +671,22 @@ async function validateMcpConfiguration() {
1380
671
  }
1381
672
  }
1382
673
 
1383
- async function validateHumanWritingGovernance() {
1384
- console.log('\nChecking human writing governance...');
1385
-
1386
- const disallowedEmojiPattern = /[\u2705\u274C\u26A0\u{1F4CC}\u{1F536}\u{1F4CE}\u{1F534}\u{1F7E0}\u{1F7E1}\u{1F7E2}]/u;
1387
-
1388
- for (const formalArtifactPath of FORMAL_ARTIFACT_PATHS) {
1389
- const absoluteFormalArtifactPath = join(ROOT_DIR, formalArtifactPath);
1390
-
1391
- if (!(await fileExists(absoluteFormalArtifactPath))) {
1392
- fail(`Missing formal artifact for writing governance: ${formalArtifactPath}`);
1393
- continue;
1394
- }
1395
-
1396
- const formalArtifactContent = await readTextFile(absoluteFormalArtifactPath);
1397
-
1398
- if (disallowedEmojiPattern.test(formalArtifactContent)) {
1399
- fail(`${formalArtifactPath} contains disallowed emoji symbols in formal text`);
1400
- } else {
1401
- pass(`${formalArtifactPath} has no disallowed emoji symbols`);
1402
- }
1403
- }
1404
-
1405
- for (const snippetRule of REQUIRED_HUMAN_WRITING_SNIPPETS) {
1406
- const absoluteRulePath = join(ROOT_DIR, snippetRule.path);
1407
- if (!(await fileExists(absoluteRulePath))) {
1408
- fail(`Missing writing governance source: ${snippetRule.path}`);
1409
- continue;
1410
- }
1411
-
1412
- const writingRuleContent = await readTextFile(absoluteRulePath);
1413
- for (const requiredSnippet of snippetRule.snippets) {
1414
- if (writingRuleContent.includes(requiredSnippet)) {
1415
- pass(`${snippetRule.path} includes writing governance snippet: ${requiredSnippet}`);
1416
- } else {
1417
- fail(`${snippetRule.path} is missing writing governance snippet: ${requiredSnippet}`);
1418
- }
1419
- }
1420
- }
1421
- }
1422
-
1423
- async function validateInstructionAdapters() {
1424
- console.log('\nChecking instruction adapter consolidation...');
1425
-
1426
- const canonicalInstructionContent = normalizeLineEndings(await readTextFile(CANONICAL_INSTRUCTION_PATH));
1427
- const canonicalSnapshotHash = createHash('sha256').update(canonicalInstructionContent).digest('hex');
1428
-
1429
- for (const thinAdapterPath of THIN_ADAPTER_PATHS) {
1430
- const absoluteAdapterPath = join(ROOT_DIR, thinAdapterPath);
1431
-
1432
- if (!(await fileExists(absoluteAdapterPath))) {
1433
- fail(`Missing thin adapter file: ${thinAdapterPath}`);
1434
- continue;
1435
- }
1436
-
1437
- const thinAdapterContent = await readTextFile(absoluteAdapterPath);
1438
-
1439
- if (
1440
- thinAdapterContent.includes('Adapter Mode: thin')
1441
- && thinAdapterContent.includes('Adapter Source: .instructions.md')
1442
- ) {
1443
- pass(`${thinAdapterPath} declares thin adapter metadata`);
1444
- } else {
1445
- fail(`${thinAdapterPath} must declare Adapter Mode: thin and Adapter Source: .instructions.md`);
1446
- }
1447
-
1448
- const hashMatch = thinAdapterContent.match(/Canonical Snapshot SHA256:\s*([a-f0-9]{64})/);
1449
- if (!hashMatch) {
1450
- fail(`${thinAdapterPath} must declare Canonical Snapshot SHA256`);
1451
- continue;
1452
- }
1453
-
1454
- if (hashMatch[1] === canonicalSnapshotHash) {
1455
- pass(`${thinAdapterPath} canonical hash matches .instructions.md`);
1456
- } else {
1457
- fail(`${thinAdapterPath} canonical hash drift detected (expected ${canonicalSnapshotHash})`);
1458
- }
1459
-
1460
- const thinAdapterLineCount = thinAdapterContent.split(/\r?\n/u).length;
1461
- if (thinAdapterLineCount <= 80) {
1462
- pass(`${thinAdapterPath} remains thin (${thinAdapterLineCount} lines)`);
1463
- } else {
1464
- fail(`${thinAdapterPath} is too large for thin-adapter mode (${thinAdapterLineCount} lines)`);
1465
- }
1466
- }
1467
- }
1468
-
1469
- async function validateSkillPurgeSurface() {
1470
- console.log('\nChecking skill and tier purge surface...');
1471
-
1472
- const skillDirectoryPath = join(AGENT_CONTEXT_DIR, 'skills');
1473
- if (await fileExists(skillDirectoryPath)) {
1474
- fail('Skills directory must be removed: .agent-context/skills');
1475
- } else {
1476
- pass('Skills directory removed: .agent-context/skills');
1477
- }
1478
-
1479
- const retiredFiles = [
1480
- join(ROOT_DIR, 'lib', 'cli', 'skill-selector.mjs'),
1481
- join(ROOT_DIR, 'scripts', 'skill-tier-policy.mjs'),
1482
- join(ROOT_DIR, 'scripts', 'trust-scorer.mjs'),
1483
- ];
1484
-
1485
- for (const retiredFilePath of retiredFiles) {
1486
- const relativeRetiredPath = relative(ROOT_DIR, retiredFilePath).replace(/\\/g, '/');
1487
- if (await fileExists(retiredFilePath)) {
1488
- fail(`Retired file still present: ${relativeRetiredPath}`);
1489
- } else {
1490
- pass(`Retired file removed: ${relativeRetiredPath}`);
1491
- }
1492
- }
1493
- }
1494
-
1495
674
  async function main() {
1496
675
  console.log('===============================================');
1497
676
  console.log(' Agentic-Senior-Core Repository Validator');
1498
677
  console.log('===============================================');
1499
678
 
679
+ const coverageValidationContext = {
680
+ AGENT_CONTEXT_DIR,
681
+ CANONICAL_INSTRUCTION_PATH,
682
+ ROOT_DIR,
683
+ fail,
684
+ fileExists,
685
+ normalizeLineEndings,
686
+ pass,
687
+ readTextFile,
688
+ };
689
+
1500
690
  await validateRequiredFiles();
1501
691
  await validateMarkdownFiles();
1502
692
  await validateRuleFiles();
@@ -1508,21 +698,21 @@ async function main() {
1508
698
  await validatePolicyFile();
1509
699
  await validateVersionConsistency();
1510
700
  await validateDocumentationFlow();
1511
- await validateTerminologyMapping();
1512
- await validateDetectionTransparencyCoverage();
1513
- await validateStackResearchEngineCoverage();
1514
- await validateUniversalSopConsolidationCoverage();
1515
- await validateTemplateFreeBootstrapCoverage();
1516
- await validateUpgradeUiContractWarningCoverage();
1517
- await validateUiDesignAutomationCoverage();
1518
- await validateDockerRuntimeAutomationCoverage();
1519
- await validateDependencyFreshnessAutomationCoverage();
1520
- await validateDeterministicBoundaryEnforcementCoverage();
701
+ await validateTerminologyMapping(coverageValidationContext);
702
+ await validateDetectionTransparencyCoverage(coverageValidationContext);
703
+ await validateStackResearchEngineCoverage(coverageValidationContext);
704
+ await validateUniversalSopConsolidationCoverage(coverageValidationContext);
705
+ await validateTemplateFreeBootstrapCoverage(coverageValidationContext);
706
+ await validateUpgradeUiContractWarningCoverage(coverageValidationContext);
707
+ await validateUiDesignAutomationCoverage(coverageValidationContext);
708
+ await validateDockerRuntimeAutomationCoverage(coverageValidationContext);
709
+ await validateDependencyFreshnessAutomationCoverage(coverageValidationContext);
710
+ await validateDeterministicBoundaryEnforcementCoverage(coverageValidationContext);
1521
711
  await validateStackResearchSnapshotState();
1522
712
  await validateMcpConfiguration();
1523
- await validateHumanWritingGovernance();
1524
- await validateInstructionAdapters();
1525
- await validateSkillPurgeSurface();
713
+ await validateHumanWritingGovernance(coverageValidationContext);
714
+ await validateInstructionAdapters(coverageValidationContext);
715
+ await validateSkillPurgeSurface(coverageValidationContext);
1526
716
 
1527
717
  console.log('\n===============================================');
1528
718
  console.log(' RESULTS');