# 7.5 Readiness Levels

_Peios / Advanced Peios / peinit / Dependencies_

> How a service waits for a condition inside another service — Requires = ["netd:routed"] — and why a level is exact, per-publisher and never stale.

`network-online.target` on systemd is famously meaningless, because
"online" has no single definition. A service needing a default route and
a service needing only a loopback address want different things, and one
target cannot mean both.

peinit does not have an online target. A service says what it is waiting
for, in the publisher's own vocabulary:

```
Requires = ["netd:routed"]
Wants    = ["timed:synchronised"]
```

`netd:routed` waits for netd to be active **and** to have published the
level `routed`. `netd` on its own is unchanged — the ordinary "that
service must be active" dependency.

## 7.5.1 The syntax

`<service>:<level>`, split on the first colon. It rides on the existing
`Requires`, `Wants` and `BindsTo` fields rather than a field of its own,
because a level dependency *is* a service dependency with a stricter
predicate: `netd:routed` subsumes `netd`. Each relationship keeps exactly
the semantics [it already has](/peios/advanced-peios/peinit/dependencies/relationships.md), applied to
the stricter test.

It cannot collide with a service name. A service name may contain only
letters, digits, `.`, `_` and `-`, so a colon never appears in one, and
no existing definition can accidentally become a level dependency.

A trailing colon — `"netd:"` — reads as a plain dependency on `netd`. It
is a typo, and treating it as a request for the empty level would produce
a condition nothing could ever satisfy.

## 7.5.2 How a level gets there

The service publishes it on the notification channel it already has, as
`LEVEL=` beside `READY=1` and `STATUS=`:

```
LEVEL=routed
```

An empty value retracts it. peinit records the level against the sending
service, and holds any dependent whose declaration does not match.

There is no subscription. peinit does not connect to netd's socket or
timed's, does not need to find them before they exist, and carries no
knowledge of their wire formats — which matters, because PID 1 is the one
process on the machine that cannot afford to fail to start.

## 7.5.3 Levels are exact, not ordered

`Requires = ["netd:addressed"]` is **not** satisfied by `netd:routed`.

peinit has no ordering over another daemon's vocabulary and does not
invent one. netd knows that `routed` implies `addressed`; peinit does
not, and a central table of which levels imply which would recreate
exactly the coupling that naming levels after their publisher avoids.

A service that genuinely wants "addressed or better" should depend on the
level it actually needs. If a publisher's levels are ordered in a way
dependents keep needing to express, that is a sign the publisher should
name the useful condition directly.

## 7.5.4 A level is never stale

peinit clears a service's level whenever that service leaves a state that
satisfies dependents. A level is a claim about a process that is
currently making it, and one that outlived its process would hold a
dependent open on a promise nobody was keeping — the exact failure the
mechanism exists to prevent.

Because peinit is the process that notices a service exiting, this needs
no timeout and no liveness check.

## 7.5.5 How the gate holds

A level is settled at dispatch, not at planning. The plan decides *what*
to start; whether a level is met is a live question — it can arrive after
the target's own start completed (netd is active long before DHCP
finishes) and be retracted while a dependent is still waiting — so the
[execution graph](/peios/advanced-peios/peinit/dependencies/graph-execution.md)
re-checks it against the service table every time it considers releasing
the dependent, and holds the start until the answer is yes.

That check runs even when there is nothing to start. An already-active
target is not part of the start plan, but the condition on it still is:
the graph keeps a level edge to a service it is not starting, which is
what makes `Requires = ["netd:routed"]` hold when netd is up and merely
not routed yet.

Two events re-open the question. A `LEVEL=` arriving from the publisher
releases every dependent held on it — this is the only thing that can
open a `Requires` or `BindsTo` gate, which take the exact level and
nothing else. And the publisher leaving a state that satisfies dependents
releases `Wants` waiters: a soft dependency waits only while someone is
running who could still publish the level, and proceeds once nobody is —
which keeps `Wants` failure-tolerant, the property that defines it.

A held start does not time out. `Requires = ["netd:no-such-level"]`
holds the dependent indefinitely: the service stays inactive and the
start operation stays pending, visible in `svctl status` as an operation
that has not completed. That is the declared semantics, not a hang — the
condition was never met, so the start never happened.

## 7.5.6 What happens on a drop

Nothing, in this version. If a level falls away after a dependent has
already started, the dependent keeps running and is not told.

That is a deliberate limit, not an oversight. The notification channel is
one-way by specification (PSPU §4.16), so peinit has no way to tell a
running service anything. A service that needs to react to a level
changing while it runs should subscribe to the publisher directly — which
is what resolvd does with netd today, and what any consumer that cares
that much will want anyway, since it will need the detail rather than
just the fact.

peinit's contribution is the start gate: the moment when the service does
not exist yet and so cannot subscribe to anything at all.

## 7.5.7 Published levels

| Publisher | Levels |
|---|---|
| [netd](/peios/using-peios/networking/overview.md) | `link` → `addressed` → `routed` |
| [timed](/peios/using-peios/time/overview.md) | `unsynchronised`, `settling`, `synchronised`, `spike` |

Any service may publish a level; nothing about the mechanism is specific
to these two. The vocabulary is the publisher's own, and needs no
registration.
