Skip to content

fix(repo): point live surfaces at the canonical repository - #4776

Merged
huangruiteng merged 4 commits into
loopx-project:mainfrom
DJC1412:codex/canonical-repo-pointer
Sep 20, 2026
Merged

huangruiteng merged 4 commits into
loopx-project:mainfrom
DJC1412:codex/canonical-repo-pointer

Conversation

@DJC1412

@DJC1412 DJC1412 commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Goal And Delivered Outcome

  • Goal/source and gap: [Task]: Live surfaces and one relevance oracle still carry the pre-transfer repository address #4753. The organization migration moved the canonical address to loopx-project/loopx, and most surfaces followed (README, workflows, the Tauri config, the hosted site, scripts/install-from-github.sh, self_update.DEFAULT_UPDATE_REPO) — but the addresses a shipped build hands out did not: the first-run report link, the onboarding projection, the documentation.url two machine-configuration namespaces project into CLI and Dashboard, two monitored connector targets, configuration_catalog.py's ten doc pointers, and copied command/package metadata. GitHub's redirect is why none of it failed loudly. One of them was a behavior bug rather than a stale link: loopx-community-discussion's STRONG_TERMS matched only the pre-transfer owner and repo URL, so a mention of the project's own current address was graded weak.
  • Observable before → after, with the validation row that proves it: before, make_fact(source_url="https://github.com/loopx-project/loopx/issues/7", …) returned relevance: "weak", relevance_reason: "no explicit project disambiguation term" — the exact string the mutation run below reproduces; after, both the current and the archived address classify strong, and a loopear title is still dropped. Proven by the unit and regression_parity rows.
  • Issue/task and intended base: Closes [Task]: Live surfaces and one relevance oracle still carry the pre-transfer repository address #4753. Base main.

Scope And Continuation

  • Completed scope and remaining work: live code, script, workflow and package surfaces are repointed, a check now keeps them that way, and the provider matches both addresses. Not claimed here, and named rather than silently widened: 279 blob/main / tree/main document links and 30 bare identity mentions still sit under docs/**, docs/book/** and the hosted blog HTML; 431 /pull/N, /issues/N, /commit/sha and /releases/download/tag citations were measured and deliberately left as historical record. Also untouched with a reason: packages/dsh-loopx-plugin's data/plugins/huangruiteng__loopx--packages-dsh-loopx-plugin.yml filename is derived identity in already-installed state, so it needs a migration decision, not a rename; and loopx/web/chat/assets/index-*.js carries a baked-in blob/main link, which a rebuild fixes — hand-editing minified output does not.
  • Slice boundary / successor: the split is "what a release emits at run time" versus "what prose recorded once", which is the same line the new check enforces, so the docs sweep is a separate diff-noise decision for the owner (a scripted pass over two pointer forms plus the docs-governance link check is the shape I would take). No new follow-up issue is filed; [Task]: Live surfaces and one relevance oracle still carry the pre-transfer repository address #4753 carries the counts.

Validation

  • Tested revision: 805dab5e2 (rebased on current main; the focused rows were re-run on this head and the earlier revision note below stays as the record of where each was first measured)
  • Run state: finished
  • Input classes: public_fixture, synthetic
Check kind Result Public-safe evidence / limitation
unit passed python3 packages/loopx-community-discussion/smoke/community_discussion_smoke.pyok: offline contract smoke passed, including the new case that pins current-address strong, archived-address strong and loopear noise dropped.
unit passed python3 -m pytest -q <31 test files matching the touched modules>573 passed, covering first-run report, onboarding, configuration_catalog, machine-configuration contract/UI/goal-defaults, change-quality and connector consumers.
static passed python3 examples/repository-hygiene-smoke.py reaches and passes validate_canonical_repository_pointer (see the coverage row for the one check that fails independently of this diff).
static passed python3 -m py_compile over every changed Python file; the three changed JSON files re-parse.
regression_parity passed Two mutations, each reverted afterwards. (1) Re-adding the pre-transfer URL to loopx/agent_onboarding.py makes the new check fail with the offending path listed. (2) Removing the two added STRONG_TERMS entries makes the provider smoke fail with relevance: "weak", and the hygiene check then fails on the dropped disambiguation address — so both halves of the fix are load-bearing rather than cosmetic.
manual passed loopx check --scan-path examples/repository-hygiene-smoke.py --scan-path loopx --scan-path packages → public boundary scan clean (1294 files), 7 non-literal credential-reference hits downgraded as expected by the scan's own classifier.
static failed examples/repository-hygiene-smoke.py also fails validate_release_timeline with release timeline is missing version entries: v1.1.0. Reproduced independently of this PR: git show origin/main:docs/product/release-readiness.md contains 0 v1.1.0 entries, i.e. main is red on that check since the 1.1.0 release commit. Out of scope here (it needs release evidence only the owner has); reporting it rather than folding a release-docs change into an identity PR.
  • Coverage and gaps: the changed lines are string defaults, one term tuple, one documentation list and one new check, so the risk is a consumer asserting an old value — that is what the 573-test selection over the 31 matching modules covers, and it found none. Not run: npm run test:control-plane (no TypeScript state rule or effect touched), the hosted-site and desktop build pipelines (only a checked-in built bundle and a package manifest string changed, no source of either), and no live GitHub API call was made to prove the connector targets resolve; issue and discussion numbers are preserved by the transfer redirect.

Frontend / Visual Evidence

  • UI impact: changed (text only)
  • Before: the Dashboard/CLI machine-configuration detail for manager_runtime and steward_executor rendered a documentation.url under github.com/huangruiteng/loopx/blob/main/….
  • After: the same fields render under github.com/loopx-project/loopx/blob/main/…; no layout, control or state changed, so no screenshot is added — the projection reads the string this PR changes, and tests/capabilities/test_machine_configuration_contract.py / test_capability_configuration_ui.py cover it.
  • States and viewports shown: not applicable — no visual state changed, only a link value.
  • Source data: public_fixture

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring (no functional changes)
  • Documentation update
  • Test update

LoopX Area

  • Control plane (goals, todos, quota, scheduler, registry, runtime)
  • Benchmark boundary (adapters, runners, verifiers, scoring, evidence)
  • Capability or extension (providers, adapters, skills)
  • Public docs or presentation surface (README, protocols, dashboard)
  • Build, packaging, installer, or CI
  • Host or runtime integration

Technical Direction

  • Direction / acceptance reference, when applicable: maintenance of project identity after the organization migration; no roadmap id claimed.

Shared-authority RFC fixture impact

  • N/A: no production-scale fixture, provider conformance arm, authority-store or promotion/routing change; the three JSON edits are copied example requests, not persisted contracts.

Boundary Checklist

  • Neither the diff nor this PR body/comments/attachments disclose private state, credentials, raw traces or verifier output, internal links, or local machine paths (including .loopx/, .codex/goals/, and live ACTIVE_GOAL_STATE.md).
  • I did not duplicate maintainer-owned benchmark work unless a maintainer split out a public issue for it.
  • I kept the change scoped to the linked issue/task.
  • I completed the visual evidence section for UI changes, or marked UI impact none.
  • Every commit includes a DCO Signed-off-by trailer (git commit -s).

@DJC1412
DJC1412 force-pushed the codex/canonical-repo-pointer branch from b0d0a5e to fffa423 Compare September 20, 2026 06:58
@DJC1412

DJC1412 commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

Rebased-free rewrite pushed as fffa423: the Sign-off check failed because my commit identity put the whole Name <email> string into user.email, producing Signed-off-by: DJC1412 <DJC1412 1088…@users.noreply.github.com>. Author/committer emails and the three trailers are now well-formed and the diff is byte-identical to b0d0a5eb3 (git diff between the two heads is empty), so no re-validation was needed beyond re-running the canonical-pointer check and the provider smoke, both green.

@DJC1412

DJC1412 commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

The one red test is reproduced on clean main, without this diff

test-shard (4) reports exactly one failure (read from the run's python-junit-4 artifact):

tests/extensions/test_lark_goal_topic_runtime.py::test_manager_authorized_turn_quietly_recovers_history_as_context
>   assert result["context_material_count"] == 1
E   assert 0 == 1

Reproduced on a disposable worktree at origin/main (607c11d75) with none of this PR's changes applied, same interpreter and test selection:

This diff touches none of that. Files changed here: examples/repository-hygiene-smoke.py loopx/agent_onboarding.py loopx/capabilities/benchmark_toolkit/README.md loopx/capabilities/manager_runtime/machine_profile.py loopx/capabilities/steward_executor/machine_defaults.py loopx/capabilities/value_connectors/planner.py loopx/cli_commands/first_run_report.py loopx/configuration_catalog.py packages/dsh-loopx-plugin/README.md packages/dsh-loopx-plugin/package.json packages/loopx-community-discussion/README.md packages/loopx-community-discussion/examples/request.json packages/loopx-community-discussion/smoke/community_discussion_smoke.py packages/loopx-community-discussion/src/loopx_community_discussion/normalize.py packages/loopx-repo-health/examples/request.json

So the shard result is a pre-existing failure surfacing in this PR's shard grouping rather than a regression introduced here. Flagging rather than working around it: I did not mark or skip anything, and I would rather the owner decide whether that path needs a fix (#4318) or an environment-qualified gate, since my reproduction is on macOS/arm64 with Node 22.23.2 and the CI runner is Ubuntu with Node 24 — the same two tests could disagree between the two for reasons that belong to whoever owns the Lark adapter.

@DJC1412

DJC1412 commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

Correcting the scope of my previous comment, because I have now read every shard's JUnit artifact for this run rather than one:

shard failures this PR names
1 0
2 1 tests/canary/test_maintainability_ratchet.py::test_current_repository_debt_is_reviewed_without_line_count_pins
4 1 tests/extensions/test_lark_goal_topic_runtime.py::test_manager_authorized_turn_quietly_recovers_history_as_context
  • The ratchet failure is unambiguous pre-existing: main's own run at 361347713 failed the same test (python-junit-2, 1 failure), and pytest and merge-gate went red with it.
  • The Lark one I should not have implied is settled. What I can support: on this machine it fails identically on a clean origin/main worktree with none of this diff (tests/extensions/test_lark_goal_topic_runtime.py → 2 failed, 49 passed), and this diff changes no Lark path — the changed files are the ones listed above. What I cannot yet explain: main's run above shows 0 Lark failures across all four shards, so on Linux CI it passed there and failed here. Shard membership is duration-based (--splitting-algorithm least_duration), and this run's shard 4 carried 2665 tests versus 2662 on main's run, so ordering differences are the leading candidate; a re-run of the identical head distinguishes order-dependence from a real delta, and I will post the outcome rather than leave this as an argument.

@DJC1412

DJC1412 commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

Closing the loop on my two comments here, because the answer turned out to be neither "pre-existing on macOS only" nor "shard ordering": it is a calendar.

tests/extensions/test_lark_goal_topic_runtime.py pinned its fixture events at 2026-09-13T05:59/06:00Z, while manager context expires after MANAGER_CONTEXT_MAX_AGE = timedelta(days=7) measured against the wall clock. Those fixtures crossed the line at 2026-09-20T05:59Z, which is why main's run at 05:03Z reported zero failures in that file and its run at 06:43Z reported both of them — no merge between the two. My earlier local baseline was real but incomplete: it proved this diff does not cause the failure, and I over-read it as an unresolved macOS/CI disagreement. The ordering theory I floated is dead; main is red on its own right now.

Filed with the full bracketing as #4797 and fixed test-only in #4798 (55 passed on this file, 943 passed for tests/extensions). So the shard-4 and shard-3 failures here are the same as main's, and the shard-2 ratchet failure is the other pre-existing one, unrelated to either.

The organization migration moved the project to loopx-project/loopx, and
GitHub's redirect meant nothing failed loudly while shipped defaults,
projected documentation links, monitored connector targets and copied
command examples kept handing out the pre-transfer address.

Dated citations (pull/issue numbers in prose) are left alone: they record
the address the event happened under.

Signed-off-by: DJC1412 <108855841+DJC1412@users.noreply.github.com>
STRONG_TERMS named only the pre-transfer owner and repo URL, so a mention
of the canonical loopx-project/loopx address was graded weak: the provider
downgraded this project's own current pages. Both addresses are strong
now, and the smoke pins the current form, the archived form and a noise
term in one pass.

Signed-off-by: DJC1412 <108855841+DJC1412@users.noreply.github.com>
Code, scripts, workflows and package surfaces must carry the canonical
repository address; prose may still cite the historical one, the provider
disambiguation list must match both, and the packaged chat bundle is
excluded because it is a build product fixed by rebuilding.

Signed-off-by: DJC1412 <108855841+DJC1412@users.noreply.github.com>
@DJC1412
DJC1412 force-pushed the codex/canonical-repo-pointer branch from fffa423 to 805dab5 Compare September 20, 2026 08:03
@DJC1412

DJC1412 commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

Status of the red here, with the numbers, so nobody has to re-derive it. The head is now rebased onto current main (805dab5e2) and my own focused set is green on it (tests/capabilities/test_periodic_report_incremental.py, tests/control_plane/test_post_writeback_capability_hooks.py, tests/cli_commands/test_periodic_report_intent_capability_chain.py → 95 passed). Two failures remain, neither produced by this diff:

  1. tests/extensions/test_lark_goal_topic_runtime.py (2 tests) — absolute fixture dates crossing MANAGER_CONTEXT_MAX_AGE = timedelta(days=7) against the wall clock. Diagnosed in [Bug]: absolute fixture dates make the Lark manager-context tests expire after seven days #4797, fixed test-only in test(lark): date the manager-context fixtures from the run #4798.
  2. tests/canary/test_maintainability_ratchet.py::test_current_repository_debt_is_reviewed_without_line_count_pins — reproduced on a clean current-main worktree with nothing applied. The report is:
module lines reviewed ceiling
loopx/chat_server.py 1525 1518
loopx/extensions/lark/goal_topic_connections.py 1542 1500 (default)

any_count and dict_any_count are inside their ceilings for both, so the debt is purely line count, and the ratchet's own guidance is to refresh the ceiling "for the growth this review accepts". I am deliberately not doing that in this PR: accepting someone else's growth into a reviewed budget is the owner's call or the author's of that merge, not something a drive-by contributor should slip in beside an unrelated change. The alternative — actually slimming those two modules back under their ceilings — is real work I would take as its own PR if the owner would rather not raise the numbers.

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

评审结论:REQUEST_CHANGES

评审 head:805dab5e22b0eb5148e4408a93f58836eb230c20

阻塞项

  1. [P1] 新增的 repository-hygiene guard 没有覆盖它自己刚修正的两个 package README,而且 live/history 判断依赖文件内容而不是文件路径。

    LIVE_PACKAGE_MARKERS 不包含 README,因此 _is_checked_surface("packages/dsh-loopx-plugin/README.md")_is_checked_surface("packages/loopx-community-discussion/README.md") 都返回 False。也就是说,把本 PR 修正过的 DSH release-download 安装命令或 community-discussion 扫描命令重新改回旧 owner,新增 guard 仍然不会报错。

    同时,_stale_live_pointer() 只接收 contents,却用 text.endswith((".md", ...)) or "/README" in text 猜测它是不是 prose。精确复现中,同一个 https://github.com/huangruiteng/loopx/releases/download/... 字符串,仅仅因为前面多了无关的 /README 文本,就从“offender”变成“允许的历史引用”。而 /releases/download 又被整个放进 HISTORICAL_CITATION_RE,会把这个 PR 明确认定为 live install command 的链接也当历史材料放行。

    这不满足 #4753 maintainer intake 要求的“显式 live surfaces / reviewed allowlist”,并且让“防止 residue 再长回来”的交付结果仍然不成立。最小修复:把 name 与 contents 一起交给 classifier;显式纳入这两个 README/安装命令;按 path + use 建立小型 reviewed exception table;用 mutation case 证明旧 DSH release URL 会被点名、合法历史 PR citation 不受文件内其它文字影响。

  2. [P2] relevance smoke 缺少 maintainer 明确要求的 generic weak 行。

    _pre_and_post_transfer_addresses_are_both_strong() 当前只钉住 canonical strong、archived strong 和 loopear noise。由于本 PR 新增了较宽的 loopx-project substring,应该同时钉住“title/url/text 均不含 identity 或 noise”的普通事实仍返回非空 weak。我在 base/head 对比里验证当前实现确实保留了 weak,但这个约束还没有进入 durable smoke;请补上第四行,避免未来扩展 strong terms 时把无关事实静默抬成 strong。

动机

这个 PR 解决的是一次被 GitHub redirect 掩盖的真实迁移残留:first-run、agent onboarding、machine configuration、value connector、package examples/metadata 继续对外发旧地址;更重要的是,community-discussion 只认识旧 owner,导致项目自己的 canonical URL 被判为 weak。这个问题及边界由 #4753 和 maintainer intake 明确确认,历史 PR/issue/commit 引用、DSH 已安装 identity filename、generated chat bundle不应被 blanket rewrite。

从结果看,运行时字符串与 relevance 行为的主体修复是成立的;当前缺口集中在“以后不能再退化”的 guard 本身,而不是 URL 替换方向。

改动思路

实现复用了正确的现有 owner:

  • 各现有 runtime/configuration/package surface 只改自己的输出字面量;
  • normalize.py 仍是 discussion relevance 的唯一决策点,同时保留旧地址作为历史 alias;
  • community_discussion_smoke.py 扩展现有 offline contract smoke;
  • examples/repository-hygiene-smoke.py 扩展现有仓库卫生检查,没有再建第二套检查器。

正向路径是:现有 caller 发出 canonical URL → classify_relevance 在 noise precedence 后匹配 canonical term → make_fact 保存 strong → scan/render consumer 得到正确输出。负向/维护路径应是:tracked path + URL use 被显式分类 → live old address 报出具体文件 → reviewed historical citation 保留。当前负向路径把 path 信息丢掉了,所以 classification 既漏了 live README,也会随无关 contents 改变。

具体改动

  • 15 个文件,+155/-29
  • production/runtime:first-run issue URL、onboarding source repository、两类 machine configuration documentation URL、十个 configuration catalog URL、两个 value connector targets。
  • provider behavior:STRONG_TERMS 增加 canonical organization/repository,保留 huangruiteng 和旧 URL alias。
  • public package/docs:DSH package metadata/release command、community-discussion commands/request、repo-health request、benchmark toolkit links。
  • validation:新增 transfer-address smoke,以及 81 行 repository hygiene selector/classifier。

关键代码讲解

  1. normalize.py::classify_relevance(约 35 行)保持 noise-first 顺序;相同四行 fixture 的 base/head 对比为:canonical weak -> strong,archived strong -> strong,generic weak -> weak,noise noise -> noise。这是预期且有价值的唯一行为变化。
  2. repository-hygiene-smoke.py::_is_checked_surface(约 52 行)决定 guard 的覆盖全集。它包含所有 loopx/**,但 package 侧只选 /src/package.json、request 和 smoke,遗漏本 PR 自己改变的 live README。
  3. repository-hygiene-smoke.py::_stale_live_pointer(约 64 行)本应决定 live pointer 与 historical citation,实际却没有 path 入参,prose 由 contents 偶然决定;这正是 P1 的错误 owner/boundary。
  4. community_discussion_smoke.py::_pre_and_post_transfer_addresses_are_both_strong(约 83 行)覆盖两个 alias 与 noise,但遗漏 intake 指定的 generic weak regression。

对主干的风险

主体 URL 替换风险较低:未新增 API、状态、CLI 或 authority,都是既有 caller 的 string/default 修正;静态 JSON 可解析,changed Python 可编译,配置/onboarding/value-connector focused tests 全绿。旧 URL 继续作为 discussion 历史 alias,兼容性方向正确。

最大风险来自错误的“已守住”信号:当前树通过新增 canonical validator 并不能证明未来 mutation 会失败。exact-head probe 已证明两个 changed README 根本不在 scan set 内,而且同一 release URL 可因 contents 里出现 /README 被豁免。blast radius 是未来用户继续复制旧安装/scan 命令,同时维护者以为 CI 已覆盖;另一侧则可能把合法历史 citation 当 stale live pointer,形成噪声红灯。

语义与 CI 对齐

现行 acceptance 来自 #4753 maintainer intake:显式 live surfaces 或 canonical owner、reviewed historical exceptions,以及 canonical strong / archived strong / generic weak / noise 四行矩阵。当前 exact head 在 guard 覆盖与四行 durable regression 上未完全对齐。

本地验证(按 packet,未读取/等待远端 CI):

  • community_discussion_smoke.py:通过;
  • 组织 identity、machine configuration、capability UI/defaults、manager/steward、value connector、agent onboarding:61 passed
  • identical base/head relevance matrix:预期的 weak,strong,weak,noise -> strong,strong,weak,noise
  • changed Python py_compile、3 个 JSON parse、git diff --check:通过;
  • full repository-hygiene-smoke.py:先通过本 PR 新增 canonical validator,随后仍在主干既有 v1.1.0 release-timeline 缺口失败;这个 baseline failure 已由 issue/PR 正确披露,我没有把它归因于本 diff,也没有把它隐藏或降级。

我的整体评价

这是一个目标明确、范围基本合适的迁移修复:现有 owner 复用合理,runtime/package 输出和 relevance 行为确实改善,历史 alias 也被保留。没有必要另造 repository-identity 框架;未来向的最有价值小重构,就是让现有 hygiene guard 直接持有 path-aware 的 live/history 语义,而不是继续扩大 substring/content heuristic。

因此我暂不批准。修复 P1、补齐 generic weak regression,并在同一 exact head 重新跑 provider smoke、focused tests、README mutation + historical citation 两个 guard counterfactual 后,可以做完整复审。

English verdict: REQUEST_CHANGES - head 805dab5; the canonical URL and relevance fixes are valid, but the new hygiene guard excludes both changed package READMEs and derives live-vs-history from incidental file contents, so the exact stale install pointer can regress undetected. Add path-aware coverage and the missing generic-weak regression; focused local validation otherwise passed (61 tests plus the offline provider smoke).

The first cut guessed whether a file was prose from its own contents, so an
install command could be excused by unrelated text sharing the file, and the
package READMEs whose install commands this branch fixed were not covered by
the guard at all.

Liveness now comes from where a file is, and each occurrence is classified by
the path segment that follows the address: repository, issue_form, discussion,
release_asset and main_pointer are live, a numbered issue or pull citation is
historical only where that path and use are in the reviewed table. Five cases
inside the smoke pin the classifier itself, including that a pull citation
stays tolerated beside a line mentioning a README, and that the same shape is
still a live address in a product module.

Also pins a fact with no project identity as weak, so widening the
disambiguation terms cannot silently promote unrelated discussion.

Signed-off-by: DJC1412 <108855841+DJC1412@users.noreply.github.com>
@DJC1412

DJC1412 commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

两处都按建议改了,head 38cf0b9af

P1:guard 不再从文件内容猜"这是不是 prose",也不再漏掉它自己修过的 README。

  • 是否 live 只看路径:_is_live_surface() = loopx/scripts/.github/workflows/packages/ 前缀,唯一排除是 loopx/web/chat/assets/(构建产物,按规则写明"靠重建修,不手改压缩输出")。两个 README 现在都在覆盖范围内,并且有一行 case 直接断言 _is_live_surface("packages/dsh-loopx-plugin/README.md") 为真。
  • 每次出现按它自己后面那段路径分类,与文件里其它文字无关:repository(裸址/clone)、issue_form/issues/new)、discussionrelease_asset/releases/download/...)、main_pointerblob|tree/main)是 live;带编号的 /issues/N/pull/N/commit/N 才是历史引用。你复现的那条 —— 同一个 release-download 串因为前面多了 /README 就从 offender 变允许 —— 现在结构上不可能:分类器只拿到 (path, 该次出现的后缀)
  • 例外改成 path + use 的小型 reviewed 表:normalize.py → {repository, issue}(它必须继续匹配归档地址)、community smoke → {issue}issue_fix 两份 README 与 loopx-codex-provider-routing/RUNBOOK.md → {pull}。表里没有的组合一律算 offender,所以"某个路径被豁免"不会顺带豁免别的形状。
  • 你点名的两条 mutation 变成 smoke 内部常驻断言(_validate_stale_address_classifier(),5 条):旧 DSH releases/download URL 必被点名;pull 引用在同文件出现 README 字样时仍被容忍;pull 引用出现在 loopx/configuration_catalog.py 里仍是 offender;blob/main 指针必被点名;generated bundle 的排除本身被断言。

/releases/download 不再整体当历史材料——它只在带编号 issue/pull/commit 那类"引用事件发生时的地址"里才是历史,安装包下载地址按本 PR 的定性就是 live。

P2:补了第四行。_pre_and_post_transfer_addresses_are_both_strong() 现在同时钉 canonical strong、archived strong、不含任何 identity/noise 的普通事实必须仍是非空 weak(新增 example/other-tool 的 issue + 无关键字正文),以及 loopear 仍是 noise。这样以后再加宽 strong terms 也不可能把无关讨论静默抬成 strong。

复验:provider smoke 离线通过;tests/canary/test_maintainability_ratchet.py 之外无新增红(该棘轮与 Lark 夹具两条仍是 main 自带,前者 ceiling 数值我没有动、后者在 #4798);repository-hygiene 的 canonical-pointer 与 5 条分类器 case 全过;loopx/**packages/** 公开边界扫描 clean;触达模块对应的 31 个测试文件 573 passed。未做(仍留给 owner 决定):docs/blog 里 279 条 blob|tree/main 的机械清扫、以及 chat_server.py 1525/1518 与 goal_topic_connections.py 1542/1500 的 ceiling 处置。

@DJC1412

DJC1412 commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

@huangruiteng both review points are addressed on 38cf0b9af (details in my previous comment); the branch is rebased onto current main, reviewDecision is still CHANGES_REQUESTED, so a re-review on that head is what this needs.

Current CI here is 10 passed / 11 pending / 0 failed — the four test-shard jobs have not reported yet, and when they do they will show the two failures main already has, not new ones:

  • tests/extensions/test_lark_goal_topic_runtime.py (2 tests) — absolute fixture dates crossing the seven-day retention window, so it has been failing on every branch since 2026-09-20T05:59Z. Fix is ready and test-only: test(lark): date the manager-context fixtures from the run #4798 (diagnosis in [Bug]: absolute fixture dates make the Lark manager-context tests expire after seven days #4797). Merging that first would stop it staining every open pull request, including this one.
  • tests/canary/test_maintainability_ratchet.py::test_current_repository_debt_is_reviewed_without_line_count_pinsloopx/chat_server.py 1525 lines against a 1518 ceiling, and loopx/extensions/lark/goal_topic_connections.py 1542 against the 1500 default. Both grew in fix(manager): reconcile stale Lark routes #4780 and feat(delegation): pin managed Codex worker profiles #4785, and I am deliberately leaving it alone: raising a ceiling I did not earn is exactly what the ratchet's no-suppression rule forbids, and the only alternative I can see means re-cutting connect_lark_goal_topic (550 lines) and list_lark_connections (238 lines) that landed hours ago. If you would rather the debt be paid down than accepted, say which seam you want extracted and I will take it as its own PR; if the growth is acceptable, the refresh belongs with you or that merge's author.

Everything in this PR's own scope is green: the canonical-pointer guard with its five classifier assertions, the package smokes, and the 573 tests across the 31 modules this diff touches.

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复审结论:APPROVE

评审 head:38cf0b9afb9d83ee920764db365fb0ab1118d290

上一轮在 805dab5e22b0eb5148e4408a93f58836eb230c20 提出的两个阻塞项已经按其语义边界修复,而不是只让当前 fixture 变绿:

  1. 原 P1 的 hygiene guard 现在以 path + 单个 URL occurrence 的 use 为决策输入。_is_live_surface() 会覆盖整个 packages/,仅排除明确声明的 generated bundle;_address_use() 把每个旧地址分别分类为 repository / issue / issue_form / release_asset / discussion / main_pointer / branch / pull / commit 等 use;只有 REVIEWED_ADDRESS_EXCEPTIONS[exact_path] 中明确允许的 use 才能保留。无关 prose 不再影响结论。
  2. 原 P2 的 relevance smoke 已补上 generic row,并明确要求它返回非空 weak。当前矩阵完整覆盖 canonical strong、archived strong、generic weak、loopear noise dropped。

动机

这个 PR 修的是 repository transfer 后被 redirect 掩盖的两类真实问题:一类是 first-run、onboarding、machine configuration、value connector 和 package command/metadata 仍向用户或工具发出旧 owner 地址;另一类是 community-discussion 能识别旧地址,却把项目自己的 canonical URL 判成 weak

目标不只是做一次字符串替换,还要避免同一类 residue 再长回来,同时不能因为全仓 substring denylist 把历史 PR/issue/commit citation、provider 的 archived alias 或 generated bundle 一并破坏。当前 head 已经把这三个边界——live、reviewed history、generated output——落成可观察规则。

改动思路

实现继续复用现有 owner:

  • 各 runtime/configuration/package surface 只改自己发出的 public literal;
  • packages/loopx-community-discussion/.../normalize.py 仍是 strong/weak/noise 的唯一决策点,并保留 pre-transfer identity 作为历史 alias;
  • community_discussion_smoke.py 固化四行 relevance matrix;
  • examples/repository-hygiene-smoke.py 作为已有 repository maintenance gate,按 tracked path 与 URL use 检查旧地址。

正向路径是:caller 发出 loopx-project/loopx → provider 在 noise precedence 后匹配 canonical term → make_fact 保存 strong → scan/render consumer 得到正确输出。

负向路径是:tracked live path 包含旧地址 → OLD_ADDRESS_RE 枚举每次 occurrence → _address_use() 只根据该 URL 的 suffix 分类 → exact path/use exception 未命中 → validator 点名文件和 use 并失败。这里已经没有“同一文件里恰好出现 /README 就把 release asset 当历史材料”的内容耦合。

具体改动

  • 全 PR:15 files,+248/-29
  • production/runtime:first-run issue URL、agent onboarding repository、machine configuration documentation URLs、configuration catalog URLs、value connector targets。
  • provider behavior:canonical organization/repository identity 变成 strong;旧 owner/address 继续作为 archived alias;noise-first 与 unmatched-weak 默认不变。
  • public package/docs:DSH metadata/release command、community-discussion commands/request、repo-health request、benchmark toolkit links。
  • maintenance coverage:全 live-prefix inventory、generated prefix exclusion、occurrence-level URL use classifier、exact path/use exception table、counterfactual assertions和四行 provider matrix。
  • 相对上一轮评审 head,新增修改只在两个 smoke 文件,+139/-46,直接关闭 P1/P2,没有扩张到新的 runtime framework。

关键代码讲解

  1. repository-hygiene-smoke.py::_is_live_surface(line 58)只读 path;packages/ 的 README 因此和 source/request 一样进入 scan,generated chat bundle 则由单独 prefix 排除。
  2. _address_use / stale_address_uses(line 64/96)把 occurrence 的 suffix 转成窄 use token,并以 exact path exception fail closed。未知新 use 默认不会被放行。
  3. normalize.py::classify_relevance(line 35)保持 noise → strong → weak 的顺序;唯一有意行为差异是 canonical identity 从 weak 变 strong。
  4. community_discussion_smoke.py::_pre_and_post_transfer_addresses_are_both_strong(line 83)现在同时钉住 canonical strong、archived strong、generic weak 和 noise dropped,补上上一轮漏掉的 false-positive boundary。

对主干的风险

生产风险较低:没有新 API、持久状态、CLI option、scheduler、quota、permission 或 authority contract;大多数生产 diff 是现有 consumer 的 literal 修正。兼容性方面旧 repository identity 仍是 provider strong alias,reviewed historical pull citations 仍可保留。

主要维护风险是显式 exception inventory 需要随新的 intentional history 更新;但这会 fail closed 并在 CI 中暴露为可评审噪声,优于 silent drift。LIVE_ADDRESS_USES 当前未被消费,是一个可删的小 cleanup,但不形成第二套 authority,也不改变行为,我不建议为它再次扩大本 PR。

远端 CI 目前还不是 merge-ready:test shard 2 的 maintainability ratchet 已在当前 main 失败;shard 3/4 是 7 天后过期的 Lark absolute-date fixture,#4798 在 clean origin/main 复现 2 failed, 49 passed 并提供修复。pytestmerge-gate 是这些 shard failure 的传递结果。它们不由本 diff 引入,因此不构成本次 code-review blocker,但本次批准不豁免这些门禁,也不授权合并。

语义与 CI 对齐

当前 head 与 #4753 maintainer intake 及上一轮 P1/P2 repair contract 对齐:live surface 由 path 决定;旧地址是否允许由 occurrence use + exact path exception 决定;relevance 必须保持 canonical strong / archived strong / generic weak / noise dropped。没有用 author prose 替代机器证据。

本地 exact-head 验证:

  • community_discussion_smoke.py:通过;
  • 直接调用 validate_canonical_repository_pointer():通过,并执行 old release asset / reviewed pull citation / product-code pull / blob-main / generated asset / DSH README 六类 counterfactual;
  • organization identity、capability configuration UI/defaults、machine configuration、change quality、value connector、agent onboarding、chat machine/goal configuration:95 passed in 22.02s
  • git diff --check origin/main...HEAD:通过;
  • git merge-tree --write-tree origin/main HEAD:通过;
  • review result 按 policy revision 7 校验:approval_consistent=true,无 blocker。

我的整体评价

这是一个范围完整且可回滚的 repository-transfer 修复。上一轮最关键的问题不是“README 又漏了两个”,而是 guard 把 path 语义丢掉后,用 contents 猜 live/history;当前修复已经把 decision owner 放回 path/use boundary,并用反例固定。generic weak 也进入 durable smoke,避免 canonical strong term 未来继续扩张时静默抬高无关事实。

Future-facing pass 的结论是无需再建 repository identity abstraction:现有 caller owner、provider owner 和 hygiene owner 已足够清晰。当前 PR 可以批准;合并仍应等待或重新评估远端基线门禁,不在本次 review 中绕过。

English verdict: APPROVE - head 38cf0b9; both prior blockers are resolved at their semantic boundary: the hygiene guard is path/use-aware with exact reviewed exceptions and mutation-sensitive counterfactuals, and the provider smoke now pins canonical strong, archived strong, generic weak, and noise dropped. Exact-head local validation passed (95 focused tests, both smokes/validators, diff check, and clean merge-tree); current remote shard failures reproduce on main or are covered by #4798, so they remain a merge-readiness hold rather than a finding in this diff.

@huangruiteng
huangruiteng merged commit 693b5d9 into loopx-project:main Sep 20, 2026
25 of 30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Task]: Live surfaces and one relevance oracle still carry the pre-transfer repository address

2 participants