fix(hygiene): cover GitHub's own rendered pages as live surfaces - #4954
huangruiteng merged 2 commits into
Conversation
`LIVE_SURFACE_PREFIXES` guarded `.github/workflows/` alone, so the files GitHub renders at a visitor or a reporter escaped the canonical-repository check entirely: the private-vulnerability entry in `SECURITY.md`, the four contact links in `ISSUE_TEMPLATE/config.yml` that GitHub prints on its own new-issue page, `SUPPORT.md`'s routing table, the PR template's guidance pointer, and the ruleset link `GOVERNANCE.md` itself calls live. Seventeen addresses named the pre-transfer owner, and they kept resolving only because the transfer left a redirect behind -- which is a courtesy, not an ownership fact. Point each of those at `loopx-project/loopx`. Governance's record of the initial public commit and of the issue that settled a roster entry keeps the address those events happened under, reviewed per path and use like the existing pull citations; the ruleset link does not, because the sentence around it calls it live. Only the widened prefix decides this, not a new rule: every classified use is an offender until a path-and-use exception reviews it, so the two citations had to be judged rather than inherited. The smoke now pins both directions -- the new-issue contact file is a live surface, and a dated commit citation under it stays tolerated. `LIVE_ADDRESS_USES` is removed: nothing referenced it, while its comment described a live-versus-citation split the implementation never applied, which is the easiest thing in this file to "fix" by editing a constant that does nothing. Signed-off-by: Yue Dai <54579099+yuedai-pbc@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
动机
#4953 指出仓库迁移后,GitHub 直接展示给提问者、漏洞报告者和贡献者的 .github/ 文件仍使用旧 owner 链接,而原有 hygiene smoke 只扫描 .github/workflows/。在基线 eb16c5443 上,ISSUE_TEMPLATE/config.yml 不属于 live surface、仓库 smoke 仍通过;把它纳入检查并修正公开入口是有价值的目标。不过本 head 尚未完整达到“仅豁免经审查的历史引用”。
改动思路
沿用现有 examples/repository-hygiene-smoke.py 的 tracked-file 扫描、路径分类和旧地址识别,扩大 .github/ 的 live-surface 前缀,并在同一例外表里保留治理文档中的两条历史记录。这比另建一套 GitHub 链接检查更合适;判定权仍在原有 smoke。正向路径已成立:新的 contact/security/support 等入口指向 loopx-project/loopx,未来常规旧地址会触发 smoke。
具体改动
六份 GitHub 展示文件更新了安全私报、提问、支持、发布、规则集和贡献指引等 URL;GOVERNANCE.md 的历史 commit 与 issue 链接保留。smoke 扩大扫描范围,移除未使用的 LIVE_ADDRESS_USES,补了 rendered contact file 与历史 commit 的断言。
关键代码讲解
LIVE_SURFACE_PREFIXES:从.github/workflows/扩到全部.github/,使 GitHub 新建 issue 页展示的config.yml进入实际扫描。REVIEWED_ADDRESS_EXCEPTIONS:新增GOVERNANCE.md -> {commit, issue};这里按文件和 URL 类别而非两条已审查引用的身份放行。stale_address_uses:逐个识别旧地址后仅按类别过滤。它与上述新例外组合时,无法区分历史 #4069 和后来新增的其他旧仓库 issue。
对主干的风险
[P1] 新例外过宽,会让新增的旧 owner 链接绕过刚扩大的护栏。用相同的合成输入在基线和 head 调用真实分类器:对 GOVERNANCE.md 中一个非历史例外的编号 issue 链接,基线返回 ['issue'],此 head 返回 [];换成另一个 commit ID 也返回 []。因此完整的 repository hygiene smoke 通过,仍不能证明该文件只豁免了那两条历史引用。请把例外限制到确切的历史 URL/ID(或等效的单条引用身份),并增加“另一编号 issue/commit 必须报错”的反例测试;重跑 uv run --extra test python examples/repository-hygiene-smoke.py。
语义与 CI 对齐
这里影响的是当前生效的 public-link hygiene 规则,不是未来 RFC 建议;复用了正确的规则 owner,但例外粒度违反“只容忍已审查引用”的语义。基线和 head 的 repository hygiene smoke 都通过,head 的 Ruff 与 diff-check 通过。另一个 docs-governance-smoke.py 在两者都因同一份 RFC 镜像断言失败,属于已确认的基线问题,不归因于本 PR;按当前 Goal 配置未轮询远端 CI。
我的整体评价
修正六份公开文件及扩大扫描范围的方向和规模都合理,且无需额外运行时抽象;阻塞点集中在新增例外,而不是全 PR 的方向。修到精确历史引用并证明无关旧地址仍被发现后,可按同一 exact head 重新评审。当前结论:请求修改。
English verdict: REQUEST_CHANGES - head 4089025; narrow the GOVERNANCE.md historical exceptions so unrelated old-owner numbered issue/commit links cannot pass the live-surface guard. Base/head smoke and synthetic classifier probes were run; the governance smoke has the same unrelated baseline failure.
The GOVERNANCE.md entry in REVIEWED_ADDRESS_EXCEPTIONS tolerated the whole commit and issue shapes, so widening the .github/ live prefix let any old-owner numbered issue or commit link added to that file pass unreviewed. Name the two reviewed historical references by their ids instead, and assert that another numbered issue and another commit id in the same file are still reported. Signed-off-by: yuedai-pbc <54579099+yuedai-pbc@users.noreply.github.com>
Amendment — head
|
上一个 head 408902537 |
本 head e15959b43 |
基线 eb16c5443 |
|
|---|---|---|---|
issues/4070 |
[] |
["issue"] |
["issue"] |
| 另一 commit id | [] |
["commit"] |
["commit"] |
validate_canonical_repository_pointer() 对真实 .github/GOVERNANCE.md 仍返回无 offender,所以收窄没有把那两处历史记录变成红灯。
门禁与证据
python examples/repository-hygiene-smoke.py→repository-hygiene-smoke ok(工作树为本 PR head)。与评审给的命令差一处:我没新建uv sync --extra test环境,而是用本机一份已装好的 venv 解释器(Python 3.12.14)在该 worktree 里跑;系统python3是 3.9,会在loopx/file_lock.py的dataclass(slots=True)上直接 ImportError,这一点只影响怎么起环境,不影响断言结果。ruff check examples/repository-hygiene-smoke.py→ All checks passed;python -m mypy(无参,与 CI 一致)→Success: no issues found in 22 source files;git diff --check干净。- 如实披露:这份文件在未改动的 head 与 base 上同样不满足
ruff format --check(我逐字比对过未改动版本,OLD_ADDRESS_RE与REVIEWED_ADDRESS_EXCEPTIONS前两行的排版就在期望之外),所以我没有顺手格式化整个文件;ruff format --diff对本轮新增的行没有提出任何改动。 - 另一处未闭环与上轮相同:
examples/docs-governance-smoke.py在 base 与本 head 上因同一份 RFC 镜像断言失败,属既有基线问题,未顺手修。
四条变异,逐条被抓
| 变异 | 结果 |
|---|---|
GOVERNANCE 例外退回 {"commit", "issue"} 类别 |
红:an exception for one reviewed issue must not tolerate another old-owner issue link in the same file |
去掉 stale_address_uses() 里的单条引用臂 |
红:widening .github/ must not turn a dated history citation into an offender… |
编号取错段(segments[0] 而非 segments[1]) |
红:同上历史引用断言 |
_IDENTITY_BEARING_USES 只留 pull |
红:同上历史引用断言 |
remaining work(未变)
apps/presentation/site/public/blog/** 那 7 个已发布页面(108 处,中英镜像)里混着 live 指针与文章内的历史引用,"某段散文算不算历史"属于 owner 判断,没塞进这条;loopx/web/chat/assets/index-<hash>.js 这一半结构性成因也仍按生成物豁免。
CI attribution — 本 head 上的红灯来自
|
| 位置 | chat-bundle |
失败步骤 |
|---|---|---|
本 PR head e15959b43 |
failure | Qualify the actual compiled UI before saving the artifact |
上游 main tip 46280da6e |
failure | 同一步骤,逐字相同 |
上游 main 前一提交 c83731531 |
failure | 未取步骤名 |
| 无关 open PR #5012 / #5013 的 head | failure | 未取步骤名 |
- 本 head 上 conclusion=failure 的五个是
chat-bundle加四个聚合门:checks(失败步骤Require kernel and Dashboard qualification)、pytest(Require every upstream check)、merge-gate(Reject incomplete or unsuccessful qualification)、stage2c-correctness-e2e(Require every Stage 2C lane)。这四道门只在"上游有 job 没成功"时报红,本身不跑测试。 - 实际执行测试的
test-shard、以及kernel-static-checks、dashboard-acceptance、windows-powershell、stage2c矩阵,结论全是skipped——没有一条测试失败记录。绿的有node-minimum-compatibility、dependency-review、changes、Sign-off。 - 本 PR 触及的全部路径是
.github/下六份 Markdown 加examples/repository-hygiene-smoke.py,不含任何 UI 构建输入,而chat-bundle校验的正是编译后的 UI 产物。 - 上一个 head
408902537在 GitHub 上查不到任何 check run(total_count: 0),所以这次不是"把绿改成了红",而是这套门第一次真正跑起来就撞在主干自带的chat-bundle断点上。 - 没有把分支同步到最新
main:主干自己红,sync 不会让它变绿。等chat-bundle在主干修好后重跑即可;若需要,我可以在这个 exact head 上点 re-run。 - 同期另几条 open PR(fix(windows): skip POSIX-only fchmod in atomic private writers #5008、Settle blocked Turns without spend and back off the exact Todo #5005、Make event-owned Todo completion atomic and source-bound #5003)的
pytest也红,但它们chat-bundle是绿的——那是另一种红,本评论不对它们作归因,只是说明主干上目前不止一类失败。 - 本地自证与上一条评论一致:
repository-hygiene-smokeok、ruff check过、无参mypy→Success: no issues found in 22 source files、git diff --check干净、七条变异逐条被抓。[P1] 要求的"无关旧地址仍要被发现"已在新 head 上闭环。
Goal And Delivered Outcome
surface carries the pre-transfer repository address, and defined that surface by path
prefix. The
.github/half of that prefix list stopped atworkflows/, so the gate neverlooked at the files GitHub renders to the person about to contact this project —
SECURITY.md,ISSUE_TEMPLATE/config.yml,ISSUE_TEMPLATE/bug_report.yml,SUPPORT.md,PULL_REQUEST_TEMPLATE.mdand the ruleset linkGOVERNANCE.mditself calls live. Twentyaddress uses across those six files stayed outside the check, while
.github/workflows/— the one.github/path the gate does police — was already clean.edits all passed the owning smoke: reverting the prefix to
.github/workflows/, dropping.github/from it entirely while keeping the text fixes, and deleting theGOVERNANCE.mdexception. After: each fails with its own named assertion (seeregression_parity), and the smoke passes only with the widened prefix and therepointed files, which is the pair this PR delivers.
408902537was that the newGOVERNANCE.mdexception tolerated the wholecommitandissueshapes, so any old-owner numbered issue or commit link later added to that file would pass unreviewed.e15959b43binds the exception to the two reviewed references themselves and adds the counter-assertions; see the amendment comment.current
main. No file underloopx/changes, so no runtime behavior changes.Scope And Continuation
.github/is now live by location, the eighteenruntime-facing address uses in those six files name the canonical repository, and the two
GOVERNANCE.mduses that name a historical event (where the project started, and whichissue settled a roster change) are recorded as reviewed exceptions naming each reference
(
commit:<sha>,issue:4069) rather than the whole shape, rather than silently kept. Deliberately not folded in, because both need an owner judgment aboutwhether a sentence is history rather than a pointer: the published prose under
apps/presentation/site/public/blog/**andapps/presentation/site/public/benchmarks/deepswe-sol/(mixing live pointers with dated citations), and the tracked build output
loopx/web/chat/assets/index-<hash>.jsthat [Queue] 19 个 open PR 与 main 冲突:其中 7 个只卡在两组 append-only RFC ledger,3 个卡在已提交的前端 bundle #4677 already names as the structural cost..github/surface is complete within this scope. Theapps/residue is a separate decision and should not be smuggled into a prefix change;it is named above so a successor can be filed against it directly.
Validation
e15959b43(review round 1; previous head408902537)real_entrypointpassedpython3 examples/repository-hygiene-smoke.py→repository-hygiene-smoke okon the widened prefix with all six files repointed. This is the check that owns the rule being widened, and it is the check a future stale link under.github/will fail.regression_paritypassede15959b43, each producing its own failure and each reverted before the final run: (1) prefix back to.github/workflows/→AssertionError: GitHub renders ISSUE_TEMPLATE/config.yml as the contact links on its own new-issue page, so it is a live surface; (2) drop.github/from the prefix while keeping the file edits → same classifier assertion, which shows the gate and not the text is what enforces this; (3) delete theGOVERNANCE.mdexception →live surfaces must name the canonical loopx-project/loopx; ... still appears in: ['.github/GOVERNANCE.md (commit, issue)'], which shows the exception is load-bearing and that widening coverage did not loosen the rule. (4)GOVERNANCE.mdexception widened back to thecommit/issueshapes →an exception for one reviewed issue must not tolerate another old-owner issue link in the same file; (5) remove the single-record arm ofstale_address_uses()→widening .github/ must not turn a dated history citation into an offender…; (6) read the record id from the wrong path segment → same historical assertion; (7) dropissue/commitfrom_IDENTITY_BEARING_USES→ same historical assertion. Recomputing the reviewer's own synthetic probe against.github/GOVERNANCE.md: a non-exempt numbered issue and another commit id returned[]on408902537and return['issue']/['commit']here, which is the behavior the review asked to restore. Reverting all seven → smoke ok.staticpassedpython -m ruff checkandpy_compileclean on the changed Python file;git diff --checkclean across all seven paths;loopx check --scan-pathover every touched path →ok: true,errors=0,warnings=2.python -m mypy(unparameterized, as CI runs it) →Success: no issues found in 22 source files. Disclosure: this file does not satisfyruff format --checkon the base or on either head (verified against the unmodified revision), so no incidental reformatting was applied;ruff format --diffproposes nothing on the lines added here.staticfailed(pre-existing on the base, not caused here)python3 examples/docs-governance-smoke.pyfails withAssertionError: automatic-execution-admission-v0.md. Reproduced identically on an unmodified checkout ofmainat the same revision, so it is a release/governance record owned by the maintainers and is disclosed rather than fixed in this PR. It is the same class of residue #4776 disclosed forvalidate_release_timeline.unitnot_runtests/module exercises these paths; the rule lives in the smoke above. CI runs the full suite on the merge ref regardless..github/files, andthe checks above are the ones that read them. Not covered here and not changed: the
apps/prose named in the scope section, and thedocs-governance-smokefailure, whichreproduces on the base.
Frontend / Visual Evidence
edited files are Markdown/YAML consumed by GitHub; the address text before this PR is
observable on the public new-issue page of the repository and in the raw files at
main.Type of Change
LoopX Area
Technical Direction
hygiene. No roadmap id claimed.
Shared-authority RFC fixture impact
or compatibility projection changes.
Boundary Checklist
.loopx/,.codex/goals/, and liveACTIVE_GOAL_STATE.md).none.Signed-off-bytrailer (git commit -s).