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
{{ message }}
This repository was archived by the owner on Oct 26, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Oct 26, 2026. It is now read-only.
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.
Triage: pm:queue · Task · tooling. Port the framework-hardened cross-repo-issue-closer.yml family rather than re-deriving it: PR-guard placed before the already-closed branch, refusal accounting (setFailed after the loop), backlink-on-closed with state_reason handling and re-run idempotency, and the extracted-script harness with --self-test. First deliverable is the measurement over THIS repo's merged PRs (it decides whether item 1 is urgent or merely wrong), as the card states. Serial note for the claimer: objectstack#9711 is in flight on the framework copy — port the post-#9711 vintage, and name that PR in the claim's serial-constraints line.
Claim: PM loop round 13
Session: session_01RV6yuVCxymHYE16PL9vQkE
Branch: claude/issue-5261-port-hardened-cross-repo-closer
Worktree: objectui-issue-5261
Domain: repo:objectui (tooling / CI)
File surface: .github/workflows/cross-repo-issue-closer.yml + the extracted script and its harness under scripts/ (stop on breach; explain in the report)
Container & model: M, mode:subagent, model: opus
Clause-②: no — CI-time only; no published surface, no accept-set change.
Serial constraints cleared: .github/workflows/ is free — #5246 landed (PR5273) and nothing else is in flight there. The four other in-flight cards are in packages/plugin-view (#5270), apps/console (#5286), eslint-rules/ (#5191), and content/docs/** (#5271). ⚠️ Note PR #5207 is open on packages/plugin-dashboard and unrelated to this surface.
{
"issue": 5261,
"status": "done",
"branch": "claude/issue-5261-port-hardened-cross-repo-closer",
"pr": "https://github.com/objectstack-ai/objectui/pull/5295",
"premise_still_valid": true,
"summary": "Ported the framework-hardened cross-repo-issue-closer family from objectstack-ai/objectstack cb9ff23fa (repo head a065e4655) rather than re-deriving it: the issue.pull_request guard placed BEFORE the already-closed branch, refusal accounting (setFailed after the loop, the catch's isolation unchanged), backlink-on-closed split three ways by state_reason with a per-PR marker for re-run idempotency, plus the extracted-script harness and its --self-test, wired into lint.yml. FIRST DELIVERABLE, the measurement over THIS repo, and it is NOT the framework's zero: over all 3425 merged PRs here (#1..#5288, the closed-PR listing paged to exhaustion at 37 pages), 60 carry a qualified foreign closing keyword (61 occurrences, 59 distinct targets) against the framework's 0-of-1176; of the 57 targets that resolve, ZERO name a pull request (2 unresolvable: objectstack-ai/cloud#667 and #654, this session's proxy answers 403 for that repo and add_repo reports no access; 5 more resolve only via the objectstack-ai/framework and objectql/objectui renames and are all issues). Counter-probes so those zeros are readings: 246 qualified same-repo references and the bare form in 972 of the same PRs. The severity finding is defect 3, not defect 1: since this workflow landed here on 2026-08-09 (#3969) 15 merged PRs carried a foreign target, and in 14 of the 15 the framework issue was closed by a seat 1-2 seconds after the merge, BEFORE the workflow run was even created (the 15th's close lands in the same second the run is created, runner later still) - so the loop hit state === 'closed' 15 times out of 15, skipped each target whole, left no backlink on any of them, and reported success, as have all 941 runs of this job. Quiet/warn/red judgement: RED, matching the framework's landed version (warning annotation naming the target plus a post-loop setFailed carrying the malformed class separately from the refusal class); convergence is the card's binding scope, and this repo's own facts support it more strongly than the framework's did - affordability re-derived here rather than inherited: the main ruleset (11776024) has no required_status_checks rule at all, the job runs only after the merge, and this repo has no workflow_run listener.",
"tests": "All at HEAD a5a0678ac (the commit the PR is opened on). EXECUTED, green: `node scripts/check-cross-repo-closer-outcome.mjs --self-test` -> '77 assertions, 14 mutations of the shipped script each driven to red'; `node scripts/check-cross-repo-closer-outcome.mjs` -> 'OK (105 assertions over 18 scenarios, driving the 18420-char script extracted from .github/workflows/cross-repo-issue-closer.yml)'. REVERSE VERIFICATION (the refusal-accounting proof the bar asks for): the module is inert on import by design, so judge() was pointed at a tree holding this repo's origin/main copy of the workflow - same 105 checks produce 40 failed assertions there and 0 here, including '[L3] L3 FAILS the job -- the defect this card is about; got 0' (L3 simulates one target's issues.get refused with HTTP 404 while the other two stay reachable: pre-port calls setFailed zero times, ported goes red and still closes the other two) and '[L12] L12 still closes the other two targets -- isolation holds; got 3' (pre-port closed all three, one of them a pull request). No rebuild is involved in either leg - the harness extracts the shipped YAML bytes and runs them as an AsyncFunction, there is no dist/ in the path. Also executed green: check-control-bytes, check-changeset-presence (4 files changed, 0 under a released package src/, exits 0 - no changeset owed, and objectui has no skip-changeset label so none was applied), check-changeset-no-major, check-lint-coverage, check-type-check-coverage, check-node-esm-load, check-phantom-dependencies, check-action-forward-parity, check-published-dist-tooling, check-skills-paths, `npx eslint scripts/check-cross-repo-closer-outcome.mjs`, and `vitest run --project unit scripts/__tests__` = 55 files / 1272 tests passing (includes the four that pin these workflows: ci-cd-pipeline-doc, lint-workflow, merge-queue-reporting, dependabot-merge-gate). YAML validity and the credential walk were machine-diffed old vs new: trigger, top-level permissions, absence of job permissions, merged==true gate, action version, github-token expression and step env all SAME; added only the step inputs retries:3 and retry-exempt-status-codes:400,401,404,422, and one new read-only API method (issues.listComments) on a repo the token already comments on and closes in. NOT executed and not claimed: GitHub Actions cannot run locally, so nothing here asserts a real run of the workflow. objectui has no scripts/pm/dispatch-gates.mjs (framework-only), so the gate set was derived by hand from the changed paths.",
"open_questions": [],
"out_of_scope_findings": [
"filed as objectstack-ai/objectstack#9917 (label `finding`, unassigned): the framework's own copy of this family carries two wrong/stale evidence citations - its harness cites objectui#4478 as a closed ISSUE answering state_reason null when that number is a PULL REQUEST (which is why it answers null, and which is the very thing L13 refuses), and its lint.yml step comment hand-counts 'seven ways' / 'Ten scenarios' where MUTATIONS now holds 14 and SCENARIOS 18. Comments only, no behaviour at risk; the port deliberately dropped both counts rather than carrying them across."
]
}
File surface, wider than the card declared
The card scoped this to the workflow plus the script and harness under scripts/. Two additions were needed and are in the PR:
.github/workflows/lint.yml — the wiring. Without it the harness runs nowhere, and the self-test asserts the wiring is present (it was red on exactly those two assertions until the step landed).
package.json + pnpm-lock.yaml — extractScript needs a real YAML parser rather than a hand-rolled one. yaml@2.9.0 was already resolved in this lockfile as a transitive, so the delta is three lines and no new package version enters the tree; the framework declares the same yaml: ^2.9.0 at its root.
Activity
os-support-ai commentedon Aug 18, 2026
Triage:
pm:queue· Task ·tooling. Port the framework-hardenedcross-repo-issue-closer.ymlfamily rather than re-deriving it: PR-guard placed before the already-closed branch, refusal accounting (setFailedafter the loop), backlink-on-closed withstate_reasonhandling and re-run idempotency, and the extracted-script harness with--self-test. First deliverable is the measurement over THIS repo's merged PRs (it decides whether item 1 is urgent or merely wrong), as the card states. Serial note for the claimer: objectstack#9711 is in flight on the framework copy — port the post-#9711 vintage, and name that PR in the claim's serial-constraints line.Generated by Claude Code
os-support-ai commentedon Aug 19, 2026
Claim: PM loop round 13⚠️ Note PR #5207 is open on
Session:
session_01RV6yuVCxymHYE16PL9vQkEBranch:
claude/issue-5261-port-hardened-cross-repo-closerWorktree:
objectui-issue-5261Domain:
repo:objectui(tooling / CI)File surface:
.github/workflows/cross-repo-issue-closer.yml+ the extracted script and its harness underscripts/(stop on breach; explain in the report)Container & model: M,
mode:subagent,model: opusClause-②: no — CI-time only; no published surface, no accept-set change.
Serial constraints cleared:
.github/workflows/is free — #5246 landed (PR5273) and nothing else is in flight there. The four other in-flight cards are inpackages/plugin-view(#5270),apps/console(#5286),eslint-rules/(#5191), andcontent/docs/**(#5271).packages/plugin-dashboardand unrelated to this surface.分诊的串行注记已现读,并且它现在过期了 —— 朝好的方向。 注记(2026-08-18 23:15Z)写
objectstack#9711 是 in flight,移植 post-#9711 的版本。实测:objectstack#9711 已于 2026-08-19T00:23:33Z 关闭为completed(closed_byos-steve)。所以 post-#9711 的版本已经在 framework main 上,这张卡不再被挡,dev 直接照 framework 现状移植即可 —— ⛔ 但仍要以 frameworkorigin/main的实际文件为准,不要照 #9711 正文里的代码片段抄(那是提案时的写法)。#9711 还提供了本卡用得上的两件事:PR-guard 的准确形状(⚠️ 那是 framework 的数字,不是本仓的;triage 把「先在本仓跑同一个量测」定为第一交付物,正是因为它决定 item 1 是紧急还是仅仅错误。⛔ 不要把 framework 的零搬过来当本仓的读数。
if (issue.pull_request) { announce and skip }),以及 framework 侧的严重度量测 —— 1176 个最近合并的 PR 里,零个 qualified foreign closing keyword(2026-08-18 两个不同窗口各测一次,都是零)。Generated by Claude Code
os-support-ai commentedon Aug 19, 2026
{ "issue": 5261, "status": "done", "branch": "claude/issue-5261-port-hardened-cross-repo-closer", "pr": "https://github.com/objectstack-ai/objectui/pull/5295", "premise_still_valid": true, "summary": "Ported the framework-hardened cross-repo-issue-closer family from objectstack-ai/objectstack cb9ff23fa (repo head a065e4655) rather than re-deriving it: the issue.pull_request guard placed BEFORE the already-closed branch, refusal accounting (setFailed after the loop, the catch's isolation unchanged), backlink-on-closed split three ways by state_reason with a per-PR marker for re-run idempotency, plus the extracted-script harness and its --self-test, wired into lint.yml. FIRST DELIVERABLE, the measurement over THIS repo, and it is NOT the framework's zero: over all 3425 merged PRs here (#1..#5288, the closed-PR listing paged to exhaustion at 37 pages), 60 carry a qualified foreign closing keyword (61 occurrences, 59 distinct targets) against the framework's 0-of-1176; of the 57 targets that resolve, ZERO name a pull request (2 unresolvable: objectstack-ai/cloud#667 and #654, this session's proxy answers 403 for that repo and add_repo reports no access; 5 more resolve only via the objectstack-ai/framework and objectql/objectui renames and are all issues). Counter-probes so those zeros are readings: 246 qualified same-repo references and the bare form in 972 of the same PRs. The severity finding is defect 3, not defect 1: since this workflow landed here on 2026-08-09 (#3969) 15 merged PRs carried a foreign target, and in 14 of the 15 the framework issue was closed by a seat 1-2 seconds after the merge, BEFORE the workflow run was even created (the 15th's close lands in the same second the run is created, runner later still) - so the loop hit state === 'closed' 15 times out of 15, skipped each target whole, left no backlink on any of them, and reported success, as have all 941 runs of this job. Quiet/warn/red judgement: RED, matching the framework's landed version (warning annotation naming the target plus a post-loop setFailed carrying the malformed class separately from the refusal class); convergence is the card's binding scope, and this repo's own facts support it more strongly than the framework's did - affordability re-derived here rather than inherited: the main ruleset (11776024) has no required_status_checks rule at all, the job runs only after the merge, and this repo has no workflow_run listener.", "tests": "All at HEAD a5a0678ac (the commit the PR is opened on). EXECUTED, green: `node scripts/check-cross-repo-closer-outcome.mjs --self-test` -> '77 assertions, 14 mutations of the shipped script each driven to red'; `node scripts/check-cross-repo-closer-outcome.mjs` -> 'OK (105 assertions over 18 scenarios, driving the 18420-char script extracted from .github/workflows/cross-repo-issue-closer.yml)'. REVERSE VERIFICATION (the refusal-accounting proof the bar asks for): the module is inert on import by design, so judge() was pointed at a tree holding this repo's origin/main copy of the workflow - same 105 checks produce 40 failed assertions there and 0 here, including '[L3] L3 FAILS the job -- the defect this card is about; got 0' (L3 simulates one target's issues.get refused with HTTP 404 while the other two stay reachable: pre-port calls setFailed zero times, ported goes red and still closes the other two) and '[L12] L12 still closes the other two targets -- isolation holds; got 3' (pre-port closed all three, one of them a pull request). No rebuild is involved in either leg - the harness extracts the shipped YAML bytes and runs them as an AsyncFunction, there is no dist/ in the path. Also executed green: check-control-bytes, check-changeset-presence (4 files changed, 0 under a released package src/, exits 0 - no changeset owed, and objectui has no skip-changeset label so none was applied), check-changeset-no-major, check-lint-coverage, check-type-check-coverage, check-node-esm-load, check-phantom-dependencies, check-action-forward-parity, check-published-dist-tooling, check-skills-paths, `npx eslint scripts/check-cross-repo-closer-outcome.mjs`, and `vitest run --project unit scripts/__tests__` = 55 files / 1272 tests passing (includes the four that pin these workflows: ci-cd-pipeline-doc, lint-workflow, merge-queue-reporting, dependabot-merge-gate). YAML validity and the credential walk were machine-diffed old vs new: trigger, top-level permissions, absence of job permissions, merged==true gate, action version, github-token expression and step env all SAME; added only the step inputs retries:3 and retry-exempt-status-codes:400,401,404,422, and one new read-only API method (issues.listComments) on a repo the token already comments on and closes in. NOT executed and not claimed: GitHub Actions cannot run locally, so nothing here asserts a real run of the workflow. objectui has no scripts/pm/dispatch-gates.mjs (framework-only), so the gate set was derived by hand from the changed paths.", "open_questions": [], "out_of_scope_findings": [ "filed as objectstack-ai/objectstack#9917 (label `finding`, unassigned): the framework's own copy of this family carries two wrong/stale evidence citations - its harness cites objectui#4478 as a closed ISSUE answering state_reason null when that number is a PULL REQUEST (which is why it answers null, and which is the very thing L13 refuses), and its lint.yml step comment hand-counts 'seven ways' / 'Ten scenarios' where MUTATIONS now holds 14 and SCENARIOS 18. Comments only, no behaviour at risk; the port deliberately dropped both counts rather than carrying them across." ] }File surface, wider than the card declared
The card scoped this to the workflow plus the script and harness under
scripts/. Two additions were needed and are in the PR:.github/workflows/lint.yml— the wiring. Without it the harness runs nowhere, and the self-test asserts the wiring is present (it was red on exactly those two assertions until the step landed).package.json+pnpm-lock.yaml—extractScriptneeds a real YAML parser rather than a hand-rolled one.yaml@2.9.0was already resolved in this lockfile as a transitive, so the delta is three lines and no new package version enters the tree; the framework declares the sameyaml: ^2.9.0at its root.Generated by Claude Code