Skip to content

One thought shared once, and cards that read as cards - #215

Merged
Parshkov merged 1 commit into
mainfrom
claude/one-thought-one-id
Sep 7, 2026
Merged

One thought shared once, and cards that read as cards#215
Parshkov merged 1 commit into
mainfrom
claude/one-thought-one-id

Conversation

@Parshkov

@Parshkov Parshkov commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Three things found on one screen, /thoughts.

The duplicate — and why the obvious fix is wrong

Not a rendering fault. Production really held two sessions with the same topic, prepared four seconds apart and shared thirteen seconds apart. Each raised its own standing-search alert against the same person, so the corpus, the alerts and every count on the home screen were wrong together.

There is a UNIQUE constraint on sessions.thought_id for exactly this, and it never fires — the id ends in secrets.token_hex(4).

But that randomness is not carelessness. The store never rebinds a thought_id, even after deletion (v0.1 tombstone policy), so a content-derived id would permanently bar someone from sharing again anything they had once withdrawn. I tried it, and it does. The test proving re-sharing still works is in this commit for the next person who has the same idea.

So the id stays unique per attempt — with the reason written beside it — and duplication is answered where it belongs: as a product question, against what is live now.

_refuse_a_live_duplicate compares the reasoning itself — over labels rather than node ids (an assistant may supply ids one time and not the next), unordered (arrival order is not the reasoning) — and refuses with a sentence naming the thought already here:

this reasoning is already shared and still looking ("AI dynamically creates antenna form"), as ses-… Nothing was duplicated.

Withdraw it and you can share it again. Another person may reason the same way freely.

The cards

Grid items stretched to the tallest card in the row, and .card__actions { margin-top: auto } pushed the footer to the bottom of that borrowed height — so a short thought showed its title floating in the middle of an empty card. align-items: start. Measured after: two cards, same top, heights 323 and 864.

The structure

Every idea was printed twice — as a chip, and again inside each relation it appears in — so a cause with three effects appeared four times and the card read as a heap.

Relations are now grouped under the idea they come from, which is how a person says it: this causes that, and that, and prevents the other. The cause takes the serif the page gives its titles, effects stay sans and quieter, a hairline separates the blocks. Ideas nobody linked are listed after so they do not vanish.

705 tests OK (1 skipped)   both gates pass, gold unedited

🤖 Generated with Claude Code

Three things found on one screen, /thoughts.

THE DUPLICATE. Not a rendering fault: production really held two sessions with
the same topic, prepared four seconds apart and shared thirteen seconds apart.
Each raised its own standing-search alert against the same person, so the
corpus, the alerts and every count on the home screen were wrong together, and
the page honestly showed the duplicate twice.

The conflict is subtler than it looks, and the obvious fix is wrong. There is
a UNIQUE constraint on `sessions.thought_id` that exists to prevent exactly
this, and it never fires, because the id ends in `secrets.token_hex(4)`. But
that randomness is not carelessness: the store never rebinds a `thought_id`,
even after deletion (v0.1 tombstone policy), so an id derived from the content
would permanently bar a person from sharing again anything they had once
withdrawn. I tried it and it does; the test that proves re-sharing still works
is in this commit for the next person who has the same idea.

So the id stays unique per attempt, with the reason written next to it, and
duplication is answered where it belongs -- as a product question, against
what is LIVE now. `_refuse_a_live_duplicate` compares the reasoning itself,
over labels rather than node ids (an assistant may supply ids one time and not
the next) and unordered (the order nodes arrive in is not the reasoning), and
refuses with a sentence that names the thought already here. Withdraw it and
you can share it again; another person may reason the same way freely.

THE CARDS. `.card-grid` items stretched to the tallest card in the row, and
`.card__actions { margin-top: auto }` then pushed the footer to the bottom of
that borrowed height -- so a short thought showed its title floating in the
middle of an empty card beside a long one. `align-items: start`. Measured
after: two cards, same top, heights 323 and 864.

THE STRUCTURE. Every idea was printed twice -- once as a chip and again inside
each relation it appears in -- so a cause with three effects appeared four
times and the card read as a heap. Relations are now grouped under the idea
they come from, which is also how a person says it: this causes that, and
that, and prevents the other. The cause takes the serif the page gives its
titles, the effects stay sans and quieter, and a hairline separates the
blocks, so a stack of chains no longer reads as one undifferentiated run.
Ideas nobody linked to anything are listed after, so they do not vanish.

705 tests OK, both gates pass with gold unedited.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Parshkov
Parshkov merged commit e81ce6d into main Sep 7, 2026
3 checks passed
@Parshkov
Parshkov deleted the claude/one-thought-one-id branch September 7, 2026 05:05
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