fix: Discord follow-up replies avoid false stale snapshots#97642
fix: Discord follow-up replies avoid false stale snapshots#97642scribe-dandelion-cult wants to merge 4 commits into
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 29, 2026, 12:45 AM ET / 04:45 UTC. Summary PR surface: Source +28, Tests +93. Total +121 across 2 files. Reproducibility: yes. at source level: current main JSON-stringifies reply-session entries while storage can represent the same skillsSnapshot as durable promptRef, hydrated prompt, or runtime-only resolvedSkills. The inspected proof corpus also includes after-fix Discord logs, but I did not run a live Discord reproduction locally. Review metrics: 1 noteworthy metric.
Stored data model Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Mantis proof suggestion Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land one canonical shared session-store fix after checks settle, then close the duplicate same-root-cause PRs and linked issue through that merged branch. Do we have a high-confidence way to reproduce the issue? Yes at source level: current main JSON-stringifies reply-session entries while storage can represent the same skillsSnapshot as durable promptRef, hydrated prompt, or runtime-only resolvedSkills. The inspected proof corpus also includes after-fix Discord logs, but I did not run a live Discord reproduction locally. Is this the best way to solve the issue? Yes, this is a sound fix shape at the shared session-store boundary because it normalizes only revision comparison identity and keeps runtime hydration intact. The remaining issue is selecting one canonical green branch across overlapping open fixes. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against bf66b4e1ea7e. Label changesLabel justifications:
Evidence reviewedPR surface: Source +28, Tests +93. Total +121 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
@clawsweeper re-review 794ee30 Updated PR-scoped proof corpus for this fix:
It includes the focused unit proof, P2 normalization gates for runtime-only |
Strip runtime-only skillsSnapshot caches before deriving reply initialization revisions so hydrated writer entries match durable session JSON. Co-authored-by: Copilot <[email protected]>
|
🦞🧹 I asked ClawSweeper to review this item again. |
Exercise runtime-only resolvedSkills on the cached writer-store entry so the reply-init revision guard proves the persisted-shape normalization path. Co-authored-by: Copilot <[email protected]>
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Thanks @scribe-dandelion-cult for working through this same reply-session failure mode, and thanks @wiidz for the original report in #96698. A canonical fix has now landed in #97657 via 75db48a. It addresses the same persisted-versus-hydrated Because #97657 has merged with focused regression coverage and live Discord before/after proof, this PR is now superseded. Closing in favor of the landed fix. |
Summary
Fix false
stale-snapshotconflicts during reply-session initialization when a persistedskillsSnapshot.promptRefis hydrated into runtimeskillsSnapshot.prompt.Fixes #96698.
Related to #96699.
What Problem This Solves
Discord/channel follow-up messages can fail with:
The reply-session initialization guard computes a revision by serializing the session entry. But session-store reads can represent the same logical entry in multiple shapes:
skillsSnapshot: { skills, promptRef }skillsSnapshot: { skills, prompt }skillsSnapshot.resolvedSkillsThat means the optimistic guard can compare two equivalent session entries and falsely conclude that the entry changed concurrently.
Fix
Build reply-init revisions from the normalized persisted session-entry shape before comparing. This makes hydrated
prompt, durablepromptRef, and runtime-onlyresolvedSkillscaches compare equivalently while keeping the optimistic guard intact for real concurrent entry mutations.Evidence
The regression test recreates the exact mismatch:
skillsSnapshot.prompt.skillsSnapshot.promptRef.skillsSnapshot.resolvedSkillsto the hydrated writer entry.commitReplySessionInitialization.stale-snapshot.Focused proof:
node scripts/run-vitest.mjs run src/config/sessions/session-accessor.test.ts -t 'skillsSnapshot'Supplemental live output from Ronan after the rescue frond-build shows consecutive Discord
message.actionsuccesses and zero reply-init conflict/stale-snapshot lines in the same copied journal window:PR-scoped proof corpus:
Validation
node scripts/run-vitest.mjs run src/config/sessions/session-accessor.test.ts -t 'skillsSnapshot' node scripts/run-vitest.mjs run src/config/sessions/session-accessor.test.ts node scripts/run-vitest.mjs run src/config/sessions/store.skills-stripping.test.ts node scripts/run-vitest.mjs run src/auto-reply/reply/session.test.ts CI=true pnpm tsgo:core:test node scripts/run-oxlint-shards.mjs --only=core --split-coreFull
node scripts/test-projects.mjswas also run. It failed unrelated baseline/environment/catalog shards outside this session-store change; targeted session-store/reply-session coverage passed.