You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
workspace-validation.yml mode=release currently conflates correctness and perf-flakiness into a single RED. After the 2026-07-13 tail burn-down (PyAutoHeart#72) fixed every real bug, the integrate stage still can't reach a clean verdict because a population of genuinely-slow real-search scripts (real Nautilus fits + finite-difference JAX gradients) flakes around the per-script timeout cap — the failing set shifts every run (shared_preloads literally flip-flopped between re-val #3 and #4). Raising the cap and adding no_run SLOW-skips one script at a time never converges and erodes coverage.
This introduces an advisory tier: a timeout on a declared-slow script is downgraded to YELLOW (loud, tracked), while a timeout on any undeclared script stays RED. This is the path that lets mode=release reach its normal shippable GREEN/YELLOW once the real bugs are fixed, instead of being held hostage by the perf tail.
Plan
Add a companion config/build/advisory.yaml per workspace — same flat-list + inline-comment format as no_run.yaml, but the listed scripts still run and report; only their timeouts are advisory. Growing this list never erodes coverage, so it converges where SLOW-skips whack-a-mole. Absent file → today's behaviour exactly.
Build (runner mechanism): a new TIMEOUT_ADVISORY result status; the runner tags a timeout as advisory when the script matches advisory.yaml; has_failures / aggregate ready exclude advisory timeouts; a non-advisory timeout still fails the run.
Heart (policy): the stage report and validation_report carry an advisory_timeouts count; readiness maps advisory_timeouts > 0 to a YELLOW reason (not RED), keeping the release GREEN→YELLOW rather than RED-blocked.
Keep it loud: advisory timeouts surface in the aggregate report, the CI step summary, and Heart's YELLOW reasons — a tracked backlog, with durable speedups owned by the Profiling Agent.
autobuild/run_python.py — load config/build/advisory.yaml (workspace override → empty default, mirroring the no_run.yaml resolution), parse its reasons, thread advisory_list/advisory_reasons into execute_scripts_in_folder.
autobuild/build_util.py — in execute_script (and execute_notebook for symmetry), on subprocess.TimeoutExpired, if the file matches advisory_list (reuse should_skip path semantics) record TIMEOUT_ADVISORY with the advisory reason instead of TIMEOUT.
autobuild/aggregate_results.py — timeout_advisory is not in the failure set (so ready is unaffected); add an advisory_timeouts list + a loud "## Advisory-Tier Timeouts (slow real-search; not release-blocking)" markdown section. A non-advisory timeout still flips ready=false.
PyAutoHeart (policy):
5. heart/validate.py — to_stage_report carries advisory_timeouts (count + entries) from the aggregate into the stage report (NOT folded into failures); _Accumulator + report schema sum it into the top-level validation_report; status still derives from aggregate.ready. Bump the schema docstring.
6. heart/readiness.py — in the release-validation gate, when the report has advisory_timeouts > 0, append a YELLOW reason ("N advisory-tier script timeout(s) in release validation (slow real-search; not release-blocking)") + hit("validation_advisory_timeout") with a _SCORES entry. This turns a correctness-clean run GREEN→YELLOW instead of RED.
7. .github/workflows/workspace-validation.yml — comment the tier; echo the advisory-timeout count into $GITHUB_STEP_SUMMARY. No gate-logic change (already keys off ready).
8. docs/release_validation.md — document the advisory tier and the # ADVISORY <date> - reason marker convention.
config/build/advisory.yaml (new, per *_test workspace) — the declared-slow registry
Design notes
advisory.yaml vs a duration threshold: an explicit list is reviewable and stable; a duration threshold would re-capture exactly the borderline near-cap scripts that flip-flop. Chosen: explicit list.
Advisory downgrades timeouts only — a genuine FAILED (exception) on an advisory script stays RED, preserving the correctness signal.
mode=release should tier slow real-search scripts as advisory, not RED-block on the perf tail
Type: feature
Target: PyAutoHeart
Repos:
PyAutoHeart
PyAutoBuild
Difficulty: medium
Autonomy: supervised
Priority: high
Status: formalised
The 2026-07-13 release-validation burn-down (PyAutoHeart#72) fixed every real
correctness bug in the tail (A–H + the jax_grad config gap). But the workspace-validation.yml mode=release integrate stage still cannot reach a clean
verdict, because it runs the FULL script set — including a population of genuinely
slow real-search scripts (PYAUTO_TEST_MODE=0/1 real Nautilus fits +
finite-difference JAX gradients) that flake around the per-script timeout cap. The
failure set shifts run to run:
Raising BUILD_SCRIPT_TIMEOUT (300→1800) and adding no_run SLOW-skips one script at
a time does not converge — each run surfaces a different handful of borderline
scripts, and de-gating them individually is whack-a-mole that also erodes coverage.
The structural problem:mode=release gates a RELEASE on the full-set run, but a
big fraction of that set is genuinely-slow real work whose pass/fail near a per-script
cap is nondeterministic (CI runner load). Correctness and perf-flakiness are conflated
into one RED. (This is the "mode=release full-tail RED policy" question first raised on #72 comment-4966797130.)
Proposal — tier the run so integrate gates on CORRECTNESS, not the perf tail:
Introduce a slow/advisory tier for known-slow real-search scripts (a slow: true marker in config/build/no_run.yaml or a companion slow.yaml, or a
duration threshold): these still RUN and are reported, but a timeout on an
advisory-tier script is advisory (yellow), not an integrate-RED.
Alternatively/additionally, run the slow tier as a separate off-critical-path job
with a large budget (e.g. 3600s+), so a slow-tier flake never blocks the release
verdict while still surfacing regressions.
A timeout on a non-advisory script is still RED (a script that should be fast
timing out IS a signal). Only the declared-slow population is de-gated.
Keep it loud: advisory failures surface in the report + Heart's YELLOW reasons
(same spirit as the existing SLOW/NEEDS_FIX banners), so they're a tracked backlog,
not silently hidden — the durable speedups are the Profiling Agent's job
(draft/feature/profiling/profiling_agent_jax_compile_time_scope.md).
Outcome: after the real bugs are fixed, mode=release reaches GREEN/YELLOW on
correctness and the release-decision gate stops being held hostage by real-search
perf-flakes. Design in PyAutoHeart (workspace-validation.yml + heart/validate.py
tiering) with the runner support in PyAutoBuild (run_python.py/build_util.py).
Cross-ref project_release_2026_07_13_blocked_3bugs and PyAutoHeart#72.
Overview
workspace-validation.yml mode=releasecurrently conflates correctness and perf-flakiness into a single RED. After the 2026-07-13 tail burn-down (PyAutoHeart#72) fixed every real bug, the integrate stage still can't reach a clean verdict because a population of genuinely-slow real-search scripts (real Nautilus fits + finite-difference JAX gradients) flakes around the per-script timeout cap — the failing set shifts every run (shared_preloadsliterally flip-flopped between re-val #3 and #4). Raising the cap and addingno_runSLOW-skips one script at a time never converges and erodes coverage.This introduces an advisory tier: a timeout on a declared-slow script is downgraded to YELLOW (loud, tracked), while a timeout on any undeclared script stays RED. This is the path that lets
mode=releasereach its normal shippable GREEN/YELLOW once the real bugs are fixed, instead of being held hostage by the perf tail.Plan
config/build/advisory.yamlper workspace — same flat-list + inline-comment format asno_run.yaml, but the listed scripts still run and report; only their timeouts are advisory. Growing this list never erodes coverage, so it converges where SLOW-skips whack-a-mole. Absent file → today's behaviour exactly.TIMEOUT_ADVISORYresult status; the runner tags a timeout as advisory when the script matchesadvisory.yaml;has_failures/ aggregatereadyexclude advisory timeouts; a non-advisory timeout still fails the run.validation_reportcarry anadvisory_timeoutscount; readiness mapsadvisory_timeouts > 0to a YELLOW reason (not RED), keeping the release GREEN→YELLOW rather than RED-blocked.advisory.yamlin the*_testworkspaces from the re-val PyAutoPulse v1.3 — stop --all (recover orphan daemon) #3/PyAutoPulse v1.4 — classify generated json/png as dirty-noise #4 flip-flop population as aship_workspacefollow-up.Detailed implementation plan
Affected Repositories
heart/validate.py,heart/readiness.py,.github/workflows/workspace-validation.yml,docs/release_validation.mdautobuild/result_collector.py,autobuild/run_python.py,autobuild/build_util.py,autobuild/aggregate_results.pyBranch Survey
No worktree conflict (active claims are all on the science libraries). Suggested branch:
feature/release-advisory-tier-slow-scriptsThe failure path being severed
build_utiltimeout →Status.TIMEOUT→RunReport.has_failures→aggregate_results.ready=false→ workflow "Fail if not ready" +emit_release_reportstatus=fail →validate.pystageintegrate=fail →release_ready=false→readiness.pyhit("validation_failed")→ RED.Implementation Steps
PyAutoBuild (runner mechanism):
autobuild/result_collector.py— addStatus.TIMEOUT_ADVISORY = "timeout_advisory";RunReport.has_failuresexcludes it;summary/to_dictcarry it.autobuild/run_python.py— loadconfig/build/advisory.yaml(workspace override → empty default, mirroring theno_run.yamlresolution), parse its reasons, threadadvisory_list/advisory_reasonsintoexecute_scripts_in_folder.autobuild/build_util.py— inexecute_script(andexecute_notebookfor symmetry), onsubprocess.TimeoutExpired, if the file matchesadvisory_list(reuseshould_skippath semantics) recordTIMEOUT_ADVISORYwith the advisory reason instead ofTIMEOUT.autobuild/aggregate_results.py—timeout_advisoryis not in the failure set (soreadyis unaffected); add anadvisory_timeoutslist + a loud "## Advisory-Tier Timeouts (slow real-search; not release-blocking)" markdown section. A non-advisory timeout still flipsready=false.PyAutoHeart (policy):
5.
heart/validate.py—to_stage_reportcarriesadvisory_timeouts(count + entries) from the aggregate into the stage report (NOT folded intofailures);_Accumulator+ report schema sum it into the top-levelvalidation_report; status still derives fromaggregate.ready. Bump the schema docstring.6.
heart/readiness.py— in the release-validation gate, when the report hasadvisory_timeouts > 0, append a YELLOW reason ("N advisory-tier script timeout(s) in release validation (slow real-search; not release-blocking)") +hit("validation_advisory_timeout")with a_SCORESentry. This turns a correctness-clean run GREEN→YELLOW instead of RED.7.
.github/workflows/workspace-validation.yml— comment the tier; echo the advisory-timeout count into$GITHUB_STEP_SUMMARY. No gate-logic change (already keys offready).8.
docs/release_validation.md— document the advisory tier and the# ADVISORY <date> - reasonmarker convention.Tests
PyAutoBuild/tests/test_result_collector.py(+ new aggregate test): advisory-matched timeout →TIMEOUT_ADVISORY,has_failuresfalse,readytrue,advisory_timeoutspopulated; non-advisory timeout →readyfalse.PyAutoHeart/tests/test_validate.py:to_stage_reportcarries the advisory count and stage status stayspass; readiness mapsadvisory_timeouts > 0→ YELLOW (not RED).Key Files
PyAutoBuild/autobuild/result_collector.py—Status,RunReport.has_failuresPyAutoBuild/autobuild/build_util.py—execute_script/execute_notebooktimeout branch,should_skipPyAutoBuild/autobuild/run_python.py— advisory.yaml load + thread-throughPyAutoBuild/autobuild/aggregate_results.py—aggregate()failure set + report sectionPyAutoHeart/heart/validate.py—to_stage_report,_Accumulator, schemaPyAutoHeart/heart/readiness.py— release-validation gate YELLOW reasonPyAutoHeart/.github/workflows/workspace-validation.yml— step summaryconfig/build/advisory.yaml(new, per*_testworkspace) — the declared-slow registryDesign notes
FAILED(exception) on an advisory script stays RED, preserving the correctness signal.draft/feature/profiling/profiling_agent_jax_compile_time_scope.md(durable speedups).Original Prompt
Click to expand starting prompt
mode=release should tier slow real-search scripts as advisory, not RED-block on the perf tail
Type: feature
Target: PyAutoHeart
Repos:
Difficulty: medium
Autonomy: supervised
Priority: high
Status: formalised
The 2026-07-13 release-validation burn-down (PyAutoHeart#72) fixed every real
correctness bug in the tail (A–H + the jax_grad config gap). But the
workspace-validation.yml mode=releaseintegrate stage still cannot reach a cleanverdict, because it runs the FULL script set — including a population of genuinely
slow real-search scripts (
PYAUTO_TEST_MODE=0/1real Nautilus fits +finite-difference JAX gradients) that flake around the per-script timeout cap. The
failure set shifts run to run:
interferometer mge/slam, multi/shared_preloads — all of which passed in PyAutoPulse v1.3 — stop --all (recover orphan daemon) #3
(
shared_preloadsliterally flip-flopped).Raising
BUILD_SCRIPT_TIMEOUT(300→1800) and addingno_runSLOW-skips one script ata time does not converge — each run surfaces a different handful of borderline
scripts, and de-gating them individually is whack-a-mole that also erodes coverage.
The structural problem:
mode=releasegates a RELEASE on the full-set run, but abig fraction of that set is genuinely-slow real work whose pass/fail near a per-script
cap is nondeterministic (CI runner load). Correctness and perf-flakiness are conflated
into one RED. (This is the "mode=release full-tail RED policy" question first raised on
#72 comment-4966797130.)
Proposal — tier the run so integrate gates on CORRECTNESS, not the perf tail:
slow: truemarker inconfig/build/no_run.yamlor a companionslow.yaml, or aduration threshold): these still RUN and are reported, but a timeout on an
advisory-tier script is advisory (yellow), not an integrate-RED.
with a large budget (e.g. 3600s+), so a slow-tier flake never blocks the release
verdict while still surfacing regressions.
timing out IS a signal). Only the declared-slow population is de-gated.
(same spirit as the existing SLOW/NEEDS_FIX banners), so they're a tracked backlog,
not silently hidden — the durable speedups are the Profiling Agent's job
(
draft/feature/profiling/profiling_agent_jax_compile_time_scope.md).Outcome: after the real bugs are fixed,
mode=releasereaches GREEN/YELLOW oncorrectness and the release-decision gate stops being held hostage by real-search
perf-flakes. Design in PyAutoHeart (
workspace-validation.yml+heart/validate.pytiering) with the runner support in PyAutoBuild (
run_python.py/build_util.py).Cross-ref project_release_2026_07_13_blocked_3bugs and PyAutoHeart#72.