feat: confluence benchmark, pattern extractor, agent KB, UX spec
- extract-patterns.js: mines layered arch, ArgoCD appsets, cloud regions,
CIDR allocations, naming conventions, sync waves, tech stack from code
- agent-kb.js: token-efficient JSON rendering of same doc tree
- eval-confluence-ref-questions.json: 32 reference-only benchmark questions
- wiggum-v2.sh: Ralph Wiggum loop targeting confluence baseline (77.8%)
- docs/human-ux-spec.md: BMad UX designer spec for human doc structure
- Eval results: V2 at 28.7% vs confluence 77.8% baseline
- Hub/spoke ownership now correctly extracted (95% on that question)
- Naming conventions, regions, CIDRs surfaced in system-architecture.md
2026-03-10 14:20:35 +00:00
|
|
|
const fs = require('fs');
|
|
|
|
|
|
feat: repo-agnostic refactor (BMad spec-test-build loop)
- NEW: repo-profiler.js — deterministic archetype detection (Infra, Frontend, Backend, etc.)
- NEW: extract-dynamic.js — generic extractor replacing hardcoded Foxtrot patterns
- NEW: eval-generator.js — dynamic ground-truth question generation from any repo graph
- NEW: specs/bmad-agnostic-refactor-spec.md — full BMad spec with acceptance criteria
- REFACTORED: prose.js — two-pass LLM synthesis with rich context (shared secrets, ports, service refs)
- REFACTORED: sysdoc.js — wired repo-profiler + extract-dynamic, --legacy escape hatch
- REFACTORED: wiggum-v2.sh — uses eval-generator before benchmarks
- FIXED: graph.js — _edgeSet rebuilt on loadSnapshot() (edge dedup was broken)
- FIXED: graph.js — recursive sortKeys() for deep equality in diffing
- FIXED: prose.js — robust JSON array extraction from LLM output
- FIXED: ratchet.js — syntax validation (node --check) before saving LLM mutations
- FIXED: extract-dynamic.js — centralized state services regex, added console.warn for silent failures
- TESTS: test-eval-generator, test-repo-profiler, test-synthesis-quality + mock fixtures
Eval: 81.5% on Foxtrot (fully repo-agnostic, no hardcoded reference pages)
BMad reviews: Architect B+, Dev Lead B-, TEA B-
2026-03-11 14:40:31 +00:00
|
|
|
let content = fs.readFileSync('sysdoc.js', 'utf8');
|
|
|
|
|
|
|
|
|
|
content = content.replace(
|
|
|
|
|
"const { extractDeep } = require('./extract-deep.js');",
|
|
|
|
|
"const { extractDeep } = require('./extract-deep.js');\nconst { profileRepo, ARCHETYPES } = require('./repo-profiler.js');\nconst { extractDynamic } = require('./extract-dynamic.js');"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
content = content.replace(
|
|
|
|
|
/const patterns = extractAllPatterns\(srcRoot\);\s*const deepData = extractDeep\(srcRoot\);/,
|
|
|
|
|
`let patterns = {
|
|
|
|
|
layers: [],
|
|
|
|
|
appsets: [],
|
|
|
|
|
regions: { aws: [], gcp: [], azure: [] },
|
|
|
|
|
cidrs: [],
|
|
|
|
|
naming: [],
|
|
|
|
|
techStack: { containerImages: [] },
|
|
|
|
|
syncWaves: []
|
|
|
|
|
};
|
|
|
|
|
let deepData = { addons: [], scriptParams: [], tfConfigs: [], helmValues: [], stateServices: [] };
|
|
|
|
|
let archetypeStr = ARCHETYPES ? ARCHETYPES.UNKNOWN : 'Unknown';
|
|
|
|
|
|
|
|
|
|
if (opts.legacyMode) {
|
|
|
|
|
patterns = extractAllPatterns(srcRoot);
|
|
|
|
|
deepData = extractDeep(srcRoot);
|
|
|
|
|
if (!archetypeStr || archetypeStr === 'Unknown') archetypeStr = 'Infrastructure';
|
|
|
|
|
} else {
|
|
|
|
|
const profile = profileRepo(srcRoot, graph);
|
|
|
|
|
archetypeStr = profile.archetype;
|
|
|
|
|
console.log(\`Detected Repo Archetype: \${archetypeStr} (confidence: \${profile.confidence})\`);
|
|
|
|
|
|
|
|
|
|
const dynamicData = extractDynamic(graph, archetypeStr, srcRoot);
|
|
|
|
|
deepData = {
|
|
|
|
|
addons: [],
|
|
|
|
|
scriptParams: [],
|
|
|
|
|
tfConfigs: [],
|
|
|
|
|
helmValues: [],
|
|
|
|
|
stateServices: dynamicData.stateServices || [],
|
|
|
|
|
configs: dynamicData.configs || [],
|
|
|
|
|
deploymentPatterns: dynamicData.deploymentPatterns || [],
|
|
|
|
|
networkTopology: dynamicData.networkTopology || []
|
|
|
|
|
};
|
|
|
|
|
}`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
content = content.replace(
|
|
|
|
|
/await proseMod\.synthesizeReferencePages\(agentKB, deepData, outDir, \{ confluenceCtx, model: process\.env\.LLM_MODEL \|\| 'claude-haiku-4\.5' \}\);/,
|
|
|
|
|
"await proseMod.synthesizeReferencePages(agentKB, deepData, outDir, archetypeStr, { confluenceCtx, model: process.env.LLM_MODEL || 'claude-haiku-4.5' });"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
fs.writeFileSync('sysdoc.js', content);
|