Skip to content

fix(selfhost): distinguish missing-ref and detached-HEAD errors in update script - #4158

Merged
JSONbored merged 1 commit into
mainfrom
fix/selfhost-update-error-precision-4156
Jul 8, 2026
Merged

fix(selfhost): distinguish missing-ref and detached-HEAD errors in update script#4158
JSONbored merged 1 commit into
mainfrom
fix/selfhost-update-error-precision-4156

Conversation

@JSONbored

@JSONbored JSONbored commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Summary

Precision follow-up to #4151 (merged; #1660 itself is done). While that PR was open, the Gittensory Orb
review flagged 7 non-blocking nits (readiness 100/100, no blockers, held only because it touched
guarded paths). #4151 got merged by a separate verification pass before I finished triaging those
nits, so this PR carries the two genuinely worth fixing, now tracked under #4156 since issue #1660 already shows CLOSED
already closed:

  1. Imprecise ff-only error. scripts/selfhost-update.sh's git merge --ff-only failure path
    printed the same "local history has diverged" message for two different causes: a real
    non-fast-forward divergence, and a bad SELFHOST_UPDATE_BRANCH/SELFHOST_UPDATE_REMOTE override
    pointing at a ref that doesn't exist at all (git merge --ff-only <bad-ref> fails the same way
    either way). Added git rev-parse --verify --quiet "$REMOTE/$BRANCH" right after the fetch so a
    missing ref gets its own distinct, actionable error instead of being misreported as a divergence.
  2. Confusing detached-HEAD message. current_branch="$(git rev-parse --abbrev-ref HEAD)"
    literally returns the string HEAD in a detached checkout, so the existing branch-mismatch
    error read "currently on 'HEAD', expected 'main'" and suggested a nonsensical
    SELFHOST_UPDATE_BRANCH=HEAD override. Detached HEAD now gets its own message.

Also fixed, alongside those two: an inaccurate comment on the .gitignore tracked-file-shadowing
test (test/unit/docs-selfhost-git-deploy-hygiene.test.ts) claiming a tracked file matching the new
*.bak-*/*.backup-* patterns would get "silently untracked... the moment someone re-clones" —
verified empirically (scratch repo: track a file, add a matching ignore pattern, modify it, git add -A) that .gitignore has no effect on already-tracked files at all; the modification still
staged normally. The real risk runs the other way: a new file matching the pattern would be
silently excluded from git status's untracked list and from git add -A/git add ., so it could
go uncommitted without anyone noticing. Corrected the comment to describe that mechanism instead.

Closes #4156.

Scope

  • The PR title follows type(scope): short summary Conventional Commit format, for example fix(api): restore profile access checks.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked a currently open issue this PR resolves (Closes #4156).

Validation

  • git diff --check
  • npm run actionlint (no workflow files touched; ran anyway as part of the full gate)
  • npm run typecheck — clean
  • npm run test:coverage locally — 587 test files passed / 2 skipped, 11982 tests passed / 7 skipped, unsharded. No src/**/packages/** lines changed (only scripts/**, test/**), so no new Codecov codecov/patch obligation — ran it anyway to confirm nothing broke.
  • npm run test:workers
  • npm run build:mcp
  • npm run test:mcp-pack
  • npm run ui:openapi:check
  • npm run ui:lint
  • npm run ui:typecheck
  • npm run ui:build
  • npm audit --audit-level=moderate — 0 vulnerabilities
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries — two new real-execution cases added to test/unit/selfhost-update-script.test.ts:
    • a checkout in a detached HEAD state gets the new distinct message, not the generic branch-mismatch one;
    • SELFHOST_UPDATE_BRANCH naming a branch the remote doesn't have gets the new "does not exist after fetching" message, distinct from the fast-forward-divergence message.
      20/20 passing (the 8 pre-existing cases plus the 2 new ones).

If any required check was skipped, explain why:

  • Ran the full npm run test:ci gate end-to-end (all steps green, including test:engine-parity,
    db:migrations:check, db:schema-drift:check, selfhost:env-reference:check,
    selfhost:validate-observability, cf-typegen:check, rees:test, ui:openapi:settings-parity,
    ui:version-audit, docs:drift-check, manifest:drift-check, command-reference:check,
    ui:test) beyond just the boxes above.
  • Did not run the gittensory-mcp pre-submit predictors: same as chore(selfhost): script git-backed self-host updates, ignore stray backups #4151, they need an interactive
    GitHub device-flow login this session can't complete, and as the repo owner this PR is held for
    manual merge rather than auto-closed on an adverse gate signal.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests. (N/A — no such changes.)
  • API/OpenAPI/MCP behavior is updated and tested where needed. (N/A — no such changes; ui:openapi:check confirms no drift.)
  • UI changes use live API data or real empty/error/loading states, not production mock/demo fallbacks. (N/A — no UI changes in this PR at all, only scripts/** and test/**.)
  • Visible UI changes include a UI Evidence section below with JPG/JPEG or PNG screenshots arranged as organized, captioned, clickable thumbnails. SVG screenshots are not used as review evidence. Review-only screenshots or recordings are not committed to the repository. (N/A — no UI/docs route touched by this PR.)
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs.

UI Evidence

Not applicable: this PR only touches scripts/selfhost-update.sh and its test files — no UI, docs
route, or other visible surface.

Notes

  • Root cause of why this is a separate PR rather than a chore(selfhost): script git-backed self-host updates, ignore stray backups #4151 follow-up commit: I was mid-triage on
    the Orb's 7 nits (verifying which were real before pushing anything) when a separate verification
    pass merged chore(selfhost): script git-backed self-host updates, ignore stray backups #4151 out from under the branch. Rather than push dangling commits to a closed PR's
    branch, cut a fresh branch off the post-merge origin/main tip, cherry-picked the one commit that
    carried genuine fixes, opened polish(selfhost): sharpen selfhost-update.sh error precision #4156 to track it (since issue build(selfhost): make host deploys Git-backed and image-ready #1660 already shows CLOSED and a linked open
    issue is required), and rebased/re-verified the full gate against the new base before pushing.
  • Verified empirically, not asserted: the .gitignore-doesn't-untrack claim above was checked in a
    disposable scratch git repo (track a file → add a matching ignore pattern → modify the file →
    git add -A → confirm it still stages) before rewriting the comment, rather than trusting either
    the original (wrong) comment or the review's suggested rewording at face value — the suggested
    rewording ("git add -A would silently skip the file going forward") turned out to also be
    imprecise for an already-tracked file, so the final comment states the mechanism for a new
    file instead, which is what the test's git ls-files check actually guards against.

…date script

selfhost-update.sh's ff-only merge failure previously printed the same
"diverged history" message for two unrelated causes: a genuine
non-fast-forward divergence, and a bad SELFHOST_UPDATE_BRANCH/
SELFHOST_UPDATE_REMOTE override pointing at a ref that doesn't exist at all
(git merge --ff-only fails the same way for both). Add an explicit
`git rev-parse --verify` check right after the fetch so a missing ref gets
its own distinct, more actionable error instead of being misreported as a
divergence. Also give a checkout in a detached HEAD state (where
`git rev-parse --abbrev-ref HEAD` literally returns "HEAD") its own message
instead of the generic branch-mismatch one, which read oddly ("currently on
'HEAD', expected 'main'") and suggested a nonsensical
SELFHOST_UPDATE_BRANCH=HEAD override.

Also fix an inaccurate comment in
test/unit/docs-selfhost-git-deploy-hygiene.test.ts's tracked-file-shadowing
test: .gitignore has no effect on files git already tracks (verified: `git
add -A` still stages a modification to an already-tracked-but-now-ignored
file). The real risk the test guards against is the opposite direction -- a
future PR adding a genuinely new tracked file whose name happens to match
the pattern would have it silently excluded from `git status`'s untracked
list and from `git add -A`/`git add .`, not "untracked on reclone" as the
comment previously and incorrectly claimed.

Add test coverage for both new error paths (detached HEAD, and
SELFHOST_UPDATE_BRANCH naming a branch the remote doesn't have) to
selfhost-update-script.test.ts.

Both nits were flagged by the Gittensory Orb review on #4151 (merged).

Closes #4156
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.73%. Comparing base (f5c5c52) to head (f19a3cb).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4158   +/-   ##
=======================================
  Coverage   93.73%   93.73%           
=======================================
  Files         386      386           
  Lines       36304    36304           
  Branches    13298    13298           
=======================================
  Hits        34029    34029           
  Misses       1618     1618           
  Partials      657      657           
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 8, 2026
@loopover-orb

loopover-orb Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Warning

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-08 08:39:43 UTC

3 files · 1 AI reviewer · no blockers · readiness 100/100 · CI green · clean

⏸️ Suggested Action - Manual Review

  • Touches a guarded path — held for manual review: This PR changes guardrail-protected path(s): scripts/selfhost-update.sh (matched scripts/**).

Review summary
This is a narrow, well-scoped follow-up to #4151/#1660 that fixes two genuinely-verified selfhost-update.sh error-message bugs: a detached-HEAD checkout previously produced a nonsensical 'currently on HEAD, expected main' message with a useless SELFHOST_UPDATE_BRANCH=HEAD suggestion, and a bad/typo'd SELFHOST_UPDATE_BRANCH or SELFHOST_UPDATE_REMOTE pointing at a nonexistent ref was misreported as a history-divergence rather than a missing-ref error. Both guards are placed at the correct source point (right after computing current_branch, and right after the fetch/before the ff-only merge) and are traceable to real, reachable failure paths rather than can't-occur conditions. The two new tests in selfhost-update-script.test.ts exercise the real script against a live git sandbox (actual detached HEAD via `git checkout --detach`, an actual local branch with no upstream counterpart) rather than fabricating state, and each asserts the new message is present and the old/wrong message is absent.

Nits — 6 non-blocking
  • The rewritten comment in test/unit/docs-selfhost-git-deploy-hygiene.test.ts (docs-selfhost-git-deploy-hygiene.test.ts:34-42) is fairly long for a non-normative aside; consider trimming to the one or two sentences that matter (gitignore doesn't untrack existing files; the real risk is new matching files silently skipped by broad `git add`).
  • The PR description asserts this is tracked under polish(selfhost): sharpen selfhost-update.sh error precision #4156 but the diff itself doesn't show an issue link/closing keyword — worth confirming the PR is actually linked to polish(selfhost): sharpen selfhost-update.sh error precision #4156 in GitHub metadata, not just referenced in prose.
  • Consider also covering the case where SELFHOST_UPDATE_REMOTE itself is bogus (not just the branch) in selfhost-update-script.test.ts, since the new `git rev-parse --verify --quiet "$REMOTE/$BRANCH"` guard covers both variables but only the branch-typo path is currently tested.
  • scripts/selfhost-update.sh:69's error message could mention that `git fetch` succeeding doesn't guarantee the branch exists on that remote — the current wording already does this reasonably well, so this is optional polish only.
  • PR author also opened the linked issue — Link an issue that was opened by a different contributor, or provide a rationale for why this self-authored issue represents genuine discovery work.
  • Touches a guarded path — held for manual review — A maintainer must review and merge this change.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #1660, #4156
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (2 linked issues).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 52 registered-repo PR(s), 43 merged, 486 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 52 PR(s), 486 issue(s).
Gate result ⚠️ Not blocking Advisory; not blocking this PR.
Linked issue satisfaction

Not yet addressed
This PR only refines error messages in scripts/selfhost-update.sh (distinguishing detached-HEAD and missing-ref failures) plus a doc comment fix; it does not touch any of the issue's actual asks around Git-backed host deployment, override isolation, rollback snapshotting, compose/readiness verification, or AI CLI image build support.

Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, TypeScript, JavaScript, Ruby, Go, Kotlin, MDX, Shell
  • Official Gittensor activity: 52 PR(s), 486 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Treat this as maintainer-lane context rather than normal contributor-lane activity.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 8, 2026
@JSONbored
JSONbored merged commit ab57363 into main Jul 8, 2026
11 checks passed
@JSONbored
JSONbored deleted the fix/selfhost-update-error-precision-4156 branch July 8, 2026 08:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

polish(selfhost): sharpen selfhost-update.sh error precision

1 participant