Skip to content

board: every evidence gap carries the check that closes it - #177

Merged
Jammy2211 merged 1 commit into
mainfrom
claude/pyautoheart-stale-r4swxg
Aug 25, 2026
Merged

board: every evidence gap carries the check that closes it#177
Jammy2211 merged 1 commit into
mainfrom
claude/pyautoheart-stale-r4swxg

Conversation

@Jammy2211

Copy link
Copy Markdown
Contributor

A STALE board offered nothing copyable that closed a gap: every stale reason got the same /health re-run the stale evidence: <text> string, and a reason row carried no command on any surface (commands existed only on section rows). STALE is the board's steady state — STALE · score 65 on every heart-health.yml run since 2026-08-19 — so that is most of what the board is asked to do.

What changed

  • heart/readiness.pycompute emits stale_details: each stale reason with the gate key that produced it (install_unknown, validation_absent, …), index for index with stale_reasons. Additive; the flat reason lists, the verdict, the score, the profiles and the release gate are untouched (tests/test_readiness.py passes unmodified). Internally the stale.append(...) / hit(...) pairs became one add_stale(msg, key) helper, so a gap cannot be filed without its key or its penalty.
  • heart/dashboard.pySTALE_REMEDIES maps that key to the check that closes the gap. A stale row gains command (the shell remedy, None where the remedy needs a conversation) and a prompt that names both the check and the gap. The tier gains stale_plan: one prompt walking every current gap, plus the shell chain that does the same — offered only when every gap has a command, since a chain that silently skips one reads as if it cleared it.
  • heart/fix.py + bin/pyauto-heartpyauto-heart fix stale: the same payloads in a terminal, from the same persisted verdict, so the two surfaces cannot prescribe different things. readiness now ends a stale block with → clear them: pyauto-heart fix stale.

Per surface: html renders a ⌨ command chip beside the 📋 prompt chip and a "clear them all" line above the gaps; md leads its prompts block with the plan; json carries blockers[].command and stale_plan (schema v3, additive).

Invariants held

  • Every remedy re-runs a check; none touches code. A stale row can never emit a /bug prompt — asserted in the tests.
  • Remedies are looked up by gate key, never sniffed from the reason text. A reason with no key (a verdict from an older Heart) falls back to the generic nudge, and no plan is offered, rather than a guessed remedy.
  • Observer-only: the Heart still never dispatches a rehearsal, so the release-validation gaps carry a prompt (/release rehearse) and no command.

Deliberately not done

  • The README strip stays one line for STALE — test_md_brief_is_one_line_unless_something_is_wrong pins that on purpose, and a glance surface is the wrong place for a multi-step plan.
  • skew_pypi_unknown carries a prompt but no command: the deep PyPI leg has no pyauto-heart verb, and inventing one would have been a fake remedy.

Testing

pytest tests/ -q → 615 passed (8 new dashboard tests, 3 new readiness tests). Rendered a synthetic cloud snapshot end to end: it reproduces the live STALE · score 65 with the three current gaps, and pyauto-heart fix stale prints their commands and the one plan.

The Brain-side consumer is PyAutoLabs/PyAutoBrain#(companion branch claude/pyautoheart-stale-r4swxg); a Brain board reading an older Heart surface renders exactly as before.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WY6Q2fZquoDQijLD6PXtAT


Generated by Claude Code

A STALE board offered nothing copyable that closed a gap: every stale
reason got the same "/health re-run the stale evidence: <text>" string,
and a reason row carried no command on any surface. STALE is the board's
steady state, so that is most of what the board is asked to do.

Readiness now emits `stale_details` — each stale reason with the gate key
that produced it (additive; the flat reason lists, the verdict, the score
and the release gate are untouched). The dashboard keys a remedy table off
that: a stale row gains `command` (⌨ on html) beside a prompt that names
the check AND the gap, and the tier gains `stale_plan` — ONE prompt that
walks every current gap, plus the shell chain that does the same when
every gap has a command (withheld when one needs a rehearsal, since a
chain that skips a gap reads as if it cleared it). `pyauto-heart fix
stale` is the terminal door to the same payloads, and `readiness` now
points at it.

Every remedy re-runs a check; none touches code — a stale row can never
emit a /bug prompt. A reason with no key (an older verdict) falls back to
the generic nudge rather than a guessed remedy. json goes to schema v3.

The README strip stays one line for STALE, as its test asks.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WY6Q2fZquoDQijLD6PXtAT
@Jammy2211
Jammy2211 merged commit 6235a48 into main Aug 25, 2026
2 checks passed
@Jammy2211
Jammy2211 deleted the claude/pyautoheart-stale-r4swxg branch August 25, 2026 15:52
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.

2 participants