Skip to content

Do not report a required subprogram verified when its gate left it ungated - #35

Merged
chenyueqi merged 1 commit into
mainfrom
required-coverage-ungated
Sep 6, 2026
Merged

Do not report a required subprogram verified when its gate left it ungated#35
chenyueqi merged 1 commit into
mainfrom
required-coverage-ungated

Conversation

@second5t

@second5t second5t commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

What this is

verify_recipe_candidates decided a required subprogram's gates_passed from the owner unit's gate statuses alone. A differential gate whose oracle has no reference for a subprogram lists it as ungated (metrics["ungated"], {name: why}) and passes the unit on the rest, so a required subprogram that nothing ever compared came out observed / gates_passed / accepted, the report was accepted, and the training loop merged the candidate.

  • Read each required gate's verdict for its ungated names and treat a required subprogram ungated on any owner unit as not gates_passed. The report then rejects with subprogram.required_coverage, the code the campaign already routes to repair. Unrequired subprograms keep today's behaviour: recorded as unverified, not blocking. Tests in tests/test_phases.py.

Found by the training lab: an agent repair (39f9f8d there) stubbed LAPACK externals in the oracle build and listed the subprograms reaching them as ungated; splines' required spline3 and spline3pars passed without ever being compared. This is the upstream version of the lab's fix, rebased onto main (1044bc4). The lab's agent-authored engine repairs that followed (C-keyword dummies as f2py names, negative-subscript redraws, LOGICAL INOUT scalars) are pending human audit and are not in this PR.

Checks run locally (uv, Python 3.11, gfortran 13)

  • ruff check . clean; mypy clean (109 files); tools/check_signoff.py 1044bc4..HEAD clean.
  • pytest with dev fortran translate verify: 891 passed, 20 skipped.
  • tools/check_hygiene.py .: the same 4 lines as main (docs/roadmap.md, src/recast/fortran/constants.py), nothing from this branch.
  • ruff format --check .: the same 2 Markdown files as main, untouched here.

🤖 Generated with Claude Code

…gated

verify_recipe_candidates decided a required subprogram's gates_passed from
the owner unit's gate statuses alone. A differential gate whose oracle has
no reference for a subprogram lists it as ungated (metrics["ungated"],
{name: why}) and passes the unit on the rest, so a required subprogram that
nothing ever compared came out observed/gates_passed/accepted, the report
accepted, and the training loop merged the candidate.

Read each required gate's verdict for its ungated names and treat a
required subprogram ungated on any owner unit as not gates_passed. The
report then rejects with subprogram.required_coverage, the code the
campaign already routes to repair. Unrequired subprograms keep today's
behaviour: recorded as unverified, not blocking.

Found by the lab: 39f9f8d stubbed LAPACK externals in the oracle build and
listed the subprograms reaching them as ungated; splines' required spline3
and spline3pars passed without being compared.

Signed-off-by: 2st <mouseisnotalwaysmouse@outlook.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
@chenyueqi chenyueqi added bug Something isn't working area:spine recipes, registry, run, CLI, stores, engines catalog labels Sep 6, 2026
chenyueqi added a commit that referenced this pull request Sep 6, 2026
… and #35

The table is unchanged. Per-subprogram metrics now carry PR #31's `shaped`
and `input_profile` and PR #33's `declined` by reason, and minpack's chkder
is named for its declined draws as PR #33's own re-record named it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018vrAgr6x1yLT47EumS39L5
@chenyueqi
chenyueqi merged commit 132b8dd into main Sep 6, 2026
chenyueqi added a commit that referenced this pull request Sep 6, 2026
…-bounds

The CLUBB stack and this branch extended the same functions in different
directions; where git could not merge them, this is what was decided:

- An Expr has both a `str` node (a character value) and a `call` node (a
  folded intrinsic); `render` spells both. Constant folding is main's
  typed `with_integer_division`, with the `str` short-cut kept.
- One ALLOCATE scanner walks parentheses across continuation lines for
  both readers: an object's components (`COMPONENT_ALLOCATION`) and a
  module allocatable's own shape (`ALLOCATION`); `ALLOCATE_THIS` goes.
- The recorder keeps this branch's guard for an array the run never
  allocated -- poison of the planned shape -- and generalizes it to CLUBB's
  case: an extent the run owns (`extent_args`, written from `size()`) is
  spelled zero under the guard, so `c%coef` under `sclr_dim = 0` is
  recorded as `(ngrdcol, 0)` of nothing, the shape the kernel's dims
  declare, rather than main's `(0,0)` record. `_record_component` goes;
  the CLUBB test asserts the new spelling.
- The replay reads a logical (`T`/`F`) before it takes any other text as a
  character value. The flat adapter names a type only where a dummy of it
  is declared, and reaches a private specific through its generic.
- The JAX call rewrite takes main's host-call preamble and positional
  list, narrowed to the emitted convention: optionals as keywords, OUT
  scalars omitted, an OUT array passed only where it is the caller's
  buffer (the `buffer` mark, not `dims`). The elided-buffer table is
  main's positional one with this branch's temporary for an OUT scalar the
  anchor unpacks; an unpassed OUT array stays refused.
- The single-exit rewrite is this branch's flag-based one (returns inside
  loops, the guarded remainder as one block), with main's placement of the
  flag and placeholder after the statements before the first return, the
  placeholder shaped like the final value where that is already bound.
  The flag guard now applies at every block level through the visit of
  each branch, which is what main's `_fold_returns` covered (`if (bad)
  then; if (worse) return; y = y + 1; return`); that helper and
  `_guard_after_returns` go.
- The kernel lowerer knows both the trace-time statics and the names that
  size an array or bound a range; a literal store to either stays Python.
- The JAX runtime exports both sides' shims once; SUM folds sequentially
  along an axis too. The NumPy SUM is main's for the same reason.
- `_ret`-flag tests: the statics marker may precede a loop's done flag.
- Ruff and mypy on this branch's own files: long lines wrapped, a
  re-exported constant imported from its home, duplicate runtime
  definitions dropped.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018vrAgr6x1yLT47EumS39L5
@chenyueqi
chenyueqi deleted the required-coverage-ungated branch September 6, 2026 18:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:spine recipes, registry, run, CLI, stores, engines catalog bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants