Skip to content

[finding] H19 cannot resolve a cross-repo Blocked-by: target — the exact shape contract-first dispatch produces, and its UNJUDGED row reads like a clean one #11218

Description

@os-zhuang

Finding — recording only, not claimed. Filed under the maintainer direct-dispatch channel, this session, verbatim: 「然后 把 1–4 落成 finding 卡」. PM session session_0124Qg8rLvpXnQDwCmpKUmaJ.

Measured

From anchor #9857, sweep 2026-08-23T02:11:54Z (run 32612222532):

Blocker liveness (H19): targets resolved on 17 of 19 distinct Blocked-by: target(s) named by open pm:blocked card(s)

and the row that explains the gap:

H19#10938pm:blocked and 1 of 1 Blocked-by: target(s) could NOT be resolved this sweep (objectstack-ai/cloud#944 (HTTP 404)) — so whether this block has outlived its blocker is UNJUDGED, not confirmed.

objectstack-ai/cloud#944exists and is open (title: "Five error dialects answer /api/v1, none of them the declared envelope…", carrying pm:queue). The 404 is the patrol token's repo scope, not a missing issue.

Why this matters more than 2-of-19 suggests

Cross-repo blockers are not an edge case — they are the normal output of the contract-first split. The dispatch protocol requires that a cross-repo feature become a parent plus one sub-issue per repo, with the downstream carrying Blocked-by: <owner/repo>#<n>. So the single class of blocker the protocol most reliably manufactures is exactly the class H19 cannot judge.

Live specimens found this round, all cross-repo, all currently un-judgeable by any patrol:

  • cloud#1509 (priority:p0 + security) → Blocked-by: objectstack-ai/objectstack#11184
  • cloud#1395objectstack#10101
  • objectui#4676objectstack#9019, objectui#4664objectstack#8704, objectui#5233objectstack#9933, objectui#5210objectstack#9934, objectui#5601objectstack#10054

The last five were resolved by hand this round; four had been stale for 4–7 days.

The second half: UNJUDGED does not read as unjudged

The report renders one line per unresolved target inside an H19 row. In a 94-finding report a reader skims for red; a row that says "whether this block has outlived its blocker is UNJUDGED" sits in the same visual weight as a row that made a determination. This repo has ruled on this exact hazard before — "could not read the input" must never look like "input is clean" (#4690), which is why the script exits non-zero when the whole sweep fails. The per-target failure has no equivalent.

Shape of the fix

Two independent halves; either is useful alone.

  1. Give the resolver cross-repo read. The sibling finding on the single-repo patrol needs the same thing, so these two should probably be priced together.
  2. Make an unresolved target loud — a distinct count in the header line (resolved on 17 of 19 is already there, so the datum exists; it is the per-card consequence that is quiet), or a dedicated section, so an operator cannot mistake "we could not check" for "we checked".

⛔ Which of the two, and whether a scoped token is acceptable, is a routing/security call for triage — not decided here.

Re-check

# the header line and the UNJUDGED row
gh issue view 9857 --repo objectstack-ai/objectstack --json body -q .body | grep -E 'Blocker liveness|UNJUDGED'

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions