Commit 13e840d
Add pre-merge-commit hook to resolve file ordering race (#183)
* Install pre-merge-commit hook to regenerate sections post-merge
The merge driver's per-file `mdsmith fix` could read stale sibling
files because git merges paths one at a time: when the driver runs
on PLAN.md, plan/*.md may still hold "ours" content, so the
regenerated catalog reflects pre-merge sources. CI run 24971661273
hit this — PLAN.md row 94 stayed 🔲 while plan/94 status was ✅.
`mdsmith merge-driver install` now writes a pre-merge-commit hook
that re-runs `mdsmith fix` on the registered files once every
path has reached its final merged state. The merge-queue workflow
builds mdsmith from source so the install logic always matches
the directive schema of the branch being queued.
* Add e2e test reproducing the file-ordering race
Sets up two branches that each bump a different plan file's
status to ✅ and regenerate PLAN.md, then merges them after
running `mdsmith merge-driver install`. Asserts the merged
PLAN.md catalog matches the post-merge plan files and that
`mdsmith check .` reports no drift.
Verified by temporarily disabling the pre-merge-commit hook
install: the test then fails with the exact symptom from CI
run 24971661273 — a stale row in PLAN.md and MDS019
"generated section is out of date".
* Address review: revert workflow, fix hook robustness, add 100% coverage
- Revert merge-queue.yml to downloading the pinned v0.5.0 release binary
instead of building from source (per jeduden's review request; the
build-from-source approach will land in a follow-up PR alongside a new
release that includes this hook fix)
- Handle core.hooksPath: resolveHooksDir() uses git rev-parse --git-path
hooks so install respects repos that redirect hooks to a custom path
- Handle non-ENOENT read errors on the existing hook file: treat them as
a safety failure rather than silently overwriting an unreadable hook
- Split per-file fix commands into separate lines so set -e reliably
aborts the hook on a mdsmith fix or git add failure (the && form can
suppress errexit in some POSIX shells)
- Add tests covering all new code paths: resolveHooksDir (fallback, default
git repo, relative and absolute core.hooksPath), unreadable-hook error,
MkdirAll failure, WriteFile failure, and e2e install with unmanaged hook
https://claude.ai/code/session_012XG9t645SL8z2RW9ik79gw
* Fix test robustness per Copilot review
- Add runtime.GOOS=="windows" skip to the three POSIX permission tests
to match the pattern used elsewhere in the repo
- TestResolveHooksDir_DefaultGitRepo: derive expected path via
git rev-parse --git-path hooks instead of hard-coding .git/hooks,
so the test passes when a developer has core.hooksPath set globally
- TestE2E_MergeDriver_Install: use gitHooksDir() helper instead of
hard-coded .git/hooks path for the hook assertion
- TestE2E_MergeDriver_Install_UnmanagedHook: use gitHooksDir() for
hook setup so the pre-existing hook is placed where install looks
https://claude.ai/code/session_012XG9t645SL8z2RW9ik79gw
* Address Copilot review: fix --, Windows exec-bit guards, comment placement
- Add -- separator to mdsmith fix in generated hook so file paths
starting with - are not misinterpreted as flags
- Guard info.Mode()&0o111 exec-bit assertions with runtime.GOOS != "windows"
in both the unit test and e2e test (POSIX permission bits don't apply on
Windows)
- Move the writeFixture doc comment back to sit directly above writeFixture;
gitHooksDir now has only its own comment above it
https://claude.ai/code/session_012XG9t645SL8z2RW9ik79gw
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 6b2cf56 commit 13e840d
3 files changed
Lines changed: 494 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
| |||
192 | 193 | | |
193 | 194 | | |
194 | 195 | | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
195 | 209 | | |
196 | 210 | | |
197 | 211 | | |
| |||
1236 | 1250 | | |
1237 | 1251 | | |
1238 | 1252 | | |
| 1253 | + | |
| 1254 | + | |
| 1255 | + | |
| 1256 | + | |
| 1257 | + | |
| 1258 | + | |
| 1259 | + | |
| 1260 | + | |
| 1261 | + | |
| 1262 | + | |
| 1263 | + | |
| 1264 | + | |
| 1265 | + | |
| 1266 | + | |
| 1267 | + | |
1239 | 1268 | | |
1240 | 1269 | | |
1241 | 1270 | | |
| |||
1255 | 1284 | | |
1256 | 1285 | | |
1257 | 1286 | | |
| 1287 | + | |
| 1288 | + | |
| 1289 | + | |
| 1290 | + | |
| 1291 | + | |
| 1292 | + | |
| 1293 | + | |
| 1294 | + | |
| 1295 | + | |
| 1296 | + | |
| 1297 | + | |
| 1298 | + | |
| 1299 | + | |
| 1300 | + | |
| 1301 | + | |
| 1302 | + | |
| 1303 | + | |
| 1304 | + | |
| 1305 | + | |
| 1306 | + | |
| 1307 | + | |
| 1308 | + | |
| 1309 | + | |
| 1310 | + | |
1258 | 1311 | | |
1259 | 1312 | | |
1260 | 1313 | | |
| |||
1401 | 1454 | | |
1402 | 1455 | | |
1403 | 1456 | | |
| 1457 | + | |
| 1458 | + | |
| 1459 | + | |
| 1460 | + | |
| 1461 | + | |
| 1462 | + | |
| 1463 | + | |
| 1464 | + | |
| 1465 | + | |
| 1466 | + | |
| 1467 | + | |
| 1468 | + | |
| 1469 | + | |
| 1470 | + | |
| 1471 | + | |
| 1472 | + | |
| 1473 | + | |
| 1474 | + | |
| 1475 | + | |
| 1476 | + | |
| 1477 | + | |
| 1478 | + | |
| 1479 | + | |
| 1480 | + | |
| 1481 | + | |
| 1482 | + | |
| 1483 | + | |
| 1484 | + | |
| 1485 | + | |
| 1486 | + | |
| 1487 | + | |
| 1488 | + | |
| 1489 | + | |
| 1490 | + | |
| 1491 | + | |
| 1492 | + | |
| 1493 | + | |
| 1494 | + | |
| 1495 | + | |
| 1496 | + | |
| 1497 | + | |
| 1498 | + | |
| 1499 | + | |
| 1500 | + | |
| 1501 | + | |
| 1502 | + | |
| 1503 | + | |
| 1504 | + | |
| 1505 | + | |
| 1506 | + | |
| 1507 | + | |
| 1508 | + | |
| 1509 | + | |
| 1510 | + | |
| 1511 | + | |
| 1512 | + | |
| 1513 | + | |
| 1514 | + | |
| 1515 | + | |
| 1516 | + | |
| 1517 | + | |
| 1518 | + | |
| 1519 | + | |
| 1520 | + | |
| 1521 | + | |
| 1522 | + | |
| 1523 | + | |
| 1524 | + | |
| 1525 | + | |
| 1526 | + | |
| 1527 | + | |
| 1528 | + | |
| 1529 | + | |
| 1530 | + | |
| 1531 | + | |
| 1532 | + | |
| 1533 | + | |
| 1534 | + | |
| 1535 | + | |
| 1536 | + | |
| 1537 | + | |
| 1538 | + | |
| 1539 | + | |
| 1540 | + | |
| 1541 | + | |
| 1542 | + | |
| 1543 | + | |
| 1544 | + | |
| 1545 | + | |
| 1546 | + | |
| 1547 | + | |
| 1548 | + | |
| 1549 | + | |
| 1550 | + | |
| 1551 | + | |
| 1552 | + | |
| 1553 | + | |
| 1554 | + | |
| 1555 | + | |
| 1556 | + | |
| 1557 | + | |
| 1558 | + | |
| 1559 | + | |
| 1560 | + | |
| 1561 | + | |
| 1562 | + | |
| 1563 | + | |
| 1564 | + | |
| 1565 | + | |
| 1566 | + | |
| 1567 | + | |
| 1568 | + | |
| 1569 | + | |
| 1570 | + | |
| 1571 | + | |
| 1572 | + | |
| 1573 | + | |
| 1574 | + | |
| 1575 | + | |
| 1576 | + | |
| 1577 | + | |
| 1578 | + | |
| 1579 | + | |
| 1580 | + | |
| 1581 | + | |
| 1582 | + | |
| 1583 | + | |
| 1584 | + | |
| 1585 | + | |
| 1586 | + | |
| 1587 | + | |
| 1588 | + | |
| 1589 | + | |
| 1590 | + | |
| 1591 | + | |
| 1592 | + | |
| 1593 | + | |
| 1594 | + | |
| 1595 | + | |
| 1596 | + | |
1404 | 1597 | | |
1405 | 1598 | | |
1406 | 1599 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
391 | 391 | | |
392 | 392 | | |
393 | 393 | | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
394 | 401 | | |
395 | 402 | | |
396 | 403 | | |
| 404 | + | |
397 | 405 | | |
398 | 406 | | |
399 | 407 | | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
400 | 497 | | |
401 | 498 | | |
402 | 499 | | |
| |||
0 commit comments