rulesync/log/25/10/07 Tue - DRYing out AI Coding Configs
2025-10-07 Tue
How to DRY out AI/Coding/Configs
Thinking About rulesync/GitHub/Issue/25/09/Brainstorm needed - how to share some rules across repos, but not all i329
- Rules, commands, subagents and other AI coding configurations need to be defined at different scopes. In general, there's a need for
public,teamandprivatescopes. In addition, within each of these, sub-scopes would be necessary for individual projects and specific technologies.- Here are some examples that illustrate why three high-level scopes—
public,team,private—and their sub-scopes (per-technology and per-project) are all useful. They are grouped by scope, then shown a few sub-scope situations for each. 1. PUBLIC SCOPE (usable by anyone, even outside the company)
2. TEAM SCOPE (shared only by the internal engineering org)
3. PRIVATE SCOPE (individual or very restricted use)
Why the distinctions matter
- Here are some examples that illustrate why three high-level scopes—
- Let's elaborate a bit on specific recommendations for how teams and developers could use
rulesyncin a way that better honors the Software/Engineering/Principle/DRY (Don't Repeat Yourself).Markdown/Frontmatter/Yaml
remoteConfig Key- In the
.rulesync/{commands,rules,subagents,...}/*.md's yaml frontmatter, you could support a yaml key likeremotewhich could have a pointer to where the command/rule/subagent definition was located: - Then upon
rulesync generate, it would pull in the rule file into thetargets. - As indicated above, there are issues. Introducing a
remotekey may encourage less experienced engineers to open up their system to prompt injection.
- In the
Rulesync
includeConfig Keysrulesync.jsonccould support a config like the followingProposed extension: rulesync.jsonc → "include" array
IncludeObject specification
Required
Optional
ref(string): Git reference (commit SHA, tag, or branch). Default = repository default branch.subDir(string): Path inside the repo where the root.rulesyncdirectory lives if it is not at repo root.features(array<string>|"*"): Subset of tool-agnostic "features" to import:"rules","commands","ignore","mcp","subagents". Default ="*"(all recognised features).patterns(array<string>|Record<Feature,array<string>>): Glob patterns (minimatch style) applied afterfeaturesfiltering. Shorthand array applies to every selected feature; map form lets you specify per-feature patterns.select(Record<Feature,array<string>>): Explicit file list (relative to the feature directory) that must be present. Ifselectis provided for a feature, it overridespatternsfor that feature.exclude(array<string>): Additional glob exclusions applied last, across all chosen features.mode("merge"|"override"): merge – included files are added only when no equally-named file exists locally. override – included files replace conflicting local files. Default = "merge".rename(Record<string,string>): MappingsourcePath → targetPath(paths relative to their feature roots) for files that need to land under a different name locally.transform(string): Command (executed with the file streamed to STDIN, transformed content from STDOUT) that post-processes each included file. Optional ‑ for advanced use only.
Resolution rules & precedence
- 1. Iterate through
includearray in order. - 2. For each IncludeObject:
- a. Clone or fetch
repoatref. - b. Identify the
.rulesyncdirectory (/by default orsubDir). - c. Filter by
features, thenpatterns, thenselect, thenexclude. - d. For each remaining file, determine destination path (after optional
rename). - e. Apply
transformif present. - f. Place file into the local staging area, respecting
mode.
- a. Clone or fetch
- 3. After all includes are processed, run the normal local generation / export logic.
- 1. Iterate through
Illustrative examples
Error handling
Compatibility note
- Rules, commands, subagents and other AI coding configurations need to be defined at different scopes. In general, there's a need for