fix(hygiene): cover GitHub's own rendered pages as live surfaces - #4954
yuedai-pbc wants to merge 1 commit 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.
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.
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 path+use exceptions rather than
silently kept. Deliberately not folded in, because both need an owner judgment about
whether 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
408902537real_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_paritypassed.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. Reverting all three → 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.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).