fix: address hands-on testing findings round 2 (new auto-detect, check --fix cache bypass, duplicate tables)#286
Conversation
- new/scaffold: fall back to the project's single non-test source file (e.g. a fresh cargo crate with only src/lib.rs) when no directory or file matches the module name, so the README quickstart flow produces a spec with real files: and pre-populated exports instead of an empty files: [] that immediately fails validation; new prints a warning with guidance when nothing can be detected - check --fix: bypass the hash cache's unchanged-skip (like --strict and --force already did) — a spec that failed check --strict was still recorded in the cache, so a follow-up check --fix printed "All specs unchanged", fixed nothing, and exited 0 - check --fix: promote bare API-kind headings under ## Public API (### Functions, ### Methods, ### Types, …) to ### Exported <Kind> and skip symbols already documented in any Public API table, instead of appending a duplicate export table for the same symbols - check: print the partial "N/M exports documented" summary as ⚠ — it is counted as a warning, so the summary's warning count now matches the printed ⚠ lines Updated the affected specs (6) and added 6 integration tests plus unit tests for find_single_source_fallback and get_all_api_table_symbols. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces several enhancements and bug fixes to specsync, including auto-detecting source files in single-source-file projects for the new and scaffold commands, ensuring check --fix bypasses the hash cache to prevent silent no-ops, promoting bare API-kind headings to canonical export headers, and aligning the warning count with displayed warnings. Feedback on the changes identifies a potential issue in find_single_source_fallback where nested or duplicate source directories could cause WalkDir to traverse the same file multiple times, leading to false duplicate detections. Using a HashSet to track unique relative paths is recommended to resolve this.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
✅ Corvin says...
_
<(^\ .oO(Caw! ^v^)
|/(\
\(\\
" "\\
"Caw! Your code sparkles like a dropped french fry."
CI Summary
| Check | Status |
|---|---|
| Validate action.yml | ✅ Passed |
| Dependency Audit | ✅ Passed |
| Code Coverage | ✅ Passed |
| Format Check | ✅ Passed |
| Docs Site | ✅ Passed |
| Spec Validation | ✅ Passed |
| Tests (build, test, clippy) | ✅ Passed |
| VS Code Extension | ✅ Passed |
📋 Spec Validation Details
✅ SpecSync: Passed
| Metric | Value |
|---|---|
| Specs checked | 58 |
| Passed | 58 |
| Errors | 0 |
| Warnings | 0 |
| File coverage | 100% (74/74) |
| LOC coverage | 100% (33727/33727) |
Generated by specsync · Run specsync check --format github to reproduce
Powered by corvid-pet
Summary
Three bugs found while integration-testing the #285 build in a scaffolded cargo project (
src/lib.rs, v4.specsync/layout), plus one cosmetic counter mismatch:specsync new <module>now auto-detects the source in single-source-file projects. When no directory or file matches the module name but the project has exactly one non-test source file (the README quickstart's fresh crate with onlysrc/lib.rs), the newgenerator::find_single_source_fallbackuses it — sospecsync new greeterwrites realfiles:frontmatter and pre-populates thegreetexport instead offiles: []that immediately fails validation ("Frontmatter invalid").scaffoldgets the same fallback. When nothing can be detected,newprints a ⚠ with guidance instead of silently writing a spec that failscheck.check --fixis never a silent no-op (most dangerous). A spec that failedcheck --strictwas still recorded in the hash cache (warnings are cached by design), so a follow-upcheck --fixprinted "⊘ Skipped 1 unchanged spec(s)… All specs unchanged", fixed nothing, and exited 0.--fixnow bypasses the unchanged-skip the same way--strictand--forcedo, while still computing change classifications so requirements-drift regeneration keeps working.check --fixno longer creates a duplicate table. A hand-written### Functionstable isn't on the export-header allowlist (parser::is_export_header), so--fixappended a second "### Exported Functions" table containing the same symbol. Now (a) bare API-kind headings under## Public API(Functions,Methods,Types,Classes,Constants,Components,Hooks,Interfaces,Enums,Structs,Traits,Protocols) are promoted to### Exported <Kind>during--fix, making the existing rows the recognized export table, and (b) the newparser::get_all_api_table_symbolsmakes--fixskip any symbol already documented in any table within the Public API section.Updated the 6 affected specs (version bumps + change-log entries) and the CHANGELOG.
Test Plan
new_auto_detects_single_source_file,new_warns_when_no_source_files_match,scaffold_auto_detects_single_source_file,fix_runs_even_when_cache_marks_specs_unchanged(exact repro: strict fail → cached →--fixmust fix),fix_does_not_duplicate_symbols_documented_under_bare_headings,warning_count_matches_printed_warning_linesfind_single_source_fallback× 4,get_all_api_table_symbols× 2)cargo test— 627 unit + 148 integration, all green (re-run after rebase onto main)cargo fmt --check,cargo clippy -- -D warnings— cleancargo run --release -- check --strict --require-coverage 100 --force— 58 specs, 0 warnings, 0 failed, 100% file/LOC coverage--fixrepro against the release binary🤖 Generated with Claude Code