carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

REJECT

  1. P1 — Captured worker builds are unprotected before plan 5. internal/release/adopt.go:405, internal/activator/workerbuild.go:52.

A worker runs A, whose staged files are over six hours old. Two promotions install B then C before the worker converges. Its live link and registry now pin C and B; nothing exported by this branch pins A. The next hourly sweep can delete A. Alternatively, adoption of a re-shipped A can overwrite it because BoxPins reports it unreferenced.

A subsequent crash or max_run recycle refuses A through VerifyStaged. The exited-worker branch keeps retrying that identity and never reaches convergence, leaving the worker down indefinitely. This happens without any new flag.

Smallest fix: treat worker references as unknown until they are exported, suppressing both destructive restaging and eviction in that state. Alternatively, bring the worker-pin writer and both consumers into this branch. Add a regression covering two repoints followed by sweep/restage and recycle.

  1. P2 — Same-build recycles can prevent convergence indefinitely. internal/activator/activator.go:1974, internal/activator/activator.go:2548.

An always-on worker runs A with max_run=30s; root installs B. Every recycle correctly respawns A, but also clears staleSince. The drift never survives the 90-second ConvergeGrace, so B never runs. Frequent crashes produce the same starvation; exited workers skip the drift check entirely. Before this change, their respawn followed the updated live link.

Smallest fix: preserve drift age across recycles of the same build, evaluate drift even when a recycle is due, and give an eligible convergence priority while retaining the convergence budget. Test several recycle intervals after a promotion, not only the first recycle.

  1. P2 — Chained live symlinks hide referenced copies from BoxPins. internal/release/pins.go:59, internal/release/staged.go:53.

With live/h → /opt/operator-current → versions/v1/app, and no registry version pin for v1, BoxPins records only /opt/operator-current. Another host adopting a re-shipped v1 therefore overwrites a copy the live link still references. ResolveLive likewise retains the intermediate link, rather than the final executable path. A later digest refusal detects the damage but does not prevent the overwrite.

Smallest fix: resolve the captured target’s remaining symlinks for executable identity and pinning; preserve necessary intermediate-path pins and fail closed when resolution is uncertain. Add a chained-link restage-refusal test. The ledger’s Task 3 symlink minor needs promotion to a pre-merge fix.

Ledger rulings and deferred items

  • R1, R7, R9: workflow choices; no implementation objection.
  • R2–R5: consistent with the binding sections and current code. Preserving cgroup cleanup and the config-admission gate is necessary.
  • R6: canonical comparison and outage fallback are consistent with the stated contract. This does not establish that the reference set is complete.
  • R8: reasonable against this base; the later staging integration still needs review.
  • R10: acceptable. The fixtures still reach the binding refusal and retain their assertions.
  • R11: the conservative refusal is correct. Its claimed recovery is not guaranteed: a held row is not necessarily adopted by a full pass, and that pass may never stage its requested version. Correct that expectation; do not restore the incomplete-pin overwrite.

Deferred-minor triage:

| Ledger area | Disposition | |---|---| | Task 1 | Test-comment wording and missing uppercase rejection test: P3. | | Task 2 | Lossy-sibling comment is already corrected. Older-sibling reuse test: P3. | | Task 3 | Chained symlink: finding 3. Relative-link assertion, wording and error wrapping: P3. | | Task 4 | Empty SHA is already rejected by validateManifest, so CanonicalDemand returns hold. EqualFold/digest assertion gaps: P3. | | Task 5 | Parent-directory fsync, reader consolidation, missing branch tests, parse-error wrapping and empty-host-list strictness: P3. | | Task 6 | Missing-platform diagnostics/test, repeated hashing/logging and held-stage explanation: P3. | | Task 7 | Ordering comment, generic failure reason and coverage gaps: P3. Host-claim selection and unit-less proof-policy behavior are not new defects. | | Task 8 | Regular-file and unreadable-target refusals fail closed. Missing failure-path test: P3. | | Task 9 | Captured-copy loss: finding 1, must fix. Coalescing backoff/logging and remaining coverage gaps: P3; add refused-recycle coverage with finding 1. |

Static review only; no files modified and no tests run. git diff --check 4f26f15c..HEAD passed.