@ryuenn3123/agentic-senior-core 2.5.22 → 3.0.2

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 (174) hide show
  1. package/.agent-context/prompts/bootstrap-design.md +22 -0
  2. package/.agent-context/prompts/init-project.md +55 -39
  3. package/.agent-context/prompts/refactor.md +2 -1
  4. package/.agent-context/prompts/review-code.md +3 -2
  5. package/.agent-context/review-checklists/pr-checklist.md +8 -1
  6. package/.agent-context/rules/architecture.md +11 -0
  7. package/.agent-context/rules/frontend-architecture.md +2 -2
  8. package/.agent-context/state/architecture-map.md +1 -1
  9. package/.agent-context/state/memory-continuity-benchmark.json +1 -1
  10. package/.agents/workflows/init-project.md +3 -3
  11. package/.agents/workflows/refactor.md +1 -1
  12. package/.agents/workflows/review-code.md +4 -5
  13. package/.cursorrules +27 -71
  14. package/.gemini/instructions.md +6 -7
  15. package/.github/copilot-instructions.md +5 -6
  16. package/.windsurfrules +27 -71
  17. package/AGENTS.md +7 -9
  18. package/CONTRIBUTING.md +18 -31
  19. package/README.md +17 -43
  20. package/bin/agentic-senior-core.js +0 -6
  21. package/lib/cli/commands/init.mjs +113 -650
  22. package/lib/cli/commands/launch.mjs +1 -23
  23. package/lib/cli/commands/rollback.mjs +1 -1
  24. package/lib/cli/commands/upgrade.mjs +47 -28
  25. package/lib/cli/compiler.mjs +77 -72
  26. package/lib/cli/constants.mjs +84 -26
  27. package/lib/cli/init-architecture-flow.mjs +231 -0
  28. package/lib/cli/init-detection-flow.mjs +123 -0
  29. package/lib/cli/init-options.mjs +344 -0
  30. package/lib/cli/init-selection.mjs +100 -0
  31. package/lib/cli/preflight.mjs +1 -1
  32. package/lib/cli/profile-packs.mjs +15 -1
  33. package/lib/cli/project-scaffolder.mjs +18 -154
  34. package/lib/cli/utils.mjs +224 -13
  35. package/mcp.json +19 -19
  36. package/package.json +5 -2
  37. package/scripts/context-triggered-audit.mjs +18 -18
  38. package/scripts/documentation-boundary-audit.mjs +92 -5
  39. package/scripts/forbidden-content-check.mjs +1 -1
  40. package/scripts/frontend-usability-audit.mjs +21 -28
  41. package/scripts/governance-weekly-report.mjs +29 -15
  42. package/scripts/llm-judge.mjs +2 -5
  43. package/scripts/mcp-server.mjs +389 -5
  44. package/scripts/release-gate.mjs +121 -145
  45. package/scripts/sync-thin-adapters.mjs +161 -0
  46. package/scripts/v3-purge-audit.mjs +231 -0
  47. package/scripts/validate-evidence-bundle.mjs +1 -1
  48. package/scripts/validate.mjs +224 -272
  49. package/.agent-context/blueprints/api-nextjs.md +0 -184
  50. package/.agent-context/blueprints/aspnet-api.md +0 -247
  51. package/.agent-context/blueprints/ci-github-actions.md +0 -226
  52. package/.agent-context/blueprints/ci-gitlab.md +0 -200
  53. package/.agent-context/blueprints/fastapi-service.md +0 -210
  54. package/.agent-context/blueprints/go-service.md +0 -217
  55. package/.agent-context/blueprints/graphql-grpc-api.md +0 -51
  56. package/.agent-context/blueprints/infrastructure-as-code.md +0 -62
  57. package/.agent-context/blueprints/kubernetes-manifests.md +0 -76
  58. package/.agent-context/blueprints/laravel-api.md +0 -233
  59. package/.agent-context/blueprints/mobile-app.md +0 -91
  60. package/.agent-context/blueprints/nestjs-logic.md +0 -247
  61. package/.agent-context/blueprints/observability.md +0 -227
  62. package/.agent-context/blueprints/spring-boot-api.md +0 -218
  63. package/.agent-context/profiles/platform.md +0 -13
  64. package/.agent-context/profiles/regulated.md +0 -13
  65. package/.agent-context/profiles/startup.md +0 -13
  66. package/.agent-context/review-checklists/frontend-excellence-rubric.md +0 -73
  67. package/.agent-context/review-checklists/frontend-skill-parity.md +0 -29
  68. package/.agent-context/review-checklists/frontend-usability.md +0 -35
  69. package/.agent-context/review-checklists/marketplace-acceptance.md +0 -60
  70. package/.agent-context/review-checklists/performance-audit.md +0 -71
  71. package/.agent-context/review-checklists/release-operations.md +0 -33
  72. package/.agent-context/review-checklists/security-audit.md +0 -119
  73. package/.agent-context/skills/README.md +0 -63
  74. package/.agent-context/skills/backend/README.md +0 -68
  75. package/.agent-context/skills/backend/architecture.md +0 -361
  76. package/.agent-context/skills/backend/compatibility-manifest.json +0 -8
  77. package/.agent-context/skills/backend/data-access.md +0 -231
  78. package/.agent-context/skills/backend/errors.md +0 -138
  79. package/.agent-context/skills/backend/validation.md +0 -117
  80. package/.agent-context/skills/backend.md +0 -29
  81. package/.agent-context/skills/cli/.evidence/compatibility-manifest.json +0 -5
  82. package/.agent-context/skills/cli/.evidence/sbom-excerpt.json +0 -10
  83. package/.agent-context/skills/cli/.evidence/test-report.json +0 -8
  84. package/.agent-context/skills/cli/CHANGELOG.md +0 -6
  85. package/.agent-context/skills/cli/README.md +0 -56
  86. package/.agent-context/skills/cli/compatibility-manifest.json +0 -8
  87. package/.agent-context/skills/cli/init.md +0 -38
  88. package/.agent-context/skills/cli/output.md +0 -36
  89. package/.agent-context/skills/cli/package.json +0 -5
  90. package/.agent-context/skills/cli/safety-telemetry.md +0 -39
  91. package/.agent-context/skills/cli/tests/.gitkeep +0 -1
  92. package/.agent-context/skills/cli/upgrade.md +0 -38
  93. package/.agent-context/skills/cli.md +0 -32
  94. package/.agent-context/skills/distribution/.evidence/compatibility-manifest.json +0 -9
  95. package/.agent-context/skills/distribution/.evidence/sbom-excerpt.json +0 -6
  96. package/.agent-context/skills/distribution/.evidence/test-report.json +0 -8
  97. package/.agent-context/skills/distribution/CHANGELOG.md +0 -7
  98. package/.agent-context/skills/distribution/README.md +0 -27
  99. package/.agent-context/skills/distribution/compatibility-manifest.json +0 -8
  100. package/.agent-context/skills/distribution/compatibility.md +0 -32
  101. package/.agent-context/skills/distribution/package.json +0 -5
  102. package/.agent-context/skills/distribution/provenance-attestation.md +0 -47
  103. package/.agent-context/skills/distribution/publish.md +0 -37
  104. package/.agent-context/skills/distribution/rollback.md +0 -32
  105. package/.agent-context/skills/distribution/tests/.gitkeep +0 -1
  106. package/.agent-context/skills/distribution.md +0 -32
  107. package/.agent-context/skills/frontend/.evidence/compatibility-manifest.json +0 -9
  108. package/.agent-context/skills/frontend/.evidence/sbom-excerpt.json +0 -6
  109. package/.agent-context/skills/frontend/.evidence/test-report.json +0 -8
  110. package/.agent-context/skills/frontend/CHANGELOG.md +0 -7
  111. package/.agent-context/skills/frontend/README.md +0 -50
  112. package/.agent-context/skills/frontend/accessibility.md +0 -107
  113. package/.agent-context/skills/frontend/compatibility-manifest.json +0 -8
  114. package/.agent-context/skills/frontend/conversion-clarity.md +0 -51
  115. package/.agent-context/skills/frontend/motion.md +0 -67
  116. package/.agent-context/skills/frontend/package.json +0 -5
  117. package/.agent-context/skills/frontend/performance.md +0 -63
  118. package/.agent-context/skills/frontend/responsive-delivery.md +0 -41
  119. package/.agent-context/skills/frontend/tests/.gitkeep +0 -1
  120. package/.agent-context/skills/frontend/ui-architecture.md +0 -128
  121. package/.agent-context/skills/frontend.md +0 -40
  122. package/.agent-context/skills/fullstack/.evidence/compatibility-manifest.json +0 -9
  123. package/.agent-context/skills/fullstack/.evidence/sbom-excerpt.json +0 -6
  124. package/.agent-context/skills/fullstack/.evidence/test-report.json +0 -8
  125. package/.agent-context/skills/fullstack/CHANGELOG.md +0 -7
  126. package/.agent-context/skills/fullstack/README.md +0 -27
  127. package/.agent-context/skills/fullstack/compatibility-manifest.json +0 -8
  128. package/.agent-context/skills/fullstack/contracts.md +0 -53
  129. package/.agent-context/skills/fullstack/end-to-end.md +0 -42
  130. package/.agent-context/skills/fullstack/feature-slicing.md +0 -65
  131. package/.agent-context/skills/fullstack/package.json +0 -5
  132. package/.agent-context/skills/fullstack/release-coordination.md +0 -51
  133. package/.agent-context/skills/fullstack/tests/.gitkeep +0 -1
  134. package/.agent-context/skills/fullstack.md +0 -30
  135. package/.agent-context/skills/index.json +0 -107
  136. package/.agent-context/skills/review-quality/.evidence/compatibility-manifest.json +0 -9
  137. package/.agent-context/skills/review-quality/.evidence/sbom-excerpt.json +0 -6
  138. package/.agent-context/skills/review-quality/.evidence/test-report.json +0 -8
  139. package/.agent-context/skills/review-quality/CHANGELOG.md +0 -7
  140. package/.agent-context/skills/review-quality/README.md +0 -27
  141. package/.agent-context/skills/review-quality/benchmark.md +0 -30
  142. package/.agent-context/skills/review-quality/compatibility-manifest.json +0 -8
  143. package/.agent-context/skills/review-quality/package.json +0 -5
  144. package/.agent-context/skills/review-quality/planning.md +0 -38
  145. package/.agent-context/skills/review-quality/release-decision.md +0 -49
  146. package/.agent-context/skills/review-quality/security.md +0 -34
  147. package/.agent-context/skills/review-quality/tests/.gitkeep +0 -1
  148. package/.agent-context/skills/review-quality.md +0 -34
  149. package/.agent-context/stacks/csharp.md +0 -149
  150. package/.agent-context/stacks/flutter.md +0 -16
  151. package/.agent-context/stacks/go.md +0 -181
  152. package/.agent-context/stacks/java.md +0 -135
  153. package/.agent-context/stacks/php.md +0 -192
  154. package/.agent-context/stacks/python.md +0 -153
  155. package/.agent-context/stacks/react-native.md +0 -16
  156. package/.agent-context/stacks/ruby.md +0 -80
  157. package/.agent-context/stacks/rust.md +0 -86
  158. package/.agent-context/stacks/typescript.md +0 -317
  159. package/.agent-context/state/skill-platform.json +0 -38
  160. package/lib/cli/skill-selector.mjs +0 -232
  161. package/lib/cli/templates/api-contract.md.id.tmpl +0 -143
  162. package/lib/cli/templates/api-contract.md.tmpl +0 -143
  163. package/lib/cli/templates/architecture-decision-record.md.id.tmpl +0 -106
  164. package/lib/cli/templates/architecture-decision-record.md.tmpl +0 -145
  165. package/lib/cli/templates/database-schema.md.id.tmpl +0 -74
  166. package/lib/cli/templates/database-schema.md.tmpl +0 -74
  167. package/lib/cli/templates/flow-overview.md.id.tmpl +0 -118
  168. package/lib/cli/templates/flow-overview.md.tmpl +0 -131
  169. package/lib/cli/templates/project-brief.md.id.tmpl +0 -55
  170. package/lib/cli/templates/project-brief.md.tmpl +0 -79
  171. package/scripts/init-project.ps1 +0 -105
  172. package/scripts/init-project.sh +0 -131
  173. package/scripts/skill-tier-policy.mjs +0 -76
  174. package/scripts/trust-scorer.mjs +0 -119
package/lib/cli/utils.mjs CHANGED
@@ -25,16 +25,14 @@ export function printUsage() {
25
25
  console.log(' npx @ryuenn3123/agentic-senior-core init');
26
26
  console.log(' npm install -g @ryuenn3123/agentic-senior-core && agentic-senior-core init');
27
27
  console.log(' bunx @ryuenn3123/agentic-senior-core init # optional Bun path');
28
- console.log(' open GitHub template: https://github.com/fatidaprilian/Agentic-Senior-Core/generate');
29
28
  console.log('');
30
29
  console.log('Usage:');
31
30
  console.log(' agentic-senior-core launch');
32
31
  console.log(' agentic-senior-core init [target-directory] [--preset <name>] [--profile <beginner|balanced|strict>] [--profile-pack <name>] [--stack <name>] [--blueprint <name>] [--project-description <text>] [--architect-token-budget <number>] [--architect-timeout-ms <number>] [--architect-research-mode <snapshot|realtime>] [--enable-realtime-research] [--architect-realtime-signal-file <path>] [--ci <true|false>] [--newbie] [--token-optimize] [--no-token-optimize] [--token-agent <name>] [--memory-continuity] [--no-memory-continuity] [--scaffold-docs] [--no-scaffold-docs] [--docs-lang <en|id>] [--project-config <path>] [--runtime-env <auto|linux-wsl|linux|windows|macos>]');
33
- console.log(' agentic-senior-core upgrade [target-directory] [--dry-run] [--yes] [--mcp-template]');
32
+ console.log(' agentic-senior-core upgrade [target-directory] [--dry-run] [--yes] [--mcp-template] [--no-mcp-template] [--prune] [--no-prune]');
34
33
  console.log(' agentic-senior-core optimize [target-directory] [--agent <copilot|claude|cursor|windsurf|gemini|codex|cline>] [--enable|--disable] [--show]');
35
34
  console.log(' agentic-senior-core mcp');
36
35
  console.log(' agentic-senior-core rollback [target-directory]');
37
- console.log(' agentic-senior-core skill [domain] [--tier <standard|advance|expert|above>] [--json]');
38
36
  console.log(' agentic-senior-core --version');
39
37
  console.log('');
40
38
  console.log('Options:');
@@ -68,12 +66,12 @@ export function printUsage() {
68
66
  console.log(' --runtime-env Override runtime environment hint (auto, linux-wsl, linux, windows, macos)');
69
67
  console.log(' --dry-run Preview upgrade without writing files');
70
68
  console.log(' --yes Skip confirmation prompts for upgrade');
69
+ console.log(' --prune Keep managed governance files synchronized 1:1 (default in upgrade)');
70
+ console.log(' --no-prune Do not remove stale managed governance files during upgrade');
71
71
  console.log(' --agent Target agent integration for token optimization mode');
72
72
  console.log(' --enable Enable token optimization policy and rebuild compiled rules');
73
73
  console.log(' --disable Disable token optimization policy and rebuild compiled rules');
74
74
  console.log(' --show Print current token optimization state as JSON');
75
- console.log(' --tier Choose a skill tier for the skill selector');
76
- console.log(' --json Emit machine-readable skill selection output');
77
75
  }
78
76
 
79
77
  export async function pathExists(targetPath) {
@@ -114,11 +112,188 @@ export async function copyDirectory(sourceDirectoryPath, targetDirectoryPath) {
114
112
  }
115
113
  }
116
114
 
115
+ function toPosixRelativePath(relativePath) {
116
+ return relativePath.split(path.sep).join('/');
117
+ }
118
+
119
+ function isPathWithinPrefix(relativePath, prefixPath) {
120
+ const normalizedRelativePath = toPosixRelativePath(relativePath).replace(/\/+$/g, '');
121
+ const normalizedPrefixPath = toPosixRelativePath(prefixPath).replace(/\/+$/g, '');
122
+
123
+ if (!normalizedPrefixPath) {
124
+ return false;
125
+ }
126
+
127
+ return normalizedRelativePath === normalizedPrefixPath
128
+ || normalizedRelativePath.startsWith(`${normalizedPrefixPath}/`);
129
+ }
130
+
131
+ async function collectRelativeTreeEntries(baseDirectoryPath, relativeRootPath) {
132
+ const files = [];
133
+ const directories = [];
134
+
135
+ if (!(await pathExists(baseDirectoryPath))) {
136
+ return { files, directories };
137
+ }
138
+
139
+ const normalizedRootPath = toPosixRelativePath(relativeRootPath);
140
+ directories.push(normalizedRootPath);
141
+
142
+ async function walkDirectory(currentDirectoryPath, currentRelativePath) {
143
+ const directoryEntries = await fs.readdir(currentDirectoryPath, { withFileTypes: true });
144
+
145
+ for (const directoryEntry of directoryEntries) {
146
+ const sourceEntryPath = path.join(currentDirectoryPath, directoryEntry.name);
147
+ const relativeEntryPath = toPosixRelativePath(path.join(currentRelativePath, directoryEntry.name));
148
+
149
+ if (directoryEntry.isDirectory()) {
150
+ directories.push(relativeEntryPath);
151
+ await walkDirectory(sourceEntryPath, relativeEntryPath);
152
+ continue;
153
+ }
154
+
155
+ files.push(relativeEntryPath);
156
+ }
157
+ }
158
+
159
+ await walkDirectory(baseDirectoryPath, normalizedRootPath);
160
+ return { files, directories };
161
+ }
162
+
163
+ async function buildManagedSourceManifest() {
164
+ const sourceFiles = new Set();
165
+ const sourceDirectories = new Set();
166
+
167
+ for (const sourceDirectoryName of directoryCopies) {
168
+ const sourceDirectoryPath = path.join(REPO_ROOT, sourceDirectoryName);
169
+ const sourceTreeEntries = await collectRelativeTreeEntries(sourceDirectoryPath, sourceDirectoryName);
170
+
171
+ for (const sourceFilePath of sourceTreeEntries.files) {
172
+ sourceFiles.add(sourceFilePath);
173
+ }
174
+
175
+ for (const sourceDirectoryPathRelative of sourceTreeEntries.directories) {
176
+ sourceDirectories.add(sourceDirectoryPathRelative);
177
+ }
178
+ }
179
+
180
+ for (const entryPointFileName of entryPointFiles) {
181
+ const sourceFilePath = path.join(REPO_ROOT, entryPointFileName);
182
+ if (!(await pathExists(sourceFilePath))) {
183
+ continue;
184
+ }
185
+
186
+ sourceFiles.add(toPosixRelativePath(entryPointFileName));
187
+ }
188
+
189
+ return {
190
+ files: sourceFiles,
191
+ directories: sourceDirectories,
192
+ };
193
+ }
194
+
195
+ async function collectManagedTargetManifest(resolvedTargetDirectoryPath) {
196
+ const targetFiles = new Set();
197
+ const targetDirectories = new Set();
198
+
199
+ for (const sourceDirectoryName of directoryCopies) {
200
+ const targetDirectoryPath = path.join(resolvedTargetDirectoryPath, sourceDirectoryName);
201
+ const targetTreeEntries = await collectRelativeTreeEntries(targetDirectoryPath, sourceDirectoryName);
202
+
203
+ for (const targetFilePath of targetTreeEntries.files) {
204
+ targetFiles.add(targetFilePath);
205
+ }
206
+
207
+ for (const targetDirectoryPathRelative of targetTreeEntries.directories) {
208
+ targetDirectories.add(targetDirectoryPathRelative);
209
+ }
210
+ }
211
+
212
+ for (const entryPointFileName of entryPointFiles) {
213
+ const targetFilePath = path.join(resolvedTargetDirectoryPath, entryPointFileName);
214
+ if (!(await pathExists(targetFilePath))) {
215
+ continue;
216
+ }
217
+
218
+ targetFiles.add(toPosixRelativePath(entryPointFileName));
219
+ }
220
+
221
+ return {
222
+ files: targetFiles,
223
+ directories: targetDirectories,
224
+ };
225
+ }
226
+
227
+ export async function analyzeManagedGovernanceSurface(
228
+ resolvedTargetDirectoryPath,
229
+ options = {}
230
+ ) {
231
+ const preservePathPrefixes = Array.isArray(options.preservePathPrefixes)
232
+ ? options.preservePathPrefixes
233
+ : ['.agent-context/state'];
234
+
235
+ const sourceManifest = await buildManagedSourceManifest();
236
+ const targetManifest = await collectManagedTargetManifest(resolvedTargetDirectoryPath);
237
+
238
+ const staleFiles = [];
239
+ const staleDirectories = [];
240
+ const preservedFiles = [];
241
+ const preservedDirectories = [];
242
+
243
+ const sortedTargetFiles = [...targetManifest.files].sort((leftPath, rightPath) => leftPath.localeCompare(rightPath));
244
+ const sortedTargetDirectories = [...targetManifest.directories].sort(
245
+ (leftPath, rightPath) => rightPath.length - leftPath.length || leftPath.localeCompare(rightPath)
246
+ );
247
+
248
+ for (const targetFilePath of sortedTargetFiles) {
249
+ if (sourceManifest.files.has(targetFilePath)) {
250
+ continue;
251
+ }
252
+
253
+ if (preservePathPrefixes.some((prefixPath) => isPathWithinPrefix(targetFilePath, prefixPath))) {
254
+ preservedFiles.push(targetFilePath);
255
+ continue;
256
+ }
257
+
258
+ staleFiles.push(targetFilePath);
259
+ }
260
+
261
+ for (const targetDirectoryPathRelative of sortedTargetDirectories) {
262
+ if (sourceManifest.directories.has(targetDirectoryPathRelative)) {
263
+ continue;
264
+ }
265
+
266
+ if (preservePathPrefixes.some((prefixPath) => isPathWithinPrefix(targetDirectoryPathRelative, prefixPath))) {
267
+ preservedDirectories.push(targetDirectoryPathRelative);
268
+ continue;
269
+ }
270
+
271
+ staleDirectories.push(targetDirectoryPathRelative);
272
+ }
273
+
274
+ return {
275
+ staleFiles,
276
+ staleDirectories,
277
+ preservedFiles,
278
+ preservedDirectories,
279
+ managedSourceFileCount: sourceManifest.files.size,
280
+ managedSourceDirectoryCount: sourceManifest.directories.size,
281
+ managedTargetFileCount: targetManifest.files.size,
282
+ managedTargetDirectoryCount: targetManifest.directories.size,
283
+ };
284
+ }
285
+
117
286
  export async function copyGovernanceAssetsToTarget(
118
287
  resolvedTargetDirectoryPath,
119
288
  options = {}
120
289
  ) {
121
290
  const shouldIncludeMcpTemplate = options.includeMcpTemplate === true;
291
+ const shouldPruneManagedSurface = options.pruneManagedSurface === true;
292
+ const managedSurfacePlan = shouldPruneManagedSurface
293
+ ? options.managedSurfacePlan || await analyzeManagedGovernanceSurface(resolvedTargetDirectoryPath)
294
+ : null;
295
+ const deletedManagedFiles = [];
296
+ const deletedManagedDirectories = [];
122
297
 
123
298
  for (const sourceDirectoryName of directoryCopies) {
124
299
  const sourceDirectoryPath = path.join(REPO_ROOT, sourceDirectoryName);
@@ -145,6 +320,28 @@ export async function copyGovernanceAssetsToTarget(
145
320
  await fs.copyFile(sourceFilePath, targetFilePath);
146
321
  }
147
322
 
323
+ if (shouldPruneManagedSurface && managedSurfacePlan) {
324
+ for (const staleFileRelativePath of managedSurfacePlan.staleFiles) {
325
+ const staleFilePath = path.join(resolvedTargetDirectoryPath, ...staleFileRelativePath.split('/'));
326
+ if (!(await pathExists(staleFilePath))) {
327
+ continue;
328
+ }
329
+
330
+ await fs.unlink(staleFilePath);
331
+ deletedManagedFiles.push(staleFileRelativePath);
332
+ }
333
+
334
+ for (const staleDirectoryRelativePath of managedSurfacePlan.staleDirectories) {
335
+ const staleDirectoryPath = path.join(resolvedTargetDirectoryPath, ...staleDirectoryRelativePath.split('/'));
336
+ if (!(await pathExists(staleDirectoryPath))) {
337
+ continue;
338
+ }
339
+
340
+ await fs.rm(staleDirectoryPath, { recursive: true, force: true });
341
+ deletedManagedDirectories.push(staleDirectoryRelativePath);
342
+ }
343
+ }
344
+
148
345
  if (shouldIncludeMcpTemplate) {
149
346
  const projectName = path.basename(resolvedTargetDirectoryPath);
150
347
  const mcpArgs = ['./scripts/mcp-server.mjs'];
@@ -199,7 +396,7 @@ export async function copyGovernanceAssetsToTarget(
199
396
  parsedZedSettings.context_servers['agentic-senior-core'] = zedMcpConfig.context_servers['agentic-senior-core'];
200
397
  await fs.writeFile(zedSettingsPath, JSON.stringify(parsedZedSettings, null, 2) + '\n', 'utf8');
201
398
  }
202
- } catch (err) {
399
+ } catch {
203
400
  // Fallback or ignore if user has broken JSON
204
401
  }
205
402
  }
@@ -216,7 +413,7 @@ export async function copyGovernanceAssetsToTarget(
216
413
  if (await pathExists(globalGeminiMcpPath)) {
217
414
  const content = await fs.readFile(globalGeminiMcpPath, 'utf8');
218
415
  if (content.trim()) {
219
- try { geminiConfig = JSON.parse(content); } catch (e) {}
416
+ try { geminiConfig = JSON.parse(content); } catch {}
220
417
  }
221
418
  }
222
419
  if (!geminiConfig.mcpServers) geminiConfig.mcpServers = {};
@@ -233,12 +430,18 @@ export async function copyGovernanceAssetsToTarget(
233
430
 
234
431
  await fs.writeFile(globalGeminiMcpPath, JSON.stringify(geminiConfig, null, 2) + '\n', 'utf8');
235
432
  }
236
- } catch (err) {
433
+ } catch {
237
434
  // Ignore global injection errors
238
435
  }
239
436
  }
240
437
  }
241
438
 
439
+ return {
440
+ deletedManagedFiles,
441
+ deletedManagedDirectories,
442
+ managedSurfacePlan,
443
+ };
444
+
242
445
  }
243
446
 
244
447
  export async function askChoice(promptMessage, options, userInterface) {
@@ -346,11 +549,19 @@ export function parseBlockingSeverities(rawSeverityValues, fileName) {
346
549
  }
347
550
 
348
551
  export async function collectFileNames(folderPath) {
349
- const fileNames = await fs.readdir(folderPath, { withFileTypes: true });
350
- return fileNames
351
- .filter((entry) => entry.isFile() && entry.name.endsWith('.md'))
352
- .map((entry) => entry.name)
353
- .sort((leftName, rightName) => leftName.localeCompare(rightName));
552
+ try {
553
+ const fileNames = await fs.readdir(folderPath, { withFileTypes: true });
554
+ return fileNames
555
+ .filter((entry) => entry.isFile() && entry.name.endsWith('.md'))
556
+ .map((entry) => entry.name)
557
+ .sort((leftName, rightName) => leftName.localeCompare(rightName));
558
+ } catch (error) {
559
+ if (error?.code === 'ENOENT') {
560
+ return [];
561
+ }
562
+
563
+ throw error;
564
+ }
354
565
  }
355
566
 
356
567
  export function formatBlockingSeverities(blockingSeverities) {
package/mcp.json CHANGED
@@ -1,31 +1,31 @@
1
1
  {
2
2
  "version": "1.0",
3
3
  "name": "agentic-senior-core",
4
- "description": "MCP configuration for governance-aware diagnostics and self-healing workflows with full knowledge injection.",
4
+ "description": "MCP configuration for governance-aware diagnostics and self-healing workflows with dynamic knowledge injection.",
5
5
  "knowledgeLayers": {
6
6
  "enabled": true,
7
- "description": "8-layer unified knowledge injection for AI agents",
7
+ "description": "8-layer dynamic knowledge injection for AI agents",
8
8
  "layers": {
9
9
  "rules": {
10
10
  "path": ".agent-context/rules",
11
11
  "count": 14,
12
12
  "autoLoad": true
13
13
  },
14
- "stacks": {
15
- "path": ".agent-context/stacks",
16
- "count": 10,
14
+ "stack-strategies": {
15
+ "path": "dynamic",
16
+ "count": 0,
17
17
  "autoLoad": true
18
18
  },
19
- "blueprints": {
20
- "path": ".agent-context/blueprints",
21
- "count": 14,
19
+ "architecture-playbooks": {
20
+ "path": "dynamic",
21
+ "count": 0,
22
22
  "autoLoad": true
23
23
  },
24
- "skills": {
25
- "path": ".agent-context/skills",
26
- "count": 6,
24
+ "execution-contracts": {
25
+ "path": "dynamic",
26
+ "count": 0,
27
27
  "autoLoad": true,
28
- "packs": ["backend", "frontend", "cli", "distribution", "fullstack", "review-quality"]
28
+ "sources": ["prompts", "review-checklists", "policies"]
29
29
  },
30
30
  "prompts": {
31
31
  "path": ".agent-context/prompts",
@@ -33,9 +33,9 @@
33
33
  "autoLoad": true,
34
34
  "templates": ["init-project", "refactor", "review-code"]
35
35
  },
36
- "profiles": {
37
- "path": ".agent-context/profiles",
38
- "count": 3,
36
+ "governance-modes": {
37
+ "path": "dynamic",
38
+ "count": 0,
39
39
  "autoLoad": true,
40
40
  "governance": ["platform", "regulated", "startup"]
41
41
  },
@@ -78,11 +78,11 @@
78
78
  "steps": [
79
79
  "load_all_knowledge_layers",
80
80
  "inject_rules",
81
- "inject_stacks",
82
- "inject_blueprints",
83
- "inject_skills",
81
+ "inject_stack_strategies",
82
+ "inject_architecture_playbooks",
83
+ "inject_execution_contracts",
84
84
  "inject_prompts",
85
- "inject_profiles",
85
+ "inject_governance_modes",
86
86
  "inject_state",
87
87
  "inject_policies"
88
88
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryuenn3123/agentic-senior-core",
3
- "version": "2.5.22",
3
+ "version": "3.0.2",
4
4
  "type": "module",
5
5
  "description": "Force your AI Agent to code like a Staff Engineer, not a Junior.",
6
6
  "bin": {
@@ -48,6 +48,9 @@
48
48
  "audit:rules-guardian": "node ./scripts/rules-guardian-audit.mjs",
49
49
  "audit:explain-on-demand": "node ./scripts/explain-on-demand-audit.mjs",
50
50
  "audit:single-source-lazy-loading": "node ./scripts/single-source-lazy-loading-audit.mjs",
51
+ "audit:v3-purge": "node ./scripts/v3-purge-audit.mjs",
52
+ "sync:adapters": "node ./scripts/sync-thin-adapters.mjs",
53
+ "check:adapters": "node ./scripts/sync-thin-adapters.mjs --check",
51
54
  "gate:release": "node ./scripts/release-gate.mjs && node ./scripts/forbidden-content-check.mjs",
52
55
  "prepublishOnly": "npm run gate:release",
53
56
  "sbom:generate": "node ./scripts/generate-sbom.mjs",
@@ -62,6 +65,6 @@
62
65
  "report:docs-quality-drift": "node ./scripts/docs-quality-drift-report.mjs",
63
66
  "report:governance-weekly": "node ./scripts/governance-weekly-report.mjs",
64
67
  "validate": "node ./scripts/validate.mjs",
65
- "test": "node --test ./tests/cli-smoke.test.mjs ./tests/mcp-server.test.mjs ./tests/llm-judge.test.mjs ./tests/enterprise-ops.test.mjs ./tests/skill-tier-gate.test.mjs"
68
+ "test": "node --test ./tests/cli-smoke.test.mjs ./tests/mcp-server.test.mjs ./tests/llm-judge.test.mjs ./tests/enterprise-ops.test.mjs"
66
69
  }
67
70
  }
@@ -16,8 +16,8 @@ const __filename = fileURLToPath(import.meta.url);
16
16
  const __dirname = dirname(__filename);
17
17
  const REPOSITORY_ROOT = resolve(__dirname, '..');
18
18
 
19
- const SECURITY_CHECKLIST_PATH = '.agent-context/review-checklists/security-audit.md';
20
- const PERFORMANCE_CHECKLIST_PATH = '.agent-context/review-checklists/performance-audit.md';
19
+ const PR_CHECKLIST_PATH = '.agent-context/review-checklists/pr-checklist.md';
20
+ const ARCHITECTURE_CHECKLIST_PATH = '.agent-context/review-checklists/architecture-review.md';
21
21
  const DEFAULT_WORKFLOW = 'auto';
22
22
  const SMALL_EDIT_MAX_FILES = 3;
23
23
  const MAJOR_FEATURE_MIN_SIGNIFICANT_FILES = 4;
@@ -36,18 +36,18 @@ const SUPPORTED_WORKFLOWS = new Set([
36
36
  'standard',
37
37
  ]);
38
38
 
39
- const REQUIRED_SECURITY_CHECKLIST_SNIPPETS = [
40
- '## Context Trigger Policy',
41
- 'Strict security audit auto-runs for review requests, PR-intent workflows, and major feature completion.',
42
- 'Small edits default to lightweight mode unless strict mode is explicitly forced.',
43
- 'User can force strict mode manually at any time.',
39
+ const REQUIRED_PR_CHECKLIST_SNIPPETS = [
40
+ '### 11. Context-Triggered Audit Mode',
41
+ 'Strict audit mode activates automatically on review and PR-intent workflows',
42
+ 'Small edits avoid heavy checks by default unless strict mode is explicitly requested',
43
+ 'User can always force strict audit mode manually',
44
44
  ];
45
45
 
46
- const REQUIRED_PERFORMANCE_CHECKLIST_SNIPPETS = [
47
- '## Context Trigger Policy',
48
- 'Strict performance audit auto-runs for review requests, PR-intent workflows, and major feature completion.',
49
- 'Small edits default to lightweight mode unless strict mode is explicitly forced.',
50
- 'User can force strict mode manually at any time.',
46
+ const REQUIRED_ARCHITECTURE_CHECKLIST_SNIPPETS = [
47
+ '## Backend Universal Principles',
48
+ 'No clever hacks in backend and shared core modules',
49
+ 'No premature abstraction',
50
+ 'Readability over brevity',
51
51
  ];
52
52
 
53
53
  function pushResult(results, isPassed, checkName, details) {
@@ -348,16 +348,16 @@ function runAudit() {
348
348
  pushResult(results, true, 'strict-audit-activation', `Strict audit mode activated (${auditMode.triggerReason})`);
349
349
 
350
350
  assertChecklist(
351
- 'security',
352
- SECURITY_CHECKLIST_PATH,
353
- REQUIRED_SECURITY_CHECKLIST_SNIPPETS,
351
+ 'pr',
352
+ PR_CHECKLIST_PATH,
353
+ REQUIRED_PR_CHECKLIST_SNIPPETS,
354
354
  failures,
355
355
  results
356
356
  );
357
357
  assertChecklist(
358
- 'performance',
359
- PERFORMANCE_CHECKLIST_PATH,
360
- REQUIRED_PERFORMANCE_CHECKLIST_SNIPPETS,
358
+ 'architecture',
359
+ ARCHITECTURE_CHECKLIST_PATH,
360
+ REQUIRED_ARCHITECTURE_CHECKLIST_SNIPPETS,
361
361
  failures,
362
362
  results
363
363
  );
@@ -15,6 +15,13 @@ import { fileURLToPath } from 'node:url';
15
15
  const __filename = fileURLToPath(import.meta.url);
16
16
  const __dirname = dirname(__filename);
17
17
  const REPOSITORY_ROOT = resolve(__dirname, '..');
18
+ const DOCUMENTATION_BOUNDARY_AUDIT_REPORT_VERSION = '2.1.0';
19
+ const AUTO_DOCS_SYNC_SCOPE_PHASE = 'phase-1';
20
+ const AUTO_DOCS_SYNC_SCOPE_BOUNDARIES = [
21
+ 'public-surface',
22
+ 'api-contract',
23
+ 'database-structure',
24
+ ];
18
25
 
19
26
  const CORE_DOCUMENTATION_FILES = new Set(['README.md', 'CHANGELOG.md']);
20
27
 
@@ -22,6 +29,12 @@ const BOUNDARY_RULES = [
22
29
  {
23
30
  boundaryName: 'public-surface',
24
31
  requirement: 'Public surface changes must update README.md, CHANGELOG.md, or docs/* in the same scope.',
32
+ suggestedDocumentationUpdates: [
33
+ 'README.md',
34
+ 'CHANGELOG.md',
35
+ 'docs/architecture-decision-record.md',
36
+ 'docs/flow-overview.md',
37
+ ],
25
38
  trigger(filePath) {
26
39
  return /^(bin\/|lib\/|scripts\/)/.test(filePath) && !isDocumentationFilePath(filePath);
27
40
  },
@@ -32,6 +45,12 @@ const BOUNDARY_RULES = [
32
45
  {
33
46
  boundaryName: 'api-contract',
34
47
  requirement: 'API endpoint or contract changes must update API/OpenAPI documentation in the same scope.',
48
+ suggestedDocumentationUpdates: [
49
+ 'docs/api-contract.md',
50
+ 'docs/flow-overview.md',
51
+ '.agent-context/rules/api-docs.md',
52
+ 'README.md',
53
+ ],
35
54
  trigger(filePath) {
36
55
  return !isDocumentationFilePath(filePath)
37
56
  && /(api|openapi|contract|controller|route|endpoint)/i.test(filePath);
@@ -45,6 +64,12 @@ const BOUNDARY_RULES = [
45
64
  {
46
65
  boundaryName: 'database-structure',
47
66
  requirement: 'Database structure changes must update schema or migration documentation in the same scope.',
67
+ suggestedDocumentationUpdates: [
68
+ 'docs/database-schema.md',
69
+ 'docs/flow-overview.md',
70
+ '.agent-context/rules/database-design.md',
71
+ 'README.md',
72
+ ],
48
73
  trigger(filePath) {
49
74
  return !isDocumentationFilePath(filePath)
50
75
  && /(database|schema|migration|repository|sql|prisma|typeorm|knex)/i.test(filePath);
@@ -135,6 +160,9 @@ function isDocumentationFilePath(filePath) {
135
160
 
136
161
  function evaluateBoundary(boundaryRule, changedFiles, changedDocumentationFiles) {
137
162
  const boundaryChangedFiles = changedFiles.filter((filePath) => boundaryRule.trigger(filePath));
163
+ const expectedDocumentationPaths = Array.isArray(boundaryRule.suggestedDocumentationUpdates)
164
+ ? boundaryRule.suggestedDocumentationUpdates
165
+ : [];
138
166
 
139
167
  if (boundaryChangedFiles.length === 0) {
140
168
  return {
@@ -144,12 +172,21 @@ function evaluateBoundary(boundaryRule, changedFiles, changedDocumentationFiles)
144
172
  passed: true,
145
173
  changedFiles: [],
146
174
  documentationFiles: [],
175
+ expectedDocumentationPaths,
176
+ missingDocumentationUpdates: false,
177
+ suggestedActions: [],
147
178
  details: 'Boundary not triggered by changed scope.',
148
179
  };
149
180
  }
150
181
 
151
182
  const matchingDocumentationFiles = changedDocumentationFiles.filter((filePath) => boundaryRule.docsMatcher(filePath));
152
183
  const boundaryPassed = matchingDocumentationFiles.length > 0;
184
+ const suggestedActions = boundaryPassed
185
+ ? []
186
+ : [
187
+ `Update one or more boundary docs: ${expectedDocumentationPaths.join(', ')}`,
188
+ 'Re-run scripts/documentation-boundary-audit.mjs before merge.',
189
+ ];
153
190
 
154
191
  const details = boundaryPassed
155
192
  ? `Boundary triggered and synchronized with documentation updates: ${matchingDocumentationFiles.join(', ')}`
@@ -162,6 +199,9 @@ function evaluateBoundary(boundaryRule, changedFiles, changedDocumentationFiles)
162
199
  passed: boundaryPassed,
163
200
  changedFiles: boundaryChangedFiles,
164
201
  documentationFiles: matchingDocumentationFiles,
202
+ expectedDocumentationPaths,
203
+ missingDocumentationUpdates: !boundaryPassed,
204
+ suggestedActions,
165
205
  details,
166
206
  };
167
207
  }
@@ -175,25 +215,72 @@ function runDocumentationBoundaryAudit() {
175
215
  evaluateBoundary(boundaryRule, changedFiles, changedDocumentationFiles)
176
216
  ));
177
217
 
178
- const failures = boundaryResults
218
+ const violations = boundaryResults
179
219
  .filter((boundaryResult) => boundaryResult.triggered && !boundaryResult.passed)
180
- .map((boundaryResult) => {
181
- const affectedFiles = boundaryResult.changedFiles.join(', ');
182
- return `${boundaryResult.boundaryName}: ${boundaryResult.requirement} Changed files: ${affectedFiles}`;
183
- });
220
+ .map((boundaryResult) => ({
221
+ boundaryName: boundaryResult.boundaryName,
222
+ requirement: boundaryResult.requirement,
223
+ changedFiles: boundaryResult.changedFiles,
224
+ expectedDocumentationPaths: boundaryResult.expectedDocumentationPaths,
225
+ suggestedActions: boundaryResult.suggestedActions,
226
+ diagnosticCode: `BOUNDARY_${boundaryResult.boundaryName.toUpperCase().replace(/-/g, '_')}_DOCS_SYNC_REQUIRED`,
227
+ }));
228
+
229
+ const failures = violations.map((violation) => {
230
+ const affectedFiles = violation.changedFiles.join(', ');
231
+ return `${violation.boundaryName}: ${violation.requirement} Changed files: ${affectedFiles}`;
232
+ });
184
233
 
185
234
  const reportPayload = {
186
235
  generatedAt: new Date().toISOString(),
236
+ reportVersion: DOCUMENTATION_BOUNDARY_AUDIT_REPORT_VERSION,
187
237
  auditName: 'documentation-boundary-audit',
188
238
  source: changedScope.source,
189
239
  changedFileCount: changedFiles.length,
190
240
  changedFiles,
191
241
  boundaryResults,
242
+ violations,
192
243
  passed: failures.length === 0,
193
244
  failureCount: failures.length,
194
245
  failures,
195
246
  };
196
247
 
248
+ const triggeredBoundaryResults = boundaryResults.filter((boundaryResult) => boundaryResult.triggered);
249
+ const passedTriggeredBoundaryResults = triggeredBoundaryResults.filter((boundaryResult) => boundaryResult.passed);
250
+ const scopeMatchedDocumentationFiles = uniqueSorted(
251
+ triggeredBoundaryResults.flatMap((boundaryResult) => boundaryResult.documentationFiles),
252
+ );
253
+ const scopeMatchedDocumentationFileSet = new Set(scopeMatchedDocumentationFiles);
254
+ const outOfScopeDocumentationFiles = changedDocumentationFiles.filter(
255
+ (filePath) => !scopeMatchedDocumentationFileSet.has(filePath),
256
+ );
257
+
258
+ const precisionNumerator = scopeMatchedDocumentationFiles.length;
259
+ const precisionDenominator = changedDocumentationFiles.length;
260
+ const recallNumerator = passedTriggeredBoundaryResults.length;
261
+ const recallDenominator = triggeredBoundaryResults.length;
262
+
263
+ const precision = precisionDenominator > 0 ? precisionNumerator / precisionDenominator : 1;
264
+ const recall = recallDenominator > 0 ? recallNumerator / recallDenominator : 1;
265
+
266
+ reportPayload.autoDocsSyncScope = {
267
+ phase: AUTO_DOCS_SYNC_SCOPE_PHASE,
268
+ bounded: true,
269
+ explicitBoundaries: AUTO_DOCS_SYNC_SCOPE_BOUNDARIES,
270
+ };
271
+
272
+ reportPayload.rolloutMetrics = {
273
+ measuredAt: reportPayload.generatedAt,
274
+ precision,
275
+ recall,
276
+ precisionNumerator,
277
+ precisionDenominator,
278
+ recallNumerator,
279
+ recallDenominator,
280
+ scopeMatchedDocumentationFiles,
281
+ outOfScopeDocumentationFiles,
282
+ };
283
+
197
284
  console.log(JSON.stringify(reportPayload, null, 2));
198
285
  process.exit(reportPayload.passed ? 0 : 1);
199
286
  }
@@ -1,4 +1,4 @@
1
- import { readFileSync, statSync, readdirSync } from 'node:fs';
1
+ import { readFileSync, readdirSync } from 'node:fs';
2
2
  import { join, relative } from 'node:path';
3
3
 
4
4
  const ROOT_DIR = process.cwd();