Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/plan-refactor-client-store-lifecycle-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
- **模块 / symbol**:`client/src/main/java/com/bong/client/lifecycle/{ClientStoreScopeManifest,SessionScopedStore,SessionStoreHandle,SessionScopedStoreRegistry}.java`;`SessionScopedStore.clearOnDisconnect()`;`SessionStoreHandle.forStore(...)`;`SessionScopedStoreRegistry.clearAllOnDisconnect()`。
- **测试抓手**:`ClientStoreScopeManifestTest` 精确 pin 108 个 Store 的三分类、106 个 session Store、`ClientConnectionStatusStore` 外部 token 管理与 P0 空 registry;`SessionScopedStoreRegistryTest` pin 声明顺序、重复 FQCN fail-fast、Store / reporter 异常隔离和 `Error` 透传。
- **跨仓库契约**:纯 client 生命周期基础设施;schema、Redis key、CustomPayload 均无新增或变更。
- ⬜ **P1 在册 Store 平移**:把当前 `clearClientStateOnDisconnect()` 中已存在的 Store 清理逐项迁入 registry;断线 helper 改为调用 registry 一次。非 Store 的 renderer / handler / ambience 等生命周期 hook 继续由 helper 显式拥有,P1 不借重构删除它们。
- ⬜ **P1 在册 Store 平移**:把当前 `clearClientStateOnDisconnect()` 中已存在的 Store 清理逐项迁入 registry;断线 helper 改为调用 registry 一次。非 Store 的 renderer / handler / ambience 等生命周期 hook 继续由 helper 显式拥有,P1 不借重构删除它们。R1 craft 接缝以本阶段已登记的 `CraftStore` 为唯一 client session-state owner;R7 P2 只消费该 Store 实现 close/pause/reopen/resume,不再建立第二份状态。
- **模块 / symbol**:`client/src/main/java/com/bong/client/lifecycle/SessionScopedStoreRegistry.java` 的显式 `REGISTERED`;`client/src/main/java/com/bong/client/BongNetworkHandler.java` 的 `disconnectSession(...)` / `clearClientStateOnDisconnect()`。
- **测试抓手**:`ClientStoreScopeManifestTest` 精确 pin P1 已迁移 FQCN 集;`BongNetworkHandlerTest` pin token invalidation 先于 registry、迟到旧 handler 不清新 session、非 Store hook 仍保留;每个 adapter 以目标 Store 的状态级行为测试证明 method reference 未错绑。
- **跨仓库契约**:保持现有 wire、schema、Redis key 与 CustomPayload 不变。
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Expand Down Expand Up @@ -111,7 +111,7 @@ skeleton:niche-guardian-cross-session-leak。

- 独占:全部 `*Store.java` 的生命周期接口与登记、`BongNetworkHandler.java` 的 `clearClientStateOnDisconnect` 区段。
- 不碰:`BongNetworkHandler.register()` 的 channel 注册区(R6 域,同文件分区段协作,两轨 merge 前互相 fetch);Screen 结构(R7 域);store 的业务字段语义。
- 依赖:无前置,Wave 0 即可动工。R7/R9 依赖本轨接口,先于它们合入
- 依赖:Wave/start/order/cutover 只引用 master §3/§4.1 与 PR 1902;R7/R9 只消费本轨冻结的 Store interface,不在 R2 复制跨轨箭头

## bot 验收场景

Expand Down
55 changes: 35 additions & 20 deletions docs/plan-refactor-inventory-core-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

## 阶段

- ✅ 2026-08-03 P0 完整契约面重写 + absorption audit
- ⬜ P1:inventory 拆分 + txn/capacity 骨架 + inventory-layout/dropped-loot 纯 migration helpers(依赖 R3 P1 seam
- ⬜ P2:production writer 迁移分为 P2a metadata/provider + Public writer path 与 P2b OwnerOnly private-writer activation;P2a 依赖 R3 P2 atomic commit seam 与旧 dropped-loot compatibility,P2b 必须等 R3 P4 dropped-loot migration/hydration、R6 P1 recipient projection/page、R5 P3 + R6 P4、R10 P3 pickup txn 及 R4 pickup consumer 全部完成后才可启用
- ⬜ P3:pickup/merge txn(依赖 R5 P3 attrition API、R6 P4 receipt API)
- ⬜ P4:联合 bot/e2e + plan 收口(依赖 R4 handler 与 R3 P4 legacy inventory-layout consumer)
- P0 完整契约面重写 + absorption audit
- ⬜ P1:inventory 拆分 + txn/capacity 骨架 + inventory-layout/dropped-loot 纯 migration helpers;对应 master M-06/M-13 的 transaction/provider surface,R3 seam 只按 M-04 提供。
- ⬜ P2:production writer 迁移分为 metadata/providerPublic/OwnerOnly writer 与 terminal worker;terminal worker 对应 M-06/O-10..O-27,dropped-loot hydration/projection 与 pickup consumer 只按 master M-13/M-14/M-15 启用
- ⬜ P3:pickup/merge txn;R4/R5/R6 consumer 与 receipt/attrition 接缝只引用 master M-14/M-15。
- ⬜ P4:联合 bot/e2e + plan 收口;完成 evidence 需覆盖对应 M-row 与 canonical O-row。

实现属 Wave 2;跨轨工作须登记 owning plan。
所有跨轨 start/order/cutover 只引用 `plan-refactor-master-v1.md §3/§4.1` 与 PR 1902;本阶段表不复制箭头

## 1. 完整 contract surface

Expand Down Expand Up @@ -39,6 +39,25 @@ InventoryTxn::pickup_and_merge(PickupRequest, PickupAuthorization, &mut DroppedL

`consume_checked` receipt 逐 instance 记录扣除量/剩余量;insufficient、unknown、zero 任一失败不得部分扣除。

### 1.2 Terminal-delivery production consumer(P2c)

R10 P2c 交付常驻 `SessionDeliveryWorker`,作为 R3 outbox 的唯一 production consumer。它只实现 R1 canonical obligation reducer 的 O-10..O-21/O-26/O-27,不拥有 gameplay session 状态或 teardown:

```rust
SessionDeliveryWorker::claim_next(now, worker_id)
-> Result<Option<ClaimedDelivery {
delivery_id, lease_id, generation, payload, payload_digest
}>, DeliveryWorkerError>
SessionDeliveryWorker::commit_claimed(claimed, Option<&mut SpillContext>)
-> Result<DeliveryCommitReceipt, DeliveryWorkerError>
SessionDeliveryWorker::fail(claimed, reason, now)
-> Result<DeliveryRetryState, DeliveryWorkerError>
```

`commit_claimed` 必须先预留 bounded history capacity(不足走 O-26),再校验 digest并从 `claimed.payload` decode/validate 唯一 `DeliveryRequest`;caller 无权另传 request。O-16 transaction 对拍 canonical bytes/digest、semantic item set 与 inventory receipt,并原子提交 inventory/spill、receipt、obligation delete、quota `-Q`。malformed/digest mismatch 命中 O-14,禁止调用 `deliver`;retry/lease/dead-letter 只走 O-12/O-13/O-18,绝不恢复 R1 session/claim。

P2c pins 直接执行 R1 O-10..O-21/O-26/O-27:并发唯一 claim、claim 后 crash/lease expiry、payload A/request B 拒绝、history quota fail-before-mutation、deliver 前后 crash、receipt replay、retry/dead-letter/operator CAS、满包 spill。R1 `session_delivery_crash_atomicity` 与 R3 `session_delivery_outbox_atomicity` 必须走真实 worker,不得由 domain 直接调用 `InventoryTxn::deliver` 冒充 consumer。

`pickup` receipt 含 request id、revision、removed drop、merge/placement、`target_instance_id`、`incoming_instance_id/count/abs_qi_before`。placement 的 target 等于 incoming;merge 的 target 是提交后既有 stack。R5 只按 incoming absolute qi 做 attrition:`target_after = preexisting_abs_qi + incoming_after`,不得磨损旧数量或由合并后整栈反推。

## 2. Spill / overflow 守恒
Expand Down Expand Up @@ -87,15 +106,10 @@ R10 的 inventory-layout 与 dropped-loot migration 函数均纯且幂等,保

## 6. 所有权与顺序

- **R10**:`server/src/inventory/**` model/grid/txn/capacity、writer enumeration、typed outcome、纯 migration。P1 仅在 **R3 P1** 的 inventory/overflow seam 冻结后实现 txn/capacity 骨架;P2a 负责 metadata/provider 与 `Public` writer path,依赖 **R3 P2** durable spill/pickup recoverable-commit seam、旧 dropped-loot migration compatibility 与 crash/retry pins;P2b 才能启用 `OwnerOnly` private writers,且必须等 **R3 P4 dropped-loot migration/hydration、R6 P1 recipient projection/page、R5 P3 + R6 P4、R10 P3 pickup txn、R4 pickup consumer** 全部完成;P3 pickup/attrition consumer 只有在 **R5 P3** incoming-only attrition/ledger API 与 **R6 P4** receipt wire/client API 已合入后才可接通。
- **R3**:SQL/outbox、spill/pickup recoverable commit、hydration guard、migration consumer;R10 只消费 R3 P1/P2/P4 已冻结并实现的接口。P4 必须拆成 dropped-loot hydration 子批次与 inventory-layout overflow 子批次,前者不等待 R10 P3,后者才等待其实际 durable/capacity 前置。
- **R4**:C2S gate/handler、authoritative pickup context、调用 R10 并转交 R6 outcome;R4 handler/consumer phase 必须等待 **R10 P3 pickup txn、R6 P4** receipt API 与 **R5 P3** attrition API,不得以 R10 mock 或仅 R6 P1 schema 代替。
- **R5**:incoming-only qi attrition/ledger;provider phase 为 R5 P3。
- **R6**:receipt wire/client、recipient projection/page、decoder;canonical plan 登记 rotate、pack feedback、dropped sync;dropped-loot projection/page consumer 为 R6 P1,必须在 **R10 P2a owner/visibility metadata provider** 与 **R3 P4 dropped-loot migration/hydration consumer** 完成后才可消费;receipt provider phase 为 R6 P4。
- **R1**:txn stored/spilled 成功后才 teardown,失败保留 session。
- **R7**:UI 消费,不拥有事务。

顺序:**R3 P1 → R10 P1(含纯 inventory-layout/dropped-loot migration helpers)→ R3 P2 atomic seam 实现 + legacy dropped-loot migration/hydration compatibility pins → R10 P2a metadata/provider + Public writer path → R3 P4 dropped-loot migration/hydration consumer → R6 P1 dropped-loot projection/page consumer → R5 P3 + R6 P4 → R10 P3 pickup/merge txn → R4 handler/pickup consumer → R10 P2b OwnerOnly private-writer activation → R3 P4 inventory-layout overflow consumer → R10 P4 联合 e2e**。R10 P2a 在 R3 P2 atomic seam 与旧 dropped-loot migration compatibility 未合入前不得开始;R3 P4 dropped-loot migration/hydration consumer 必须先于 R6 P1 dropped-loot projection/page consumer,确保旧 `entry_json` 已先升级为带 `owner`/`visibility` 的 canonical entry;R10 P2b 只有在 R3 P4 dropped-loot hydration、R6 P1 projection/page、R5 P3 + R6 P4、R10 P3 pickup txn 与 R4 pickup consumer 全部完成后才可启用,避免 OwnerOnly writer 在授权消费链闭合前广播或转移私有掉落;R10 P3 在 R5 P3/R6 P4 provider 未合入前不得开始 pickup consumer;R4/R3 的外轨交付物只作 R10 P4 验收前置、不计入 R10 自身 phase;R10 不越权改 persistence、wire、handler 或 client。
- **R10** 独占 `server/src/inventory/**`、纯 migration helpers 与 `SessionDeliveryWorker`;terminal worker 只投影 R1 O-10..O-21/O-26/O-27,inventory/spill transaction 不定义 session teardown。
- **R3** 独占 SQL/outbox/CAS/reconciliation、hydration guard 与 migration consumer;R10 通过冻结接口 claim/commit/fail。
- **R4/R5/R6/R7** 分别拥有 C2S authorization、qi attrition ledger、receipt/projection wire 与 UI consumer;R10 不修改其文件。
- 所有跨轨 start/order/cutover 仅引用 master §3/§4.1 与 PR 1902,不在本 plan 复制箭头。接口可 contract-first 合入;真实 worker activation 必须等 master 列出的 R3 outbox 与 R10 transaction artifacts 存在,且不得用 mock 宣称 production closure。

## 7. 审核要求的 contract pins

Expand All @@ -108,15 +122,16 @@ R10 的 inventory-layout 与 dropped-loot migration 函数均纯且幂等,保
5. pickup 同维成功;跨维、超距/zone、owner/private 拒绝;merge、placement-only、failed attach/capacity/validation/persistence 后 entry 仍在;成功后才删。
6. incoming-only attrition receipt + R5 ledger:旧 stack absolute qi 不变;注入 attrition 后、durable commit 中断与 restart/retry,断言 attrited item + zone/ledger + drop delete 原子且总量守恒。
7. visibility matrix:同维/范围内 `Public` 对非 owner 可见,`OwnerOnly` 对 owner 可见、对普通非 owner 不可见、对 server-authorized admin 可见;另测跨维/超距拒绝。page/revision 按每个 recipient projection;缺页/混 revision 不替换。
8. accepted/rejected move correlation;pack stow/equip/unequip 与拒绝必须动作级 receipt,stale event 和 snapshot-only baseline 不通过。
9. forge 深链保留;另锁 `/give hoe_iron → 新 snapshot → 真实非零 instance → held/equip → lingtian_start_till`,禁止 `instance_id=0` 或任意 server-data 冒充成功。
10. inventory-layout migration pure happy/empty/full/dynamic/idempotent/invalid;dropped-loot migration 覆盖旧 `entry_json` 缺 owner/visibility → `None`/`Public`、已有字段原样保留、malformed/幂等;R3 consumer 对真实 context 成功,缺 context/capacity/persistence/migration failure 保留旧行可重试。
8. terminal-delivery worker:执行 R1 O-10..O-21/O-26/O-27,覆盖空队列、并发唯一 claim、lease expiry、payload/digest binding、history quota fail-before-mutation、commit crash、receipt replay、retry/dead-letter/operator CAS;quota effect 逐 row 对拍。
9. accepted/rejected move correlation;pack stow/equip/unequip 与拒绝必须动作级 receipt,stale event 和 snapshot-only baseline 不通过。
10. forge 深链保留;另锁 `/give hoe_iron → 新 snapshot → 真实非零 instance → held/equip → lingtian_start_till`,禁止 `instance_id=0` 或任意 server-data 冒充成功。
11. inventory-layout migration pure happy/empty/full/dynamic/idempotent/invalid;dropped-loot migration 覆盖旧 `entry_json` 缺 owner/visibility → `None`/`Public`、已有字段原样保留、malformed/幂等;R3 consumer 对真实 context 成功,缺 context/capacity/persistence/migration failure 保留旧行可重试。

## 8. Named bot acceptance(P4)

以下名称即 `scripts/bot/scenarios/<name>.py` 的稳定身份:

1. `inv_full_delivery_matrix`:craft/alchemy/forge/give 满包时 `stored + spilled == requested`,失败不 teardown。
1. `inv_full_delivery_matrix`:craft/alchemy/forge/give 满包时 `stored + spilled == requested`;checkpointed 三域经真实 `SessionDeliveryOutbox`→P2c O-10..O-16→receipt 链。handoff 已在 R1 S-14 teardown,worker failure 只留 Pending/DeadLetter obligation,不恢复 session
2. `inv_stack_merge`:同 identity merge、异 identity 分栈;placement-only 与拒绝路径保留 drop;attrition durable 中断/restart 仍原子守恒。
3. `inv_footprint_sync`:2×1 rotate 后以 request/instance/from/to/revision 锚定 1×2 authoritative receipt;snapshot 不代替回执。
4. `inv_pack_feedback`:stow/equip/unequip 的 accepted/rejected 均按时间锚与 correlation 匹配,stale event 不通过。
Expand All @@ -128,7 +143,7 @@ R10 的 inventory-layout 与 dropped-loot migration 函数均纯且幂等,保

| plan | 2026-08-03 验真结论 | 证据/落点 |
|---|---|---|
| `alchemy-takeback-full-inventory-loss` | 部分吸收 | 满包 deliver/spill 后才由 R1 teardown。 |
| `alchemy-takeback-full-inventory-loss` | 部分吸收 | terminal handoff 后由 obligation worker deliver/spill;失败走 O-13,不 reopen。 |
| `dropped-loot-pickup-stack-merge` | 仍真实,吸收 | 当前 pickup 只找空 footprint;落 `pickup_and_merge`。 |
| `force-attach-grid-collision` | 仍真实,吸收 | `(0,0)` 强塞仍可达;改合法 attach/spill。 |
| `rotate-footprint-sync` | 仍真实,吸收 | `Moved` 缺权威新 footprint;R6 receipt 补齐。 |
Expand Down
Loading