Skip to content

proef v0.19.0

Latest

Choose a tag to compare

@github-actions github-actions released this 11 Sep 08:29
· 4 commits to main since this release
21b0e3a

Fixed

  • The Homebrew formula installs the man page and the shell completions. Its
    def install was bin.install "proef" and nothing else, so from 0.16.0 —
    the release that started shipping proef.1 and five completions/ files in
    every archive — until 0.18.0, brew install proef gave no man proef and no
    tab completion, while binstall and a direct download gave both. The formula
    is a heredoc inside release.yml and the archive is staged in a different
    job, so nothing tied the two together and no gate could see the gap; the
    render step now fails if the archive lacks a file the formula installs, and
    the formula's own test do asserts the man page and completion landed.
    Takes effect on the next tag: a tag runs the workflow from its own commit.

  • --dry-run refuses a file,…; asset that is not there. A suite whose
    asset had been deleted reported dry-run OK, and the failure arrived later
    from a different command, against a live backend — from the one gate CI runs
    before standing an environment up. Whether an asset resolves is statically
    knowable, so it is answered there now. The checker is staging's own
    (assets::resolve_assets, split out of stage_assets) rather than a second
    walk over the same artifacts, so validation and the run cannot disagree; the
    message and the diagnostic code are the ones a run already gave.

  • file, inside a JSON or assertion body is no longer mistaken for a file
    asset.
    The emitter found the files an artifact reads by scanning its text
    for the literal file, and a closing ;, so a request body containing that
    substring — {"note": "see file,notes.txt; for details"} — produced a
    phantom asset, and staging then failed the run over a file the request never
    reads. The claiming engine now reads its own AST, where a body reference and
    six characters of prose are different things.

Breaking

  • proef_core::emit::emit takes the registered step kinds, and
    StepKindSpec gains an assets hook.
    Asset recognition was hurl's body
    grammar living in proef-core: emit::file_refs_in scanned for the literal
    "file,", which ADR-0002's amendment forbids and — worse — which the guard
    pinning that amendment could not see. engine_grammar_kind classifies
    fences, HTTP, [Section] headers, method lines and key: value options; a
    body constructor is none of those, so the literal was never sanctioned and
    never reported missing. The ADR's own measurement said thirteen literals; it
    was fourteen.

    The scan moves behind the seam as StepKindSpec::assets, the fourth
    engine-contributed hook beside validate, fragments and options, and the
    guard gains a body arm so the shape is classifiable whether or not anything
    currently uses it. emit() takes &[StepKindSpec] to reach it; FrontEnd
    carries kinds beside the kind_to_engine table it is built with, which
    registry already documents as a pair that must not be re-derived
    separately. emit::file_refs_in is gone.

Internal

  • A fragment's assets stage from where its file was read, not from where its
    name points.
    AssetRoots::source_dir rebuilt a fragment's directory by
    splitting file.hurl#name and joining the file half onto the project root —
    the naming boundary run backwards, without the canonicalize fallback that
    boundary carries precisely because a lexical-only version already shipped a
    bug (a suite reached through a symlink silently failed to match, R11-9). The
    two agreed only because both were seeded from config.root() and discovery
    walked from that same root, so only the lexical case was ever exercised, and
    nothing made them stay inverses. The corpus reader now records the directory
    it read each file from (front::CorpusDirs, carried on FrontEnd beside
    kinds), and staging looks it up — the fragment-side twin of what
    LoadedFeature::read_from already does for features, so both halves of the
    naming boundary are one-way in the same way. AssetRoots loses its project
    field and build_specs its project_root argument: with nothing to
    recompute, the project root is no longer staging's business.

  • --rerun reads its base record once. It called record::read_events for
    the JUnit overlay and then record::rerun_candidates, which read and
    deserialized the same events.jsonl a second time — two full passes bounded
    only by the 256 MiB record ceiling, over a file another process may still be
    writing. rerun_candidates now takes the &[Event] its caller already
    holds, which is the rule read_record's own documentation had already
    stated for exactly this case. The read error is handled once as well: the
    first call swallowed it with .ok() and the second rediscovered it a line
    later.

  • The one doc check that reads only files now runs in the half that reads
    files.
    no_current_behaviour_doc_spells_a_format_as_an_output_path lived
    in tests/docs.rs, whose stated charter is the checks needing a built
    binary
    to ask clap — this one only scans markdown, so it never ran in the
    fast doc-only CI step. It is now xtask docs-check's
    check_output_path_spelling, reusing living_docs() instead of carrying a
    second directory walk. Its allowlist-shrink guard got stricter on the way:
    it counted ADRs into the same total, so a renamed entry could be masked by
    docs/adr being larger than the shortfall — which is the one failure that
    guard exists to catch. All three paths were checked by mutation: a stale
    spelling planted in an allowlisted doc, one planted in an ADR, and an
    allowlisted doc renamed away.

Documentation

  • The worklist stops contradicting what shipped. Three entries in
    OPEN-FINDINGS still called CTRF declined or its trigger unfired — the
    2026-08-31 external re-test, the RF audit's deferred list, and R3-5 under
    "deferred, with the trigger named" — for the eight days after --ctrf
    actually shipped (#160). R3-9, four bullets below R3-5 in that same list, was
    annotated the moment it shipped — the convention the three missed. Two more claims
    had outlived their facts: the shipped-changelog duplicate headers (no release
    carries one now, and check_changelog_kinds fails if one returns) and the
    machine-side note about Homebrew's Rust shadowing rustup. Filed at the same
    time: a_second_interrupt_hard_exits_with_130 failed once on Linux CI and
    passed on a re-run of the same commit, so the evidence, the mechanism and the
    fix shape are written down instead of left to the next re-run. And the stance
    that a scenario-level @retry is deliberately absent — retry-until-green
    hides a one-in-four defect 99.6% of the time — is stated in
    TESTING-STRATEGY §5, which the worklist asked for and nobody had written.

  • The runbook records that the registry skips three versions. 0.15.0–0.17.0
    were tagged and GitHub-released but never published, so crates.io moves
    0.14.0 → 0.18.0. Noted in RELEASING.md so the gap does not read as a failed
    upload. The long-standing homepage question in OPEN-FINDINGS is also
    resolved: the field reached the registry with 0.18.0, exactly as that entry
    predicted; documentation remains unset and still open.

  • The release history records every release again. RELEASING.md's History
    section carried no entry for v0.16.0 or v0.17.0 and filed v0.15.0
    between v0.13.0 and v0.14.0; the order is repaired and all three versions
    are present, v0.18.0 included. The corpus also stops calling the 0.18 series
    unreleased, and an IMPROVEMENT-PLAN pointer into CHANGELOG [Unreleased]
    now names the releases that actually carried the work — [Unreleased] has
    been cut several times since that sentence was written.