fix(update-check): passive Git safety and bounded shallow counts - #83181
fix(update-check): passive Git safety and bounded shallow counts#83181alexgunsberg wants to merge 7 commits into
Conversation
Supersedes closed NousResearch#83163 safety BLOCK and integrates NousResearch#82658 structured update facts so the patches cannot overwrite each other. Passive update checks now: - never unlink shallow.lock / index.lock / HEAD.lock / packed-refs.lock - use absolute --depth TARGET (not relative --deepen) when tips differ - short-circuit equal tips via ls-remote so repeated checks cannot grow - trust FETCH_HEAD only after a successful fetch in the current call - preserve linked-worktree common-dir writable probes and argv-only git Also surfaces backend update failures truthfully (error_code, repo_writable, check_for_updates_details) for Dashboard/Desktop.
|
Release follow-up at exact head |
|
Correction follow-up at new exact head |
|
Final correction follow-up at exact head |
|
Final exact head |
|
Final exact head |
|
Final exact head |
|
Final review follow-up pushed at exact head This restores Verification at this exact head: 72 update-focused tests passed; Ruff passed; |
|
Independent exact-head review: PASS Reviewed head: 5a7de73 Evidence:
This accepts the candidate only. Merge remains with the normal release/branch-policy owner; no admin bypass or deploy is authorized by this comment. |
Merge-ready evidence (contributor lane; blocked on maintainer gates)PR: #83181 Already verified offline (Kanban t_0300b15f)
Live GitHub gates (cannot satisfy from contributor identity
|
| Gate | Observed | Blocker |
|---|---|---|
Required check All required checks pass |
No successful rollup; latest CI run 31399321703 conclusion=action_required |
Fork workflow approval needs repo admin (403 Must have admin rights) |
| Merge / auto-merge | mergeStateStatus=BLOCKED; merge/auto-merge denied |
No push/write on NousResearch/hermes-agent |
| Admin bypass | Not attempted | Policy forbids |
Maintainer unblock (normal path, no force, no admin bypass of protection)
- Approve fork workflow runs for head
5a7de73a350512c27e59ec727d8341471ad8015f(CI run31399321703, Docker31399324265or equivalent fresh PR runs). - Wait for required check All required checks pass = success.
- Merge with normal merge commit (or repo default). Prefer not squash unless intentional.
Out of scope / left alone
- Did not touch PR fix(gateway): classify real token locks and keep lifecycle running #83183
- Obsolete duplicate routes already CLOSED: fix(update-check): recover shallow behind counts safely #83164, fix(update-check): recover shallow behind counts safely #83163, fix(updates): report backend update failures truthfully #82658
- No gateway restart/deploy from this lane (merge-only)
Kanban owner card: t_058dfff3
|
Heads-up: PR #86257 (merged, bf10349) landed the behind-count class fix — no surface fabricates "1 commit behind" anymore, and shallow/ls-remote-only checks now recover the exact count via the GitHub compare API. That overlaps the count-integrity part of this PR. The parts NOT covered by #86257 and still unique here: git-stderr classification (ownership/permission/lock/offline error codes), the passive-safety contract (never unlink locks, absolute --depth target instead of repeated --deepen, never trust stale FETCH_HEAD), and the web_server/dashboard surfacing. If you'd like, rebase onto current main and rescope this PR to those safety pieces — they're worth reviewing on their own. |
|
Thanks @alexgunsberg — this was solid work on a real symptom. Superseded on main by the Aug 14 update-status wave: exact behind-counts are now recovered via the GitHub compare API in both the CLI banner and the desktop (PR #86257, |
Summary
Shallow candidate/worktree installs were stuck at
behind=-1(Desktop badge(update)instead of(+N)). Closed #83163 attempted lock recovery + deepen but was BLOCKed for three safety defects. This v2 fix addresses behind-counts without those hazards, and intentionally integrates open #82658 structured backend update facts so the two patches cannot overwrite each other.Safety contract (v2)
shallow.lock,index.lock,HEAD.lock, orpacked-refs.lock. Lock recovery belongs only in explicit quiescent maintenance.ls-remote(no fetch/depth growth). When tips differ, recovery uses absolutegit fetch --depth <TARGET>(idempotent), never relative--deepenon every cache expiry.FETCH_HEADfails closed to ls-remote /UPDATE_AVAILABLE_NO_COUNT/ error — never trusts leftover tips.UPDATE_AVAILABLE_NO_COUNTfallback otherwise._git_run/ fetch-result /check_for_updates_details/ ownership-safe read-only probes / Dashboarderror_code+repo_writable/can_apply.Overlap disposition
Test plan
Exact head verification:
Acceptance coverage includes real
file://shallow clones (repeated equal-tip no-deepen), old-but-liveshallow.locknever unlinked, lock replacement race (no unlink helper), failed fetch + stale FETCH_HEAD, real shallow linked worktree/common-dir, absolute depth idempotence, ownership/ls-remote fallback, and Dashboard error_code/can_applycontracts.Do not deploy before independent review PASS.