mirror of
https://github.com/Comfy-Org/comfy-typescript-sdk.git
synced 2026-11-04 23:47:27 +00:00
[PR #173] [MERGED] ci(cursor-review): prove the pin moved before closing the stale-pin issue #171
Labels
No labels
audit:ai-readiness
audit:community
audit:github
audit:health-scoring
audit:policy
audit:release
audit:supply-chain
bug
cursor-review-pin
effort:medium
effort:small
effort:trivial
priority:nice-to-have
priority:recommended
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Comfy-Org/comfy-typescript-sdk#171
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/Comfy-Org/comfy-typescript-sdk/pull/173
Author: @mattmillerai
Created: 9/21/2026
Status: ✅ Merged
Merged: 10/9/2026
Merged by: @mattmillerai
Base:
matt/be-15270-resync-cursor-review-pins← Head:matt/be-16376-record-pin-on-stale-issue📝 Commits (10+)
b7ea71eci(cursor-review): prove the pin moved before closing the stale-pin issued320b45Merge base 'matt/be-15270-resync-cursor-review-pins' into the pin-marker branch1e95954ci(cursor-review): stop the movement proof failing open, and fence the manual run9d5b324ci(cursor-review): stop a second dispatch cancelling the first mid-mutationfac9c52Merge base 'matt/be-15270-resync-cursor-review-pins' into the pin-marker branch33ed546ci(cursor-review): scope the pin marker to the alarm cycle, hold when unprovenaf95676Merge base 'matt/be-15270-resync-cursor-review-pins' into the pin-marker branch6a6d5b2ci(cursor-review): re-serialise sdk-parity, and key the stale report on the bump state6db283fMerge base 'matt/be-15270-resync-cursor-review-pins' into the pin-marker branch723e52fci(cursor-review): scope the dedup read, and stop the reports asserting stale facts📊 Changes
1 file changed (+830 additions, -56 deletions)
View changed files
📝
.github/workflows/ci.yml(+830 -56)📄 Description
STACKED — merging lands on
matt/be-15270-resync-cursor-review-pins(owned by @mattmillerai, PR #153), NOTmain. Thecursor-review-pin-freshnessjob this changes exists only on that branch;main'sci.ymlhas no such job. PRs #169 and #170 stack on the same base.ELI-5
The pin-freshness watchdog opens a sticky issue when this repo's
Comfy-Org/github-workflowspin goes stale, and closed that issue again as soon as nothing was "overdue". But "nothing overdue" is measured purely from the age of the oldest upstream commit this repo has not picked up — and that commit disappears from the walk, with the pin untouched, whenever upstream narrows the list of paths it watches. So the watchdog could close its own issue on a completely frozen pin. This makes it record the pin in every report it files and refuse to close unless the pin it sees now is a different one.What changed
1. Every stale report records the pin. The body the stale step writes now ends with an
<!-- cursor-review-pin: <sha> -->HTML comment — invisible to a reader. That body is re-commented once per report rather than once per run — keyed on the pin, the bump-PR state and the date basis of the grace verdict, since the report's premise and its step-1 remediation both branch onBUMP_PR/BUMP_DELIVERS, so the same frozen pin produces a materially different report once a bump PR opens against it, stops carrying the owed commit, or ages back out ofdelivered. A sibling<!-- cursor-review-pin-report: <pin> <pr> <delivers> <date-basis> -->marker records that key; it is a separate marker precisely so the close step's movement proof, which matchescursor-review-pin(-held|-unknown)?:against an exact 40-hex string, cannot see it. The fourth field is theFUTURE_DATEDselector, because the report'soverdueparagraph branches on it as well — without it, a frozen pin whose oldest owed commit turns out to be future-dated kept a durable report giving the other diagnosis. The key omits the bump PR's age and the day-varying upstream facts (NEWEST_SHA,NEWEST_DATE,BEHIND_COUNT), which move whenever upstream lands a watched commit, pin or no pin, and so would defeat the suppression on exactly the long-frozen pins it exists for. Those are handled in the body instead: it labels both a snapshot of one run, and step 3 no longer namesNEWEST_SHAas the SHA to hand-bump to — it sends the reader to the newest daily run's log for the current tip. That was the one with teeth: a maintainer following a suppressed, weeks-old report would move the pin to a SHA still far behind, and the close step reads any movement off the recorded marker, so it would then close the alarm asserting a bump landed. Deduping at all matters because a frozen pin, the very state this watchdog exists to report, otherwise accrued one whole report a day on the same thread the close step must--paginatein full. On reopen it is posted before the reopen, so an open issue always carries the current cycle's marker. The last marker recorded in the current alarm cycle — at or after the moment the issue was last closed — is the pin as of the most recent report. This dedup read is scoped to that same cycle, and by the same anchor, as the close step's movement-proof read: unscoped, the two steps disagreed about which markers exist, so a hand-reopened alarm (or one whose reopen run died after posting) was suppressed on the previous cycle's markers — left with a stale Run URL and backlog count, a::notice::claiming a report was already there, and a close step that then found nothing in-cycle and held it open an extra day. A failed read still falls through to commenting, and now says why in a::warning::rather than swallowing the error, since a persistent failure silently reverts the step to commenting once per run — the unbounded growth the dedup exists to stop. No escaping is needed:assessasserts the value is 40-hex before writing it to$GITHUB_OUTPUT, so it cannot break out of the comment.2. The
graceclose proves movement first.currentstill closes unconditionally.gracenow reads the recorded pin back and branches four ways: a different pin closes with "The pin moved fromxtoysince it was last recorded on this issue, so a bump landed"; an equal pin does NOT close — it comments why the backlog shrank without the pin moving, emits a::warning::and exits 0 (the verdict is stillgrace, i.e. passing) — and what it is willing to claim there depends on whether this alarm cycle ever recorded the pin while the backlog was still overdue. Only the stale step's plaincursor-review-pin:marker is written in that state —-heldand-unknownare both written fromgrace, i.e. after the backlog shrank — so the test is over the whole cycle's records: with a plain marker for this pin in the cycle, upstream narrowingWATCHED_PATHSPECSis named as the likely cause; without one, the comment says only that the pin has not moved since it was first sighted and states outright that a bump landing before that is indistinguishable from a narrowed watch list. Two rounds were needed to get this right. Byte-identical markers first made the no-baseline case assert the other case's cause as fact; splitting out-unknownfixed the run that reads it directly but not the one after, because that run's-heldmarker — written by the weak branch itself — read as a real predecessor and laundered the chain back to the strong claim one cycle later. Keying on the cycle's plain markers rather than the newest marker's form is what actually closes it: a-heldrecord is still honest that the pin has not moved since it, but it cannot vouch for a predecessor it never had. This matters on exactly the ship-day input the branch exists for, where a bump that lands and reachesgraceis what gets recorded with no baseline; no marker in this cycle does NOT close either — there is nothing to compare against, and that is precisely the state in which a real bump and a narrowedWATCHED_PATHSPECScannot be told apart, so it RECORDS the current pin as a distinct<!-- cursor-review-pin-unknown: <sha> -->marker, emits a::warning::and holds the issue one more cycle; it cannot stick open, because that marker is what closes the issue tomorrow if the pin moved; a failed read is UNKNOWN, which is neither "moved" nor "no marker", so it does NOT close either — it emits a::warning::carrying gh's stderr and leaves the issue open for the next scheduled run to read again.The equal-pin branch comments once per pin, not once per run: it ends its comment with a sibling
<!-- cursor-review-pin-held: <sha> -->marker and skips the comment when that is already the newest marker on the thread. The::warning::still fires on every held run, so nothing goes unreported. A later stale report writes a plain marker that is newer, so a fresh entry into the state is still announced. The movement comparison reads the newest marker of any of the three kinds, so a held or unknown record counts as a record; the three forms cannot cross-match, and the-reportmarker stays invisible to both greps.A marker only counts if it was recorded in the current alarm cycle — at or after the moment the issue was last closed. Unscoped, the “different pin” test proves inequality rather than “a bump landed since the alarm came back”, and two ordinary sequences reach it: a run dying between the reopen step's two API calls, and a maintainer reopening a wrongly-closed alarm by hand. Both leave an open issue whose newest marker is a previous cycle's pin, so the next
gracerun closes the alarm claiming a bump landed — on a pin nothing has touched. Scoped, both land on the no-marker branch and hold. The anchor is the lastclosedevent rather than the lastreopenedone precisely because the report is posted before the reopen: anchoring on the reopen would exclude the very marker the reopen just wrote. A reopened issue therefore reads its comments only; the filing body is read only when the issue has never been closed, since otherwise it belongs to an earlier cycle.currentstill closes with no movement proof, and that is a decision rather than the same hole one door over:currentmeans nothing is owed at all, so this issue's premise — a backlog frozen past the grace window — is gone whatever removed it. A narrowedWATCHED_PATHSPECScan reachcurrenton a frozen pin, and if it does, this watchdog has nothing left to say; a pin that is wrong rather than merely behind isworkflow-pins' beat. The issue body says as much ("closes itself on the first daily run that finds the pin moved, or nothing owed").The read is
gh apion the issue andgh api --paginateon its comments, deliberately notgh issue view --json comments— that returns only the first 100 comments, which a sticky issue commented on daily passes inside about three months, after which the newest marker would fall off the end and the step would compare against a stale one.3.
workflow_dispatch, kept permanently. The job isif: github.event_name == 'schedule'andon:had no manual trigger, so nothing about this job — verdict or sticky-issue behaviour — is reachable from any PR run, and a change to it could previously only be validated by waiting a day. It is also the only on-demand way to re-run the watchdog after a bump lands.sdk-parity's issue steps gate ongithub.event_name == 'schedule'themselves and are untouched, so a manual run does its network check and touches no issue. Dropping cancellation forschedule, however, did reachsdk-parity: that job runs on the cron, does the same non-atomic list-then-mutate against a title-matched sticky issue, and had no job-level group of its own, so it had been relying on run-level cancellation to stay single-instance. It now carries its ownsdk-parity-${{ github.event_name == 'schedule' && 'schedule' || github.run_id }}group withcancel-in-progress: false. Only scheduled runs share it —github.run_idis unique per run, so PR and push runs keep going fully in parallel. Because that group no longer cancels in progress, the job also gainedtimeout-minutes: 15:scripts/sync-python-surface.mjsis the one step here that reaches the network and fetches with noAbortSignal, and undici'sheadersTimeout/bodyTimeoutare inactivity-based, so without a bound a trickling response would hold the group for the six-hour default and queue every later scheduled run behind it.This job does touch its issues on a manual run — that is the point of having one — so it carries two guards of its own. Its
actions/checkoutis pinned togithub.event.repository.default_branch, not the dispatched ref. The ref is caller-chosen and the pin is read out of the working tree, so without that pin a run dispatched from a bump branch (or from a branch used to test the job, which theon:comment recommends) would assess a pin that has not landed, close the real alarm on it, and write that unlanded pin into the marker governing every later close. It costs nothing the manual run is for: GitHub runs the workflow FILE from the dispatched ref either way, so the job's own YAML and inline shell are still exercised end to end, sticky issue included — only the tree the pin is read out of comes from where the pin ships. It does not exercise an uncommitted change toscripts/check-workflow-pins.mjs, which is invoked out of the checkout; that script is covered byworkflow-pinson ordinary PR runs. And overlapping runs are serialised by a PAIR ofconcurrencysettings, neither of which is sufficient alone. Every issue step is a non-atomic list-then-mutate (gh issue list, thencreate/reopen/comment/close) against one shared sticky issue, so overlapping runs could file duplicates, or have the slower one reopen a thread the faster one just correctly closed. Dispatch vs cron: the workflow-level key includesgithub.event_name, which stops a push cancelling the cron but also let a manual run execute concurrently with it; the job now carries its own group WITHOUT the event name, which queues rather than cancels, since cancelling would abandon a half-applied mutation. Dispatch vs dispatch: two dispatches of the same ref DO land in the identical run-level group, and a job-level group cannot override run-level cancellation — so the second run would have cancelled the first outright, mid-mutation, which is precisely the state the job group was added to avoid. The workflow-levelconcurrencytherefore drops cancellation for the two events that reach this job (cancel-in-progress: ${{ github.event_name != 'workflow_dispatch' && github.event_name != 'schedule' }}); every other event keepstrueunchanged, since on a PR or a push only the newest commit's verdict matters. Cron vs its own re-run:scheduleis on that list even though the 07:17 cron cannot overlap itself under a 10-minute job timeout — “Re-run all jobs” keeps the originalscheduleevent and ref, so a re-run lands in the identical group and would cancel an in-flight cron run mid-mutation, exactly like the dispatch case. A re-run is a deliberate act taken when the cron run looked wrong, which is precisely when it is most likely to still be running. The cost is that two same-ref runs of these events also run the ordinary test matrix twice instead of superseding — and onschedule, not even that, sincetestis skipped there. A manual dispatch or re-run is a rare deliberate act, and duplicated runner minutes are cheaper than a corrupted alarm.current,deliveredand theassessstep are unchanged.4. Merged the base branch, three times. Round 12 (
9d84ec9). It rewrote the same watchdog step this PR is changing, so the two conflicted. Both conflicts were resolved keeping both sides, and two of base's fixes that this PR's rewrite had silently undone are re-applied on top of the new four-branch structure: the paragraph break (a""element inside a singleprintf '%s 'list is joined with a space, emitting one extra SPACE rather than the blank LINE markdown needs — each grace branch now builds its second paragraph separately and joins withprintf '%s\n' "$premise" "" "$para2", so all four carry the fix, not just the one base had), and the de-hardcoded default branch (base resolves it once fromrefs/remotes/origin/HEAD; this PR's rewrite had reintroduced a literalgithub-workflows@mainin the shared premise and in the frozen-pin comment'sWATCHED_PATHSPECSpath, both now$UPSTREAM_BRANCH). Base's per-verdictstep1remediation and this PR's pin marker are independent additions to the stale-report body and both survive.dependabot.ymlandcheck-workflow-pins.mjsmerged clean and are identical to base.Round 18 (
673888f). Same step, same kind of conflict; this branch's movement-proof rewrite was kept and base's one substantive change carried into it (the grace window is quoted from$GRACE_DAYSrather than spelled3-dayby hand).Latest. Base moved the watchdog's issue lookups off exact-title matching and onto per-mode labels (
cursor-review-pin-stale/cursor-review-pin-blocked, both created idempotently and both applied atgh issue create), because a title is human-editable and a maintainer retitling the sticky issue made every later lookup miss; and it made every CLOSE path close every open match rather than only the first. That lands on the sameClose the stale-pin issuestep this PR rewrites, so it conflicted again. Resolved keeping both: the sticky thread is now found byMODE_LABELwithmin_by(.number)— the same lookup the open/update path uses, which matters here because the movement proof has to be read off exactly the thread the stale step records its markers on — and the title compare is gone. That last part is load-bearing rather than cosmetic: base had already droppedTITLEfrom this step'senv:, so keeping this branch'sselect(.title == env.TITLE)would have leftenv.TITLEunset and the lookup silently matching nothing, i.e. an alarm that never closes. A missing open match now exits early instead of falling into a marker read that has no thread to read;currentstill closes unconditionally andgracestill runs all four marker branches, three of which hold the issue open; and the two branches that DO close fall through to base's close-every-open-match loop instead of closing the one issue alone. The sibling steps (stale-report open/update, bump-PR note, watchdog-blocked open and close) merged clean, so this PR's once-per-pin dedup and its comment-before-reopen ordering now sit on top of base's label lookups.How this was tested
workflow_dispatchmade the job runnable on a branch, so the paths below were exercised against the real workflow, on real runs, against real issue #171.staleon this PR's branch<!-- cursor-review-pin: 425c154… -->(change 1, live)grace, recorded pin EQUAL::warning::grace, recorded pin DIFFERENT425c154…toebfd9e4…since the last stale report, so a bump landed"Runs 2 and 3 came from two throwaway branches (
GRACE_SECONDSraised to one year to force agraceverdict, and for run 3 the caller pin rewritten to an older SHA so the recorded pin differed). Both branches are deleted; this PR's branch carries neither edit —GRACE_SECONDSis still"259200" # 3 daysand the caller pin is still425c154ce5049324ee23ad10e106baeed4cfa31b.The author filter on the comment read was verified live against #171's real
github-actions[bot]comments, and the exact two-call read pipeline returns the recorded marker. That live check used the original.user.type == "Bot"spelling; the review round replaced it with.user.login == "github-actions[bot]"(see below), which is strictly narrower over the same #171 comments.Run 3's quoted message ("…since the last stale report") is what that run really emitted; the review round reworded it to "…since it was last recorded on this issue", because the read can legitimately fall back to the marker in the issue body, which is the filing report rather than the last one.
The ticket's premise that upstream narrows its watched list was checked against the two upstream commits it names:
Comfy-Org/github-workflows@90da1d5(#324) is "exclude tests/ and README.md from the agents-md, coderabbit-config, groom and cursor-review fleets", and@422cfa4(#302) addsWATCHED_EXECto five fleets. Both move the watched set under a frozen pin, which is exactly the failure mode this closes.Local, on this branch:
node scripts/check-workflow-pins.mjs(1 caller, pins agree),node scripts/check-public-repo-hygiene.mjs(clean),pnpm lint,pnpm format:check,pnpm typecheck,pnpm test(26 files, 620 tests, all passing), plusshellcheckclean on both rewritten step scripts and a stubbed-ghharness driving all fourgracebranches.On capability: this change adds paths that decline to close an issue rather than paths that refuse a caller, and both outcomes of the equal/differing decision were produced on live runs rather than asserted by a test. The review round does narrow one thing on purpose — a
workflow_dispatchrun no longer judges the dispatcher's own tree — and that is the point of the fix, not a side effect; the manual run's actual purpose (exercising the job and its sticky-issue behaviour on demand) is preserved, because the dispatched ref still supplies the workflow file that runs.Judgment calls
select(.user.login == "github-actions[bot]")), which the plan did not ask for. Anyone can comment on an issue in a public repo, and this marker is the movement proof — an unfiltered read would let a drive-by comment carrying a different 40-hex value close the very issue this check exists to hold open. This started as.user.type == "Bot"; the review round narrowed it, becausetypeauthenticates by actor class and every GitHub App installed on this public repo is aBot, so that spelling trusted all of them — including a compromised one — rather than just the identity this job posts under. The body is read unfiltered because this job opens it. If the workflow token ever stops posting asgithub-actions[bot], the filter finds nothing. On an issue that has never been closed the read still falls back to the marker in the issue body — a genuine report, the filing one. On a reopened issue the body is out of scope by the rule above, so the read finds nothing and lands on the no-marker branch, which records the pin and holds. Both degrade safely rather than going wrong. (Two earlier drafts got this backwards in opposite directions; it is now stated per case.)&&, not;as the plan sketched, so a failure of either surfaces as a non-zero status instead of being masked by the other succeeding.?per_page=100on the comments call, to cut the number of paginated requests on a long-lived sticky issue.--paginatein full, so the read grew without bound and got steadily likelier to hit the unreadable branch, which now holds the issue open. The reason stays visible on the thread via the one comment, and every held run still annotates its own log.::warning::carrying gh's stderr escapes%before flattening line breaks. Workflow-command messages are percent-decoded by the runner, so an unescaped percent-encoded URL in stderr would be mangled or would inject extra log lines.Residual
gh, because no marker-less sticky issue existed and manufacturing one meant opening a decoy issue on a public repo. Both now close nothing — the conservative direction — but nothing has run them against the real GitHub API. The same applies to everything added since those threeworkflow_dispatchruns, which predate it: the once-per-pin dedup on both the held-open branch and the stale step, the default-branch checkout, and the cycle-scoped marker read (including itsissues/<n>/timelinecall, whose shape is asserted only against a stub).gracecomments and the one-year grace window they were judged against come from those scratch branches, not from a scheduled run. Anyone reading that thread should skip the first four comments.deliveredis untouched and still suspends the watchdog on the strength of an open bump PR, bounded only byBUMP_PR_GRACE_SECONDS. That path has its own open question and is explicitly out of scope here.cursor-review-pin-report:andcursor-review-pin-unknown:markers, the cycle-scoped dedup read, andsdk-parity's new concurrency group and timeout have not run live. All are verified by a YAML parse,bash -n,shellcheck, and — for the markers and the dedup — the real blocks extracted from the parsed workflow and driven through a stubbedgh. GitHub's run-level concurrency cannot be exercised from a worktree, and atimeout-minutescan only be observed by wedging a run.cursor-review-pinlabel, so once #153 merges every--label "$MODE_LABEL"lookup misses it: the stale path files a duplicate and neither close loop can ever close #171. The label scheme is entirely the base's (20+ sites; this PR'sbase...HEADdiff has one such lookup, inherited into the close step by a merge resolution), so it has to be fixed on #153 — a one-shot backfill or a legacy title fallback. Raised by 3 of 6 round-19 reviewers, triaged on that thread and recorded as a follow-up.sdk-parityfails on every run of this branch (including run 1 above). That is pre-existing drift against the Python SDK, tracked by PR #167, and is unrelated to this change.Provenance
31f9a66, which this round did not move: no commit was pushed, and the only change is to this description. On arrival nothing was outstanding on any mechanical axis —mergeable: MERGEABLEwith the base tip56a738balready an ancestor (nothing to merge), all 27 review threads resolved, every PR check passing, and no merge-queue run on anygh-readonly-queue/.../pr-173-*ref, so no ejected merged result to reproduce. The two newest commits (723e52f,31f9a66) were pushed AFTER the last panel round, which ran on6a6d5b2, so they carry no panel findings of their own; rather than take the prior round's word for them they were re-verified from scratch here. The whole local gate was re-run in a clean isolated worktree:pnpm test620 passed / 0 failed (26 files);pnpm lint,format:checkandtypecheckclean;check-spec-drift.mjs,check-workflow-pins.mjs(1 caller, pins agree) andcheck-public-repo-hygiene.mjsclean;ci.ymlparses (6 jobs) andbash -nplusshellcheck -S warningare clean across all 21runblocks — independently reproducing every count the prior round claimed. The realbaseline/held_reportedcaseblocks were then extracted verbatim from the PARSED workflow and driven through 11 thread shapes. That confirms the laundering chain the last commit exists to close:-unknown→-held→-heldnow holds atbaseline=unprovenat runs 3 AND 4, where keying on the newest marker's form had flipped run 3 toproven; a plain in-cyclecursor-review-pin:marker for THIS pin is the only record that selectsproven;cursor-review-pin-report:cannot vouch as a plain marker; andheld_reportedstill suppresses only on an exact-held: $PINnewest marker. No regression — every shape that closed before still closes, and the shapes whererecorded != $PINnever reach the baseline test at all. Two stale claims in this description were corrected: 1 carried a duplicated clause, and 2 quoted the PRE-REWORD close message ("…since the last stale report") as current behaviour when the code says "…since it was last recorded on this issue" — a drift## How this was testedalready records for the run-3 table row, but which had not been carried into the behaviour summary. Prior round (head31f9a66): review round on head31f9a66. On arrival this PR had nothing outstanding on the mechanical axes:mergeable: MERGEABLEwith the base already merged in at56a738b, all 27 review threads resolved, every PR check passing, and no merge-queue run on anygh-readonly-queue/.../pr-173-*ref (so no ejected merged result to reproduce). The round-20 findings remain addressed as described below. This round's one change came from adversarial self-review of that fix and is its own commit: the no-marker branch's-unknownmarker stopped the NEXT run asserting theWATCHED_PATHSPECScause without a baseline, but the run after that one saw the-heldmarker the weak branch had just written, scored itbaseline=provenand asserted the cause anyway — the same wrong claim, one cycle later, on the ship-day input where a landed bump is what gets recorded with no baseline.baselineis now computed over the whole cycle's records (proven iff a plaincursor-review-pin:marker for this pin was filed in this cycle) instead of from the newest marker's form, and the marker-writing comment no longer claims a-heldrecord can upgrade the chain — see 2. Comparison is acaseglob over the already-read$reports, not| grep -q, whose SIGPIPE/141 under theset -o pipefailin force would read a match as a miss. No branch that closed before closes now;held_reported, the four branches and the marker greps are unchanged. Prior round (head723e52f) addressed all seven open round-20 panel findings, none deferred and none judged wrong. Three Medium: the stale step's dedup read took the whole thread while the close step scoped its read to the alarm cycle, so a hand-reopened alarm was suppressed on the previous cycle's markers (both reads are now scoped by the sameclosedanchor — see 1);REPORT_KEYdid not cover theFUTURE_DATEDbranch, and the body's day-varying upstream facts were being carried as current by a suppressed report, step 3 included (key extended, body relabelled a snapshot, step 3 now points at the run log — see 1); and the no-marker branch recorded a-heldmarker byte-identical to the held branch's (distinct-unknownform — completed by this round's fix above). Three Low and a Nit:sdk-parityhad notimeout-minutesunder its new non-cancelling group (now 15 — see 3); the dedup read's2>/dev/nullhid a broken dedup (stderr captured,::warning::emitted); and two comment-accuracy fixes (the!cancelled()note contradicted theconcurrencyblock in the same diff, and "once per pin" is "once per report" now). It changed.github/workflows/ci.ymlonly. Local, in a clean isolated worktree (base already an ancestor, nothing to merge):pnpm test: 620 passed, 0 failed (26 files);pnpm lint/format:check/typecheck: clean;node scripts/check-spec-drift.mjs,node scripts/check-workflow-pins.mjs(1 caller, pins agree) andnode scripts/check-public-repo-hygiene.mjs: clean. On the workflow itself:ci.ymlparses, andbash -nandshellcheck -S warningare clean across all 21runblocks. The realbaseline/held_reportedblock was extracted from the parsed workflow and driven through 11 thread shapes — all three marker forms, the laundering chain at runs 2/3/4, a plain report filed on a different pin, a re-report after a hold, and the-reportmarker (which must not vouch as a plain one) — with every expected verdict. No liveworkflow_dispatchrun was made this round or the last; the three runs listed under How this was tested predate everything added since.bash -n/shellcheck, not on a live run — the held-open branch it corrects is reached only from a scheduledgraceverdict on an alarm whose cycle carries no plain marker, which cannot be staged without a decoy issue on a public repo. Likewise the no-marker branch, the read-failure branches, the report dedup on both the stale and held-open paths, the default-branch checkout, the cycle-scoped marker reads, thecursor-review-pin-report:andcursor-review-pin-unknown:markers, andsdk-parity's new concurrency group and timeout are verified locally (YAML parse,bash -n,shellcheck, greps andcasebranches driven directly) rather than on a live run — see## Residual. Theissues/<n>/timelineread in particular has not been exercised against the real API — and this round added a second such call, in the stale step — while GitHub's run-level cancellation cannot be exercised from a worktree at all. CI on this PR runs no test/lint gates whatsoever, because the base is not the default branch (CodeRabbit reports "reviews are disabled for this base branch"), so the local results above are the only functional evidence for this round — the green check list on this PR is the cursor-review panel and policy checks, not a test run. One known defect is knowingly left unfixed here because it is the base's, not this PR's: the missing mode-label backfill described under## Residual, which must be fixed on #153 before that branch merges.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.