Skip to content

The 'check runs, exits clean, observed the wrong surface' defect class has no citable home — artifacts cite a closed, narrower instance #4482

Description

@usirin

Decision wanted

Does the broad "right-when-written, silently-wrong" verification class get ADR force — and in what shape relative to #4628's already-ruled ADR? One question; the deliverable is a recorded choice. The class's instances stay separately owned build tickets regardless of the ruling.

The class, restated at its now-visible width

An artifact or check result that was right when written becomes wrong silently, and the failure presents as a plausible value rather than an absent one — so the natural guards (is it empty? non-zero? did it match?) are structurally blind. The countermeasure discipline the ruling would (or would not) canonize: re-derive at the point of consumption; never branch on a signal that cannot distinguish "no" from "never ran", or "complete" from "lagged".

Adjacent canon, neither of which covers this width:

Six independent instances in one session (2026-08-01), one shape

  1. Stale plan — epic fabrika foundation: the home, the conventions, and the authoring-brief contract #4648's plan (children minted 06:44–06:47Z) executed against a founder scope correction made 17:21Z; three children conflicted with the corrected scope and read as a valid plan until a timestamp check caught it (fabrika foundation: the home, the conventions, and the authoring-brief contract #4648 comments 5152523719, 5152655871). Verified by this re-triage from the comments.
  2. One-way ADR link.decisions/0110-plugin-carries-no-version-continuous-ship.md carries status: accepted and no in-file forward pointer; a reader arriving there gets a confident answer with no signal that downstream state moved. (In-file status verified by this re-triage; the staleness of the continuous-ship claim itself is the reported half.)
  3. Stale inline contractvalidate-gate-path-drift.sh's marketplace source parse passes non-matching lines through verbatim, so a failed parse reads as a value #4663: an inline # || true: no-match → empty comment asserts a fail-closed contract the code does not have; disproved by a live pipe test (validate-gate-path-drift.sh's marketplace source parse passes non-matching lines through verbatim, so a failed parse reads as a value #4663 comment 5152633484 — the expression emits verbatim, exit 0).
  4. Stale line anchor — a line anchor in a crew instruction, accurate when written, stale once rows were appended below. (Reported by the re-triage requester; not board-verifiable from this seat — carried as unverified.)
  5. Could-not-run reads as "no"Skill fence exits 127 with empty stdout when the hook-planted .claude/.pipeline link is absent — "never ran" can read as "said no" #4666: post-fix(pipeline): skill fences resolve in ANY consuming repo via a hook-planted .claude/.pipeline link (#4605) #4645 skill fences through a missing .claude/.pipeline link exit 127 with empty stdout; a caller branching on non-zero-means-no consumes "never ran" as "said no". Two independent worktrees hit it.
  6. Lagged read reads as smaller truthWave read right after a labeling write can under-report, and a short list is consumed as the real wave #4667: an eventually-consistent label-index read returned 7 of 11 wave members seconds after all 11 writes landed; the wave-list contract fails only on empty, so an incomplete list is indistinguishable from a genuinely smaller wave.

Plus the wrong-surface instances from the original filing, each separately owned: #3779, #4338 / #4163, #4215, #4431, #4493, #4497, #4501, #4508.

Candidate shapes (recorded for the founder — the ruling is his, not triage's)

Acceptance criteria

Triage note (re-triage, 2026-08-01): promoted type:choretype:decision, p2p1, on new information — six independent instances in one session widened the class beyond a citable-vocabulary need into a shape question that must be answered before #4628's ADR is authored. Rationale in the re-triage comment.


Prior triage enrichment (chore-era, superseded by this re-type)

Problem

A recurring defect class — a check that runs, exits clean, and observed the wrong surface, so its clean exit is evidence about the wrong thing — keeps being cited in issue bodies and coordination artifacts, but has no citable home. The instance that was being cited (#4418) was correctly closed as a duplicate of the narrower #3779, so citations of "the pattern" now dangle on a closed, narrower ticket.

The class is real and heavily instantiated. It splits into two halves:

  1. Already canonical: the zero-scope / unreadable-input fails open half is owned by ADR 0092 and its generalized §ZS invariant in the pipeline formats contract (claude-plugins/kampus-pipeline/skills/gh-issue-intake-formats.md). Instances: jq -e exits 0 on empty input, so the canonical "validate the payload shape" guard fails OPEN #4431 (jq -e exits 0 on empty input), leak-guard scan reports "clean" and exits 0 for a file that does not exist #4497 / leak-guard.yml resolves an unreadable diff to a clean green — zero changed files exits 0 unscanned #4508 (leak-guard reports clean for a missing file / unreadable diff), classify-ui-surface.sh swallows its changed-file read (|| true) — a failed gh api becomes exit 0 + empty stdout, which the off-ramp reads as "no rendered surface" #4493 (|| true turns a failed fetch into "no rendered surface"), write-code's containment / cycle-doc / golden-pointer reads resolve an UNREADABLE input to the permissive answer (§ZS) #4501 (unreadable input resolves to the permissive answer).
  2. No home: the wrong-surface half — the check ran on real, non-empty input, but the surface it read is not the surface the requirement is about. Instances: Nothing catches a cross-PR ADR number collision — two concurrent lanes both minted ADR 0198 #3779 (allocator reads the local tree; a number claimed by an unmerged PR is invisible), Agents execute skills from the working tree, so a stale checkout silently applies withdrawn doctrine #4338 / A stale working tree fails toward "does not exist" — recurrence of #308 across 4 seats #4163 (a stale working tree executes withdrawn doctrine / fails toward "does not exist"), Unchecked producer exit status defeats verification idioms — pipe-masking is one of three variants #4215 (pipe-masking defeats exit-status idioms), and this issue's own filing (labels checked for existence while the requirement was queue reachability). §ZS does not cover these: the input wasn't empty, it was the wrong thing.

Deliverable (canon work — docs only, no behavior change)

A new .patterns/ doc under the CI / pipeline section of .patterns/index.md naming the class and the countermeasure discipline: verify the surface the check reads, not that it exits clean; fail closed on an unreadable/empty read; re-derive at the point of consumption. This clears the index's "when to add a new pattern doc" bar on all three criteria: the pattern recurs in many places, it is non-obvious (the instruments meant to catch it keep instantiating it — twice in one night per the original report), and agents demonstrably invent worse versions without it.

A .glossary/ row is not part of the deliverable — .glossary/LANGUAGE.md is architecture vocabulary, and an indexed pattern doc is already a citable anchor.

Acceptance criteria

Triage note: canon-shaped work — the deliverable is a .patterns/ doc, so this routes to the canon/docs path, not a code lane. The class's instances are separately owned build tickets and are explicitly out of scope here.

Original report (verbatim)

What was observed

A recurring defect class keeps being cited in issue bodies and crew coordination as a general pattern, but the ticket being cited — #4418 — was (correctly) closed as a duplicate of #3779, which is scoped to ADR number collisions only. The general pattern now has no open, citable home; at least two issue bodies (#4477, #4478) cited the closed instance as if it were the pattern, and their author is correcting them.

'## The first concrete example is this ticket'''s own filing
This issue was filed with zero labels — confirmed by the filer as "filed" against the issue existing, while the requirement was the issue being discoverable: the intake queue is queried by the status:needs-triage label, so an unlabeled ticket is invisible to the very queue that pulls it. The check verified existence; the requirement was reachability. Caught by a peer seat reading the queue, not the issue; corrected by one labels POST, verified this time against the queue query itself. That makes it the sixth instance of the class in one night, and the second in a row where the instrument meant to catch the class instantiated it.

The class'

A check that runs, exits clean, and observed the wrong surface — so its clean exit is evidence about the wrong thing. Open instances, each with its own fix, none owning the class:

What a home might be (triage's call, not binding)

Not an epic and probably not a build ticket — the instances are separately owned. Candidates: a .patterns/ doc naming the class and the countermeasure discipline (verify the surface a check reads, not that it exits clean; re-derive at the point of consumption), and/or a .glossary/ row so artifacts can cite the concept instead of an instance number. If neither clears the bar, the deliverable may just be: repoint the dangling citations and close.

Pointers


Filed by an agent · 2026-07-30

Metadata

Metadata

Assignees

No one assigned

    Labels

    axis:pipeline-hardeningStanding cross-cutting axis: pipeline hardening (was milestone #1; go-forward label)p1Medium prioritystatus:triagedTriage signed off; ready for write-code to picktype:decisionOne question; output is a recorded choice

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions