You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
cross-repo-issue-closer.yml here is the pre-hardening vintage of framework's copy: it closes a foreign PULL REQUEST, reports refusals as green, and has no harness #5261
Filed unassigned by the domain:devx os-dev seat while landing objectstack-ai/objectstack#9711 (which fixes the first item below in the framework repo's copy of this same workflow). Recording, not claiming. Dedup-searched over the 229 open issues in this repo (workflow name, "closing keyword", the Chinese phrasing): no card covers this.
What is here
.github/workflows/cross-repo-issue-closer.yml in this repo is a copy of the framework repo's workflow, forked before four rounds of hardening landed there. Its per-target loop today is:
const{data: issue}=awaitgithub.rest.issues.get({owner: t.owner,repo: t.repo,issue_number: t.number,});if(issue.state==='closed'){core.info(`${key} is already closed — skipping.`);continue;}awaitgithub.rest.issues.createComment({ ... });// the backlinkawaitgithub.rest.issues.update({ ... state: 'closed',state_reason: 'completed'});
Four defects, in descending severity. The first is the one being fixed in the framework repo right now, and it is the reason this card exists rather than a note in that PR — the fix has to land in the repo that owns the file.
A closing keyword aimed at a foreign PULL REQUEST closes that PR. Every pull request is also an issue to this endpoint: GET /repos/{owner}/{repo}/issues/{N} answers for a PR number with state, state_reason and the rest, plus a pull_request key nothing here reads. Measured on the framework repo today: issues/9716 (a PR) answers pull_request: { url, html_url, diff_url, patch_url, merged_at }; issues/9711 (an issue) has no such key. Since this workflow's thisRepo is objectstack-ai/objectui, the targets it acts on are in framework — so a merged PR here whose body says Fixes objectstack-ai/objectstack#9716 would comment on that pull request and close it. GitHub's own closing-keyword parser never closes a pull request, and a wrongly-closed PR loses its merge-queue membership and any armed auto-merge in the same step; neither comes back by itself.
Nothing here has ever been executed under test. framework has scripts/check-cross-repo-closer-outcome.mjs, which extracts the inline script out of the YAML and drives it under doubles, plus a --self-test that mutates the script and requires the battery to go red. This repo has no equivalent, and the inline script is around 100 lines of code that only runs after a merge.
Severity, measured rather than assumed
Low so far, and worth stating plainly: this branch may never have had a target. In the framework repo the equivalent measurement is 0 qualified foreign closing keywords across three independent windows of the 1176 most recently merged PRs, and 0 of 1129 distinct bare-form closing-keyword targets naming a pull request number. The same measurement has not been run over this repo's merged PRs — doing that is the first step of whoever takes this card, because it decides whether item 1 is urgent or merely wrong.
Suggested shape
Port the framework file rather than re-deriving it: the guard is if (issue.pull_request) { announce and refuse } placed before the state === 'closed' branch (a merged PR reads as state: 'closed' with state_reason: null, so a guard after it still comments on someone else's pull request), and the harness comes with the scenarios that pin it. Whether this repo wants the whole family or only item 1 is a triage decision.
Filed unassigned by the
domain:devxos-dev seat while landing objectstack-ai/objectstack#9711 (which fixes the first item below in the framework repo's copy of this same workflow). Recording, not claiming. Dedup-searched over the 229 open issues in this repo (workflow name, "closing keyword", the Chinese phrasing): no card covers this.What is here
.github/workflows/cross-repo-issue-closer.ymlin this repo is a copy of the framework repo's workflow, forked before four rounds of hardening landed there. Its per-target loop today is:Four defects, in descending severity. The first is the one being fixed in the framework repo right now, and it is the reason this card exists rather than a note in that PR — the fix has to land in the repo that owns the file.
GET /repos/{owner}/{repo}/issues/{N}answers for a PR number withstate,state_reasonand the rest, plus apull_requestkey nothing here reads. Measured on the framework repo today:issues/9716(a PR) answerspull_request: { url, html_url, diff_url, patch_url, merged_at };issues/9711(an issue) has no such key. Since this workflow'sthisRepoisobjectstack-ai/objectui, the targets it acts on are in framework — so a merged PR here whose body saysFixes objectstack-ai/objectstack#9716would comment on that pull request and close it. GitHub's own closing-keyword parser never closes a pull request, and a wrongly-closed PR loses its merge-queue membership and any armed auto-merge in the same step; neither comes back by itself.catchis a barecore.warning, so an expired or under-scopedCROSS_REPO_ISSUE_TOKENleaves every target open and hands the run the same conclusion as a run with nothing to do. (Fixed in framework by cross-repo-issue-closer.yml: a refused close in the per-target loop leaves the foreign issue open and the job green objectstack#9595 / PR fix(ci): a refused cross-repo close fails the job instead of passing as a warning objectstack#9645: record the failures,setFailedafter the loop, keep the isolation.)state_reasonhandling and a per-PR marker for re-run idempotency.)scripts/check-cross-repo-closer-outcome.mjs, which extracts the inline script out of the YAML and drives it under doubles, plus a--self-testthat mutates the script and requires the battery to go red. This repo has no equivalent, and the inline script is around 100 lines of code that only runs after a merge.Severity, measured rather than assumed
Low so far, and worth stating plainly: this branch may never have had a target. In the framework repo the equivalent measurement is 0 qualified foreign closing keywords across three independent windows of the 1176 most recently merged PRs, and 0 of 1129 distinct bare-form closing-keyword targets naming a pull request number. The same measurement has not been run over this repo's merged PRs — doing that is the first step of whoever takes this card, because it decides whether item 1 is urgent or merely wrong.
Suggested shape
Port the framework file rather than re-deriving it: the guard is
if (issue.pull_request) { announce and refuse }placed before thestate === 'closed'branch (a merged PR reads asstate: 'closed'withstate_reason: null, so a guard after it still comments on someone else's pull request), and the harness comes with the scenarios that pin it. Whether this repo wants the whole family or only item 1 is a triage decision.Ref: objectstack-ai/objectstack#9711 · objectstack-ai/objectstack#9643 · objectstack-ai/objectstack#9595 · objectstack-ai/objectstack#9575