skills: add pi-devbox-firstboot, and point the managed AGENTS block at it
The fleet's first-boot acceptance round is now scoped by published state (policy v2, artifact art_20261023T204306_b388e93c3d64): a booting container reads two claim keys -- firstboot-release-<TAG> and firstboot-image-<TAG>-<ARCH> -- and derives whether it owes the release tier, the per-architecture image tier, or only the device tier. Nothing delivered that procedure to a device that does not already have a coordination chain. The gate deliberately needs no roster, because fleet membership changes in both directions, so no message addresses a new device and nothing enrolls it. The consequence is that a BRAND-NEW device -- empty mailbox, no chain, and the mempalace skill correctly telling it that an empty mailbox is a fine answer -- had no path to the round at all. Historically a peer planted the newcomer's first ask cross-device, which is exactly the roster dependency the state design removes. This skill is how a device learns to plant its own. The skill is a FINDER, not the policy: it locates the newest policy.update on topic=firstboot-acceptance and fetches the artifact, and says plainly that the artifact wins on disagreement. A policy baked into an image is pinned to that image; keeping only the lookup here means a revision needs no release and a device on an older image still reaches the current policy. Baked canonical, like pi-devbox-environment, rather than skillset-owned. The round verifies the image, so pinning it to the image is right -- and a skillset-owned skill needs the vendoring machinery (ARG SKILLSET_SNAPSHOT_REF, the manifest/label pair, a per-skill refresh script) that today exists only for mempalace. No wiring was needed: entrypoint-user.sh and pi-devbox-version both enumerate the baked skills directory. smoke-test.sh asserts the AGENTS.md pointer BY PATH, not by prose. A new device reaches the round only through that line, so rewording the paragraph must not be able to cut it silently. Both skill-resolution loops gain the new name.
This commit is contained in:
@@ -13,6 +13,44 @@ Pre-v1.0.0 tags followed the pi npm version (`v{pi_version}[letter]`).
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
|
||||
- **`pi-devbox-firstboot` skill + a managed-block pointer to it, so a new
|
||||
device can find the fleet's first-boot acceptance round at all.** The round
|
||||
is now *scoped by published state* (policy v2, artifact
|
||||
`art_20261023T204306_b388e93c3d64`): a booting container reads two claim
|
||||
keys — `firstboot-release-<TAG>` and `firstboot-image-<TAG>-<ARCH>` — and
|
||||
derives whether it owes the release tier, the per-architecture image tier, or
|
||||
only the device tier. Previously every device re-ran the entire sequence on
|
||||
every release, which was drift rather than a decision: each device plants its
|
||||
own successor ask carrying the previous round's checklist, so scope only grew
|
||||
(4 checks at v1.10.2 → B1–B5 at v1.11.2 → B1–B7 at v1.12.2) while a peer's
|
||||
PASS on *identical image bytes* was recorded as context rather than as grounds
|
||||
to skip. The v1.8.10-era "image half — already settled, do not repeat" split
|
||||
was never retired; it simply lapsed.
|
||||
|
||||
Two properties the skill exists to protect. First, **the gate needs no
|
||||
roster**: fleet membership changes in both directions, so nothing addresses a
|
||||
device and nothing enrolls it — state is read, not pushed. The case that
|
||||
therefore has no delivery path at all is a *brand-new* device, whose mailbox
|
||||
is legitimately empty and whose coordination chain does not exist yet; it must
|
||||
plant its own first ask, and this skill is how it learns that. Second, the
|
||||
skill is a **finder, not the policy**: it locates the current policy artifact
|
||||
in the logstream instead of restating it, because a policy baked into an image
|
||||
is pinned to that image — a device on an older release still reaches the
|
||||
current policy, and a revision needs no release.
|
||||
|
||||
Baked canonical (like `pi-devbox-environment`), not skillset-owned: the round
|
||||
verifies the image, so pinning it to the image is correct, and a skillset-owned
|
||||
skill would need the vendoring machinery (`ARG SKILLSET_SNAPSHOT_REF`, the
|
||||
manifest/label pair, a per-skill refresh script) that today exists only for
|
||||
`mempalace`. `entrypoint-user.sh` and `pi-devbox-version` both enumerate the
|
||||
baked skills directory, so no wiring change was needed for either to pick it
|
||||
up. `scripts/smoke-test.sh` asserts the baked file, both resolution loops, and
|
||||
the `AGENTS.md` pointer **by path rather than by prose** — a new device reaches
|
||||
the round only through that line, so rewording the paragraph must not be able
|
||||
to break the link silently.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **CI: a smoke job's image could be deleted mid-test by another job's disk
|
||||
|
||||
Reference in New Issue
Block a user