@ryuenn3123/agentic-senior-core 3.0.19 → 3.0.20

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 (77) hide show
  1. package/.agent-context/prompts/bootstrap-design.md +84 -103
  2. package/.agent-context/prompts/init-project.md +32 -100
  3. package/.agent-context/prompts/refactor.md +22 -44
  4. package/.agent-context/prompts/review-code.md +28 -52
  5. package/.agent-context/review-checklists/architecture-review.md +31 -62
  6. package/.agent-context/review-checklists/pr-checklist.md +74 -108
  7. package/.agent-context/rules/api-docs.md +18 -206
  8. package/.agent-context/rules/architecture.md +40 -207
  9. package/.agent-context/rules/database-design.md +10 -199
  10. package/.agent-context/rules/docker-runtime.md +5 -5
  11. package/.agent-context/rules/efficiency-vs-hype.md +11 -149
  12. package/.agent-context/rules/error-handling.md +9 -231
  13. package/.agent-context/rules/event-driven.md +17 -221
  14. package/.agent-context/rules/frontend-architecture.md +66 -119
  15. package/.agent-context/rules/git-workflow.md +1 -1
  16. package/.agent-context/rules/microservices.md +28 -161
  17. package/.agent-context/rules/naming-conv.md +8 -138
  18. package/.agent-context/rules/performance.md +9 -175
  19. package/.agent-context/rules/realtime.md +11 -44
  20. package/.agent-context/rules/security.md +11 -295
  21. package/.agent-context/rules/testing.md +9 -174
  22. package/.agent-context/state/benchmark-analysis.json +3 -3
  23. package/.agent-context/state/memory-continuity-benchmark.json +1 -1
  24. package/.agent-context/state/onboarding-report.json +71 -11
  25. package/.agents/workflows/init-project.md +7 -24
  26. package/.agents/workflows/refactor.md +7 -24
  27. package/.agents/workflows/review-code.md +7 -24
  28. package/.cursorrules +22 -21
  29. package/.gemini/instructions.md +2 -2
  30. package/.github/copilot-instructions.md +2 -2
  31. package/.instructions.md +112 -213
  32. package/.windsurfrules +22 -21
  33. package/AGENTS.md +4 -4
  34. package/CONTRIBUTING.md +13 -22
  35. package/README.md +6 -20
  36. package/lib/cli/commands/init.mjs +102 -148
  37. package/lib/cli/commands/launch.mjs +3 -3
  38. package/lib/cli/commands/optimize.mjs +14 -4
  39. package/lib/cli/commands/upgrade.mjs +25 -23
  40. package/lib/cli/compiler.mjs +96 -62
  41. package/lib/cli/constants.mjs +28 -136
  42. package/lib/cli/detector/design-evidence.mjs +189 -6
  43. package/lib/cli/detector.mjs +6 -7
  44. package/lib/cli/init-detection-flow.mjs +10 -93
  45. package/lib/cli/init-selection.mjs +2 -68
  46. package/lib/cli/project-scaffolder/constants.mjs +1 -1
  47. package/lib/cli/project-scaffolder/design-contract.mjs +162 -108
  48. package/lib/cli/project-scaffolder/discovery.mjs +36 -82
  49. package/lib/cli/project-scaffolder/prompt-builders.mjs +41 -55
  50. package/lib/cli/project-scaffolder/storage.mjs +0 -2
  51. package/lib/cli/token-optimization.mjs +1 -1
  52. package/lib/cli/utils.mjs +75 -9
  53. package/package.json +2 -2
  54. package/scripts/detection-benchmark.mjs +4 -15
  55. package/scripts/documentation-boundary-audit.mjs +9 -9
  56. package/scripts/explain-on-demand-audit.mjs +11 -11
  57. package/scripts/forbidden-content-check.mjs +9 -9
  58. package/scripts/frontend-usability-audit.mjs +45 -35
  59. package/scripts/llm-judge.mjs +1 -1
  60. package/scripts/mcp-server/constants.mjs +2 -2
  61. package/scripts/mcp-server/tool-registry.mjs +1 -1
  62. package/scripts/release-gate/audit-checks.mjs +4 -4
  63. package/scripts/release-gate/static-checks.mjs +5 -5
  64. package/scripts/release-gate.mjs +1 -1
  65. package/scripts/rules-guardian-audit.mjs +14 -13
  66. package/scripts/single-source-lazy-loading-audit.mjs +3 -3
  67. package/scripts/sync-thin-adapters.mjs +5 -5
  68. package/scripts/ui-design-judge/design-execution-summary.mjs +27 -1
  69. package/scripts/ui-design-judge/prompting.mjs +4 -4
  70. package/scripts/ui-design-judge/reporting.mjs +2 -1
  71. package/scripts/ui-design-judge/rubric-calibration.mjs +8 -5
  72. package/scripts/ui-design-judge/rubric-goldset.json +2 -2
  73. package/scripts/ui-design-judge.mjs +70 -6
  74. package/scripts/validate/config.mjs +138 -48
  75. package/scripts/validate/coverage-checks.mjs +32 -7
  76. package/scripts/validate.mjs +8 -4
  77. package/lib/cli/architect.mjs +0 -431
@@ -11,7 +11,8 @@ import {
11
11
  CLI_VERSION,
12
12
  AGENT_CONTEXT_DIR,
13
13
  PROFILE_PRESETS,
14
- BLUEPRINT_RECOMMENDATIONS,
14
+ AGENT_DECISION_STACK_FILE_NAME,
15
+ AGENT_DECISION_BLUEPRINT_FILE_NAME,
15
16
  } from '../constants.mjs';
16
17
 
17
18
  import {
@@ -103,8 +104,8 @@ export function parseUpgradeArguments(commandArguments) {
103
104
  function buildExistingProjectMajorConstraints() {
104
105
  return [
105
106
  'Preserve existing project markers and avoid forced stack migration.',
106
- 'Keep stack rule loading lazy and scoped to touched code.',
107
- 'Upgrade keeps prior onboarding choices unless user overrides them.',
107
+ 'Use runtime markers as evidence only unless the user already recorded an explicit runtime constraint.',
108
+ 'Upgrade keeps prior explicit onboarding constraints but does not create new stack or blueprint decisions.',
108
109
  ];
109
110
  }
110
111
 
@@ -172,9 +173,11 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
172
173
 
173
174
  try {
174
175
  console.log(`\nAgentic-Senior-Core CLI v${CLI_VERSION}`);
175
- console.log('Running rules operations upgrade assistant (Federated Governance baseline) for an existing repository.');
176
+ console.log('Running managed guidance upgrade for an existing repository.');
176
177
 
177
- const managedSurfacePlan = await analyzeManagedGovernanceSurface(resolvedTargetDirectoryPath);
178
+ const managedSurfacePlan = await analyzeManagedGovernanceSurface(resolvedTargetDirectoryPath, {
179
+ includeMcpTemplate: upgradeOptions.includeMcpTemplate === true,
180
+ });
178
181
 
179
182
  const stackFileNames = await collectFileNames(path.join(AGENT_CONTEXT_DIR, 'stacks'));
180
183
  const blueprintFileNames = await collectFileNames(path.join(AGENT_CONTEXT_DIR, 'blueprints'));
@@ -184,29 +187,28 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
184
187
  ? existingOnboardingReport.selectedProfile
185
188
  : 'balanced';
186
189
 
187
- const selectedStackFileName = stackFileNames.includes(existingOnboardingReport?.selectedStack)
190
+ const hasExplicitRuntimeConstraint = existingOnboardingReport?.runtimeDecision?.mode === 'explicit-constraint';
191
+ const hasExplicitArchitectureConstraint = existingOnboardingReport?.architectureDecision?.mode === 'explicit-constraint';
192
+
193
+ const selectedStackFileName = hasExplicitRuntimeConstraint && stackFileNames.includes(existingOnboardingReport?.selectedStack)
188
194
  ? existingOnboardingReport.selectedStack
189
- : projectDetection.recommendedStackFileName || 'typescript.md';
195
+ : AGENT_DECISION_STACK_FILE_NAME;
190
196
 
191
- const selectedAdditionalStackFileNames = Array.isArray(existingOnboardingReport?.selectedAdditionalStacks)
197
+ const selectedAdditionalStackFileNames = hasExplicitRuntimeConstraint && Array.isArray(existingOnboardingReport?.selectedAdditionalStacks)
192
198
  ? Array.from(new Set(existingOnboardingReport.selectedAdditionalStacks.filter(
193
199
  (stackFileName) => stackFileNames.includes(stackFileName) && stackFileName !== selectedStackFileName
194
200
  )))
195
- : Array.from(new Set((projectDetection.secondaryStackFileNames || []).filter(
196
- (stackFileName) => stackFileNames.includes(stackFileName) && stackFileName !== selectedStackFileName
197
- )));
201
+ : [];
198
202
 
199
- const selectedBlueprintFileName = blueprintFileNames.includes(existingOnboardingReport?.selectedBlueprint)
203
+ const selectedBlueprintFileName = hasExplicitArchitectureConstraint && blueprintFileNames.includes(existingOnboardingReport?.selectedBlueprint)
200
204
  ? existingOnboardingReport.selectedBlueprint
201
- : BLUEPRINT_RECOMMENDATIONS[selectedStackFileName] || 'api-nextjs.md';
205
+ : AGENT_DECISION_BLUEPRINT_FILE_NAME;
202
206
 
203
- const selectedAdditionalBlueprintFileNames = Array.isArray(existingOnboardingReport?.selectedAdditionalBlueprints)
207
+ const selectedAdditionalBlueprintFileNames = hasExplicitArchitectureConstraint && Array.isArray(existingOnboardingReport?.selectedAdditionalBlueprints)
204
208
  ? Array.from(new Set(existingOnboardingReport.selectedAdditionalBlueprints.filter(
205
209
  (blueprintFileName) => blueprintFileNames.includes(blueprintFileName) && blueprintFileName !== selectedBlueprintFileName
206
210
  )))
207
- : Array.from(new Set(selectedAdditionalStackFileNames
208
- .map((stackFileName) => BLUEPRINT_RECOMMENDATIONS[stackFileName] || null)
209
- .filter((blueprintFileName) => blueprintFileName && blueprintFileName !== selectedBlueprintFileName)));
211
+ : [];
210
212
 
211
213
  const includeCiGuardrails = typeof existingOnboardingReport?.ciGuardrailsEnabled === 'boolean'
212
214
  ? existingOnboardingReport.ciGuardrailsEnabled
@@ -269,10 +271,10 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
269
271
  };
270
272
 
271
273
  console.log('\nExisting project detection transparency:');
272
- if (projectDetection.recommendedStackFileName) {
274
+ if (projectDetection.detectedStackFileName) {
273
275
  const confidenceScoreLabel = Number(projectDetection.confidenceScore || 0).toFixed(2);
274
276
  console.log(
275
- `- Detected stack: ${toTitleCase(projectDetection.recommendedStackFileName)} (${projectDetection.confidenceLabel}, score ${confidenceScoreLabel})`
277
+ `- Detected stack: ${toTitleCase(projectDetection.detectedStackFileName)} (${projectDetection.confidenceLabel}, score ${confidenceScoreLabel})`
276
278
  );
277
279
  } else {
278
280
  console.log('- Detected stack: unresolved (insufficient markers).');
@@ -312,11 +314,11 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
312
314
 
313
315
  console.log('\nUpgrade preview:');
314
316
  console.log(`- Target directory: ${resolvedTargetDirectoryPath}`);
315
- console.log(`- Stack: ${toTitleCase(selectedStackFileName)}`);
317
+ console.log(`- Runtime decision: ${selectedStackFileName === AGENT_DECISION_STACK_FILE_NAME ? 'agent recommendation required from repo evidence' : toTitleCase(selectedStackFileName)}`);
316
318
  if (selectedAdditionalStackFileNames.length > 0) {
317
319
  console.log(`- Additional stacks: ${selectedAdditionalStackFileNames.map((stackFileName) => toTitleCase(stackFileName)).join(', ')}`);
318
320
  }
319
- console.log(`- Blueprint: ${toTitleCase(selectedBlueprintFileName)}`);
321
+ console.log(`- Architecture decision: ${selectedBlueprintFileName === AGENT_DECISION_BLUEPRINT_FILE_NAME ? 'agent recommendation required from repo evidence' : toTitleCase(selectedBlueprintFileName)}`);
320
322
  if (selectedAdditionalBlueprintFileNames.length > 0) {
321
323
  console.log(`- Additional blueprints: ${selectedAdditionalBlueprintFileNames.map((blueprintFileName) => toTitleCase(blueprintFileName)).join(', ')}`);
322
324
  }
@@ -355,7 +357,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
355
357
  const detectedVersionLabel = staleDoc.detectedTemplateVersion || 'missing';
356
358
  console.log(`- docs/${staleDoc.fileName} (detected: ${detectedVersionLabel}, expected: ${projectDocStalenessReport.expectedTemplateVersion})`);
357
359
  }
358
- console.log('Recommendation: regenerate docs with init --scaffold-docs or update the files manually to match the latest template version.');
360
+ console.log('Required action: regenerate docs with init --scaffold-docs or update the files manually to match the latest template version.');
359
361
  }
360
362
 
361
363
  if (uiScopeSignals.isUiScopeLikely && missingDesignContractPaths.length > 0) {
@@ -372,7 +374,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
372
374
  if (shouldSeedDesignIntentOnApply) {
373
375
  console.log('- Planned seed on apply: docs/design-intent.json');
374
376
  }
375
- console.log('Recommendation: create or refresh docs/DESIGN.md and docs/design-intent.json before allowing UI implementation work.');
377
+ console.log('Required action: create or refresh docs/DESIGN.md and docs/design-intent.json before allowing UI implementation work.');
376
378
  console.log('Upgrade synchronizes governance assets and can seed docs/design-intent.json, but it does not author project-specific docs/DESIGN.md automatically.');
377
379
  }
378
380
 
@@ -8,7 +8,8 @@ import path from 'node:path';
8
8
  import {
9
9
  CLI_VERSION,
10
10
  POLICY_FILE_NAME,
11
- BLUEPRINT_RECOMMENDATIONS,
11
+ AGENT_DECISION_STACK_FILE_NAME,
12
+ AGENT_DECISION_BLUEPRINT_FILE_NAME,
12
13
  } from './constants.mjs';
13
14
 
14
15
  import {
@@ -49,10 +50,11 @@ export async function writeOnboardingReport({
49
50
  operationMode = 'init',
50
51
  tokenOptimization = undefined,
51
52
  memoryContinuity = undefined,
52
- architectRecommendation = null,
53
53
  detectionTransparency = null,
54
54
  uiScopeSignals = null,
55
55
  }) {
56
+ const hasExplicitRuntimeDecision = selectedStackFileName && selectedStackFileName !== AGENT_DECISION_STACK_FILE_NAME;
57
+ const hasExplicitArchitectureDecision = selectedBlueprintFileName && selectedBlueprintFileName !== AGENT_DECISION_BLUEPRINT_FILE_NAME;
56
58
  const onboardingReportPath = path.join(targetDirectoryPath, '.agent-context', 'state', 'onboarding-report.json');
57
59
  const resolvedTokenOptimization = typeof tokenOptimization === 'undefined'
58
60
  ? await readTokenOptimizationState(targetDirectoryPath)
@@ -68,32 +70,39 @@ export async function writeOnboardingReport({
68
70
  selectedPreset,
69
71
  projectScope,
70
72
  projectTopology,
71
- selectedStack: selectedStackFileName,
72
- selectedAdditionalStacks: selectedAdditionalStackFileNames,
73
- selectedBlueprint: selectedBlueprintFileName,
74
- selectedAdditionalBlueprints: selectedAdditionalBlueprintFileNames,
73
+ runtimeDecision: {
74
+ mode: hasExplicitRuntimeDecision ? 'explicit-constraint' : 'agent-decision-required',
75
+ explicitStack: hasExplicitRuntimeDecision ? selectedStackFileName : null,
76
+ detectedStackEvidence: projectDetection.detectedStackFileName || null,
77
+ detectedAdditionalStackEvidence: projectDetection.secondaryStackFileNames || [],
78
+ },
79
+ architectureDecision: {
80
+ mode: hasExplicitArchitectureDecision ? 'explicit-constraint' : 'agent-decision-required',
81
+ explicitBlueprint: hasExplicitArchitectureDecision ? selectedBlueprintFileName : null,
82
+ detectedBlueprintEvidence: projectDetection.detectedBlueprintFileName || null,
83
+ },
84
+ selectedStack: hasExplicitRuntimeDecision ? selectedStackFileName : null,
85
+ selectedAdditionalStacks: hasExplicitRuntimeDecision ? selectedAdditionalStackFileNames : [],
86
+ selectedBlueprint: hasExplicitArchitectureDecision ? selectedBlueprintFileName : null,
87
+ selectedAdditionalBlueprints: hasExplicitArchitectureDecision ? selectedAdditionalBlueprintFileNames : [],
75
88
  ruleLoadingPolicy: {
76
89
  canonicalSource: '.instructions.md',
77
90
  stackLoadingMode: 'lazy',
78
91
  loadedOnDemand: true,
79
- primaryStack: selectedStackFileName,
80
- additionalStacks: selectedAdditionalStackFileNames,
92
+ primaryStack: hasExplicitRuntimeDecision ? selectedStackFileName : null,
93
+ additionalStacks: hasExplicitRuntimeDecision ? selectedAdditionalStackFileNames : [],
94
+ agentDecisionRequired: !hasExplicitRuntimeDecision,
81
95
  },
82
96
  ciGuardrailsEnabled: includeCiGuardrails,
83
97
  setupDurationMs,
84
98
  runtimeEnvironment,
85
99
  tokenOptimization: resolvedTokenOptimization,
86
100
  memoryContinuity: resolvedMemoryContinuity,
87
- architectRecommendation,
88
101
  autoDetection: {
89
- recommendedStack: projectDetection.recommendedStackFileName,
90
- recommendedAdditionalStacks: projectDetection.secondaryStackFileNames || [],
91
- recommendedBlueprint: projectDetection.recommendedBlueprintFileName,
92
- recommendedAdditionalBlueprints: Array.isArray(projectDetection.secondaryStackFileNames)
93
- ? projectDetection.secondaryStackFileNames
94
- .map((secondaryStackFileName) => BLUEPRINT_RECOMMENDATIONS[secondaryStackFileName] || null)
95
- .filter(Boolean)
96
- : [],
102
+ detectedStack: projectDetection.detectedStackFileName,
103
+ detectedAdditionalStacks: projectDetection.secondaryStackFileNames || [],
104
+ detectedBlueprint: projectDetection.detectedBlueprintFileName,
105
+ detectedAdditionalBlueprints: [],
97
106
  confidenceLabel: projectDetection.confidenceLabel,
98
107
  confidenceScore: projectDetection.confidenceScore,
99
108
  confidenceGap: projectDetection.confidenceGap,
@@ -151,6 +160,8 @@ export async function buildCompiledRulesContent({
151
160
  const availableStackProfileFileNames = new Set(await collectFileNames(selectedStacksDirectoryPath));
152
161
  const availableBlueprintProfileFileNames = new Set(await collectFileNames(selectedBlueprintsDirectoryPath));
153
162
  const contextBlocks = [];
163
+ const hasExplicitRuntimeDecision = selectedStackFileName && selectedStackFileName !== AGENT_DECISION_STACK_FILE_NAME;
164
+ const hasExplicitArchitectureDecision = selectedBlueprintFileName && selectedBlueprintFileName !== AGENT_DECISION_BLUEPRINT_FILE_NAME;
154
165
 
155
166
  function firstMarkdownHeading(content, fallbackLabel) {
156
167
  const headingLine = content
@@ -174,11 +185,11 @@ export async function buildCompiledRulesContent({
174
185
  contextBlocks.push(
175
186
  [
176
187
  '## BOOTSTRAP CHAIN (MANDATORY)',
177
- 'Load every layer before responding. Do not skip steps:',
188
+ 'Resolve the smallest relevant layer set before responding. Do not eagerly load unrelated layers:',
178
189
  '1. .agent-context/rules/',
179
- '2. Resolve architecture and stack signals from project context and live evidence.',
190
+ '2. Resolve runtime and architecture signals from project context, repo evidence, and live research.',
180
191
  '3. .agent-context/prompts/',
181
- '4. Dynamic architecture and stack signals (from project context + research evidence)',
192
+ '4. Dynamic runtime and architecture decision signals (from project context + research evidence)',
182
193
  '5. .agent-context/state/',
183
194
  `6. .agent-context/policies/${POLICY_FILE_NAME}`,
184
195
  '7. docs/ project context (or bootstrap prompts when docs are not materialized)',
@@ -191,31 +202,43 @@ export async function buildCompiledRulesContent({
191
202
 
192
203
  contextBlocks.push(
193
204
  [
194
- '## LAYER 1: UNIVERSAL RULES (MANDATORY)',
195
- 'Read every file under .agent-context/rules/ before implementation:',
205
+ '## LAYER 1: RULES (SCOPE-RESOLVED)',
206
+ 'Available rule files under .agent-context/rules/:',
196
207
  ...universalRuleFileNames.map((universalRuleFileName, index) => `${index + 1}. .agent-context/rules/${universalRuleFileName}`),
197
208
  '',
198
- 'Conflict resolution: prioritize data safety and API contract integrity first, then writing polish.',
209
+ 'Resolution policy: load only the rule files relevant to the current task and prioritize data safety and API contract integrity first, then writing polish.',
199
210
  ].join('\n')
200
211
  );
201
212
 
202
- const stackFilePath = path.join(selectedStacksDirectoryPath, selectedStackFileName);
203
- const hasStackProfileFile = availableStackProfileFileNames.has(selectedStackFileName);
204
- const stackSummary = hasStackProfileFile
205
- ? firstMarkdownHeading(await fs.readFile(stackFilePath, 'utf8'), selectedStackFileName)
206
- : `Dynamic stack strategy signal for ${humanizeProfileName(selectedStackFileName)}.`;
207
- contextBlocks.push(
208
- [
209
- `## LAYER 2: STACK PROFILE (${selectedStackFileName})`,
210
- hasStackProfileFile
211
- ? `Source: stack-profile:${selectedStackFileName}`
212
- : 'Source: dynamic-research-signal (static stack profile file not required)',
213
- `Summary: ${stackSummary}`,
214
- 'Load this stack profile to enforce language-specific conventions.',
215
- ].join('\n')
216
- );
213
+ if (hasExplicitRuntimeDecision) {
214
+ const stackFilePath = path.join(selectedStacksDirectoryPath, selectedStackFileName);
215
+ const hasStackProfileFile = availableStackProfileFileNames.has(selectedStackFileName);
216
+ const stackSummary = hasStackProfileFile
217
+ ? firstMarkdownHeading(await fs.readFile(stackFilePath, 'utf8'), selectedStackFileName)
218
+ : `Explicit runtime constraint for ${humanizeProfileName(selectedStackFileName)}.`;
219
+ contextBlocks.push(
220
+ [
221
+ `## LAYER 2: RUNTIME CONSTRAINT (${selectedStackFileName})`,
222
+ hasStackProfileFile
223
+ ? `Source: stack-profile:${selectedStackFileName}`
224
+ : 'Source: explicit user constraint',
225
+ `Summary: ${stackSummary}`,
226
+ 'Use this only as a constraint when the task touches that runtime. Do not treat it as design direction.',
227
+ ].join('\n')
228
+ );
229
+ } else {
230
+ contextBlocks.push(
231
+ [
232
+ '## LAYER 2: RUNTIME DECISION REQUIRED',
233
+ 'No runtime stack was selected by the user.',
234
+ 'For a fresh project, the first implementation step is to ask the AI agent to recommend a runtime/framework from the brief, constraints, and live official documentation.',
235
+ 'For an existing project, inspect repo markers and current files directly before editing. Detection evidence is not a migration instruction.',
236
+ 'Do not silently choose a stack from offline defaults.',
237
+ ].join('\n')
238
+ );
239
+ }
217
240
 
218
- if (normalizedAdditionalStackFileNames.length > 0) {
241
+ if (hasExplicitRuntimeDecision && normalizedAdditionalStackFileNames.length > 0) {
219
242
  contextBlocks.push(
220
243
  [
221
244
  '## LAYER 2B: ADDITIONAL STACK PROFILES',
@@ -234,9 +257,9 @@ export async function buildCompiledRulesContent({
234
257
  contextBlocks.push(
235
258
  [
236
259
  '## LAYER 2 POLICY: LAZY RULE LOADING',
237
- hasStackProfileFile
238
- ? `Primary stack profile is always loaded for this project: stack-profile:${selectedStackFileName}`
239
- : `Primary stack strategy is always loaded for this project: ${selectedStackFileName} (dynamic mode)`,
260
+ hasExplicitRuntimeDecision
261
+ ? `Primary runtime constraint: ${selectedStackFileName}`
262
+ : 'Primary runtime constraint: unresolved until agent recommendation is approved',
240
263
  normalizedAdditionalStackFileNames.length > 0
241
264
  ? `Additional stack profiles load on demand: ${normalizedAdditionalStackFileNames.map((stackFileName) => {
242
265
  if (availableStackProfileFileNames.has(stackFileName)) {
@@ -245,9 +268,9 @@ export async function buildCompiledRulesContent({
245
268
 
246
269
  return `${stackFileName} (dynamic signal)`;
247
270
  }).join(', ')}`
248
- : 'Additional stack profiles load only when explicitly selected or detected.',
249
- 'Load stack guidance only when task scope touches that stack.',
250
- 'Avoid eager loading unrelated stack profiles to prevent instruction conflicts.',
271
+ : 'Additional runtime guidance loads only when explicitly selected by the user or required by touched code.',
272
+ 'Load runtime-specific guidance only when task scope touches that runtime.',
273
+ 'Avoid eager loading unrelated runtime guidance to prevent instruction conflicts.',
251
274
  ].join('\n')
252
275
  );
253
276
 
@@ -261,28 +284,39 @@ export async function buildCompiledRulesContent({
261
284
  '4. .agent-context/prompts/bootstrap-design.md -> ui, ux, layout, screen, tailwind, frontend, redesign',
262
285
  'UI trigger policy:',
263
286
  '- Load .agent-context/prompts/bootstrap-design.md and .agent-context/rules/frontend-architecture.md first.',
264
- '- Keep UI-only requests context-isolated and do not eagerly load backend-only rules such as database-design.md, docker-runtime.md, or microservices.md unless the task explicitly crosses those boundaries.',
287
+ '- Keep UI-only requests context-isolated and do not eagerly load backend-only rules such as database-design.md, docker-runtime.md, microservices.md, git-workflow.md, or general implementation-theory rules unless the task explicitly crosses those boundaries.',
265
288
  '- For UI scope, materialize docs/DESIGN.md and docs/design-intent.json before implementing UI surfaces.',
266
289
  ].join('\n')
267
290
  );
268
291
 
269
- const blueprintFilePath = path.join(selectedBlueprintsDirectoryPath, selectedBlueprintFileName);
270
- const hasBlueprintProfileFile = availableBlueprintProfileFileNames.has(selectedBlueprintFileName);
271
- const blueprintSummary = hasBlueprintProfileFile
272
- ? firstMarkdownHeading(await fs.readFile(blueprintFilePath, 'utf8'), selectedBlueprintFileName)
273
- : `Dynamic architecture strategy signal for ${humanizeProfileName(selectedBlueprintFileName)}.`;
274
- contextBlocks.push(
275
- [
276
- `## LAYER 3: BLUEPRINT PROFILE (${selectedBlueprintFileName})`,
277
- hasBlueprintProfileFile
278
- ? `Source: architecture-profile:${selectedBlueprintFileName}`
279
- : 'Source: dynamic-research-signal (static blueprint profile file not required)',
280
- `Summary: ${blueprintSummary}`,
281
- 'Load this blueprint when scaffolding or changing architecture boundaries.',
282
- ].join('\n')
283
- );
292
+ if (hasExplicitArchitectureDecision) {
293
+ const blueprintFilePath = path.join(selectedBlueprintsDirectoryPath, selectedBlueprintFileName);
294
+ const hasBlueprintProfileFile = availableBlueprintProfileFileNames.has(selectedBlueprintFileName);
295
+ const blueprintSummary = hasBlueprintProfileFile
296
+ ? firstMarkdownHeading(await fs.readFile(blueprintFilePath, 'utf8'), selectedBlueprintFileName)
297
+ : `Explicit architecture constraint for ${humanizeProfileName(selectedBlueprintFileName)}.`;
298
+ contextBlocks.push(
299
+ [
300
+ `## LAYER 3: ARCHITECTURE CONSTRAINT (${selectedBlueprintFileName})`,
301
+ hasBlueprintProfileFile
302
+ ? `Source: architecture-profile:${selectedBlueprintFileName}`
303
+ : 'Source: explicit user constraint',
304
+ `Summary: ${blueprintSummary}`,
305
+ 'Use this only as an explicit constraint when scaffolding or changing architecture boundaries.',
306
+ ].join('\n')
307
+ );
308
+ } else {
309
+ contextBlocks.push(
310
+ [
311
+ '## LAYER 3: ARCHITECTURE DECISION REQUIRED',
312
+ 'No architecture blueprint was selected by the user.',
313
+ 'The AI agent must propose the architecture from the product brief, repo evidence, required docs, and live research before implementation.',
314
+ 'Do not map detected runtime markers into a blueprint automatically.',
315
+ ].join('\n')
316
+ );
317
+ }
284
318
 
285
- if (normalizedAdditionalBlueprintFileNames.length > 0) {
319
+ if (hasExplicitArchitectureDecision && normalizedAdditionalBlueprintFileNames.length > 0) {
286
320
  contextBlocks.push(
287
321
  [
288
322
  '## LAYER 3A: ADDITIONAL BLUEPRINT PROFILES',
@@ -17,128 +17,54 @@ export const POLICY_FILE_NAME = 'llm-judge-threshold.json';
17
17
 
18
18
  export const ALLOWED_SEVERITY_LEVELS = new Set(['critical', 'high', 'medium', 'low']);
19
19
 
20
- export const BLUEPRINT_RECOMMENDATIONS = {
21
- 'typescript.md': 'api-nextjs.md',
22
- 'python.md': 'fastapi-service.md',
23
- 'java.md': 'spring-boot-api.md',
24
- 'php.md': 'laravel-api.md',
25
- 'go.md': 'go-service.md',
26
- 'csharp.md': 'aspnet-api.md',
27
- 'react-native.md': 'mobile-app.md',
28
- 'flutter.md': 'mobile-app.md',
29
- };
30
-
31
- export const FALLBACK_STACK_FILE_NAMES = [
32
- 'typescript.md',
33
- 'python.md',
34
- 'go.md',
35
- 'java.md',
36
- 'php.md',
37
- 'csharp.md',
38
- 'rust.md',
39
- 'ruby.md',
40
- 'react-native.md',
41
- 'flutter.md',
42
- ];
43
-
44
- export const FALLBACK_BLUEPRINT_FILE_NAMES = [
45
- 'api-nextjs.md',
46
- 'nestjs-logic.md',
47
- 'fastapi-service.md',
48
- 'spring-boot-api.md',
49
- 'go-service.md',
50
- 'aspnet-api.md',
51
- 'laravel-api.md',
52
- 'graphql-grpc-api.md',
53
- 'ci-github-actions.md',
54
- 'ci-gitlab.md',
55
- 'kubernetes-manifests.md',
56
- 'infrastructure-as-code.md',
57
- 'observability.md',
58
- 'mobile-app.md',
59
- ];
20
+ export const AGENT_DECISION_STACK_FILE_NAME = 'agent-decision-runtime.md';
21
+ export const AGENT_DECISION_BLUEPRINT_FILE_NAME = 'agent-decision-architecture.md';
60
22
 
61
23
  export const INIT_PRESETS = {
62
- 'frontend-web': {
63
- stack: 'typescript.md',
64
- blueprint: 'api-nextjs.md',
24
+ 'frontend-ui': {
25
+ stack: null,
26
+ blueprint: null,
65
27
  ci: true,
66
- description: 'Frontend-first web app starter',
28
+ description: 'Frontend/UI scope hint; agent recommends runtime and architecture before coding',
67
29
  },
68
- 'backend-api': {
69
- stack: 'python.md',
70
- blueprint: 'fastapi-service.md',
30
+ 'backend-service': {
31
+ stack: null,
32
+ blueprint: null,
71
33
  ci: true,
72
- description: 'Backend API starter with safe defaults',
34
+ description: 'Backend/API scope hint; agent recommends runtime and architecture before coding',
73
35
  },
74
36
  'fullstack-product': {
75
- stack: 'typescript.md',
76
- blueprint: 'api-nextjs.md',
77
- ci: true,
78
- description: 'Product delivery starter with fullstack governance',
79
- },
80
- 'platform-governance': {
81
- stack: 'go.md',
82
- blueprint: 'go-service.md',
83
- ci: true,
84
- description: 'Platform and delivery starter with Go service defaults',
85
- },
86
- 'mobile-react-native': {
87
- stack: 'react-native.md',
88
- blueprint: 'mobile-app.md',
89
- ci: true,
90
- description: 'Mobile app starter for React Native',
91
- },
92
- 'mobile-flutter': {
93
- stack: 'flutter.md',
94
- blueprint: 'mobile-app.md',
95
- ci: true,
96
- description: 'Mobile app starter for Flutter',
97
- },
98
- 'observability-platform': {
99
- stack: 'go.md',
100
- blueprint: 'observability.md',
101
- ci: true,
102
- description: 'Observability and platform starter',
103
- },
104
- 'typescript-nestjs-service': {
105
- stack: 'typescript.md',
106
- blueprint: 'nestjs-logic.md',
107
- ci: true,
108
- description: 'TypeScript service starter with NestJS module blueprint',
109
- },
110
- 'java-enterprise-api': {
111
- stack: 'java.md',
112
- blueprint: 'spring-boot-api.md',
37
+ stack: null,
38
+ blueprint: null,
113
39
  ci: true,
114
- description: 'Enterprise API starter for JVM teams',
40
+ description: 'Fullstack product scope hint; agent recommends runtime and architecture before coding',
115
41
  },
116
- 'dotnet-enterprise-api': {
117
- stack: 'csharp.md',
118
- blueprint: 'aspnet-api.md',
42
+ 'mobile-app': {
43
+ stack: null,
44
+ blueprint: null,
119
45
  ci: true,
120
- description: '.NET API starter with enterprise-friendly defaults',
46
+ description: 'Mobile app scope hint; agent recommends native strategy before coding',
121
47
  },
122
- 'php-laravel-api': {
123
- stack: 'php.md',
124
- blueprint: 'laravel-api.md',
48
+ 'platform-ops': {
49
+ stack: null,
50
+ blueprint: null,
125
51
  ci: true,
126
- description: 'Laravel API starter with current framework defaults',
52
+ description: 'Platform operations scope hint; agent recommends runtime and architecture before coding',
127
53
  },
128
- 'kubernetes-platform': {
129
- stack: 'go.md',
130
- blueprint: 'kubernetes-manifests.md',
54
+ observability: {
55
+ stack: null,
56
+ blueprint: null,
131
57
  ci: true,
132
- description: 'Platform starter focused on Kubernetes delivery assets',
58
+ description: 'Observability scope hint; agent recommends runtime and architecture before coding',
133
59
  },
134
60
  };
135
61
 
136
62
  export const PROFILE_PRESETS = {
137
63
  beginner: {
138
64
  displayName: 'Beginner',
139
- description: 'Safest path. Minimal decisions, TypeScript defaults, and CI enabled.',
140
- defaultStackFileName: 'typescript.md',
141
- defaultBlueprintFileName: 'api-nextjs.md',
65
+ description: 'Safest path. Minimal decisions, agent-led stack decision, and CI enabled.',
66
+ defaultStackFileName: null,
67
+ defaultBlueprintFileName: null,
142
68
  defaultCi: true,
143
69
  lockCi: true,
144
70
  blockingSeverities: ['critical'],
@@ -180,40 +106,6 @@ export const PROJECT_SCOPE_CHOICES = [
180
106
  },
181
107
  ];
182
108
 
183
- export const PROJECT_SCOPE_STACK_FILTERS = {
184
- 'frontend-only': ['typescript.md'],
185
- 'backend-only': ['typescript.md', 'python.md', 'go.md', 'java.md', 'php.md', 'csharp.md', 'ruby.md', 'rust.md'],
186
- both: ['typescript.md', 'python.md', 'go.md', 'java.md', 'php.md', 'csharp.md', 'ruby.md', 'rust.md'],
187
- };
188
-
189
- export const WEB_FRONTEND_STACK_CANDIDATES = ['typescript.md'];
190
-
191
- export const WEB_BACKEND_STACK_CANDIDATES = [
192
- 'typescript.md',
193
- 'python.md',
194
- 'go.md',
195
- 'java.md',
196
- 'php.md',
197
- 'csharp.md',
198
- 'ruby.md',
199
- 'rust.md',
200
- ];
201
-
202
- export const WEB_FRONTEND_BLUEPRINT_CANDIDATES = [
203
- 'api-nextjs.md',
204
- ];
205
-
206
- export const WEB_BACKEND_BLUEPRINT_CANDIDATES = [
207
- 'nestjs-logic.md',
208
- 'fastapi-service.md',
209
- 'go-service.md',
210
- 'spring-boot-api.md',
211
- 'laravel-api.md',
212
- 'aspnet-api.md',
213
- 'graphql-grpc-api.md',
214
- 'api-nextjs.md',
215
- ];
216
-
217
109
  export const RUNTIME_ENVIRONMENT_CHOICES = [
218
110
  {
219
111
  key: 'linux-wsl',