wake/verification: add a mechanical precondition — confirm the running process holds config you just changed #961
Open
opened 2026-07-30 19:14:14 +00:00 by mos-dt-0
·
0 comments
No Branch/Tag Specified
main
remediation/state
feat/rm-02-gate-registry
fix/rm-01-reproducible-checkout
remediation/mission-setup
fix/hygiene-inert-format-gate
fix/1019-queue-guard-stdin
feat/mos-ste-writing-standard
fix/1007-suite-hermeticity
fix/991-comment-url-scheme-normalise
feat/push-guard-null-case-verification
mos-comms-live
docs/heartbeat-framework-layering-ms-lead
feat/869-c4-version-coupling
feat/869-c2-install-ordering-guard
feat/869-c5-doctor-activation-check
feat/per-agent-gitea-identity
fix/875-belongs-case-insensitive-slug
fix/ci-queue-wait-404-branch-absent
feat/869-c1-activation-probe
feat/869-c3-broker-supervisor
fix/865-tea-cli-comment-invocation
feat/glpi-skills
fix/860-deflake-mutator-lease-gate
fix/850-detect-platform-port-normalization
fix/856-worktree-deps-preflight
fix/835-pr-review-approve-reject-comment-flag
fix/848-truthful-evidence
fix/812-pr-review-comment
fix/849-recovery-runtime-fixture-race
docs/758-ledger-m5-001-sync
feat/834-tc-server-side-doc
feat/833-constrained-recovery-command
feat/827-gate0-probe
governance/gate0-probe3-amendment
fix/795-codex-pr-diff
fix/795-ci-base-jq
fix/795-ci-base-git
feat/791-pr3-fleet-regen
feat/791-pr2-snapshot-restore
fix/807-glpi-206
fix/808-agent-send-false-sender
feat/791-upgrade-config-protection
feat/790-mosaic-yolo-claudex-pr2
feat/790-mosaic-yolo-claudex
feat/758-v1-v2-migrator
fix/766-exact-fleet-comms
test/758-reconciler-lifecycle-gates
docs/771-kbn101-db-role-split
test/758-example-profile-dispositions
feat/758-shared-role-resolution
feat/mos-logical-identity-fencing
feat/769-kbn100-unified-schema
docs/753-kbn010-threat-gate
feat/758-roster-v2-compiler
feat/756-official-discord-plugin
docs/758-fleet-config-management
fix/mos-option2-qualification-format
docs/issue-758-m0
docs/mos-option2-qualification
mos-comms
feat/tess-interaction-agent
fix/tess-docs-format
next
draft/mosaic-platform-prd
fix/installer-provider-gate-and-local-gateway-redis
release/mosaic-cli-0.0.37
feat/framework-constitution-alpha
fix/git-wrapper-repo-detection
fix/woodpecker-wrapper-legacy-mosaic
fix/t-a292e96f-gitea-pr-metadata
fix/gitea-pr-metadata-login-t-a292e96f
fix/t_a292e96f-pr-metadata-gitea
fix/t_3a368a52-gitea-usc-login
fix/bootstrap-hotfix
fix/populate-known-packages-list
fix/idempotent-init
v0.0.39-alpha
mosaic-v0.0.31
fed-v0.2.0-m2
fed-v0.1.0-m1
mosaic-v0.0.29
mosaic-v0.0.28
mosaic-v0.0.27
mosaic-v0.0.26
mosaic-v0.0.25
mosaic-v0.0.24
v0.2.0
v0.1.0
v0.0.8
v0.0.7
v0.0.6
v0.0.5
v0.0.4
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: mosaicstack/stack#961
Reference in New Issue
Block a user
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.
Summary
Add a mechanical precondition to the verification path: before verifying anything that depends on
configuration you just changed, confirm the running process holds that configuration.
This is checkable and judgement-free, so per our own convention it belongs in a hook or a checklist
step, not in guide prose. Filing it because it currently exists only as a post-mortem observation,
and a rule that only fires in the post-mortem is not yet a control.
Evidence: a verified rename that was one scheduled step from certifying a broken state
Measured on 2026-07-30 during a host-identity rename in the wake pipeline. Hostnames abstracted to
HOST_A (the wrong, outgoing label) and HOST_B (the correct one).
The rename touched two things that look like one thing:
wake/beacon-sink.sh, re-read from disk per emit (sh -c "$WAKE_BEACON_SINK_CMD",tools/wake/beacon.sh:262)host_idpayload fieldtools/wake/beacon.sh:222,"${WAKE_BEACON_HOST_ID:-$(hostname)}", resolved from the daemon's environmentmosaic-wake.serviceusesEnvironmentFile=Config on disk was fully renamed at 13:54:29. The daemon had started at 06:57:31 and still held the
old
WAKE_BEACON_HOST_IDin/proc/<pid>/environroughly seven hours later.Consequence: at 13:58:41 the daemon emitted once to the new branch carrying the old payload
label. That mixed state stood on the remote for 4m25s until the next emit overwrote it (parentless
force-push, so the object is now unreachable — the only durable trace was a service-journal line and
a gap in a monotonic counter, 602 -> 604).
An audit of the config directory at 13:57 would have reported the rename complete and correct.
Why a hook and not a guide line
Three agents ran a three-clause witness predicate on this change. Every clause tested the git ref;
the claim under test was about a field inside the payload. The predicate was one scheduled step
from certifying the mixed state — its remaining red clause was slated to be cleared by the
operator's own next action in the agreed sequence.
What actually prevented that was an unrelated question from a peer about whether the units needed
restarting — aimed at the stale-env hazard, not at the predicate. The measurement and the derivation
that followed were deliberate and reproducible from any prompt that put the running process in front
of the operator. Nothing in the system produced that prompt. The gap is a missing precondition,
not missing luck, and that distinction is what makes it fixable cheaply.
Proposed shape
A pre-verification check, roughly:
EnvironmentFile=,--env-file, or an equivalent start-time read (systemd unit, container env, etc.).ActiveEnterTimestamp.restart or reload before verifying.
All three steps are mechanical. No judgement, no domain knowledge, one comparison.
Relationship to existing checks
Complements SC25 rather than duplicating it. SC25 detects premature stopping ("did I stop
because the answer looked done"). This detects never starting ("nothing scheduled the
measurement that mattered"). Between them they cover both ends of the same failure.
Also adjacent to the existing "instruments that lie" family: when N failure modes share one
observable, the observable is not a diagnostic. Here the observable — a correctly renamed config
directory — was shared by "rename complete" and "rename complete but not in effect."
Generalisations worth carrying with the fix