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
159 changes: 159 additions & 0 deletions examples/repository-hygiene-smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,86 @@
FIRST_PUBLIC_RELEASE = (0, 1, 3)
VERSION_TAG_RE = re.compile(r"^v(\d+)\.(\d+)\.(\d+)$")

CANONICAL_REPO = "loopx-project/loopx"
PRE_TRANSFER_REPO_URL = "github.com/huangruiteng/loopx"
OLD_ADDRESS_RE = re.compile(
r'github\.com/huangruiteng/loopx((?:/[^\s"<>)\],]*)?)'
)
# 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/")
# 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.
REVIEWED_ADDRESS_EXCEPTIONS: dict[str, frozenset[str]] = {
"packages/loopx-community-discussion/src/loopx_community_discussion/normalize.py":
frozenset({"repository", "issue"}),
"packages/loopx-community-discussion/smoke/community_discussion_smoke.py":
frozenset({"issue"}),
"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"}),
}
DISAMBIGUATION_TERMS_SOURCE = (
"packages/loopx-community-discussion/src/loopx_community_discussion/normalize.py"
)


def _is_live_surface(name: str) -> bool:
if name.startswith(GENERATED_ASSET_PREFIXES):
return False
return name.startswith(LIVE_SURFACE_PREFIXES)


def _address_use(raw_path: str) -> str:
"""Classify one old-address occurrence by the path that follows it.

Only the occurrence itself decides the use, so unrelated text in the same
file cannot turn an install command into a citation or the reverse.
"""

segments = [part for part in raw_path.strip("/").split("/") if part]
if not segments:
return "repository"
lead = segments[0]
if lead == "issues":
return "issue" if len(segments) > 1 and segments[1].isdigit() else "issue_form"
if lead == "releases":
return "release_asset"
if lead == "discussions":
return "discussion"
if lead == "tree":
return "main_pointer" if len(segments) > 1 and segments[1] == "main" else "branch"
if lead.startswith("."):
return "repository"
return {"pull": "pull", "commit": "commit", "blob": "main_pointer"}.get(
lead, lead
)


# 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"})


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

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
]


def tracked_files() -> set[str]:
completed = subprocess.run(
Expand Down Expand Up @@ -101,6 +181,84 @@ def release_tags() -> list[str]:
return tags



def validate_canonical_repository_pointer() -> None:
"""Fail when a live surface hands out the pre-transfer repository address.

GitHub's redirect made the migration silent: a first-run link, a projected
documentation pointer, an install command or a provider's own relevance
terms could keep naming the previous owner while everything still resolved.
Exceptions are per path and per use, so a reviewed citation cannot be
reclassified by unrelated text in the same file, and a reviewed file cannot
hide an install command.
"""
offenders: list[str] = []
for name in sorted(tracked_files()):
if not _is_live_surface(name):
continue
stale = stale_address_uses(
name, (REPO_ROOT / name).read_text(encoding="utf-8", errors="replace")
)
if stale:
offenders.append(f"{name} ({', '.join(sorted(set(stale)))})")
if offenders:
raise AssertionError(
f"live surfaces must name the canonical {CANONICAL_REPO}; "
f"{PRE_TRANSFER_REPO_URL} still appears in: {offenders}"
)
terms = (REPO_ROOT / DISAMBIGUATION_TERMS_SOURCE).read_text(encoding="utf-8")
for address in (CANONICAL_REPO, PRE_TRANSFER_REPO_URL.removeprefix("github.com/")):
if f"github.com/{address}" not in terms:
raise AssertionError(
f"project disambiguation terms dropped {address}; current and archived "
"pages must both classify as this project"
)
_validate_stale_address_classifier()


def _validate_stale_address_classifier() -> None:
"""Prove the classifier keys on path and use, not on surrounding prose."""

install = (
"curl -L https://github.com/huangruiteng/loopx/releases/download/"
"pkg-v1/pkg.tgz -o pkg.tgz\n"
)
if stale_address_uses("packages/dsh-loopx-plugin/README.md", install) != [
"release_asset"
]:
raise AssertionError(
"an install command under a package README must be named as a live "
"pre-transfer address"
)
cited = (
"See the README notes at #12 (https://github.com/huangruiteng/loopx/pull/12)\n"
)
if stale_address_uses("packages/loopx-codex-provider-routing/RUNBOOK.md", cited):
raise AssertionError(
"a reviewed pull-request citation must stay tolerated even where the "
"same file mentions a README"
)
if stale_address_uses("loopx/configuration_catalog.py", cited) != ["pull"]:
raise AssertionError(
"a reviewed exception for one path must not tolerate the same shape "
"elsewhere: a pull citation in a product module is still a live address"
)
pointer = "https://github.com/huangruiteng/loopx/blob/main/docs/x.md\n"
if stale_address_uses("packages/loopx-community-discussion/README.md", pointer) != [
"main_pointer"
]:
raise AssertionError("a documentation pointer must be named as a live address")
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 "
"release that rebuilds it, not by hand-editing minified output"
)
if not _is_live_surface("packages/dsh-loopx-plugin/README.md"):
raise AssertionError(
"an install command under a package README is a live surface"
)


def validate_release_timeline() -> None:
if not RELEASE_TIMELINE.is_file():
raise AssertionError(f"missing release timeline: {RELEASE_TIMELINE.relative_to(REPO_ROOT)}")
Expand All @@ -122,6 +280,7 @@ def main() -> int:
files = tracked_files()
validate_required_tracked_files(files)
validate_public_private_boundary()
validate_canonical_repository_pointer()
validate_release_timeline()
print("repository-hygiene-smoke ok")
return 0
Expand Down
2 changes: 1 addition & 1 deletion loopx/agent_onboarding.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def _skill_delivery_contract(
else {}
)
),
"source_repository": "https://github.com/huangruiteng/loopx",
"source_repository": "https://github.com/loopx-project/loopx",
"source_directories": [
f"skills/{skill_id}"
for skill_id in required_skill_ids
Expand Down
4 changes: 2 additions & 2 deletions loopx/capabilities/benchmark_toolkit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1360,8 +1360,8 @@ All commands are local and no-upload by default. `benchmark-toolkit` grants no m
Docker, runner, upload, submission, publication, or production authority.

The active benchmark research program and current public-safe practice live under
[`benchmark/`](https://github.com/huangruiteng/loopx/blob/main/benchmark/README.md). Retired implementations, superseded runners, and dated research
packets are retained under [`deprecate/benchmark-legacy/`](https://github.com/huangruiteng/loopx/blob/main/deprecate/benchmark-legacy/README.md)
[`benchmark/`](https://github.com/loopx-project/loopx/blob/main/benchmark/README.md). Retired implementations, superseded runners, and dated research
packets are retained under [`deprecate/benchmark-legacy/`](https://github.com/loopx-project/loopx/blob/main/deprecate/benchmark-legacy/README.md)
for source archaeology only.
Immutable experiment snapshots follow the canonical
[archive placement rules](../../../benchmark/README.md#archive-placement),
Expand Down
2 changes: 1 addition & 1 deletion loopx/capabilities/manager_runtime/machine_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def manager_runtime_machine_configuration_namespace() -> MachineConfigurationNam
documentation={
"path": "docs/architecture/rfcs/manager-runtime-profile-v0.md",
"url": (
"https://github.com/huangruiteng/loopx/blob/main/"
"https://github.com/loopx-project/loopx/blob/main/"
"docs/architecture/rfcs/manager-runtime-profile-v0.md"
),
},
Expand Down
2 changes: 1 addition & 1 deletion loopx/capabilities/steward_executor/machine_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def steward_executor_machine_configuration_namespace() -> (
documentation={
"path": "docs/architecture/rfcs/harness-selection-dsh-pi-v0.md",
"url": (
"https://github.com/huangruiteng/loopx/blob/main/"
"https://github.com/loopx-project/loopx/blob/main/"
"docs/architecture/rfcs/harness-selection-dsh-pi-v0.md"
),
},
Expand Down
4 changes: 2 additions & 2 deletions loopx/capabilities/value_connectors/planner.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ def build_value_connector_plan_fixture(
channel="GitHub issue",
stage="monitor",
target_ref="public workflow intake issue",
target_url="https://github.com/huangruiteng/loopx/issues/670",
target_url="https://github.com/loopx-project/loopx/issues/670",
access_mode="public_metadata_only",
external_reads_allowed=True,
value_axis="demand",
Expand All @@ -286,7 +286,7 @@ def build_value_connector_plan_fixture(
channel="GitHub discussion",
stage="monitor",
target_ref="public workflow discussion",
target_url="https://github.com/huangruiteng/loopx/discussions/673",
target_url="https://github.com/loopx-project/loopx/discussions/673",
access_mode="public_metadata_only",
external_reads_allowed=True,
value_axis="demand",
Expand Down
2 changes: 1 addition & 1 deletion loopx/cli_commands/first_run_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
None,
]

FIRST_RUN_ISSUE_URL = "https://github.com/huangruiteng/loopx/issues/new"
FIRST_RUN_ISSUE_URL = "https://github.com/loopx-project/loopx/issues/new"
FIRST_RUN_ISSUE_TEMPLATE = "first_run.yml"


Expand Down
20 changes: 10 additions & 10 deletions loopx/configuration_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def build_goal_configuration_catalog(
"documentation": {
"path": "docs/quota-allocation.md#completed-todo-review-cadence",
"url": (
"https://github.com/huangruiteng/loopx/blob/main/"
"https://github.com/loopx-project/loopx/blob/main/"
"docs/quota-allocation.md#completed-todo-review-cadence"
),
},
Expand Down Expand Up @@ -216,7 +216,7 @@ def build_goal_configuration_catalog(
"documentation": {
"path": "docs/architecture/rfcs/shared-goal-authority-state-provider-v0.md",
"url": (
"https://github.com/huangruiteng/loopx/blob/main/"
"https://github.com/loopx-project/loopx/blob/main/"
"docs/architecture/rfcs/shared-goal-authority-state-provider-v0.md"
),
},
Expand Down Expand Up @@ -280,7 +280,7 @@ def build_goal_configuration_catalog(
"documentation": {
"path": "docs/integrations/codex-subagent-orchestration.md",
"url": (
"https://github.com/huangruiteng/loopx/blob/main/"
"https://github.com/loopx-project/loopx/blob/main/"
"docs/integrations/codex-subagent-orchestration.md"
),
},
Expand Down Expand Up @@ -341,7 +341,7 @@ def build_goal_configuration_catalog(
"documentation": {
"path": "docs/integrations/codex-subagent-orchestration.md",
"url": (
"https://github.com/huangruiteng/loopx/blob/main/"
"https://github.com/loopx-project/loopx/blob/main/"
"docs/integrations/codex-subagent-orchestration.md"
),
},
Expand Down Expand Up @@ -390,7 +390,7 @@ def build_goal_configuration_catalog(
"documentation": {
"path": "loopx/capabilities/explore/README.md",
"url": (
"https://github.com/huangruiteng/loopx/blob/main/"
"https://github.com/loopx-project/loopx/blob/main/"
"loopx/capabilities/explore/README.md"
),
},
Expand Down Expand Up @@ -443,7 +443,7 @@ def build_goal_configuration_catalog(
"documentation": {
"path": "loopx/capabilities/explore/README.md",
"url": (
"https://github.com/huangruiteng/loopx/blob/main/"
"https://github.com/loopx-project/loopx/blob/main/"
"loopx/capabilities/explore/README.md"
),
},
Expand Down Expand Up @@ -535,7 +535,7 @@ def build_goal_configuration_catalog(
"documentation": {
"path": "loopx/capabilities/change_quality/README.md",
"url": (
"https://github.com/huangruiteng/loopx/blob/main/"
"https://github.com/loopx-project/loopx/blob/main/"
"loopx/capabilities/change_quality/README.md"
),
},
Expand Down Expand Up @@ -630,7 +630,7 @@ def build_goal_configuration_catalog(
"documentation": {
"path": "loopx/capabilities/reward_memory/README.md",
"url": (
"https://github.com/huangruiteng/loopx/blob/main/"
"https://github.com/loopx-project/loopx/blob/main/"
"loopx/capabilities/reward_memory/README.md"
),
},
Expand Down Expand Up @@ -701,7 +701,7 @@ def build_goal_configuration_catalog(
"documentation": {
"path": "loopx/extensions/lark/docs/lark-event-inbox.md",
"url": (
"https://github.com/huangruiteng/loopx/blob/main/"
"https://github.com/loopx-project/loopx/blob/main/"
"loopx/extensions/lark/docs/lark-event-inbox.md"
),
},
Expand Down Expand Up @@ -758,7 +758,7 @@ def build_goal_configuration_catalog(
"documentation": {
"path": "docs/integrations/lark-kanban-control-plane-adapter.md",
"url": (
"https://github.com/huangruiteng/loopx/blob/main/"
"https://github.com/loopx-project/loopx/blob/main/"
"docs/integrations/lark-kanban-control-plane-adapter.md"
),
},
Expand Down
2 changes: 1 addition & 1 deletion packages/dsh-loopx-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Install the prebuilt release into the web profile:

```bash
dsh plugin --profile web add \
"https://github.com/huangruiteng/loopx/releases/download/dsh-loopx-plugin-v0.1.1-beta.5/dsh-loopx-plugin-0.1.1-beta.5.tgz"
"https://github.com/loopx-project/loopx/releases/download/dsh-loopx-plugin-v0.1.1-beta.5/dsh-loopx-plugin-0.1.1-beta.5.tgz"
```

The prebuilt release above retains its original DSH compatibility. This source
Expand Down
2 changes: 1 addition & 1 deletion packages/dsh-loopx-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/huangruiteng/loopx.git",
"url": "git+https://github.com/loopx-project/loopx.git",
"directory": "packages/dsh-loopx-plugin"
},
"license": "Apache-2.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/loopx-community-discussion/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ Direct CLI:

```bash
loopx-community-discussion --doctor
loopx-community-discussion scan --owner huangruiteng --repo loopx --days 14 --format json
loopx-community-discussion scan --owner huangruiteng --repo loopx --days 14 --format md
loopx-community-discussion scan --owner loopx-project --repo loopx --days 14 --format json
loopx-community-discussion scan --owner loopx-project --repo loopx --days 14 --format md
```

`schemas/fact.schema.json`, `schemas/scan.schema.json`, and the request/response
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"schema_version": "loopx_community_discussion_request_v0",
"owner": "huangruiteng",
"owner": "loopx-project",
"repo": "loopx",
"days": 14
}
Loading
Loading