Repository navigation
issue_fix: borrow MAINTAINER_ASSOCIATIONS from github_public - #8613
huangruiteng merged 2 commits into
Conversation
candidate_evidence drops its private restatement; a new architecture guard pins the single owner. Signed-off-by: psychologister <230141834+psychologister@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · max
本次评审对应提交 0932a4151ded8393175196436ca46c3783fde554。
[P2] 把 maintainer association 检查对准候选入口。 全包 AST 检查会拒绝无关的有序展示标签。隔离候选分支额外接受 CONTRIBUTOR 后,新增检查全部通过,真实候选构建器却收录了该评论修订。
动机 / Motivation
执行 issue-fix 候选预检的用户和维护相关权限判断的贡献者。候选预检和 PR lifecycle 持有相同三成员规则,候选端另有本地副本。基线与当前头对六类 association 的候选证据完全一致。三个成员产生当前评论修订证据,缺少 updatedAt 时拒绝。其他三类均不进入证据。基线与当前头对六类 association 的候选证据完全一致。三个成员产生当前评论修订证据,缺少 updatedAt 时拒绝。其他三类均不进入证据。证据来自隔离本地构建器与合成 provider 评论。未查询远端 CI,也未执行 live GitHub 候选采集。全包 AST 检查会拒绝无关的有序展示标签。隔离候选分支额外接受 CONTRIBUTOR 后,新增检查全部通过,真实候选构建器却收录了该评论修订。
改动思路 / Approach
两个调用方共享现有 owner 是直接的复用方式。当前生产改动的归一化、修订与结果 shape 保持原行为。新增检查的作用域需收回到该 owner 的实际契约。 候选预检引用 github_public 已有的 MAINTAINER_ASSOCIATIONS,PR lifecycle 也引用同一个集合。修订读取仍在实际构建器里,适合在那里验证过滤和失败语义。
具体改动 / Changes
关键代码讲解
- 候选构建器按原规则归一化 authorAssociation,再用共享集合筛选评论。合格评论仍必须提供当前 updatedAt。 候选入口
- 新测试确认对象身份和 AST Load,另遍历 loopx 下的 Python 文件,匹配三标签字面量集合。这里缺少标签用途和实际调用范围。 全包扫描
- 精确基线与当前头的完整预检结果相同。OWNER、MEMBER、COLLABORATOR 提供当前评论修订,其他三类均过滤。缺失修订的成员仍走同一拒绝。 候选证据契约
采用 docs/development/README.md @ ea67e68 的 Scope-Fit Review。single_issue_fix_owner 与 current_comment_revision_parity 已满足,behavior_sensitive_guard 由两项反例判定未满足。 Scope-Fit Review
对主干的风险 / Risks
全包约束会把无关的有序显示标签变成新的测试失败。隔离 mutation 保留共享常量的引用,同时额外放行 CONTRIBUTOR,新增检查均通过,实际候选构建器已把该评论修订收进证据。这一扩权只发生在故意修改的测试模块。精确头的构建器保持六类输入的原有判断。
语义与 CI 对齐
133 项候选、GitHub 编码、PR lifecycle 与执行器相关测试及 20 项新增架构测试通过。另在隔离测试中复现两个 guard 反例。Ruff、DCO 和 git diff --check 通过。未查询远端 CI 或执行 live GitHub 候选采集。
我的整体评价 / Verdict
保留生产代码的共享 owner。请收窄新测试的静态作用域,并让实际候选入口的测试拒绝扩大的成员集合且保留当前修订校验。完成后可复审该测试边界。本次评审覆盖现有宿主与 CLI 行为。证据来自隔离本地构建器与合成 provider 评论。未查询远端 CI,也未执行 live GitHub 候选采集。
English verdict: REQUEST_CHANGES. Keep the shared constant. The package-wide guard rejects unrelated display labels and misses a deliberate expansion of the candidate predicate.
|
|
||
| def test_only_the_owner_states_the_maintainer_association_set() -> None: | ||
| offenders: dict[str, list[int]] = {} | ||
| for path in sorted(PACKAGE_ROOT.rglob("*.py")): |
There was a problem hiding this comment.
[P2] 把 maintainer association 检查对准候选入口。 这个全包扫描按三个字符串的集合匹配。隔离 fixture 中,普通的有序展示标签 ('OWNER', 'MEMBER', 'COLLABORATOR') 会使该测试失败。反过来,在候选构建器加上 or association == 'CONTRIBUTOR' 后,新增静态检查和 owner 真值表全部通过,构建器却将该评论及修订纳入 maintainer evidence。请把检查约束到 issue-fix 的实际消费点,并经候选构建器断言非成员与缺失修订的行为。
Addresses the CHANGES_REQUESTED review on the maintainer-association single-owner
guard. The production single-sourcing is kept exactly as reviewed: candidate_evidence
and pr_lifecycle still borrow github_public.MAINTAINER_ASSOCIATIONS, unchanged.
Two test-only fixes:
The static census was package-wide, so any unrelated ordered display label elsewhere
in loopx that lists ("OWNER", "MEMBER", "COLLABORATOR") would be swept as a false
offender. Its scope is narrowed to loopx/capabilities/issue_fix -- the capability that
owns the contract (the owner plus its two consumers) -- so a renamed restatement inside
the capability is still caught while unrelated tuples outside it are out of scope.
The behavioural evidence only exercised github_public._normalise_comment_signal, not
the candidate gate, so a deliberate `or association == "CONTRIBUTOR"` expansion at
candidate_evidence.py's maintainer filter passed every static check and the owner truth
table. A new truth table drives the real builder
build_public_github_candidate_preflight_input with synthetic provider comments: the
three members produce maintainer evidence at their current updatedAt revision, a
non-member (notably CONTRIBUTOR) produces none, and a member comment with a missing or
empty updatedAt is rejected. Mutating the gate to admit CONTRIBUTOR fails exactly the
non-member case while the census stays green, confirming the guard is now
behaviour-sensitive at the real consumption point. The signal-normalizer table,
identity, AST-reader and poison controls are retained.
Refs loopx-project#4447.
Signed-off-by: psychologister <230141834+psychologister@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · reasoning_effort=max
复审提交 cbb8a257c7436f2a58bcbf3d4297d6a771f51516。上轮两项发现均已验证解决。本轮无阻塞发现。
动机 / Motivation
运行 issue-fix 候选预检的贡献者,需要知道哪条维护者评论会要求先核验,再继续补丁。 旧版在候选预检和评论采集各维护一份成员集合。当前提交共用已有集合,成员的当前修订、非成员过滤及缺字段错误保持一致。 我对照主干与当前提交的 11 组候选输入和 18 组评论时序,两边完整输出一致。把 CONTRIBUTOR 故意放进候选条件后,新测试抓住了这次扩张。 证据来自源码预检、合成 GitHub 评论及主干试合并。实时 GitHub 采集、整仓和托管 CI 未执行。
改动思路 / Approach
生产改动限候选预检借用现有常量,测试覆盖 issue-fix 域内的共享规则与两个实际读取入口。 把集合留在 GitHub 输入 owner,两个入口保留各自的时序和修订校验。 原来两份集合遇到策略调整需要同步。候选预检只换引用,公开回复仍以发帖时间和锚点为准,PR lifecycle 仍按已验证评论和修订处理。新增测试直接跑真实候选构建器,也约束共享规则只在所属能力内定义。
具体改动 / Changes
关键代码讲解
- current-comment-revision。候选构建器先规整 association,再通过共享成员集合筛选。OWNER、MEMBER、COLLABORATOR 以及带空白的 owner 都输出当前评论 URL 和修订。 CONTRIBUTOR 与未知身份不进入证据。成员缺 updatedAt、缺 association、重复 URL 或缺 URL 保持原拒绝。 候选预检分支
- shared-owner-parity。公开评论归一化和 PR 生命周期继续读取同一对象。在公开回复入口,三个维护者身份只有晚于锚点的其他评论才产生信号,正文未进入投影。 公开回复投影 生命周期读入
- regression-sensitive-guard。在独立副本加入同标签的域外显示元组,静态检查通过。扩张候选条件后 CONTRIBUTOR 用例失败,两个普通非成员用例依旧通过。保护条件在候选构建器上生效。扫描范围 候选反例
契约依据为 loopx/capabilities/issue_fix/README.md,版本 167b0a1。按相同提交的 Scope-Fit Review 核对了验证作用域、现有调用方和可证伪性。候选证据契约 Scope-Fit Review
对主干的风险 / Risks
运行时仍只把具备当前修订的维护者评论作为候选证据,审批关闭路径的另一组成员规则保持其独立用途。最直接的风险是普通评论被当作维护者输入,或测试误拦同名展示标签。两项针对上轮发现的反例均已覆盖。精确头 56 项、最新主干 33 项、试合并 65 项相关测试通过。源码与 GitHub 的改动路径一致,Ruff、DCO、diff 检查和 RFC 双语门通过。 架构测试的 fixture 仍有合并空间,现有反例已足以保护变更。
我的整体评价 / Verdict
批准当前提交。共享规则归属明确,候选证据和回复时序的原有语义得以保留。未来若调整评论来源字段,应继续在现有预检验证修订和失败回执。证据来自源码预检、合成 GitHub 评论及主干试合并。实时 GitHub 采集、整仓和托管 CI 未执行。 本次评审只判定代码和当前行为。
English verdict: APPROVE. The scoped guard now leaves unrelated display labels alone and catches an expanded maintainer predicate at the real candidate builder. The exact head preserves comment-revision and reply-timing behavior against main.
What
issue_fix/candidate_evidence.pykept a private_MAINTAINER_ASSOCIATIONS = {"COLLABORATOR", "MEMBER", "OWNER"}. It now borrowsMAINTAINER_ASSOCIATIONSfromgithub_public.py, whichpr_lifecycle.pyalready imports.github_publicis a leaf module (stdlib only), so this introduces no import cycle.Guard
New
tests/architecture/test_issue_fix_maintainer_association_owner.py:_normalise_comment_signalwith timing held fixed, so association membership — not the clock — is what flips the signal.The four-member TypeScript reviewer set (adds
CONTRIBUTOR) is a different question and is left alone.Tests
Guard + issue_fix focused tests + turn-executor integration pass locally; the census is poison-proven.