You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Audit the already-merged Yjs CRDT + Railway Hocuspocus realtime path (#59 / #60–#63). If the implementation is sound for production multi-tab use (Chase’s default: many agentnote.dev tabs open), enable the feature flags on Vercel production and fix Railway origin allowlist for www.agentnote.dev. If the audit finds blockers, do not enable — report and stop.
Why This Matters
Chase keeps multiple agentnote.dev tabs open by default. #73/#74 hardened the legacy whole-document PUT path against silent clobber, but the product goal is Notion-like streaming sync: edits on one tab appear on the other without LWW races. That stack is already built and the collab service is healthy; production simply never flipped the flags. Enabling without a proper audit risks body duplication, origin rejection, or one-way CRDT seeding surprises.
Vercel production currently has noNEXT_PUBLIC_AGENTNOTE_CRDT / NEXT_PUBLIC_AGENTNOTE_COLLAB_URL (verified via vercel env ls on linked cwhuh/memo project).
Chase lock (2026-08-05): audit → if OK enable flags. Hand to Opus. Prefer Notion-like realtime over staying on legacy forever. CRDT was previously deferred as follow-up; now authorized to turn on if audit passes.
Domain today: https://www.agentnote.dev (and memo.chasehuh.com → redirect). README still says collab allowlist is pinned to https://memo.chasehuh.com — must include agentnote.dev origins before enable, or WebSocket auth will fail closed.
Flag is effectively one-way per note: once a snapshot exists, legacy PUT body returns 409 { reason: "crdt_managed_body" }. Turning the flag off leaves those notes non-body-editable until doc rows are deleted (projected notes.body remains).
Desired Behavior
Audit report (issue comment or PR body) covering correctness, security, ops readiness, and explicit go/no-go.
If go: production flags set and a deploy that picks them up; Railway allowlist includes agentnote.dev; smoke proves two tabs stream the same note.
If no-go: flags remain unset; blockers listed with severity and suggested fix PRs.
Target production env (Vercel project memo / cwhuh/memo, Production)
# Must include the live site origin(s). Prefer explicit list:
AGENTNOTE_ALLOWED_ORIGINS=https://www.agentnote.dev,https://agentnote.dev,https://memo.chasehuh.com
DATABASE_URL + CLERK_SECRET_KEY must already match production Clerk (do not print secrets). Confirm they are set; do not rotate unless broken.
Vercel: project linked from /Users/huhchaewon/chase/memo/.vercel → prj_5vnO1SA0hDdvACA2Rn5vq8jTH0Ah (memo)
Railway project: chasehuh (workspace chasehuh), service agentnote-collab
Audit Checklist (must complete before enable)
A. Correctness
Seeding is exactly-once / advisory-locked; double-seed cannot duplicate body (tests + code path).
HTTP sync and Hocuspocus storemerge into one history (no second document lineage).
Projection to notes.body stays coherent for publish//p/…, titles, sidebar, revisions.
IME composition gate holds remote applies during Hangul composition.
Peer-tab BroadcastChannel doc-update + WS path do not fight (origins: remote/broadcast/network).
Legacy PUT correctly 409s once CRDT-managed; intentional Overwrite/Use server N/A on CRDT path (merge instead).
Existing notes (e.g. 0804.md / dsb-wbhi-aqa) seed from current notes.body without truncation.
B. Security / tenancy
Room auth: bad token / wrong user / alias id / missing note → fail closed before DB where designed.
Origin allowlist behavior understood; production origins for agentnote.dev included.
Clerk secret on collab matches production app Clerk instance.
C. Ops
Collab /health green; recent Railway deploy not crash-looping.
Compaction cron still configured (CRON_SECRET present on Vercel per earlier env ls).
README allowlist note updated if origins change.
Rollback: unsetting NEXT_PUBLIC_AGENTNOTE_COLLAB_URL falls back to HTTP CRDT poll; unsetting CRDT leaves already-seeded notes read-only for body — document this in the enable comment.
D. Tests
pnpm vitest run (or project test script) green on main after any fix commits.
Room-auth + persist merge tests still meaningful vs current code.
Implementation Notes (enable path)
Likely files (only if audit finds gaps)
README.md — update allowlisted production origins to agentnote.dev
services/collab/** — only if auth/origin/health bugs found
lib/crdt/** / components/agentnote-app.tsx — only if audit finds real bugs blocking enable
Ops steps (authorized for production)
Fresh clone of chasehuh/agentnote (not Cursor worktree under shared checkout if using gt; for this repo historical path is worktree/clone + gh pr — prefer gh here; notsumelabs/sume-com).
Run audit locally against main; write findings as issue comment.
If no-go: stop. Do not set Vercel flags.
If go:
Set Railway AGENTNOTE_ALLOWED_ORIGINS (redeploy collab if needed).
Trigger Vercel production redeploy so Next inlines the public env at build time (NEXT_PUBLIC_* require rebuild).
Smoke: two browser contexts / tabs on same note — type in A, see stream in B within ~100ms on WS path; confirm header not stuck Offline; confirm no legacy 409 clobber.
If small code/docs fixes are required for go: one PR, then enable after merge+deploy of that PR (order: fix → merge → flags → redeploy).
Authorization
Authorized: read production env names (not values dumps of secrets), set the two Vercel public flags, update Railway AGENTNOTE_ALLOWED_ORIGINS, trigger redeploy, read Railway health/logs (no secret printing).
Not authorized: DB destructive SQL on production notes, deleting note_doc_* rows, Clerk key rotation, changing DATABASE_URL, CRDT Phase 3 remote cursors/presence.
Edge Cases And Risks
One-way per note: once opened under CRDT, legacy PUT is refused. Rolling the flag back is not a clean undo for seeded notes.
After enable: signed-in two tabs on https://www.agentnote.dev, same note — concurrent type, Hangul IME composition while other tab types, reload mid-edit, offline→online flush if easy.
Confirm publish page still shows projected body for a CRDT-touched note.
Confirm legacy PUT against a seeded note returns crdt_managed_body (optional API check with session).
Suggested PR Scope
S if audit-only + env ops (maybe tiny README origin fix PR).
M if audit finds a real bug that must land before enable — fix PR first, then ops enable in the same Opus session after merge.
Stage boundary: Opus owns audit + (on go) flag enable + any required fix PR through merge for this agentnote task (Chase asked to turn the flag on). Report done with evidence; hard-refresh reminder for Chase.
Summary
Audit the already-merged Yjs CRDT + Railway Hocuspocus realtime path (#59 / #60–#63). If the implementation is sound for production multi-tab use (Chase’s default: many
agentnote.devtabs open), enable the feature flags on Vercel production and fix Railway origin allowlist forwww.agentnote.dev. If the audit finds blockers, do not enable — report and stop.Why This Matters
Chase keeps multiple
agentnote.devtabs open by default. #73/#74 hardened the legacy whole-document PUT path against silent clobber, but the product goal is Notion-like streaming sync: edits on one tab appear on the other without LWW races. That stack is already built and the collab service is healthy; production simply never flipped the flags. Enabling without a proper audit risks body duplication, origin rejection, or one-way CRDT seeding surprises.Conversation Context
0804.md(dsb-wbhi-aqa) — fix: stop 409-rebased stale buffers from silently clobbering newer note bodies (0804 wipe RCA) #73 fixed 409 token laundry; fix: stop row-stamped peer drafts from laundering stale buffers into a valid save token (post-#73 multi-tab clobber) #74 fixed post-fix: stop 409-rebased stale buffers from silently clobbering newer note bodies (0804 wipe RCA) #73 multi-tab draft laundering (broadcastDraftstamped list-rowupdated_at).GET https://agentnote-collab-production.up.railway.app/health→{"ok":true,"service":"agentnote-collab"}.NEXT_PUBLIC_AGENTNOTE_CRDT/NEXT_PUBLIC_AGENTNOTE_COLLAB_URL(verified viavercel env lson linkedcwhuh/memoproject).https://www.agentnote.dev(andmemo.chasehuh.com→ redirect). README still says collab allowlist is pinned tohttps://memo.chasehuh.com— must include agentnote.dev origins before enable, or WebSocket auth will fail closed.Current Behavior
baseUpdatedAtRef,base_fingerprint, conflict Overwrite/Use server).components/agentnote-app.tsx:CRDT_ENABLED = process.env.NEXT_PUBLIC_AGENTNOTE_CRDT === "1"COLLAB_URL = process.env.NEXT_PUBLIC_AGENTNOTE_COLLAB_URL?.trim() || nulluseNoteDoc({ noteId: activeId, collabUrl: COLLAB_URL, … }); editor bindsytext; legacy dirty/409 path short-circuits.GET/POST /api/notes/:id/doc(+ sync); tablesnote_doc_updates,note_doc_snapshotsviaensureSchema().services/collabHocuspocus; room = canonical note id; Clerk JWT + ownership; sharedlib/crdt/note-doc-store.tswith HTTP path.PUTbody returns409 { reason: "crdt_managed_body" }. Turning the flag off leaves those notes non-body-editable until doc rows are deleted (projectednotes.bodyremains).Desired Behavior
Target production env (Vercel project
memo/cwhuh/memo, Production)Target Railway collab env
# Must include the live site origin(s). Prefer explicit list: AGENTNOTE_ALLOWED_ORIGINS=https://www.agentnote.dev,https://agentnote.dev,https://memo.chasehuh.comDATABASE_URL+CLERK_SECRET_KEYmust already match production Clerk (do not print secrets). Confirm they are set; do not rotate unless broken.Source Of Truth
Internal
README.md— CRDT + Realtime sections (ops, one-way flag, compaction, IME, undo)components/agentnote-app.tsx— flag gates,useNoteDocwiringlib/crdt/*— doc store, transports, composition gate, local IndexedDBservices/collab/src/{index,env,room-auth}.ts— Hocuspocus auth/persistapp/api/notes/[id]/route.ts—crdt_managed_body409External / live checks
https://agentnote-collab-production.up.railway.app/healthhttps://www.agentnote.dev/Users/huhchaewon/chase/memo/.vercel→prj_5vnO1SA0hDdvACA2Rn5vq8jTH0Ah(memo)chasehuh(workspace chasehuh), serviceagentnote-collabAudit Checklist (must complete before enable)
A. Correctness
storemerge into one history (no second document lineage).notes.bodystays coherent for publish//p/…, titles, sidebar, revisions.doc-update+ WS path do not fight (origins: remote/broadcast/network).0804.md/dsb-wbhi-aqa) seed from currentnotes.bodywithout truncation.B. Security / tenancy
C. Ops
/healthgreen; recent Railway deploy not crash-looping.CRON_SECRETpresent on Vercel per earlier env ls).NEXT_PUBLIC_AGENTNOTE_COLLAB_URLfalls back to HTTP CRDT poll; unsetting CRDT leaves already-seeded notes read-only for body — document this in the enable comment.D. Tests
pnpm vitest run(or project test script) green onmainafter any fix commits.Implementation Notes (enable path)
Likely files (only if audit finds gaps)
README.md— update allowlisted production origins to agentnote.devservices/collab/**— only if auth/origin/health bugs foundlib/crdt/**/components/agentnote-app.tsx— only if audit finds real bugs blocking enableOps steps (authorized for production)
chasehuh/agentnote(not Cursor worktree under shared checkout if usinggt; for this repo historical path is worktree/clone +gh pr— preferghhere; notsumelabs/sume-com).main; write findings as issue comment.AGENTNOTE_ALLOWED_ORIGINS(redeploy collab if needed).vercel env add/ update Production:NEXT_PUBLIC_AGENTNOTE_CRDT=1NEXT_PUBLIC_AGENTNOTE_COLLAB_URL=wss://agentnote-collab-production.up.railway.appNEXT_PUBLIC_*require rebuild).Authorization
AGENTNOTE_ALLOWED_ORIGINS, trigger redeploy, read Railway health/logs (no secret printing).note_doc_*rows, Clerk key rotation, changingDATABASE_URL, CRDT Phase 3 remote cursors/presence.Edge Cases And Risks
Non-Goals
Acceptance Criteria
NEXT_PUBLIC_AGENTNOTE_CRDT=1and collab WSS URL; Vercel redeploy completed.https://www.agentnote.dev(and apex if used).QA Plan
pnpm vitest run(full or at leastlib/crdt+ collab unit tests).curl -sS https://agentnote-collab-production.up.railway.app/healthhttps://www.agentnote.dev, same note — concurrent type, Hangul IME composition while other tab types, reload mid-edit, offline→online flush if easy.crdt_managed_body(optional API check with session).Suggested PR Scope
Stage boundary: Opus owns audit + (on go) flag enable + any required fix PR through merge for this agentnote task (Chase asked to turn the flag on). Report done with evidence; hard-refresh reminder for Chase.