fix(auto-extract): generate UUID before INSERT β NOT NULL constraint (v4.12.5)#37
Merged
FRIDAY-Drakon merged 1 commit intomainfrom Apr 25, 2026
Merged
Conversation
v4.12.4 unblocked the read side of auto-extract (path-encoding fix),
exposing a second silent failure on the write side. Both
pre-compact-hook.mjs and session-end-hook.mjs built INSERT statements
that omitted the `uuid` column. The schema declares
`uuid TEXT NOT NULL UNIQUE` with no default, so every insert errored
out β silently from the user's perspective:
[auto-extract] Read 4 messages from session JSONL (5186 chars)
[auto-extract] Failed to save "Decision: X, fix Y, prefer Z":
NOT NULL constraint failed: memories.uuid
[shieldcortex] Pre-compact complete: 0 memories auto-extracted
Reproduced on TARS 2026-04-25 immediately after upgrading to v4.12.4.
Fix:
- New `scripts/lib/save-memory.mjs` β single source of truth for
hook-side memory writes. Generates `crypto.randomUUID()` and binds
it to the INSERT.
- pre-compact-hook.mjs and session-end-hook.mjs delegate via thin
wrappers, so they can no longer drift apart and produce
"one hook works, the other silently fails" bugs.
5 new tests in src/__tests__/save-auto-extracted-memory.test.ts wire
a fresh SQLite DB against the real schema and assert:
- Insert lands with a valid UUID (the v4.12.4 bug repro)
- 5 inserts β 5 unique UUIDs (UNIQUE constraint coverage)
- Multiple writes don't collide
- null project accepted (sessions without scoping)
- tags persisted as JSON-encoded text
Bumps to v4.12.5 across root pkg, plugin pkg, plugin manifest, lockfile.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
v4.12.4 unblocked the read side of auto-extract (path-encoding fix), exposing a second silent failure on the write side. Both `pre-compact-hook.mjs` and `session-end-hook.mjs` built INSERT statements that omitted the `uuid` column. The schema declares `uuid TEXT NOT NULL UNIQUE` with no default, so every insert errored out β silently from the user's perspective.
Reproduction (TARS 2026-04-25)
```text
[auto-extract] Read 4 messages from session JSONL (5186 chars)
[auto-extract] Failed to save "Decision: X, fix Y, prefer Z":
NOT NULL constraint failed: memories.uuid
[shieldcortex] Pre-compact complete: 0 memories auto-extracted
```
`shieldcortex status` still showed 0 memories despite the read side working perfectly.
Fix
Tests
5 new in `src/tests/save-auto-extracted-memory.test.ts` against a fresh SQLite DB built from the real `src/database/schema.sql`:
42/42 release-track tests green.
Verification on a fleet host after v4.12.5
```bash
npm install -g shieldcortex@4.12.5
echo '{"session_id":"x","cwd":"/home/$USER/.openclaw/workspace"}' | shieldcortex hook pre-compact
shieldcortex status # Memories > 0, Last activity recent
```
Why it matters
Second silent zero-memory bug in 24 hours. v4.12.4 closed the path side; v4.12.5 closes the write side. Both shipped because the original auto-extract path had no end-to-end test exercising the actual SQLite schema. The new shared `save-memory.mjs` lib gives every hook one tested write path so the next bug in this area can't hide in two places.
π€ Generated with Claude Code