@cubis/foundry 0.3.79 → 0.3.80

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 (80) hide show
  1. package/dist/cli/build/commands.js +1 -1
  2. package/dist/cli/build/commands.js.map +1 -1
  3. package/dist/cli/core.js +253 -149
  4. package/dist/cli/core.js.map +1 -1
  5. package/package.json +1 -1
  6. package/src/cli/build/commands.ts +1 -1
  7. package/src/cli/core.ts +282 -194
  8. package/workflows/workflows/agent-environment-setup/generated/route-manifest.json +2 -2
  9. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/accessibility.toml +1 -1
  10. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/architecture.toml +2 -2
  11. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/backend.toml +1 -1
  12. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/create.toml +1 -1
  13. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/database.toml +1 -1
  14. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/debug.toml +1 -1
  15. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/devops.toml +1 -1
  16. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/implement-track.toml +1 -1
  17. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/migrate.toml +1 -1
  18. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/mobile.toml +1 -1
  19. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/onboard.toml +1 -1
  20. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/orchestrate.toml +1 -1
  21. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/plan.toml +1 -1
  22. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/refactor.toml +1 -1
  23. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/release.toml +1 -1
  24. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/review.toml +1 -1
  25. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/security.toml +1 -1
  26. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/spec.toml +1 -1
  27. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/test.toml +1 -1
  28. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/vercel.toml +1 -1
  29. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/architecture.md +19 -19
  30. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/spec.md +2 -2
  31. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/architecture.md +19 -19
  32. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/spec.md +2 -2
  33. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/architecture.md +19 -19
  34. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/spec.md +2 -2
  35. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-accessibility.prompt.md +1 -1
  36. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-architecture.prompt.md +2 -2
  37. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-backend.prompt.md +1 -1
  38. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-create.prompt.md +1 -1
  39. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-database.prompt.md +1 -1
  40. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-debug.prompt.md +1 -1
  41. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-devops.prompt.md +1 -1
  42. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-implement-track.prompt.md +1 -1
  43. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-migrate.prompt.md +1 -1
  44. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-mobile.prompt.md +1 -1
  45. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-onboard.prompt.md +1 -1
  46. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-orchestrate.prompt.md +1 -1
  47. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-plan.prompt.md +1 -1
  48. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-refactor.prompt.md +1 -1
  49. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-release.prompt.md +1 -1
  50. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-review.prompt.md +1 -1
  51. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-security.prompt.md +1 -1
  52. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-spec.prompt.md +1 -1
  53. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-test.prompt.md +1 -1
  54. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-vercel.prompt.md +1 -1
  55. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/architecture.md +19 -19
  56. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/spec.md +2 -2
  57. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/accessibility.toml +1 -1
  58. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/architecture.toml +2 -2
  59. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/backend.toml +1 -1
  60. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/create.toml +1 -1
  61. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/database.toml +1 -1
  62. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/debug.toml +1 -1
  63. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/devops.toml +1 -1
  64. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/implement-track.toml +1 -1
  65. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/migrate.toml +1 -1
  66. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/mobile.toml +1 -1
  67. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/onboard.toml +1 -1
  68. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/orchestrate.toml +1 -1
  69. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/plan.toml +1 -1
  70. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/refactor.toml +1 -1
  71. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/release.toml +1 -1
  72. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/review.toml +1 -1
  73. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/security.toml +1 -1
  74. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/spec.toml +1 -1
  75. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/test.toml +1 -1
  76. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/vercel.toml +1 -1
  77. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/architecture.md +19 -19
  78. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/spec.md +2 -2
  79. package/workflows/workflows/agent-environment-setup/shared/workflows/architecture.md +19 -19
  80. package/workflows/workflows/agent-environment-setup/shared/workflows/spec.md +2 -2
package/dist/cli/core.js CHANGED
@@ -35,6 +35,8 @@ const TECH_ARCHITECTURE_BLOCK_START_RE = /<!--\s*cbx:architecture:tech:start[^>]
35
35
  const TECH_ARCHITECTURE_BLOCK_END_RE = /<!--\s*cbx:architecture:tech:end\s*-->/g;
36
36
  const ROADMAP_FOUNDATION_BLOCK_START_RE = /<!--\s*cbx:roadmap:foundation:start[^>]*-->/g;
37
37
  const ROADMAP_FOUNDATION_BLOCK_END_RE = /<!--\s*cbx:roadmap:foundation:end\s*-->/g;
38
+ const FOUNDATION_DOCS_DIR = path.join("docs", "foundation");
39
+ const FOUNDATION_ADR_DIR = path.join(FOUNDATION_DOCS_DIR, "adr");
38
40
  const COPILOT_ALLOWED_SKILL_FRONTMATTER_KEYS = new Set([
39
41
  "compatibility",
40
42
  "description",
@@ -1127,7 +1129,7 @@ function buildEngineeringArchitectureSection(snapshot) {
1127
1129
  ...profile.testingStrategy.map((rule) => ` - ${rule}`),
1128
1130
  "- Doc refresh policy:",
1129
1131
  " - Update these managed sections when architecture, scale, boundaries, design-system rules, or testing strategy changes.",
1130
- " - For non-trivial work, read PRODUCT.md, ENGINEERING_RULES.md, ARCHITECTURE.md, and TECH.md in that order when they exist.",
1132
+ ` - For non-trivial work, read ${FOUNDATION_DOCS_DIR}/PRODUCT.md, ENGINEERING_RULES.md, ${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md, and ${FOUNDATION_DOCS_DIR}/TECH.md in that order when they exist.`,
1131
1133
  "<!-- cbx:architecture:rules:end -->",
1132
1134
  "",
1133
1135
  ].join("\n");
@@ -1239,7 +1241,7 @@ function buildRoadmapFoundationSection(snapshot, specRoots = []) {
1239
1241
  "- Use this section for medium-term scaling themes, major migrations, or cross-team architecture investments.",
1240
1242
  "",
1241
1243
  "### Backbone Maintenance",
1242
- "- Keep PRODUCT.md, ARCHITECTURE.md, ENGINEERING_RULES.md, and TECH.md aligned when direction or structure changes.",
1244
+ `- Keep ${FOUNDATION_DOCS_DIR}/PRODUCT.md, ${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md, ENGINEERING_RULES.md, and ${FOUNDATION_DOCS_DIR}/TECH.md aligned when direction or structure changes.`,
1243
1245
  "- Link major roadmap themes back to specs and ADRs instead of burying them in chat-only planning.",
1244
1246
  "<!-- cbx:roadmap:foundation:end -->",
1245
1247
  "",
@@ -1376,6 +1378,42 @@ function buildRoadmapTemplate(snapshot, specRoots = []) {
1376
1378
  "",
1377
1379
  ].join("\n");
1378
1380
  }
1381
+ function buildProductBuildSkeleton() {
1382
+ return [
1383
+ "# Product",
1384
+ "",
1385
+ "This file is managed by `cbx build architecture`.",
1386
+ "",
1387
+ "<!-- cbx:product:foundation:start version=1 profile=uninitialized -->",
1388
+ "Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
1389
+ "<!-- cbx:product:foundation:end -->",
1390
+ "",
1391
+ ].join("\n");
1392
+ }
1393
+ function buildArchitectureBuildSkeleton() {
1394
+ return [
1395
+ "# Architecture",
1396
+ "",
1397
+ "This file is managed by `cbx build architecture`.",
1398
+ "",
1399
+ "<!-- cbx:architecture:doc:start version=1 profile=uninitialized -->",
1400
+ "Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
1401
+ "<!-- cbx:architecture:doc:end -->",
1402
+ "",
1403
+ ].join("\n");
1404
+ }
1405
+ function buildTechBuildSkeleton() {
1406
+ return [
1407
+ "# TECH.md",
1408
+ "",
1409
+ "This file is managed by `cbx build architecture`.",
1410
+ "",
1411
+ "<!-- cbx:architecture:tech:start version=1 snapshot=uninitialized -->",
1412
+ "Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
1413
+ "<!-- cbx:architecture:tech:end -->",
1414
+ "",
1415
+ ].join("\n");
1416
+ }
1379
1417
  function buildAdrReadme() {
1380
1418
  return [
1381
1419
  "# Architecture Decision Records",
@@ -1450,7 +1488,7 @@ function buildEngineeringRulesManagedBlock({ platform, productFilePath, architec
1450
1488
  "2. Keep architecture simple (KISS) and avoid speculative work (YAGNI).",
1451
1489
  "3. Apply SOLID pragmatically to reduce change risk, not add ceremony.",
1452
1490
  "4. Use clear naming with focused responsibilities and explicit boundaries.",
1453
- "5. For non-trivial work, read PRODUCT.md, ENGINEERING_RULES.md, ARCHITECTURE.md, and TECH.md in that order when they exist before planning or implementation.",
1491
+ `5. For non-trivial work, read ${FOUNDATION_DOCS_DIR}/PRODUCT.md, ENGINEERING_RULES.md, ${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md, and ${FOUNDATION_DOCS_DIR}/TECH.md in that order when they exist before planning or implementation.`,
1454
1492
  "6. Require validation evidence (lint/types/tests) before merge.",
1455
1493
  "7. Use Decision Log response style.",
1456
1494
  "8. Every Decision Log must include a `Skills Used` section listing skill, workflow, or agent names.",
@@ -1617,6 +1655,16 @@ async function upsertTaggedSectionInFile({ targetPath, initialContent, block, st
1617
1655
  nextContent =
1618
1656
  trimmed.length > 0 ? `${trimmed}\n\n${block}\n` : `${block}\n`;
1619
1657
  }
1658
+ if (!exists) {
1659
+ if (!dryRun) {
1660
+ await mkdir(path.dirname(targetPath), { recursive: true });
1661
+ await writeFile(targetPath, nextContent, "utf8");
1662
+ }
1663
+ return {
1664
+ action: dryRun ? "would-create" : "created",
1665
+ filePath: targetPath,
1666
+ };
1667
+ }
1620
1668
  if (nextContent === original) {
1621
1669
  return {
1622
1670
  action: "unchanged",
@@ -1638,18 +1686,14 @@ async function upsertTaggedSectionInFile({ targetPath, initialContent, block, st
1638
1686
  filePath: targetPath,
1639
1687
  };
1640
1688
  }
1641
- function buildArchitectureBuildMetadata({ platform, researchMode, productProfileHash, architectureDocHash, rulesProfileHash, techSnapshotHash, roadmapProfileHash, }) {
1689
+ function buildArchitectureBuildMetadata({ platform, researchMode, managedDocs, }) {
1642
1690
  return {
1643
- schemaVersion: 2,
1691
+ schemaVersion: 3,
1644
1692
  generatedBy: "cbx build architecture",
1645
1693
  generatedAt: new Date().toISOString(),
1646
1694
  platform,
1647
1695
  researchMode,
1648
- productProfileHash,
1649
- architectureDocHash,
1650
- rulesProfileHash,
1651
- techSnapshotHash,
1652
- roadmapProfileHash,
1696
+ managedDocs,
1653
1697
  };
1654
1698
  }
1655
1699
  async function ensureArchitectureDocScaffold({ workspaceRoot, snapshot, specRoots = [], overwrite = false, dryRun = false, }) {
@@ -1746,6 +1790,78 @@ async function ensureArchitectureDocScaffold({ workspaceRoot, snapshot, specRoot
1746
1790
  adrTemplateResult,
1747
1791
  };
1748
1792
  }
1793
+ async function ensureArchitectureBuildScaffold({ workspaceRoot, dryRun = false, }) {
1794
+ const foundationRoot = path.join(workspaceRoot, FOUNDATION_DOCS_DIR);
1795
+ const productPath = path.join(foundationRoot, "PRODUCT.md");
1796
+ const architectureDocPath = path.join(foundationRoot, "ARCHITECTURE.md");
1797
+ const techMdPath = path.join(foundationRoot, "TECH.md");
1798
+ const adrDir = path.join(workspaceRoot, FOUNDATION_ADR_DIR);
1799
+ const adrReadmePath = path.join(adrDir, "README.md");
1800
+ const adrTemplatePath = path.join(adrDir, "0000-template.md");
1801
+ const productResult = await upsertTaggedSectionInFile({
1802
+ targetPath: productPath,
1803
+ initialContent: `${buildProductBuildSkeleton()}\n`,
1804
+ block: [
1805
+ "<!-- cbx:product:foundation:start version=1 profile=uninitialized -->",
1806
+ "Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
1807
+ "<!-- cbx:product:foundation:end -->",
1808
+ "",
1809
+ ].join("\n"),
1810
+ startPattern: PRODUCT_FOUNDATION_BLOCK_START_RE,
1811
+ endPattern: PRODUCT_FOUNDATION_BLOCK_END_RE,
1812
+ dryRun,
1813
+ });
1814
+ const architectureDocResult = await upsertTaggedSectionInFile({
1815
+ targetPath: architectureDocPath,
1816
+ initialContent: `${buildArchitectureBuildSkeleton()}\n`,
1817
+ block: [
1818
+ "<!-- cbx:architecture:doc:start version=1 profile=uninitialized -->",
1819
+ "Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
1820
+ "<!-- cbx:architecture:doc:end -->",
1821
+ "",
1822
+ ].join("\n"),
1823
+ startPattern: ARCHITECTURE_DOC_BLOCK_START_RE,
1824
+ endPattern: ARCHITECTURE_DOC_BLOCK_END_RE,
1825
+ dryRun,
1826
+ });
1827
+ const techResult = await upsertTaggedSectionInFile({
1828
+ targetPath: techMdPath,
1829
+ initialContent: `${buildTechBuildSkeleton()}\n`,
1830
+ block: [
1831
+ "<!-- cbx:architecture:tech:start version=1 snapshot=uninitialized -->",
1832
+ "Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
1833
+ "<!-- cbx:architecture:tech:end -->",
1834
+ "",
1835
+ ].join("\n"),
1836
+ startPattern: TECH_ARCHITECTURE_BLOCK_START_RE,
1837
+ endPattern: TECH_ARCHITECTURE_BLOCK_END_RE,
1838
+ dryRun,
1839
+ });
1840
+ const adrReadmeResult = await writeTextFile({
1841
+ targetPath: adrReadmePath,
1842
+ content: `${buildAdrReadme()}\n`,
1843
+ overwrite: false,
1844
+ dryRun,
1845
+ });
1846
+ const adrTemplateResult = await writeTextFile({
1847
+ targetPath: adrTemplatePath,
1848
+ content: `${buildAdrTemplate()}\n`,
1849
+ overwrite: false,
1850
+ dryRun,
1851
+ });
1852
+ return {
1853
+ productPath,
1854
+ architectureDocPath,
1855
+ techMdPath,
1856
+ adrReadmePath,
1857
+ adrTemplatePath,
1858
+ productResult,
1859
+ architectureDocResult,
1860
+ techResult,
1861
+ adrReadmeResult,
1862
+ adrTemplateResult,
1863
+ };
1864
+ }
1749
1865
  function normalizeTechPackageName(value) {
1750
1866
  if (value === undefined || value === null)
1751
1867
  return null;
@@ -10248,7 +10364,7 @@ function printInstallEngineeringSummary({ engineeringResults, techResult }) {
10248
10364
  function printInstallDocumentationNotice() {
10249
10365
  console.log("\nProject backbone docs:");
10250
10366
  console.log("- Install only wires the rule references and workflow assets.");
10251
- console.log("- Use `cbx rules init` to scaffold ENGINEERING_RULES.md and TECH.md, or `cbx build architecture --platform <codex|claude|gemini|copilot>` to generate PRODUCT.md, ARCHITECTURE.md, ENGINEERING_RULES.md, TECH.md, ROADMAP.md, and ADR scaffolds.");
10367
+ console.log(`- Use \`cbx rules init\` to scaffold ENGINEERING_RULES.md and TECH.md, or \`cbx build architecture --platform <codex|claude|gemini|copilot>\` to generate ${FOUNDATION_DOCS_DIR}/PRODUCT.md, ${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md, ${FOUNDATION_DOCS_DIR}/TECH.md, and ADR scaffolds.`);
10252
10368
  }
10253
10369
  async function upsertEngineeringArtifacts({ platform, scope, overwrite = false, skipTech = false, dryRun = false, cwd = process.cwd(), }) {
10254
10370
  const ruleFilePath = await resolveRuleFilePath(platform, scope, cwd);
@@ -10399,6 +10515,61 @@ async function listSpecPackRoots(workspaceRoot) {
10399
10515
  .sort((a, b) => a.localeCompare(b))
10400
10516
  .slice(0, 8);
10401
10517
  }
10518
+ async function resolveArchitectureInspectionAnchors(workspaceRoot, snapshot, specRoots) {
10519
+ const seen = new Set();
10520
+ const ordered = [];
10521
+ const pushCandidate = async (relativePath) => {
10522
+ const normalized = toPosixPath(relativePath);
10523
+ if (!normalized || seen.has(normalized))
10524
+ return;
10525
+ if (!(await pathExists(path.join(workspaceRoot, relativePath))))
10526
+ return;
10527
+ seen.add(normalized);
10528
+ ordered.push(normalized);
10529
+ };
10530
+ for (const candidate of [
10531
+ "README.md",
10532
+ "package.json",
10533
+ "pubspec.yaml",
10534
+ "go.mod",
10535
+ "pyproject.toml",
10536
+ "Cargo.toml",
10537
+ "Dockerfile",
10538
+ "docker-compose.yml",
10539
+ "docker-compose.yaml",
10540
+ "compose.yaml",
10541
+ "cbx_config.json",
10542
+ ".vscode/mcp.json",
10543
+ ".gemini/settings.json",
10544
+ ]) {
10545
+ await pushCandidate(candidate);
10546
+ }
10547
+ for (const specRoot of specRoots.slice(0, 4)) {
10548
+ await pushCandidate(specRoot);
10549
+ }
10550
+ for (const app of snapshot.architectureByApp || []) {
10551
+ if (!app?.rootPath || app.rootPath === ".")
10552
+ continue;
10553
+ await pushCandidate(app.rootPath);
10554
+ for (const child of [
10555
+ "README.md",
10556
+ "src",
10557
+ "lib",
10558
+ "app",
10559
+ "prisma",
10560
+ "migrations",
10561
+ "test",
10562
+ "tests",
10563
+ "docs",
10564
+ ]) {
10565
+ await pushCandidate(path.join(app.rootPath, child));
10566
+ }
10567
+ }
10568
+ for (const dir of snapshot.topDirs || []) {
10569
+ await pushCandidate(dir);
10570
+ }
10571
+ return ordered.slice(0, 18);
10572
+ }
10402
10573
  function resolveArchitectureConditionalSkills(snapshot, specRoots, researchMode) {
10403
10574
  const conditional = [];
10404
10575
  const frameworks = new Set(snapshot.frameworks || []);
@@ -10443,13 +10614,12 @@ async function resolveArchitectureSkillPathHints(platform, cwd, skillIds) {
10443
10614
  .map((skillId) => path.join(skillsDir, skillId, "SKILL.md"))
10444
10615
  .map((filePath) => toPosixPath(path.relative(findWorkspaceRoot(cwd), filePath)));
10445
10616
  }
10446
- function buildArchitecturePrompt({ platform, workspaceRoot, snapshot, specRoots, researchMode, coreSkills, conditionalSkills, skillPathHints, }) {
10447
- const productPath = "PRODUCT.md";
10448
- const architecturePath = "ARCHITECTURE.md";
10449
- const rulesPath = "ENGINEERING_RULES.md";
10450
- const techPath = "TECH.md";
10451
- const roadmapPath = "ROADMAP.md";
10452
- const adrReadmePath = "docs/adr/README.md";
10617
+ function buildArchitecturePrompt({ platform, workspaceRoot, snapshot, specRoots, inspectionAnchors, researchMode, coreSkills, conditionalSkills, skillPathHints, }) {
10618
+ const productPath = `${FOUNDATION_DOCS_DIR}/PRODUCT.md`;
10619
+ const architecturePath = `${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md`;
10620
+ const techPath = `${FOUNDATION_DOCS_DIR}/TECH.md`;
10621
+ const adrReadmePath = `${FOUNDATION_ADR_DIR}/README.md`;
10622
+ const adrTemplatePath = `${FOUNDATION_ADR_DIR}/0000-template.md`;
10453
10623
  const architectureSignals = snapshot.architectureByApp
10454
10624
  .filter((item) => (item.architectureSignals || []).length > 0)
10455
10625
  .map((item) => {
@@ -10460,8 +10630,8 @@ function buildArchitecturePrompt({ platform, workspaceRoot, snapshot, specRoots,
10460
10630
  `You are running inside ${platform}.`,
10461
10631
  "",
10462
10632
  "Objective:",
10463
- `- Inspect the repository at ${toPosixPath(workspaceRoot)} and refresh the scalable project backbone in ${productPath}, ${architecturePath}, ${rulesPath}, ${techPath}, and ${roadmapPath}.`,
10464
- "- Keep PRODUCT.md focused on intent, ARCHITECTURE.md on accepted structure, ENGINEERING_RULES.md on normative rules, TECH.md on current-state evidence, and ROADMAP.md on delivery themes.",
10633
+ `- Inspect the repository at ${toPosixPath(workspaceRoot)} and author or refresh the core foundation docs in ${productPath}, ${architecturePath}, ${techPath}, ${adrReadmePath}, and ${adrTemplatePath}.`,
10634
+ "- The content should be primarily AI-authored from repository inspection, not copied from placeholder scaffolding.",
10465
10635
  "- Preserve manual content outside the managed `cbx:*` markers.",
10466
10636
  "",
10467
10637
  "Required skill bundle:",
@@ -10481,27 +10651,33 @@ function buildArchitecturePrompt({ platform, workspaceRoot, snapshot, specRoots,
10481
10651
  architectureSignals.length > 0
10482
10652
  ? `- Architecture signals: ${architectureSignals.join(" | ")}`
10483
10653
  : "- Architecture signals: none confidently inferred from the repo scan",
10654
+ `- Entry points: ${snapshot.entryPoints.length > 0 ? snapshot.entryPoints.slice(0, 8).join(" | ") : "none detected"}`,
10655
+ `- Key scripts: ${snapshot.keyScripts.length > 0 ? snapshot.keyScripts.slice(0, 8).map((item) => `${item.name}=${item.command}`).join(" | ") : "none detected"}`,
10656
+ `- Inspection anchors: ${inspectionAnchors.length > 0 ? inspectionAnchors.join(", ") : "no concrete anchors detected; inspect the repo root, main source trees, and manifest files manually"}`,
10484
10657
  "",
10485
10658
  "Execution contract:",
10486
- `1. Read ${productPath}, ${rulesPath}, ${architecturePath}, and ${techPath} in that order when they exist.`,
10487
- "2. Inspect the repo before making architecture claims.",
10488
- "3. Update only the content between the existing managed markers in the backbone docs and preserve the marker lines themselves, including their hash metadata.",
10489
- "4. In PRODUCT.md, state product scope, primary surfaces, users or operators, core journeys, success signals, and product guardrails.",
10490
- "5. In ARCHITECTURE.md, state accepted architecture style, bounded contexts, stable decision areas, ADR linkage, and add at least one Mermaid architecture diagram if the repo is non-trivial.",
10491
- "6. In ENGINEERING_RULES.md, state architecture style, dependency rules, feature or module structure rules, design-system source of truth, testability expectations, and doc refresh policy.",
10492
- "7. In TECH.md, update architecture snapshot, module or app topology, flow narratives, Mermaid diagrams, and scaling or deployment notes.",
10493
- "8. In ROADMAP.md, capture current delivery themes, active spec-driven work, and major architecture follow-ups without turning it into a speculative wishlist.",
10659
+ "1. Inspect the repository first before writing any backbone doc content. Derive structure, product surfaces, runtime boundaries, and technical constraints from the actual codebase.",
10660
+ "2. Complete a real inspection pass before drafting. At minimum, inspect the concrete anchors listed above, plus any adjacent directories needed to understand the main execution paths, data boundaries, and integration surfaces.",
10661
+ "3. Do not infer architecture from filenames alone when you can open representative files. Read enough source to validate the main app boundaries, runtime flows, and persistence/integration patterns.",
10662
+ `4. Then read ${productPath}, ${architecturePath}, and ${techPath} in that order when they exist so you can preserve useful manual context and update existing managed sections cleanly.`,
10663
+ `5. Replace or update only the content between the existing managed markers in ${productPath}, ${architecturePath}, and ${techPath}. Do not append a second marker block.`,
10664
+ `6. In ${productPath}, write a concrete product foundation: product purpose, primary users/operators, main journeys, business capabilities, operational constraints, and what future contributors must preserve.`,
10665
+ `7. In ${architecturePath}, write a lean but detailed architecture backbone in a pragmatic arc42/C4 style: system purpose and constraints, bounded contexts, major building blocks, dependency rules, data and integration boundaries, runtime flows, deployment/operability notes, testing/debugging strategy, and only the diagram levels that add real value.`,
10666
+ `8. In ${techPath}, write the developer-facing technical map: stack, repo layout, key commands, entrypoints, data stores, external services, environment/config surfaces, MCP/tooling footprint, and change hotspots future agents should inspect before editing code.`,
10667
+ "9. Every major claim should be grounded in repository evidence. Mention concrete repo paths in the docs when a structural claim would otherwise be ambiguous.",
10668
+ "10. Avoid placeholder filler, generic checklists, and duplicated content across files. Each doc should have a clear job.",
10669
+ "11. Do not create ROADMAP.md, ENGINEERING_RULES.md, or other extra docs unless the prompt explicitly asks for them.",
10494
10670
  researchMode === "never"
10495
- ? "9. Stay repo-only. Do not use outside research."
10496
- : "9. Use repo evidence first. Use official docs when needed. Treat Reddit or community sources only as labeled secondary evidence.",
10671
+ ? "12. Stay repo-only. Do not use outside research."
10672
+ : "12. Use repo evidence first. Use official docs when needed. Treat Reddit or community sources only as labeled secondary evidence.",
10497
10673
  researchMode === "always"
10498
- ? "10. Include an external research evidence subsection in TECH.md with clearly labeled primary and secondary evidence."
10499
- : "10. Include external research notes only if they materially informed the architecture update.",
10500
- "11. If the project clearly follows Clean Architecture, feature-first modules, or another stable structure, make that explicit so future implementation stays consistent.",
10501
- `12. Ensure ${adrReadmePath} exists as the ADR entrypoint and mention ADR follow-up when the repo lacks decision history.`,
10674
+ ? `13. Include an external research evidence subsection in ${techPath} with clearly labeled primary and secondary evidence.`
10675
+ : "13. Include external research notes only if they materially informed the architecture update.",
10676
+ `14. If the project clearly follows Clean Architecture, feature-first modules, DDD, modular monolith, or another stable structure, make that explicit in ${architecturePath} with evidence from the repo.`,
10677
+ `15. Ensure ${adrReadmePath} and ${adrTemplatePath} exist as ADR entrypoints, but keep them lean.`,
10502
10678
  "",
10503
10679
  "Return one JSON object on the last line with this shape:",
10504
- '{"files_written":["PRODUCT.md","ARCHITECTURE.md","ENGINEERING_RULES.md","TECH.md","ROADMAP.md","docs/adr/README.md"],"research_used":false,"gaps":[],"next_actions":[]}',
10680
+ `{"files_written":["${productPath}","${architecturePath}","${techPath}","${adrReadmePath}","${adrTemplatePath}"],"research_used":false,"gaps":[],"next_actions":[]}`,
10505
10681
  "",
10506
10682
  "Do not emit placeholder TODOs in the managed sections.",
10507
10683
  ].join("\n");
@@ -10723,107 +10899,51 @@ async function captureFileContents(filePaths) {
10723
10899
  return snapshot;
10724
10900
  }
10725
10901
  async function readArchitectureDriftStatus(workspaceRoot, snapshot) {
10726
- const specRoots = await listSpecPackRoots(workspaceRoot);
10727
- const productPath = path.join(workspaceRoot, "PRODUCT.md");
10728
- const architecturePath = path.join(workspaceRoot, "ARCHITECTURE.md");
10729
- const rulesPath = path.join(workspaceRoot, "ENGINEERING_RULES.md");
10730
- const techPath = path.join(workspaceRoot, "TECH.md");
10731
- const roadmapPath = path.join(workspaceRoot, "ROADMAP.md");
10732
- const adrReadmePath = path.join(workspaceRoot, "docs", "adr", "README.md");
10902
+ const productPath = path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "PRODUCT.md");
10903
+ const architecturePath = path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "ARCHITECTURE.md");
10904
+ const techPath = path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "TECH.md");
10905
+ const adrReadmePath = path.join(workspaceRoot, FOUNDATION_ADR_DIR, "README.md");
10733
10906
  const metadataPath = path.join(workspaceRoot, ".cbx", ARCHITECTURE_BUILD_METADATA_FILENAME);
10734
10907
  const productExists = await pathExists(productPath);
10735
10908
  const architectureExists = await pathExists(architecturePath);
10736
- const rulesExists = await pathExists(rulesPath);
10737
10909
  const techExists = await pathExists(techPath);
10738
- const roadmapExists = await pathExists(roadmapPath);
10739
10910
  const adrReadmeExists = await pathExists(adrReadmePath);
10740
- const expectedProductHash = hashStableObject(inferProductFoundationProfile(snapshot, specRoots));
10741
- const expectedArchitectureHash = hashStableObject(inferArchitectureDocProfile(snapshot, specRoots));
10742
- const expectedRulesHash = hashStableObject(inferArchitectureContractProfile(snapshot));
10743
- const expectedTechHash = hashStableObject({
10744
- style: inferArchitectureContractProfile(snapshot).style,
10745
- topDirs: snapshot.topDirs,
10746
- frameworks: snapshot.frameworks,
10747
- architectureByApp: snapshot.architectureByApp,
10748
- });
10749
- const expectedRoadmapHash = hashStableObject({
10750
- topDirs: snapshot.topDirs,
10751
- frameworks: snapshot.frameworks,
10752
- specRoots,
10753
- });
10754
10911
  const findings = [];
10755
10912
  let actualProductHash = null;
10756
10913
  let actualArchitectureHash = null;
10757
- let actualRulesHash = null;
10758
10914
  let actualTechHash = null;
10759
- let actualRoadmapHash = null;
10760
10915
  if (!productExists) {
10761
- findings.push("PRODUCT.md is missing.");
10916
+ findings.push(`${FOUNDATION_DOCS_DIR}/PRODUCT.md is missing.`);
10762
10917
  }
10763
10918
  else {
10764
10919
  const content = await readFile(productPath, "utf8");
10765
10920
  actualProductHash = extractTaggedMarkerAttribute(content, PRODUCT_FOUNDATION_BLOCK_START_RE, "profile");
10766
10921
  if (!actualProductHash) {
10767
- findings.push("PRODUCT.md is missing the managed product foundation block.");
10768
- }
10769
- else if (actualProductHash !== expectedProductHash) {
10770
- findings.push(`PRODUCT.md foundation is stale (expected ${expectedProductHash}, found ${actualProductHash}).`);
10922
+ findings.push(`${FOUNDATION_DOCS_DIR}/PRODUCT.md is missing the managed product foundation block.`);
10771
10923
  }
10772
10924
  }
10773
10925
  if (!architectureExists) {
10774
- findings.push("ARCHITECTURE.md is missing.");
10926
+ findings.push(`${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md is missing.`);
10775
10927
  }
10776
10928
  else {
10777
10929
  const content = await readFile(architecturePath, "utf8");
10778
10930
  actualArchitectureHash = extractTaggedMarkerAttribute(content, ARCHITECTURE_DOC_BLOCK_START_RE, "profile");
10779
10931
  if (!actualArchitectureHash) {
10780
- findings.push("ARCHITECTURE.md is missing the managed architecture backbone block.");
10781
- }
10782
- else if (actualArchitectureHash !== expectedArchitectureHash) {
10783
- findings.push(`ARCHITECTURE.md backbone is stale (expected ${expectedArchitectureHash}, found ${actualArchitectureHash}).`);
10784
- }
10785
- }
10786
- if (!rulesExists) {
10787
- findings.push("ENGINEERING_RULES.md is missing.");
10788
- }
10789
- else {
10790
- const content = await readFile(rulesPath, "utf8");
10791
- actualRulesHash = extractTaggedMarkerAttribute(content, ENGINEERING_ARCHITECTURE_BLOCK_START_RE, "profile");
10792
- if (!actualRulesHash) {
10793
- findings.push("ENGINEERING_RULES.md is missing the managed architecture contract block.");
10794
- }
10795
- else if (actualRulesHash !== expectedRulesHash) {
10796
- findings.push(`ENGINEERING_RULES.md architecture profile is stale (expected ${expectedRulesHash}, found ${actualRulesHash}).`);
10932
+ findings.push(`${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md is missing the managed architecture backbone block.`);
10797
10933
  }
10798
10934
  }
10799
10935
  if (!techExists) {
10800
- findings.push("TECH.md is missing.");
10936
+ findings.push(`${FOUNDATION_DOCS_DIR}/TECH.md is missing.`);
10801
10937
  }
10802
10938
  else {
10803
10939
  const content = await readFile(techPath, "utf8");
10804
10940
  actualTechHash = extractTaggedMarkerAttribute(content, TECH_ARCHITECTURE_BLOCK_START_RE, "snapshot");
10805
10941
  if (!actualTechHash) {
10806
- findings.push("TECH.md is missing the managed architecture snapshot block.");
10807
- }
10808
- else if (actualTechHash !== expectedTechHash) {
10809
- findings.push(`TECH.md architecture snapshot is stale (expected ${expectedTechHash}, found ${actualTechHash}).`);
10810
- }
10811
- }
10812
- if (!roadmapExists) {
10813
- findings.push("ROADMAP.md is missing.");
10814
- }
10815
- else {
10816
- const content = await readFile(roadmapPath, "utf8");
10817
- actualRoadmapHash = extractTaggedMarkerAttribute(content, ROADMAP_FOUNDATION_BLOCK_START_RE, "profile");
10818
- if (!actualRoadmapHash) {
10819
- findings.push("ROADMAP.md is missing the managed roadmap foundation block.");
10820
- }
10821
- else if (actualRoadmapHash !== expectedRoadmapHash) {
10822
- findings.push(`ROADMAP.md backbone is stale (expected ${expectedRoadmapHash}, found ${actualRoadmapHash}).`);
10942
+ findings.push(`${FOUNDATION_DOCS_DIR}/TECH.md is missing the managed architecture snapshot block.`);
10823
10943
  }
10824
10944
  }
10825
10945
  if (!adrReadmeExists) {
10826
- findings.push("docs/adr/README.md is missing.");
10946
+ findings.push(`${FOUNDATION_ADR_DIR}/README.md is missing.`);
10827
10947
  }
10828
10948
  const metadata = await readJsonFileIfExists(metadataPath);
10829
10949
  if (!metadata.exists) {
@@ -10834,21 +10954,12 @@ async function readArchitectureDriftStatus(workspaceRoot, snapshot) {
10834
10954
  findings,
10835
10955
  productPath,
10836
10956
  architecturePath,
10837
- rulesPath,
10838
10957
  techPath,
10839
- roadmapPath,
10840
10958
  adrReadmePath,
10841
10959
  metadataPath,
10842
- expectedProductHash,
10843
- expectedArchitectureHash,
10844
- expectedRulesHash,
10845
- expectedTechHash,
10846
- expectedRoadmapHash,
10847
10960
  actualProductHash,
10848
10961
  actualArchitectureHash,
10849
- actualRulesHash,
10850
10962
  actualTechHash,
10851
- actualRoadmapHash,
10852
10963
  };
10853
10964
  }
10854
10965
  async function runBuildArchitecture(options) {
@@ -10872,7 +10983,7 @@ async function runBuildArchitecture(options) {
10872
10983
  console.log(`Platform: ${platform}`);
10873
10984
  console.log(`Workspace: ${toPosixPath(workspaceRoot)}`);
10874
10985
  console.log(`Status: ${drift.stale ? "stale" : "fresh"}`);
10875
- console.log("Backbone docs: PRODUCT.md, ARCHITECTURE.md, ENGINEERING_RULES.md, TECH.md, ROADMAP.md, docs/adr/README.md");
10986
+ console.log(`Backbone docs: ${FOUNDATION_DOCS_DIR}/PRODUCT.md, ${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md, ${FOUNDATION_DOCS_DIR}/TECH.md, ${FOUNDATION_ADR_DIR}/README.md`);
10876
10987
  if (drift.findings.length > 0) {
10877
10988
  console.log("Findings:");
10878
10989
  for (const finding of drift.findings) {
@@ -10885,24 +10996,12 @@ async function runBuildArchitecture(options) {
10885
10996
  return;
10886
10997
  }
10887
10998
  const managedFilePaths = [
10888
- path.join(workspaceRoot, "PRODUCT.md"),
10889
- path.join(workspaceRoot, "ARCHITECTURE.md"),
10890
- path.join(workspaceRoot, "ENGINEERING_RULES.md"),
10891
- path.join(workspaceRoot, "TECH.md"),
10892
- path.join(workspaceRoot, "ROADMAP.md"),
10893
- path.join(workspaceRoot, "docs", "adr", "README.md"),
10894
- path.join(workspaceRoot, "docs", "adr", "0000-template.md"),
10999
+ path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "PRODUCT.md"),
11000
+ path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "ARCHITECTURE.md"),
11001
+ path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "TECH.md"),
11002
+ path.join(workspaceRoot, FOUNDATION_ADR_DIR, "README.md"),
11003
+ path.join(workspaceRoot, FOUNDATION_ADR_DIR, "0000-template.md"),
10895
11004
  ];
10896
- const filesBefore = dryRun
10897
- ? Object.fromEntries(managedFilePaths.map((filePath) => [filePath, null]))
10898
- : await captureFileContents(managedFilePaths);
10899
- const scaffold = await ensureArchitectureDocScaffold({
10900
- workspaceRoot,
10901
- snapshot,
10902
- specRoots,
10903
- overwrite,
10904
- dryRun,
10905
- });
10906
11005
  const coreSkills = [
10907
11006
  "architecture-doc",
10908
11007
  "system-design",
@@ -10912,11 +11011,13 @@ async function runBuildArchitecture(options) {
10912
11011
  const conditionalSkills = resolveArchitectureConditionalSkills(snapshot, specRoots, researchMode);
10913
11012
  const skillBundle = [...coreSkills, ...conditionalSkills];
10914
11013
  const skillPathHints = await resolveArchitectureSkillPathHints(platform, cwd, skillBundle);
11014
+ const inspectionAnchors = await resolveArchitectureInspectionAnchors(workspaceRoot, snapshot, specRoots);
10915
11015
  const prompt = buildArchitecturePrompt({
10916
11016
  platform,
10917
11017
  workspaceRoot,
10918
11018
  snapshot,
10919
11019
  specRoots,
11020
+ inspectionAnchors,
10920
11021
  researchMode,
10921
11022
  coreSkills,
10922
11023
  conditionalSkills,
@@ -10924,6 +11025,13 @@ async function runBuildArchitecture(options) {
10924
11025
  });
10925
11026
  const adapter = await probeArchitectureAdapter(platform, workspaceRoot);
10926
11027
  const args = adapter.buildInvocation(prompt);
11028
+ const managedTargets = [
11029
+ path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "PRODUCT.md"),
11030
+ path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "ARCHITECTURE.md"),
11031
+ path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "TECH.md"),
11032
+ path.join(workspaceRoot, FOUNDATION_ADR_DIR, "README.md"),
11033
+ path.join(workspaceRoot, FOUNDATION_ADR_DIR, "0000-template.md"),
11034
+ ].map((filePath) => toPosixPath(filePath));
10927
11035
  if (dryRun) {
10928
11036
  const summary = {
10929
11037
  platform,
@@ -10931,15 +11039,7 @@ async function runBuildArchitecture(options) {
10931
11039
  adapter: adapter.binary,
10932
11040
  invocation: [adapter.binary, ...args],
10933
11041
  researchMode,
10934
- managedTargets: [
10935
- toPosixPath(scaffold.productPath),
10936
- toPosixPath(scaffold.architectureDocPath),
10937
- toPosixPath(scaffold.engineeringRulesPath),
10938
- toPosixPath(scaffold.techMdPath),
10939
- toPosixPath(scaffold.roadmapPath),
10940
- toPosixPath(scaffold.adrReadmePath),
10941
- toPosixPath(scaffold.adrTemplatePath),
10942
- ],
11042
+ managedTargets,
10943
11043
  skillBundle,
10944
11044
  };
10945
11045
  if (emitJson) {
@@ -10950,12 +11050,17 @@ async function runBuildArchitecture(options) {
10950
11050
  console.log(`Workspace: ${toPosixPath(workspaceRoot)}`);
10951
11051
  console.log(`Adapter: ${adapter.binary}`);
10952
11052
  console.log(`Research mode: ${researchMode}`);
10953
- console.log(`Managed targets: ${toPosixPath(scaffold.engineeringRulesPath)}, ${toPosixPath(scaffold.techMdPath)}`);
11053
+ console.log(`Managed targets: ${summary.managedTargets.join(", ")}`);
10954
11054
  console.log(`Skill bundle: ${skillBundle.join(", ")}`);
10955
11055
  console.log(`Invocation: ${[adapter.binary, ...args].join(" ")}`);
10956
11056
  }
10957
11057
  return;
10958
11058
  }
11059
+ const filesBefore = await captureFileContents(managedFilePaths);
11060
+ const scaffold = await ensureArchitectureBuildScaffold({
11061
+ workspaceRoot,
11062
+ dryRun,
11063
+ });
10959
11064
  if (!emitJson) {
10960
11065
  console.log(`Streaming ${adapter.binary} output...`);
10961
11066
  }
@@ -10971,22 +11076,21 @@ async function runBuildArchitecture(options) {
10971
11076
  const changedFiles = managedFilePaths
10972
11077
  .filter((filePath) => filesBefore[filePath] !== filesAfter[filePath])
10973
11078
  .map((filePath) => toPosixPath(path.relative(workspaceRoot, filePath)));
10974
- const rulesContent = filesAfter[scaffold.engineeringRulesPath] ??
10975
- (await readFile(scaffold.engineeringRulesPath, "utf8"));
10976
11079
  const techContent = filesAfter[scaffold.techMdPath] ?? (await readFile(scaffold.techMdPath, "utf8"));
10977
11080
  const productContent = filesAfter[scaffold.productPath] ?? (await readFile(scaffold.productPath, "utf8"));
10978
11081
  const architectureContent = filesAfter[scaffold.architectureDocPath] ??
10979
11082
  (await readFile(scaffold.architectureDocPath, "utf8"));
10980
- const roadmapContent = filesAfter[scaffold.roadmapPath] ?? (await readFile(scaffold.roadmapPath, "utf8"));
10981
11083
  const metadataPath = path.join(workspaceRoot, ".cbx", ARCHITECTURE_BUILD_METADATA_FILENAME);
10982
11084
  const metadata = buildArchitectureBuildMetadata({
10983
11085
  platform,
10984
11086
  researchMode,
10985
- productProfileHash: extractTaggedMarkerAttribute(productContent, PRODUCT_FOUNDATION_BLOCK_START_RE, "profile") || "unknown",
10986
- architectureDocHash: extractTaggedMarkerAttribute(architectureContent, ARCHITECTURE_DOC_BLOCK_START_RE, "profile") || "unknown",
10987
- rulesProfileHash: extractTaggedMarkerAttribute(rulesContent, ENGINEERING_ARCHITECTURE_BLOCK_START_RE, "profile") || "unknown",
10988
- techSnapshotHash: extractTaggedMarkerAttribute(techContent, TECH_ARCHITECTURE_BLOCK_START_RE, "snapshot") || "unknown",
10989
- roadmapProfileHash: extractTaggedMarkerAttribute(roadmapContent, ROADMAP_FOUNDATION_BLOCK_START_RE, "profile") || "unknown",
11087
+ managedDocs: [
11088
+ `${FOUNDATION_DOCS_DIR}/PRODUCT.md`,
11089
+ `${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md`,
11090
+ `${FOUNDATION_DOCS_DIR}/TECH.md`,
11091
+ `${FOUNDATION_ADR_DIR}/README.md`,
11092
+ `${FOUNDATION_ADR_DIR}/0000-template.md`,
11093
+ ],
10990
11094
  });
10991
11095
  await mkdir(path.dirname(metadataPath), { recursive: true });
10992
11096
  await writeFile(metadataPath, `${JSON.stringify(metadata, null, 2)}\n`, "utf8");
@@ -11008,8 +11112,8 @@ async function runBuildArchitecture(options) {
11008
11112
  console.log(`Platform: ${platform}`);
11009
11113
  console.log(`Adapter: ${adapter.binary}`);
11010
11114
  console.log(`Workspace: ${toPosixPath(workspaceRoot)}`);
11011
- console.log("Managed docs: PRODUCT.md, ARCHITECTURE.md, ENGINEERING_RULES.md, TECH.md, ROADMAP.md");
11012
- console.log("ADR scaffold: docs/adr/README.md, docs/adr/0000-template.md");
11115
+ console.log(`Managed docs: ${FOUNDATION_DOCS_DIR}/PRODUCT.md, ${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md, ${FOUNDATION_DOCS_DIR}/TECH.md`);
11116
+ console.log(`ADR scaffold: ${FOUNDATION_ADR_DIR}/README.md, ${FOUNDATION_ADR_DIR}/0000-template.md`);
11013
11117
  console.log(`Skill bundle: ${skillBundle.join(", ")}`);
11014
11118
  console.log(`Files written: ${(result.filesWritten || []).join(", ") || "(none reported)"}`);
11015
11119
  console.log(`Research used: ${result.researchUsed ? "yes" : "no"}`);