Skip to content

0.26.0

Choose a tag to compare

@github-actions github-actions released this 17 Sep 00:07
· 2554 commits to main since this release

Added

  • A branch may say the field it owns holds nothing: sets: {field: {cleared: true}}. sets:
    admitted input.<field> or a literal, and neither can say "absent". The three ways to write it
    before this, measured on an adopter's model:

    written what happened
    nothing the field kept what an earlier act determined, so the suite required the old value
    metrics: none compiled, then dropped by synthesis — a literal is not read as the field's type
    lane_id: "" an empty string, which is a different reading from absent, and impossible for a struct

    The first cost that adopter a red scenario in one run of three: its dispose branch clears a lead
    and an asynchronous backend read sometimes put it back before the assertion.

    Two rules, and each is about a place rather than a value. The field's type must be Optional<…> —
    a required field cannot hold nothing, and a specification saying it can is wrong rather than
    surprising. And it is an entity source: refused on an event payload, because an event field the
    emitter does not determine is one the outcome does not list, which is what PayloadSource already
    calls undetermined.

    Synthesis asserts it rather than abstaining: the scenario reads the view and requires the field
    empty, so a target that leaves the old value fails. That is the difference from every other source
    this could have been modelled as.

Fixed

  • A suite required a field at the value an earlier act supplied, after a later act overwrote it.
    Synthesis accumulates what each invoked branch leaves in the entity's fields, and it abstains on
    two sources it cannot read as a value — a literal, and a field crossing a declared conversion.
    Abstaining is a statement about that act; the older determination was left standing, which turned
    it into a claim about the row, and the opposite claim.

    Measured on an adopter's model: a leave branch writing campaign_id: "" produced a suite whose
    view assertion went on requiring the campaign id the creating act had supplied. Two scenarios
    failed against an implementation that cleared the field exactly as the specification said to, and
    nothing in either document said why. A branch that writes a field now drops any earlier
    determination of it, whether or not it determines a value in its place.

    What is still unsaid, and is a construct rather than a defect: a branch that clears an
    Optional field has no spelling. sets: admits input.<field> or a literal, so "this branch
    leaves nothing here" can only be written as a literal the reader must not believe. Filed as
    story:a-branch-may-clear-the-field-it-owns.

  • A skipped scenario says why. The emitted Go runtime discarded the target's own error on
    ErrUnsupported and printed only the construct's name, so three different causes rendered
    identically. Measured on an adopter's run: 41 skips, three distinct reasons, one message — and
    the only way to learn anything was to patch the generated file, which an adopter did four times in
    one day before this landed. All four call sites now include the error: execute_command, both
    view reads and the binding invocation.

    The Rust runner never had this defect — it carries a Diagnostic (report.rs:487-493). This was
    the Go emitter alone, and the asymmetry is why it went unnoticed.

    The report still carries <status> <id> and no reason. It cannot carry one without a new
    field: failed_scenarios is a list of strings and evidence.rs:99-104 reads everything after the
    first space as the scenario identity, so appending a reason would corrupt that field for every
    reader. Filed as story:a-report-says-why-a-scenario-was-skipped rather than forced into a format

  • A filtered run published a report claiming the scenarios it never ran had passed. -run skips
    a subtest's body, so its status kept the optimistic default set before t.Run and report/1
    recorded it anyway. Measured on an adopter's suite/4: one selected scenario, go test exit
    0, and a document asserting "status": "passed", "scenarios_total": 112,
    "scenarios_failed": 0 — with the 61 that normally skip counted as passes. That is the document an
    adopter's own instructions say to trust instead of the exit code.

    Both formats now refuse a run that did not reach every scenario the suite holds, and say what is
    missing and what to do:

    report/1 refused: incomplete execution: 1 of 99 scenarios reached a conclusion, so this
    run cannot say what the other 98 came to. A `-run` filter is the usual cause — drop it to
    publish a document, or unset ESS_REPORT_OUT to filter without publishing one
    

    report/2 already refused, via countDocument, but said only "selected subtests omitted or did not
    terminate" — neither the counts nor the remedy. Both now share one check.

    Filtering without asking for a document is unaffected: no ESS_REPORT_OUT, no document, nothing to
    be wrong. An unfiltered run is unchanged — verified on the same consumer: inconclusive, 99 total,
    59 not passed.
    with no room for it.