Hello, I always appreciate rulesync.
Problem
I found a data loss bug in CopilotRule.toRulesyncRule(). When converting a root rule with applyTo: "**", the value is normalized to "**/*" during conversion to a RulesyncRule, but this original value is never restored on the way back, causing the roundtrip to be non-idempotent.
Evidence
In src/features/rules/copilot-rule.ts around line 117–118:
if (this.isRoot()) {
globs = ["**/*"]; // Always hardcoded — original "**" is lost
}
And in fromRulesyncRule() around line 160:
applyTo: rulesyncFrontmatter.globs?.length
? rulesyncFrontmatter.globs.join(",")
: undefined,
The roundtrip results in:
| Step |
Value |
Input (applyTo) |
"**" |
After toRulesyncRule (globs) |
["**/*"] |
After fromRulesyncRule (applyTo) |
"**/*" |
The original "**" is permanently replaced with "**/*" after a single conversion cycle.
Reproduction Steps
- Create a
CopilotRule with applyTo: "**" in frontmatter
- Call
.toRulesyncRule() → observe globs: ["**/*"]
- Call
CopilotRule.fromRulesyncRule() on the result → observe applyTo: "**/*" (not "**")
Expected Behavior
A roundtrip conversion should preserve the original glob value, or at minimum, the two values ("**" and "**/*") should be treated as equivalent throughout the pipeline.
Actual Behavior
"**" is silently replaced with "**/*", causing inconsistency when re-importing or re-syncing rules.
Your consideration would be appreciated.
Hello, I always appreciate rulesync.
Problem
I found a data loss bug in
CopilotRule.toRulesyncRule(). When converting a root rule withapplyTo: "**", the value is normalized to"**/*"during conversion to aRulesyncRule, but this original value is never restored on the way back, causing the roundtrip to be non-idempotent.Evidence
In
src/features/rules/copilot-rule.tsaround line 117–118:And in
fromRulesyncRule()around line 160:The roundtrip results in:
applyTo)"**"toRulesyncRule(globs)["**/*"]fromRulesyncRule(applyTo)"**/*"The original
"**"is permanently replaced with"**/*"after a single conversion cycle.Reproduction Steps
CopilotRulewithapplyTo: "**"in frontmatter.toRulesyncRule()→ observeglobs: ["**/*"]CopilotRule.fromRulesyncRule()on the result → observeapplyTo: "**/*"(not"**")Expected Behavior
A roundtrip conversion should preserve the original glob value, or at minimum, the two values (
"**"and"**/*") should be treated as equivalent throughout the pipeline.Actual Behavior
"**"is silently replaced with"**/*", causing inconsistency when re-importing or re-syncing rules.Your consideration would be appreciated.