fix: frontmatter gate crashed on a tracked symlink with an unreachable target - #3
Merged
Conversation
…e target Found by the gate's own first real CI run, against gtmify-config, where it died with a FileNotFoundError on skills/_gstack-command/SKILL.md. The cause is a genuine repo defect, not a CI quirk. That path is a committed symlink whose target is the ABSOLUTE /Users/scottwueschinski/claude/config/gtmify/skills/ gstack/SKILL.md, and it points into skills/gstack/, which that repo gitignores. So it resolves only on the machine that created it and is dangling everywhere else, including on the second machine and in CI. An audit of that repo found roughly 145 tracked symlinks, the large majority with absolute targets. Three behaviors were possible and only one is right. Crashing is obviously wrong. Failing would turn tier A permanently red over a pre-existing problem the gate was not built to solve, and a permanently red gate gets ignored within a week. So these are counted, named in the output with their unreachable target, and excluded from the verdict, and the summary states plainly how many were not assessed. A gate that quietly skips work reads as full coverage and is worse than one that admits a gap. A dangling symlink still cannot mask a real violation elsewhere in the same run; there is a test for exactly that. Adds tests/frontmatter_gate_test.sh, 8 cases, including the one that crashed. The self-test now iterates tests/*_test.sh rather than naming one file, so a new suite is picked up without editing the workflow. Co-Authored-By: Claude Opus 5 (1M context) <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.
Found by the gate's own first real CI run, against
gtmify-config, where it died with aFileNotFoundErroronskills/_gstack-command/SKILL.md.The cause is a real repo defect, not a CI quirk
That path is a committed symlink whose target is the absolute
/Users/scottwueschinski/claude/config/gtmify/skills/gstack/SKILL.md, and it points intoskills/gstack/, which that repo gitignores. It resolves only on the machine that created it, and is dangling on the second machine and in CI.An audit found roughly 145 tracked symlinks in
gtmify-config, the large majority with absolute/Users/...targets. That is its own piece of work and is not addressed here.Why skip rather than fail
Three behaviors were possible and only one is right:
The summary now states plainly how many files were not assessed and why. A gate that quietly skips work reads as full coverage, which is worse than one that admits a gap.
A dangling symlink still cannot mask a genuine violation elsewhere in the same run. There is a test for exactly that.
Tests
New
tests/frontmatter_gate_test.sh, 8 cases, all passing, including the one that crashed:The self-test now iterates
tests/*_test.shinstead of naming one file, so a new suite is picked up without editing the workflow.shellcheckclean, junk suite still 35/0.🤖 Generated with Claude Code