Skip to content

fix(digest): restore the single owner for the whole-value SHA-256 shape - #6845

Merged
huangruiteng merged 3 commits into
loopx-project:mainfrom
JasonBuildAI:codex/digest-owner-restore-c5n8
Oct 19, 2026
Merged

huangruiteng merged 3 commits into
loopx-project:mainfrom
JasonBuildAI:codex/digest-owner-restore-c5n8

Conversation

@JasonBuildAI

@JasonBuildAI JasonBuildAI commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Goal And Delivered Outcome

Author Declaration

  • Written by: model_agent (OpenAI Codex).
  • AI disclosure: this change was drafted with AI assistance at my request, under my direction and review.

Implemented against

Criterion (spec clause) Disposition Symbol / path Test or command
No module outside the owner states a whole-value digest shape implemented loopx/control_plane/status/goal_source.py, loopx/hosts/checkpoint_retention.py tests/architecture/test_content_digest_single_owner.py::test_only_the_owner_module_states_a_whole_value_digest_shape
A new reader names a canonical export and is pinned in the manifest implemented both modules import BARE_SHA256_PATTERN; both added to CONSUMER_MODULES ::test_the_consumer_manifest_is_exactly_the_pinned_set, ::test_consumers_name_the_canonical_exports_and_use_them, ::test_every_consumer_holds_the_owner_object_not_an_equal_copy
No behaviour change at the retired call sites implemented BARE_SHA256_PATTERN.fullmatch replaces the local patterns ::test_each_retired_spelling_and_the_owner_split_the_same_strings (21 probes, including the trailing newline)
  • Self-check before submission: reproduced the failure locally at dc9fdbb51; then removed both modules from the tree (they did not exist before their introducing merges) and the focused test passed (1 passed), proving these sites are the only cause; restored the tree, applied the fix, and the whole guard file passes. Also ran ruff, the semantic coinage advisory, the architecture suite and canary premerge, with every remaining failure base-verified (details below).
  • Independent review: an independent reviewer verified this revision (checked ancestry, re-ran the base reproduction and the head guard file, probed the retired spellings against the owner including trailing-newline and non-string inputs, and re-ran the changed-surface tests): verdict APPROVE WITH NOTES, no blocking findings. Its two notes are recorded under Coverage and gaps.

Scope And Continuation

  • Completed scope and remaining work: complete within this scope — the four sites now read the owner, both modules are pinned, and the guard is green again.
  • Slice boundary / successor: N/A — the guard remains the enforcement point for future surfaces; the separate windows-powershell budget failure that also feeds merge-gate is a different pre-existing defect and is not part of this diff.

Validation

  • Tested revision: 0866d6f3b6a33927f412e9c687fe0c987c6b900c
  • Run state: finished
  • Input classes: none
Check kind Result Public-safe evidence / limitation
regression_parity passed tests/architecture/test_content_digest_single_owner.py at this head: 227 passed. The same file at dc9fdbb51 fails with the four listed sites. With both modules removed the focused test passes (1 passed), and with them restored plus the fix it passes again — failing-before / passing-after in one worktree.
static passed uv run --extra test python -m ruff check tests/architecture/test_content_digest_single_owner.py loopx/control_plane/status/goal_source.py loopx/hosts/checkpoint_retention.py → "All checks passed!"; scripts/generate_semantic_inventory.py --changed-from HEAD → no supported new vocabulary carriers.
unit passed tests/architecture (excluding the two cp936-limited files listed below): 1500 passed, 1 skipped.
unit not_applicable tests/control_plane/test_checkpoint_retention.py: 12 skipped — the module refuses non-POSIX hosts by design, so the retired \Z spelling is covered by the guard's parity corpus instead; hosted Linux shards exercise the POSIX path.
unit failed tests/presentation/test_goal_source.py: 3 failures at this head and identical at a baseline dc9fdbb51 worktree (POSIX-absolute source paths on a Windows host: ValueError: Source paths must be absolute); the 5 host-independent cases pass. Pre-existing, not caused by this diff.
unit failed tests/architecture/test_semantic_quota_run_witness.py and tests/architecture/test_settlement_receipt_source_boundaries.py::test_failure_input_witnesses_cover_the_registered_wire_domain fail with UnicodeDecodeError: 'gbk' codec ... on this cp936 host, reproduced at the baseline dc9fdbb51 worktree; excluded from the suite row above.
manual failed loopx canary premerge --from-git-diff: public-boundary check passed (0 errors / 0 warnings); the direct and risk-profile failures (pr-review-command-smoke, install-local-smoke WinError 1314 symlink privilege, codex-cli-packaged-install-smoke requiring bash, loopx-update-smoke, and the dsh plugin phases requiring a pnpm workspace) reproduce identically in the baseline worktree.
integration failed Hosted lanes at this head finished. The decisive test-shard (1) runs tests/architecture/test_content_digest_single_owner.py::test_only_the_owner_module_states_a_whole_value_digest_shape as PASSED (job 117864821025, 05:19:40Z) and ends 1 failed, 4137 passed, 107 skipped - the single failure is the pre-existing tests/test_chat_manager_inspection.py Codex app-server timeout, which fails identically on the baseline run. Per-lane comparison against run 39172287050 at dc9fdbb51: shard 1 1 failed / 4137 passed here vs 2 failed / 4136 passed baseline (the baseline extra failure is exactly the digest second-owner assertion this PR removes); shard 3 2 failed / 4138 passed on both (monitor DID NOT RAISE + chat [todos]); shard 4 1 failed / 4144 passed on both (chat [todos_exact]); shards 5 and 2 end cancelled on both runs (the 60-minute job ceiling); shard 6 success on both. windows-powershell fails on both runs on the pre-existing budget defect (heartbeat_prompt_brief/json emitted 10522 chars; variant ceiling is 10500; baseline job 117808033252). pytest and merge-gate therefore stay red for causes identical to dc9fdbb51 and outside this diff; no new failing test id appears at this head.
  • Coverage and gaps: the changed lines validate a container id, a source-identity namespace and a rotation-point digest. The guard proves there is no second statement and no equal copy, and its parity corpus (both retired spellings × 21 probes including the trailing newline) is the behaviour oracle. Not executed here: the POSIX-only rotation path (skipped on this Windows host); hosted Linux CI covers it. Two reviewed non-blocking notes: (1) the pre-existing windows-powershell budget failure keeps merge-gate red independently of this diff; (2) because the owner pattern ends in $, a future switch of any site from .fullmatch to .match/.search would accept a trailing newline where the retired \Z spelling rejected it — no current call site does this, and the guard's layer-4 corpus documents that $-vs-\Z boundary.

Frontend / Visual Evidence

  • UI impact: none — no user-visible surface changed.
  • 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 visual surface changed.
  • Craft review: N/A — no new UI.

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: N/A — reproduced defect with a bounded repair; no RFC anchor.

Shared-authority RFC fixture impact

  • Production-scale fixture schema: N/A
  • Semantic dimensions changed, or reviewed no-impact rationale: N/A — no vocabulary added; the change reuses the existing owner.
  • 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

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).

The required Python Tests check is red on main dc9fdbb: the digest-owner
guard reports second owners of the whole-value bare SHA-256 shape in
loopx/control_plane/status/goal_source.py (three re.fullmatch sites added by
6e8b4b1) and loopx/hosts/checkpoint_retention.py (the compiled _SHA added by
c56a3b1). This is the same class as loopx-project#6117 on the TypeScript twin; every PR
based on current main inherits the failing required check.

Validate all four sites through BARE_SHA256_PATTERN from the canonical owner
and pin both modules in the guard's CONSUMER_MODULES, which is the guard's
designed review event for a new reader of the owner. The guard's layer-4
parity corpus already proves that the retired spellings split exactly the same
strings as the owner pattern, including the trailing-newline probe, so this is
behaviour-preserving.

Closes loopx-project#6841.

Signed-off-by: JasonBuildAI <jasonbuildai@gmail.com>
@JasonBuildAI

Copy link
Copy Markdown
Contributor Author

Independent review record — 0866d6f3b6a33927f412e9c687fe0c987c6b900c

Verdict: APPROVE WITH NOTES. Reviewed by an independent reviewer in a separate session, against this exact head and a baseline worktree at dc9fdbb51; the reviewer re-ran the evidence rather than reading the author's claims.

Verified independently:

  • Ancestry and scope: single commit over dc9fdbb51, exactly 3 files, +8/-4, DCO trailer present, no unrelated edits.
  • Before/after: the guard file fails at dc9fdbb51 with exactly the four reported sites and passes at this head (227 passed in 21.5 s). The modified test only adds manifest pins, so this is a genuine failing-before / passing-after pair rather than a test adapted to the change.
  • Behaviour parity at the retired sites: probed the retired spellings (re.fullmatch(r"[0-9a-f]{64}", …), and compiled [0-9a-f]{64}\Z with .fullmatch) against BARE_SHA256_PATTERN.fullmatch over 22+ values (63/64/65 hex, mixed case, non-hex, empty, trailing \n, \n\n, \r\n, leading newline, envelope-prefixed, doubled, non-ASCII): zero mismatches; non-string inputs raise the same ValueError. _SHA is BARE_SHA256_PATTERN is true at runtime and no other module imports _SHA.
  • The two pins are necessary, not decorative: without them test_the_consumer_manifest_is_exactly_the_pinned_set fails with "imports the owner but is not pinned".
  • uv run --extra test python -m ruff check on the three changed files: "All checks passed!".
  • Broader tests/architecture at this head shows only the pre-existing local cp936 decode failures, each re-run at the baseline and failing identically.

Non-blocking notes (outside this diff):

  1. windows-powershell fails on the pre-existing tests/control_plane/test_cli_output_budget.py ceiling (heartbeat_prompt_brief/json emitted 10522 chars; variant ceiling is 10500), identical at dc9fdbb51; because merge-gate needs that lane, the required gate remains red for that separate cause until it is fixed elsewhere.
  2. The owner pattern ends in $: a future change of any site from .fullmatch to .match/.search would accept a trailing newline where the retired \Z spelling rejected it. No current call site does this, and the guard's layer-4 parity corpus records that $-vs-\Z boundary.

@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 · observation=bc811dddc598476f28a07c6665e70eee96fe6fc5e62a624f0e5d31c4946ae644

结论:APPROVE,绑定 0866d6f3b6a33927f412e9c687fe0c987c6b900c(base dc9fdbb5186618ec2e797a9d7545e2fe524fee56)。本地实际执行的检查通过;精确范围质量凭证缺失仍为独立合并门槛。

动机

维护者运行主干的格式所有权检查时,会被两个已发布读取器重复声明 SHA-256 规则阻断。例如来源标识和检查点恢复都需要校验完整的 64 位小写十六进制值:旧代码各写一套模式,违反单一 owner 契约;本次改为引用已有规则,并保留原来接受和拒绝的输入。独立重跑确认,基线报告的四处重复声明在候选版本消失,21 类输入经过四个真实读取入口的结果与错误信息逐项相同。本 PR 不扩大可访问来源、不改变检查点删除权限或持久化格式,也不宣称其余主干失败均已修复。

改动思路

沿用既有共享格式规则并移除四处重复声明,两个读取器继续负责自己的来源范围和文件恢复条件;无需新增兼容分支、provider 或判断 owner。当前边界是四个完整值校验点与两个消费者清单项;来源读取、检查点恢复、原有错误信息和副作用条件保持不变。入口按 GoalSource constructor/manifest parser and loopback read_endpoint -> canonical bare pattern; retention original receipt recovery -> _SHA alias -> same canonical pattern. 追踪。没有另建权威状态、手工同步字段或用户配置。无改动会保留已复现的验证问题;仅改数字/豁免扫描会缺失必要证明,因此本提案连同对应契约、消费者和反例一起审查。

具体改动

规范依据:先读取 immutable base 的既有契约,再将本轮局部审查标准映射如下;这些标准不新增产品词表或执行权限。D1 已实现:来源构造、manifest 解析和 loopback 描述返回值三个完整值判断改用 canonical export,retention 的 _SHA 保留名称但成为同一个对象;不再重编译相等模式。D2 已实现:消费者清单新增这两个真实模块,原四层 guard、扫描范围和行为断言没有删除、豁免或放宽。D3 已实现:所有相关实际调用仍使用 fullmatch,调用方的类型、来源范围、回执文件名、状态和恢复前置条件保持原样。TypeScript 是值的 owner,生成的 Python 常量没有改,纯 Python 调用未增加桥接 IO。

关键代码讲解

  • GoalSource.__post_init__:Pinned container identity and source scope before IO。Existing canonical pattern replaces local literal; parse follows same rule。
  • read_endpoint:Validates actual loopback description before later source reads。Namespace regex delegates to same owner。
  • _recover_trash:Checks original receipt identity/name/status before quarantine recovery。_SHA is actual canonical object; fullmatch and all recovery guards retained。

对主干的风险

同三个模块在 immutable base 为 1 失败、246 通过,失败明确列出三处 goal_source literal 和一处 retention 模式;head 为 247 通过,无跳过。除了 guard,还执行真实 POSIX 检查点 preview、execute、失败恢复、并发读锁和惯常 CLI 路径,补上作者 Windows 环境未能执行的 POSIX 部分。另用相同 21 类输入分别进入 dataclass 构造、manifest 解析、真实 loopback HTTP 描述读取和原始 retention 回执恢复,共 84 个观察/版本:接受/拒绝、异常类型与错误信息逐项一致,拒绝后原回执字节不变。容器真正执行和远端 SSH/Docker 环境没有新增实测。

主要反例是摘要格式被意外放宽后导致错绑来源或恢复错误文件。本轮覆盖大写、长短值、非十六进制、envelope、空白、换行/CRLF、后缀、全角字符和非字符串,仍由原读取器拒绝。实际 POSIX 恢复测试通过;没有把这些结果称为 Windows 或全仓库健康。作者记录的其他历史失败及 hosted 状态没有被本轮测试数替代。Ruff、diff 检查通过;标准原生 premerge 的 6 个 direct 与 13 个 selected 检查实际执行并通过。托管精确范围质量凭证返回 receipt_missing,所以premerge 外层 exit=1 / ok=false,没有记为全绿,也没有生成或伪造凭证。该合并门槛与源码评审结论分别保留。没有查询、等待或派发 CI。

语义与 CI 对齐

本 PR 恢复已存在的“一个 owner 声明完整摘要形状”契约,属于 reuse_existing。清单 pin 是已有所有权检查要求,不是新增业务状态;没有增加授权、值域或持久化版本。实际 whole-value 语言保持等价,当前所有路径都用 fullmatch,因此 $ 与旧 \Z 的换行差异没有扩大接受范围。未来改成 match/search 需重新验证,当前无需为假设中的调用方式增加兼容层。静态词表 smoke 和当前选择的语义检查通过,检查通过不代替上述实际反例与合同判断。

我的整体评价

四处重复声明的修复和行为不变性已独立验证,建议 APPROVE。长期工作与用户体验均评为 preserved:格式 owner 归一,原生读取、拒绝、恢复和完整错误信息保持既有行为;测试恢复不能直接证明长期效果提升。这次移除重复规则就是有边界的简化,不需要新增抽象或迁移。两项维度的结论只覆盖上述真实路径和完整提案。沿用既有共享格式规则并移除四处重复声明,两个读取器继续负责自己的来源范围和文件恢复条件;无需新增兼容分支、provider 或判断 owner。当前边界是四个完整值校验点与两个消费者清单项;来源读取、检查点恢复、原有错误信息和副作用条件保持不变。未发现本 head 的阻断性源码问题;批准不代表质量凭证已齐备、其他 review hold 已清除或获得合并权限。发布前再次核对当前 head 和原生 action,后续版本变化需要重新判断。

English verdict: APPROVE — Restores the canonical bare-SHA256 owner without widening actual reader acceptance. Base failure, real reader parity and POSIX recovery paths were independently verified. The separate exact-scope quality-receipt hold remains.

@huangruiteng
huangruiteng requested a review from songoow as a code owner October 19, 2026 08:52
@huangruiteng
huangruiteng merged commit f2a7fd2 into loopx-project:main Oct 19, 2026
4 of 6 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.

[Bug]: main's Python digest-owner guard fails - goal_source.py and checkpoint_retention.py restate the bare SHA-256 shape

3 participants