Repository navigation
Conversation
Design spec for replacing the per-surface implementations of the deck model (renderers, CSS, mutations, artifacts, theme, markdown, deck loading) with shared core/render/artifacts/ai packages consumed by thin hosts. Includes inventory of current duplication with file references, decision table, document + reducer design, six-phase migration plan, deletion estimates, testing strategy, and risks. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015B7qW78KqCz7p1Po2Q9bXE
szweibel
left a comment
There was a problem hiding this comment.
The consolidation direction is useful, but the proposed dual-write transition and retained fenced-parser/token-estimate fallbacks conflict with the current fleet direction. Please revise to one authoritative path and identify the real data-preservation boundary separately, without maintaining old/new writes in parallel. Coordinate mutation-log row/version semantics with #12 before implementation. Current CI proves the unchanged app builds; it does not validate this proposed architecture.
Address the review on PR #11: - Remove the dual-write transition. Phase 1 keeps the normalized tables as the only store and writes them through the reducer; Phase 2 is the single data-preservation boundary, with a frozen API, a verified round trip for every deck before any write, a file backup, and a one-release-cycle rollback before the tables are dropped. - Delete the fenced-JSON parser and the chars/4 token estimate at Phase 5 instead of keeping them as fallbacks; models without function calling are dropped from the model list rather than given a second parser. - Align commit and version semantics with the companion design: one log row per committed batch, keyed by (deck_id, version), version incremented once per commit, propose mode writes nothing. - State the review scope: CI proves the unchanged app builds and does not validate the proposed architecture. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015B7qW78KqCz7p1Po2Q9bXE
Address the review on PR #12: - SSRF guard: node:dns lookup throws "Not implemented" on Workers; the guard is rewritten on resolve4/resolve6 with the same private-range policy and rebinding re-check, and the residual time-of-check gap is stated honestly (new section 2.10). - Rate Limiting bindings are per-location and approximate, not a global hard limit; they are now throttles only, and every limit that must be exact is listed with the strongly consistent store that enforces it. - DeckRoom log uses the commit-per-batch version semantics of PR #11 (one row per batch, version incremented once per commit), replacing the per-mutation version primary key. - Administrator authorization comes from admission's AdmissionResolver over a service binding, replacing the local admin-subject list; if admission declines the binding the app has no admin surface. - State the review scope: not approval for account migration, infrastructure changes, or deployment; each phase names what it needs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015B7qW78KqCz7p1Po2Q9bXE
|
Revised in 7519049 to address the review:
Generated by Claude Code |
szweibel
left a comment
There was a problem hiding this comment.
Reviewed the revision at 7519049. The dual-write transition and retained fenced-parser/token-estimate fallbacks are removed, and the data-preservation boundary now names the freeze, round-trip verification, backup and rollback. Those address the corresponding earlier findings.
One migration contradiction remains, noted inline: Phase 1 already records a commit at the current version, while Phase 2 inserts system:import at that same primary key. Please preserve the existing history and define a checkpoint/import operation consistent with the shared version contract. Also make the single-writer/freeze boundary explicit for the retained legacy endpoints; moving the current frontend off them does not prevent an old client from writing.
These are design-review findings. I inspected the revised document and its prior-review changes; the green application CI does not validate the migration. The next step is a document revision by the proposal author, followed by our review of these preservation boundaries.
| This is the one step that changes where deck data lives. It runs once, with the API frozen, with a verified round trip before any write and a file-level rollback after, instead of a period in which two representations are kept in sync. | ||
| - **Freeze.** The mutations endpoint returns `503` with `retry-after` for the duration; the SQLite file is copied to `/data/slide-maker-storage/db/backups/<timestamp>.db`. Exports and reads keep working. | ||
| - **Verify.** For every deck: build `DeckDocument` from the rows with the Phase 1 `loadDeck`, project it back to rows with the Phase 1 writer, and assert deep equality with the original rows (ids, order, zone, `data`, `stepOrder`, `splitRatio`, `title`, `notes`, `metadata`). One failing deck stops the migration with nothing written; the failure is fixed in the loader or the writer, and the script is rerun from the start. | ||
| - **Write.** `decks.document` and one `system:import` commit row per deck, with `version` equal to the deck's current `decks.version` and `base_version` the same, in one transaction per deck. |
There was a problem hiding this comment.
[P1] Preserve existing commit history during document import. Phase 1 writes deck_commits and advances decks.version (line 192); the primary key is (deck_id, version) (line 137). For a deck edited during Phase 1, inserting this import row at the current version collides with its latest commit. Replacing that row would destroy history. Specify a separate checkpoint or a versioned import that preserves prior rows and follows the shared version contract.
Summary
Add a comprehensive architecture design document proposing a refactor to consolidate duplicated deck model implementations across the codebase into a single shared core consumed by thin hosts (editor, API, export).
Overview
This spec (
docs/superpowers/specs/2026-09-03-unified-architecture-design.md) addresses the current architectural debt where the same deck concerns (rendering, styling, mutations, artifacts, theming, markdown, loading) are implemented separately for each surface (canvas edit, canvas view, iframe preview, zip export, chat, planner).Key Sections
@slide-maker/corepackage (document schema, mutation reducer, inverses, validation) consumed by three hosts:@slide-maker/render— Pure Svelte 5 view components with SSR support@slide-maker/artifacts— 13 native factories with dual Vite build (ESM + IIFE)@slide-maker/ai— Provider adapters with generated tool schemadecks.documentJSON +deck_mutationslog) replacing normalizedslides/content_blockstables; singlePOST /api/decks/:id/mutationsendpoint replacing 14 REST endpointsmaindeployable; Phases 1–2 deliver atomic edits and correct undo/redo$libalias)Impact
TODO.mdas by-products (undo/redo hardening, mutation expansion, system prompt generation)$libimport limitation in vitest)Companion
#12 pairs this with the host decision: one Cloudflare Worker behind the lab's CUNY-login doorway, model access through the lab's model gateway, per-deck Durable Objects on top of the reducer proposed here. The two can be reviewed independently and land in order.
This is a proposal document for discussion and planning; no code changes are included.
https://claude.ai/code/session_015B7qW78KqCz7p1Po2Q9bXE