Closes Plan 1.5.1 §3 item #4 (the explicitly-deferred AST adapter output piping). Pre-1.5.4 introspectAsync() handed AST adapters SourceFile[] = [] because of a placeholder at codebase-introspector.ts:160-170. Adapters always worked (verified by adapter-grammar-strict.test.ts 10/10 fixtures with 'high' confidence) but their extracted conventions never reached the user-facing emitted config. 1.5.4 ships the real per-adapter file sampler and pipes AST output into detected.<adapter-id>: blocks.
Daemon code unchanged — 1.5.0 48 h soak verdict applies to 1.5.4.
Added
detect/adapters/file-sampler.ts— per-adapter file sampler. ReusesEXTENSIONSandTEST_FILE_PATTERNSfromsource-dir-detector.ts:84-104(no parallel maps; CR-46 self-attest #3). Algorithm: per language inadapter.languages, walk source dirs fromdetection.sourceDirs[<lang>].source_dirsup to depth 3, filter by extension, exclude test files, cap per-adapter at 50 files, drop files >MAX_AST_FILE_BYTES(256 KB). Refuses symlinks and ignored dirs (node_modules, .git, dist, target, etc.).- AST output piping in
runInit— after variant template merge, runsintrospectAsync(detection, projectRoot)and merges every adapter's output (where_confidence !== 'none') intoconfig.detected[<adapter-id>]. Each block carries the adapter's extracted conventions (route_method,scope_prefix_base,controller_class, etc.) plus_provenanceand_confidencepertypes.ts:114-130. --no-introspectCLI flag — bypasses the AST introspect step. Useful for fast sync init or when grammar download is undesirable. Default-on (introspect runs).sample-files-coverage.test.ts— 3 strict gates: every language declared by ANY of the 10 first-party adapters has bothSAMPLE_EXTENSIONSandSAMPLE_TEST_FILE_PATTERNSentries; extension strings are well-formed (no leading dot). Future adapters targeting an uncovered language fail the build.init-end-to-end.test.tsextension — addeddetected.<adapter-id>:block assertion: when the AST adapter for a fixture's framework returns non-'none'confidence, the block must carry_confidenceand at least one non-meta convention key. Lenient on grammar-load failure (CI offline) but strict on shape when present.
Verification
npx tsc --noEmit: 0 errorsnpm test: 2086 source-level tests pass (+8 tarball-level skipped perMASSU_TARBALL_E2Egate)MASSU_TARBALL_E2E=1 npm test: tarball gate runs against the 1.5.4 build with the new sampler + introspect pipingbash scripts/massu-pattern-scanner.sh: PASSbash scripts/massu-generalization-scanner.sh: PASS- 1.5.1's
init-end-to-end.test.tsstill green (5/5) — variant template merge stays correct core-bundled-ids-drift.test.ts: green (addedfile-sampler.tstoADAPTER_SUPPORT_FILES)
Closes
- Plan 1.5.1 §3 item #4 ("Pipe
introspectAsync()output todetected.<adapter-id>:block in the emitted config") — explicitly deferred at 1.5.1 ship; closed here.