fix: remember_event atomicity + dead code cleanup (post-porting review)#4
Merged
fix: remember_event atomicity + dead code cleanup (post-porting review)#4
Conversation
Previously, CreateEvent wrote the event row directly on *sql.DB before the observation-loop transaction was opened. Any DB error during the loop (SQLITE_BUSY, FK violation, disk full) left an orphan event row with zero attached observations. CreateEvent now accepts the dbtx interface (already implemented by *sql.DB and *sql.Tx). The remember_event handler opens a single transaction for both the event insert and the observation loop; rollback on any error discards the whole unit. Proof: TestRememberEventAtomicityOnMidLoopFailure installs a BEFORE INSERT trigger on entities that RAISE(ABORT) on a sentinel value. Pre-fix this test reported "before=0 after=1 (orphan event row left behind)"; post-fix it passes. Invariant added to OPERATIONS.md. Addresses Diana review finding R4 on commit 8dddddf.
- scanEntityRecord (events.go): defined but never called. Sat next to live scanEventRecord / scanEntityObservation helpers, implying a code path that does not exist. Go silently accepts unreferenced package-level functions, so this survived compilation. - EventTypeFilter (tools.go ToolArgs): declared but never read. The recall_events handler correctly uses args.EventType. A caller passing event_type_filter in JSON got no error and no filter — silent no-op contract drift. Both eliminations. The existing EventType field already covers the recall_events filter surface; wiring EventTypeFilter in parallel would have been fake symmetry. Addresses Diana review findings R1 and R2 on commit 8dddddf.
There was a problem hiding this comment.
Pull request overview
Improves correctness of remember_event by ensuring event creation and observation attachments commit atomically, while also removing unused/dead code surfaced during post-port review.
Changes:
- Wrap
remember_eventevent insert + observation attachment loop in a single transaction to prevent orphan event rows on mid-loop failure. - Refactor
CreateEventto accept a transaction-capable interface (dbtx) and remove unusedscanEntityRecord. - Add a regression test proving rollback behavior on injected mid-loop failure; document the invariant in
OPERATIONS.md.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| internal/store/tools.go | Makes remember_event transactional end-to-end; removes unused EventTypeFilter arg field. |
| internal/store/parity_test.go | Adds TestRememberEventAtomicityOnMidLoopFailure to prevent orphan events/entities on failures. |
| internal/store/events.go | Updates CreateEvent to accept dbtx; removes dead scanEntityRecord. |
| OPERATIONS.md | Documents the remember_event atomicity invariant with a concrete test reference. |
Diana's R3 finding flagged the absence of a proof against Kilo or another real external client. It was archaeology by the time it reached review: the binary at /Users/zenosartori/workmem/workmem has been wired as the MCP server backing Claude Code's memory and private_memory entries (via ~/.claude.json + governor env files), and is also live in Kilo and Codex. The review session itself exercised the binary through real tool calls (remember_batch, recall_entity) with correct results. Removing the stale P1 entry from OPERATIONS.md.
marlian
added a commit
that referenced
this pull request
Apr 14, 2026
- docs/TELEMETRY.md: full user-facing guide. Adapted from the Node telemetry.md, with privacy-strict mode documented (trade-off: ranking debug vs plaintext leak risk on sensitive backends). Includes example client config for Claude Code / governor env-file wiring. - OPERATIONS.md invariants: telemetry is opt-in and never affects the success path; DB is physically separate from memory DB; strict mode sha256-hashes identifiers before disk. P1 "telemetry deferred" entry removed (condition met). P2 telemetry-schema entry removed (designed and implemented). Pre-Launch TODO no longer lists Kilo proof — already closed in PR #4. - IMPLEMENTATION.md: new Step 3.4 Telemetry marked done with explicit Gate — enabled writes rows, disabled creates no DB, strict hashes. - DECISION_LOG.md: append entry documenting the three Go-native refinements (nil-tolerant Client, no globals, SearchMetrics tuple) and the new privacy-strict mode. Explicitly rejects at-rest encryption with keychain for this iteration as over-scope.
marlian
added a commit
that referenced
this pull request
Apr 14, 2026
- docs/TELEMETRY.md: full user-facing guide. Adapted from the Node telemetry.md, with privacy-strict mode documented (trade-off: ranking debug vs plaintext leak risk on sensitive backends). Includes example client config for Claude Code / governor env-file wiring. - OPERATIONS.md invariants: telemetry is opt-in and never affects the success path; DB is physically separate from memory DB; strict mode sha256-hashes identifiers before disk. P1 "telemetry deferred" entry removed (condition met). P2 telemetry-schema entry removed (designed and implemented). Pre-Launch TODO no longer lists Kilo proof — already closed in PR #4. - IMPLEMENTATION.md: new Step 3.4 Telemetry marked done with explicit Gate — enabled writes rows, disabled creates no DB, strict hashes. - DECISION_LOG.md: append entry documenting the three Go-native refinements (nil-tolerant Client, no globals, SearchMetrics tuple) and the new privacy-strict mode. Explicitly rejects at-rest encryption with keychain for this iteration as over-scope.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Addresses Diana post-porting review on
8dddddf(the Node→Go port that landed via PR #2). Findings:remember_event(state-concurrency).CreateEventwrote the event row on*sql.DBdirectly, before the observation-loop transaction opened. Any mid-loop DB error (SQLITE_BUSY, FK violation, disk full) left an orphan event row with zero attached observations. Fix:CreateEventnow acceptsdbtx; the handler opens a single transaction covering event insert + observation loop. Rollback discards the whole unit.scanEntityRecorddead code removed fromevents.go. Defined but never called.EventTypeFilterfield removed fromToolArgs. Declared but never read — silent no-op contract drift for any JSON caller passingevent_type_filter. The existingEventTypefield already servesrecall_events.~/.claude.json+governorenv files), Kilo, and Codex. Live tool calls (remember_batch,recall_entity) succeeded during this very review session. Removing the stale P1 entry fromOPERATIONS.md.Invariant added to
OPERATIONS.md:remember_eventmust be atomic — event row and all attached observations commit together or not at all.Test plan
TestRememberEventAtomicityOnMidLoopFailureinstalls aBEFORE INSERTtrigger onentitiesthatRAISE(ABORT)on a sentinel value. Pre-fix:before=0 after=1 (orphan event row left behind). Post-fix: passes.go test ./...suite green on darwin/arm64.Commits
fix: make remember_event atomic against mid-loop DB errorschore: remove dead code flagged by Diana reviewdocs: close R3 real-client debt — binary is already in production