This PR completes issue #60 by documenting and verifying that the Aether event store provides immutability guarantees at multiple levels: interface design, storage implementation, and tests.
The EventStore interface is append-only by design - it provides no Update or Delete methods. JetStreamEventStore implements this with file-based storage and a limits-based retention policy that ensures events are immutable during their lifetime.
Changes
event.go: Enhanced EventStore interface documentation to explicitly document the immutability guarantee and explain the absence of Update/Delete methods
store/jetstream.go: Added detailed retention policy documentation showing how MaxAge and file-based storage enforce immutability at the storage layer
store/immutability_test.go: New test file with comprehensive immutability verification tests covering:
Event persistence cannot be modified after saving
No Update/Delete methods exist on the interface
Version enforcement ensures monotonic ordering
Events cannot be deleted through the API
README.md: Added detailed "Events are immutable" section explaining:
Interface-level append-only guarantee
Storage-level immutability mechanisms
Audit trail reliability guarantees
Pattern for handling corrections (append new event vs modify)
Testing
All immutability tests pass:
TestEventImmutability_MemoryStore
TestEventImmutability_NoUpdateMethod
TestEventImmutability_VersionOnlyGoesUp
TestEventImmutability_EventCannotBeDeleted
All existing tests continue to pass with no regressions.
## Summary
This PR completes issue #60 by documenting and verifying that the Aether event store provides immutability guarantees at multiple levels: interface design, storage implementation, and tests.
The EventStore interface is append-only by design - it provides no Update or Delete methods. JetStreamEventStore implements this with file-based storage and a limits-based retention policy that ensures events are immutable during their lifetime.
## Changes
- **event.go**: Enhanced EventStore interface documentation to explicitly document the immutability guarantee and explain the absence of Update/Delete methods
- **store/jetstream.go**: Added detailed retention policy documentation showing how MaxAge and file-based storage enforce immutability at the storage layer
- **store/immutability_test.go**: New test file with comprehensive immutability verification tests covering:
- Event persistence cannot be modified after saving
- No Update/Delete methods exist on the interface
- Version enforcement ensures monotonic ordering
- Events cannot be deleted through the API
- **README.md**: Added detailed "Events are immutable" section explaining:
- Interface-level append-only guarantee
- Storage-level immutability mechanisms
- Audit trail reliability guarantees
- Pattern for handling corrections (append new event vs modify)
## Testing
All immutability tests pass:
- TestEventImmutability_MemoryStore
- TestEventImmutability_NoUpdateMethod
- TestEventImmutability_VersionOnlyGoesUp
- TestEventImmutability_EventCannotBeDeleted
All existing tests continue to pass with no regressions.
Closes #60
Co-Authored-By: Claude Code <noreply@anthropic.com>
Document that EventStore interface has no Update/Delete methods, enforcing
append-only semantics by design. Events are immutable once persisted.
Changes:
- Update EventStore interface documentation in event.go to explicitly state
immutability guarantee and explain why Update/Delete methods are absent
- Add detailed retention policy documentation to JetStreamConfig showing
how MaxAge limits enforce automatic expiration without manual deletion
- Document JetStreamEventStore's immutability guarantee with storage-level
explanation of file-based storage and limits-based retention
- Add comprehensive immutability tests verifying:
- Events cannot be modified after persistence
- No Update or Delete methods exist on EventStore interface
- Versions are monotonically increasing
- Events cannot be deleted through the API
- Update README with detailed immutability section explaining:
- Interface-level append-only guarantee
- Storage-level immutability through JetStream configuration
- Audit trail reliability
- Pattern for handling corrections (append new event)
Closes#60
Co-Authored-By: Claude Code <noreply@anthropic.com>
store/memory.go:30-32 - Errors from json.Marshal and json.Unmarshal are silently discarded. While Event should always be JSON-marshallable, ignoring errors is bad practice and could mask future bugs if struct fields change.
Suggestions:
Handle the error from json.Marshal and return it or panic (depending on design intent)
Alternatively, use reflect-based copying to avoid JSON roundtrip and associated error handling
Add a comment explaining why JSON errors are considered impossible (if that's the design decision)
## Code Review: Changes Requested
**Issues:**
1. `store/memory.go:30-32` - Errors from json.Marshal and json.Unmarshal are silently discarded. While Event should always be JSON-marshallable, ignoring errors is bad practice and could mask future bugs if struct fields change.
**Suggestions:**
- Handle the error from json.Marshal and return it or panic (depending on design intent)
- Alternatively, use reflect-based copying to avoid JSON roundtrip and associated error handling
- Add a comment explaining why JSON errors are considered impossible (if that's the design decision)
Error handling for json.Marshal and json.Unmarshal properly implemented with appropriate panic behavior documented. All tests passing including new immutability verification tests.
## Code Review: Approved ✓
Error handling for json.Marshal and json.Unmarshal properly implemented with appropriate panic behavior documented. All tests passing including new immutability verification tests.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
This PR completes issue #60 by documenting and verifying that the Aether event store provides immutability guarantees at multiple levels: interface design, storage implementation, and tests.
The EventStore interface is append-only by design - it provides no Update or Delete methods. JetStreamEventStore implements this with file-based storage and a limits-based retention policy that ensures events are immutable during their lifetime.
Changes
Testing
All immutability tests pass:
All existing tests continue to pass with no regressions.
Closes #60
Co-Authored-By: Claude Code noreply@anthropic.com
Code Review: Changes Requested
Issues:
store/memory.go:30-32- Errors from json.Marshal and json.Unmarshal are silently discarded. While Event should always be JSON-marshallable, ignoring errors is bad practice and could mask future bugs if struct fields change.Suggestions:
Fixed review feedback
Code Review: Approved ✓
Error handling for json.Marshal and json.Unmarshal properly implemented with appropriate panic behavior documented. All tests passing including new immutability verification tests.
78aaea9330to6549125f3d