novox/hq issue 213: the controller moves from a container to a process on its one machine. Today every orphan is removed before anything is applied, so the container would go first and nothing would answer the mesh-controller seat while the process is fetched, unpacked and started — and nothing at all if it never starts.
Rebased onto main after #85. #85's oneshot unit for a run-once process is kept as it is; this PR adds only what #85 doesn't cover.
Changes
process.replaces. A process can name resources the declaration no longer declares. Such an orphan is not removed in the first pass. It is removed only after the replacing process applied and stayed up: active/running at two checks 10 s apart, with the same MainPID and no restart in between. This is stricter than ADR 0184's second check, which counts a crash-looping unit in activating/auto-restart as running.
When the replacement isn't up. If it failed, was skipped behind its module's step, or isn't up, the orphan keeps running and stays recorded. It is reported as kept, the apply fails and names it, and the next apply hands it over.
Refused: replacing something still declared, replacing itself, an empty id, one id named by two processes, and replaces on a step or a schedule.
A step written ./name runs its own bundle's binary, and is started, never enabled.
A failed run-once process now gates its module, as a run-once container already did.
An unchanged run-once process is no longer re-run on every apply.
An unchanged scheduled process is now kept up by its timer; before, every apply started its service.
Tests. New: internal/apply/handover_test.go and internal/declaration/replaces_test.go; they fail without the change. #85's process_step_test.go still passes, and go test ./... passes. The controller's composed declaration from mesh-controller #253 parses here (MESH_EMITTED).
Order. This must be live on the controller's machine before mesh-controller #253 is registered. A host without it refuses the whole declaration (unknown field replaces); that fails safe, since the container keeps running.
Genesis.internal/bootstrap step 9 is not changed here. See #253 for why that is not in this PR.
novox/hq issue 213: the controller moves from a container to a process on its one machine. Today every orphan is removed before anything is applied, so the container would go first and nothing would answer the mesh-controller seat while the process is fetched, unpacked and started — and nothing at all if it never starts.
Rebased onto main after #85. #85's oneshot unit for a run-once process is kept as it is; this PR adds only what #85 doesn't cover.
**Changes**
- **`process.replaces`.** A process can name resources the declaration no longer declares. Such an orphan is not removed in the first pass. It is removed only after the replacing process applied and stayed up: `active/running` at two checks 10 s apart, with the same MainPID and no restart in between. This is stricter than ADR 0184's second check, which counts a crash-looping unit in `activating/auto-restart` as running.
- **When the replacement isn't up.** If it failed, was skipped behind its module's step, or isn't up, the orphan keeps running and stays recorded. It is reported as `kept`, the apply fails and names it, and the next apply hands it over.
- **Refused:** replacing something still declared, replacing itself, an empty id, one id named by two processes, and `replaces` on a step or a schedule.
- **Beyond #85:**
- A step written `./name` runs its own bundle's binary, and is started, never enabled.
- A failed run-once process now gates its module, as a run-once container already did.
- An unchanged run-once process is no longer re-run on every apply.
- An unchanged scheduled process is now kept up by its timer; before, every apply started its service.
**Tests.** New: `internal/apply/handover_test.go` and `internal/declaration/replaces_test.go`; they fail without the change. #85's `process_step_test.go` still passes, and `go test ./...` passes. The controller's composed declaration from mesh-controller #253 parses here (`MESH_EMITTED`).
**Order.** This must be live on the controller's machine before mesh-controller #253 is registered. A host without it refuses the whole declaration (unknown field `replaces`); that fails safe, since the container keeps running.
**Genesis.** `internal/bootstrap` step 9 is not changed here. See #253 for why that is not in this PR.
The controller moves from a container to a process on the one machine
that runs it (novox/hq issue 213). Every orphan is removed before anything
is applied, so the container would go first and nothing would answer the
mesh's verbs while the process was fetched, unpacked and started — and
never again, if it did not start.
- a process may say what it `replaces`: resources the declaration no
longer declares. Such an orphan is kept through the up-front sweep and
removed right after the process applied and is up: active and running
at two looks ten seconds apart, the same main process, no restart in
between (stricter than ADR 0184's second look, which reads a unit
waiting to restart as running). If the process failed, was skipped
behind its module's step, or is not running, the orphan stays running
and recorded, reported kept, and the next apply hands it over.
Refused: naming something still declared, itself, an empty id, one
thing named by two processes, and `replaces` on a step or a schedule.
- beyond #85's oneshot unit for a step: a step written ./name runs its
own bundle's binary (tested), and is started, never enabled.
- a run-once process that fails gates its module, as a run-once
container already did, so a version whose preparation failed is not
started.
- an unchanged run-once process is not run again, and an unchanged
scheduled one is kept up by its timer: both were "a daemon that had
stopped" and were started on every apply.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
novox/hq issue 213: the controller moves from a container to a process on its one machine. Today every orphan is removed before anything is applied, so the container would go first and nothing would answer the mesh-controller seat while the process is fetched, unpacked and started — and nothing at all if it never starts.
Rebased onto main after #85. #85's oneshot unit for a run-once process is kept as it is; this PR adds only what #85 doesn't cover.
Changes
process.replaces. A process can name resources the declaration no longer declares. Such an orphan is not removed in the first pass. It is removed only after the replacing process applied and stayed up:active/runningat two checks 10 s apart, with the same MainPID and no restart in between. This is stricter than ADR 0184's second check, which counts a crash-looping unit inactivating/auto-restartas running.kept, the apply fails and names it, and the next apply hands it over.replaceson a step or a schedule../nameruns its own bundle's binary, and is started, never enabled.Tests. New:
internal/apply/handover_test.goandinternal/declaration/replaces_test.go; they fail without the change. #85'sprocess_step_test.gostill passes, andgo test ./...passes. The controller's composed declaration from mesh-controller #253 parses here (MESH_EMITTED).Order. This must be live on the controller's machine before mesh-controller #253 is registered. A host without it refuses the whole declaration (unknown field
replaces); that fails safe, since the container keeps running.Genesis.
internal/bootstrapstep 9 is not changed here. See #253 for why that is not in this PR.161ac1ff01to2ff3b50a84