Skip to content

feat: hand back the colliding note, not just its id (0.7.3) - #44

Merged
vib795 merged 1 commit into
mainfrom
feat/collision-body
Aug 29, 2026
Merged

feat: hand back the colliding note, not just its id (0.7.3)#44
vib795 merged 1 commit into
mainfrom
feat/collision-body

Conversation

@vib795

@vib795 vib795 commented Aug 29, 2026

Copy link
Copy Markdown
Owner

The last piece of the capture pipeline, and the one that survived contact with brief.

The problem

A title collision reported the other note's id and stopped:

warning: title collision: session-auth reads the same as existing use-sessions;
         set contradicts or merge them

Deciding what to do with that — merge a duplicate, supersede a changed claim, or link a genuine contradiction — needs the other note's words. Getting them meant a second agent-memory get. On a biller that charges per prompt rather than per tool call, that is another request for something write already had in hand.

Now

created session-auth [decision]
warning: title collision: session-auth reads the same as existing use-sessions [decision] Chose server sessions over JWT
    Why: revocation had to take effect immediately.
    Rejected: short-TTL JWT, because logout would lag by the TTL.
    Implemented in src/auth/session.js:42, with the store in Postgres so a restart
    does not sign everyone out.
    -> update use-sessions by id, or set supersedes or contradicts on session-auth.

Fixed in the turn that found it. --json gains a collisions array with existing, existingType, existingTitle, existingArchived, excerpt, truncated.

One extra row is read, and only when a collision actually occurred — bodies are still not loaded for the whole store to describe the one that collided.

The excerpt is cut on a word or line boundary, for the same reason the digest sheds whole items rather than trimming characters: text that stops mid-word reads as corrupted. When clipped, it says where the rest is:

    ... agent-memory get long-note for the rest

Why this matters more than it looks

This is precisely what content-hash dedup cannot catch. compact merges notes whose content is identical; two notes making one claim in different words are not identical, only synonymous. No amount of later compaction repairs that — the moment to catch it is the write.

Not built, deliberately

write --dry-run was on the Tier 3 list. It would turn one call into two, and brief already answers "what is already here" before composing — the same question, asked earlier and cheaper. Adding it would have made the turn economics worse, not better.

Verification

  • 111 tests, up from 109 — two new, covering the returned body, the self-update case that must stay silent, and boundary clipping
  • skills/remember/SKILL.md updated: decide in this turn, do not run get for what you were handed
  • Zero dependencies; all versions synced to 0.7.3

🤖 Generated with Claude Code

https://claude.ai/code/session_014fSLBRUVVhAauWDuzJM4mc

The last piece of the capture pipeline, and the one that survived contact with
`brief`.

A title collision reported the other note's id and stopped there. Deciding what
to do with it — merge a duplicate, supersede a changed claim, or link a genuine
contradiction — needs that note's words, and getting them meant a second
`agent-memory get`. On a biller that charges per prompt rather than per tool
call, that is another request for something `write` already had in hand.

It now returns the existing note's type, title and a clipped body, so the fix
happens in the turn that found the problem. One extra row is read, and only when
a collision actually occurred; bodies are still not loaded for the whole store to
describe the one that collided.

The excerpt is cut on a word or line boundary, for the same reason the digest
sheds whole items rather than trimming characters: text that stops mid-word reads
as corrupted. When it is clipped it says where the rest is.

This is what content-hash dedup structurally cannot catch. `compact` merges notes
whose content is identical; two notes making one claim in different words are not
identical, only synonymous, and no amount of compaction repairs that later.

Not built, deliberately: `write --dry-run`. It would turn one call into two, and
`brief` already answers "what is already here" before composing — which is the
same question, asked earlier and cheaper.

111 tests, up from 109. Zero dependencies.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014fSLBRUVVhAauWDuzJM4mc
@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 37 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 485e302f-7719-4315-ae64-0c9074ca316f

📥 Commits

Reviewing files that changed from the base of the PR and between 7593c22 and 9a5229c.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (8)
  • .claude-plugin/marketplace.json
  • .claude-plugin/plugin.json
  • README.md
  • package.json
  • skills/remember/SKILL.md
  • src/cli.js
  • src/config.js
  • test/integration.test.js

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@vib795
vib795 merged commit 9b9bd59 into main Aug 29, 2026
13 checks passed
@vib795
vib795 deleted the feat/collision-body branch August 29, 2026 18:34
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.

1 participant