Skip to content

fix(materials): revise existing candidates after exact reads - #5934

Merged
loopx-agent merged 2 commits into
mainfrom
codex/material-source-revision-20261008
Oct 8, 2026
Merged

loopx-agent merged 2 commits into
mainfrom
codex/material-source-revision-20261008

Conversation

@loopx-agent

@loopx-agent loopx-agent commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

When an existing material was first saved from a short preview and later fully read, append-only intake rejects the changed content or metadata. The saved material consequently remains metadata-only despite the new reading evidence.

Add an optional revision/rollback extension to the existing material source SDK. It binds the current authority and previous record, stages exact-read content under the same identity, and checks membership, peers, lifecycle, ranking and retained content before CAS publication. Rollback rechecks current authorization and refuses to cross subsequent writes. Intake stays append-only; ranking remains a separate Decision Context-backed operation.

The reviewed P1 is fixed: the retained snapshot now passes the shared candidate validator before staging. Invalid source/record metadata or content lengths cannot enter a public-safe receipt and make rollback unusable. Eleven regression cases assert rejection before staging or file/authority changes; ten of them fail on the reviewed head and pass after this repair.

This extends the established Python source apply boundary for the S6 material revision journey. Project adapters still own durable receipts, invalidation of stale public-field reviews, and queue publication/readback. Generic frontend adoption is outside this change.

Validation on the repaired head:

  • 166 related Material Lifecycle and Decision Context tests pass, including 23 revision tests.
  • Ruff check/format and scoped strict mypy (--strict --follow-imports silent on the revision module) pass. A recursive unscoped mypy attempt reports repository-wide errors; a full repository typecheck is not claimed.
  • Standard diff-derived premerge passes: 5 direct checks and 19 selected/executed checks, with no failures, warnings, advisory findings or manual holds. Goal change-quality qualification is disabled.
  • The isolated actual project file-source/QueuePublisher canary preserves 787 identities and peer ordering, verifies exact backing, replay, rollback, grant revocation, projection-failure restoration, and invalidation of a changed public-field review. Its Core authorization fixture is synthetic; it is not live Bot proof.
  • The preceding reviewed head was also adopted in a live original-session project Bot journey: one existing material was revised under the native owner Turn and ranked independently, with immutable backing and separate revision/ranking receipts verified. That observation qualifies the earlier local project candidate, not live execution of this repaired head or a released install.
  • No CI was polled. Private material, identities, configuration and receipts are excluded.

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

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=xhigh

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

English verdict: REQUEST_CHANGES — at 4fcbea4b33e94509b275d627ed470f60c3a31fae, an unvalidated old-record snapshot enters a receipt labeled public-safe after publication; rollback then rejects that same snapshot. The valid-record path and repository checks pass, but this privacy/reversibility defect blocks approval.

动机

需要把已保存的短预览更新为完整已读文章的材料 source SDK 调用方会遇到这个问题。此前,同一材料后来读到全文时,append-only intake 拒绝变化,调用方只能保留旧预览;本 PR 拟在同一材料身份下替换内容并保留可回滚的旧版本。

有效旧记录的实文件验证确认了定向更新、同伴及排序不变、正常回滚;但旧记录含非 opaque 引用时,apply 成功返回了不安全的公开回执,随后 rollback 拒绝恢复。本次增量不引入排名策略、自动激活、额外 Core 写权限或新的通用前端入口。项目适配器持久化回执、重新审核公开字段、发布并读回队列,以及真实 Core/Bot 和 packaged frontend 的采用仍未由这份 SDK 评审证明。

改动思路

新的显式 SDK 调用把当前材料身份、旧记录版本与全文摘要绑定起来,先把新内容和目录放到不可变的候选版本,再核对同伴、成员、排序和旧内容,最后重新验授权、CAS 切换并读回。排序仍由原 owner 决策,provider 负责文件或服务 IO;proposal/回执引用本身不授予权限。这个安排也保留了旧 intake 的 append-only 行为:我通过实文件旧入口确认,重复身份且内容变化仍拒绝,authority 没有切换。

沿用已有 source apply 所有者,在 provider IO 与 SDK 验证之间加入针对单条记录的替换和保全证明,边界合理;当前缺口可以复用旧记录字段验证修复,不需要第二套权限或排名所有者。当前 PR 保留可选 SDK 的单条候选记录修订/回滚边界;在发布旧记录快照前补齐验证,真实产品适配与接入继续单独验收。不做更新会留下真实的短预览问题,直接放松 intake 会改变旧调用方;新增独立全局状态/权限框架也没有必要。当前 module 的额外协议和两项 provider 方法是这段可逆 IO 的成本,最有价值的伴随收敛是让新旧快照共用已有字段 validator。真实 Core 授权尚未验证;本次文件 fixture 提供的是合成 grant verifier,不能据此认证实际账户或 Bot。

具体改动

完整 base-to-head 为 4 文件、953 行新增:revision.py 509 行行为实现,__init__.py 18 行导出,文件验证 402 行,README 24 行操作说明。没有旧实现删除、自动调用或 scheduler/quota 改动。本次是首个完整 exact-head 评审,没有继承旧批准。

规范依据:docs/reference/protocols/material-lifecycle-architecture-v0.md,固定到 base 89505091fe52d318112aaaefb85f97e61cf11b33,先于实现读取。按原文边界判定:Position 已在 SDK 调用边界实现 default-off/既有 scope gate;Owner-Gated Apply and Rollback 未满足,旧快照验证不对称;Stage-0 Contracts 未满足,非 opaque 旧字段进入 public-safe 回执;Stage Boundary 明确 deferred,剩余真实适配与接入见上述 gap,不能把本 PR 称作整个材料采用流程已完成。

关键代码讲解

  • build_material_candidate_revision_proposal(revision.py:96):复用 intake 对 owner、引用、摘要和长度的输入校验,再绑定 expected/new record 与修订 schema。构造 packet 只证明数据一致性,既不激活能力也不授权读取源。
  • apply_material_candidate_revision(:297):当前 grant、source CAS 和 record CAS 之后 staging;替换记录在 :371 使用共享 _validate_candidate,随后 reconciliation 保全同伴/顺序/旧 backing 并再次验权切换。问题是 :337 得到的旧记录只做部分验证,:403–415 在切换后直接复制字段到 previous_record。
  • rollback_material_candidate_revision(:435):回执 hash、当前 grant、after-revision CAS 与历史保全核对后,在 :474 对旧记录完整校验。这一校验合理,但它会拒绝 apply 刚刚放进回执的非法旧字段,因此成功 apply 不等于可恢复。

__init__ 给出了真实可调用的公共 SDK 入口;树内调用方搜索只发现导出与本组测试,没有找到新的 production adapter 调用。README 正确声明可选 SDK 与后续适配边界。三项 v0 schema 是既有 Material Lifecycle vocabulary 的扩展,不是另一个 actor/权限生命周期;semantic advisory 没发现支持的新增载体,但 scalar schema 常量不在其覆盖范围,所以我还手动检查了这三个标识及关联 owner。

对主干的风险

[P1] 发布前校验旧记录快照(revision.py:404)。 旧记录的 source_ref、source_revision、exact_read_ref 或 content_backing_ref 可携带共享 compact-token validator 已明确拒绝的 raw URL、路径或 credential-like 值。新的 proposal 与替换记录全部合法、reconciliation 也成功时,当前 apply 仍切换 authority 并把该值复制进 visibility=public_safe、private_locations_captured=false 的回执。随后 rollback 在验证旧记录时抛出 ValueError,authority 保持新版本。四个字段的独立实文件反例都复现了此链路;正常 opaque 引用对照可以恢复完整旧 catalog,peer 和 ranking 保持不变。

最小修复是在 stage_candidate_revision 之前复用已有 candidate/compact-token 与正数长度验证,把旧 snapshot 变为已经校验的公共值,再生成回执;原始 legacy metadata 留在 provider 私有存储并用 opaque ref 引用。不要删除 rollback 校验或仅修改 privacy 标志。回归用例应分别污染旧引用/摘要/长度,断言没有 staging、authority switch 或 public receipt,同时保留有效 apply/rollback 和 peer/rank 的对照。

下面是当前 head 可直接复现的最小例子(真实临时 catalog/backing;授权 verifier 是测试 fixture)。现有 head 最后一个断言失败,并且若传该回执调用 rollback,会因 raw URL 抛错;修复后应在 apply 前置验证处拒绝这个输入:

uv run --extra test python - <<'REPRO'
import importlib.util, json, tempfile
from pathlib import Path
s = importlib.util.spec_from_file_location('revision_fixture', 'tests/test_material_candidate_revision.py')
t = importlib.util.module_from_spec(s)
s.loader.exec_module(t)
with tempfile.TemporaryDirectory() as d:
    source = t.FileSource(Path(d))
    old = source.load('revision:old')
    unsafe = 'https://example.invalid/private-read'
    old['records']['material:article']['exact_read_ref'] = unsafe
    source.save('revision:old', old)
    receipt = t.apply(source)
    assert receipt['status'] == 'applied'
    assert unsafe not in json.dumps(receipt), 'unsafe old ref in public_safe receipt'
REPRO

验证:12 个材料/decision-context test modules 155 passed;标准 canary premerge --from-git-diff --git-diff-base 89505091fe52d318112aaaefb85f97e61cf11b33 的 5 direct + 19 selected 检查通过、0 failure/warning/manual hold;diff/compile/maintainability 与公开路径边界扫描通过。独立文件 probe 的正常分支通过,非法旧字段的语义断言结果是 FAIL / PR regression,并非“测试命令退出 0 所以功能安全”。初次错误测试路径和不存在的 premerge 参数是评审命令准备错误,改正后已完成上述检查,未归因给 PR。没有查询或等待 CI。

语义与 CI 对齐

现行约束是 compact public-safe/content-free receipt 和 owner-gated rollback。触发点是新增 previous_record 的未校验复制,不是状态名字或文案问题;上述实文件链路证明了违反。修复后需重跑旧字段负例、有效恢复和完整材料测试,以及标准 premerge。默认关闭路径通过 unchanged intake/source 与实文件对照确认,import 无 effect、新字段不强加给旧调用方;但关闭默认只限制影响范围,不能替代显式启用后的公开数据校验。

我的整体评价

这是一个有明确调用结果的 justified_increment,设计和范围整体 proportionate。沿用已有 source apply 所有者,在 provider IO 与 SDK 验证之间加入针对单条记录的替换和保全证明,边界合理;当前缺口可以复用旧记录字段验证修复,不需要第二套权限或排名所有者。当前 PR 保留可选 SDK 的单条候选记录修订/回滚边界;在发布旧记录快照前补齐验证,真实产品适配与接入继续单独验收。 bounded future-facing pass 的具体方向就是复用旧记录 sanitizer,当前缺陷无需新 framework 或全量语言迁移。

long_horizon=regression:保留了无法用于恢复的旧 snapshot,破坏可逆演进;user_experience=regression:成功且 public-safe 的回执给调用方错误保证。新增 valid-record 能力有价值,仍须修复 P1 后按新的完整 head 再评。实际 Core/Bot grant、项目队列持久化/发布、packaged frontend 和其他平台均未测,不采纳作者对这些环境的声明为独立证据。既有 gate、CAS、候选状态和机器强制义务用精确比较/共享 typed owner,没有新增 substring 状态猜测、领域外措辞或 silent default change。

本评审针对完整 head 4fcbea4b33e94509b275d627ed470f60c3a31fae / base 89505091fe52d318112aaaefb85f97e61cf11b33;author-owned GitHub 限制使发布记录为 COMMENTED,此处的 REQUEST_CHANGES 是明确的工程结论。没有 APPROVE、CI 认证或 merge 权限声明。

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

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=xhigh

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

English verdict: APPROVE — exact head 3110eee08df2d3b3b9b4a57ff708212defe77221 fixes the retained-snapshot P1 before staging and passes independent real-file privacy/rollback checks. This COMMENTED review records the self-review conclusion; merge authority remains separate. No CI was queried or awaited.

动机

管理已激活材料库、先短预览后全文读取的 source SDK 调用方需要修订同一候选材料。旧 append-only intake 会拒绝同一身份下变更内容,材料停留在短预览;新的显式修订入口保留身份和排名,并可在当前 authority 未继续变化时恢复旧版本。实文件验证确认正常修订、保全和恢复;非法旧快照现在在任何 staging 前拒绝,不再进入 public-safe 回执。本 PR 不改变 intake 的 append-only 行为、不决定排名、不新增授权来源,也不代表完整 Bot 或 frontend 旅程已经上线。通用 frontend、真实 Core 授权和项目适配后的持久回执/队列读回仍需各自 owner 验收;本次未执行真实 Bot 或账户操作。

改动思路

沿用已有 material source SDK 的验证、当前授权和 provider IO 边界;用共享 candidate validator 对旧快照做对称校验,避免复制一套公共引用/内容规则。本 PR 交付可选 SDK 的单条候选材料修订与回滚;项目适配器的持久回执、queue readback、真实 Core/Bot 和通用 frontend 接入保持原有后续边界。 放松 intake 会静默改变旧调用方;为这个修订加入第二套权限/排名 owner 没有必要。现有不可变 staging、完整保全证明和 CAS 可以支撑可逆 SDK 操作。本次伴随收敛已应用:旧记录与替换记录共用 _validate_candidate,把验证放在 effect/public receipt 之前。

具体改动

完整 89505091fe52d318112aaaefb85f97e61cf11b33 → 3110eee08df2d3b3b9b4a57ff708212defe77221 为4文件、+1009/-0:513行 SDK、454行测试、18行导出、24行 README。与已审旧 head 4fcbea4b3 的完整差异仅是 retained snapshot 在 staging 前共享校验、回执复用已验证 snapshot,以及11个反例;README/导出及原 SDK 其他路径均未变。重新核验原全边界、当前 source provenance 和这些差异,没有继承旧批准。

规范依据:docs/reference/protocols/material-lifecycle-architecture-v0.md,固定到接受的 base 89505091fe52d318112aaaefb85f97e61cf11b33,先于实现读取。Position 的可选既有 scope owner、Owner-Gated Apply and Rollback 的当前授权/保全/CAS/恢复、Stage-0 Contracts 的 compact 公共回执均 implemented;Stage Boundary 为 deferred,真实产品适配/queue/frontend 的 gap 如上,不将 source SDK 认证成整个 S6 完成。

关键代码讲解

  • build_material_candidate_revision_proposal(revision.py:96)复用 intake 作者输入校验,绑定 source authority、expected/new record 和全文 digest/size;构造 proposal 不激活能力或授予权限。
  • apply_material_candidate_revision(:297)在 :337–357 从当前旧 readback 构造 previous_record,先用共享 _validate_candidate 校验,再 staging。替换 readback、完整 membership/peer/rank/old backing 保全、当前 grant 重验和 CAS switch 仍在原 owner;回执 :419 使用已经校验的旧 snapshot。
  • rollback_material_candidate_revision(:439)检查回执身份、当前 grant、after-revision CAS、旧 snapshot 和保全后恢复;后续写入使旧回执失效,不能跨写覆盖。

旧 P1 的准确 head 验收

新 head 的实文件 SDK 修订只更新目标候选材料,保全 peer、排名和旧 backing;rollback 恢复原 catalog。四种非法旧引用均在 staging 前 ValueError,stages=0、switches=0、authority=revision:old,所有文件字节不变。166 项 Material/Decision Context 测试通过;旧 head 同一11反例10失败/1通过,新 head全部通过。 原有 intake 在同一实文件 harness 的 base/head 两次运行中都拒绝变更同一 material 身份,错误文本一致、switches=0、原 catalog/backing 字节不变,intake 模块 hash 相同。新 SDK 在 base 不存在;没有伪造一个不存在的 base SDK 调用。回归敏感性使用已审旧 head 4fcbea4b3:同一11case 10失败/1通过,新 head全部通过。

对主干的风险

标准 premerge 5 direct +19 selected/executed 全通过,0失败/警告/advisory/manual hold;166项相关测试通过。实文件 probe使用真实不可变目录/内容和导出 SDK,只有 Core grant verifier 是合成的。撤销 grant、after-stage race、corrupted peer、archive 和 later-write rollback 路径也在材料套件内验证。未执行新 head live Bot、实际 Core 账户、通用 packaged frontend 或外部 provider 原子 IO;作者的早期 live 证据不替换这些未测项。

语义与CI对齐

三项新 schema 扩展既有 material vocabulary;Python 沿用稳定 source apply/provider IO 边界,不再创建通用控制面决策 owner。默认没有 revision effect,旧 intake 保持 append-only,排名仍是独立 Decision Context 操作;引用、导入和安装不构成激活/授权。新增严格 old-snapshot 拒绝来自已接受的 public-safe/reversible 契约,不是靠修订预算或删断言获得通过。

我的整体评价

当前有界 source SDK 可批准;旧 P1 已按实际 effect 前置条件解决。未来改动的收敛已落实为共享 validator,不需要再加验证框架。沿用已有 material source SDK 的验证、当前授权和 provider IO 边界;用共享 candidate validator 对旧快照做对称校验,避免复制一套公共引用/内容规则。本 PR 交付可选 SDK 的单条候选材料修订与回滚;项目适配器的持久回执、queue readback、真实 Core/Bot 和通用 frontend 接入保持原有后续边界。 这是当前 head 的完整 COMMENTED 自审结论;runtime PR 按项目当前规则由维护者合并,源 SDK 批准不结算父 Goal 的产品验收。

@loopx-agent
loopx-agent merged commit 5cb9e4b into main Oct 8, 2026
22 of 28 checks passed
@loopx-agent
loopx-agent deleted the codex/material-source-revision-20261008 branch October 8, 2026 05:42
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.

1 participant