Skip to content

docs: Add Mutation-Invariant Mismatch bug pattern (#13)#27

Merged
adewale merged 5 commits intomainfrom
claude/investigate-track-steps-YSKIG
Jan 1, 2026
Merged

docs: Add Mutation-Invariant Mismatch bug pattern (#13)#27
adewale merged 5 commits intomainfrom
claude/investigate-track-steps-YSKIG

Conversation

@adewale
Copy link
Copy Markdown
Owner

@adewale adewale commented Jan 1, 2026

Document the step array resizing bug where handleSetTrackStepCount
violates the invariant that arrays must be exactly MAX_STEPS (128).

  • Add comprehensive spec in specs/research/STEP-ARRAY-INVARIANT-BUG.md
  • Add Bug Pattern Add linting pre-commit hook with husky and lint-staged #13: Mutation-Invariant Mismatch (Dual Truth Source)
  • Include codebase audit results identifying all affected handlers
  • Document that mock-durable-object.ts replicates the same bugs
  • Provide detection scripts and prevention checklist

Key findings:

  • handleSetTrackStepCount truncates arrays, violating invariants
  • handleToggleStep expands arrays via push()
  • Neither calls validateAndRepairState after mutation
  • 6 handlers don't call validation (only 2 have array risk)

claude added 5 commits January 1, 2026 00:54
Document the step array resizing bug where handleSetTrackStepCount
violates the invariant that arrays must be exactly MAX_STEPS (128).

- Add comprehensive spec in specs/research/STEP-ARRAY-INVARIANT-BUG.md
- Add Bug Pattern #13: Mutation-Invariant Mismatch (Dual Truth Source)
- Include codebase audit results identifying all affected handlers
- Document that mock-durable-object.ts replicates the same bugs
- Provide detection scripts and prevention checklist

Key findings:
- handleSetTrackStepCount truncates arrays, violating invariants
- handleToggleStep expands arrays via push()
- Neither calls validateAndRepairState after mutation
- 6 handlers don't call validation (only 2 have array risk)
- Add "How We Know We're Right" section with evidence table
- Prove all Model B (variable arrays) evidence was introduced in af466ff
- Document scheduler proof: guard implies arrays can be longer than stepCount
- Add complete implementation requirements with file list
- Document conflicting documentation in bug-patterns.ts that must be fixed
- Add client-side fix requirements for grid.tsx
- Document positive consequences (invariants pass, no data loss, hash stability)
- Confirm UI already handles 128-length arrays correctly (slices for display)
- Explain backward compatibility (repair auto-pads on load)
- Analyze state payload size impact (~1KB per track, mitigated by gzip)
- Add rollout considerations (must deploy client+server atomically)
- List specific tests that verify wrong behavior and must be updated
- Document snapshot storm mechanics and how it would manifest
- List existing defenses (debounce, threshold, interval)
- Add detection methods (metrics to monitor, log patterns)
- Describe resolution strategy if storm detected during rollout
- Add "The Vanishing Pattern" demo scenario showing data loss vs preservation
- Include test script for the demo
- Add user story for acceptance criteria
- Show original SET_TRACK_STEP_COUNT that we're restoring (just sets stepCount)
- Document the root cause: design intent was never explicitly stated
- Identify documentation gap: invariant enforced design but didn't explain WHY
- Add lesson learned: invariants should include rationale, not just checks
- Note that LESSONS-LEARNED.md used <= 128 not === 128, adding to confusion
@adewale adewale merged commit 699c739 into main Jan 1, 2026
4 of 5 checks passed
@adewale adewale deleted the claude/investigate-track-steps-YSKIG branch January 1, 2026 02:41
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.

2 participants