R4 P0: C2S 门禁设计收口与吸收清单验真 - #1892
Conversation
📝 WalkthroughSummary by CodeRabbit
Walkthrough新增 C2S 门禁重构计划,冻结 104 个 ChangesC2S 门禁计划与契约
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Central reviewDecision: Validated findings[major] Resolve and wire coffin ownership before declaring P0 closed
P0 is marked complete as a design closeout, but matrix row 27 still specifies Root cause: the plan declares design closure and full absorption before resolving the coffin-break ownership policy and before specifying the domain state that produces authoritative coffin ownership, leaving a required production gate disconnected from its source of truth. [major] Bound gate-denial alerts and logging per client
The new P0 contract requires P1 to emit an Root cause: the frozen gate contract treats every rejected c2s message as an independently logged and acknowledged event but omits resource bounds at the untrusted request boundary. p1 needs an explicit per-client budget/backpressure policy, with denial alerts and logs rate-limited or coalesced, plus a flood/burst acceptance test that proves bounded work and output. [major] Frozen Euclidean reach contract breaks existing Workbench boundary behavior
The new frozen contract requires every player-to-world-target reach check to use 3D Euclidean squared distance and assigns Workbench a 3.0 radius. The current production helper Root cause: the plan treats preserving a numeric radius as preserving reach behavior, but freezes a global euclidean metric without preserving domain-specific existing metrics. for workbench, replacing the established chebyshev predicate with euclidean distance shrinks the accepted interaction volume and contradicts the plan's behavior-preservation requirement. [major] Update the master and R6 contracts to the 104-variant baseline
The promoted plan states that the authoritative enum now has 104 variants and that the old 113 count "cannot continue". However, the parent plan still defines completion as "113 C2S variants" in Root cause: the pr corrected a duplicated canonical variant count only in the promoted r4 plan, leaving the parent and cross-track acceptance contracts stale. this creates an already-observable inconsistency in duplicated sources of truth and makes plan completion evidence ambiguous. [major] P1 cannot wire the exhaustive gate before P3 declares the remaining variants
The plan freezes an exhaustive Root cause: the staged delivery splits installation of an enum-exhaustive production dispatcher from declaration of most of the enum's required routing metadata, even though those two pieces must be introduced atomically for the production gate to be both compilable and fail-closed. [major] Target-first rejection ordering exposes an entity existence and location oracle
The frozen evaluation order resolves the attacker-supplied target before checking dimension and distance ( Root cause: the gate design treats global target existence, dimension, and distance failures as requester-visible diagnostics before establishing a visibility/capability boundary for the target. distinct early failures turn authoritative target resolution into an entity-existence and location oracle. the contract should collapse all pre-authorization target failures to one indistinguishable external response (while retaining internal diagnostics), or establish requester visibility/authority before emitting differentiated reasons. [major] Completed P0 claims an enum-matrix script check that is not present
The new plan marks P0 complete at line 282 and then states at line 284 that a script compared all 104 matrix rows with all 104 Root cause: p0 is declared complete based on an asserted enum-to-matrix script check, but the change does not provide the claimed check or any durable result. the plan and rust enum remain independent sources, so the stated no-gap/no-duplicate acceptance evidence is not reproducible or regression-protected. |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/plan-refactor-c2s-gate-v1.md`:
- Around line 328-330: 在 active plan
中补充“开放问题”章节,列出所有未决项;若无未决项,明确写出“无开放问题”及验证依据。针对每项开放问题,在实施前新增对应的“§N.1
决议”,记录结论、实施方案、边界条件,并同时标注文件:行号与 plan 章节双锚点。
- Around line 352-354: 补充 §10 末尾“单次 consume-plan 全自动到 merge”章节,明确一次提交
`/consume-plan` 后系统按 PR-2 至 PR-5 串行执行、等待每阶段门禁、完成 merge,并最终迁移至
`docs/finished_plans/`;同时定义任一阶段失败、门禁未通过或进入暂停状态时立即停止且不得归档,保留 §10.4 现有终态条件。
In `@docs/plans-skeleton/plan-refactor-wire-s2c-v1.md`:
- Line 25: 修正 P4 计划中 ServerDataType 基线的来源或数值:核对 agent schema 的 ServerDataType
union 计数;若 144 包含旁路 channel 或其他服务端 Rust 变体,明确标注其来源和范围,否则将基线改为当前 agent union
的实际数量,避免按错误总量规划验证。
In `@scripts/check_c2s_gate_matrix.py`:
- Around line 12-29: Update enum_variants() and VARIANT_RE to recognize struct,
unit, and tuple ClientRequestV1 variants, while tracking whether the enum’s
closing brace was found. Reject unrecognized top-level variants and raise an
error for truncated or otherwise unclosed enums, even when some variants were
parsed. Add fixture tests covering all three variant forms and malformed or
truncated enum definitions.
- Around line 9-11: 补齐 scripts/check_c2s_gate_matrix.py(9-11 行)的跨仓 parity
gate:增加 agent 的 ClientRequestV1 TypeBox schema 输入,规范化并对比 Rust enum、matrix 与
agent schema 的变体集合,同时统一声明 authority、projection 边界及差异 allowlist。更新
docs/plan-refactor-c2s-gate-v1.md(243 行),将 104/104 证据扩展为 Rust、matrix、agent
schema、gate registry 的完整契约校验,或明确标注 server-only 变体。更新
docs/plans-skeleton/plan-refactor-master-v1.md(101 行),不要将 Rust 数量表述为全部跨仓
ClientRequestV1 变体。
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: f410b153-9386-4149-b095-bd580c4f81cf
📒 Files selected for processing (5)
docs/plan-refactor-c2s-gate-v1.mddocs/plans-skeleton/plan-refactor-c2s-gate-v1.mddocs/plans-skeleton/plan-refactor-master-v1.mddocs/plans-skeleton/plan-refactor-wire-s2c-v1.mdscripts/check_c2s_gate_matrix.py
💤 Files with no reviewable changes (1)
- docs/plans-skeleton/plan-refactor-c2s-gate-v1.md
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
- GitHub Check: e2e
🧰 Additional context used
📓 Path-based instructions (7)
docs/**/*.md
📄 CodeRabbit inference engine (docs/CLAUDE.md)
docs/**/*.md: 新 plan 头部必须写明接入面:进料、出料、复用的共享类型/event/schema、server/agent/client 跨仓库契约,以及对应的worldview.md锚点。
涉及真元、灵气、衰减、逸散、半衰、距离损耗、排斥或吸力的 plan,必须调用qi_physics;新物理常数和公式必须先扩展qi_physics,不得在功能 plan 中重复实现。
所有真元/灵气流动必须遵守守恒律并通过qi_physics::ledger::QiTransfer;释放使用qi_release_to_zone,吸收使用qi_excretion,不得凭空生成或销毁真元。
涉及玩家可感知行为的 plan,必须在对应机制阶段中内联可直接实现的粒子、音效、HUD、环境、动画和 narration 规格;不得将视听内容笼统推迟到独立阶段。纯 server 逻辑 plan 例外。
每份 plan 必须列出开放问题;实施前必须追加§N.1 决议,逐项给出结论、实施方案、边界条件,并以文件:行号和 plan 章节双锚点落地。
scope 大于或等于 4 个 PR 的 plan,必须在末尾包含§10 实施工作流,并按依赖顺序在一个 plan 内序列化多个 PR,不得拆成多个 plan。
涉及 NBT 建筑、worldgen layout 或复杂视觉资产的 TODO,必须完成三轮提交:(round 1/3)、(round 2/3)、(round 3/3);终轮提交必须包含拼写准确的<PROMISE>担保块。
§10 最末必须包含“单次 consume-plan 全自动到 merge”章节,明确用户提交/consume-plan后即可等待最终归档至docs/finished_plans/。一个 PR 只允许修改一个 plan;
/consume-plan只能追加 Finish Evidence 或执行允许的 plan 归档移动,不得自动修改其他 docs 文件、CLAUDE.md或 worldview 文档。
Files:
docs/plans-skeleton/plan-refactor-wire-s2c-v1.mddocs/plans-skeleton/plan-refactor-master-v1.mddocs/plan-refactor-c2s-gate-v1.md
docs/plans-skeleton/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
新建 plan 前必须先阅读
docs/CLAUDE.md;骨架 plan 必须包含主题和 P0/P1 等阶段总览。
Files:
docs/plans-skeleton/plan-refactor-wire-s2c-v1.mddocs/plans-skeleton/plan-refactor-master-v1.md
**/*.{rs,ts,tsx,java,json,md}
📄 CodeRabbit inference engine (CLAUDE.md)
唯一真货币是骨币;矿物是交易筹码,灵石是燃料/衰变物,金银不是货币。
Files:
docs/plans-skeleton/plan-refactor-wire-s2c-v1.mddocs/plans-skeleton/plan-refactor-master-v1.mddocs/plan-refactor-c2s-gate-v1.md
**/*
📄 CodeRabbit inference engine (CLAUDE.md)
**/*: 禁止git stash push后不执行对应git stash pop;不得留下孤儿 WIP stash。
每个逻辑单元使用中文 atomic commit;agent 产生的每个 commit 必须包含真实模型 ID 的Model:trailer。
未经明确确认不得执行 force push、hard reset、amend、交互式 rebase、批量删除/移动文件或依赖版本/生产配置修改;严禁--no-verify、--no-gpg-sign及关闭签名。
PR review 只能通过独立评论/review触发;不得等待 Codex,review 修改后必须重新等待 re-review。
Files:
docs/plans-skeleton/plan-refactor-wire-s2c-v1.mddocs/plans-skeleton/plan-refactor-master-v1.mddocs/plan-refactor-c2s-gate-v1.mdscripts/check_c2s_gate_matrix.py
docs/plan-*.md
📄 CodeRabbit inference engine (CLAUDE.md)
docs/plan-*.md: Active plan 每个阶段必须写出可核验的模块路径、类型/函数、测试、schema、Redis key 或跨仓库契约 symbol。
plan 归档前必须所有阶段标记为✅ YYYY-MM-DD并补充严格标题为## Finish Evidence的证据章节。
Files:
docs/plan-refactor-c2s-gate-v1.md
**/*.{rs,ts,tsx,java,py}
📄 CodeRabbit inference engine (CLAUDE.md)
新增 skill/cast/主动能力必须同时提供独立 animation、particle/VFX、SFX、HUD 反馈和 hotbar/SkillBar PNG icon;仅实现 server 或 schema 不算完成。
Files:
scripts/check_c2s_gate_matrix.py
**/*.{nbt,bbmodel,json,py}
📄 CodeRabbit inference engine (CLAUDE.md)
NBT 建筑、worldgen layout、复杂模型和视觉资产必须经过三轮打磨;提交信息标注
(round N/3),终轮包含<PROMISE>...已 3 轮打磨...</PROMISE>。
Files:
scripts/check_c2s_gate_matrix.py
🧠 Learnings (3)
📚 Learning: 2026-07-17T00:31:10.779Z
Learnt from: Kizunad
Repo: Kizunad/Bong PR: 1218
File: docs/plans-skeleton/plan-skill-av-relink-v1.md:1-1
Timestamp: 2026-07-17T00:31:10.779Z
Learning: 在审查该仓库 `docs/plans-skeleton/` 下的“docs-only skeleton plan”创建类 PR 时:先核对 `docs/CLAUDE.md` 中“Plan 消费规范”,并逐份查看本计划文档里的“§10 实施工作流”,确认后续实施阶段是否会遵循“每个 PR 只修改一个 plan”,且实施/归档时不会出现跨 plan 的修改。该规则不适用于用户显式指定、共享调研基线且计划之间存在互相交叉引用的 skeleton plan 同批创建 PR;对这类情况应按实际交叉引用关系放宽,确保仍能按独立或约定的序列化方式推进。
Applied to files:
docs/plans-skeleton/plan-refactor-wire-s2c-v1.mddocs/plans-skeleton/plan-refactor-master-v1.md
📚 Learning: 2026-07-17T00:31:13.643Z
Learnt from: Kizunad
Repo: Kizunad/Bong PR: 1218
File: docs/plans-skeleton/plan-skill-av-relink-v1.md:81-85
Timestamp: 2026-07-17T00:31:13.643Z
Learning: 审核 docs/plans-skeleton/*.md 下的 skeleton 草案 PR 时:不得要求作者在“§N 开放问题(P0 决策门前需收口)”核查完成之前提前填写对应的“§N.1 决议”。仅当计划进入 active 且 P0 实施前,已由 Explore agent 并行核查代码现状后,才允许追加“§N.1 决议”,且该决议需包含结论、实施方案、边界条件,并使用“文件:行号 + plan 章节”的双锚点格式。
Applied to files:
docs/plans-skeleton/plan-refactor-wire-s2c-v1.mddocs/plans-skeleton/plan-refactor-master-v1.md
📚 Learning: 2026-07-22T02:11:59.191Z
Learnt from: Kizunad
Repo: Kizunad/Bong PR: 1247
File: docs/plans-skeleton/plan-bughunt-animal-air-spawn-gravity-v1.md:0-0
Timestamp: 2026-07-22T02:11:59.191Z
Learning: 在 `docs/plans-skeleton/` 目录下的计划状态行中,若起草日期同时涉及 UTC 与本地日期(例如时区换算后可能跨到不同日期),请在该行中同时标注 UTC 起草日与本地起草日。这样可以避免基于 UTC 的时间基准在 GitHub/CodeRabbit 审查时将本地日期误判为“未来日期”。
Applied to files:
docs/plans-skeleton/plan-refactor-wire-s2c-v1.mddocs/plans-skeleton/plan-refactor-master-v1.md
🪛 LanguageTool
docs/plan-refactor-c2s-gate-v1.md
[uncategorized] ~301-~301: 您的意思是“"不"齐”?
Context: ...questV1变体穷尽声明Spec/NoGate(reason)`、补齐声明所需 authority/state adapter,并把 product...
(BU)
[uncategorized] ~306-~306: 您的意思是“"不"洞”?
Context: ...StateGateId adapter 保留单一事实源,不再承担任何枚举声明补洞。 - 测试抓手:enum↔registry 穷尽编译门继续常绿;...
(BU)
[uncategorized] ~332-~332: 您不可用“是”来表达个形容词。大部分人都平常用“很”来代替“是”。您是不是想表达"很纯"?
Context: ...。 ## §10 实施工作流 ### §10.1 适用边界 本 plan 是纯 server/network 逻辑重构,不产出 NBT、worldgen la...
(SHI_ADHECTIVE_ERROR)
[uncategorized] ~339-~339: 您的意思是“"不"枚”?
Context: ...变。 4. PR-4 / P3:删重复门禁并收敛领域 adapter,不补枚举声明欠账。 5. PR-5 / P4:bot/e2e 与符合条件的吸...
(BU)
🪛 Ruff (0.16.0)
scripts/check_c2s_gate_matrix.py
[warning] 28-28: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 36-36: Use a list comprehension to create a transformed list
(PERF401)
[warning] 38-38: Avoid specifying long messages outside the exception class
(TRY003)
🔇 Additional comments (2)
docs/plan-refactor-c2s-gate-v1.md (1)
1-242: LGTM!Also applies to: 244-327, 331-351
scripts/check_c2s_gate_matrix.py (1)
1-8: LGTM!Also applies to: 30-45, 46-95
| - ⬜ P2 client 桥接层收敛:枚举前缀剥离收敛到单点(含 forge-session 修复);`ServerDataRouter` 注册表整备(分域注册文件,不再单个 1547 行 switch 追加)。 | ||
| - ⬜ P3 旁路归一批次:28 channel 逐批收编入 server_data envelope 或登记豁免(资源包/握手类可豁免);删除散装 receiver。 | ||
| - ⬜ P4 契约 pin 全量化:双向 sample 对拍测试补齐(113 C2S + 144 S2C 每变体至少一条正反 sample,schema 改动连 sample 一起改);emit 迁移到 builder 的长尾批次。 | ||
| - ⬜ P4 契约 pin 全量化:双向 sample 对拍测试补齐(届时现行 `ClientRequestV1` 全部变体,2026-08-03 基线 104;以及届时现行 `ServerDataType` 全部变体,2026-07-27 侦察基线 144;每变体至少一条正反 sample,schema 改动连 sample 一起改);emit 迁移到 builder 的长尾批次。 |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/sh
set -eu
python3 - <<'PY'
from pathlib import Path
import re
text = Path("agent/packages/schema/src/server-data.ts").read_text(encoding="utf-8")
block = text.split("export const ServerDataType = Type.Union([", 1)[1]
block = block.split("]);", 1)[0]
tags = re.findall(r'Type\.Literal\("([^"]+)"\)', block)
print(f"ServerDataType literal count: {len(tags)}")
if len(tags) != 144:
raise SystemExit("ServerDataType count does not match the documented 144 baseline")
PYRepository: Kizunad/Bong
Length of output: 248
🏁 Script executed:
#!/bin/sh
set -eu
echo "== plan =="
sed -n '1,80p' docs/plans-skeleton/plan-refacor-wire-s2c-v1.md 2>/dev/null || true
echo "== file match =="
fd -a 'plan-refactor-wire-s2c-v1\.md|server-data\.ts' . | sed 's#^\./##'
echo "== schema outline/search =="
wc -l agent/packages/schema/src/server-data.ts
python3 - <<'PY'
from pathlib import Path
text = Path("agent/packages/schema/src/server-data.ts").read_text(encoding="utf-8")
print("contains ServerDataType:", "export const ServerDataType = Type.Union([" in text)
print("line 190-305:")
for i,line in enumerate(text.splitlines(), 1):
if 190 <= i <= 305:
print(f"{i}: {line}")
PY
echo "== enumerate all Type.Literal values in server-data.ts =="
python3 - <<'PY'
import re
from pathlib import Path
text = Path("agent/packages/schema/src/server-data.ts").read_text(encoding="utf-8")
print("all exported/labeled datatypes:")
for i,line in enumerate(text.splitlines(), 1):
if "export const " in line or "Type.Union" in line:
print(f"{i}: {line}")
print("ServerDataType total literals:", len(re.findall(r'Type\.Literal\("([^"]+)"\)', text)))
PY
echo "== search for 144 and ServerDataType =="
rg -n "144|ServerDataType|ClientRequestV1|Client.*base|基线" docs/plans-skeleton docs agent packages 2>/dev/null | head -n 200Repository: Kizunad/Bong
Length of output: 50368
🏁 Script executed:
#!/bin/sh
set -eu
echo "== plan exact =="
sed -n '1,70p' docs/plans-skeleton/plan-refactor-wire-s2c-v1.md
echo "== schema TypeScript exports from server-data.ts =="
python3 - <<'PY'
import re
from pathlib import Path
text = Path("agent/packages/schema/src/server-data.ts").read_text()
lines = text.splitlines()
for i,line in enumerate(lines, 1):
if i < 20 or line.startswith(("export const ", "export type ") or "Type.Union" in line):
if i <= 400:
print(f"{i}: {line}")
PY
echo "== Rust ServerData enum search =="
fd -a 'server_data\.(rs|rs)$$' . | sed 's#^\./##'
rg -n "enum ServerData|ServerData(v1)?|ServerDataType|Type::" server agent 2>/dev/null | sed -n '1,240p'
echo "== agent package source files near ServerDataV1 =="
rg -n "ServerDataV1|ServerDataType" docs/plans-skeleton/plan-refactor-wire-s2c-v1.md agent/packages/schema src 2>/dev/null | sed -n '1,200p'
echo "== precise literal count in ServerDataType union block =="
python3 - <<'PY'
import re
from pathlib import Path
text = Path("agent/packages/schema/src/server-data.ts").read_text()
block = text.split("export const ServerDataType = Type.Union([",1)[1]
block = block.split("]);",1)[0]
vals = re.findall(r'Type\.Literal\("([^"]+)"\)', block)
print("count", len(vals))
PYRepository: Kizunad/Bong
Length of output: 44261
修正 ServerDataType 基线或补全说明。
P4 的 ServerDataType 侦察基线写为 144,但 agent schema 的 ServerDataType literal 计数为 100。若这 144 包含旁路 channel 或其他服务端 Rust 变体,请标注来源;否则将基线改为当前 agent union 数量,避免 P4 按错误总量留空验证。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/plans-skeleton/plan-refactor-wire-s2c-v1.md` at line 25, 修正 P4 计划中
ServerDataType 基线的来源或数值:核对 agent schema 的 ServerDataType union 计数;若 144 包含旁路
channel 或其他服务端 Rust 变体,明确标注其来源和范围,否则将基线改为当前 agent union 的实际数量,避免按错误总量规划验证。
Central reviewDecision: Validated findings[major] Wire the enum-to-matrix contract check into automated tests
The PR defines the changed P0 contract as Root cause: the new consistency assertion was implemented only as an opt-in standalone script and was not registered in ci or an automated test target, so the observable enum-to-matrix contract has no enforced regression protection. [major] Unit or tuple request variants silently bypass the matrix check
Root cause: the enum parser treats only struct-style rust variants as variants instead of parsing every top-level [major] 104-variant baseline ignores the TypeBox source of truth
The new plan declares Root cause: the plan reverses the repository's schema authority by treating the rust serde enum as canonical, and the new validation checks only that mirror against documentation instead of validating typebox, generated json schema, rust, and consumers together. |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@agent/packages/schema/src/client-request.ts`:
- Around line 1184-1212: Update the entity ID fields in
SupplyCoffinOpenRequestV1, ContainerOpenRequestV1, WorkbenchOpenRequestV1, and
GiveDanToElderRequestV1 to use Type.Integer({ minimum: 0 }) instead of bare
Type.Integer(), matching the existing non-negative entity ID schema convention.
- Around line 1382-1430: 在 client-request.ts 的 ClientRequestV1 samples
定义中,为新增的各个 variant(包括 qi_scatter_bead_use、装备/背包/战斗、搜索、容器及 lingtian_start_*
等)逐一补充符合当前 schema 的正向和反向 sample;同时完善 inventory_move_intent 与 cancel_search
的完整正反对拍,并确保 samples 与最新 schema 变更保持一致。
- Around line 1237-1300: 将 LingtianStartTillRequestV1 和
LingtianStartHarvestRequestV1 中的 mode 从 Type.String() 改为覆盖实际协议允许值的
Type.Union([Type.Literal(...),
...]),分别使用各自对应的有限取值集合;同步确保生成的静态类型反映这些字面量约束,不要引入未定义的模式值。
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 9a714cd4-6739-41fd-bf70-019ef1f4f43c
⛔ Files ignored due to path filters (1)
agent/packages/schema/generated/client-request-v1.jsonis excluded by!**/generated/**
📒 Files selected for processing (5)
.github/workflows/e2e.ymlagent/packages/schema/src/client-request.tsdocs/plan-refactor-c2s-gate-v1.mdscripts/check_c2s_gate_matrix.pyscripts/tests/check_c2s_gate_matrix_test.py
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
- GitHub Check: e2e
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{rs,ts,tsx,java,py}
📄 CodeRabbit inference engine (CLAUDE.md)
新增 skill/cast/主动能力必须同时提供独立 animation、particle/VFX、SFX、HUD 反馈和 hotbar/SkillBar PNG icon;仅实现 server 或 schema 不算完成。
Files:
scripts/tests/check_c2s_gate_matrix_test.pyagent/packages/schema/src/client-request.tsscripts/check_c2s_gate_matrix.py
**/*.{nbt,bbmodel,json,py}
📄 CodeRabbit inference engine (CLAUDE.md)
NBT 建筑、worldgen layout、复杂模型和视觉资产必须经过三轮打磨;提交信息标注
(round N/3),终轮包含<PROMISE>...已 3 轮打磨...</PROMISE>。
Files:
scripts/tests/check_c2s_gate_matrix_test.pyscripts/check_c2s_gate_matrix.py
**/*
📄 CodeRabbit inference engine (CLAUDE.md)
**/*: 禁止git stash push后不执行对应git stash pop;不得留下孤儿 WIP stash。
每个逻辑单元使用中文 atomic commit;agent 产生的每个 commit 必须包含真实模型 ID 的Model:trailer。
未经明确确认不得执行 force push、hard reset、amend、交互式 rebase、批量删除/移动文件或依赖版本/生产配置修改;严禁--no-verify、--no-gpg-sign及关闭签名。
PR review 只能通过独立评论/review触发;不得等待 Codex,review 修改后必须重新等待 re-review。
Files:
scripts/tests/check_c2s_gate_matrix_test.pydocs/plan-refactor-c2s-gate-v1.mdagent/packages/schema/src/client-request.tsscripts/check_c2s_gate_matrix.py
docs/**/*.md
📄 CodeRabbit inference engine (docs/CLAUDE.md)
docs/**/*.md: 新 plan 头部必须写明接入面:进料、出料、复用的共享类型/event/schema、server/agent/client 跨仓库契约,以及对应的worldview.md锚点。
涉及真元、灵气、衰减、逸散、半衰、距离损耗、排斥或吸力的 plan,必须调用qi_physics;新物理常数和公式必须先扩展qi_physics,不得在功能 plan 中重复实现。
所有真元/灵气流动必须遵守守恒律并通过qi_physics::ledger::QiTransfer;释放使用qi_release_to_zone,吸收使用qi_excretion,不得凭空生成或销毁真元。
涉及玩家可感知行为的 plan,必须在对应机制阶段中内联可直接实现的粒子、音效、HUD、环境、动画和 narration 规格;不得将视听内容笼统推迟到独立阶段。纯 server 逻辑 plan 例外。
每份 plan 必须列出开放问题;实施前必须追加§N.1 决议,逐项给出结论、实施方案、边界条件,并以文件:行号和 plan 章节双锚点落地。
scope 大于或等于 4 个 PR 的 plan,必须在末尾包含§10 实施工作流,并按依赖顺序在一个 plan 内序列化多个 PR,不得拆成多个 plan。
涉及 NBT 建筑、worldgen layout 或复杂视觉资产的 TODO,必须完成三轮提交:(round 1/3)、(round 2/3)、(round 3/3);终轮提交必须包含拼写准确的<PROMISE>担保块。
§10 最末必须包含“单次 consume-plan 全自动到 merge”章节,明确用户提交/consume-plan后即可等待最终归档至docs/finished_plans/。一个 PR 只允许修改一个 plan;
/consume-plan只能追加 Finish Evidence 或执行允许的 plan 归档移动,不得自动修改其他 docs 文件、CLAUDE.md或 worldview 文档。
Files:
docs/plan-refactor-c2s-gate-v1.md
docs/plan-*.md
📄 CodeRabbit inference engine (CLAUDE.md)
docs/plan-*.md: Active plan 每个阶段必须写出可核验的模块路径、类型/函数、测试、schema、Redis key 或跨仓库契约 symbol。
plan 归档前必须所有阶段标记为✅ YYYY-MM-DD并补充严格标题为## Finish Evidence的证据章节。
Files:
docs/plan-refactor-c2s-gate-v1.md
**/*.{rs,ts,tsx,java,json,md}
📄 CodeRabbit inference engine (CLAUDE.md)
唯一真货币是骨币;矿物是交易筹码,灵石是燃料/衰变物,金银不是货币。
Files:
docs/plan-refactor-c2s-gate-v1.mdagent/packages/schema/src/client-request.ts
agent/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Agent TypeScript 改动应运行对应包的
npm test;schema 源码改动后必须先构建@bong/schema的 dist。
Files:
agent/packages/schema/src/client-request.ts
agent/packages/schema/src/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
修改 schema 源码后必须执行
cd agent && npm run build -w@bong/schema``,因为 agent 使用构建产物dist/。
Files:
agent/packages/schema/src/client-request.ts
agent/packages/schema/**/*.{ts,json}
📄 CodeRabbit inference engine (CLAUDE.md)
每个 TypeBox/serde schema variant 都必须有正反 sample 对拍;schema 变更必须同步修改 samples。
Files:
agent/packages/schema/src/client-request.ts
**/*.{rs,ts,tsx,java}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{rs,ts,tsx,java}: 六境界必须使用“醒灵→引气→凝脉→固元→通灵→化虚”,不得使用练气、筑基、金丹、元婴等旧称。
命名不得使用末法禁词玄、陨、星、仙、太、古,除明确允许的俗世矿名例外。
Files:
agent/packages/schema/src/client-request.ts
🪛 Ruff (0.16.0)
scripts/tests/check_c2s_gate_matrix_test.py
[warning] 10-10: Assertion should be broken down into multiple parts
Break down assertion into multiple parts
(PT018)
[warning] 46-46: Use pytest.raises instead of unittest-style assertRaisesRegex
Replace assertRaisesRegex with pytest.raises
(PT027)
scripts/check_c2s_gate_matrix.py
[warning] 27-27: Too many branches (13 > 12)
(PLR0912)
[warning] 45-45: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 53-53: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 56-56: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 61-61: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 68-68: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 90-90: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 94-94: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 117-117: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 137-137: Too many branches (17 > 12)
(PLR0912)
[warning] 159-159: zip() without an explicit strict= parameter
Add explicit value for parameter strict=
(B905)
🔇 Additional comments (19)
docs/plan-refactor-c2s-gate-v1.md (3)
132-243: LGTM!
295-310: LGTM!
132-136: 📐 Maintainability & Code Quality无需拆分此更改。
docs/plans-skeleton文件是骨架文档,不在/consume-plan归档消费路径内;按根CLAUDE.md定义,一 PR 一份 plan 约束的是 active plan 实施与/consume-plan归档行为,不禁止 docs-only 骨架基线更新与此 plan 的联动补充。> Likely an incorrect or invalid review comment.agent/packages/schema/src/client-request.ts (6)
545-556: LGTM!
652-675: LGTM!
937-949: LGTM!
1352-1370: LGTM!
1439-1445: LGTM!
1214-1225: 🗄️ Data Integrity & Integration无需为
ExternalContainerMoveRequestV1增加 revision 字段。该请求仅使用
session_id/instance_id/from/to,协议、Rust enum、TypeBox schema 及 proto 定义均不含独立 revision;校验与并发控制依赖资源锁和 server 重读,不在 schema 层面定义 revision 字段。> Likely an incorrect or invalid review comment.scripts/check_c2s_gate_matrix.py (8)
1-20: LGTM!
23-69: LGTM! 解析逻辑对 struct/unit/tuple/多行 tuple 及未知顶层语法(如显式 discriminant)均能正确处理并 fail closed,与配套测试用例的断言一致。
72-83: LGTM!
86-117: LGTM! 已补齐 TypeBox union 成员、wire literal 与生成 JSON Schema 的解析,覆盖此前缺失的跨仓校验输入。
120-134: LGTM!
137-181: LGTM!
182-195: LGTM!
197-204: LGTM!scripts/tests/check_c2s_gate_matrix_test.py (1)
1-52: LGTM! 三个用例覆盖 struct/unit/tuple 及未知顶层语法的 fail-closed 场景,与check_c2s_gate_matrix.py::parse_enum_variants的实际实现行为一致。.github/workflows/e2e.yml (1)
119-123: 🩺 Stability & Availability无需修改。
生成文件
agent/packages/schema/generated/client-request-v1.json已受 git 追踪且未被 gitignore 排除。
| export const SupplyCoffinOpenRequestV1 = Type.Object( | ||
| { | ||
| v: Type.Literal(1), | ||
| type: Type.Literal("supply_coffin_open"), | ||
| entity_id: Type.Integer(), | ||
| }, | ||
| { additionalProperties: false }, | ||
| ); | ||
| export type SupplyCoffinOpenRequestV1 = Static<typeof SupplyCoffinOpenRequestV1>; | ||
|
|
||
| export const ContainerOpenRequestV1 = Type.Object( | ||
| { | ||
| v: Type.Literal(1), | ||
| type: Type.Literal("container_open"), | ||
| entity_id: Type.Integer(), | ||
| }, | ||
| { additionalProperties: false }, | ||
| ); | ||
| export type ContainerOpenRequestV1 = Static<typeof ContainerOpenRequestV1>; | ||
|
|
||
| export const WorkbenchOpenRequestV1 = Type.Object( | ||
| { | ||
| v: Type.Literal(1), | ||
| type: Type.Literal("workbench_open"), | ||
| entity_id: Type.Integer(), | ||
| }, | ||
| { additionalProperties: false }, | ||
| ); | ||
| export type WorkbenchOpenRequestV1 = Static<typeof WorkbenchOpenRequestV1>; |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
为 entity_id 类字段补充非负约束。
SupplyCoffinOpenRequestV1.entity_id(Line 1188)、ContainerOpenRequestV1.entity_id(Line 1198)、WorkbenchOpenRequestV1.entity_id(Line 1208)、GiveDanToElderRequestV1.elder_entity_id(Line 1336)均使用裸 Type.Integer()。
上游参照片段 container-interaction.ts 中 StartSearchRequestV1.container_entity_id 使用 Type.Integer({ minimum: 0 })。这些新字段与既有 entity id 约定不一致,允许负数 ID 通过客户端 schema 校验。
请为这些字段补充 { minimum: 0 }。
🛡️ 建议修复
export const SupplyCoffinOpenRequestV1 = Type.Object(
{
v: Type.Literal(1),
type: Type.Literal("supply_coffin_open"),
- entity_id: Type.Integer(),
+ entity_id: Type.Integer({ minimum: 0 }),
},
{ additionalProperties: false },
);
export const ContainerOpenRequestV1 = Type.Object(
{
v: Type.Literal(1),
type: Type.Literal("container_open"),
- entity_id: Type.Integer(),
+ entity_id: Type.Integer({ minimum: 0 }),
},
{ additionalProperties: false },
);
export const WorkbenchOpenRequestV1 = Type.Object(
{
v: Type.Literal(1),
type: Type.Literal("workbench_open"),
- entity_id: Type.Integer(),
+ entity_id: Type.Integer({ minimum: 0 }),
},
{ additionalProperties: false },
); export const GiveDanToElderRequestV1 = Type.Object(
{
v: Type.Literal(1),
type: Type.Literal("give_dan_to_elder"),
pill_instance_id: Type.Integer({ minimum: 0, maximum: JS_SAFE_INTEGER_MAX }),
- elder_entity_id: Type.Integer(),
+ elder_entity_id: Type.Integer({ minimum: 0 }),
},
{ additionalProperties: false },
);Also applies to: 1331-1341
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@agent/packages/schema/src/client-request.ts` around lines 1184 - 1212, Update
the entity ID fields in SupplyCoffinOpenRequestV1, ContainerOpenRequestV1,
WorkbenchOpenRequestV1, and GiveDanToElderRequestV1 to use Type.Integer({
minimum: 0 }) instead of bare Type.Integer(), matching the existing non-negative
entity ID schema convention.
| ZhenfaPlaceRequestV1, | ||
| ZhenfaTriggerRequestV1, | ||
| ZhenfaDisarmRequestV1, | ||
| QiScatterBeadUseRequestV1, | ||
| LearnSkillScrollRequestV1, | ||
| TechniqueScrollUseRequestV1, | ||
| InventoryMoveIntentRequestV1, | ||
| EquipFalseSkinRequestV1, | ||
| ForgeFalseSkinRequestV1, | ||
| InventoryDiscardItemRequestV1, | ||
| TreasureActivateRequestV1, | ||
| DropWeaponIntentRequestV1, | ||
| RepairWeaponIntentRequestV1, | ||
| PickupDroppedItemRequestV1, | ||
| RemainsLootRequestV1, | ||
| MineralProbeRequestV1, | ||
| FreshnessProbeRequestV1, | ||
| ApplyPillRequestV1, | ||
| SelfAntidoteRequestV1, | ||
| DuoSheRequestV1, | ||
| QiColorInspectRequestV1, | ||
| UseLifeCoreRequestV1, | ||
| JiemaiRequestV1, | ||
| ChargeCarrierRequestV1, | ||
| ThrowCarrierRequestV1, | ||
| AnqiContainerSwitchRequestV1, | ||
| UseQuickSlotRequestV1, | ||
| QuickSlotBindRequestV1, | ||
| SkillBarCastRequestV1, | ||
| SkillBarBindRequestV1, | ||
| SkillConfigIntentRequestV1, | ||
| CombatReincarnateRequestV1, | ||
| CombatTerminateRequestV1, | ||
| CombatCreateNewCharacterRequestV1, | ||
| StartExtractRequestV1, | ||
| CancelExtractRequestV1, | ||
| StartSearchRequestV1, | ||
| CancelSearchRequestV1, | ||
| SupplyCoffinOpenRequestV1, | ||
| ContainerOpenRequestV1, | ||
| WorkbenchOpenRequestV1, | ||
| ExternalContainerMoveRequestV1, | ||
| ExternalContainerCloseRequestV1, | ||
| LingtianStartTillRequestV1, | ||
| LingtianStartRenewRequestV1, | ||
| LingtianStartPlantingRequestV1, | ||
| LingtianStartHarvestRequestV1, | ||
| LingtianStartReplenishRequestV1, | ||
| LingtianStartDrainQiRequestV1, |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# 定位 schema samples 目录及现有正反样例,核对是否覆盖新增 variant
fd -t d -i sample agent/packages/schema
rg -n "alchemy_learn_recipe_fragment|coffin_break|coffin_menu_reclaim|qi_scatter_bead_use|supply_coffin_open|container_open|workbench_open|external_container_move|external_container_close|lingtian_start|jiemai|craft_start|craft_cancel|give_dan_to_elder" agent/packages/schema -g '*sample*'Repository: Kizunad/Bong
Length of output: 181
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "## repo files under agent/packages/schema"
git ls-files agent/packages/schema | sed -n '1,160p'
echo
echo "## sample files"
git ls-files agent/packages/schema/samples | sed -n '1,240p'
echo
echo "## sample files mentioning new-ish terms"
rg -n "QiScatterBeadUseRequest|inventory_move|external_container_(move|close)|lingtian_start|JiemaiRequest|SupplyCoffinOpen|ContainerOpen|WorkbenchOpen|Equipment|UseQuickSlot|QuickSlotBind|SkillBar|CombatReincarnate|StartExtract|CancelExtract|StartSearch|CancelSearch" agent/packages/schema/samples || true
echo
echo "## schema relevant new variants and lines"
rg -n "QiScatterBeadUseRequest|InventoryMoveIntentRequest|EquipFalseSkinRequest|ForgeFalseSkinRequest|InventoryDiscardItemRequest|TreasureActivateRequest|DropWeaponIntentRequest|RepairWeaponIntentRequest|PickupDroppedItemRequest|RemainsLootRequest|MineralProbeRequest|FreshnessProbeRequest|ApplyPillRequest|SelfAntidoteRequest|DuoSheRequest|QiColorInspectRequest|UseLifeCoreRequest|JiemaiRequest|ChargeCarrierRequest|ThrowCarrierRequest|AnqiContainerSwitchRequest|UseQuickSlotRequest|QuickSlotBindRequest|SkillBarCastRequest|SkillBarBindRequest|SkillConfigIntentRequest|CombatReincarnateRequest|CombatTerminateRequest|CombatCreateNewCharacterRequest|StartExtractRequest|CancelExtractRequest|StartSearchRequest|CancelSearchRequest|SupplyCoffinOpenRequest|ContainerOpenRequest|WorkbenchOpenRequest|ExternalContainerMoveRequest|ExternalContainerCloseRequest|LingtianStart" agent/packages/schema/src/client-request.ts agent/packages/schema -g '*.ts' || trueRepository: Kizunad/Bong
Length of output: 50368
补齐新增 ClientRequestV1 变体的正反 sample
client-request.ts 中的新增 variant 需要逐个补充 sample,包括 qi_scatter_bead_use、equip_false_skin、forge_false_skin、inventory_discard_item、treasure_activate、drop_weapon_intent、repair_weapon_intent、use_quick_slot、quick_slot_bind、skill_bar_cast、skill_bar_bind、skill_config_intent、combat_reincarnate、combat_terminate、combat_create_new_character、start_extract、cancel_extract、supply_coffin_open、container_open、workbench_open、external_container_move、external_container_close、lingtian_start_*、jiemai、charge_carrier、throw_carrier、anqi_container_switch、start_search、cancel_search 等;已有部分 inventory_move_intent、cancel_search 样例仍需补齐完整正反对拍,并按 schema 变更要求同步到 samples。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@agent/packages/schema/src/client-request.ts` around lines 1382 - 1430, 在
client-request.ts 的 ClientRequestV1 samples 定义中,为新增的各个 variant(包括
qi_scatter_bead_use、装备/背包/战斗、搜索、容器及 lingtian_start_* 等)逐一补充符合当前 schema 的正向和反向
sample;同时完善 inventory_move_intent 与 cancel_search 的完整正反对拍,并确保 samples 与最新 schema
变更保持一致。
Source: Coding guidelines
Central reviewDecision: Validated findings[major] Add negative contract tests for the four-way gate-matrix checker
The newly wired CI step runs the checker only against the repository's currently consistent files, while Root cause: the test suite exercises only the rust enum parser and never drives the four-representation validation logic with deliberately inconsistent fixtures. the positive repository check proves only that today's inputs agree; it does not regression-protect the checker's failure behavior, which is the observable contract this pr adds to ci. [major] Craft quantity schema omits the server's maximum of 64
Root cause: the newly added typebox contract omitted the server's canonical maximum craft quantity, leaving the producer/schema boundary broader than the rust serde consumer contract. [major] Pin the new craft quantity boundary in schema tests
Root cause: the pr adds request payload validation contracts but adds only union-membership/order checking, not dedicated schema behavior tests for the new fields and their boundaries. consequently, field-level constraints can regress consistently across source and generated artifacts without any test failing. [major]
|
353c013 to
46c8406
Compare
Central reviewDecision: The review could not complete safely. No approval or code finding was inferred from the failed stages.
|
Central reviewDecision: The review could not complete safely. No approval or code finding was inferred from the failed stages.
|
Central reviewDecision: Validated findings[major] Lingtian replenish required and closed-shape contract is omitted
Root cause: the exhaustive-looking new-contract table skips one newly added union variant, and existing source-enum tests do not cover that variant's required-field or closed-object guarantees. [major] Do not deduplicate generated schema wires before validating duplicates
Root cause: the generated-schema representation is deduplicated before validation, which destroys the evidence needed by the duplicate-contract check and allows malformed or drifted generated unions to pass the ci gate. [major] Recipe-fragment request has no production producer
Root cause: the pr registers a new cross-stack request contract and server consumer but does not wire the existing alchemy fragment ui action to a matching client encoder/sender. the production producer remains connected to the legacy recipe-id request, leaving [major] Pin entity IDs to the Rust i32 wire range
The new contract table supplies ordinary positive Root cause: the new entity-id contracts were tested only for presence and closed shape, without pinning the numeric range shared by typebox and rust. the typebox producer contract is therefore wider than the rust [major] Reconcile the P0-only claim with runtime changes in this PR
This plan says the PR “只完成 P0 docs closeout” and that runtime implementation remains blocked, and later repeats that P0 does not modify the runtime gate. However, this pull request also changes the production handler: Root cause: the plan was written against an earlier [major] Cover Zhenfa placement gate through the client-request path
The handler now rejects every Root cause: a new security-sensitive c2s reach/dimension gate lacks production-path regression coverage. tests that deserialize or directly inject [major] New request boundary constraints are not regression-pinned
The new parameterized suite supplies only small valid values for every bounded identifier ( Root cause: the shared test table validates presence and closed shapes but does not encode the numeric and string boundary constraints of the new request schemas, leaving multiple changed wire contracts unprotected against permissive regressions. [major] Recipe-fragment learning has no production client producer
The changed generated union exposes Root cause: the pr registers the new request in the shared schema and wires its server consumer, but omits the client-side producer and interaction entry point. consequently a normal client can never send the request, leaving recipe-fragment learning unreachable despite schema and synthetic server tests passing. [major] Rust still accepts craft_start payloads rejected by the source schema
A Root cause: the pull request adds [major] New C2S contracts lack required boundary and per-variant regression tests
The new schemas introduce bounded IDs such as Root cause: the regression suite exercises representative happy-path values but does not pin the newly declared numeric boundaries or every new request contract. this leaves observable c2s validation behavior unprotected, contrary to the required saturated schema tests for boundary, off-by-one, invalid-input, and per-variant coverage. [major] Test strict Lingtian mode rejection and dispatch
Unknown Lingtian till and harvest modes are now required to be rejected before Root cause: the strict mode-parsing behavior changes an externally supplied request value from fail-open defaulting to rejection, but the event-dispatch boundary and invalid-input branch are unprotected by regression tests. |
Central reviewDecision: Validated findings[major] Stacked attributes bypass the variant wire-rename guard
A future valid Rust variant declaration such as Root cause: the parser stores only the most recent top-level variant attribute instead of accumulating and validating all attributes attached to the pending variant. this makes the new purported fail-closed wire-contract check order-dependent and allows a serde rename to be hidden by any following attribute. [major] Inline-attributed variants are silently omitted from the gate matrix inventory
Root cause: the parser identifies an attribute solely by [minor] Plan edits unnecessarily trigger the full 45-minute E2E job
A documentation-only commit that changes Root cause: the workflow path filter couples a planning-document change to the full end-to-end job instead of a focused matrix-contract job. because the workflow's existing job has broad build, integration, and bot stages, ordinary edits to this large plan cause substantial avoidable ci latency and runner consumption. [major] Stacked attributes bypass the tested serde-rename rejection
The new negative test only covers a Root cause: the parser regression tests cover only one immediately adjacent attribute and omit valid stacked variant attributes. consequently, the checker's single-slot |
Central reviewDecision: The review could not complete safely. No approval or code finding was inferred from the failed stages.
|
Central reviewDecision: Validated findings[major] Remove unrelated item textures from the P0 gate-plan closeout
This PR's declared P0 deliverable says it "only adds docs, absorption evidence, and the enum/matrix static checker" ( Root cause: unrelated gameplay assets were bundled into a docs-and-static-checker phase even though the changed plan explicitly excludes texture output and defines a narrower p0 file/deliverable boundary. this obscures the authoritative purpose and validation surface of the change; the assets should be moved to the gameplay/asset change that owns and verifies them, or the plan and acceptance evidence must explicitly absorb that scope. [major] Reject trailing variant declarations instead of silently skipping them
A valid Rust declaration can place more than one variant on a line, for example Root cause: the line-oriented parser validates only the first character of the text following the first variant name and then discards the rest of that line. it neither consumes one complete rust variant declaration nor rejects trailing non-comment tokens, so additional valid variants can be silently omitted from the inventory and therefore from the required gate matrix. [major] Plan matrix parsing is mocked out of every regression test
The new test suite never exercises Root cause: the plan-side parser, which is a changed observable contract of the new ci gate, has no direct regression test; all contract tests mock away that boundary. add parser tests using representative markdown for valid rows and malformed, missing, duplicate, reordered, and unrelated numbered tables, or an end-to-end test with controlled enum and plan files. |
68b7b93 to
ecc44f0
Compare
仅重放原 stripped head 相对基线的 P0 文档与检查器文件,保留主线 v2.1 审查策略。 Model: cc-sonnet-high Co-Authored-By: Claude <noreply@anthropic.com>
ecc44f0 to
1d042f7
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/check_c2s_gate_matrix.py`:
- Around line 92-94: Update the variant-level serde attribute validation in
scripts/check_c2s_gate_matrix.py:92-94 to fail closed for every #[serde(...)]
attribute, or at minimum reject alias, skip, other, rename, and variant-level
rename_all instead of only rename. Add rejection test cases for alias, skip,
other, and variant-level rename_all in
scripts/tests/check_c2s_gate_matrix_test.py:54-87.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: aa7f0efc-4d0f-4851-9cac-5d20c4a285ea
📒 Files selected for processing (7)
.github/workflows/e2e.ymldocs/plan-refactor-c2s-gate-v1.mddocs/plans-skeleton/plan-refactor-c2s-gate-v1.mddocs/plans-skeleton/plan-refactor-master-v1.mddocs/plans-skeleton/plan-refactor-wire-s2c-v1.mdscripts/check_c2s_gate_matrix.pyscripts/tests/check_c2s_gate_matrix_test.py
💤 Files with no reviewable changes (1)
- docs/plans-skeleton/plan-refactor-c2s-gate-v1.md
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
- GitHub Check: e2e
🧰 Additional context used
📓 Path-based instructions (5)
docs/**/*.md
📄 CodeRabbit inference engine (docs/CLAUDE.md)
docs/**/*.md: 新 plan 头部必须写明接入面:进料、出料、复用的共享类型/event/schema、server/agent/client 跨仓库契约,以及对应的worldview.md锚点。
涉及真元、灵气、衰减、逸散、半衰、距离损耗、排斥或吸力的 plan,必须调用qi_physics;新物理常数和公式必须先扩展qi_physics,不得在功能 plan 中重复实现。
所有真元/灵气流动必须遵守守恒律并通过qi_physics::ledger::QiTransfer;释放使用qi_release_to_zone,吸收使用qi_excretion,不得凭空生成或销毁真元。
涉及玩家可感知行为的 plan,必须在对应机制阶段中内联可直接实现的粒子、音效、HUD、环境、动画和 narration 规格;不得将视听内容笼统推迟到独立阶段。纯 server 逻辑 plan 例外。
每份 plan 必须列出开放问题;实施前必须追加§N.1 决议,逐项给出结论、实施方案、边界条件,并以文件:行号和 plan 章节双锚点落地。
scope 大于或等于 4 个 PR 的 plan,必须在末尾包含§10 实施工作流,并按依赖顺序在一个 plan 内序列化多个 PR,不得拆成多个 plan。
涉及 NBT 建筑、worldgen layout 或复杂视觉资产的 TODO,必须完成三轮提交:(round 1/3)、(round 2/3)、(round 3/3);终轮提交必须包含拼写准确的<PROMISE>担保块。
§10 最末必须包含“单次 consume-plan 全自动到 merge”章节,明确用户提交/consume-plan后即可等待最终归档至docs/finished_plans/。引用世界观内容时统一使用
worldview.md §X L<line>格式;不得自动修改docs/worldview.md或主动回写docs/library/。
Files:
docs/plans-skeleton/plan-refactor-master-v1.mddocs/plans-skeleton/plan-refactor-wire-s2c-v1.mddocs/plan-refactor-c2s-gate-v1.md
docs/plans-skeleton/**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
新 plan 必须先读取
docs/CLAUDE.md;骨架、Active 和 Finished plan 必须遵循三态流转及规定的阶段状态、Finish Evidence 结构。
Files:
docs/plans-skeleton/plan-refactor-master-v1.mddocs/plans-skeleton/plan-refactor-wire-s2c-v1.md
**/*
📄 CodeRabbit inference engine (CLAUDE.md)
**/*: commit message 必须使用中文,每个逻辑单元一个 atomic commit;agent 生成的 commit 必须带真实模型Model: <精确模型 id>trailer。
禁止使用--no-verify、--no-gpg-sign、关闭签名配置、未经确认的 force push、hard reset、amend 或交互式 rebase。
禁止留下 auto-stash 产生的孤儿 WIP stash;自动 stash 流程完成后必须恢复自己的 stash。
Files:
docs/plans-skeleton/plan-refactor-master-v1.mddocs/plans-skeleton/plan-refactor-wire-s2c-v1.mdscripts/tests/check_c2s_gate_matrix_test.pyscripts/check_c2s_gate_matrix.pydocs/plan-refactor-c2s-gate-v1.md
**/*.{rs,ts,tsx,java,py}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{rs,ts,tsx,java,py}: 每个新增函数、组件或协议必须测试 happy path、边界、错误分支和全部状态转换;测试应断言外部可观察行为而非内部实现。
schema、enum 和状态机必须有专属 pin 测试;TypeBox/serde variant 要有正反 sample 对拍,每个 enum variant 和状态转换至少有一条用例。
Files:
scripts/tests/check_c2s_gate_matrix_test.pyscripts/check_c2s_gate_matrix.py
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Python 文件保存后应由 ruff 自动格式化,worldgen 修改应通过仓库规定的 regen、raster 校验和构建流程。
Files:
scripts/tests/check_c2s_gate_matrix_test.pyscripts/check_c2s_gate_matrix.py
🧠 Learnings (3)
📚 Learning: 2026-07-17T00:31:10.779Z
Learnt from: Kizunad
Repo: Kizunad/Bong PR: 1218
File: docs/plans-skeleton/plan-skill-av-relink-v1.md:1-1
Timestamp: 2026-07-17T00:31:10.779Z
Learning: 在审查该仓库 `docs/plans-skeleton/` 下的“docs-only skeleton plan”创建类 PR 时:先核对 `docs/CLAUDE.md` 中“Plan 消费规范”,并逐份查看本计划文档里的“§10 实施工作流”,确认后续实施阶段是否会遵循“每个 PR 只修改一个 plan”,且实施/归档时不会出现跨 plan 的修改。该规则不适用于用户显式指定、共享调研基线且计划之间存在互相交叉引用的 skeleton plan 同批创建 PR;对这类情况应按实际交叉引用关系放宽,确保仍能按独立或约定的序列化方式推进。
Applied to files:
docs/plans-skeleton/plan-refactor-master-v1.mddocs/plans-skeleton/plan-refactor-wire-s2c-v1.md
📚 Learning: 2026-07-17T00:31:13.643Z
Learnt from: Kizunad
Repo: Kizunad/Bong PR: 1218
File: docs/plans-skeleton/plan-skill-av-relink-v1.md:81-85
Timestamp: 2026-07-17T00:31:13.643Z
Learning: 审核 docs/plans-skeleton/*.md 下的 skeleton 草案 PR 时:不得要求作者在“§N 开放问题(P0 决策门前需收口)”核查完成之前提前填写对应的“§N.1 决议”。仅当计划进入 active 且 P0 实施前,已由 Explore agent 并行核查代码现状后,才允许追加“§N.1 决议”,且该决议需包含结论、实施方案、边界条件,并使用“文件:行号 + plan 章节”的双锚点格式。
Applied to files:
docs/plans-skeleton/plan-refactor-master-v1.mddocs/plans-skeleton/plan-refactor-wire-s2c-v1.md
📚 Learning: 2026-07-22T02:11:59.191Z
Learnt from: Kizunad
Repo: Kizunad/Bong PR: 1247
File: docs/plans-skeleton/plan-bughunt-animal-air-spawn-gravity-v1.md:0-0
Timestamp: 2026-07-22T02:11:59.191Z
Learning: 在 `docs/plans-skeleton/` 目录下的计划状态行中,若起草日期同时涉及 UTC 与本地日期(例如时区换算后可能跨到不同日期),请在该行中同时标注 UTC 起草日与本地起草日。这样可以避免基于 UTC 的时间基准在 GitHub/CodeRabbit 审查时将本地日期误判为“未来日期”。
Applied to files:
docs/plans-skeleton/plan-refactor-master-v1.mddocs/plans-skeleton/plan-refactor-wire-s2c-v1.md
🪛 LanguageTool
docs/plan-refactor-c2s-gate-v1.md
[uncategorized] ~301-~301: 您的意思是“"不"齐”?
Context: ...questV1变体穷尽声明Spec/NoGate(reason)`、补齐声明所需 authority/state adapter,并把 product...
(BU)
[uncategorized] ~306-~306: 您的意思是“"不"洞”?
Context: ...StateGateId adapter 保留单一事实源,不再承担任何枚举声明补洞。 - 测试抓手:enum↔registry 穷尽编译门继续常绿;...
(BU)
[uncategorized] ~332-~332: 您不可用“是”来表达个形容词。大部分人都平常用“很”来代替“是”。您是不是想表达"很纯"?
Context: ...。 ## §10 实施工作流 ### §10.1 适用边界 本 plan 是纯 server/network 逻辑重构,不产出 NBT、worldgen la...
(SHI_ADHECTIVE_ERROR)
[uncategorized] ~339-~339: 您的意思是“"不"枚”?
Context: ...变。 4. PR-4 / P3:删重复门禁并收敛领域 adapter,不补枚举声明欠账。 5. PR-5 / P4:bot/e2e 与符合条件的吸...
(BU)
🪛 Ruff (0.16.0)
scripts/tests/check_c2s_gate_matrix_test.py
[warning] 13-13: Assertion should be broken down into multiple parts
Break down assertion into multiple parts
(PT018)
[warning] 51-51: Use pytest.raises instead of unittest-style assertRaisesRegex
Replace assertRaisesRegex with pytest.raises
(PT027)
[warning] 56-56: Use pytest.raises instead of unittest-style assertRaisesRegex
Replace assertRaisesRegex with pytest.raises
(PT027)
[warning] 64-64: Use pytest.raises instead of unittest-style assertRaisesRegex
Replace assertRaisesRegex with pytest.raises
(PT027)
[warning] 73-73: Use pytest.raises instead of unittest-style assertRaisesRegex
Replace assertRaisesRegex with pytest.raises
(PT027)
[warning] 80-80: Use pytest.raises instead of unittest-style assertRaisesRegex
Replace assertRaisesRegex with pytest.raises
(PT027)
scripts/check_c2s_gate_matrix.py
[warning] 49-49: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 53-53: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 57-57: Too many branches (17 > 12)
(PLR0912)
[warning] 60-60: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 62-62: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 82-82: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 93-93: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 97-97: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 100-100: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 105-105: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 112-112: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 124-124: Use a list comprehension to create a transformed list
(PERF401)
[warning] 126-126: Avoid specifying long messages outside the exception class
(TRY003)
🔇 Additional comments (5)
docs/plan-refactor-c2s-gate-v1.md (2)
328-332: 补齐开放问题和对应决议登记。当前 plan 没有独立的“开放问题”章节。
P0 决议不能替代未决项清单。请列出未决项。若无未决项,请明确写出“无开放问题”和验证依据。实施前请为每项补充
§N.1 决议,并记录结论、实施方案、边界条件、文件:行号和 plan 章节双锚点。
352-354: 定义单次/consume-plan的自动闭环和停止条件。§10.4 只定义了归档终态。它没有说明用户提交一次
/consume-plan后会自动串行执行 PR-2 至 PR-5、等待门禁、merge 并归档。请明确任一阶段失败、门禁未通过或暂停时立即停止,且不得归档。
docs/plans-skeleton/plan-refactor-wire-s2c-v1.md (1)
25-25: 修正或说明ServerDataType的 144 项基线。当前文本仍将
ServerDataType写为 144 项。此前核验显示 agent schema 的ServerDataTypeunion 为 100 项。如果 144 包含 Rust-only 或旁路变体,请说明来源和范围。否则,请使用当前 agent union 的实际数量。
docs/plans-skeleton/plan-refactor-master-v1.md (1)
101-101: LGTM!.github/workflows/e2e.yml (1)
119-123: LGTM!
| if any("serde" in attribute and "rename" in attribute for attribute in pending_attributes): | ||
| raise RuntimeError("ClientRequestV1 variant-level serde rename is unsupported") | ||
| pending_attributes.clear() |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -U \
'^\s*#\[serde\([^]]*(alias|skip|other|rename|rename_all)' \
server/src/schema/client_request.rsRepository: Kizunad/Bong
Length of output: 974
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '--- files ---\n'
git ls-files | rg '(^|/)check_c2s_gate_matrix(\.py)?$|(^|/)check_c2s_gate_matrix_test\.py$' || true
printf '\n--- checker outline/contents ---\n'
wc -l scripts/check_c2s_gate_matrix.py
sed -n '1,150p' scripts/check_c2s_gate_matrix.py
printf '\n--- tests relevant section ---\n'
sed -n '1,140p' scripts/tests/check_c2s_gate_matrix_test.py
printf '\n--- schema excerpts client_request.rs relevant ---\n'
sed -n '1,50p' server/src/schema/client_request.rs
sed -n '760,800p' server/src/schema/client_request.rsRepository: Kizunad/Bong
Length of output: 241
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '--- files ---\n'
git lg ls-files | rg '(^|/)check_c2s_gate_matrix(\.py)?$|(^|/)check_c2s_gate_matrix_test\.py$' || true
printf '\n--- checker outline/contents ---\n'
wc -l scripts/check_c2s_gate_matrix.py
sed -n '1,150p' scripts/check_c2s_gate_matrix.py
printf '\n--- tests relevant section ---\n'
sed -n '1,140p' scripts/tests/check_c2s_gate_matrix_test.py
printf '\n--- schema excerpts client_request.rs relevant ---\n'
sed -n '1,50p' server/src/schema/client_request.rs
sed -n '760,800p' server/src/schema/client_request.rsRepository: Kizunad/Bong
Length of output: 241
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- files ---'
git lg ls-files | rg '(^|/)check_c2s_gate_matrix(\.py)?$|(^|/)check_c2s_gate_matrix_test\.py$' || true
printf '%s\n' ''
printf '%s\n' '--- checker outline/contents ---'
wc -l scripts/check_c2s_gate_matrix.py
sed -n '1,150p' scripts/check_c2s_gate_matrix.py
printf '%s\n' ''
printf '%s\n' '--- tests relevant section ---'
sed -n '1,140p' scripts/tests/check_c2s_gate_matrix_test.py
printf '%s\n' ''
printf '%s\n' '--- schema excerpts client_request.rs relevant ---'
sed -n '1,50p' server/src/schema/client_request.rs
sed -n '760,800p' server/src/schema/client_request.rsRepository: Kizunad/Bong
Length of output: 12717
🌐 Web query:
serde RenameAll applies to enum variant names only enum variant attributes alias other
💡 Result:
In Serde, the rename_all attribute acts differently depending on where it is applied, and it does not affect alias attributes [1][2][3]. When rename_all is used as a container attribute on an enum, it applies the specified casing convention (e.g., camelCase, snake_case) to the enum's variant names [1][4]. It does not affect the fields within those variants [4][5]. If you need to rename the fields of enum variants using a casing convention, you must either: 1. Apply rename_all individually to each struct-like variant [4][2]. 2. Use rename_all_fields if available/appropriate for your specific Serde version (note: rename_all_fields is specifically intended to apply a casing rule to the fields of variants) [1]. Regarding aliases, the alias attribute on an enum variant provides an alternative name for deserialization that is independent of any rename_all or rename attributes [6]. If a variant has a rename_all rule applied (via the container) or a rename attribute, the alias attribute still functions as an additional valid name for that variant during deserialization [6]. Explicit rename attributes on a specific variant will override the casing convention applied by rename_all at the container level [3]. Top results: [1][4][2][3][6]
Citations:
- 1: https://serde.rs/container-attrs
- 2: https://serde.rs/variant-attrs.html
- 3: https://rs4ts.dev/15-serialization/05-attributes/
- 4: untagged enum does not rename to camel case serde-rs/json#501
- 5: Apply rename_all to enum member "fields" serde-rs/serde#1061
- 6: Field aliases do not work in combination with
flattenserde-rs/serde#1504
🌐 Web query:
serde enum variant syntax alias skip default other documentation example
💡 Result:
In Serde, enum variants support several attributes to control their serialization and deserialization behavior [1][2][3]. ### Alias The #[serde(alias = "name")] attribute allows you to deserialize a variant from a different name in addition to its Rust name [1][3]. This can be repeated to specify multiple aliases [1][3]. ### Skip The #[serde(skip)] attribute prevents a variant from being serialized or deserialized [1][3]. Note: In some data formats, especially non-self-describing ones like bincode, using #[serde(skip)] on an enum variant can lead to unexpected behavior or errors because the serializer still expects to be able to represent that variant [4][5]. ### Other The #[serde(other)] attribute is used during deserialization to catch any unknown variant values and map them to a specific "catch-all" variant [5]. It is typically applied to a unit variant in an enum. If the deserializer encounters a value that does not match any other defined variants, it will deserialize it into the variant marked with #[serde(other)] [5]. ### Default While #[serde(default)] is a standard field attribute for structs (to fill missing fields with Default::default()) [6][7], it is not a direct variant attribute for enums in the same way. However, for enum variants that contain fields (e.g., struct-like variants), you can apply #[serde(default)] to those individual fields to provide default values during deserialization [2][7]. ### Example Below is an example demonstrating the use of alias and other: rust use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] enum Status { Active, #[serde(alias = "inactive", alias = "disabled")] Suspended, #[serde(other)] Unknown, } fn main() { // Deserializing "inactive" maps to Status::Suspended let s: Status = serde_json::from_str("\"inactive\"").unwrap(); println!("{:?}", s); // Output: Suspended // Deserializing "anything_else" maps to Status::Unknown due to #[serde(other)] let s: Status = serde_json::from_str("\"anything_else\"").unwrap(); println!("{:?}", s); // Output: Unknown } Top results for this query include the official Serde documentation for variant and field attributes [1][2][6].
Citations:
- 1: https://serde.rs/variant-attrs.html
- 2: https://serde.rs/attributes.html
- 3: https://kolulu23.github.io/serde-rs.github.io/attributes/variant-attrs/
- 4: https://stackoverflow.com/questions/62175415/does-serde-skip-attribute-actually-skip-an-enum-variant
- 5: Allow skipping an enum variant serde-rs/serde#2062
- 6: https://serde.rs/field-attrs.html
- 7: https://rs4ts.dev/15-serialization/05-attributes/
对所有 variant-level serde attribute 执行 fail-closed。
scripts/check_c2s_gate_matrix.py:92-94 只拒绝 rename。alias 可以增加未登记的 wire 名称,skip 和 other 也会改变反序列化集合;rename_all 也需要在 variant 上拒绝,因为它可能覆盖 enum 级别的 rename_all。
- 拒绝所有 variant-level
#[serde(...)],或至少拒绝alias、skip、other、rename以及 variant 级别的rename_all。 - 在
scripts/tests/check_c2s_gate_matrix_test.py:54-87补充alias、skip、other和 variant-levelrename_all的拒绝用例。
建议修复
- if any("serde" in attribute and "rename" in attribute for attribute in pending_attributes):
- raise RuntimeError("ClientRequestV1 variant-level serde rename is unsupported")
+ if any("serde" in attribute for attribute in pending_attributes):
+ raise RuntimeError("ClientRequestV1 variant-level serde attribute is unsupported")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if any("serde" in attribute and "rename" in attribute for attribute in pending_attributes): | |
| raise RuntimeError("ClientRequestV1 variant-level serde rename is unsupported") | |
| pending_attributes.clear() | |
| if any("serde" in attribute for attribute in pending_attributes): | |
| raise RuntimeError("ClientRequestV1 variant-level serde attribute is unsupported") | |
| pending_attributes.clear() |
🧰 Tools
🪛 Ruff (0.16.0)
[warning] 93-93: Avoid specifying long messages outside the exception class
(TRY003)
📍 Affects 2 files
scripts/check_c2s_gate_matrix.py#L92-L94(this comment)scripts/tests/check_c2s_gate_matrix_test.py#L54-L87
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/check_c2s_gate_matrix.py` around lines 92 - 94, Update the
variant-level serde attribute validation in
scripts/check_c2s_gate_matrix.py:92-94 to fail closed for every #[serde(...)]
attribute, or at minimum reject alias, skip, other, rename, and variant-level
rename_all instead of only rename. Add rejection test cases for alias, skip,
other, and variant-level rename_all in
scripts/tests/check_c2s_gate_matrix_test.py:54-87.
Central reviewDecision: The review could not complete safely. No approval or code finding was inferred from the failed stages.
|
摘要
docs/plans-skeleton/plan-refactor-c2s-gate-v1.md单次促升为 active plan,完成 R4 P0 docs closeout。ClientRequestV1权威枚举重算并逐项冻结 104 变体门禁矩阵,纠正plan-refactor-master-v1建轨时 113 变体的历史快照。GateSpec、欧氏平方 reach、fail-closed mutation barrier、内部拒绝原因与 R6 wire 所有权边界。总纲与依赖
本 PR 对齐
docs/plans-skeleton/plan-refactor-master-v1.md§2/§3/§4/§5/§6:R4 implementation 仍属于 Wave 2。#1287 已合入;R6 P1 尚未落地,因此本 PR 严格限定 P0 文档收口,不实施 gate 代码、不修改 R6 契约文件。验证
ClientRequestV1enum ↔ P0 matrix:104/104,顺序与集合精确一致。git diff --check origin/main...HEAD。83f56d37f2837bd3bdc2dd930a98b22667330827。测试说明
Docs-only;未运行 Cargo。未运行
scripts/test-tmux-shutdown-order.sh或scripts/test-server-lifecycle.sh。主导模型:
claude-sonnet-5