---
name: counter37-update-fetch-ux
description: "counter 37 / v0.18.0 — `spt update fetch` UX (Display-not-Debug + --apply); PR"
metadata: 
  node_type: memory
  type: project
  originSessionId: 8c8eef1f-6837-4fc5-a65f-0633fc292f63
---

Post-v0.17.0 (counter 36 published, main @a8baa23). Operator-surfaced, non-urgent. doyle designed (grounded), todlando built. **PR #40** (branch update-fetch-ux off origin/main, commit 5964c26). Awaiting doyle's joint counter-37 gate; version bump (additive flag = minor, v0.18.0 tentative) is the release PR's, not the fix PR's [[v072-published]].

**Two paired REQs (impl+unit), both in cli.rs cmd_update_fetch:**
- REQ-UPDATE-FETCH-CURRENT-UX: `spt update fetch` printed raw Debug `RejectReason` + exit 1 when the latest was ALREADY STAGED (rollback floor = staged_version → re-fetch rejects as Rollback{current==candidate}). Read as failure when it just needed `spt update apply`. FIX: pure `classify_fetch_reject(reason, applied, staged) → AlreadyStaged|AlreadyApplied|GenuineError`; already-staged/applied → friendly msg + exit 0; genuine → `RejectReason` **Display** (release.rs:387, NOT Debug) + exit 1 at all 3 reject sites (metadata + artifact + plan).
- REQ-UPDATE-FETCH-APPLY-FLAG: `spt update fetch --apply` = one-shot get-to-latest. Reuses `cmd_update_apply()` (no-arg `-> i32`, owns its two-phase + auto-rollback — no factoring needed). Idempotent: new-staged→apply / already-staged(applied<candidate)→STILL apply / already-applied→noop+0 / genuine-error→no-apply+err. clap `--apply` plain-doc (no codes), reference.md regen.

unit = classifier matrix + pure `fetch_reject_action(class, apply)` decision + `--apply` flag parse. product_version surfacing SKIPPED (bare counter; no cheap accessor — doyle "don't over-build").

**GOTCHA (paid): fresh git worktree target lacks the test FIXTURE bins.** `cargo nextest run -p spt --bin spt` in a fresh worktree FAILS `adapter_translate_proof_gates_on_commit` with "translate_proof_fixture must be built ... (run via cargo test -p spt)" — the fixture is a `[[bin]]` (spt/Cargo.toml: translate_proof_fixture, post_step_fixture). FIX: `cargo build -p spt --bins` FIRST (builds the [[bin]] fixtures), then nextest. Not a regression. Also: worktree off origin/main = own target = full recompile (~minutes) + OOM → CARGO_BUILD_JOBS=2. PowerShell tool resets cwd each call → Set-Location every time. Kill worktree-target spt.exe by path before xtask (lock). See [[no-machinewide-killon-shared-runner]] [[release-counter-from-published]].
