Skip to content

feat: test-performance board — CI wall-clock, hang events, NO_RUN census #163

Description

@Jammy2211

Overview

Development speed tracks test speed, and today knowing what is slow takes a manual archaeology session over CI job logs. This task builds the standing surface: a ⏱ Performance section on the Heart board showing run times of the testing/integration infrastructure (PR smoke gates, unit-test gates, weekly Workspace Smoke, Nightly Release), with history to flag drops, kill-timer/hang events surfaced, and the NO_RUN census with reasons — every actionable row carrying its own one-tap Claude prompt. The Brain board consumes the published block verbatim as a headline row (the existing heart_blockers contract).

Full design rationale with receipts: PyAutoMind/docs/pyautoheart/test_performance_board_assessment.md. Mind prompt: active/test_performance_board.md.

Plan

  • Add two cloud-safe Heart checks: ci_timing (Actions-API wall-clock scrape of the tracked gates — durations, queue delay, conclusion mix, cancelled/timed-out disambiguation) and no_run_census (parse each workspace's config/build/no_run.yaml; SLOW/NEEDS_FIX/permanent tiers, marker age, unmeasured-SLOW flagging).
  • History via the self-carrying published-artifact roll-forward (previous board.json fetched at render, today appended, capped) — no commit noise.
  • Two new dashboard sections + an additive performance block in board.json (schema v2 stays additive); rows carry their own /bug prompts.
  • Wire both checks into heart-health.yml's daily cloud run (not the <30s tick).
  • Brain board: a "⏱ Test performance" section consuming the published block verbatim; hang events count as attention in the verdict.
  • Advisory only: the GREEN/STALE/YELLOW/RED readiness verdict is untouched.
Detailed implementation plan

Affected Repositories

  • PyAutoHeart (primary)
  • PyAutoBrain (board consumer)
  • PyAutoMind (prompt lifecycle + assessment doc, already pushed)

Branch Survey

Repository Current Branch Dirty?
./PyAutoHeart main → claude/test-performance-dashboard-y3fdy7 clean
./PyAutoBrain claude/test-performance-dashboard-y3fdy7 (= main) clean
./PyAutoMind claude/test-performance-dashboard-y3fdy7 pushed

Branch: claude/test-performance-dashboard-y3fdy7 (all three repos)

Implementation Steps

  1. heart/checks/ci_timing.{sh,py} — per polled repo, gh api repos/<owner>/<name>/actions/runs?per_page=50 (PR runs included); durations from run_started_atupdated_at (never created_at); success-only medians per required workflow (+ performance: extra_workflows in config/repos.yaml: Workspace Smoke, Nightly Release); cancelled runs disambiguated (superseded-by-newer-same-branch = benign; on main or successorless = suspect event; timed_out always an event); per-repo sidecars + an aggregate $HEART_STATE_DIR/ci_timing.json that rolls history forward from the previously published board.json (dedupe by date, capped).
  2. heart/checks/no_run_census.{sh,py} — contents-API fetch of config/build/no_run.yaml per workspace-group repo; line-based parse (comments carry the markers; a bare off entry must not crash as a YAML boolean); SLOW rows flagged measured: false when the reason carries no real seconds figure (a bare "1800s cap" mention is not a measurement); 404 recorded honestly as present: false.
  3. heart/state.py — aggregate the two new global keys.
  4. heart/dashboard.py — "CI wall-clock" and "NO_RUN census" sections (cloud-observed, not in LOCAL_ONLY_FAMILIES; events → FAIL state, drift → WARN, both advisory); Board.performance emitted in to_dict as the performance block; sparkline helper for gate history.
  5. config/repos.yamlperformance: block + thresholds: ci_timing: {yellow_factor: 1.5, min_delta_s: 120, history_cap: 30} (drift flags only on ratio AND absolute floor — the profiling-conductor doctrine).
  6. .github/workflows/heart-health.yml — run both checks in the cloud-safe step.
  7. PyAutoBrain board/_board.py — one Heart board.json read serves blockers + performance; ⏱ Test performance section rendering flagged rows' prompts verbatim; events counted as attention.
  8. Tests both sides (stdlib+PyYAML, hermetic fixtures, tenant-firewall-clean).

Key Files

  • heart/checks/ci_status.{sh,py} — the API-safe check shape being mirrored
  • heart/dashboard.py — the one unified renderer (sections, blockers, html 📋 buttons)
  • .github/workflows/heart-health.yml — the daily cloud render + Pages publish
  • PyAutoBrain/board/_board.pyfetch_heart_blockers consumer contract + _row chips

Out of scope (phased separately)

  • Phase 0 prerequisite (separate PR): draft/bug/pyautoheart/script_timing_baselines_orphaned_and_window_filled.md — orphaned slugs / single-observation windows in script_timing.
  • Phase 2 (PyAutoHands): per-script smoke_timings.json from the delegated runner — the standing dataset answering item 4 of draft/research/ci/smoke_timing_and_profiling.md.

Original Prompt

Click to expand starting prompt

Test-performance section on the Heart board — run times, hangs, NO_RUN, with one-tap fix prompts

Type: feature / Target: pyautoheart / Repos: @PyAutoHeart @PyAutoHands @PyAutoBrain
Difficulty: large / Autonomy: supervised / Priority: high / Filed: 2026-08-24

Development speed tracks test speed, and today knowing what is slow takes a manual archaeology session over CI job logs. Build the standing surface: a ⏱ Performance section on the Heart board that always shows the run times of the testing/integration infrastructure — PR smoke gates (*_workspace_test, normal workspaces, HowTo), unit-test gates, weekly workspace-smoke, the nightly release driver, import time — with enough history to flag drops, kill-timer/hang events surfaced, the NO_RUN census with reasons, and a one-tap Claude prompt on every row so "speed this up" is a paste.

Full design rationale, data-plane analysis, chip payloads, and the trap list: docs/pyautoheart/test_performance_board_assessment.md in PyAutoMind.

Acceptance:

  • The Heart board page shows, per tracked gate: latest duration, p50/max over the window, trend sparkline, conclusion mix, coverage count — refreshed on the Heart's existing render cadence with no commit noise.
  • A hang/kill event (per-script TIMEOUT, unexplained cancelled, aborted summary) appears within one render, red, with a /bug … — <run url> chip.
  • Every SLOW/NEEDS_FIX no_run.yaml entry is listed with marker age, reason, and a re-measure-first fix chip; unmeasured SLOW markers are visibly flagged.
  • The Brain board carries the headline row consuming the published block verbatim.
  • Nothing gates: readiness verdict and badge.json message shape unchanged.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions