Skip to content

fix(guard): apr_bin.sh refused a HEAD-built binary sitting next to a stale one - #2511

Open
noahgift wants to merge 3 commits into
mainfrom
fix/apr-bin-prefers-fresh
Open

fix(guard): apr_bin.sh refused a HEAD-built binary sitting next to a stale one#2511
noahgift wants to merge 3 commits into
mainfrom
fix/apr-bin-prefers-fresh

Conversation

@noahgift

Copy link
Copy Markdown
Contributor

Is apr_bin.sh superior or inferior to the rest of the stack?

Superior — it is the only one. Surveyed all seven sibling repos:

repo binary resolver SHA-vs-HEAD freshness
pmat, realizar, batuta, copia, forjar none 0 scripts
trueno, bashrs none 1 script each
aprender apr_bin.sh yes yes, fail-closed under APR_BIN_STRICT

Skills: repo-scope apr-dogfood sources it correctly (. scripts/apr_bin.sh \|\| exit 1 + APR_BIN_STRICT=1). User-scope dogfood has no binary resolution at all — which is the shadowing hazard already recorded, since a user-scope skill can shadow a repo one by name.

It is also well-hardened already: refuses to search PATH, derives the target dir from cargo metadata rather than a hardcoded path, uses git rev-parse --show-toplevel instead of the bash-only BASH_SOURCE (which broke under zsh), and fails closed outside a checkout in strict mode.

The defect

apr_bin_resolve returned target/release/apr whenever it existed, then handed it to the freshness check — which refused it. Measured on a real checkout, debug/apr built from HEAD beside a stale release/apr:

STALE apr BINARY
  resolved : .../target/release/apr
  reports  : apr 0.60.0 (v0.60.0+no-git)
  HEAD     : 75d6610d8

It hard-fails and tells you to cargo install while a provably correct binary sits in the next directory. Every gate sourcing this file breaks that way, and the trigger is only "you ran cargo build --release here once".

The fix

The candidate set is unchanged, so the never-search-PATH property still holds. Only the order within it is now evidence-driven: first candidate whose embedded SHA matches HEAD wins. Fixed order remains the fallback, so an all-stale checkout still resolves something and reports STALE rather than "no apr binary found" — a worse diagnosis for the same situation.

The stale report now lists every candidate with its version, not only PATH shadows. Today's failure was a fresher binary in a sibling directory, which the old message had no way to show.

Falsifier

check_apr_bin_resolution.sh — four rows on throwaway git checkouts with fabricated binaries (shell scripts printing a version string; the resolver only substring-matches the sha, so no cargo build is needed):

stale release + fresh debug -> resolves DEBUG      <- the regression
fresh release + stale debug -> resolves RELEASE    <- order still honoured
both stale                  -> REFUSES
no binaries at all          -> REFUSES

Mutation: remove the freshness preference → row 1 goes RED, rows 2–4 stay green. Precisely the regression and nothing else.

check_apr_bin_pinned.sh cannot catch this class — it asserts that callers pin the binary, never that the resolver hands them the right one. Nothing exercised resolution order until now.

Wired into guard-runner-labels, which is in gate.needs, so it blocks rather than informs.

bashrs

0 errors. Two findings were the known false-positive classes, worked around at the source rather than suppressed: the fixture Cargo.toml is printf'd instead of heredoc'd (bashrs parses an embedded heredoc as shell, so TOML name = "x" reads as SC1007), and the version string's parens are kept off any line holding a [ ] test (SC1028).

The third — SEC011 on an unvalidated rm -rf "$dir"was right, and now uses this repo's "${dir:?}" idiom.

@noahgift
noahgift enabled auto-merge August 16, 2026 10:59
noahgift added a commit that referenced this pull request Aug 16, 2026
…oolchain, and ban hand-rolled argv parsing

WHAT WAS MISSING

Neither existing skill covered the shipped surface. Measured before writing this:

    .claude/skills/apr-dogfood/SKILL.md  (828 lines)
      references 26 distinct `apr` subcommands out of 103
      occurrences of mcp / MCP / /v1/ / curl / endpoint / route: 0
    .claude/skills/pre-release/SKILL.md
      same: 0

The 0.63.0 audit that probed 104 CLI commands, 9 MCP tools and 45 routes was
done BY HAND and was never reproducible.

scripts/dogfood_surfaces.sh covers all three interface kinds across every binary
the workspace builds, and its receipt is byte-identical across runs.

    pass=209  fail=0  skip=1  (skip 0%)   rc=0
    --twice: DETERMINISTIC, byte-identical receipts

IT USES THE DETERMINISTIC TOOLCHAIN, IT DOES NOT REIMPLEMENT IT

    pv       contract validation      (never yq, never a python YAML walk)
    bashrs   shell quality            (never shellcheck)
    probar   endpoint testing         (never a hand-rolled curl loop)
    pmat     code search / quality    (never grep for discovery)

Each is asserted PRESENT with its version rather than skipped-if-missing: a
sweep that silently drops its verification tools reports a clean pass having
checked less, which is the vacuous-scan defect the script exists to avoid.

The first draft violated this. It parsed contracts/apr-mcp-tool-schemas-v1.yaml
with python and counted `tools:` entries by hand -- muda by CLAUDE.md's explicit
rule, AND redundant, because FALSIFY-MCP-008 already asserts byte-identity
between the codegen constants and the live tools/list response at four layers.
Reimplementing a weaker version of an existing falsifier is the opposite of
dogfooding. It is `pv validate` now, plus `pv lint contracts/` over the whole
directory. The live endpoint probe runs `probar llm test`, not curl. The script
holds itself to the rule it enforces: it bashrs-lints its own source.

ENUMERATED AT RUNTIME, NEVER FROM A LIST

    binaries          cargo build --message-format=json (executables cargo REPORTS)
    apr subcommands   apr --help
    HTTP routes       the ("GET","/path",handler) table in api/router.rs
    MCP tools         const NAME in aprender-mcp/src/tools/

A written-down list is the defect this repo keeps finding: the falsification
spec asserts "exactly 36 top-level commands" and now finds 0 because the enum
moved file; CLAUDE.md has claimed 77, 103 and 111. Grepping source is no better
-- a regex over clap Subcommand enums reports 0 subcommands for `simular`, which
IS a clap-derive CLI. Only the binary knows what the binary accepts. Every
enumeration is vacuity-guarded: too few items FAILS.

A PASS MUST EXCLUDE AN OUTCOME

`--help` exiting 0 is not a pass -- a binary that prints nothing also exits 0.
Each binary must ALSO reject an unknown flag, which catches a parser that is not
parsing. Skips are counted, never silent, and a run skipping more than
MAX_SKIP_PCT FAILS.

HAND-ROLLED PARSERS: FIXED AND BANNED

scripts/check_no_hand_rolled_parsers.sh bans the CONSTRUCT, structurally and
ratcheted. It is complementary to the behavioural probe: the probe catches
today's broken parsers, the ban stops one returning. Self-test 3/3, including
two false-positive controls (a clap CLI that also calls env::args() must NOT be
flagged).

Four were hand-rolled; this converts three to clap derive (aprender-ptx-debug is
#2520). Baseline 4 -> 1.

    aprender-compute-xtask    --help exited 1
    aprender-qa-certify       apr-qa-readme-sync
    aprender-zram-generator   --help printed 0 BYTES and an unknown flag was
                              ACCEPTED at exit 0 -- so a typo'd flag was treated
                              as one of its DIRECTORY arguments. It is a systemd
                              generator; the three positional dirs are preserved
                              exactly, and --help now explains the protocol.

WHAT THE FIRST RUN FOUND

  aprender-train-lora   PANICKED on any argument
  trueno-zram           PANICKED on any argument

Both declared a short option twice -- `-m` for `model` AND `method`, `-p` for
`pages` AND `pattern`. clap's check is #[cfg(debug_assertions)], so RELEASE
builds do not panic; they ship the ambiguity. Verified on a release build,
`aprender-train-lora plan --help` listed BOTH `-m, --model` and `-m, --method`.
Fixed by making the colliding argument long-only in each.

TWO BUGS IN THIS SCRIPT, FOUND AND FIXED WHILE WRITING IT

1. It parsed `apr --help` with `^[[:space:]]+[a-z]`, scraping WRAPPED
   DESCRIPTION lines: `apr yet)`, `apr clip.wav`, `apr existing` were reported
   as subcommands and the count read 114 against a real 105.

2. It built binary paths from `cargo metadata`'s target_directory. In a worktree
   that reports /mnt/nvme-raid0/targets/aprender while cargo writes to
   <worktree>/target/debug -- .cargo/config.toml holds the redirect and is
   gitignored. The script was probing binaries built from a DIFFERENT TREE. It
   asks cargo now. The repo's own binary-pinning doctrine, violated by the first
   draft.

Route enumeration was wrong once too: globbing every "/..." string literal
reported 284 routes. Reading the route table gives 34.

VERIFICATION

  dogfood --self-test                  3/3 (incl. permissive-CLI caught)
  hand-rolled ban --self-test          3/3 (incl. 2 false-positive controls)
  dogfood --twice                      byte-identical receipts
  full sweep                           pass=209 fail=0 skip=1, rc=0
  pv lint contracts/                   0 errors
  cargo test (3 converted crates)      226 passed, 0 failed
  cargo clippy --all-targets           0 errors
  cargo fmt --all --check              rc=0

NOTE for sequencing: scripts/check_shell_lint_ratchet.sh (#2511, not yet on
main) baselines the repo-wide bashrs error count; these two new scripts add 13
(all documented false-positive classes on embedded python/awk -- `bash -n` is
clean on both), so it needs a re-baseline when both land.

Refs #2503
…stale one

`apr_bin_resolve` returned `target/release/apr` whenever it existed, then
handed it to the freshness check, which refused it. Measured on a real
checkout with `debug/apr` built from HEAD beside a stale `release/apr`:

  STALE apr BINARY
    resolved : .../target/release/apr
    reports  : apr 0.60.0 (v0.60.0+no-git)
    HEAD     : 75d6610d8

It hard-failed and told the caller to `cargo install` while a provably
correct binary sat in the next directory. Every gate that sources this
file breaks in that state, and the trigger is only "you ran `cargo build
--release` in this checkout once".

The candidate SET is unchanged, so the never-search-PATH property this
file exists for still holds. Only the ORDER within that set is now
evidence-driven: first candidate whose embedded SHA matches HEAD wins.
Fixed order stays as the fallback so an all-stale checkout still resolves
something and reports STALE, rather than "no apr binary found" -- a worse
diagnosis for the same situation.

The stale report now also lists every candidate with its version, not
only PATH shadows. Today's failure was a FRESHER binary in a sibling
directory, which the old message had no way to show.

FALSIFIER: check_apr_bin_resolution.sh, four rows on throwaway git
checkouts with fabricated binaries (shell scripts that print a version --
the resolver only substring-matches the sha, so no cargo build is
needed):

  stale release + fresh debug -> resolves DEBUG    <- the regression
  fresh release + stale debug -> resolves RELEASE  <- order still honoured
  both stale                  -> REFUSES
  no binaries at all          -> REFUSES

Mutation: remove the freshness preference -> row 1 goes RED and rows 2-4
stay green. Precisely the regression, nothing else.

check_apr_bin_pinned.sh cannot catch this class: it asserts that CALLERS
pin the binary, never that the resolver hands them the right one. Nothing
exercised resolution order until now.

Wired into guard-runner-labels, which is in gate.needs, so it blocks
rather than informs.

bashrs: 0 errors. Two of its findings were the known false-positive
classes and are worked around at the source rather than suppressed -- the
Cargo.toml is printf'd instead of heredoc'd (bashrs parses an embedded
heredoc as shell, so TOML `name = "x"` reads as SC1007), and the version
string's parens are kept off any line holding a `[ ]` test (SC1028). The
third, SEC011 on an unvalidated `rm -rf "$dir"`, was RIGHT: it now uses
this repo's `"${dir:?}"` idiom.
… at all

Follow-on to the apr_bin.sh fix in this PR, and the answer to "why did a
defect in the repo's most-sourced script survive?"

Nothing was looking at it.

  * CLAUDE.md mandates bashrs over shellcheck. CI honours that for SEVEN
    scripts -- `bashrs lint scripts/check_book_*.sh`, book.yml:58.
    apr_bin.sh is not one of them, and it is sourced by every gate in the
    repo (462 references).
  * `make lint-scripts` exists, but tier3 is not run in CI.
  * pmat DOES accept the file, and reports

        Functions: 0    Max Cyclomatic: 0

    for 227 lines holding 4 functions and heavy branching. It does not
    parse shell. That is worse than no coverage: it looks like a pass.
    Same vacuous-scan class as the rest of this repo's findings, except
    the scanner here is our own quality tool.

RATCHET, NOT A FIX. Extending the glob to scripts/*.sh surfaces 851
error lines across 73 scripts. They are dominated by bashrs's known
false positives on HAND-WRITTEN bash: an embedded heredoc parsed as
shell (TOML `name = "x"` -> SC1007), parens in a string sharing a line
with `[ ]` read as an unescaped test expression (SC1028), em-dashes in
prose as SC1100. A 851-item triage cannot land in one change, and a gate
that cannot go green gets disabled. So the count is baselined and may
only shrink -- new scripts cannot add errors, and the debt is visible
instead of hidden behind a glob.

Mutation: drop in a script with a heredoc and an unescaped `(` inside a
test -> 851 -> 853, gate RED, naming the top rules. Removing it goes
green again.

Vacuity arm: fewer than 60 scripts scanned is a hard failure, because a
glob matching nothing reports zero errors and looks like a pass -- which
is precisely how covering 7 of 72 went unnoticed.

Wired into guard-runner-labels (in gate.needs), so it blocks.

WORTH SAYING PLAINLY: the real answer is upstream of this gate. bashrs is
a Rust-to-POSIX TRANSPILER, and shell it generates does not trip its own
parser. What is being linted here is hand-written bash, which the fleet's
own tooling exists to stop us writing. Rewriting apr_bin.sh as Rust
(bashrs source, or lifted via xpile's Shell -> meta-HIR -> Rust lane) is
the actual fix; this only stops the debt growing meanwhile.
…eline

apr_bin.sh: `cd "$here"` where $here is `git rev-parse --show-toplevel`
or `pwd`, never user input -- annotate the known bashrs SEC010
false-positive per the existing bench.sh convention rather than
restructure working code.

check_shell_lint_ratchet.sh baseline (851) was captured against an
older main; #2534's 12-PR batch added scripts and grew the true
scan-everything count independent of this branch. Individually,
apr_bin.sh and check_apr_bin_resolution.sh lint at 0 errors; the
delta is corpus growth plus a bashrs cross-file parser-state artifact
reproducible on unmodified files (bench.sh + dogfood_surfaces.sh
combined also produce phantom errors that neither produces alone).
Re-baselined to the honest current count (876) rather than paper
over it.
@noahgift
noahgift force-pushed the fix/apr-bin-prefers-fresh branch from a8158f8 to 4044f15 Compare August 18, 2026 17:08
noahgift added a commit that referenced this pull request Aug 19, 2026
…ommands, 34 routes, 9 MCP tools — deterministically

WHAT WAS MISSING

Neither existing skill covered the shipped surface. Measured before writing this:

    .claude/skills/apr-dogfood/SKILL.md  (828 lines)
      references 26 distinct `apr` subcommands out of 103
      occurrences of mcp / MCP / /v1/ / curl / endpoint / route / chat-completions: 0
    .claude/skills/pre-release/SKILL.md
      same: 0

The 0.63.0 audit that probed 104 CLI commands, 9 MCP tools and 45 routes was
done BY HAND. It was never reproducible.

scripts/dogfood_surfaces.sh covers all three interface kinds across every
binary the workspace builds, and its receipt is byte-identical across runs.

ENUMERATED AT RUNTIME, NEVER FROM A LIST

  binaries          cargo build --message-format=json (executables cargo REPORTS)
  apr subcommands   apr --help
  HTTP routes       the ("GET","/path",handler) table in api/router.rs
  MCP tools         const NAME in aprender-mcp/src/tools/ + the contract

A written-down list is the defect this repo keeps finding: the falsification
spec asserts "exactly 36 top-level commands" and now finds 0 because the enum
moved file; CLAUDE.md has claimed 77, 103 and 111. Grepping source is no better
-- a regex over clap Subcommand enums reports 0 subcommands for `simular`, which
IS a clap-derive CLI. Only the binary knows what the binary accepts.

Every enumeration is vacuity-guarded: too few items FAILS, because a sweep over
a shrunken universe otherwise reports a clean pass.

A PASS MUST EXCLUDE AN OUTCOME

`--help` exiting 0 is not a pass -- a binary that prints nothing also exits 0.
Each binary must ALSO reject an unknown flag, which is what catches a parser
that is not parsing. The 0.63.0 audit found tests asserting is_ok() on invalid
input; those lock the defect in.

Skips are counted, never silent, and a run skipping more than MAX_SKIP_PCT
FAILS -- the require_model! defect, where 30 call sites `return` early and
report ok.

TWO BUGS IN THIS SCRIPT, FOUND AND FIXED WHILE WRITING IT

1. It parsed `apr --help` with `^[[:space:]]+[a-z]`, which scraped WRAPPED
   DESCRIPTION lines: `apr yet)`, `apr clip.wav`, `apr existing` were all
   reported as subcommands and the count came out 114 against a real 105. clap
   indents a subcommand by exactly two spaces; descriptions wrap far deeper.

2. It built binary paths from `cargo metadata`'s target_directory. In a worktree
   that reports /mnt/nvme-raid0/targets/aprender while cargo actually writes to
   <worktree>/target/debug -- .cargo/config.toml holds the redirect and is
   gitignored, so it exists in the main checkout and not in a worktree. The
   script was probing binaries built from a DIFFERENT TREE. Now it asks cargo
   which executables it produced. This is the repo's own binary-pinning
   doctrine, and the first version violated it.

Its route enumeration was also wrong once: globbing every "/..." string literal
reported 284 routes. It reads the route table now, and gets 34.

WHAT THE FIRST RUN FOUND (all confirmed by hand)

  aprender-train-lora   PANICKED on any argument
  trueno-zram           PANICKED on any argument

Both declared a short option twice -- `-m` for `model` AND `method`, `-p` for
`pages` AND `pattern`. clap's check is #[cfg(debug_assertions)], so RELEASE
builds do not panic; they ship the ambiguity. Verified on a release build:

    $ aprender-train-lora plan --help
      -m, --model <MODEL>    Model size in parameters ...
      -m, --method <METHOD>  Fine-tuning method ...

Two arguments claiming one short flag, in the binary `cargo install` produces.
Fixed by making the colliding argument long-only in each; the short was never
usable, and `-m`/`-p` now bind unambiguously.

STILL RED, deliberately left for a decision (they are in the receipt):

  aprender-compute-xtask --help exits 1 (hand-rolled env::args() parsing)
  aprender-zram-generator --help produces 0 bytes, and accepts an unknown flag
    at exit 0 -- it is a systemd generator taking normal_dir/early_dir/late_dir
    positionally, so an unrecognised flag is treated as a DIRECTORY PATH

VERIFICATION

  --self-test           3/3, including the row where a permissive CLI is CAUGHT
  --twice               byte-identical receipts
  full sweep            pass=198 fail=3 skip=1 (skip 0%)
  bash -n               rc=0

bashrs reports 7 errors, all the documented false-positive classes on embedded
python/awk (SC1078 x4, SC1028, SC1035, SC2296); `bash -n` is clean. NOTE for
sequencing: scripts/check_shell_lint_ratchet.sh (#2511, not yet on main)
baselines the repo-wide bashrs error count, so it will need a re-baseline when
both land.

Refs #2503

(cherry picked from commit da69eac)
noahgift added a commit that referenced this pull request Aug 19, 2026
…oolchain, and ban hand-rolled argv parsing

WHAT WAS MISSING

Neither existing skill covered the shipped surface. Measured before writing this:

    .claude/skills/apr-dogfood/SKILL.md  (828 lines)
      references 26 distinct `apr` subcommands out of 103
      occurrences of mcp / MCP / /v1/ / curl / endpoint / route: 0
    .claude/skills/pre-release/SKILL.md
      same: 0

The 0.63.0 audit that probed 104 CLI commands, 9 MCP tools and 45 routes was
done BY HAND and was never reproducible.

scripts/dogfood_surfaces.sh covers all three interface kinds across every binary
the workspace builds, and its receipt is byte-identical across runs.

    pass=209  fail=0  skip=1  (skip 0%)   rc=0
    --twice: DETERMINISTIC, byte-identical receipts

IT USES THE DETERMINISTIC TOOLCHAIN, IT DOES NOT REIMPLEMENT IT

    pv       contract validation      (never yq, never a python YAML walk)
    bashrs   shell quality            (never shellcheck)
    probar   endpoint testing         (never a hand-rolled curl loop)
    pmat     code search / quality    (never grep for discovery)

Each is asserted PRESENT with its version rather than skipped-if-missing: a
sweep that silently drops its verification tools reports a clean pass having
checked less, which is the vacuous-scan defect the script exists to avoid.

The first draft violated this. It parsed contracts/apr-mcp-tool-schemas-v1.yaml
with python and counted `tools:` entries by hand -- muda by CLAUDE.md's explicit
rule, AND redundant, because FALSIFY-MCP-008 already asserts byte-identity
between the codegen constants and the live tools/list response at four layers.
Reimplementing a weaker version of an existing falsifier is the opposite of
dogfooding. It is `pv validate` now, plus `pv lint contracts/` over the whole
directory. The live endpoint probe runs `probar llm test`, not curl. The script
holds itself to the rule it enforces: it bashrs-lints its own source.

ENUMERATED AT RUNTIME, NEVER FROM A LIST

    binaries          cargo build --message-format=json (executables cargo REPORTS)
    apr subcommands   apr --help
    HTTP routes       the ("GET","/path",handler) table in api/router.rs
    MCP tools         const NAME in aprender-mcp/src/tools/

A written-down list is the defect this repo keeps finding: the falsification
spec asserts "exactly 36 top-level commands" and now finds 0 because the enum
moved file; CLAUDE.md has claimed 77, 103 and 111. Grepping source is no better
-- a regex over clap Subcommand enums reports 0 subcommands for `simular`, which
IS a clap-derive CLI. Only the binary knows what the binary accepts. Every
enumeration is vacuity-guarded: too few items FAILS.

A PASS MUST EXCLUDE AN OUTCOME

`--help` exiting 0 is not a pass -- a binary that prints nothing also exits 0.
Each binary must ALSO reject an unknown flag, which catches a parser that is not
parsing. Skips are counted, never silent, and a run skipping more than
MAX_SKIP_PCT FAILS.

HAND-ROLLED PARSERS: FIXED AND BANNED

scripts/check_no_hand_rolled_parsers.sh bans the CONSTRUCT, structurally and
ratcheted. It is complementary to the behavioural probe: the probe catches
today's broken parsers, the ban stops one returning. Self-test 3/3, including
two false-positive controls (a clap CLI that also calls env::args() must NOT be
flagged).

Four were hand-rolled; this converts three to clap derive (aprender-ptx-debug is

    aprender-compute-xtask    --help exited 1
    aprender-qa-certify       apr-qa-readme-sync
    aprender-zram-generator   --help printed 0 BYTES and an unknown flag was
                              ACCEPTED at exit 0 -- so a typo'd flag was treated
                              as one of its DIRECTORY arguments. It is a systemd
                              generator; the three positional dirs are preserved
                              exactly, and --help now explains the protocol.

WHAT THE FIRST RUN FOUND

  aprender-train-lora   PANICKED on any argument
  trueno-zram           PANICKED on any argument

Both declared a short option twice -- `-m` for `model` AND `method`, `-p` for
`pages` AND `pattern`. clap's check is #[cfg(debug_assertions)], so RELEASE
builds do not panic; they ship the ambiguity. Verified on a release build,
`aprender-train-lora plan --help` listed BOTH `-m, --model` and `-m, --method`.
Fixed by making the colliding argument long-only in each.

TWO BUGS IN THIS SCRIPT, FOUND AND FIXED WHILE WRITING IT

1. It parsed `apr --help` with `^[[:space:]]+[a-z]`, scraping WRAPPED
   DESCRIPTION lines: `apr yet)`, `apr clip.wav`, `apr existing` were reported
   as subcommands and the count read 114 against a real 105.

2. It built binary paths from `cargo metadata`'s target_directory. In a worktree
   that reports /mnt/nvme-raid0/targets/aprender while cargo writes to
   <worktree>/target/debug -- .cargo/config.toml holds the redirect and is
   gitignored. The script was probing binaries built from a DIFFERENT TREE. It
   asks cargo now. The repo's own binary-pinning doctrine, violated by the first
   draft.

Route enumeration was wrong once too: globbing every "/..." string literal
reported 284 routes. Reading the route table gives 34.

VERIFICATION

  dogfood --self-test                  3/3 (incl. permissive-CLI caught)
  hand-rolled ban --self-test          3/3 (incl. 2 false-positive controls)
  dogfood --twice                      byte-identical receipts
  full sweep                           pass=209 fail=0 skip=1, rc=0
  pv lint contracts/                   0 errors
  cargo test (3 converted crates)      226 passed, 0 failed
  cargo clippy --all-targets           0 errors
  cargo fmt --all --check              rc=0

NOTE for sequencing: scripts/check_shell_lint_ratchet.sh (#2511, not yet on
main) baselines the repo-wide bashrs error count; these two new scripts add 13
(all documented false-positive classes on embedded python/awk -- `bash -n` is
clean on both), so it needs a re-baseline when both land.

Refs #2503

(cherry picked from commit 5a97304)
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