Skip to content

Commit 6d29882

Browse files
authored
Merge pull request #4954 from yuedai-pbc/yuedai/live-surface-github-metadata
fix(hygiene): cover GitHub's own rendered pages as live surfaces
2 parents 46280da + e15959b commit 6d29882

7 files changed

Lines changed: 111 additions & 33 deletions

File tree

‎.github/GOVERNANCE.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ but do not replace the approval required from an eligible GitHub reviewer.
146146

147147
## Main Branch Merge Gates
148148

149-
The live [main ruleset](https://github.com/huangruiteng/loopx/rules/18121976)
149+
The live [main ruleset](https://github.com/loopx-project/loopx/rules/18121976)
150150
is the operational authority. It requires a pull request, one approving
151151
review, code-owner approval where applicable, dismissal of stale approvals,
152152
approval of the last push by another reviewer, resolved review threads, and
@@ -220,7 +220,7 @@ The versioned
220220
[Current Technical Directions](../docs/project/technical-directions.md) page is
221221
the canonical map of active strategic programs, maturity, contribution routes,
222222
and promotion gates. The pinned
223-
[GitHub Discussion](https://github.com/huangruiteng/loopx/discussions/2851) is
223+
[GitHub Discussion](https://github.com/loopx-project/loopx/discussions/2851) is
224224
its community-facing projection; an issue, Discussion, RFC, or integration
225225
branch does not override merged runtime and stable reference contracts.
226226

‎.github/ISSUE_TEMPLATE/bug_report.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ body:
66
- type: markdown
77
attributes:
88
value: |
9-
Thanks for helping improve LoopX. Do not report an unpatched security vulnerability here; use [Private Vulnerability Reporting](https://github.com/huangruiteng/loopx/security/advisories/new). Remove credentials, private data, raw agent sessions, internal links, and local runtime state before submitting.
9+
Thanks for helping improve LoopX. Do not report an unpatched security vulnerability here; use [Private Vulnerability Reporting](https://github.com/loopx-project/loopx/security/advisories/new). Remove credentials, private data, raw agent sessions, internal links, and local runtime state before submitting.
1010
1111
- type: checkboxes
1212
id: preflight

‎.github/ISSUE_TEMPLATE/config.yml‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
blank_issues_enabled: false
22
contact_links:
33
- name: Ask a question
4-
url: https://github.com/huangruiteng/loopx/discussions/categories/q-a
4+
url: https://github.com/loopx-project/loopx/discussions/categories/q-a
55
about: Get community help with usage, configuration, or design questions.
66
- name: Discord community
77
url: https://discord.gg/XmGgQyCFZd
88
about: Join informal onboarding, workflow, and show-and-tell conversations.
99
- name: Report a security vulnerability
10-
url: https://github.com/huangruiteng/loopx/security/advisories/new
10+
url: https://github.com/loopx-project/loopx/security/advisories/new
1111
about: Privately report suspected unpatched vulnerabilities. Do not open a public issue.
1212
- name: Contributor task board
13-
url: https://github.com/huangruiteng/loopx/blob/main/docs/development/contributor-tasks.md
13+
url: https://github.com/loopx-project/loopx/blob/main/docs/development/contributor-tasks.md
1414
about: Start here for public, claimable work.
1515
- name: Current technical directions
16-
url: https://github.com/huangruiteng/loopx/blob/main/docs/project/technical-directions.md
16+
url: https://github.com/loopx-project/loopx/blob/main/docs/project/technical-directions.md
1717
about: Understand active programs, maturity, ownership boundaries, and promotion gates.

‎.github/PULL_REQUEST_TEMPLATE.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ baseline/head comparison and a failing-before or mutation check, not just test c
5858
Documentation-only changes may use a static/manual row and explain runtime N/A.
5959
A passing row does not waive required real-path/backend gates. -->
6060

61-
See [validation disclosure guidance](https://github.com/huangruiteng/loopx/blob/main/CONTRIBUTING.md#validation-disclosure).
61+
See [validation disclosure guidance](https://github.com/loopx-project/loopx/blob/main/CONTRIBUTING.md#validation-disclosure).
6262

6363
## Frontend / Visual Evidence
6464

‎.github/SECURITY.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ version-specific regression.
1010
## Reporting A Vulnerability
1111

1212
Please report suspected vulnerabilities through
13-
[GitHub Private Vulnerability Reporting](https://github.com/huangruiteng/loopx/security/advisories/new).
13+
[GitHub Private Vulnerability Reporting](https://github.com/loopx-project/loopx/security/advisories/new).
1414
Do not open a public issue, discussion, or pull request for an unpatched
1515
vulnerability.
1616

‎.github/SUPPORT.md‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ channels.
99

1010
| Need | Channel | Use it for |
1111
| --- | --- | --- |
12-
| Reproducible bug or installation failure | [GitHub Issues](https://github.com/huangruiteng/loopx/issues/new/choose) | Public, sanitized reproduction steps for behavior that can be investigated or fixed in the repository. |
13-
| Feature request | [GitHub Issues](https://github.com/huangruiteng/loopx/issues/new/choose) | A concrete problem, desired outcome, alternatives, and the smallest useful product change. |
14-
| Usage or design question | [GitHub Discussions: Q&A](https://github.com/huangruiteng/loopx/discussions/categories/q-a) | Questions, configuration help, and design discussion that do not yet identify a repository bug. |
15-
| Security vulnerability | [Private Vulnerability Reporting](https://github.com/huangruiteng/loopx/security/advisories/new) | Suspected unpatched vulnerabilities. Do not post them in an issue, discussion, or chat. See [`SECURITY.md`](SECURITY.md). |
12+
| Reproducible bug or installation failure | [GitHub Issues](https://github.com/loopx-project/loopx/issues/new/choose) | Public, sanitized reproduction steps for behavior that can be investigated or fixed in the repository. |
13+
| Feature request | [GitHub Issues](https://github.com/loopx-project/loopx/issues/new/choose) | A concrete problem, desired outcome, alternatives, and the smallest useful product change. |
14+
| Usage or design question | [GitHub Discussions: Q&A](https://github.com/loopx-project/loopx/discussions/categories/q-a) | Questions, configuration help, and design discussion that do not yet identify a repository bug. |
15+
| Security vulnerability | [Private Vulnerability Reporting](https://github.com/loopx-project/loopx/security/advisories/new) | Suspected unpatched vulnerabilities. Do not post them in an issue, discussion, or chat. See [`SECURITY.md`](SECURITY.md). |
1616
| Informal peer help | [Discord](https://discord.gg/XmGgQyCFZd) | Onboarding, workflow comparison, show and tell, and community conversation. Chat is not an authoritative support or release record. |
1717

1818
Public contributor work belongs on the
@@ -25,14 +25,14 @@ requests should follow
2525

2626
## Official Publication Sources
2727

28-
- [GitHub Releases](https://github.com/huangruiteng/loopx/releases) is the
28+
- [GitHub Releases](https://github.com/loopx-project/loopx/releases) is the
2929
authoritative source for published versions and release notes.
30-
- [GitHub Discussions: Announcements](https://github.com/huangruiteng/loopx/discussions/categories/announcements)
30+
- [GitHub Discussions: Announcements](https://github.com/loopx-project/loopx/discussions/categories/announcements)
3131
is the authoritative source for project announcements that are not tied to
3232
one release. The pinned
33-
[Current technical directions and known limitations](https://github.com/huangruiteng/loopx/discussions/2851)
33+
[Current technical directions and known limitations](https://github.com/loopx-project/loopx/discussions/2851)
3434
post is the community-facing projection of the versioned repository map.
35-
- [GitHub Security Advisories](https://github.com/huangruiteng/loopx/security/advisories)
35+
- [GitHub Security Advisories](https://github.com/loopx-project/loopx/security/advisories)
3636
is the authoritative source for coordinated vulnerability disclosures.
3737

3838
Repository documentation describes the current product and contributor
@@ -49,7 +49,7 @@ official publication source. Reposts, screenshots, personal accounts, and
4949
third-party communities may be useful, but they are not authoritative project
5050
communications. When sources conflict, prefer the official GitHub source for
5151
the relevant topic and ask for clarification in a public
52-
[Discussion](https://github.com/huangruiteng/loopx/discussions).
52+
[Discussion](https://github.com/loopx-project/loopx/discussions).
5353

5454
## Make A Useful Request
5555

‎examples/repository-hygiene-smoke.py‎

Lines changed: 93 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,20 @@
3434
# A surface is live by where it is, never by what else its text happens to
3535
# contain: it hands an address to a user, a host or another tool at run time,
3636
# or it is the command someone copies.
37-
LIVE_SURFACE_PREFIXES = ("loopx/", "scripts/", ".github/workflows/", "packages/")
37+
# `.github/` is whole, not just its workflows: GitHub renders
38+
# `ISSUE_TEMPLATE/config.yml` as the contact links on the new-issue page, and
39+
# `SECURITY.md`, `SUPPORT.md`, `GOVERNANCE.md` and `PULL_REQUEST_TEMPLATE.md`
40+
# each hand an address to the person reading them.
41+
LIVE_SURFACE_PREFIXES = ("loopx/", "scripts/", ".github/", "packages/")
3842
# A built bundle is regenerated, not edited, so its baked-in address is fixed by
3943
# the release that rebuilds it. This is the tracked-build-output cost #4677 names.
4044
GENERATED_ASSET_PREFIXES = ("loopx/web/chat/assets/",)
4145
# Where the pre-transfer address is the reviewed-correct content, by path and by
4246
# use: this project's own disambiguation terms must keep matching the archived
43-
# address, and prose may cite the pull request an event happened under.
47+
# address, and prose may cite the pull request an event happened under. An entry
48+
# is either a whole use shape or one exact record as "<use>:<number>", and a
49+
# record stays a record: reviewing one dated citation cannot vouch for the old
50+
# addresses later written next to it.
4451
REVIEWED_ADDRESS_EXCEPTIONS: dict[str, frozenset[str]] = {
4552
"packages/loopx-community-discussion/src/loopx_community_discussion/normalize.py":
4653
frozenset({"repository", "issue"}),
@@ -49,6 +56,16 @@
4956
"loopx/capabilities/issue_fix/README.md": frozenset({"pull"}),
5057
"loopx/capabilities/issue_fix/README.zh-CN.md": frozenset({"pull"}),
5158
"packages/loopx-codex-provider-routing/RUNBOOK.md": frozenset({"pull"}),
59+
# Governance records where the project started and which issue settled a
60+
# roster change, each by its exact reference: a category here would also
61+
# tolerate every old-owner commit or issue link later added to the file. The
62+
# ruleset link in the same file is called live and stays under review.
63+
".github/GOVERNANCE.md": frozenset(
64+
{
65+
"commit:7dcdc9dc79226d157ba57d3e8ff4bae664f020c1",
66+
"issue:4069",
67+
}
68+
),
5269
}
5370
DISAMBIGUATION_TERMS_SOURCE = (
5471
"packages/loopx-community-discussion/src/loopx_community_discussion/normalize.py"
@@ -87,24 +104,41 @@ def _address_use(raw_path: str) -> str:
87104
)
88105

89106

90-
# A use is either a live pointer this project must own or a dated citation that
91-
# may keep the address the event happened under.
92-
LIVE_ADDRESS_USES = frozenset(
93-
{"repository", "issue_form", "discussion", "release_asset", "main_pointer", "branch"})
107+
#: Uses that name one reviewable record, so an exception can quote its number.
108+
_IDENTITY_BEARING_USES = ("issue", "pull", "commit")
109+
110+
111+
def _address_reference(raw_path: str) -> tuple[str, str | None]:
112+
"""Return one occurrence's use plus the single record it names, if any.
113+
114+
``issue:4069`` is one dated citation; the bare ``issue`` shape is every
115+
old-owner issue link in a file. Only the occurrence decides either part.
116+
"""
117+
118+
use = _address_use(raw_path)
119+
if use not in _IDENTITY_BEARING_USES:
120+
return use, None
121+
segments = [part for part in raw_path.strip("/").split("/") if part]
122+
return (use, f"{use}:{segments[1]}") if len(segments) > 1 else (use, None)
94123

95124

96125
def stale_address_uses(name: str, text: str) -> list[str]:
97-
"""Return the old-address uses in a live surface that were never reviewed."""
126+
"""Return the old-address uses in ``name`` that were never reviewed.
127+
128+
Every classified use is an offender until a path-and-use exception reviews it,
129+
so widening which files are live cannot quietly reclassify a dated citation as
130+
safe: it has to be judged and named here, and an exception that names a record
131+
covers only that record.
132+
"""
98133

99134
tolerated = REVIEWED_ADDRESS_EXCEPTIONS.get(name, frozenset())
100-
return [
101-
use
102-
for use in (
103-
_address_use(match.group(1) or "")
104-
for match in OLD_ADDRESS_RE.finditer(text)
105-
)
106-
if use not in tolerated
107-
]
135+
offenders: list[str] = []
136+
for match in OLD_ADDRESS_RE.finditer(text):
137+
use, record = _address_reference(match.group(1) or "")
138+
if use in tolerated or (record is not None and record in tolerated):
139+
continue
140+
offenders.append(use)
141+
return offenders
108142

109143

110144
def tracked_files() -> set[str]:
@@ -248,6 +282,50 @@ def _validate_stale_address_classifier() -> None:
248282
"main_pointer"
249283
]:
250284
raise AssertionError("a documentation pointer must be named as a live address")
285+
advisory = "https://github.com/huangruiteng/loopx/security/advisories/new\n"
286+
if stale_address_uses(".github/SECURITY.md", advisory) != ["security"]:
287+
raise AssertionError(
288+
"the private-vulnerability-reporting entry is how a reporter reaches this "
289+
"project, so it must be named as a live address rather than a citation"
290+
)
291+
if not _is_live_surface(".github/ISSUE_TEMPLATE/config.yml"):
292+
raise AssertionError(
293+
"GitHub renders ISSUE_TEMPLATE/config.yml as the contact links on its own "
294+
"new-issue page, so it is a live surface"
295+
)
296+
if stale_address_uses(
297+
".github/GOVERNANCE.md",
298+
"https://github.com/huangruiteng/loopx/commit/7dcdc9dc79226d157ba57d3e8ff4bae664f020c1\n",
299+
):
300+
raise AssertionError(
301+
"widening .github/ must not turn a dated history citation into an "
302+
"offender: the commit a project started under keeps that address"
303+
)
304+
if stale_address_uses(
305+
".github/GOVERNANCE.md",
306+
"https://github.com/huangruiteng/loopx/issues/4069\n",
307+
):
308+
raise AssertionError(
309+
"the issue that settled a roster change is cited under the address it "
310+
"happened at, so it must stay tolerated"
311+
)
312+
if stale_address_uses(
313+
".github/GOVERNANCE.md",
314+
"https://github.com/huangruiteng/loopx/issues/4070\n",
315+
) != ["issue"]:
316+
raise AssertionError(
317+
"an exception for one reviewed issue must not tolerate another "
318+
"old-owner issue link in the same file"
319+
)
320+
if stale_address_uses(
321+
".github/GOVERNANCE.md",
322+
"https://github.com/huangruiteng/loopx/commit/"
323+
"1111111111111111111111111111111111111111\n",
324+
) != ["commit"]:
325+
raise AssertionError(
326+
"an exception for one reviewed commit must not tolerate another "
327+
"old-owner commit link in the same file"
328+
)
251329
if _is_live_surface("loopx/web/chat/assets/index-abc123.js"):
252330
raise AssertionError(
253331
"a generated bundle is outside the guard: its address is fixed by the "

0 commit comments

Comments
 (0)