Twinned from https://github.com/cfsh/ninefold/issues/666 by tools/beads/import_github.py's reconcile pass.
Implementation issue for [design 004](https://github.com/cfsh/ninefold/blob/main/design_docs/004-one-owner-for-the-integration-build.md) (status proposed, written under #543). Unclaimed and unlabelled — for the next /triage round.
Take S1 — serialize the rebuild's *publish* with a lock in the shared .git, make a losing run an announced no-op, and refuse a push whose inputs moved since the merge began. Sequence S2 (the full scheduled rebuilder service Aedan proposed) after the WSL move, and do not build S7 (the rr-cache sync #535 proposes — already true on this box).
⚠️ Why S1 and not straight to S2: two of the three costs #543 argues from have already been paid down. The rr-cache half was never true on this box (every session is a worktree of one clone), and the unconvergeable-conflict half is fixed by #465 in #654. What is left is the force-push race, which S1 closes for a fraction of S2's cost. §5 of the doc lists what would change that call.
Roughly two to three PRs, in this order:
tools/pr/rebuild_f5.py and tools/tests/test_rebuild_f5.py. The cases that matter are the ones a happy-path test misses: a stale lock must not freeze f5 (fail-open — #467 is the precedent, a 45-minute lock that silently suppressed work), a losing run must exit 0 not 1, and the pre-push re-read must refuse when main moved./playtest reads. This is also where §2.4's gap gets closed: a branch dropped by the #465 skip is currently *absent* from the manifest rather than marked excluded, so the exclusion is loud in the session's terminal and invisible to the person actually test-driving.poll.py --check's STALE-DISPATCH to cover the rebuilder. Depends on whether S2 is coming; a stale lock is the same failure wearing different clothes, so this has value under S1 alone.Tier 2, and a hardening — rebuild_f5.py is on the merge path with over 140 unit tests and silent-and-expensive failure modes. ⚠️ S2 is new capability, not a hardening of this subsystem, and should not inherit S1's justification.
§7 has four, each with a recommended default and what ships if it is never answered. The one worth answering even if S1/S2 stalls is #3 — should the manifest carry dropped branches? It is cheap and it is the half of #465 that is still open.
⚠️ Per /design Step 6, the work breakdown is in the doc, not filed as separate issues. Whoever takes this holds the whole thing and may split it then.
None.
No comments.