| 1 | # Astra: hostfiles path cap, round 3 |
| 2 | |
| 3 | Round 2 (`CODEX-REVIEW-HOSTFILES-CAP-2.md`) raised one P2. When Restore skipped an over-cap tombstone, it left the deep file on disk, so the next scan refused the tree and relocation's flush stuck. |
| 4 | |
| 5 | Fixed in 3ab48ff7 and cc1c3d24, then merged with main in b3fa7427: |
| 6 | - `removePastCap` (`internal/hostfiles/restore_unix.go`) removes an over-cap tombstone's file in one linear walk: |
| 7 | - `root.Open(".")` to get a descriptor; |
| 8 | - `descendCtx`, which is `dir_unix.go`'s `descend` with a ctx check per component, using openat O_NOFOLLOW|O_DIRECTORY per component; |
| 9 | - a plain-final-name check, then unlinkat; |
| 10 | - an fsync of the parent through the held fd. |
| 11 | - Deep tombstones are never `mark()`ed. Under-cap tombstones still use `removeInside`. |
| 12 | - `restore_other.go` is the `!unix` stub, and it errors. |
| 13 | - platform-1e's census ruling hostfiles-cap-236 is folded in. Its conditions are in the overlay `internal/provision/testdata/plan14-root-reads-hostfiles-cap-236.tsv`. |
| 14 | |
| 15 | Tests (`fix5_linux_test.go`, `internal/host/relocationflush_deeptombstone_linux_test.go`): |
| 16 | - A 2048-level removal takes about 25ms. |
| 17 | - Cancellation stops mid-walk. |
| 18 | - A symlink is never followed, at depths 0, 1024 and 2047. |
| 19 | - A non-plain final name refuses. |
| 20 | - Restore, then `ReleaseFlushFiles.Flush`, commits. |
| 21 | |
| 22 | **Judge:** |
| 23 | 1. Is round 2's P2 closed? |
| 24 | 2. Durability: is an fsync of only the immediate parent enough, given no ancestor's entries change? |
| 25 | 3. Do the ruling's five conditions hold in the code? |
| 26 | 4. Races: can a concurrent rename or symlink swap during the walk make it remove anything outside the tombstone's own path, or anything that isn't a non-directory? |
| 27 | 5. Anything new? |
| 28 | 6. **Verdict:** is it ready to merge? |
| 29 | |
| 30 | Give findings P1/P2/P3 with file:line. Read-only; run nothing heavy. |
| 31 | |