---
name: v0280-published
description: v0.28.0 PUBLISHED (counter 48 @0639b12) — JOIN-TRUTH; bump-ON-milestone-branch pattern; clean no-stall cut; strum-0.28.0 darling-class collision avoided
metadata: 
  node_type: memory
  type: project
  originSessionId: 5b3a2381-5e45-4f9a-8543-4c5f5009c468
---

**v0.28.0 PUBLISHED + PUBLIC 2026-07-07T02:17:55Z — counter 48, tag on blessed bump commit 0639b12, Latest on SaberMage/spt-releases.** Milestone: JOIN-TRUTH (W1 ceremony-clock NTP truth D1-D3 @39c1eb9 + v4-first follow @9aea594; W2 deferred elevation + verbose ceremony clock @893f06d; off main@47efdaf, PR #56). Signed rel-primary-2026, update-set v48.

- linux   sha256: 2a6cfa210867a5208a131acdabe2507a17bb79318c40badc6c8d34968dcc0ef7
- windows sha256: 502ef7eb245752171228b76bb11af2bb0670278ec47f007770c55553de2e03e2

**Adapter floor for next claude-spt = 0639b12.**

**RELEASE-DRIVE (banked):**
- BUMP-ON-MILESTONE-BRANCH pattern (vs separate release branch): join-truth was NOT pre-merged — doyle GO said "author the bump ON the branch", so the milestone PR #56 IS the release PR (runbook's "feature PR's final commit" path). Added bump commit 0639b12 onto join-truth tip 893f06d, pushed to the SAME branch, existing/opened PR to main carried waves+bump together. FF-merge `git push origin origin/join-truth:main` (5 ahead, 0 behind), tag on 0639b12.
- DARLING-CLASS COLLISION AVOIDED: NEW version 0.28.0 coincides with third-party strum/strum_macros. `grep -c 'version = "0.28.0"'` read 13 AFTER sed (11 first-party + 2 strum) — momentarily alarming, but SAFE because sed keyed on the OLD version `0.27.0→0.28.0` and no third-party was at 0.27.0; strum stayed put (doyle's diff-verify: strum untouched). LESSON REINFORCED: always replace by OLD version string, never assert on NEW-version count (a third-party dep can already sit at your new semver). Verify `remaining OLD = 0` as the real check.
- CHANGELOG 5 surfaces (doyle pre-shared census + a 5th he added: --verbose failure block carries daemon-side joiner clock / meet_failure_detail). doyle scope-gate FIRST-PASS PASS (no revisions) — the pre-shared census meant I scoped it right the first time. Command names verified from clap before wording: `spt subnet join`, `--verbose`, `--code`. Tokens grepped live: `NTP_TOTP_UNCORRECTED: all NTP servers unreachable — ceremony clock = raw system clock` (ntp.rs), verbose `ceremony clock: TOTP step N, offset +Ns, NTP-corrected|UNCORRECTED`.
- reference.md EOL-only drift (CRLF) discarded again — standard for any CLI-touching milestone on Windows gen.
- CLEAN publish: no EPERM recurrence, no flake. Applied v0.27.0 lesson — on release.yml status=completed I DIRECT-polled `gh release view isDraft` and published immediately, zero flip stall (the ~45min v0.27.0 dropped-watcher stall did NOT repeat).

Ledger: 44=v0.24.0, 45=v0.25.0, 46=v0.26.0, 47=v0.27.0, 48=v0.28.0.

**POST-FLIP (doyle):** docs commit @4406218 (flynn filing #6: api stderr-status/poll-auth/ONLINE-badge contract — held during the release freeze) pushed to main after the FF; docs-publish 28836883923 dispatched, flynn notify on verify. Enlyzeam BIGNET join FIELD-CLOSED mid-gate (2 nodes) — the incident that seeded JOIN-TRUTH is done end-to-end. Gate-arc gotchas (full list in [[join-truth-build-progress]]): hfenduleam bg-task killer recurred (gate suites foreground-staged now); pkill -f over ssh self-kills when the pattern matches the remote cmdline (explicit pids); kitsubito runs spt 0.6.0 under systemd user spt-daemon.service with a 7-day-stalled pump (operator update pass owed); HFENDULEAM still core 0.25 + adapter 0.14.3 pinned — operator bounce window pending (perri five-proof).
