fleetd #480: a relative leadRollover.handoverPath resolves against the lead's workspace

Dai Ha
2026-09-12 05:46:44 +07:00
parent 1eadfbc6e5
commit 285b0a664f
+10 -1
@@ -5447,7 +5447,7 @@ clean refusal naming `NOT_CONFIGURED`.
```yaml
leadRollover:
handoverPath: /path/to/HANDOVER.md # required when the block is present
handoverPath: .handover/HANDOVER.md # required when the block is present; relative is allowed
requireOperatorConfirm: true # default true
maxDocAgeSeconds: 3600 # default 3600
turnSettleSeconds: 20 # default 20
@@ -5481,6 +5481,15 @@ re-litigating:
the file's modified time is later than the `open` request. That check exists so a leftover file
from a previous session can never be accepted as this session's handover, and it means the
obvious order — write the file, then ask — is the wrong one.
- **A relative `handoverPath` resolves against the lead's workspace, not the daemon's.** The
daemon and the lead run in different directories — on this host the daemon sits in `<repo>/fleetd`
and the lead in `<repo>` — so a bare relative path would mean two different files. `open()`
resolves it once, against the calling lead's configured `fleet.leaders.<name>.cwd` (falling back
to the daemon's own working directory when that lead has no `cwd`), and hands back an **absolute**
path. Everything downstream — the `open` response the lead writes to, the file the daemon stats,
and the bootstrap prompt the fresh session reads — uses that one absolute path. An absolute
`handoverPath` is used unchanged.
- **`confirm` returning `accepted` does NOT mean the pane has been cleared.** It means every gate
passed and the roll is scheduled. The roll itself runs after the calling turn ends, and it may
still refuse at that point; those outcomes are logged only, because there is no caller left to