@ryuenn3123/agentic-senior-core 3.0.12 → 3.0.14

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.
@@ -8,13 +8,13 @@ import fs from 'node:fs/promises';
8
8
  import path from 'node:path';
9
9
 
10
10
  import {
11
+ PROJECT_SCOPE_CHOICES,
11
12
  CLI_VERSION,
12
13
  AGENT_CONTEXT_DIR,
13
14
  INIT_PRESETS,
14
15
  PROFILE_PRESETS,
15
16
  GOLDEN_STANDARD_PROFILE_NAME,
16
17
  BLUEPRINT_RECOMMENDATIONS,
17
- PROJECT_SCOPE_CHOICES,
18
18
  FALLBACK_STACK_FILE_NAMES,
19
19
  FALLBACK_BLUEPRINT_FILE_NAMES,
20
20
  RUNTIME_ENVIRONMENT_CHOICES,
@@ -42,10 +42,13 @@ import {
42
42
  } from '../detector.mjs';
43
43
  import { compileDynamicContext, writeSelectedPolicy, writeOnboardingReport } from '../compiler.mjs';
44
44
  import {
45
+ filterStackFileNamesByCandidates,
45
46
  filterBlueprintFileNamesByCandidates,
46
47
  normalizeAdditionalStackSelection,
47
48
  normalizeAdditionalBlueprintSelection,
48
49
  deriveAdditionalBlueprintFileNamesFromStacks,
50
+ resolveScopeStackCandidates,
51
+ resolveScopeBlueprintCandidates,
49
52
  } from '../init-selection.mjs';
50
53
  import {
51
54
  buildExistingProjectMajorConstraints,
@@ -75,11 +78,7 @@ import {
75
78
  createMemoryContinuityState,
76
79
  writeMemoryContinuityState,
77
80
  } from '../memory-continuity.mjs';
78
- import {
79
- readArchitectPreferenceState,
80
- writeArchitectPreferenceState,
81
- } from '../architect.mjs';
82
- import { resolveArchitectureSelection } from '../init-architecture-flow.mjs';
81
+ import { recommendArchitecture } from '../architect.mjs';
83
82
 
84
83
  export { REPO_ROOT } from '../constants.mjs';
85
84
  // Keep these architect option flags visible in the init command surface for validator coverage:
@@ -156,6 +155,82 @@ export function detectRuntimeEnvironment() {
156
155
  };
157
156
  }
158
157
 
158
+ function resolveProjectScopeLabelFromKey(projectScopeKey) {
159
+ return PROJECT_SCOPE_CHOICES.find((scopeChoice) => scopeChoice.key === projectScopeKey)?.label
160
+ || PROJECT_SCOPE_CHOICES.find((scopeChoice) => scopeChoice.key === 'both')?.label
161
+ || 'Both (frontend + backend)';
162
+ }
163
+
164
+ function inferProjectScopeFromDiscoveryAnswers(discoveryAnswers) {
165
+ const normalizedDomain = String(discoveryAnswers?.primaryDomain || '').trim().toLowerCase();
166
+ const normalizedDescription = [
167
+ discoveryAnswers?.projectDescription,
168
+ ...(Array.isArray(discoveryAnswers?.features) ? discoveryAnswers.features : []),
169
+ ].join(' ').toLowerCase();
170
+
171
+ if (
172
+ normalizedDomain.includes('api service')
173
+ || normalizedDomain.includes('cli tool')
174
+ || normalizedDomain.includes('library')
175
+ ) {
176
+ return 'backend-only';
177
+ }
178
+
179
+ if (normalizedDomain.includes('mobile app')) {
180
+ return 'frontend-only';
181
+ }
182
+
183
+ if (normalizedDomain.includes('web application')) {
184
+ if (/(landing page|marketing site|showcase|portfolio|brochure|company profile)/.test(normalizedDescription)) {
185
+ return 'frontend-only';
186
+ }
187
+
188
+ return 'both';
189
+ }
190
+
191
+ return 'both';
192
+ }
193
+
194
+ function resolveSilentCiGuardrailsDefault({
195
+ initOptions,
196
+ selectedPreset,
197
+ selectedProfilePack,
198
+ selectedProfile,
199
+ }) {
200
+ if (typeof initOptions.ci === 'boolean') {
201
+ return {
202
+ value: initOptions.ci,
203
+ shouldAsk: false,
204
+ };
205
+ }
206
+
207
+ if (typeof selectedPreset?.ci === 'boolean') {
208
+ return {
209
+ value: selectedPreset.ci,
210
+ shouldAsk: false,
211
+ };
212
+ }
213
+
214
+ if (typeof selectedProfilePack?.defaultCi === 'boolean') {
215
+ return {
216
+ value: selectedProfilePack.defaultCi,
217
+ shouldAsk: Boolean(!selectedProfilePack.lockCi),
218
+ };
219
+ }
220
+
221
+ if (selectedProfile.lockCi) {
222
+ return {
223
+ value: selectedProfile.defaultCi,
224
+ shouldAsk: false,
225
+ };
226
+ }
227
+
228
+ return {
229
+ value: selectedProfile.defaultCi,
230
+ shouldAsk: true,
231
+ };
232
+ }
233
+
159
234
  async function askStackSelection(promptMessage, selectableStackFileNames, userInterface) {
160
235
  const stackDisplayChoices = selectableStackFileNames.map((stackFileName) => toTitleCase(stackFileName));
161
236
  const selectedDisplayChoice = await askChoice(promptMessage, stackDisplayChoices, userInterface);
@@ -242,8 +317,6 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
242
317
  const wasDirectoryEffectivelyEmpty = await isDirectoryEffectivelyEmpty(resolvedTargetDirectoryPath);
243
318
  const hadExistingProjectDocsBeforeInit = await hasExistingProjectDocs(resolvedTargetDirectoryPath);
244
319
 
245
- await createBackup(resolvedTargetDirectoryPath);
246
-
247
320
  const userInterface = createInterface({ input: stdin, output: stdout });
248
321
 
249
322
  try {
@@ -442,20 +515,21 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
442
515
  let selectedAdditionalBlueprintFileNames = [];
443
516
  let detectedSetupWasApplied = false;
444
517
  let selectedProjectScopeKey = 'both';
445
- let selectedProjectScopeLabel = PROJECT_SCOPE_CHOICES.find(
446
- (scopeChoice) => scopeChoice.key === 'both'
447
- )?.label || 'Both (frontend + backend)';
448
-
518
+ let selectedProjectScopeLabel = resolveProjectScopeLabelFromKey('both');
449
519
  let architectureRecommendation = null;
450
- let architectureProjectDescription = '';
451
- let architectPreferenceState = await readArchitectPreferenceState();
452
- let architectPreferenceUpdated = false;
453
-
454
- const shouldRunArchitectureRecommendation = !selectedStackFileNameFromOption
455
- && !selectedPreset?.stack
456
- && !shouldAutoApplyDetectedStack
457
- && !selectedProfilePack?.defaultStackFileName
458
- && !selectedProfile.defaultStackFileName;
520
+ let architectureProjectDescription = String(initOptions.projectDescription || '').trim();
521
+ let discoveryAnswers = null;
522
+ const ciGuardrailsSelection = resolveSilentCiGuardrailsDefault({
523
+ initOptions,
524
+ selectedPreset,
525
+ selectedProfilePack,
526
+ selectedProfile,
527
+ });
528
+ const isFreshProjectTarget = !projectDetection.hasExistingProjectFiles
529
+ && wasDirectoryEffectivelyEmpty
530
+ && !hadExistingProjectDocsBeforeInit;
531
+ const shouldRunInteractiveScaffolding = isInteractiveSession
532
+ && (initOptions.scaffoldDocs === true || (initOptions.scaffoldDocs !== false && isFreshProjectTarget));
459
533
 
460
534
  const detectedSetupDecision = await resolveDetectedSetupDecision({
461
535
  shouldAutoApplyDetectedStack,
@@ -479,37 +553,76 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
479
553
  selectedAdditionalStackFileNames = detectedSetupDecision.selectedAdditionalStackFileNames;
480
554
  detectedBlueprintFileName = detectedSetupDecision.detectedBlueprintFileName;
481
555
 
482
- const architectureSelection = await resolveArchitectureSelection({
483
- shouldRunArchitectureRecommendation,
484
- initOptions: {
485
- ...initOptions,
486
- targetDirectoryPath: resolvedTargetDirectoryPath,
556
+ if (initOptions.projectConfig) {
557
+ discoveryAnswers = await loadProjectConfig(initOptions.projectConfig);
558
+ console.log(`\nLoaded project configuration from: ${initOptions.projectConfig}`);
559
+ } else if (shouldRunInteractiveScaffolding) {
560
+ discoveryAnswers = await runProjectDiscovery(userInterface, {
561
+ defaultProjectName: path.basename(resolvedTargetDirectoryPath),
562
+ defaultProjectDescription: architectureProjectDescription,
563
+ defaultIncludeCiGuardrails: ciGuardrailsSelection.value,
564
+ askForCiGuardrails: ciGuardrailsSelection.shouldAsk,
565
+ });
566
+ } else if (initOptions.scaffoldDocs === true && !isInteractiveSession) {
567
+ throw new Error('Non-interactive scaffolding requires --project-config when --scaffold-docs is enabled.');
568
+ }
569
+
570
+ if (discoveryAnswers?.projectDescription) {
571
+ architectureProjectDescription = discoveryAnswers.projectDescription;
572
+ }
573
+
574
+ if (discoveryAnswers) {
575
+ selectedProjectScopeKey = inferProjectScopeFromDiscoveryAnswers(discoveryAnswers);
576
+ selectedProjectScopeLabel = resolveProjectScopeLabelFromKey(selectedProjectScopeKey);
577
+ }
578
+
579
+ const shouldUseSilentArchitectureSelection = !selectedStackFileNameFromOption
580
+ && !selectedPreset?.stack
581
+ && !shouldAutoApplyDetectedStack
582
+ && !selectedProfilePack?.defaultStackFileName
583
+ && !selectedProfile.defaultStackFileName;
584
+
585
+ if (shouldUseSilentArchitectureSelection) {
586
+ const architectureScopeStackCandidates = filterStackFileNamesByCandidates(
587
+ stackFileNames,
588
+ resolveScopeStackCandidates(selectedProjectScopeKey)
589
+ );
590
+ const architectureScopeBlueprintCandidates = filterBlueprintFileNamesByCandidates(
591
+ blueprintFileNames,
592
+ resolveScopeBlueprintCandidates(selectedProjectScopeKey)
593
+ );
594
+
595
+ architectureRecommendation = recommendArchitecture({
596
+ projectDescription: architectureProjectDescription || `A software project named ${path.basename(resolvedTargetDirectoryPath)}.`,
597
+ projectDetection,
598
+ stackFileNames: architectureScopeStackCandidates,
599
+ blueprintFileNames: architectureScopeBlueprintCandidates,
600
+ tokenBudget: initOptions.architectTokenBudget,
601
+ timeoutMs: initOptions.architectTimeoutMs,
487
602
  researchMode: initOptions.architectResearchMode,
488
603
  enableRealtimeResearch: initOptions.enableRealtimeResearch,
489
- },
490
- projectDetection,
491
- stackFileNames,
492
- blueprintFileNames,
493
- userInterface,
494
- isInteractiveSession,
495
- initialSelectedProjectScopeKey: selectedProjectScopeKey,
496
- initialSelectedProjectScopeLabel: selectedProjectScopeLabel,
497
- initialSelectedManualStackFileName: selectedManualStackFileName,
498
- initialSelectedManualBlueprintFileName: selectedManualBlueprintFileName,
499
- architectPreferenceState,
500
- askStackSelection,
501
- askBlueprintSelection,
502
- detectionTransparency,
503
- });
604
+ realtimeSignalFilePath: initOptions.architectRealtimeSignalFile,
605
+ });
504
606
 
505
- selectedProjectScopeKey = architectureSelection.selectedProjectScopeKey;
506
- selectedProjectScopeLabel = architectureSelection.selectedProjectScopeLabel;
507
- selectedManualStackFileName = architectureSelection.selectedManualStackFileName;
508
- selectedManualBlueprintFileName = architectureSelection.selectedManualBlueprintFileName;
509
- architectureProjectDescription = architectureSelection.architectureProjectDescription;
510
- architectureRecommendation = architectureSelection.architectureRecommendation;
511
- architectPreferenceState = architectureSelection.architectPreferenceState;
512
- architectPreferenceUpdated = architectureSelection.architectPreferenceUpdated;
607
+ architectureRecommendation.projectDomain = {
608
+ key: selectedProjectScopeKey,
609
+ label: selectedProjectScopeLabel,
610
+ };
611
+ architectureRecommendation.userVeto = {
612
+ applied: false,
613
+ selectedStackFileName: architectureRecommendation.recommendedStackFileName,
614
+ selectedBlueprintFileName: architectureRecommendation.recommendedBlueprintFileName,
615
+ source: projectDetection.hasExistingProjectFiles ? 'silent-existing-bootstrap' : 'silent-fresh-bootstrap',
616
+ };
617
+
618
+ selectedManualStackFileName = architectureRecommendation.recommendedStackFileName;
619
+ selectedManualBlueprintFileName = architectureRecommendation.recommendedBlueprintFileName;
620
+
621
+ if (!projectDetection.hasExistingProjectFiles) {
622
+ detectionTransparency.quickConfirmation.response = 'fresh-project-streamlined';
623
+ detectionTransparency.decision.mode = 'fresh-project-streamlined';
624
+ }
625
+ }
513
626
 
514
627
  const blueprintDisplayChoices = blueprintFileNames.map((blueprintFileName) => toTitleCase(blueprintFileName));
515
628
 
@@ -550,15 +663,6 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
550
663
  if (architectureRecommendation) {
551
664
  architectureRecommendation.appliedStackFileName = selectedResolvedStackFileName;
552
665
  architectureRecommendation.appliedBlueprintFileName = selectedResolvedBlueprintFileName;
553
-
554
- if (!architectureRecommendation.userVeto) {
555
- architectureRecommendation.userVeto = {
556
- applied: false,
557
- selectedStackFileName: selectedResolvedStackFileName,
558
- selectedBlueprintFileName: selectedResolvedBlueprintFileName,
559
- source: 'recommendation',
560
- };
561
- }
562
666
  }
563
667
 
564
668
  const derivedAdditionalBlueprintFileNames = deriveAdditionalBlueprintFileNamesFromStacks(
@@ -580,23 +684,25 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
580
684
  detectionTransparency.decision.selectedAdditionalBlueprintFileNames = selectedAdditionalBlueprintFileNames;
581
685
  detectionTransparency.decision.usedDetectedSetup = detectedSetupWasApplied;
582
686
 
583
- const includeCiGuardrails = typeof initOptions.ci === 'boolean'
584
- ? initOptions.ci
585
- : typeof selectedPreset?.ci === 'boolean'
586
- ? selectedPreset.ci
587
- : selectedProfilePack?.lockCi
588
- ? selectedProfilePack.defaultCi
589
- : typeof selectedProfilePack?.defaultCi === 'boolean'
590
- ? selectedProfilePack.defaultCi
591
- : selectedProfile.lockCi
592
- ? selectedProfile.defaultCi
593
- : await askYesNo('Enable CI/CD quality checks (guardrails) and the LLM Judge policy?', userInterface, selectedProfile.defaultCi);
687
+ const includeCiGuardrails = typeof discoveryAnswers?.includeCiGuardrails === 'boolean'
688
+ ? discoveryAnswers.includeCiGuardrails
689
+ : ciGuardrailsSelection.shouldAsk
690
+ ? (!isInteractiveSession
691
+ ? ciGuardrailsSelection.value
692
+ : await askYesNo(
693
+ 'Enable CI/CD quality checks (guardrails) and the LLM Judge policy?',
694
+ userInterface,
695
+ ciGuardrailsSelection.value
696
+ ))
697
+ : ciGuardrailsSelection.value;
594
698
 
595
699
  detectionTransparency.activeRulesSummary.ciGuardrailsEnabled = includeCiGuardrails;
596
700
 
597
701
  detectionTransparency.decision.selectedProjectScopeKey = selectedProjectScopeKey;
598
702
  detectionTransparency.decision.selectedProjectScopeLabel = selectedProjectScopeLabel;
599
703
 
704
+ await createBackup(resolvedTargetDirectoryPath);
705
+
600
706
  await copyGovernanceAssetsToTarget(resolvedTargetDirectoryPath, {
601
707
  includeMcpTemplate: shouldIncludeMcpTemplate,
602
708
  });
@@ -629,83 +735,50 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
629
735
  // --- Project Documentation Scaffolding ---
630
736
  let scaffoldingResult = null;
631
737
  const supplementalMaterializedDocFileNames = [];
632
- const isFreshProjectTarget = wasDirectoryEffectivelyEmpty && !hadExistingProjectDocsBeforeInit;
633
- const shouldOfferScaffolding = initOptions.scaffoldDocs === true
634
- || Boolean(initOptions.projectConfig)
635
- || (initOptions.scaffoldDocs !== false && isFreshProjectTarget);
636
-
637
- if (shouldOfferScaffolding) {
638
- if (initOptions.scaffoldDocs === true && !initOptions.projectConfig && !isInteractiveSession) {
639
- throw new Error('Non-interactive scaffolding requires --project-config when --scaffold-docs is enabled.');
738
+ if (discoveryAnswers) {
739
+ const normalizedConfigDocsLanguage = normalizeDocsLanguage(discoveryAnswers.docsLang || '');
740
+ if (discoveryAnswers.docsLang && !normalizedConfigDocsLanguage) {
741
+ throw new Error(`Unsupported docs language in project config: ${discoveryAnswers.docsLang}. Supported values: en, id`);
640
742
  }
641
743
 
642
- const userWantsScaffolding = initOptions.scaffoldDocs === true
643
- || initOptions.projectConfig
644
- || (!isInteractiveSession
645
- ? false
646
- : await askYesNo(
647
- 'This is a fresh project. Want me to scaffold project documentation (architecture, database, API contract, flow)?',
648
- userInterface,
649
- true
650
- ));
744
+ // Keep generated docs in English by default to align with the writing scope.
745
+ // A different output language is only used when explicitly requested via --docs-lang.
746
+ const selectedDocsLanguage = initOptions.docsLang;
651
747
 
652
- if (userWantsScaffolding) {
653
- let discoveryAnswers;
748
+ if (!initOptions.docsLangProvided && normalizedConfigDocsLanguage && normalizedConfigDocsLanguage !== 'en') {
749
+ console.log('[INFO] Project config docsLang is set, but output defaults to English. Use --docs-lang to override.');
750
+ }
654
751
 
655
- if (initOptions.projectConfig) {
656
- discoveryAnswers = await loadProjectConfig(initOptions.projectConfig);
657
- console.log(`\nLoaded project configuration from: ${initOptions.projectConfig}`);
658
- } else {
659
- discoveryAnswers = await runProjectDiscovery(userInterface, {
660
- defaultProjectName: path.basename(resolvedTargetDirectoryPath),
661
- defaultProjectDescription: architectureProjectDescription,
662
- });
752
+ scaffoldingResult = await generateProjectDocumentation(
753
+ resolvedTargetDirectoryPath,
754
+ discoveryAnswers,
755
+ {
756
+ stackFileName: selectedResolvedStackFileName,
757
+ additionalStackFileNames: selectedAdditionalStackFileNames,
758
+ blueprintFileName: selectedResolvedBlueprintFileName,
759
+ additionalBlueprintFileNames: selectedAdditionalBlueprintFileNames,
760
+ runtimeEnvironmentKey: selectedRuntimeEnvironmentKey,
761
+ runtimeEnvironmentLabel: resolveRuntimeEnvironmentLabelFromKey(selectedRuntimeEnvironmentKey),
762
+ architectureRecommendation,
763
+ },
764
+ {
765
+ docsLanguage: selectedDocsLanguage,
663
766
  }
767
+ );
664
768
 
665
- const normalizedConfigDocsLanguage = normalizeDocsLanguage(discoveryAnswers.docsLang || '');
666
- if (discoveryAnswers.docsLang && !normalizedConfigDocsLanguage) {
667
- throw new Error(`Unsupported docs language in project config: ${discoveryAnswers.docsLang}. Supported values: en, id`);
769
+ if (scaffoldingResult.bootstrapMode === 'ai-synthesis') {
770
+ console.log(`\nAI synthesis bootstrap prompts generated in .agent-context/prompts/:`);
771
+ for (const generatedPromptFileName of scaffoldingResult.generatedPromptFileNames || []) {
772
+ console.log(` - .agent-context/prompts/${generatedPromptFileName}`);
668
773
  }
669
-
670
- // Keep generated docs in English by default to align with the writing scope.
671
- // A different output language is only used when explicitly requested via --docs-lang.
672
- const selectedDocsLanguage = initOptions.docsLang;
673
-
674
- if (!initOptions.docsLangProvided && normalizedConfigDocsLanguage && normalizedConfigDocsLanguage !== 'en') {
675
- console.log('[INFO] Project config docsLang is set, but output defaults to English. Use --docs-lang to override.');
774
+ for (const materializedFileName of scaffoldingResult.materializedFileNames || []) {
775
+ console.log(` - docs/${materializedFileName}`);
676
776
  }
677
-
678
- scaffoldingResult = await generateProjectDocumentation(
679
- resolvedTargetDirectoryPath,
680
- discoveryAnswers,
681
- {
682
- stackFileName: selectedResolvedStackFileName,
683
- additionalStackFileNames: selectedAdditionalStackFileNames,
684
- blueprintFileName: selectedResolvedBlueprintFileName,
685
- additionalBlueprintFileNames: selectedAdditionalBlueprintFileNames,
686
- runtimeEnvironmentKey: selectedRuntimeEnvironmentKey,
687
- runtimeEnvironmentLabel: resolveRuntimeEnvironmentLabelFromKey(selectedRuntimeEnvironmentKey),
688
- architectureRecommendation,
689
- },
690
- {
691
- docsLanguage: selectedDocsLanguage,
692
- }
693
- );
694
-
695
- if (scaffoldingResult.bootstrapMode === 'ai-synthesis') {
696
- console.log(`\nAI synthesis bootstrap prompts generated in .agent-context/prompts/:`);
697
- for (const generatedPromptFileName of scaffoldingResult.generatedPromptFileNames || []) {
698
- console.log(` - .agent-context/prompts/${generatedPromptFileName}`);
699
- }
700
- for (const materializedFileName of scaffoldingResult.materializedFileNames || []) {
701
- console.log(` - docs/${materializedFileName}`);
702
- }
703
- console.log('Project docs will be authored dynamically by your IDE assistant from these prompts.');
704
- } else {
705
- console.log(`\nProject documentation generated in docs/:`);
706
- for (const generatedFileName of scaffoldingResult.generatedFileNames) {
707
- console.log(` - docs/${generatedFileName}`);
708
- }
777
+ console.log('Project docs will be authored dynamically by your IDE assistant from these prompts.');
778
+ } else {
779
+ console.log(`\nProject documentation generated in docs/:`);
780
+ for (const generatedFileName of scaffoldingResult.generatedFileNames) {
781
+ console.log(` - docs/${generatedFileName}`);
709
782
  }
710
783
  }
711
784
  }
@@ -795,10 +868,6 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
795
868
  uiScopeSignals: existingProjectUiScopeSignals,
796
869
  });
797
870
 
798
- if (architectPreferenceUpdated && architectPreferenceState) {
799
- await writeArchitectPreferenceState(architectPreferenceState);
800
- }
801
-
802
871
  console.log('\nInitialization complete.');
803
872
  console.log(`- Target directory: ${resolvedTargetDirectoryPath}`);
804
873
  console.log(`- Profile: ${selectedProfile.displayName}`);
@@ -808,18 +877,8 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
808
877
  if (selectedProfilePack) {
809
878
  console.log(`- Team profile pack: ${selectedProfilePack.displayName}`);
810
879
  }
811
- if (architectureRecommendation) {
812
- console.log(
813
- `- Architect recommendation: ${toTitleCase(architectureRecommendation.recommendedStackFileName)} + ${toTitleCase(architectureRecommendation.recommendedBlueprintFileName)} (${architectureRecommendation.confidenceLabel})`
814
- );
815
- if (!projectDetection.hasExistingProjectFiles) {
816
- console.log(`- Project domain: ${selectedProjectScopeLabel}`);
817
- }
818
- if (architectureRecommendation.userVeto?.applied) {
819
- console.log(
820
- `- User veto path: applied (${toTitleCase(architectureRecommendation.userVeto.selectedStackFileName)} + ${toTitleCase(architectureRecommendation.userVeto.selectedBlueprintFileName)})`
821
- );
822
- }
880
+ if (!projectDetection.hasExistingProjectFiles) {
881
+ console.log(`- Project domain: ${selectedProjectScopeLabel}`);
823
882
  }
824
883
  console.log(`- Stack: ${toTitleCase(selectedResolvedStackFileName)}`);
825
884
  if (selectedAdditionalStackFileNames.length > 0) {
@@ -833,7 +892,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
833
892
  console.log(`- CI/CD quality checks (guardrails): ${includeCiGuardrails ? 'enabled' : 'disabled'}`);
834
893
  console.log(`- Blocking severities: ${formatBlockingSeverities(selectedProfile.blockingSeverities)}`);
835
894
  console.log(`- Setup time: ${formatDuration(setupDurationMs)}`);
836
- console.log('- Generated files: .agent-instructions.md, .cursorrules, .windsurfrules, .clauderc, and .agent-context/state/onboarding-report.json');
895
+ console.log('- Generated files: .instructions.md, .agent-instructions.md, compiled adapters, and .agent-context/state/onboarding-report.json');
837
896
  if (scaffoldingResult?.bootstrapMode === 'ai-synthesis') {
838
897
  console.log(`- Bootstrap prompts: ${(scaffoldingResult.generatedPromptFileNames || []).length} files generated in .agent-context/prompts/`);
839
898
  if ((scaffoldingResult.materializedFileNames || []).length > 0) {
@@ -33,6 +33,7 @@ import {
33
33
  } from '../detector.mjs';
34
34
  import {
35
35
  buildCompiledRulesContent,
36
+ compileDynamicContext,
36
37
  writeSelectedPolicy,
37
38
  writeOnboardingReport,
38
39
  loadOnboardingReportIfExists,
@@ -408,8 +409,15 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
408
409
  supplementalCreatedFileNames.push('docs/design-intent.json');
409
410
  }
410
411
 
411
- await fs.writeFile(currentRulesPath, plannedRulesContent, 'utf8');
412
- await fs.writeFile(path.join(resolvedTargetDirectoryPath, '.windsurfrules'), plannedRulesContent, 'utf8');
412
+ await compileDynamicContext({
413
+ targetDirectoryPath: resolvedTargetDirectoryPath,
414
+ selectedProfileName,
415
+ selectedStackFileName,
416
+ selectedAdditionalStackFileNames,
417
+ selectedBlueprintFileName,
418
+ selectedAdditionalBlueprintFileNames,
419
+ includeCiGuardrails,
420
+ });
413
421
  await writeSelectedPolicy(resolvedTargetDirectoryPath, selectedProfileName);
414
422
 
415
423
  const setupDurationMs = Date.now() - setupStartedAt;
@@ -452,7 +460,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
452
460
  supplementalCreatedFileNames.forEach((fileName) => console.log(` [NEW] ${fileName} (seed)`));
453
461
  }
454
462
 
455
- console.log('\nRefreshed files: .cursorrules, .windsurfrules, .agent-context/state/onboarding-report.json');
463
+ console.log('\nRefreshed files: .instructions.md, .agent-instructions.md, compiled adapters, and .agent-context/state/onboarding-report.json');
456
464
  } catch (error) {
457
465
  console.error('\n[FATAL] An error occurred during upgrade. Attempting automatic rollback...');
458
466
  try {
@@ -188,8 +188,8 @@ export async function buildCompiledRulesContent({
188
188
  `6. .agent-context/policies/${POLICY_FILE_NAME}`,
189
189
  '7. docs/ project context (or bootstrap prompts when docs are not materialized)',
190
190
  '',
191
- 'Primary entrypoint: .agent-instructions.md',
192
- 'Adapter entrypoints: .cursorrules, .windsurfrules, .clauderc, .gemini/instructions.md, .github/copilot-instructions.md',
191
+ 'Project-specific compiled snapshot: .agent-instructions.md',
192
+ 'Compiled adapter entrypoints: .cursorrules, .windsurfrules, .clauderc, .gemini/instructions.md, .github/copilot-instructions.md',
193
193
  'Canonical baseline: .instructions.md',
194
194
  ].join('\n')
195
195
  );
@@ -396,9 +396,15 @@ export async function buildCompiledRulesContent({
396
396
  ...projectDocsEntries.map((docFileName, docIndex) => `${docIndex + 1}. docs/${docFileName}`),
397
397
  '',
398
398
  'Universal SOP hard block policy:',
399
+ '- Stop implementation if docs/project-brief.md is missing.',
399
400
  '- Stop implementation if docs/architecture-decision-record.md (alias: docs/Architecture-Decision-Record.md) is missing.',
401
+ '- Stop implementation if docs/flow-overview.md is missing.',
402
+ '- If the product uses persistent data, docs/database-schema.md must exist before coding continues.',
403
+ '- If the product exposes API or web application flows, docs/api-contract.md must exist before coding continues.',
400
404
  '- For UI scope, stop implementation if docs/DESIGN.md or docs/design-intent.json is missing.',
401
405
  '- Materialize missing docs first, then continue coding.',
406
+ '- Bootstrap missing docs from real repo evidence and the latest user request. Do not write generic placeholder templates.',
407
+ '- Separate confirmed facts from assumptions and end each major explanation with the next validation action.',
402
408
  '',
403
409
  'These docs were generated during project initialization and reflect the architecture,',
404
410
  'database design, API contracts, and application flows chosen for this project.',
@@ -428,10 +434,15 @@ export async function buildCompiledRulesContent({
428
434
  '',
429
435
  'Bootstrap policy:',
430
436
  '- Hard block: do not write application code until docs/project-brief.md and docs/architecture-decision-record.md exist.',
437
+ '- docs/flow-overview.md must also exist before coding continues.',
438
+ '- Add docs/database-schema.md when persistent data is involved.',
439
+ '- Add docs/api-contract.md when API or web application flows are involved.',
431
440
  '- If docs/project-brief.md is missing, execute bootstrap-project-context prompt immediately.',
432
441
  hasBootstrapDesignPrompt
433
442
  ? '- For UI scope: if docs/DESIGN.md or docs/design-intent.json is missing, execute bootstrap-design prompt before implementing UI surfaces.'
434
443
  : '- For UI scope: add a design bootstrap prompt before implementing UI surfaces.',
444
+ '- Bootstrap docs from repo evidence and the latest user request. Do not use generic placeholder templates.',
445
+ '- Separate confirmed facts from assumptions, include an Assumptions to Validate section when context is incomplete, and end with the next validation action.',
435
446
  '- Save generated docs under docs/ and keep them updated when feature scope changes.',
436
447
  'Latest user prompt defines current feature scope and product direction.',
437
448
  'Treat synthesized docs as living references, then continue implementation with those docs as source of truth.',
@@ -100,6 +100,24 @@ const PROJECT_MARKER_FILE_NAMES = new Set([
100
100
  'tsconfig.json',
101
101
  ...DIRECT_UI_MARKER_NAMES,
102
102
  ]);
103
+ const INTERNAL_GOVERNANCE_SURFACE_NAMES = new Set([
104
+ '.agent-context',
105
+ '.agent-instructions.md',
106
+ '.agent-override.md',
107
+ '.agentic-backup',
108
+ '.agents',
109
+ '.clauderc',
110
+ '.cursorrules',
111
+ '.cursor',
112
+ '.gemini',
113
+ '.github',
114
+ '.instructions.md',
115
+ '.vscode',
116
+ '.windsurfrules',
117
+ '.zed',
118
+ 'AGENTS.md',
119
+ 'mcp.json',
120
+ ]);
103
121
 
104
122
  function looksLikeWorkspaceSearchCandidate(directoryName) {
105
123
  const normalizedDirectoryName = String(directoryName || '').trim().toLowerCase();
@@ -148,6 +166,10 @@ export async function collectProjectMarkers(targetDirectoryPath) {
148
166
  continue;
149
167
  }
150
168
 
169
+ if (INTERNAL_GOVERNANCE_SURFACE_NAMES.has(directoryEntry.name)) {
170
+ continue;
171
+ }
172
+
151
173
  markerNames.add(directoryEntry.name);
152
174
  }
153
175