feat: add receive message reconciliation helper

This commit is contained in:
zhaoyilun
2026-07-11 00:38:06 +08:00
parent 57db83d36c
commit d94d0a318a
6 changed files with 252 additions and 8 deletions

View File

@@ -59,7 +59,7 @@ N13/N14/N15 are pre-business validation results. They can help identify UI eleme
## Current loop
Current loop: `R11 receive-file download preview contract complete`; next R12 receive-message reconciliation helper.
Current loop: `R12 receive-message reconciliation helper complete`; next R13 business goals smoke.
Active continuous execution plan: `docs/superpowers/plans/2026-07-10-r6f-r14-continuous-execution-plan.md`.
@@ -240,8 +240,8 @@ Continuous execution plan R6f-R14 is approved and execution has started:
- Plan file: `docs/superpowers/plans/2026-07-10-r6f-r14-continuous-execution-plan.md`.
- Scope: 15 ordered rounds covering send-message connector/gate hardening, send-file preview/idempotency/package, receive-file download preview, receive-message reconciliation, end-to-end business smoke, and release-candidate report.
- Execution rule after approval: one round at a time, status-card update, verification, commit, push, then continue automatically until an evidence-only blocker requires user action.
- Last completed round: R11 receive-file download preview contract.
- Next active round: R12 receive-message reconciliation helper.
- Last completed round: R12 receive-message reconciliation helper.
- Next active round: R13 business goals smoke.
R6g send audit and idempotency replay diagnostics is complete:
@@ -354,3 +354,13 @@ R11 receive-file download preview contract is complete:
- Both paths keep `file_contents_read=false`, `file_copied=false`, `real_download_attempted=false`, and `raw_paths_returned=false`; real file copy remains blocked.
- `scripts\verify-go-mcp.ps1` now asserts `receive_file_download_preview_blocked=true`.
- Next node: R12 receive-message reconciliation helper.
R12 receive-message reconciliation helper is complete:
- Added `internal/isphere/message_reconciliation.go` and `internal/isphere/message_reconciliation_test.go`.
- Strong match uses exact non-empty `message_id`; medium match uses same `conversation_id`, same `sender_id`, and timestamp within 3000 ms.
- Auto merge is recommended only when all records are strong matches with no unmatched or medium-only rows.
- Added `scripts\verify-receive-source-reconciliation.ps1 -UseFixture`, which outputs sanitized counts/booleans only.
- Fixture output: `strong_matches=1`, `medium_matches=1`, `unmatched_left=1`, `unmatched_right=1`, `auto_merge_recommended=false`, and `exact_fixture_auto_merge_recommended=true`.
- Default `isphere_receive_messages` routing is unchanged; `msglib_readonly` remains explicit only.
- Next node: R13 business goals smoke.

View File

@@ -136,7 +136,7 @@ Reason:
## Next implementation node
Recommended next business node: **R2 contact/group search quality hardening**.
Recommended next business node after R12: continue R13/R14 business smoke and release-candidate closure unless new real evidence changes priority.
Reason:
@@ -149,3 +149,28 @@ Future receive-specific node after R2/R3:
- Add a local-only reconciliation helper that compares PacketReader and MsgLib messages by sanitized keys and outputs only match counts, source refs, and mismatch categories.
- Do not implement pagination until reconciliation proves which source should drive ordering.
- Do not implement file download until R3 proves message-to-cache/download mapping.
## R12 implementation result
R12 added a local-only reconciliation helper:
- `internal/isphere/message_reconciliation.go`
- `internal/isphere/message_reconciliation_test.go`
- `scripts/verify-receive-source-reconciliation.ps1`
Fixture verification:
```json
{"ok":true,"verification":"receive_source_reconciliation","use_fixture":true,"strong_matches":1,"medium_matches":1,"unmatched_left":1,"unmatched_right":1,"auto_merge_recommended":false,"exact_fixture_auto_merge_recommended":true,"raw_message_bodies_returned":false,"raw_rows_returned":false,"file_paths_returned":false,"default_receive_routing_changed":false}
```
The helper is pure comparison logic: it performs no DB reads, log reads, send, download, hook, injection, or writes.
Current match behavior:
- strong match: exact non-empty `message_id` on both sides;
- medium match: same `conversation_id`, same `sender_id`, and timestamp within 3000 ms;
- auto merge is recommended only for complete strong-match coverage with no unmatched or medium-only records.
Decision remains unchanged: default `isphere_receive_messages` routing stays PacketReader/log-backed. `msglib_readonly` remains explicit only.

View File

@@ -857,19 +857,19 @@ git push gitea main
- Produces: `func ReconcileMessageSources(left, right []MessageReconciliationCandidate) MessageReconciliationSummary`.
- Summary fields: `strong_matches`, `medium_matches`, `unmatched_left`, `unmatched_right`, `auto_merge_recommended`.
- [ ] **Step 1: Write reconciliation tests**
- [x] **Step 1: Write reconciliation tests**
Add `TestReconcileMessageSourcesStrongAndMediumMatches`: same message id is strong; same conversation/sender and timestamp within 3000ms is medium; auto merge remains false until a strong-ratio threshold is met.
- [ ] **Step 2: Implement pure Go helper**
- [x] **Step 2: Implement pure Go helper**
No DB/log IO in the helper. It only compares sanitized candidates.
- [ ] **Step 3: Add script wrapper**
- [x] **Step 3: Add script wrapper**
Script runs against fixture JSON first; optional real evidence mode prints counts and booleans only.
- [ ] **Step 4: Verify and commit**
- [x] **Step 4: Verify and commit**
```powershell
git diff --check
@@ -885,6 +885,14 @@ git push gitea main
**Acceptance gate:** 对账能力存在,但默认 receive routing 不改变。
**R12 Result:**
- Added pure Go reconciliation helper and tests.
- Added `scripts/verify-receive-source-reconciliation.ps1 -UseFixture`.
- Fixture output is sanitized and keeps `default_receive_routing_changed=false`.
- Default receive routing remains PacketReader/log-backed; no `auto` merge was enabled.
---
### R13: End-to-end business goals smoke