feat(wake): #940 snapshot-datable digests — adapter fd-3 snapshot-metadata channel
ci/woodpecker/pr/ci Pipeline was successful

A digest locator carried observed_hash + emit_ts but nothing DATING the
snapshot, so a consumer could not tell a fresh snapshot from one already
superseded at delivery without a tool call (wake-pilot finding
fw-wake-digest-snapshot-lag: seq 56 rendered "(none)" from a board revision
superseded ~5s before delivery by one adding a FLEET STOP block).

Additive + backward-compatible:
- detector.sh: invoke the W4 source adapter with fd 3 -> temp file; the
  adapter MAY write {"snapshot_sha": "<git commit sha>", "snapshot_ts":
  <epoch>}. Out-of-band is load-bearing: stdout is hashed by the delta
  gate, so an in-band tip-commit sha would advance observed_hash on every
  unrelated push. Metadata is ADVISORY and validated (sha ^[0-9a-f]{7,64}$,
  ts number); malformed metadata drops LOUDLY but never fails the poll or
  suppresses the wake. Valid fields join the enqueue locators. An adapter
  that never writes fd 3 is byte-identical legacy behavior.
- digest.sh: _locator_line renders snapshot_sha=/snapshot_ts= (scrubbed)
  beside observed_hash=; snapshot_sha+path upgrades the actionable-tier
  re-verify hint to one-call `git show <snapshot_sha>:<path>`. With
  emit_ts already in the header, snapshot age is local arithmetic.
- tests: detector D10 (fields land in locators; metadata-only change is
  NOT a delta) + D11 (malformed metadata: loud drop, wake still fires, no
  fields); digest Q10 (orientation dating render, no-vestige sibling,
  actionable re-verify upgrade). manifest 0.6.12; watch-list schema
  untouched ([1,1]); store/reconcile/beacon unchanged.

Closes #940

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NsKce8iZuSuRnu3gVMCBKB
This commit is contained in:
Jason Woltje
2026-07-30 05:13:47 -05:00
co-authored by Claude Fable 5
parent b981b4ec10
commit bb54e09aec
5 changed files with 202 additions and 4 deletions
@@ -445,6 +445,90 @@ EOF
echo "$err" | grep -qi 'range' || fail_msg "D9: the out-of-range failure must still state it is out of the supported range [$err]"
) && ok
echo "== D10: snapshot metadata (fd 3, #940) — adapter-attested sha/ts land in the enqueued locators =="
(
WAKE_STATE_HOME="$(fresh_state d10)"
export WAKE_STATE_HOME
unset WAKE_AGENT
stub="$TMP_ROOT/d10stub"
mkdir -p "$stub"
# Stub adapter that ALSO writes snapshot metadata out-of-band on fd 3.
cat >"$stub/adapter.sh" <<EOF
#!/usr/bin/env bash
set -u
kind="\$1"; id="\$2"
base="$stub/\${kind}_\${id}"
[ -f "\$base" ] && cat "\$base"
[ -f "\$base.meta" ] && { cat "\$base.meta" >&3; } 2>/dev/null
exit 0
EOF
chmod +x "$stub/adapter.sh"
export WAKE_DETECTOR_SOURCE_CMD="$stub/adapter.sh"
wl="$TMP_ROOT/d10.json"
write_watchlist "$wl" 1
export WAKE_WATCH_LIST="$wl"
printf 'SHA-AAA\n' >"$stub/repo_r1"
printf '## LANE-X\ndecision: hold\n' >"$stub/board_file_b1"
printf '{"snapshot_sha":"0123abc4567890def0123abc4567890def012345","snapshot_ts":1753850000}\n' >"$stub/repo_r1.meta"
"$DET" poll-once >/dev/null || fail_msg "D10: baseline pass failed"
printf 'SHA-BBB\n' >"$stub/repo_r1"
"$DET" poll-once >/dev/null || fail_msg "D10: change pass failed"
entry="$("$STORE" drain)"
echo "$entry" | jq -e 'select(.locators.snapshot_sha=="0123abc4567890def0123abc4567890def012345" and .locators.snapshot_ts==1753850000)' >/dev/null \
|| fail_msg "D10: enqueued locators must carry the adapter-attested snapshot_sha + snapshot_ts [$entry]"
# And the metadata must NOT have leaked into the hashed content: an unchanged
# source with CHANGED metadata is still a no-op (delta gate intact).
d0="$(det_seq)"
printf '{"snapshot_sha":"ffff111122223333444455556666777788889999","snapshot_ts":1753860000}\n' >"$stub/repo_r1.meta"
"$DET" poll-once >/dev/null || fail_msg "D10: metadata-only pass failed"
[ "$(det_seq)" = "$d0" ] || fail_msg "D10: metadata is OUT-OF-BAND — a metadata-only change must NOT be a delta, got seq $(det_seq)"
) && ok
echo "== D11: snapshot metadata is ADVISORY — malformed metadata is dropped LOUDLY, the wake still fires, no fields emitted =="
(
WAKE_STATE_HOME="$(fresh_state d11)"
export WAKE_STATE_HOME
unset WAKE_AGENT
stub="$TMP_ROOT/d11stub"
mkdir -p "$stub"
cat >"$stub/adapter.sh" <<EOF
#!/usr/bin/env bash
set -u
kind="\$1"; id="\$2"
base="$stub/\${kind}_\${id}"
[ -f "\$base" ] && cat "\$base"
[ -f "\$base.meta" ] && { cat "\$base.meta" >&3; } 2>/dev/null
exit 0
EOF
chmod +x "$stub/adapter.sh"
export WAKE_DETECTOR_SOURCE_CMD="$stub/adapter.sh"
wl="$TMP_ROOT/d11.json"
write_watchlist "$wl" 1
export WAKE_WATCH_LIST="$wl"
printf 'SHA-AAA\n' >"$stub/repo_r1"
printf '## LANE-X\ndecision: hold\n' >"$stub/board_file_b1"
"$DET" poll-once >/dev/null 2>&1 || fail_msg "D11: baseline pass failed"
# (a) non-JSON garbage on fd 3.
printf 'this is not json\n' >"$stub/repo_r1.meta"
printf 'SHA-BBB\n' >"$stub/repo_r1"
err="$("$DET" poll-once 2>&1 >/dev/null)"; rc=$?
[ "$rc" -eq 0 ] || fail_msg "D11: malformed metadata must NEVER fail the poll (rc=$rc)"
echo "$err" | grep -qi 'snapshot' || fail_msg "D11: dropping malformed metadata must be LOUD on stderr [$err]"
entry="$("$STORE" drain | tail -1)"
echo "$entry" | jq -e '.locators | has("snapshot_sha") or has("snapshot_ts")' >/dev/null 2>&1 \
&& fail_msg "D11: malformed metadata must emit NO snapshot fields [$entry]"
# (b) valid JSON but a non-hex snapshot_sha -> same: loud drop, wake fires, no fields.
printf '{"snapshot_sha":"NOT-A-HEX-SHA","snapshot_ts":"also-not-a-number"}\n' >"$stub/repo_r1.meta"
printf 'SHA-CCC\n' >"$stub/repo_r1"
err="$("$DET" poll-once 2>&1 >/dev/null)"; rc=$?
[ "$rc" -eq 0 ] || fail_msg "D11: rejected snapshot_sha must NEVER fail the poll (rc=$rc)"
echo "$err" | grep -qi 'snapshot' || fail_msg "D11: rejecting a bad snapshot_sha must be LOUD on stderr [$err]"
entry="$("$STORE" drain | tail -1)"
echo "$entry" | jq -e '.locators | has("snapshot_sha") or has("snapshot_ts")' >/dev/null 2>&1 \
&& fail_msg "D11: rejected metadata must emit NO snapshot fields [$entry]"
[ "$(det_seq)" = "2" ] || fail_msg "D11: both real deltas must still have enqueued (advisory metadata never suppresses a wake), got seq $(det_seq)"
) && ok
echo
if [ -s "$FAILFILE" ]; then
echo "wake detector harness: FAILED ($(grep -c . "$FAILFILE") assertion(s))" >&2