Skip to content

Give a source's default layer an id derived from the source - #19

Draft
ewraj wants to merge 1 commit into
mainfrom
fix/deterministic-default-layer
Draft

ewraj wants to merge 1 commit into
mainfrom
fix/deterministic-default-layer

Conversation

@ewraj

@ewraj ewraj commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Foundation fix F6 from PHASE_6_OVERVIEW.md (#17).

The bug

ensureDefaultLayer creates a "Notes" layer with crypto.randomUUID() for any source that has no layers. Every device that opens the same source therefore creates its own default layer. Once one person's work from two devices meets, through an imported .annotatecode file soon and sync later, they get two "Notes" layers with their annotations split between them.

The fix

New default layers get the id ${sourceId}::layer:default (defaultLayerId). The same source on any device arrives at the same layer by construction.

Existing layers are untouched. ensureDefaultLayer still returns the first existing layer whenever there is one, and a layer that already exists keeps its id, because every annotation in it points to that id. No migration is needed.

Tested

New src/ink/store.test.ts, using fake-indexeddb:

  • A new default layer gets the derived id.
  • Two "devices" (the database wiped in between) get the same id.
  • Different sources get different ids.
  • An existing layer with a random id is returned unchanged and nothing else is written.
  • Two concurrent calls still create exactly one layer.

npm run typecheck, npm test (271 tests), npm run build and npm run test:e2e (29 tests, Chromium) all pass locally.

🤖 Generated with Claude Code

Every device that opens a source with no layers creates a "Notes" layer, and
each one got a random id. Once the same work meets itself, through an
imported file today or sync later, that becomes two "Notes" layers with the
annotations split between them. Deriving the id from the source makes the two
layers one by construction.

Only new default layers get the derived id. An existing layer keeps its id,
because every annotation in it points there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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