Skip to content

test(architecture): close the two coverage gaps review found in the owner censuses - #8055

Merged
huangruiteng merged 1 commit into
loopx-project:mainfrom
keoyyo85:fix/census-coverage-gaps
Nov 5, 2026
Merged

huangruiteng merged 1 commit into
loopx-project:mainfrom
keoyyo85:fix/census-coverage-gaps

Conversation

@keoyyo85

@keoyyo85 keoyyo85 commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Goal And Delivered Outcome

  • Outcome basis / optional anchor: Review feedback on two merged changes — the P3 comment on refactor(chat): read the action-kind vocabulary from the store that owns it #7825 (tests/architecture/test_chat_action_kind_owner.py:67) and the P3 comment on refactor(progress-review): read the pending reason from the policy that owns it #7826 (tests/architecture/test_progress_review_pending_reason_owner.py:93). No issue is filed for either and none is invented here.

  • Goal/source and gap: Both files are censuses whose whole purpose is to fail when a second owner of one decision reappears. Each had a way for a copy to reappear while the guard stayed green.

    • The action-kind census walked module-level statements and skipped anything that was not ast.Assign, so a copy written as LOCAL: set[str] = {...} — the same fourteen members, annotated — passed.
    • The pending-reason census proved a consumer imports the owner and that the value still compares equal. Rebinding the imported name below the import with an equal but computed string ("pending_" + "evaluation") keeps the import, keeps the equality, and is invisible to a literal-keyed scan; an identity assertion does not close it either, because CPython folds that concatenation and interns the result.
  • Observable before → after: with both counterexamples planted in the same tree, the guards on main report 22 passed and see nothing; the guards here report 2 failed and name the second owner. On the clean tree the guards here are 26 passed against 22 on main, the four extra cases being the ones that pin this behaviour. Proved by the regression_parity rows below.

  • Issue/task and intended base: Related to refactor(chat): read the action-kind vocabulary from the store that owns it #7825 and refactor(progress-review): read the pending reason from the policy that owns it #7826 (both merged). Base main at ce4cfc1ce.

Author Declaration

  • Written by: model_agent (Claude-family model behind an AI coding agent).

Implemented against

  • Specification and revision: the two P3 review comments quoted above, each of which states both the counterexample and the accepted remedy ("handle ast.AnnAssign, or narrow the scanner's coverage claim" / "detect a later assignment to the imported name, or narrow the no-computed-copy claim").

  • Criteria:

Criterion (spec clause) Disposition Symbol / path Test or command
A reintroduced copy must fail the census whether renamed, reordered or annotated implemented module_level_bindings and vocabulary_assignments in tests/architecture/test_chat_action_kind_owner.py pytest tests/architecture/test_chat_action_kind_owner.py -k reintroduced_copy
An import that is later rebound locally is a second owner implemented owner_import_lines and module_assignment_lines in tests/architecture/test_progress_review_pending_reason_owner.py pytest tests/architecture/test_progress_review_pending_reason_owner.py -k "never_rebinds_it or flags_a_rebind"
Identity must not be used as evidence for a folded string implemented module docstring and the rejected counterexample case in the same file pytest tests/architecture/test_progress_review_pending_reason_owner.py::test_the_census_flags_a_rebind_that_keeps_the_import_and_the_value
  • Self-check before submission: I reproduced both counterexamples from the review against the merged guards before writing anything, and confirmed each guard stayed green, so neither claim rests on reading alone. The two scanners are scoped deliberately: the action-kind census reads module-level statements only, because a function-local variable holding the same members is not a second module-level owner; the new rebind check is module-level for the same reason, while the pending-reason literal census keeps its whole-tree walk. I narrowed rather than widened one claim: the pending-reason scanner still keys the literal census on a constant value, because its new rebind check — not the literal scan — is what now catches a computed copy, and the module docstring says so. Nothing in the product code is touched, so no behaviour is at risk here.

Scope And Continuation

  • Completed scope and remaining work: both censuses now reject the copies review identified, and each has a pinned case proving the scanner sees it. Remaining work: refactor(material-lifecycle): decide the apply outcome vocabulary in one owner #7398 carries two further review comments of the same family (a str(relative_to(...)) comparison that misfires on native Windows, and an over-stated comprehension-coverage claim in its header); they are the same class of gap in a different contributor's open change and are not edited here.
  • Slice boundary / successor: complete within this scope; each guard stays independently revertible because the folds they protect already landed.

Validation

  • Tested revision: 434c13542
  • Run state: finished
  • Input classes: public_fixture
Check kind Result Public-safe evidence / limitation
static passed ruff check on both changed guard files under the repository configuration: All checks passed.
unit passed pytest tests/architecture/test_chat_action_kind_owner.py tests/architecture/test_progress_review_pending_reason_owner.py tests/capabilities/test_progress_review.py tests/control_plane/test_external_progress_review.py → 84 passed at this revision, including both folded vocabularies' consumer suites.
regression_parity passed Failing-before, run as a discrimination test rather than a claim: the same two counterexamples (an annotated fourteen-member copy in loopx/chat_actions.py, and an equal computed rebind below the import in loopx/capabilities/progress_review/receipt.py) were planted in both trees. The guards on main reported 22 passed, seeing neither copy; the guards here reported 2 failed, naming both.
regression_parity passed With the counterexamples removed, this revision reports 26 passed and the base revision 22 passed, so the added coverage is four cases and no existing case changed outcome; both trees were re-verified clean after the mutations.
unit not_run CI has not run this revision yet: as a first-contribution workflow on this account the checks wait for a maintainer to approve them, so no CI outcome is claimed here.
  • Coverage and gaps: the pinned cases exercise the scanners directly with the exact shapes review supplied, and the consumer tests keep the real modules under the same guards, so a regression in either direction is visible. Untested: function-scope rebinding, deliberately out of scope as explained above, and native Windows execution (nothing here branches on host platform).

Frontend / Visual Evidence

  • UI impact: none
  • Before: N/A
  • After: N/A
  • First viewport and preview: N/A
  • States and viewports shown: N/A
  • Source data: none
  • Attention review: N/A — no presentation surface changed.
  • Craft review: N/A — no presentation surface changed.

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: Architecture convergence on shared vocabulary owners — keeping the censuses that protect them honest.

Shared-authority RFC fixture impact

  • Production-scale fixture schema: N/A
  • Semantic dimensions changed, or reviewed no-impact rationale: N/A
  • Provider conformance arms run: N/A
  • Read-only legacy/file/PostgreSQL three-arm rehearsal (required for promotion, runtime-routing, or compatibility-projection changes): N/A — test-only change, no routing or projection touched.

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.
  • Existing English/Chinese RFC pairs (including ledger entries) both have a diff, and the local premerge check python3 scripts/check_rfc_bilingual.py --base origin/main --head HEAD passes, or no paired RFC changed.
  • 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).

…wner censuses

The chat action-kind census visited only ast.Assign, so a reintroduced copy
annotated as LOCAL: set[str] = {...} passed the guard that exists to catch a
second owner. It now reads annotated module-level assignments too, and a
parametrised case proves a typed, renamed or reordered copy is recognised.

The pending-reason guard checked that the import exists and that the value still
compares equal. Rebinding the imported name below the import with an equal
computed string keeps both checks green and still installs a second owner, and an
identity assertion cannot see it either because CPython folds and interns such a
string. The guard now rejects any later module-level assignment to the imported
name, whatever shape that value has, with the counterexample pinned as a case.

Signed-off-by: keoyyo85 <335569976+keoyyo85@users.noreply.github.com>

@loopx-agent loopx-agent 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.

Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=max.

动机

没有阻塞性 finding;有一项 P3 覆盖说明建议。head 434c1354285b327b5c8f5b1b0a850e6c4b85a881,基线 ce4cfc1ce74a2ffe0d685758b8d6e9233b467f41。

  • 受影响调用者:维护 Chat action-kind 与 progress-review pending-reason 单一 owner 约束的贡献者和评审者。
  • 前后场景:相同的带类型十四成员集合副本、保留 import 的等值计算字符串重绑定,基线 census 均漏检;head 的原有真实检查分别拒绝这两个直接模块体反例。
  • 可观察结果:补上原两条 P3 评论指出的直接绑定覆盖缺口,保留现有生产 owner 和消费者行为;条件块覆盖仍作为非阻塞建议披露。
  • 非目标:不修改生产 vocabulary、运行策略或权限,不将直接模块体扫描等同完整 Python 名称绑定分析,不声称 CI 或长期收益已验证。

先读取了原评审依据:discussion_r4436543786,版本 1d31f0cb9b82d2d96ca193030b1b415909c03153;以及 discussion_r4436544120,版本 d8d81476212af75b5f878b578f42181e21a941f6。两条 P3 都允许修复相应直接反例或收窄覆盖声明;本次不把它们扩写成完整 Python 分析器的义务。

改动思路

在两个原 census 内补上对应输入形状,保留真实 owner/consumer 检查。第一个合并直接 Assign/AnnAssign 的读取;第二个同时核对 owner import、局部名字重新赋值和实际值。等值甚至同一对象都不能证明 owner 没被重新定义:CPython 可以折叠并 intern "pending_" + "evaluation"。

不用修改运行时,也无需新建共享 scanner 框架。其他架构测试虽有局部 AST helper,其资源与 scope 不同;这里复用原 guard 是较小且可独立回滚的边界。

具体改动

关键代码讲解

独立执行结果:四个原生模块(两 census+两个消费者 suite)基线 80 passed、head 84 passed;单独两 census 分别22/26 passed,Ruff 通过。相同的两处源码输入反例注入后,基线仍22 passed,head为24 passed、两个预期失败,分别落在实际重复 owner 检查。源码输入通过读取边界追加,实际 AST/guard/结果未被替换,tracked 文件未修改。另验证 annotation-only、函数局部、owner 引用和部分集合等七个合法控制未被误拒绝。

原生 quick premerge 5 direct+2 selected 全过,含 maintainability 与 semantic-vocabulary;精确 scope CQR通过,含下面的非阻塞 advisory。一个提交的 DCO trailer 已核对。

对主干的风险

P3:收窄“module-level”覆盖说明。 这两个 helper 只遍历 ast.parse(source).body。在 owner import 后加入 if True: PROGRESS_REVIEW_PENDING_REASON = "pending_" + "evaluation",同时把带类型集合副本放入 if True,head 的26项仍全部通过;这是模块作用域绑定,但不是直接模块体赋值。建议把说明明确写成“直接模块体绑定”,或有界遍历模块控制块并排除函数/类局部。原两条评论的直接反例确已修复,此项不阻塞;无需因此引入通用静态分析器。

生产代码、默认值、权限与用户操作路径未改变。检查的 source overlay 是合成反例,不能外推为完整 Python 名称绑定覆盖;原生 Windows/Linux 和远端 CI 未验证,未获取、轮询或等待 CI。当前完整队列中 keoyyo85 只有此 PR,不从这一次修复推断贡献者重复低价值工作。

我的整体评价

同意这个完整小修复,保留上面的 P3。它让两条已经证实漏检的输入真正触发原 guard,同时保持消费者和合法输入通过;新增用例数本身不是价值证明。

视觉评审不适用:改动仅为 tests/architecture/test_chat_action_kind_owner.py、tests/architecture/test_progress_review_pending_reason_owner.py 的测试代码与说明,没有 rendered presentation 变化。未验证范围:安装后 Host/model 行为、原生 Windows/Linux、整页视觉和长期效果。实际产品入口和额外必需交互轮数保持不变。APPROVE 不授予合并权限。

English verdict: APPROVE — the two direct-binding escapes are detected at 434c1354285b327b5c8f5b1b0a850e6c4b85a881. One non-blocking P3 clarifies conditional/module-body coverage; CI and platform qualification remain unverified.

def module_assignment_lines(source: str) -> dict[str, int]:
"""Module-level names assigned a value, whatever shape that value has."""
assignments: dict[str, int] = {}
for statement in ast.parse(source).body:

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.

[P3] 建议把说明限定为直接模块体绑定,或覆盖模块控制块。这里仅遍历 Module.body;在 owner import 后追加 if True: PROGRESS_REVIEW_PENDING_REASON = "pending_" + "evaluation",并将带类型集合副本同样包在条件块内,当前26项仍全过。原两条直接绑定反例已经修复,此项不阻塞;若保留“任何后续 module-level assignment”的声明,建议补此反例并排除函数/类局部作用域。

@huangruiteng
huangruiteng merged commit 1c69e1c into loopx-project:main Nov 5, 2026
23 of 34 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.

3 participants