Skip to content

feat(scratchnode): import published event recap into NodeBench workspace (roadmap #3 slice 1)#494

Merged
HomenShum merged 2 commits into
mainfrom
feat/scratchnode-event-import
Jun 3, 2026
Merged

feat(scratchnode): import published event recap into NodeBench workspace (roadmap #3 slice 1)#494
HomenShum merged 2 commits into
mainfrom
feat/scratchnode-event-import

Conversation

@HomenShum
Copy link
Copy Markdown
Owner

What

Roadmap item #3, slice 1: import a published ScratchNode event wiki into NodeBench as one editable product document, under a fresh NodeBench-origin anonymous product identity (the founder decision: anon-preview → merge on sign-in). PUBLIC-DATA-ONLY — only the published wiki snapshot is read; private notes are never touched.

Founder identity decision, realized with zero new merge code

Import writes to the existing productDocuments / productDocumentBlocks / productDocumentSnapshots / productEntities tables under anon:<productSessionId>. Those tables are already in bootstrap.ts's PRODUCT_OWNED_TABLES, so the existing claimAnonymousProductWorkspace merge path re-owns the imported recap from anon:<sessionId>user:<id> on later sign-in. No bespoke owner-key merge was needed.

Changes

Backend

  • convex/events.tsgetPublishedWikiStructuredBySlug({ slug }) + shared reader loadStructuredPublishedWiki(ctx, slug). Returns the SAME published snapshot as getPublishedWikiBySlug, but structured ({ eventId, slug, eventName, roomCode, wikiVersion, answers:[{question,body}], sources:[{title,uri,excerpt}] }) so the importer builds editable blocks with no HTML round-trip. PUBLISHED-only; BOUND ≤ 20 answers / 20 sources. Purely additive (120 insertions, 0 deletions).
  • convex/domains/product/scratchnodeImport.ts (new) — importPublishedWiki({ slug, anonymousSessionId }) and getScratchnodeImportStatus({ slug, anonymousSessionId }). Creates one entity_memory document ("<eventName> — recap", Q&A + sources blocks) + the canonical event entity (entityType: "event", owner-private). Returns { ok, documentId, entitySlug, created, alreadyImported }. No fuzzy company/person extraction (deferred — avoids fabricated entities).

Frontend

  • src/features/redesign/surfaces/ScratchnodeEventsSurface.tsx — per-row "Import this recap into NodeBench" action, only shown when a published wiki exists, importing under the fresh product anon identity (getAnonymousProductSessionId, NOT the cross-domain sn_session_id), with real importing/done/error states and a link to /entity/<entitySlug>. The existing "Open in ScratchNode" CTA is unchanged.

Idempotency

  • Stable entity slug scratchnode-event-<hash(eventId)> maps every re-import of the same event to the same document.
  • Per-import key hash(eventId|wikiVersion|ownerKey) recorded on the import-event ledger: re-importing the same published version is a no-op (alreadyImported:true); a newer published version writes a fresh revision/snapshot on the same document (no duplicate).

Reliability (agentic_reliability 8-point)

BOUND (reads ≤ 25), HONEST_STATUS (ok:false, reason:"no_published_wiki" on draft/unpublished/unknown; throws on entity-create failure), BOUND_READ (dangling ids skipped, text capped), DETERMINISTIC (FNV-1a hash, stable block ids / slug / import key). No external fetch → SSRF/TIMEOUT N/A.

Privacy

PUBLIC-DATA-ONLY. The importer reads only the published wiki via loadStructuredPublishedWiki; it never reads or writes userNotes / liveEventNoteAnchors, and never writes under another user's owner key. A dedicated test asserts a private-note marker never reaches the imported document.

Verification

  • convex/domains/product/scratchnodeImport.test.ts11/11 convex-test scenarios green (happy import, idempotency no-dup, re-publish → new revision, unpublished/draft/unknown honest no-ops, privacy no-leak, status query, structured read).
  • Existing scratchnode.publicWiki + publicWikiRead suites still green (additive change).
  • npx tsc --noEmit --pretty false — clean (0 errors).
  • npm run build — clean.
  • npx convex codegen was NOT run (no deploy creds in this env); new function refs use (api as any) in tests/frontend, mirroring ScratchnodeEventsSurface.tsx, so tsc passes before CI codegen.

Notes / open questions

  • The task brief referenced a ScratchnodeWikiBridge.tsx + /events/:slug/wiki React route as the receiving surface; those don't exist on origin/main — the public wiki is served by api/scratchnode-wiki.js (static SSR HTML, no React, can't host an interactive button). The honest in-app home for the import action is ScratchnodeEventsSurface.tsx (/scratchnode-events), the real React surface with Convex hooks. Flagged for review.

🤖 Generated with Claude Code

@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
nodebench-ai Ready Ready Preview, Comment Jun 3, 2026 5:56pm

Request Review

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 3, 2026

PR size advisory

This PR adds 1314 lines of substantive change. CONTRIBUTING.md defines a soft limit of ~400 LOC.

If the PR is genuinely cohesive (e.g. an architecture map, a generated migration, a deletion of a dead module), no action is needed. Otherwise consider:

  • splitting into 2-3 PRs along independent concerns
  • pre-discussing the architecture change in a GitHub Discussion before merge

This is advisory — it does not block the merge.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 3, 2026

✅ Dogfood Visual QA Gate: PASSED

Check Status
Screenshots 23 captured (pass)
Walkthrough 9 chapters (pass)
Key Frames 9 extracted (pass)
Scribe Steps 8 how-to steps (pass)
Build success
Artifacts

Download the dogfood-evidence-7fc24fe artifact from the Actions tab for full screenshots, frames, and walkthrough video.


Generated by Dogfood QA Gate

@HomenShum HomenShum enabled auto-merge (squash) June 3, 2026 08:05
Roadmap #3, slice 1. Lets a visitor import a published ScratchNode event
wiki as ONE editable NodeBench product document under a fresh
NodeBench-origin anonymous product identity. On later sign-in the existing
bootstrap merge path (claimAnonymousProductWorkspace) re-owns it from
anon:<sessionId> to user:<id> — no bespoke merge code.

Backend:
- convex/events.ts: getPublishedWikiStructuredBySlug + shared reader
  loadStructuredPublishedWiki — the same published snapshot as
  getPublishedWikiBySlug, structured (answers + sources) for the importer.
  PUBLISHED-only; private notes excluded at publish time. BOUND ≤ 20/20.
- convex/domains/product/scratchnodeImport.ts (new):
  importPublishedWiki + getScratchnodeImportStatus. Reuses the existing
  productDocuments/Blocks/Snapshots primitives (no parallel doc system),
  creates the canonical event entity (entityType "event", owner-private),
  and is idempotent via a stable entity slug + hash(eventId|version|owner)
  import key (same version = no-op, newer version = new revision). Honest
  no-op on draft/unpublished/unknown. No fuzzy entity extraction (deferred).

Frontend:
- ScratchnodeEventsSurface.tsx: per-row "Import this recap into NodeBench"
  action, gated on a published wiki, importing under the fresh product anon
  identity (getAnonymousProductSessionId, not the cross-domain sn_session_id),
  with real importing/done/error states and a link to /entity/<entitySlug>.

Reliability: BOUND, HONEST_STATUS, BOUND_READ, DETERMINISTIC. PUBLIC-DATA-ONLY
— never reads or writes userNotes / private-note content.

Tests: 11 convex-test scenarios (happy import, idempotency, re-publish→new
revision, unpublished/draft/unknown no-ops, privacy no-leak, status query,
structured read). 11/11 green; tsc --noEmit clean; npm run build clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@HomenShum HomenShum merged commit 06ee660 into main Jun 3, 2026
17 checks passed
@HomenShum HomenShum deleted the feat/scratchnode-event-import branch June 3, 2026 18:07
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 3, 2026

Demo: walkthrough of the surfaces this PR changed is available as a workflow artifact (pr-demo-494) at https://github.com/HomenShum/nodebench-ai/actions/runs/26903736501

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.

2 participants