Skip to content

fix: address hands-on testing findings round 2 (new auto-detect, check --fix cache bypass, duplicate tables)#286

Merged
0xLeif merged 1 commit into
mainfrom
fix/hands-on-findings-2
Jun 11, 2026
Merged

fix: address hands-on testing findings round 2 (new auto-detect, check --fix cache bypass, duplicate tables)#286
0xLeif merged 1 commit into
mainfrom
fix/hands-on-findings-2

Conversation

@0xLeif

@0xLeif 0xLeif commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #285 — these bugs were found while integration-testing the fix/hands-on-findings build. This branch was stacked on fix/hands-on-findings, but GitHub rejected that base (the branch was deleted when #285 squash-merged), so it has been rebased onto main (which already contains #285).

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 only src/lib.rs), the new generator::find_single_source_fallback uses it — so specsync new greeter writes real files: frontmatter and pre-populates the greet export instead of files: [] that immediately fails validation ("Frontmatter invalid"). scaffold gets the same fallback. When nothing can be detected, new prints a ⚠ with guidance instead of silently writing a spec that fails check.
  • check --fix is never a silent no-op (most dangerous). A spec that failed check --strict was still recorded in the hash cache (warnings are cached by design), so a follow-up check --fix printed "⊘ Skipped 1 unchanged spec(s)… All specs unchanged", fixed nothing, and exited 0. --fix now bypasses the unchanged-skip the same way --strict and --force do, while still computing change classifications so requirements-drift regeneration keeps working.
  • check --fix no longer creates a duplicate table. A hand-written ### Functions table isn't on the export-header allowlist (parser::is_export_header), so --fix appended 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 new parser::get_all_api_table_symbols makes --fix skip any symbol already documented in any table within the Public API section.
  • Warning counter mismatch (investigated — real, fixed). The partial "N/M exports documented" summary is inserted into the warnings list and counted, but printed with a green ✓ — so the summary said "2 warning(s)" while only one ⚠ line was visible. It now prints as ⚠.

Updated the 6 affected specs (version bumps + change-log entries) and the CHANGELOG.

Test Plan

  • 6 new integration tests: 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 → --fix must fix), fix_does_not_duplicate_symbols_documented_under_bare_headings, warning_count_matches_printed_warning_lines
  • 6 new unit tests (find_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 — clean
  • Self-check: cargo run --release -- check --strict --require-coverage 100 --force — 58 specs, 0 warnings, 0 failed, 100% file/LOC coverage
  • Manual repro of the README quickstart flow and the cache/--fix repro against the release binary

🤖 Generated with Claude Code

- 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>
@0xLeif 0xLeif requested a review from a team as a code owner June 11, 2026 15:16
@0xLeif 0xLeif requested review from 0xGaspar, Kyntrin and tofu-ux June 11, 2026 15:16

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread src/generator.rs

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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

@0xLeif 0xLeif merged commit 25e5978 into main Jun 11, 2026
16 checks passed
@0xLeif 0xLeif deleted the fix/hands-on-findings-2 branch June 11, 2026 15:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant