diff --git a/docs/vrs/03-host-local/requirements.md b/docs/vrs/03-host-local/requirements.md new file mode 100644 index 00000000..b1316dde --- /dev/null +++ b/docs/vrs/03-host-local/requirements.md @@ -0,0 +1,34 @@ +# Host-local supervision requirements + +This sub-VRS applies the root [st2 requirements](../requirements.md) to one +host. It refines R03, R04, R11, R18, and R28. It does not change them. + +## Requirements + +- **HOST-R01 One local subject:** A resident st2 process selects one catalog and + one host. It reconciles only that pair. A host can run another process for a + different catalog. The process is not the root agent or a supervisor persona. +- **HOST-R02 Local convergence:** The process compares declarations for the + selected host with local task state. It adopts matching work. It starts only + missing work. +- **HOST-R03 One writer:** Only one resident st2 process can reconcile a catalog + and host pair at one time. A process for another host has a different subject. +- **HOST-R04 Independent task lifetime:** A resident process can stop, fail, or + be replaced without stopping agent tasks. Its successor adopts surviving work + and does not duplicate it. +- **HOST-R05 Explicit destructive action:** Process absence, process restart, + and peer loss do not authorize teardown. Only an explicit local retirement or + teardown action can stop local tasks. +- **HOST-R06 Local escalation:** The root agent observes local health. It makes + bounded recovery attempts and reports unresolved failures. It does not treat + an unavailable peer as a fleet-health result. +- **HOST-R07 Separate catalog liveness:** A catalog is live while one of its + canonical agents runs. The resident process has separate state. A DING + sidecar does not keep a catalog live. An incomplete view cannot prove that a + catalog is globally stopped. +- **HOST-R08 Stable state-root paths:** The catalog root and PTY root remain at + stable mounted paths while the catalog is live or the resident process runs. + File edits and sync can continue. Relocation requires the coordinated + operation in [issue #85](https://github.com/compoundingtech/st2/issues/85). + +[spec.md](spec.md) maps these requirements to code, tests, and open gaps. diff --git a/docs/vrs/03-host-local/spec.md b/docs/vrs/03-host-local/spec.md new file mode 100644 index 00000000..a5d8e12c --- /dev/null +++ b/docs/vrs/03-host-local/spec.md @@ -0,0 +1,50 @@ +# Host-local supervision specification + +This document maps the [host-local requirements](requirements.md) to current +code and tests. It does not define transport, remote attachment, deployment, +or Doctor health policy. + +## Current proof + +| Requirement | Mechanism and evidence | +| --- | --- | +| HOST-R01 | Reconciliation filters declarations by resolved host. It does not act on remote work. See [reconciliation](../../../src/reconcile.rs) and [host tests](../../../tests/reconcile.rs). | +| HOST-R02 | One pass reads declarations and task state. It then adopts or starts local work. A failed session read stops the pass. See [run](../../../src/run.rs). | +| HOST-R03 | `HostLock` records one live owner for the selected catalog and host. See [code and tests](../../../src/host_lock.rs). | +| HOST-R04 | Agent tasks survive normal exit, forced exit, and binary replacement. A new process adopts the same task generation. See [survival tests](../../../tests/nomad_survival.rs). | +| HOST-R05 | Normal exit leaves tasks alive. Retirement and teardown use separate commands. See [run](../../../src/run.rs) and [survival tests](../../../tests/nomad_survival.rs). | +| HOST-R06 | The loop reports bounded crash-loop failures. Root requirement R04 owns root-agent recovery. See [run](../../../src/run.rs) and [root requirements](../requirements.md). | +| HOST-R07 | Agent state and `HostLock` state are separate. Adoption uses current local state. A DING-only task does not make an agent live. st2 has no global catalog-liveness classifier. | +| HOST-R08 | Stable root paths are an accepted constraint. The relocation command is not implemented. See [issue #85](https://github.com/compoundingtech/st2/issues/85). | + +## Liveness and path boundary + +A live canonical agent keeps its catalog live while the resident st2 process is +down. Process loss can delay convergence. It cannot mark the agent dead, erase +the applied catalog, or authorize teardown. A DING sidecar is not a canonical +agent. An incomplete view cannot prove that the catalog is globally stopped. + +The catalog root and PTY root remain at stable mounted paths while the catalog +is live or the resident process runs. File edits and sync can continue. `up`, +`doctor`, and reconcile use only the selected paths. Root relocation requires +the coordinated operation in [issue #85](https://github.com/compoundingtech/st2/issues/85). + +## Partition and plain-folder boundary + +Root requirements R18 and R28 keep the last complete, validated local catalog +authoritative during transport loss. Hosts can use different catalog versions. +Peer absence is neutral unless an explicit local dependency says otherwise. + +A plain synced folder and direct KDL remain complete st2 inputs. They do not +require compare-and-swap, a content-addressed store, or an authoring service. +Current transaction commands are optional. They protect local publication, but +they do not identify ordered complete versions from a partial folder sync. They +also do not retain a durable last-known-good receipt for that case. + +## Open gaps + +- Define how a host identifies and orders complete synced-folder versions. +- Define a durable last-known-good receipt without requiring optional authoring. +- Define an explicit local dependency on a peer or source. +- Replace the check-then-write first-start step in + [`HostLock`](../../../src/host_lock.rs) with one atomic ownership operation. diff --git a/docs/vrs/requirements.md b/docs/vrs/requirements.md index 57a333d2..5d5da74b 100644 --- a/docs/vrs/requirements.md +++ b/docs/vrs/requirements.md @@ -115,6 +115,7 @@ accepted. - **R17 Durable error propagation:** Lifecycle, harness/eval, provider-turn, task/exec/PTY, hook, and delivery errors are durably reported to the responsible supervisor with agent/task identity and actionable context. + - **R19 Targeted reconciliation:** An exact agent/task selector resolves its identity and pinned host before mutation; unknown, ambiguous, and wrong-host targets refuse before writes, listing, or actions. Materialization, hook @@ -134,6 +135,17 @@ accepted. inspection exposes every Resource binding without interpreting its type or URI. Resource-only declaration changes do not alter a task's effective launch definition and do not stop, replace, or relaunch healthy work. +### Must remain safe through host partitions + +- **R18 Last-known-good local desired state:** During transport loss, each host + uses its last complete, validated catalog as local desired state. Missing, + partial, or invalid input cannot replace that state or authorize teardown. +- **R28 Independent fleet convergence:** Hosts may use different catalog + versions during a partition. A host can accept only a complete, validated, + newer catalog. Each host converges its own work. Peer and source reachability + are facts, not health classifications. Their absence affects local work only + through an explicit local dependency. + - **R27 Transactional catalog authoring:** One st2 publication operation admits exactly one canonical KDL Agent Spec, with explicit host and identity, against the complete prospective catalog. Publication is compare-and-swap, durable, diff --git a/docs/vrs/spec.md b/docs/vrs/spec.md index 01b07401..7597f0b1 100644 --- a/docs/vrs/spec.md +++ b/docs/vrs/spec.md @@ -441,10 +441,10 @@ validate ──► materialize ──► host-local st2 scheduler/reconciler The canonical `agent` task treats a reconciler's ambient `NO_COLOR` as a launcher preference rather than agent policy. Unless the Agent Spec declares - `NO_COLOR`, st2 removes it from the launch environment and records the removal - in the PTY launch definition. An explicit Agent Spec assignment takes - precedence. Isolation wrappers preserve both assignments and removals, so a - manual PTY restart under a different ambient environment reconstructs the + `NO_COLOR`, the reconciler removes it from the launch environment and records + the removal in the PTY launch definition. An explicit Agent Spec assignment + takes precedence. Isolation wrappers preserve both assignments and removals, + so a manual PTY restart under a different ambient environment reconstructs the same effective color policy. Adoption of an already-live task remains non-mutating: this policy is applied only when st2 creates a generation. - **R07:** Hook bundles are explicit, content-addressed, installed separately, @@ -478,6 +478,16 @@ validate ──► materialize ──► host-local st2 scheduler/reconciler lifecycle is the explicit authority to resume ordinary replacement. `retired #true` remains the separate explicit teardown path. +- **Catalog liveness:** The + [Host-local supervision contract](03-host-local/requirements.md) separates + canonical-agent liveness from resident st2 process state. A running canonical + agent keeps its catalog live while the process is down. A DING sidecar does + not. An incomplete view cannot prove that a catalog is globally stopped. The + catalog root and PTY root remain at stable paths while the catalog is live or + the resident process runs. File edits and sync can continue. Root relocation + requires the coordinated operation in + [issue #85](https://github.com/compoundingtech/st2/issues/85). + - **R23:** `st2 tasks --json` is a read-only diagnostic boundary. It emits one `st2.task-inventory.v1` envelope for the selected host. Rows are sorted by agent, task, and runtime id and cover both PTY and terminal-free exec tasks. @@ -520,6 +530,23 @@ validate ──► materialize ──► host-local st2 scheduler/reconciler closed instead of hanging reconciliation. The deadline is containment, not the mechanism for admitting a larger fleet. +## Partition and catalog activation (R18, R28) + +- **R18:** Transport loss does not invalidate a host's locally applied desired + state. Missing, partial, or invalid incoming catalog state cannot replace the + last complete validated version or cause teardown. +- **R28:** Hosts may temporarily apply different catalog versions and converge + independently. Peer or source absence is neutral unless a declared local + operation explicitly depends on it; reconnect is not itself evidence that a + candidate catalog is complete, valid, or newer. + +The [host-local sub-VRS](03-host-local/spec.md) maps these requirements to code +and tests. A plain synced catalog folder and direct KDL remain complete inputs. +Optional transaction or content-addressed tools cannot become prerequisites. +Current transaction tools protect local publication. They do not identify and +order complete versions from a partially synced folder. They also do not retain +a durable last-known-good receipt for that case. + ## Message lifecycle ```text