Skip to content

dispatch-gates renders "staleness could not be measured" identically to "this tree is current" — both are silence #12411

Description

@yinlianghui

Filed unassigned while measuring #12173 (finding ①). Not claimed, not graded.

What was measured

baseDrift() degrades every field to null rather than throwing when origin/main cannot be resolved — a fresh actions/checkout, a clone nobody fetched, a graft:

constbase=read(['rev-parse','--short',DEFAULT_BASE_REF]);if(base===null)return{base: null,behind: null,changed: [],headDate: null,baseDate: null};

driftLines() then collapses that state into the same output as a demonstrably-current tree:

exportfunctiondriftLines(drift){if(!drift||!drift.behind)return[];// base===null AND behind===0 both land here

So behind: null ("I could not measure this") and behind: 0 ("nothing to report") print byte-identically: nothing at all.

Why this matters

STALE TREE is now the load-bearing signal that a derived gate family may be short a gate that landed on main after the branch was cut — measured in #12173, it fires loudly and correctly whenever it can measure. Its own docblock states the discipline it is built on:

SILENT at zero — the last one for the same reason the banner has no "all paths present" twin: against a base ref nobody refreshed, a clean bill of health is precisely the reading the measured failure would have passed.

That reasoning justifies not printing an all-clear. It does not justify printing nothing when the instrument was unavailable: the reader cannot tell "measured, current" from "not measured", and the second one is exactly the state in which the family list is least trustworthy.

Sibling precedent in the same file: bannerLines prints the repo identity before the answer specifically so no run can be read without knowing what it is about, and --repo exists to make that checkable. The unmeasurable-staleness case has no such spelling.

Shape of the fix

One line, in the base === null branch only: say that staleness was not measured and why (origin/main not resolvable here), leaving behind === 0 silent as designed. Pin both directions in --self-test — the existing fixtures at the driftLines assertions already build a repo with and without a base ref, so the unmeasurable case has a fixture to hang on.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions