docs: fix round-2 regression — restore deleted PublishFleet row, precise lease citations
Round-1's lease-election row insertion clobbered the pre-existing status/fleet.json (PublishFleet) row instead of adding alongside it; the cross-check prose referenced status/fleet.json with no table row backing it. Re-add the row (distinct call site: lock write vs. elected content write). Also correct the lease row's imprecise line-span citation: Acquire is lease.go:187, acquireTTL:197, Held.Release:233, startRenewer:109 — cite each precisely rather than a blanket 187-231.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 file changed,
+15
−12
docs/superpowers/specs/2026-08-20-bucket-writer-audit.md+15 −12
diff --git a/docs/superpowers/specs/2026-08-20-bucket-writer-audit.md b/docs/superpowers/specs/2026-08-20-bucket-writer-audit.md| index 4c5e4b3a7..d64d0abf9 100644 |
| --- a/docs/superpowers/specs/2026-08-20-bucket-writer-audit.md |
| +++ b/docs/superpowers/specs/2026-08-20-bucket-writer-audit.md |
| @@ -38,7 +38,8 @@ safe but doesn't fit the five-word vocabulary cleanly. |
| | File:line | Key / prefix | Runner | Ruling | |
| |---|---|---|---| |
| -| `internal/host/agent.go:1895` → `internal/lease/lease.go:187-231` (`lease.Acquire`, `Held.Release`, `startRenewer`) | `<CARLOS_STATUS_PREFIX>/status-lease/lock.json` (litestream's `lss3.Leaser`: lock lands at `<prefix>/lock.json`, and the prefix passed in is `path.Join(CARLOS_STATUS_PREFIX, "status-lease")`) — conditional-write lock, TTL 15m, renewed at TTL/3, released on graceful stand-down | every non-fleet box, on every status tick, contending for THIS election; the winner renews for as long as it holds it | elected already — **this IS the status publisher's election mechanism**, not a writer needing one. Not caught by the `.Put(\|.Delete(` recipe or the supplementary S3-idiom sweep: it calls `lss3.NewLeaser().AcquireLease`/`ReleaseLease` directly, bypassing both `release.Store` and the raw AWS SDK's `PutObject`/`DeleteObject`. See Findings §1. | |
| +| `internal/host/agent.go:1895` → `internal/lease/lease.go:109,187,197,233` (`startRenewer`, `Acquire`, `acquireTTL`, `Held.Release`) | `<CARLOS_STATUS_PREFIX>/status-lease/lock.json` (litestream's `lss3.Leaser`: lock lands at `<prefix>/lock.json`, and the prefix passed in is `path.Join(CARLOS_STATUS_PREFIX, "status-lease")`) — conditional-write lock, TTL 15m, renewed at TTL/3, released on graceful stand-down | every non-fleet box, on every status tick, contending for THIS election; the winner renews for as long as it holds it | elected already — **this IS the status publisher's election mechanism**, not a writer needing one. Not caught by the `.Put(\|.Delete(` recipe or the supplementary S3-idiom sweep: it calls `lss3.NewLeaser().AcquireLease`/`ReleaseLease` directly, bypassing both `release.Store` and the raw AWS SDK's `PutObject`/`DeleteObject`. See Findings §1. | |
| +| `internal/status/fleet.go:572,580` (`PublishFleet`→`putOverwrite`) | `status/fleet.json` — the elected content this lease guards, a DISTINCT call site from the lock write above | lease-elected publisher (the winner of the `status-lease` election above) | elected already | |
| | `internal/status/snapshot.go:540,548` (`WriteBox`) | `status/boxes/<label>.json` | every box, own key | per-box keys (already) | |
| | `internal/appconfig/store.go:187` (`applyAt`, called by `Apply`/`SetEnv`) | `apps/<acct>/<app>/config.json` or `.../environments/<env>.json` | console (`apiconfig.go`) | console-only | |
| | `internal/appconfig/store.go:288` (`SetExecDeliveryAt`) | same bundle keys | console (`apiconfig.go`) | console-only | |
| @@ -136,17 +137,19 @@ mechanism, reused; no second election pattern may be introduced") and asks |
| this stage-1 audit to verify is deployment-scoped — was absent from the |
| first pass of this doc. Not an oversight of judgment: it's a genuine |
| sweep-idiom gap. `internal/host/agent.go:1895` calls `lease.Acquire(ctx, |
| -bucket, path.Join(prefix, "status-lease"), region)`; `internal/lease/lease.go`'s |
| -`acquireTTL` (187-215) hands the bucket/path straight to |
| -`github.com/benbjohnson/litestream/s3.Leaser` — `leaser.Bucket`, |
| -`leaser.Path`, `leaser.AcquireLease(ctx)` — which does its own conditional |
| -`PutObject`/`GetObject` against `<prefix>/lock.json` inside the litestream |
| -library, never through `release.Store`, never through a call site spelled |
| -`.Put(` or `.Delete(` on anything this package owns, and never through the |
| -raw AWS SDK types (`PutObjectInput` etc.) the supplementary sweep grepped |
| -for. `startRenewer` rewrites the lock every `TTL/3` (15m/3 = 5m in |
| -production, `LeaseTTL` in `lease.go`); `Held.Release` (`lease.go:233-239`) |
| -deletes it on graceful stand-down. None of the audit's grep patterns — |
| +bucket, path.Join(prefix, "status-lease"), region)` |
| +(`internal/lease/lease.go:187`), which is a thin wrapper over `acquireTTL` |
| +(`lease.go:197`) with the production `LeaseTTL`; `acquireTTL` hands the |
| +bucket/path straight to `github.com/benbjohnson/litestream/s3.Leaser` — |
| +`leaser.Bucket`, `leaser.Path`, `leaser.AcquireLease(ctx)` — which does its |
| +own conditional `PutObject`/`GetObject` against `<prefix>/lock.json` inside |
| +the litestream library, never through `release.Store`, never through a |
| +call site spelled `.Put(` or `.Delete(` on anything this package owns, and |
| +never through the raw AWS SDK types (`PutObjectInput` etc.) the |
| +supplementary sweep grepped for. `startRenewer` (`lease.go:109`) rewrites |
| +the lock every `TTL/3` (15m/3 = 5m in production, `LeaseTTL` in |
| +`lease.go`); `Held.Release` (`lease.go:233`) deletes it on graceful |
| +stand-down. None of the audit's grep patterns — |
| recipe or supplementary — could have matched any of that; the idiom list |
| above now names `lss3.Leaser`/`litestream.` explicitly so the next auditor |
| greps for it. |