Skip to content

fix(statusline): self-heal stale version-pinned path on session start - #49

Merged
SUaDtL merged 2 commits into
mainfrom
fix/statusline-pin-self-heal
Jun 13, 2026
Merged

fix(statusline): self-heal stale version-pinned path on session start#49
SUaDtL merged 2 commits into
mainfrom
fix/statusline-pin-self-heal

Conversation

@SUaDtL

@SUaDtL SUaDtL commented Jun 13, 2026

Copy link
Copy Markdown
Collaborator

What & why

wire-statusline.py writes an absolute, version-pinned path into ~/.claude/settings.json (a plugin can't own a statusLine, and ${CLAUDE_PLUGIN_ROOT} isn't expanded there). Nothing ever re-ran it after a plugin update — so an updated install kept invoking the old version's statusline.py: stale code, and eventually a blank bar once that version's cache dir is pruned. Observed live: an install pinned at 2.0.1 survived three version bumps.

Change

  • wire-statusline.py — new refresh action + refresh_if_stale(). Narrow by design (not install): heals only a ca-owned, changed pin, persists only on a real change (no session-start churn), never touches a third-party statusLine, never wires a fresh line where the user has none, and no-ops if the renderer is missing mid-update.
  • session-start.pyheal_statusline_wiring() called on every SessionStart, before the dormant gate (the statusline is wired globally, so it must heal in every repo, not just arbiter-enabled ones). Fully guarded — corrupt/absent settings.json degrades to a no-op; a wiring refresh can never crash startup.
  • Version 2.1.0-beta.4 → 2.1.0-beta.5 (payload change on a published tag — CI version-bump gate).

Test plan

  • python -m unittest discover -s tests (from plugins/ca/hooks) — 368 pass.
  • .github/scripts/test_hook_guards.py (62/0), test_hooks_cold_install.py (131/0), check-plugin-refs.py (graph intact).
  • New regression coverage: stale-pin heal, no-churn idempotency, third-party untouched, no fresh-wire, missing-renderer guard, bare-string form, loader-failure short-circuit, and a main()-level test that is mutation-verified to fail if the heal call is removed.

Tradeoff (conflict hierarchy)

Heal runs on every SessionStart, including non-arbiter repos — a correctness-over-performance call (L2 over L4): the cost is one settings.json read per session (write only on change), in exchange for the pin self-healing everywhere the global statusline actually runs.

No ADR implemented or contradicted.

SUaDtL and others added 2 commits June 13, 2026 16:17
wire-statusline.py writes an absolute, version-pinned statusline path into
~/.claude/settings.json, but nothing re-ran it after a plugin update — so
updated installs kept invoking the old version's statusline.py: stale, and
eventually a blank bar once that version's cache dir is pruned. SessionStart
now refreshes a codeArbiter-owned pin to the current renderer path, persisting
only on a real change (no steady-state churn), leaving a third-party line
untouched, never wiring a fresh line where none exists, and degrading silently
on any failure (corrupt settings.json included) so a wiring refresh can never
crash startup.

Adds a `refresh` action to wire-statusline.py and heal_statusline_wiring() in
session-start.py, both regression-tested. Version bumped 2.1.0-beta.4 ->
beta.5 (payload change on an already-published tag, per the CI version gate).

CHANGELOG: the statusline now updates itself when the plugin updates, instead
of silently running the old version until it eventually breaks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Closes the coverage gap the coverage-auditor flagged on the self-heal fix:
the actual fix point — heal_statusline_wiring(plugin) called from main()
before the dormant gate — had no test, so every test would have passed even
with that call deleted. Adds a main()-level regression test (dormant repo +
fake HOME) that fails if the heal call is removed (mutation-verified), plus
branch coverage for the missing-renderer guard, a bare-string statusLine, and
the loader-failure short-circuit.

Test-only; rides the unpublished 2.1.0-beta.5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@SUaDtL
SUaDtL merged commit 833f8fa into main Jun 13, 2026
7 checks passed
@SUaDtL
SUaDtL deleted the fix/statusline-pin-self-heal branch June 13, 2026 20:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant