Refuse a run that would lose a plugin it could not order - #125
Merged
Conversation
`internal/posture` ordered a plugin's releases by publication time and treated index 0 as the release the run exists to publish. Where no release in the set carried a time, none of `newerFirst`'s clauses fired, the order fell through to the tag, and the highest tag arrived at index 0 -- the string decisions/manifest-schema.md refuses as a version answering the question the publication time exists to answer. A defect in that release then stopped the whole run, taking every other plugin's catalogue down with it, over a published release nobody here can repair. The classification now says such a set has no newest release, so every defect in it is a named skip. That alone moves the failure rather than removing it: the plugin resolves, contributes nothing, and the catalogue is quietly one entry shorter with a zero exit, which decisions/failure-posture.md spends its longest section on being the worse of the two. So `catalogue.JudgeDropped` lands with it and refuses a run in which a plugin that resolved produces no entry and nothing stops. decisions/failure-posture.md places both, and one correction beside them. Its last section said nothing refused any of the posture and named five issues as where the refusals would arrive; all five are closed and their refusals are in the tree, so that sentence had stopped being true. It was found while writing the two conditions above, which had to say what refuses them and could not do that beside a paragraph claiming nothing does. The means is Go and the existing suites, because both rules are refusable properties over values the packages already hold and both are proven by fixtures the gate already runs. No dependency is added and go.sum is untouched. Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #114.
internal/postureordered a plugin's releases by publication time and treatedindex 0 as the release the run exists to publish. Where no release in the set
carried a time, none of
newerFirst's clauses fired, the order fell through tothe tag, and the highest tag arrived at index 0. That is the string
decisions/manifest-schema.mdrefuses as a version answering the question thepublication time exists to answer, and a defect in that release stopped the whole
run over a published release nobody here can repair.
#114 carries the decision this implements, taken on the issue on 2026-08-21: in
such a set no release is classified as the newest, and the second rule lands with
it rather than after it.
What changed
One term in the classification. A release that cannot be placed in time is not
the newest however far up the order it landed, so in a set where nothing carries
a time every defect is a named skip and nothing stops.
That alone moves the failure rather than removing it. The plugin resolves,
contributes nothing, and the catalogue is one entry shorter with a zero exit,
which
decisions/failure-posture.mdspends its longest section on being theworse of the two. So
catalogue.JudgeDroppedlands in the same change andrefuses a run in which a plugin that resolved produces no entry and nothing
stops.
Route.Publishasks it afterposture.Judgeand beforeJudge, so astop keeps its own more specific reason.
decisions/failure-posture.mdplaces both: the unorderable set under what is aloud skip, and the dropped plugin under what is fatal.
Both guards were watched refusing
Putting the classification term back to what it was:
Deleting the second rule's call from the route:
That red output is the failure the issue measured, reproduced from the tree: one
plugin gone from the placed file, exit zero, and the skips named in an output no
server reads. Both plants were made in the checkout, run, and reverted, and the
branch carries neither.
Each rule also has a near miss beside it.
TestOneDatedReleaseInTheSetIsStillTheNewestholds that one dated release in theset makes the question answerable again and a defect in it fatal as before, and
TestAPluginThatPublishesSomethingIsNotReadAsDroppedholds that a pluginpublishing one entry out of two releases is not read as dropped, which is the
ordinary state of every run today.
The rule has no real instance and is not expected to get one
Run 2026-08-22. Nothing in the declared set publishes a release list without
dates, so this refuses fixtures and is expected to go on doing so. The decision
file says so in the same words, because a rule whose first real instance will
surprise somebody is worth writing down as one.
A correction carried in the same change
The last section of
decisions/failure-posture.mdsaid nothing refused any ofthe posture, and named #24, #25, #27, #28 and #18 as where the refusals would
arrive. All five are closed and their refusals are in the tree, so the sentence
had stopped being true. It was found while writing the two conditions above,
which had to say what refuses them and could not do that beside a paragraph
claiming nothing does. The replacement hands the reader the command that derives
what is refused rather than a list that will drift the same way.
The means
Go and the suites already here. Both rules are refusable properties over values
these packages already hold, both are proven by fixtures the gate already runs,
and neither needs anything the tree does not carry. No dependency is added and
there is still no
go.sum.The gate
Run at the commit this branch carries. The harness did not run and was not asked
for, and no leg above depends on any requirement, so that verdict is complete
rather than partial. No server was started and nothing that could ask for
elevation was attempted.
This change has had no second reader. The evidence above stands in place of one:
each guard is shown refusing, each near miss is named, and every number carries
the command that produced it.