fix: update marketplace URLs after action rename - #10
Merged
Conversation
The action was renamed from "SpecSync Check" to "SpecSync", so the marketplace URL changed from specsync-check to specsync. Update all badge text and URLs in README.md to match. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0xLeif
added a commit
that referenced
this pull request
Jul 3, 2026
BLOCKING (re-review): config_to_toml omitted an empty required_sections / exclude_dirs / exclude_patterns, but the reader starts from SpecSyncConfig::default() whose defaults for these are NON-empty (7 sections, ["__tests__"], 3 test globs). So a user who explicitly set requiredSections/excludeDirs/excludePatterns = [] (opting out) had the defaults silently restored on migrate — flipping check/coverage/score pass-fail (e.g. every spec suddenly failing 6 missing-section errors), and config_to_toml_lossy_fields did not flag it. Same class as the #10 track_history default mismatch, but for arrays. Fix: always emit these three fields (empty → `= []`) via a new toml_array_line helper, so an intentional opt-out round-trips. source_extensions keeps its guard (its default is empty, so omission round-trips). source_dirs is unchanged (empty → auto-detect is documented behavior). Also (non-blocking, same array surface): strip_inline_comment was not escape-aware — an array item with an escaped quote followed by `#` was truncated mid-item. Made it track prev_backslash like find_toml_array_close. The remaining re-review non-blocking item (a hand-written config.toml value with a single backslash before t/n/r now decodes per TOML escape rules) is accepted as correct TOML semantics: tool-produced configs always escape `\`→`\\` and round-trip byte-for-byte (verified), so only hand-edited raw-backslash values change, toward spec compliance. Tests: explicitly-empty arrays round-trip; strip_inline_comment escape-aware; migrate_preserves_explicitly_empty_arrays. 704 unit + 167 integration, self-check 100%. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KDJxU4R8hUEuq1Y5jzft5m
0xLeif
added a commit
that referenced
this pull request
Jul 3, 2026
…s/parseMode, track_history) (#309) * Fix: migrate no longer silently drops config data (customRules/modules/parseMode, track_history) Two data-loss findings in the JSON→TOML config conversion migrate performs. #2 (High): config_to_toml never serialized `parse_mode`, `modules`, or `custom_rules`, and migrate deletes the source specsync.json — so upgrading a 3.x project silently lost AST parse mode, module groupings, and (security-relevant) custom validation rules, unrecoverably under --no-backup. - parse_mode and modules now round-trip losslessly: config_to_toml emits `parse_mode` and sorted `[modules."name"]` tables; load_toml_config parses a `parse_mode`/`parseMode` scalar and `[modules."name"]` sections (files, depends_on). A fully-empty module is skipped to keep writer/reader symmetric. - custom_rules has no faithful TOML representation ([[array-of-tables]] with a nested filter, unsupported by the hand-rolled reader). Rather than drop it, migrate now REFUSES via a new preflight (config_to_toml_lossy_fields + preflight_config_lossless): it exits 1 before any mutation, leaving specsync.json byte-for-byte intact, and tells the user which field blocked conversion. Mirrors the existing unparseable-config refusal. ai_api_key stays intentionally unwritten (it warns; secrets belong in an env var), so it is not flagged. #10 (Medium): LifecycleConfig derived Default gave track_history=false, but serde (and the docs) default it to true. Since load_toml_config starts from SpecSyncConfig::default(), an omitted track_history in config.toml loaded as false — so migrating a project with history tracking on silently turned it off. Added a manual Default with track_history=true so every default path agrees with serde. Tests: config round-trip for parse_mode / modules (sorted, deterministic) / track_history (true omitted-but-preserved, false written); lossy-fields flags customRules; LifecycleConfig default is true; migrate_preserves_parse_mode_and_modules and migrate_refuses_config_with_custom_rules (exit 1, JSON preserved, no config.toml). Self-check 100% (36505 LOC); 698 unit + 165 integration. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KDJxU4R8hUEuq1Y5jzft5m * Fix review findings: multi-source refusal + string escape round-trip Addresses the 5-lens adversarial review of the migrate config round-trip fix. BLOCKING — customRules refusal blind spot: apply_relocate_config converts one source but also DELETES the other legacy configs unconverted, so a higher-precedence .specsync/config.json carrying customRules (with a plain root specsync.json also present) slipped past the single-source preflight and was silently destroyed (enforcement also reverted strict→warn). preflight_config_lossless now checks EVERY JSON config migrate would convert-or-delete (specsync.json + .specsync/config.json), refusing if any is lossy; the message lists each offending file + field. String escape round-trip asymmetry: toml_escape wrote `\\ \" \n \r \t` but the reader never decoded them, so any value with a backslash/quote reloaded changed — silently corrupting a schema_pattern regex (\s \w), a Windows module path, or a module name on migrate (this also falsified the "modules round-trip losslessly" claim). Added toml_unescape (inverse of toml_escape; unknown `\x` preserved so a hand-written stray backslash is untouched) and applied it in parse_toml_string and the module-name parse. Array comma-split: parse_toml_string_array split on ',' without quote awareness, so a quoted item containing a comma was torn into bogus entries. Added the quote/escape- aware split_toml_array_items. Also: added parseMode to KNOWN_JSON_KEYS (it was honored by serde + written by config_to_toml, but printed a false "unknown key (ignored)" warning on load). Updated test_parse_toml_string_array_escaped_quote (it asserted the old un-decoded value). New tests: toml_unescape inverts toml_escape; schema_pattern regex, module special chars (backslash/comma path, quoted name) round-trip; split is quote-aware; migrate_refuses_custom_rules_in_coexisting_v4_json. 702 unit + 166 integration, self-check 100% (36679 LOC). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KDJxU4R8hUEuq1Y5jzft5m * Fix re-review finding: explicitly-empty arrays must survive migrate BLOCKING (re-review): config_to_toml omitted an empty required_sections / exclude_dirs / exclude_patterns, but the reader starts from SpecSyncConfig::default() whose defaults for these are NON-empty (7 sections, ["__tests__"], 3 test globs). So a user who explicitly set requiredSections/excludeDirs/excludePatterns = [] (opting out) had the defaults silently restored on migrate — flipping check/coverage/score pass-fail (e.g. every spec suddenly failing 6 missing-section errors), and config_to_toml_lossy_fields did not flag it. Same class as the #10 track_history default mismatch, but for arrays. Fix: always emit these three fields (empty → `= []`) via a new toml_array_line helper, so an intentional opt-out round-trips. source_extensions keeps its guard (its default is empty, so omission round-trips). source_dirs is unchanged (empty → auto-detect is documented behavior). Also (non-blocking, same array surface): strip_inline_comment was not escape-aware — an array item with an escaped quote followed by `#` was truncated mid-item. Made it track prev_backslash like find_toml_array_close. The remaining re-review non-blocking item (a hand-written config.toml value with a single backslash before t/n/r now decodes per TOML escape rules) is accepted as correct TOML semantics: tool-produced configs always escape `\`→`\\` and round-trip byte-for-byte (verified), so only hand-edited raw-backslash values change, toward spec compliance. Tests: explicitly-empty arrays round-trip; strip_inline_comment escape-aware; migrate_preserves_explicitly_empty_arrays. 704 unit + 167 integration, self-check 100%. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KDJxU4R8hUEuq1Y5jzft5m * Fix final review nit: aiProvider "custom" round-trips (was dropped to None) config_to_toml writes `ai_provider = "custom"` (via Display) but from_str_loose had no "custom" arm, so the reader parsed it back as None — a silent drop on migrate, the same writer/reader-asymmetry class. Added the symmetric arm. (Custom still needs SPECSYNC_AI_COMMAND to function; this just preserves the setting rather than silently losing it.) Also enables `--provider custom` on the CLI, consistent with the others. Test: ai_provider Custom round-trips. 705 unit + 167 integration, self-check 100%. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KDJxU4R8hUEuq1Y5jzft5m * Fix self-check: reword toml_unescape doc to not trip the Rust export parser The Rust export scanner strips string literals before comments with a DOTALL regex, so a lone `"` inside a doc comment is read as a string opener and the match runs to the next real `"` — here across the `pub fn config_to_toml` declaration, deleting it from the extracted export set and failing the dogfood spec-check ("Spec documents 'config_to_toml' but no matching export found"). The toml_unescape doc contained a bare `\"` in its escape list. Reworded to describe the escapes in prose (no literal quote), restoring 60/60 specs. (The underlying parser bug — comments tokenized after strings — is a separate export-parser item.) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KDJxU4R8hUEuq1Y5jzft5m --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SpecSync%20ChecktoSpecSyncspecsync-checktospecsyncTest plan
🤖 Generated with Claude Code