Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/GOVERNANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ but do not replace the approval required from an eligible GitHub reviewer.

## Main Branch Merge Gates

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

Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ body:
- type: markdown
attributes:
value: |
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.
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.

- type: checkboxes
id: preflight
Expand Down
8 changes: 4 additions & 4 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
blank_issues_enabled: false
contact_links:
- name: Ask a question
url: https://github.com/huangruiteng/loopx/discussions/categories/q-a
url: https://github.com/loopx-project/loopx/discussions/categories/q-a
about: Get community help with usage, configuration, or design questions.
- name: Discord community
url: https://discord.gg/XmGgQyCFZd
about: Join informal onboarding, workflow, and show-and-tell conversations.
- name: Report a security vulnerability
url: https://github.com/huangruiteng/loopx/security/advisories/new
url: https://github.com/loopx-project/loopx/security/advisories/new
about: Privately report suspected unpatched vulnerabilities. Do not open a public issue.
- name: Contributor task board
url: https://github.com/huangruiteng/loopx/blob/main/docs/development/contributor-tasks.md
url: https://github.com/loopx-project/loopx/blob/main/docs/development/contributor-tasks.md
about: Start here for public, claimable work.
- name: Current technical directions
url: https://github.com/huangruiteng/loopx/blob/main/docs/project/technical-directions.md
url: https://github.com/loopx-project/loopx/blob/main/docs/project/technical-directions.md
about: Understand active programs, maturity, ownership boundaries, and promotion gates.
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ baseline/head comparison and a failing-before or mutation check, not just test c
Documentation-only changes may use a static/manual row and explain runtime N/A.
A passing row does not waive required real-path/backend gates. -->

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

## Frontend / Visual Evidence

Expand Down
2 changes: 1 addition & 1 deletion .github/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ version-specific regression.
## Reporting A Vulnerability

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

Expand Down
18 changes: 9 additions & 9 deletions .github/SUPPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ channels.

| Need | Channel | Use it for |
| --- | --- | --- |
| 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. |
| Feature request | [GitHub Issues](https://github.com/huangruiteng/loopx/issues/new/choose) | A concrete problem, desired outcome, alternatives, and the smallest useful product change. |
| 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. |
| 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). |
| 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. |
| 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. |
| 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. |
| 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). |
| 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. |

Public contributor work belongs on the
Expand All @@ -25,14 +25,14 @@ requests should follow

## Official Publication Sources

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

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

## Make A Useful Request

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


# A use is either a live pointer this project must own or a dated citation that
# may keep the address the event happened under.
LIVE_ADDRESS_USES = frozenset(
{"repository", "issue_form", "discussion", "release_asset", "main_pointer", "branch"})
#: Uses that name one reviewable record, so an exception can quote its number.
_IDENTITY_BEARING_USES = ("issue", "pull", "commit")


def _address_reference(raw_path: str) -> tuple[str, str | None]:
"""Return one occurrence's use plus the single record it names, if any.

``issue:4069`` is one dated citation; the bare ``issue`` shape is every
old-owner issue link in a file. Only the occurrence decides either part.
"""

use = _address_use(raw_path)
if use not in _IDENTITY_BEARING_USES:
return use, None
segments = [part for part in raw_path.strip("/").split("/") if part]
return (use, f"{use}:{segments[1]}") if len(segments) > 1 else (use, None)


def stale_address_uses(name: str, text: str) -> list[str]:
"""Return the old-address uses in a live surface that were never reviewed."""
"""Return the old-address uses in ``name`` that were never reviewed.

Every classified use is an offender until a path-and-use exception reviews it,
so widening which files are live cannot quietly reclassify a dated citation as
safe: it has to be judged and named here, and an exception that names a record
covers only that record.
"""

tolerated = REVIEWED_ADDRESS_EXCEPTIONS.get(name, frozenset())
return [
use
for use in (
_address_use(match.group(1) or "")
for match in OLD_ADDRESS_RE.finditer(text)
)
if use not in tolerated
]
offenders: list[str] = []
for match in OLD_ADDRESS_RE.finditer(text):
use, record = _address_reference(match.group(1) or "")
if use in tolerated or (record is not None and record in tolerated):
continue
offenders.append(use)
return offenders


def tracked_files() -> set[str]:
Expand Down Expand Up @@ -248,6 +282,50 @@ def _validate_stale_address_classifier() -> None:
"main_pointer"
]:
raise AssertionError("a documentation pointer must be named as a live address")
advisory = "https://github.com/huangruiteng/loopx/security/advisories/new\n"
if stale_address_uses(".github/SECURITY.md", advisory) != ["security"]:
raise AssertionError(
"the private-vulnerability-reporting entry is how a reporter reaches this "
"project, so it must be named as a live address rather than a citation"
)
if not _is_live_surface(".github/ISSUE_TEMPLATE/config.yml"):
raise AssertionError(
"GitHub renders ISSUE_TEMPLATE/config.yml as the contact links on its own "
"new-issue page, so it is a live surface"
)
if stale_address_uses(
".github/GOVERNANCE.md",
"https://github.com/huangruiteng/loopx/commit/7dcdc9dc79226d157ba57d3e8ff4bae664f020c1\n",
):
raise AssertionError(
"widening .github/ must not turn a dated history citation into an "
"offender: the commit a project started under keeps that address"
)
if stale_address_uses(
".github/GOVERNANCE.md",
"https://github.com/huangruiteng/loopx/issues/4069\n",
):
raise AssertionError(
"the issue that settled a roster change is cited under the address it "
"happened at, so it must stay tolerated"
)
if stale_address_uses(
".github/GOVERNANCE.md",
"https://github.com/huangruiteng/loopx/issues/4070\n",
) != ["issue"]:
raise AssertionError(
"an exception for one reviewed issue must not tolerate another "
"old-owner issue link in the same file"
)
if stale_address_uses(
".github/GOVERNANCE.md",
"https://github.com/huangruiteng/loopx/commit/"
"1111111111111111111111111111111111111111\n",
) != ["commit"]:
raise AssertionError(
"an exception for one reviewed commit must not tolerate another "
"old-owner commit link in the same file"
)
if _is_live_surface("loopx/web/chat/assets/index-abc123.js"):
raise AssertionError(
"a generated bundle is outside the guard: its address is fixed by the "
Expand Down
Loading