@ryuenn3123/agentic-senior-core 3.0.37 → 3.0.38

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 (58) hide show
  1. package/.agent-context/prompts/bootstrap-design.md +108 -146
  2. package/.agent-context/rules/frontend-architecture.md +92 -108
  3. package/.agent-context/state/README.md +26 -0
  4. package/.cursor/mcp.json +10 -0
  5. package/.cursor/rules/agentic-senior-core.mdc +48 -0
  6. package/.cursorrules +22 -88
  7. package/.gemini/instructions.md +25 -16
  8. package/.github/copilot-instructions.md +25 -16
  9. package/.github/instructions/agentic-senior-core.instructions.md +47 -0
  10. package/.instructions.md +98 -207
  11. package/.windsurf/rules/agentic-senior-core.md +43 -0
  12. package/.windsurfrules +22 -88
  13. package/AGENTS.md +23 -26
  14. package/CLAUDE.md +43 -0
  15. package/CONTRIBUTING.md +5 -2
  16. package/GEMINI.md +43 -0
  17. package/README.md +24 -7
  18. package/lib/cli/backup.mjs +4 -4
  19. package/lib/cli/commands/init/project-context.mjs +101 -0
  20. package/lib/cli/commands/init/runtime-environment.mjs +59 -0
  21. package/lib/cli/commands/init/setup-decisions.mjs +83 -0
  22. package/lib/cli/commands/init.mjs +33 -250
  23. package/lib/cli/commands/optimize.mjs +1 -1
  24. package/lib/cli/commands/upgrade.mjs +32 -7
  25. package/lib/cli/compiler.mjs +59 -17
  26. package/lib/cli/constants.mjs +5 -0
  27. package/lib/cli/detector.mjs +4 -0
  28. package/lib/cli/preflight.mjs +3 -3
  29. package/lib/cli/project-scaffolder/design-contract/validation.mjs +789 -0
  30. package/lib/cli/project-scaffolder/design-contract.mjs +119 -924
  31. package/lib/cli/project-scaffolder/prompt-builders.mjs +69 -84
  32. package/lib/cli/utils/filesystem.mjs +79 -0
  33. package/lib/cli/utils/managed-surface.mjs +237 -0
  34. package/lib/cli/utils/prompting.mjs +44 -0
  35. package/lib/cli/utils.mjs +33 -335
  36. package/package.json +21 -2
  37. package/scripts/clean-local-artifacts.mjs +76 -0
  38. package/scripts/docs-quality-drift-report.mjs +5 -0
  39. package/scripts/frontend-usability-audit.mjs +23 -19
  40. package/scripts/governance-weekly-report.mjs +37 -15
  41. package/scripts/single-source-lazy-loading-audit.mjs +24 -0
  42. package/scripts/sync-thin-adapters.mjs +99 -129
  43. package/scripts/v3-purge-audit.mjs +5 -0
  44. package/scripts/validate/config.mjs +10 -0
  45. package/scripts/validate/coverage-checks.mjs +55 -0
  46. package/.agent-context/marketplace/trust-tiers.json +0 -114
  47. package/.agent-context/state/benchmark-analysis.json +0 -431
  48. package/.agent-context/state/benchmark-evidence-bundle.json +0 -1040
  49. package/.agent-context/state/benchmark-history.json +0 -75
  50. package/.agent-context/state/benchmark-trend-report.csv +0 -5
  51. package/.agent-context/state/benchmark-trend-report.json +0 -140
  52. package/.agent-context/state/benchmark-writer-judge-matrix.json +0 -462
  53. package/.agent-context/state/memory-continuity-benchmark.json +0 -132
  54. package/.agent-context/state/onboarding-report.json +0 -102
  55. package/.agent-context/state/quality-trend-report.json +0 -89
  56. package/.agent-context/state/token-optimization-benchmark.json +0 -130
  57. package/.agent-context/state/weekly-governance-report.json +0 -329
  58. package/lib/cli/compatibility.mjs +0 -124
package/lib/cli/utils.mjs CHANGED
@@ -14,6 +14,29 @@ import {
14
14
  entryPointFiles,
15
15
  directoryCopies,
16
16
  } from './constants.mjs';
17
+ import {
18
+ pathExists,
19
+ ensureDirectory,
20
+ syncFile,
21
+ } from './utils/filesystem.mjs';
22
+ import {
23
+ collectRelativeTreeEntries,
24
+ analyzeManagedGovernanceSurface,
25
+ } from './utils/managed-surface.mjs';
26
+ export {
27
+ pathExists,
28
+ ensureDirectory,
29
+ copyDirectory,
30
+ isAgenticManagedContent,
31
+ syncFile,
32
+ } from './utils/filesystem.mjs';
33
+ export {
34
+ analyzeManagedGovernanceSurface,
35
+ } from './utils/managed-surface.mjs';
36
+ export {
37
+ askChoice,
38
+ askYesNo,
39
+ } from './utils/prompting.mjs';
17
40
 
18
41
  export function printUsage() {
19
42
  const presetNames = Object.keys(INIT_PRESETS).join(', ');
@@ -65,67 +88,6 @@ export function printUsage() {
65
88
  console.log(' --show Print current token optimization state as JSON');
66
89
  }
67
90
 
68
- export async function pathExists(targetPath) {
69
- try {
70
- await fs.stat(targetPath);
71
- return true;
72
- } catch {
73
- return false;
74
- }
75
- }
76
-
77
- export async function ensureDirectory(directoryPath) {
78
- await fs.mkdir(directoryPath, { recursive: true });
79
- }
80
-
81
- export async function copyDirectory(sourceDirectoryPath, targetDirectoryPath) {
82
- if (path.resolve(sourceDirectoryPath) === path.resolve(targetDirectoryPath)) {
83
- return;
84
- }
85
-
86
- await ensureDirectory(targetDirectoryPath);
87
- const directoryEntries = await fs.readdir(sourceDirectoryPath, { withFileTypes: true });
88
-
89
- for (const directoryEntry of directoryEntries) {
90
- const sourceEntryPath = path.join(sourceDirectoryPath, directoryEntry.name);
91
- const targetEntryPath = path.join(targetDirectoryPath, directoryEntry.name);
92
-
93
- if (directoryEntry.isDirectory()) {
94
- await copyDirectory(sourceEntryPath, targetEntryPath);
95
- continue;
96
- }
97
-
98
- if (path.resolve(sourceEntryPath) === path.resolve(targetEntryPath)) {
99
- continue;
100
- }
101
-
102
- await fs.copyFile(sourceEntryPath, targetEntryPath);
103
- }
104
- }
105
-
106
- /**
107
- * Synchronizes a single file between source and target, returning the operation status.
108
- */
109
- export async function syncFile(sourcePath, targetPath) {
110
- if (!(await pathExists(sourcePath))) return { status: 'skipped' };
111
-
112
- if (!(await pathExists(targetPath))) {
113
- await ensureDirectory(path.dirname(targetPath));
114
- await fs.copyFile(sourcePath, targetPath);
115
- return { status: 'created' };
116
- }
117
-
118
- const sourceContent = await fs.readFile(sourcePath);
119
- const targetContent = await fs.readFile(targetPath);
120
-
121
- if (sourceContent.equals(targetContent)) {
122
- return { status: 'unchanged' };
123
- }
124
-
125
- await fs.copyFile(sourcePath, targetPath);
126
- return { status: 'updated' };
127
- }
128
-
129
91
  /**
130
92
  * Intelligent MCP configuration synchronization.
131
93
  * Merges the agentic-senior-core server into existing config or creates new.
@@ -163,233 +125,6 @@ async function syncMcpConfig(mcpJsonPath, templateConfig) {
163
125
  }
164
126
  }
165
127
 
166
- function toPosixRelativePath(relativePath) {
167
- return relativePath.split(path.sep).join('/');
168
- }
169
-
170
- function isPathWithinPrefix(relativePath, prefixPath) {
171
- const normalizedRelativePath = toPosixRelativePath(relativePath).replace(/\/+$/g, '');
172
- const normalizedPrefixPath = toPosixRelativePath(prefixPath).replace(/\/+$/g, '');
173
-
174
- if (!normalizedPrefixPath) {
175
- return false;
176
- }
177
-
178
- return normalizedRelativePath === normalizedPrefixPath
179
- || normalizedRelativePath.startsWith(`${normalizedPrefixPath}/`);
180
- }
181
-
182
- const localOnlyGovernanceFiles = new Set([
183
- '.agent-context/state/active-memory.json',
184
- ]);
185
-
186
- function isLocalOnlyGovernanceFile(relativePath) {
187
- return localOnlyGovernanceFiles.has(toPosixRelativePath(relativePath));
188
- }
189
-
190
- async function collectRelativeTreeEntries(baseDirectoryPath, relativeRootPath) {
191
- const files = [];
192
- const directories = [];
193
-
194
- if (!(await pathExists(baseDirectoryPath))) {
195
- return { files, directories };
196
- }
197
-
198
- const normalizedRootPath = toPosixRelativePath(relativeRootPath);
199
- directories.push(normalizedRootPath);
200
-
201
- async function walkDirectory(currentDirectoryPath, currentRelativePath) {
202
- const directoryEntries = await fs.readdir(currentDirectoryPath, { withFileTypes: true });
203
-
204
- for (const directoryEntry of directoryEntries) {
205
- const sourceEntryPath = path.join(currentDirectoryPath, directoryEntry.name);
206
- const relativeEntryPath = toPosixRelativePath(path.join(currentRelativePath, directoryEntry.name));
207
-
208
- if (directoryEntry.isDirectory()) {
209
- directories.push(relativeEntryPath);
210
- await walkDirectory(sourceEntryPath, relativeEntryPath);
211
- continue;
212
- }
213
-
214
- if (isLocalOnlyGovernanceFile(relativeEntryPath)) {
215
- continue;
216
- }
217
-
218
- files.push(relativeEntryPath);
219
- }
220
- }
221
-
222
- await walkDirectory(baseDirectoryPath, normalizedRootPath);
223
- return { files, directories };
224
- }
225
-
226
- async function collectOptionalManagedEntries(baseDirectoryPath, options = {}) {
227
- const files = new Set();
228
- const directories = new Set();
229
-
230
- if (options.includeMcpTemplate === true) {
231
- const mcpServerEntrypointPath = path.join(baseDirectoryPath, 'scripts', 'mcp-server.mjs');
232
- if (await pathExists(mcpServerEntrypointPath)) {
233
- files.add('scripts/mcp-server.mjs');
234
- }
235
-
236
- const mcpServerHelpersDirectoryPath = path.join(baseDirectoryPath, 'scripts', 'mcp-server');
237
- const mcpServerTreeEntries = await collectRelativeTreeEntries(
238
- mcpServerHelpersDirectoryPath,
239
- 'scripts/mcp-server'
240
- );
241
-
242
- for (const relativeFilePath of mcpServerTreeEntries.files) {
243
- files.add(relativeFilePath);
244
- }
245
-
246
- for (const relativeDirectoryPath of mcpServerTreeEntries.directories) {
247
- directories.add(relativeDirectoryPath);
248
- }
249
- }
250
-
251
- return { files, directories };
252
- }
253
-
254
- async function buildManagedSourceManifest(options = {}) {
255
- const sourceFiles = new Set();
256
- const sourceDirectories = new Set();
257
-
258
- for (const sourceDirectoryName of directoryCopies) {
259
- const sourceDirectoryPath = path.join(REPO_ROOT, sourceDirectoryName);
260
- const sourceTreeEntries = await collectRelativeTreeEntries(sourceDirectoryPath, sourceDirectoryName);
261
-
262
- for (const sourceFilePath of sourceTreeEntries.files) {
263
- sourceFiles.add(sourceFilePath);
264
- }
265
-
266
- for (const sourceDirectoryPathRelative of sourceTreeEntries.directories) {
267
- sourceDirectories.add(sourceDirectoryPathRelative);
268
- }
269
- }
270
-
271
- for (const entryPointFileName of entryPointFiles) {
272
- const sourceFilePath = path.join(REPO_ROOT, entryPointFileName);
273
- if (!(await pathExists(sourceFilePath))) {
274
- continue;
275
- }
276
-
277
- sourceFiles.add(toPosixRelativePath(entryPointFileName));
278
- }
279
-
280
- const optionalManagedEntries = await collectOptionalManagedEntries(REPO_ROOT, options);
281
- for (const sourceFilePath of optionalManagedEntries.files) {
282
- sourceFiles.add(sourceFilePath);
283
- }
284
- for (const sourceDirectoryPath of optionalManagedEntries.directories) {
285
- sourceDirectories.add(sourceDirectoryPath);
286
- }
287
-
288
- return {
289
- files: sourceFiles,
290
- directories: sourceDirectories,
291
- };
292
- }
293
-
294
- async function collectManagedTargetManifest(resolvedTargetDirectoryPath, options = {}) {
295
- const targetFiles = new Set();
296
- const targetDirectories = new Set();
297
-
298
- for (const sourceDirectoryName of directoryCopies) {
299
- const targetDirectoryPath = path.join(resolvedTargetDirectoryPath, sourceDirectoryName);
300
- const targetTreeEntries = await collectRelativeTreeEntries(targetDirectoryPath, sourceDirectoryName);
301
-
302
- for (const targetFilePath of targetTreeEntries.files) {
303
- targetFiles.add(targetFilePath);
304
- }
305
-
306
- for (const targetDirectoryPathRelative of targetTreeEntries.directories) {
307
- targetDirectories.add(targetDirectoryPathRelative);
308
- }
309
- }
310
-
311
- for (const entryPointFileName of entryPointFiles) {
312
- const targetFilePath = path.join(resolvedTargetDirectoryPath, entryPointFileName);
313
- if (!(await pathExists(targetFilePath))) {
314
- continue;
315
- }
316
-
317
- targetFiles.add(toPosixRelativePath(entryPointFileName));
318
- }
319
-
320
- const optionalManagedEntries = await collectOptionalManagedEntries(resolvedTargetDirectoryPath, options);
321
- for (const targetFilePath of optionalManagedEntries.files) {
322
- targetFiles.add(targetFilePath);
323
- }
324
- for (const targetDirectoryPath of optionalManagedEntries.directories) {
325
- targetDirectories.add(targetDirectoryPath);
326
- }
327
-
328
- return {
329
- files: targetFiles,
330
- directories: targetDirectories,
331
- };
332
- }
333
-
334
- export async function analyzeManagedGovernanceSurface(
335
- resolvedTargetDirectoryPath,
336
- options = {}
337
- ) {
338
- const preservePathPrefixes = Array.isArray(options.preservePathPrefixes)
339
- ? options.preservePathPrefixes
340
- : ['.agent-context/state'];
341
-
342
- const sourceManifest = await buildManagedSourceManifest(options);
343
- const targetManifest = await collectManagedTargetManifest(resolvedTargetDirectoryPath, options);
344
-
345
- const staleFiles = [];
346
- const staleDirectories = [];
347
- const preservedFiles = [];
348
- const preservedDirectories = [];
349
-
350
- const sortedTargetFiles = [...targetManifest.files].sort((leftPath, rightPath) => leftPath.localeCompare(rightPath));
351
- const sortedTargetDirectories = [...targetManifest.directories].sort(
352
- (leftPath, rightPath) => rightPath.length - leftPath.length || leftPath.localeCompare(rightPath)
353
- );
354
-
355
- for (const targetFilePath of sortedTargetFiles) {
356
- if (sourceManifest.files.has(targetFilePath)) {
357
- continue;
358
- }
359
-
360
- if (preservePathPrefixes.some((prefixPath) => isPathWithinPrefix(targetFilePath, prefixPath))) {
361
- preservedFiles.push(targetFilePath);
362
- continue;
363
- }
364
-
365
- staleFiles.push(targetFilePath);
366
- }
367
-
368
- for (const targetDirectoryPathRelative of sortedTargetDirectories) {
369
- if (sourceManifest.directories.has(targetDirectoryPathRelative)) {
370
- continue;
371
- }
372
-
373
- if (preservePathPrefixes.some((prefixPath) => isPathWithinPrefix(targetDirectoryPathRelative, prefixPath))) {
374
- preservedDirectories.push(targetDirectoryPathRelative);
375
- continue;
376
- }
377
-
378
- staleDirectories.push(targetDirectoryPathRelative);
379
- }
380
-
381
- return {
382
- staleFiles,
383
- staleDirectories,
384
- preservedFiles,
385
- preservedDirectories,
386
- managedSourceFileCount: sourceManifest.files.size,
387
- managedSourceDirectoryCount: sourceManifest.directories.size,
388
- managedTargetFileCount: targetManifest.files.size,
389
- managedTargetDirectoryCount: targetManifest.directories.size,
390
- };
391
- }
392
-
393
128
  export async function copyGovernanceAssetsToTarget(
394
129
  resolvedTargetDirectoryPath,
395
130
  options = {}
@@ -406,6 +141,7 @@ export async function copyGovernanceAssetsToTarget(
406
141
  const createdFiles = [];
407
142
  const updatedFiles = [];
408
143
  const unchangedFiles = [];
144
+ const preservedFiles = [];
409
145
 
410
146
  for (const sourceDirectoryName of directoryCopies) {
411
147
  const sourceDirectoryPath = path.join(REPO_ROOT, sourceDirectoryName);
@@ -417,11 +153,14 @@ export async function copyGovernanceAssetsToTarget(
417
153
  for (const relativeFilePath of sourceTree.files) {
418
154
  const sourcePath = path.join(REPO_ROOT, ...relativeFilePath.split('/'));
419
155
  const targetPath = path.join(resolvedTargetDirectoryPath, ...relativeFilePath.split('/'));
420
- const syncResult = await syncFile(sourcePath, targetPath);
156
+ const syncResult = await syncFile(sourcePath, targetPath, {
157
+ preserveUserOwned: sourceDirectoryName === '.gemini',
158
+ });
421
159
 
422
160
  if (syncResult.status === 'created') createdFiles.push(relativeFilePath);
423
161
  else if (syncResult.status === 'updated') updatedFiles.push(relativeFilePath);
424
162
  else if (syncResult.status === 'unchanged') unchangedFiles.push(relativeFilePath);
163
+ else if (syncResult.status === 'preserved') preservedFiles.push(relativeFilePath);
425
164
  }
426
165
  }
427
166
 
@@ -437,10 +176,13 @@ export async function copyGovernanceAssetsToTarget(
437
176
  continue;
438
177
  }
439
178
 
440
- const syncResult = await syncFile(sourceFilePath, targetFilePath);
179
+ const syncResult = await syncFile(sourceFilePath, targetFilePath, {
180
+ preserveUserOwned: true,
181
+ });
441
182
  if (syncResult.status === 'created') createdFiles.push(entryPointFileName);
442
183
  else if (syncResult.status === 'updated') updatedFiles.push(entryPointFileName);
443
184
  else if (syncResult.status === 'unchanged') unchangedFiles.push(entryPointFileName);
185
+ else if (syncResult.status === 'preserved') preservedFiles.push(entryPointFileName);
444
186
  }
445
187
 
446
188
  if (shouldPruneManagedSurface && managedSurfacePlan) {
@@ -595,55 +337,11 @@ export async function copyGovernanceAssetsToTarget(
595
337
  createdFiles,
596
338
  updatedFiles,
597
339
  unchangedFiles,
340
+ preservedFiles,
598
341
  managedSurfacePlan,
599
342
  };
600
343
  }
601
344
 
602
- export async function askChoice(promptMessage, options, userInterface) {
603
- console.log(`\n${promptMessage}`);
604
- options.forEach((choiceLabel, choiceIndex) => {
605
- console.log(` ${choiceIndex + 1}. ${choiceLabel}`);
606
- });
607
-
608
- while (true) {
609
- const selectedRawInput = await userInterface.question('Choose a number (press Enter for 1): ');
610
- const normalizedInput = selectedRawInput.trim();
611
-
612
- if (!normalizedInput) {
613
- return options[0];
614
- }
615
-
616
- const selectedIndex = Number.parseInt(normalizedInput, 10) - 1;
617
-
618
- if (Number.isNaN(selectedIndex) || selectedIndex < 0 || selectedIndex >= options.length) {
619
- console.log('Invalid choice. Please select a valid number.');
620
- continue;
621
- }
622
-
623
- return options[selectedIndex];
624
- }
625
- }
626
-
627
- export async function askYesNo(promptMessage, userInterface, defaultValue) {
628
- const suffix = typeof defaultValue === 'boolean'
629
- ? defaultValue ? ' (Y/n): ' : ' (y/N): '
630
- : ' (y/n): ';
631
-
632
- while (true) {
633
- const answer = await userInterface.question(`\n${promptMessage}${suffix}`);
634
- const normalizedAnswer = answer.trim().toLowerCase();
635
-
636
- if (!normalizedAnswer && typeof defaultValue === 'boolean') {
637
- return defaultValue;
638
- }
639
-
640
- if (normalizedAnswer === 'y' || normalizedAnswer === 'yes') return true;
641
- if (normalizedAnswer === 'n' || normalizedAnswer === 'no') return false;
642
-
643
- console.log("Please answer with 'y' or 'n'.");
644
- }
645
- }
646
-
647
345
  export function toTitleCase(fileName) {
648
346
  return fileName
649
347
  .replace(/\.md$/i, '')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryuenn3123/agentic-senior-core",
3
- "version": "3.0.37",
3
+ "version": "3.0.38",
4
4
  "type": "module",
5
5
  "description": "Force your AI Agent to code like a Staff Engineer, not a Junior.",
6
6
  "bin": {
@@ -11,13 +11,31 @@
11
11
  "lib/",
12
12
  "scripts/",
13
13
  ".instructions.md",
14
- ".agent-context/",
14
+ ".agent-context/policies/",
15
+ ".agent-context/prompts/",
16
+ ".agent-context/review-checklists/",
17
+ ".agent-context/rules/",
18
+ ".agent-context/state/README.md",
19
+ ".agent-context/state/architecture-map.md",
20
+ ".agent-context/state/dependency-map.md",
21
+ ".agent-context/state/benchmark-comparison-schema.json",
22
+ ".agent-context/state/benchmark-reproducibility.json",
23
+ ".agent-context/state/benchmark-thresholds.json",
24
+ ".agent-context/state/benchmark-watchlist.json",
25
+ ".agent-context/state/benchmark-writer-judge-config.json",
26
+ ".agent-context/state/memory-adapter-contract.json",
27
+ ".agent-context/state/memory-schema-v1.json",
28
+ ".agent-context/state/stack-research-snapshot.json",
15
29
  ".agents/",
30
+ ".cursor/",
16
31
  ".github/",
17
32
  ".gemini/",
33
+ ".windsurf/",
18
34
  ".cursorrules",
19
35
  ".windsurfrules",
20
36
  "AGENTS.md",
37
+ "CLAUDE.md",
38
+ "GEMINI.md",
21
39
  ".agent-override.md",
22
40
  "mcp.json",
23
41
  "README.md",
@@ -65,6 +83,7 @@
65
83
  "report:quality-trend": "node ./scripts/quality-trend-report.mjs",
66
84
  "report:docs-quality-drift": "node ./scripts/docs-quality-drift-report.mjs",
67
85
  "report:governance-weekly": "node ./scripts/governance-weekly-report.mjs",
86
+ "clean:local": "node ./scripts/clean-local-artifacts.mjs",
68
87
  "validate": "node ./scripts/validate.mjs",
69
88
  "test": "node --test ./tests/cli-smoke.test.mjs ./tests/mcp-server.test.mjs ./tests/llm-judge.test.mjs ./tests/ui-rubric-calibration.test.mjs ./tests/operations.test.mjs"
70
89
  }
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { rm, stat } from 'node:fs/promises';
4
+ import { dirname, join, relative, resolve } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const SCRIPT_FILE_PATH = fileURLToPath(import.meta.url);
8
+ const REPOSITORY_ROOT = resolve(dirname(SCRIPT_FILE_PATH), '..');
9
+
10
+ const LOCAL_ARTIFACT_PATHS = [
11
+ 'test_output.txt',
12
+ 'validate_output.txt',
13
+ 'release-gate-report.json',
14
+ '.benchmarks',
15
+ '.agentic-backup',
16
+ '.agent-context/state/active-memory.json',
17
+ '.agent-context/state/v3-purge-audit.json',
18
+ '.agent-context/state/llm-judge-report.json',
19
+ '.agent-context/state/benchmark-analysis.json',
20
+ '.agent-context/state/benchmark-evidence-bundle.json',
21
+ '.agent-context/state/benchmark-history.json',
22
+ '.agent-context/state/benchmark-trend-report.csv',
23
+ '.agent-context/state/benchmark-trend-report.json',
24
+ '.agent-context/state/benchmark-writer-judge-matrix.json',
25
+ '.agent-context/state/docs-quality-drift-report.json',
26
+ '.agent-context/state/memory-continuity-benchmark.json',
27
+ '.agent-context/state/quality-trend-report.json',
28
+ '.agent-context/state/token-optimization-benchmark.json',
29
+ '.agent-context/state/weekly-governance-report.json',
30
+ ];
31
+
32
+ function resolveLocalArtifactPath(relativePath) {
33
+ const resolvedPath = resolve(REPOSITORY_ROOT, relativePath);
34
+ const repositoryRelativePath = relative(REPOSITORY_ROOT, resolvedPath);
35
+
36
+ if (
37
+ repositoryRelativePath.startsWith('..')
38
+ || repositoryRelativePath === ''
39
+ || resolve(repositoryRelativePath) === repositoryRelativePath
40
+ ) {
41
+ throw new Error(`Refusing to clean path outside repository root: ${relativePath}`);
42
+ }
43
+
44
+ return resolvedPath;
45
+ }
46
+
47
+ async function pathExists(targetPath) {
48
+ try {
49
+ await stat(targetPath);
50
+ return true;
51
+ } catch {
52
+ return false;
53
+ }
54
+ }
55
+
56
+ let removedCount = 0;
57
+ let skippedCount = 0;
58
+
59
+ for (const relativePath of LOCAL_ARTIFACT_PATHS) {
60
+ const targetPath = resolveLocalArtifactPath(relativePath);
61
+
62
+ if (!(await pathExists(targetPath))) {
63
+ skippedCount += 1;
64
+ continue;
65
+ }
66
+
67
+ await rm(targetPath, {
68
+ force: true,
69
+ recursive: true,
70
+ });
71
+
72
+ removedCount += 1;
73
+ console.log(`removed ${relativePath}`);
74
+ }
75
+
76
+ console.log(`local artifact cleanup complete: removed=${removedCount}, skipped=${skippedCount}`);
@@ -26,8 +26,13 @@ const MONITORED_STATIC_FILE_PATHS = [
26
26
  'CHANGELOG.md',
27
27
  '.instructions.md',
28
28
  'AGENTS.md',
29
+ 'CLAUDE.md',
30
+ 'GEMINI.md',
29
31
  '.github/copilot-instructions.md',
32
+ '.github/instructions/agentic-senior-core.instructions.md',
30
33
  '.gemini/instructions.md',
34
+ '.cursor/rules/agentic-senior-core.mdc',
35
+ '.windsurf/rules/agentic-senior-core.md',
31
36
  'docs/deep_analysis_and_roadmap_backlog.md',
32
37
  ];
33
38
 
@@ -54,25 +54,29 @@ const REQUIRED_ARCHITECTURE_CHECKLIST_SNIPPETS = [
54
54
 
55
55
  const REQUIRED_FRONTEND_RULE_SNIPPETS = [
56
56
  'Frontend Design and Interaction Boundaries',
57
- 'UI work must load the smallest relevant surface, not the entire engineering handbook.',
58
- '## Auto Activation',
59
- 'UI scope triggers:',
60
- 'Do not use this file to teach generic frontend basics the model already knows.',
61
- '## Source Hygiene and Source Boundaries',
62
- 'This rule guides the LLM; it must not choose the final style',
63
- 'Design continuity is opt-in.',
64
- 'Repo evidence outranks memory residue every time.',
65
- '## Accessibility Split',
66
- 'Treat WCAG 2.2 AA as the hard compliance floor.',
67
- 'Treat APCA as advisory perceptual tuning only.',
68
- '## Anti-Generic UI Boundaries',
69
- 'Do not default to interchangeable dashboard chrome',
70
- 'Do not let repeated surfaces share the same visual treatment by habit.',
71
- 'Do not use default framework button and input treatment as the final UI language.',
72
- '## Responsive Mutation Requirements',
73
- 'Responsive quality is not allowed to be scale-only.',
74
- '## Surface and Morphology Requirements',
75
- 'Define the primary user task or reading path from current evidence',
57
+ 'Load this rule for UI-facing work. Keep the loaded surface small.',
58
+ '## Activation',
59
+ '## Authority',
60
+ 'Treat `.agent-context/` as design governance authority.',
61
+ 'Treat `README.md` as overview/install/user context only',
62
+ 'Do not choose final style, framework, palette, typography, layout paradigm, or animation library offline.',
63
+ 'Keep design continuity opt-in.',
64
+ 'Repo evidence outranks memory residue.',
65
+ '## Required Design Contract',
66
+ '## Anti-Generic UI Gate',
67
+ 'Do not ship interchangeable dashboard chrome',
68
+ 'Do not let repeated surfaces share one visual treatment by habit',
69
+ 'Use the rename test:',
70
+ 'decorative geometry are invalid as wallpaper',
71
+ '## Dynamic Anchor Gate',
72
+ '## Motion, Palette, and 3D',
73
+ 'Treat motion, 3D, WebGL, canvas, scroll choreography, and animation libraries as first-class options.',
74
+ 'Prefer visually exploratory, product-derived palettes while preserving WCAG contrast and status clarity.',
75
+ '## Responsive Mutation',
76
+ 'Responsive quality is not scale-only.',
77
+ '## Accessibility',
78
+ 'WCAG 2.2 AA is the hard floor.',
79
+ 'APCA is advisory perceptual tuning only.',
76
80
  '## Implementation Boundaries',
77
81
  'Do not hardcode Zustand, React Query, smart/dumb component doctrine',
78
82
  ];