| Path | Scenario | Prevention |
|---|---|---|
| 1 Lock Race | Simultaneous integration | Git push atomicity |
| 2 Zombie Lock | Crash mid-operation | No locks used |
| 3 Partial Integration | Half-updated state | Single atomic commit |
| 6 Concurrent Claim | Double assignment | First-wins semantics |
Verdict: ✅ All unreachable via FF-only design
Scenario: Worker commits "complete: BX1.1" but actually implemented BX1.2
Why reachable: Git only verifies commit message syntax, not semantic truth
Mitigation options:
- Content-addressed verification (hash of work vs expected)
- Human review gate
- Automated test verification (tests pass = claim valid)
Current verdict: ❌ Reachable
Scenario:
- Worker branches from main@T0
- Main advances significantly
- FF merge fails
- Rebase conflicts
- Worker resolves incorrectly
Why reachable: Rebase requires human judgment for conflicts
Mitigation options:
- Rebase prohibition (reject if not FF, force redo)
- Time-bounded integration window
- Automated conflict resolution (impossible in general)
Current verdict: ❌ Reachable
Scenario: Worker integrates commit without checkbox reference
Why reachable: No enforcement of commit message format during merge
Mitigation:
- Commit message linting in integrate.sh
- Reject commits not matching "complete: CHECKBOX"
Current verdict: ❌ Reachable
Scenario:
- Local FF merge succeeds
- Push fails (timeout)
- Retry: main moved
- Rebase required
Same as Path 7: Rebase corruption risk
Current verdict: ❌ Reachable
FF-Only Design Reality
───────────────── ─────────────────
No locks needed ←→ Conflicts happen
Atomic operations ←→ Network partitions
No rebase needed ←→ Concurrent work
Unreachable states ←→ Humans resolve conflicts
The choice:
- Accept rebase risk: Build strong verification (tests, review)
- Reject rebase: Throw away work to preserve invariants
To make remaining paths unreachable:
# integrate.sh hardened
# 1. Commit message enforcement (Path 8)
git log --format=%s HEAD^..HEAD | grep -E "^complete: [A-Z]+[0-9]+\.[0-9]+$" || exit 1
# 2. Recency check (Path 7, 9)
BRANCH_BASE=$(git merge-base HEAD origin/main)
MAIN_TIP=$(git rev-parse origin/main)
if [ "$BRANCH_BASE" != "$MAIN_TIP" ]; then
echo "ERROR: Branch too old. Abandon and redo work."
exit 1
fi
# 3. Pre-merge validation (Path 4)
./control-plane/check_gates.sh || exit 1
# 4. FF-only merge
git merge --ff-only "$WORKER_BRANCH" || exit 1
# 5. Push (atomic)
git push origin mainResult: If any check fails, integration aborts. No manual resolution allowed.
| Approach | Invalid States | Lost Work | Complexity |
|---|---|---|---|
| v1 (59 scripts) | Prevented (mostly) | Low | Very High |
| v2 simple (6 scripts) | Reachable | Medium | Low |
| FF-only + recency | Unreachable | High (rejected work) | Medium |
| FF-only + rebase | Reachable (conflict resolution) | Low | Medium |
Recommendation: FF-only + recency check for invariant-critical paths; accept rebase risk for velocity paths.