diff options
| author | Craig Jennings <c@cjennings.net> | 2026-07-16 13:42:53 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-07-16 13:42:53 -0500 |
| commit | c98fda556e9211573dab3e32eaa5c42c2dedbfcb (patch) | |
| tree | 3e9e9cb7c6060d2edaa813ebaf852637a2244c7a /todo.org | |
| parent | 125c1e9777d66645cf23b30b3d2de1c91fb492aa (diff) | |
| download | rulesets-c98fda556e9211573dab3e32eaa5c42c2dedbfcb.tar.gz rulesets-c98fda556e9211573dab3e32eaa5c42c2dedbfcb.zip | |
fix(install-lang): refuse a colliding second bundle instead of clobbering
Installing a second language bundle into a project silently replaced the first one's config. settings.json and githooks are copied with cp -rT (always overwrite), so installing bash over elisp rewired the validate hook to validate-bash.sh and dropped check-parens from pre-commit, leaving validate-el.sh orphaned on disk. The output said [ok] for both. A project could lose its paren check or secret scan and read the install as success.
The guard detects which bundles a project already has, by the same rule fingerprint sync-language-bundle uses, and refuses when the incoming bundle would overwrite a file another one ships. It names each file at risk. FORCE=1 still overrides, and the message says that also re-seeds CLAUDE.md, which is destructive on a customized project.
Only three of the five shared filenames actually collide. gitignore-add.txt is appended and deduped, and CLAUDE.md is seed-only, so both compose across bundles already.
This doesn't decide whether polyglot projects are supported, and the guard shouldn't be read as "no". A non-overlapping pair still installs: bash ships settings.json and githooks with no coverage fragment, python ships only a coverage fragment, so the two compose today. The real line is overlap, not polyglot, and nothing chose it. The open question, along with the identical coverage target names both fragments define, is filed.
home reported this after scaffolding clock-panel with python and typescript, which hit the coverage fragment. The settings.json and githooks cases are worse and hadn't been noticed. No project was damaged: the three bundles that collide aren't doubled up anywhere.
Diffstat (limited to 'todo.org')
| -rw-r--r-- | todo.org | 41 |
1 files changed, 41 insertions, 0 deletions
@@ -48,6 +48,47 @@ triage-intake.org), live trial night on rulesets. Origin: work project's proposal, [[file:docs/design/2026-07-14-sentry-workflow-proposal.org][docs/design/2026-07-14-sentry-workflow-proposal.org]]. All nine design decisions resolved with Craig 2026-07-14 (recorded in the spec). +** TODO [#C] Polyglot projects — supported, or refused? :spec: +SCHEDULED: <2026-07-20 Mon> +Do we support more than one language bundle per project? The honest answer today +is "partly, by accident." The collision guard added 2026-07-16 refuses a +*colliding* second bundle rather than silently replacing the first's config, but +a non-overlapping pair still installs fine: bash ships =settings.json= + +githooks and no coverage fragment, python ships only a coverage fragment, so +=bash= + =python= composes cleanly today and yields a real polyglot project with +both rule sets. So the line isn't polyglot-vs-not, it's overlap-vs-not — and +nobody chose that line, it fell out of which bundle happens to ship what. Origin: +home's report after scaffolding clock-panel with python + typescript, +[[file:docs/design/2026-07-16-polyglot-bundle-collision.txt][docs/design/2026-07-16-polyglot-bundle-collision.txt]]. + +Pair this with the subproject scouting below — it's the same question in a +different costume ("which projects would actually be polyglot, and why"), so +they should be one conversation. + +The three options, in the order they'd be weighed: + +1. *Unsupported, explicitly.* Keep the guard as the answer. Cheapest, and + matches how little polyglot exists (one project, clock-panel). +2. *Supported.* Needs per-bundle filenames, a merged =settings.json= (the hooks + arrays compose rather than clobber), composed githooks, and namespaced + Makefile targets with a =coverage= aggregate. This is the real work. +3. *Case-by-case.* Support the pairs that come up, refuse the rest. + +What the decision needs to know: + +- *The target-name collision is the deeper half* (home's point, and it's right). + Every bundle's fragment defines =coverage:= and =coverage-summary:=, so even + with both files present a polyglot project can't paste both into one Makefile. + Renaming files doesn't fix it. +- *Only three of five shared filenames actually collide.* =gitignore-add.txt= + (5 bundles) appends deduped and composes. =CLAUDE.md= (3) is seed-only, and + its fallback comment shows multi-bundle was already considered there. + =claude/settings.json= (3), =githooks/*= (3), and =coverage-makefile.txt= (4) + are the real ones. +- *=FORCE=1= is a poor escape hatch* (home's catch): it also re-seeds + =CLAUDE.md=, which is destructive on a customized project. If polyglot + becomes supported, the override wants to be its own flag. + ** TODO [#C] Subproject pattern — promote to claude-rules? :spec: SCHEDULED: <2026-07-20 Mon> home proposes promoting its subproject pattern (a former standalone project |
