Kill the recurring docs/plans/index.html merge conflict for good: add a git merge driver that auto-resolves the generated gallery index by unioning the plan cards from both sides whenever two plan branches collide — so every merge keeps all plans and no contributor ever hand-resolves the index again. Mirror the proven marketplace.json driver wiring already in the repo.
Read and implement all steps in the plan at docs/plans/add-plans-index-merge-driver.md — Add merge driver for docs/plans/index.html. Verify against the plan's Tests, Verification, and Acceptance Criteria before reporting done. If everything passed, mark completion in docs/plans/add-plans-index-merge-driver.md — tick each step's [x] marker and each criterion's - [x], set status: completed — and re-render the HTML from the spec. If any check failed, leave status: in-progress and say which.
More ways to run this plan — goal & workflow prompts, file path
Achieve this goal: Add merge driver for docs/plans/index.html. The plan at docs/plans/add-plans-index-merge-driver.md describes one approach — use it as reference, but optimize for the outcome. Fan out across parallel subagents where that serves the outcome. Verify against the plan's Tests, Verification, and Acceptance Criteria before reporting done. If everything passed, mark completion in docs/plans/add-plans-index-merge-driver.md — tick each step's [x] marker and each criterion's - [x], set status: completed — and re-render the HTML from the spec. If any check failed, leave status: in-progress and say which.
Run a workflow to implement the plan at docs/plans/add-plans-index-merge-driver.md — Add merge driver for docs/plans/index.html. Brief subagents with the plan file at docs/plans/add-plans-index-merge-driver.md. Reserve a final verification phase for the lead agent, not a subagent. Verify against the plan's Tests, Verification, and Acceptance Criteria before reporting done. If everything passed, mark completion in docs/plans/add-plans-index-merge-driver.md — tick each step's [x] marker and each criterion's - [x], set status: completed — and re-render the HTML from the spec. If any check failed, leave status: in-progress and say which.
add-plans-index-merge-driver.html
docs/plans/add-plans-index-merge-driver.html
docs/plans/add-plans-index-merge-driver.md
Context
The story behind this plan — what prompted the work and why it matters now.
docs/plans/index.html is a fully generated file. docs/plans/build-index.sh rebuilds it from every non-index plan .html file, and the kit/plugins/plan-agent/hooks/rebuild-plans-index.py PostToolUse hook re-runs that script on every plan write. Because every plan-adding PR regenerates the index, any two concurrent plan PRs produce a textual merge conflict in this one file — PR #308 hit it twice in a single day.
The repo already solves the identical problem for .claude-plugin/marketplace.json with a custom git merge driver: scripts/merge-marketplace.mjs , mapped in .gitattributes via merge=mkt-version , with the per-clone git config merge.<name>.driver registered idempotently by scripts/setup-merge-driver.sh (auto-run from a SessionStart hook in .claude/settings.json ). This plan reuses that exact split: a committed .gitattributes mapping plus a per-clone driver registration.
Resolution strategy (per .claude/rules/plan-hygiene.md ): the driver unions the gallery cards from both sides rather than regenerating from disk. Sandbox-verified on git 2.50 (the default ort strategy): a merge driver runs during the in-memory merge, before the incoming branch's new plan files are checked out — so regenerating the index from disk inside the driver would silently drop every incoming plan. But both index versions already contain their side's cards as blobs ( %A ours, %B theirs, %O base), so unioning those cards yields a complete index with no disk access, and bakes the resolution straight into the merge commit — exactly how scripts/merge-marketplace.mjs unions plugins[] . Ours' cards keep their order, new cards from theirs are appended, and a card deleted on either side relative to the base stays deleted.
Why no post-merge regeneration: the union already produces a correct, complete index at merge time, so no git hook is needed. Any ordering or timestamp drift versus a clean rebuild is purely cosmetic and self-heals on the very next plan write (which re-runs build-index.sh over the full set on disk). Merge drivers live in local .git/config and never travel with the repo, so this pays off in the repo's standard local rebase-on-main-before-push workflow — the driver fires for git merge , each replayed git rebase commit, and git cherry-pick alike, leaving a branch conflict-free before it reaches GitHub.
Files that change
Every file this plan touches, and what happens to each one.
- scripts/
merge-plans-index.mjsnew driver: union gallery cards from both sidessetup-merge-driver.shmodified register the plans-index node driver
- .claude/rules/
marketplace.mdmodified cross-reference the plans-index driverplan-hygiene.mdmodified canonical union-strategy doc (added this session)
tests/merge-plans-index.test.shnew union + two-branch merge smoke test- fixtures/merge-plans-index/
base.htmlnew union test fixtures.gitattributesmodified map index.html to merge=plans-indexCONTRIBUTING.mdmodified first-time setup note
docs/GITHUB_SETUP.mdmodified add driver to file inventory
Steps
The step-by-step work, in order — each step says what to do, why it matters, and how to check it worked.
Tests
The tests that prove the change does what it promises.
Definition of done
The plan counts as done when every statement below is true — check each one off as you verify it.
Final check
One last pass to confirm the whole change works end to end.
Automated: run bash scripts/setup-merge-driver.sh then bash tests/merge-plans-index.test.sh — the smoke test must pass (exit 0).
Manual end-to-end: from a clean clone, create two branches off main that each add a distinct plan file under docs/plans/ and commit (each commit regenerates index.html via the existing PostToolUse hook). Then git checkout branch-a && git merge --no-edit branch-b : the merge must complete with no conflict prompt, and docs/plans/index.html must contain gallery cards for both new plans. Repeat with git rebase in place of merge to confirm the driver also resolves on the replay path.
Non-regression: confirm git config --get merge.mkt-version.driver is still set and git check-attr merge -- .claude-plugin/marketplace.json still reports mkt-version , proving the marketplace driver is untouched.
Wrapping up
Three gates that must all pass before this plan is marked completed.
Completion Report
No items to report — all requirements met.