Skip to content

Commit a1fba4b

Browse files
committed
docs(vrs): clarify process and no-CAS boundary
1 parent d7e83eb commit a1fba4b

3 files changed

Lines changed: 98 additions & 77 deletions

File tree

docs/vrs/03-host-local/requirements.md

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,40 +10,46 @@ contract in [R18/R22](../requirements.md); this sub-VRS does not redefine it.
1010

1111
## Requirements
1212

13-
- **HOST-R01 One local subject:** A supervisor reconciles one selected catalog
14-
for one selected host. Another host's declarations and runtime records are
15-
outside that subject.
13+
- **HOST-R01 One local subject:** Each resident st2 control-plane instance
14+
selects one catalog and one host and reconciles only that pair. One host may
15+
run separate resident instances for other catalogs. The instance is the st2
16+
process, not the host's root agent or an ordinary supervisor persona. Another
17+
host's declarations and runtime records are outside the selected subject.
1618
- **HOST-R02 Local desired-versus-actual convergence:** The deterministic
17-
control plane compares declarations pinned to the selected host with that
18-
host's observed task state, adopts matching live work, and starts only
19-
genuinely missing work.
20-
- **HOST-R03 One control-plane writer:** At most one resident control plane may
21-
reconcile a given catalog and host at a time. A different host supervising
22-
the same synced catalog is a different subject.
19+
resident st2 control-plane instance compares declarations pinned to the
20+
selected host with that host's observed task state, adopts matching live
21+
work, and starts only genuinely missing work.
22+
- **HOST-R03 One control-plane writer:** At most one resident st2 control-plane
23+
instance may reconcile a given catalog and host at a time. A different host
24+
running an instance against the same synced catalog is a different subject.
2325
- **HOST-R04 Independent task lifetime:** Stopping, killing, or replacing the
24-
control plane does not stop or replace running agent tasks. A successor
25-
adopts surviving tasks without duplicating them.
26-
- **HOST-R05 Explicit destructive lifecycle:** Control-plane absence, restart,
27-
or loss of a transport peer is not teardown authority. Local tasks are
28-
stopped only by an explicit local lifecycle decision, including a locally
29-
applied retirement declaration or teardown command.
26+
resident st2 control-plane instance does not stop or replace running agent
27+
tasks. A successor instance adopts surviving tasks without duplicating them.
28+
- **HOST-R05 Explicit destructive lifecycle:** Resident st2 control-plane
29+
instance absence, restart, or loss of a transport peer is not teardown
30+
authority. Local tasks are stopped only by an explicit local lifecycle
31+
decision, including a locally applied retirement declaration or teardown
32+
command.
3033
- **HOST-R06 Intelligent local escalation:** The selected host's root agent
3134
observes local health, performs bounded recovery, and escalates unresolved
3235
failures without turning unavailable peer state into a fleet-health verdict.
33-
- **HOST-R07 Catalog liveness is not supervisor liveness:** A catalog remains
34-
live while any canonical agent belonging to it is running, including while
35-
its resident control plane is stopped, restarting, or unavailable.
36-
Supervisor state is reported separately. Its absence may delay convergence
37-
but does not make continuing agents dead, authorize teardown, or erase the
38-
last-applied catalog. DING/sidecar survival alone does not satisfy this
39-
agent-liveness predicate. Under incomplete or partitioned observation,
40-
absence of evidence cannot prove the catalog globally not live.
36+
This agent role is distinct from the resident st2 control-plane instance and
37+
from an ordinary supervisor persona.
38+
- **HOST-R07 Catalog liveness is not control-plane-instance liveness:** A
39+
catalog remains live while any canonical agent belonging to it is running,
40+
including while its resident st2 control-plane instance is stopped,
41+
restarting, or unavailable. Instance state is reported separately. Its
42+
absence may delay convergence but does not make continuing agents dead,
43+
authorize teardown, or erase the last-applied catalog. DING/sidecar survival
44+
alone does not satisfy this agent-liveness predicate. Under incomplete or
45+
partitioned observation, absence of evidence cannot prove the catalog
46+
globally not live.
4147
- **HOST-R08 Stable resolved state roots:** While a catalog is live, or while
42-
its resident supervisor is running, the resolved catalog root and PTY root
43-
remain stable mounted state paths and must not be relocated. Their contents
44-
have different semantics; ordinary catalog edit/sync remains allowed.
45-
Relocation requires the explicit coordinated migration contract in
48+
its resident st2 control-plane instance is running, the resolved catalog root
49+
and PTY root remain stable mounted state paths and must not be relocated.
50+
Their contents have different semantics; ordinary catalog edit/sync remains
51+
allowed. Relocation requires the explicit coordinated migration contract in
4652
[issue #85](https://github.com/compoundingtech/st2/issues/85).
4753

48-
Current mechanisms, executable evidence, and unimplemented partition
49-
activation work are mapped in [spec.md](spec.md).
54+
Current mechanisms, executable evidence, and the remaining partition questions
55+
are mapped in [spec.md](spec.md).

docs/vrs/03-host-local/spec.md

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,60 +7,68 @@ policy, or a second Doctor health model.
77

88
## Subject selection and ownership
99

10-
The CLI selects a catalog and an explicit or locally detected host. A
11-
[`HostLock`](../../../src/host_lock.rs#L1-L67) tracks resident ownership of
12-
that `(catalog, host)` subject independently from another host's slice of the
13-
same synced catalog.
10+
A resident st2 control-plane instance selects one catalog and an explicit or
11+
locally detected host, then reconciles only that pair. A host may run separate
12+
resident instances for other catalogs. This instance is the st2 process, not
13+
the host's root agent or an ordinary supervisor persona. A
14+
[`HostLock`](../../../src/host_lock.rs#L1-L67) tracks resident ownership of the
15+
selected `(catalog, host)` subject independently from another host's slice of
16+
the same synced catalog.
1417

1518
## Current mechanism and evidence
1619

1720
| Requirement | Current mechanism | Evidence |
1821
| --- | --- | --- |
1922
| HOST-R01 | Reconciliation filters every declaration through its resolved host; remote declarations are reported but not acted on. | [`reconcile`](../../../src/reconcile.rs#L106-L191); [host-placement tests](../../../tests/reconcile.rs#L135-L153) |
20-
| HOST-R02 | One pass discovers declarations, obtains an authoritative local session view, computes desired versus actual, and then adopts or executes the plan. A failed session listing skips the whole pass. | [reconcile pass](../../../src/run.rs#L737-L813); [reconcile-plan model](../../../src/reconcile.rs#L66-L81) |
21-
| HOST-R03 | The long-running CLI checks for a live owner of the same catalog and host, records its own PID, and reclaims stale ownership. | [catalog supervisor entry](../../../src/main.rs#L1738-L1838); [`HostLock` tests](../../../src/host_lock.rs#L83-L143) |
22-
| HOST-R04 | PTY and exec tasks survive normal or forced control-plane termination and binary replacement; the successor preserves PID and creation identity while adopting them. | [replacement acceptance](../../../tests/nomad_survival.rs#L592-L701) |
23-
| HOST-R05 | Normal supervisor exit leaves tasks running. Teardown and retirement are separate paths that target only the selected host's declared task IDs. | [`down` and teardown](../../../src/run.rs#L987-L1056); [explicit-lifecycle acceptance](../../../tests/nomad_survival.rs#L703-L780) |
24-
| HOST-R06 | The deterministic loop surfaces bounded crash-loop failure to the declared supervisor; the root-agent responsibility itself is owned by root R04. | [crash-loop surfacing](../../../src/run.rs#L1090-L1189); [R04](../requirements.md#L43-L46) |
25-
| HOST-R07 | Agent/task liveness and the resident supervisor lock are separate observations. A replacement adopts matching work visible in its selected current state. Sidecar-only work does not make an otherwise unrunnable agent live. No global catalog-liveness classifier is implemented. | [replacement adoption](https://github.com/compoundingtech/st2/blob/661c88b6e50cddbdf85e8ffaca9245c46491a1e0/tests/nomad_survival.rs#L608-L717); [separate supervisor report](https://github.com/compoundingtech/st2/blob/661c88b6e50cddbdf85e8ffaca9245c46491a1e0/src/main.rs#L985-L1008); [DING-only boundary](https://github.com/compoundingtech/st2/blob/661c88b6e50cddbdf85e8ffaca9245c46491a1e0/tests/reconcile.rs#L533-L561) |
23+
| HOST-R02 | One resident-instance pass discovers declarations, obtains an authoritative local session view, computes desired versus actual, and then adopts or executes the plan. A failed session listing skips the whole pass. | [reconcile pass](../../../src/run.rs#L737-L813); [reconcile-plan model](../../../src/reconcile.rs#L66-L81) |
24+
| HOST-R03 | The resident st2 control-plane instance checks for a live owner of the same catalog and host, records its own PID, and reclaims stale ownership. | [control-plane entry](../../../src/main.rs#L1738-L1838); [`HostLock` tests](../../../src/host_lock.rs#L83-L143) |
25+
| HOST-R04 | PTY and exec tasks survive normal or forced resident st2 control-plane instance termination and binary replacement; the successor instance preserves PID and creation identity while adopting them. | [replacement acceptance](../../../tests/nomad_survival.rs#L592-L701) |
26+
| HOST-R05 | Normal resident st2 control-plane instance exit leaves tasks running. Teardown and retirement are separate paths that target only the selected host's declared task IDs. | [`down` and teardown](../../../src/run.rs#L987-L1056); [explicit-lifecycle acceptance](../../../tests/nomad_survival.rs#L703-L780) |
27+
| HOST-R06 | The deterministic loop surfaces bounded crash-loop failure to the declared supervisor persona; the distinct root-agent responsibility is owned by root R04. | [crash-loop surfacing](../../../src/run.rs#L1090-L1189); [R04](../requirements.md#L43-L46) |
28+
| HOST-R07 | Agent/task liveness and the resident st2 control-plane instance's `HostLock` record are separate observations. A replacement instance adopts matching work visible in its selected current state. Sidecar-only work does not make an otherwise unrunnable agent live. No global catalog-liveness classifier is implemented. | [replacement adoption](https://github.com/compoundingtech/st2/blob/661c88b6e50cddbdf85e8ffaca9245c46491a1e0/tests/nomad_survival.rs#L608-L717); [separate control-plane report](https://github.com/compoundingtech/st2/blob/661c88b6e50cddbdf85e8ffaca9245c46491a1e0/src/main.rs#L985-L1008); [DING-only boundary](https://github.com/compoundingtech/st2/blob/661c88b6e50cddbdf85e8ffaca9245c46491a1e0/tests/reconcile.rs#L533-L561) |
2629
| HOST-R08 | Stable catalog-root and PTY-root path lifetime is an accepted constraint. The guided coordinated relocation operation is not implemented. | [migration contract](https://github.com/compoundingtech/st2/issues/85) |
2730

2831
## Catalog liveness and path lifetime
2932

30-
A live canonical catalog agent keeps the catalog live across supervisor
31-
downtime. The missing supervisor is separate factual state: it can delay
32-
convergence, but it cannot turn the continuing agent into dead work, erase the
33-
last-applied catalog, or authorize teardown. On restart, st2 adopts matching
34-
work that is visible in the selected current state and launches only genuinely
35-
missing work. A surviving generated DING sidecar without a canonical agent does
36-
not satisfy the catalog-agent liveness predicate.
33+
A live canonical catalog agent keeps the catalog live across resident st2
34+
control-plane instance downtime. The absent instance is separate factual state:
35+
it can delay convergence, but it cannot turn the continuing agent into dead
36+
work, erase the last-applied catalog, or authorize teardown. On restart, st2
37+
adopts matching work that is visible in the selected current state and launches
38+
only genuinely missing work. A surviving generated DING sidecar without a
39+
canonical agent does not satisfy the catalog-agent liveness predicate.
3740

3841
This is a host-local contract, not cross-root or global discovery. Under a
3942
partition or otherwise incomplete observation, st2 cannot infer that a catalog
4043
is globally not live merely because it cannot currently see a canonical agent.
41-
Supervisor state remains independently reportable.
44+
Resident st2 control-plane instance state remains independently reportable.
4245

43-
While the catalog is live, or while its resident supervisor is running, its
44-
resolved catalog root and PTY root are stable mounted state paths. Ordinary
45-
edits and file sync within the catalog remain allowed under the separate
46-
complete-version and last-known-good rules; this is a path-lifetime constraint,
47-
not an opaque-database contract. Relocating either resolved root requires the
48-
explicit coordinated operation in
46+
While the catalog is live, or while its resident st2 control-plane instance is
47+
running, its resolved catalog root and PTY root are stable mounted state paths.
48+
Ordinary edits and file sync within the catalog remain allowed under the
49+
separate complete-version and last-known-good rules; this is a path-lifetime
50+
constraint, not an opaque-database contract. Relocating either resolved root
51+
requires the explicit coordinated operation in
4952
[issue #85](https://github.com/compoundingtech/st2/issues/85). Ordinary
5053
`up`, `doctor`, and reconciliation remain scoped to the currently selected
5154
paths and never scan arbitrary old roots.
5255

5356
## Partition boundary
5457

55-
The root [R18/R22](../requirements.md) contract requires a complete,
56-
validated, locally applied catalog to remain authoritative through transport
57-
loss. The current reconciler instead discovers the live catalog filesystem on
58-
each pass ([source](../../../src/run.rs#L737-L758)), while validation is a
59-
separate read-only command
60-
([source](../../../src/validate.rs#L1-L24)). st2 does not yet stage a candidate
61-
catalog, assign or compare catalog versions, atomically activate a validated
62-
snapshot, or retain an activation receipt. That durable last-known-good
63-
activation path is unimplemented.
58+
The root [R18/R22](../requirements.md) contract requires a complete, validated,
59+
locally applied catalog to remain authoritative through transport loss. A plain
60+
synced catalog folder and direct KDL remain a complete operating path. Neither
61+
R18/R22 nor last-known-good host operation requires catalog publication,
62+
compare-and-swap, durable staging, or a content-addressed store. Optional
63+
transactional authoring may be added, but it cannot become a prerequisite for
64+
ordinary direct-KDL operation.
65+
66+
The current reconciler discovers the live catalog filesystem on each pass
67+
([source](../../../src/run.rs#L737-L758)), while validation is a separate
68+
read-only command ([source](../../../src/validate.rs#L1-L24)). st2 does not yet
69+
identify and order complete candidate versions or retain a durable
70+
last-known-good receipt. That implementation gap does not prescribe CAS or a
71+
content-addressed activation mechanism.
6472

6573
Peer reachability is not currently a reconciler input. This is consistent with
6674
peer absence being neutral, but the declaration shape for an explicit local
@@ -70,8 +78,9 @@ operation that depends on a peer or source is not yet specified.
7078

7179
- What identifies a complete candidate catalog and orders it after the locally
7280
applied version?
73-
- What atomic activation and durable receipt let a replacement control plane
74-
recover the last-known-good version after interruption?
81+
- What durable receipt lets a replacement control plane recover the
82+
last-known-good version after interruption without making a transactional
83+
authoring path mandatory?
7584
- How does a declaration express a local operation's dependency on a peer or
7685
source without turning peer presence into general health?
7786
- [`HostLock` acquisition](../../../src/host_lock.rs#L26-L48) is currently

docs/vrs/spec.md

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,13 @@ validate ──► materialize ──► host-local st2 scheduler/reconciler
169169

170170
- **Catalog liveness:** The
171171
[Host-local supervision contract](03-host-local/requirements.md) separates
172-
continuing canonical-agent liveness from resident-supervisor state. A
173-
running canonical agent keeps its catalog live across supervisor downtime;
174-
DING/sidecar-only survival does not. Incomplete observation cannot prove a
175-
catalog globally not live. While the catalog is live, or its supervisor is
176-
running, the resolved catalog root and PTY root remain stable paths; ordinary
177-
catalog edit/sync remains allowed, while relocation requires the coordinated
178-
operation in
172+
continuing canonical-agent liveness from resident st2 control-plane instance
173+
state. A running canonical agent keeps its catalog live across instance
174+
downtime; DING/sidecar-only survival does not. Incomplete observation cannot
175+
prove a catalog globally not live. While the catalog is live, or its resident
176+
st2 control-plane instance is running, the resolved catalog root and PTY root
177+
remain stable paths; ordinary catalog edit/sync remains allowed, while
178+
relocation requires the coordinated operation in
179179
[issue #85](https://github.com/compoundingtech/st2/issues/85).
180180

181181
- **Session registry:** A catalog owns the `pty` registry holding its tasks.
@@ -208,13 +208,19 @@ existing resident writer for the same local subject
208208
plane loss and adoption
209209
([evidence](../../tests/nomad_survival.rs#L592-L701)).
210210

211-
The durable catalog-activation half of R18/R22 is not implemented. Each pass
212-
currently discovers the live catalog directory directly
211+
A plain synced catalog folder and direct KDL remain a complete operating path
212+
for R18/R22. Last-known-good host operation does not require catalog
213+
publication, compare-and-swap, durable staging, or a content-addressed store.
214+
An optional transactional authoring path may be added, but it cannot become a
215+
prerequisite for direct-KDL operation.
216+
217+
The complete-version and durable last-known-good half of R18/R22 is not
218+
implemented. Each pass currently discovers the live catalog directory directly
213219
([source](../../src/run.rs#L737-L758)); `st2 validate` is separate and
214-
read-only. There is no staged candidate boundary, catalog version ordering,
215-
atomic validated activation, or durable last-known-good receipt. The exact
216-
candidate-completeness, version, and activation-recovery contracts remain open
217-
design work.
220+
read-only. There is no identified and ordered complete candidate version or
221+
durable last-known-good receipt. The exact completeness, version, and recovery
222+
contracts remain open design work; that gap does not prescribe CAS or a
223+
content-addressed activation mechanism.
218224

219225
## Message lifecycle
220226

0 commit comments

Comments
 (0)