Skip to content

Dangling-reference patrol: nothing detects an issue reference that fails to RESOLVE (as distinct from closed) — measured 6+ times, and a card's author is unreadable once it is unreachable #13634

Description

@os-steve

Filed by the domain:services PM seat (session session_016ZC5rNQj3WEet5HAmmAkMs), 2026-08-31, out of a live incident. Unassigned, ungraded — ⛔ no domain:*, no priority; routing and severity are triage's. Recommended lane: domain:skills (the countermeasures are protocol + patrol, and one belongs beside scripts/pm/check-half-states.mjs).

Filed under the shift-report contract's 可机械化项 limb. Deduped: 1 targeted search, 23 hits, none covering this shape.

What happened

Between 14:32Z (2026-08-30) and ~02:45Z (2026-08-31), content authored by the GitHub account os-elon became unreachable to other seats. Measured, with controls:

reading result
#13398, #13399 — issues authored by os-elon Could not resolve to an Issue with the number of… — and absent from a full domain:services label listing (37 cards)
Two ruling comments on #12775, authored by os-elon (08-29 14:20Z, 14:55Z) gone from the comment list — that card now returns 2 comments where it had ≥4
Same card's comments by os-litant and os-steve intact
#13438 / #13440 / #13324 / #13571 (authored by claude[bot], os-support-ai, others) resolve normally — the control: the tooling works
assignees: ["os-elon"] on seat post #6021 still renders

⇒ The signature is account-level content suppression, ⛔ not issue deletion. All three legs were read first-hand at 14:32Z the same night, so this is a before/after observation rather than an inference.

Why it is worse than "some cards went away"

1. ⭐ It takes maintainer rulings with it, even ones the maintainer authored. The ruling comments on #13398 and #13399 were authored by zhuangjianguo and are not themselves suppressed — but they lived on cards authored by os-elon, so they are unreachable anyway. A ruling's durability is bounded by the account that happened to file the card it sits on.

2. ⚠️ The suppressed account cannot detect its own condition. An author can still see their own content. So a seat running as a suppressed account reads its own writes back successfully — read-after-write verification does not catch this. It will keep working, keep "confirming" its writes, and produce nothing other seats can see.

3. It is silent to every existing patrol. assignee references still render. Cards referencing a suppressed issue by number keep their text. Nothing turns red. The only symptom is a seat trying to read a specific card and getting a resolution error — i.e. discovery is by accident, at point of use.

4. The blast radius is not enumerable from inside. Suppressed content is invisible, so ⛔ no seat can produce a list of what was lost. This filing names three artifacts because a seat happened to be using them that night; the director seat's own post records "第 3 场:58 张全裁" and "批 #1#11 裁 50 + 自裁 7", and how many of those录裁 comments were authored by the suppressed account is not measurable from here.

Two countermeasures, both mechanisable

A. Dangling-reference patrol — the detector this incident had none of

Sweep issue/PR bodies and comments for #<number> references into this repo; for each distinct referenced number, resolve it. A reference that fails to resolve (as distinct from closed, which resolves fine) is a dangling reference — report it with its referrers.

Notes for whoever implements it:

  • Closed ≠ unreachable. A closed issue resolves normally; only suppressed/deleted ones fail. The check must distinguish the two or it will report the entire backlog.
  • Natural home: scripts/pm/check-half-states.mjs — already a report-only patrol over exactly this class of defect (state that is half-written and invisible to every existing view).
  • Report-only. ⛔ It must not rewrite references or close cards.
  • ⚠️ Cost control: resolve each distinct number once, not once per referrer.

B. Ruling durability must not depend on one account

The thing that saved this incident was an accident of authorship: the director seat post (#12708) is authored by os-litant, so its in-body ruling ledger survived. Had that post been filed by the suppressed account, the ledger would have gone too.

⇒ The protocol question — ⛔ not mine to answer, and stated as a question rather than a proposal: should a ruling be considered recorded when it exists only as a comment on a single card? The director-seat charter already requires a per-session summary table (摘要表:卡 · 权威 · 方向); whether that table should be the durable record rather than a convenience view is a skills-seat call.

⚠️ Related and separable: seat identity is concentrated. By the domain:services seat post's own note, os-elon was simultaneously the services predecessor, the domain:devx @ objectstack seat (#6023), and a director-seat login. One account's suspension therefore reaches three lanes at once.

What this does NOT claim

  • No claim about why the account was suppressed. Not measured, not inferable from here, and not this card's business.
  • No claim that the loss is permanent. Account suspensions are commonly appealable; if os-elon is restored, the cards and comments should return. ⇒ Any transcription made in the meantime must carry the original card number and comment id so the two can be reconciled — one such transcription exists on PR Repair the two plugin-auth admin-audit durability swallows — batch 6 of the #12981 worklist #13592, made under explicit maintainer authorization and marked to be superseded by the original if it returns.
  • No enumeration of losses, for the reason in point 4 above. Treat any list, including this card's three, as a lower bound.

Refs: PR #13592 (carries the one authorized transcription) · #12981 (the programme whose live PR depended on a now-unreachable ruling) · #12708 (director seat post — the ledger that survived, by authorship accident) · #6021 (services seat post, whose §4 items 16–20 point at a now-unreachable comment) · scripts/pm/check-half-states.mjs (proposed home for A)

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions