Settles the `4.2c planning gate — Reversals leave link rows and delete payloads out of step with the log` followup in a design session. Docs only; the implementation is a new followup, a standalone PR before 4.2c's merge. ## What was wrong (reproduced on `main` after #567) - **Dangling links.** CTRL-Z of a user-created character leaves the pass's involvement, awareness and relationship rows naming her. CTRL-Z, regenerate and rollback run no closure, and where a closure ran it followed only a happening's links. - **Rows back with no history.** A reversal of a write to a row held only in a delete's `undo_payload` touched nothing, was pruned, and the payload kept the stale copy. Undoing the delete then restored a relationship, an awareness row, or the deleted happening itself with no delta. Reproduced through abort and through a prose edit's sweep. ## The contract - **Every reversal closes over the rows its creates delete, and the rows naming them**, on every path, through one reference registry (link tables and translations), live or held in a payload. Reference removal beats `rowKeepingColumns`; a fact taken by reference loses its survival-anchor shield. - **A reversal applies to a row a delete holds:** a create's undo strips it from the payload, or prunes the delete when it was the target; an update's undo patches the payload copy. Captured facts follow live ones: swept with the prose, re-derived when it returns. Accepted cost: a pass running between undoing the edit and undoing the delete loses links naming the still-deleted row. - **Two integrity refusals**, both unreachable today: pruning a delete whose group would write the removed id back (entity deletes), and a captured row in a CTRL-Z redo snapshot. - **Redo** restores the closure's rows; a sweep's rows stay re-derived. - **No-gate write phase:** a periodic pass's writes hold a per-branch write lock exclusively, so no other write can interleave with the burst. ## Files - `generation-pipeline.md` → Reverse-replay (rewritten closure paragraphs, new payload and refusal paragraphs, sketch), Concurrency model (new `### No-gate write phase`). - `data-model.md` → Entry mutability & rollback, Survival anchor, Branch model (fork), Translation. - `memory/cadence.md`, `memory/classifier.md`, `rollback-confirm.md`, `roadmap.md` (M6.1), `02c-collision-review.md` (merge question, History refresh input). - `followups.md`: the gate entry replaced by the implementation entry. - Record: `docs/explorations/2026-10-04-reversal-integrity.md` (probes, decisions, rejected options, adversarial pass). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|---|---|---|
| .agents/skills | ||
| .claude | ||
| .github | ||
| .storybook | ||
| app | ||
| assets/images | ||
| bench | ||
| components | ||
| constants | ||
| docs | ||
| e2e | ||
| electron | ||
| hooks | ||
| lib | ||
| locales/en | ||
| patches | ||
| scripts | ||
| types | ||
| .coderabbit.yaml | ||
| .editorconfig | ||
| .gitattributes | ||
| .gitignore | ||
| .mcp.json | ||
| .npmrc | ||
| .nvmrc | ||
| .prettierignore | ||
| .prettierrc.json | ||
| .remarkignore | ||
| AGENTS.md | ||
| app.json | ||
| babel.config.js | ||
| CLAUDE.md | ||
| components.json | ||
| drizzle.config.ts | ||
| drizzle.studio.config.ts | ||
| eslint.config.js | ||
| global.css | ||
| lefthook.yml | ||
| LICENSE.md | ||
| metro.config.js | ||
| nativewind-env.d.ts | ||
| package.json | ||
| playwright.config.ts | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| postcss.config.js | ||
| README.md | ||
| tailwind.config.js | ||
| tsconfig.json | ||
| vite.config.ts | ||
| vitest.config.ts | ||
| vitest.setup.ts | ||
| vitest.shims.d.ts | ||
Aventuras
An AI-collaborative writing app. You write fiction with an AI co-author against backed by an advanced memory system that ensures characters, locations, items, factions, lore, plot threads, and event history are all tracked as the story unfolds. Branch the narrative freely. Roll back any change. All data lives on your machine.
Cross-platform via a single Expo app: mobile (iOS / Android) through Expo Go, desktop (Linux / macOS / Windows) through Electron wrapping the web build. No accounts, no cloud, no environment variables; everything in local database file.
Note on history. The previous iteration of this project lives on the
legacy/masterbranch. Themainbranch is a ground-up rewrite taking lessons learned. Same idea, different architecture. Old issues, branches, and history remain reachable vialegacy/master.
Status
Pre-implementation. The project is in the design + foundation phase:
- Domain, schema, architecture, and UI surfaces are
comprehensively specified in
docs/. - Tooling is wired (Expo, Electron, Storybook, ESLint, Prettier, remark, lefthook, Vitest, Playwright story tests, CI).
- A handful of design-system primitives have been scaffolded
(
components/ui/*with Storybook stories). - The writing-app domain itself, stories, entries, the classifier pipeline, world-state retrieval, the AI collaborator, has not yet been built.
This README describes the project's intent. Documentation describes the design. Code-following-design lands incrementally.
Documentation
The substance of the project today is the design corpus. Start here:
docs/README.mdindex of all documentation.docs/architecture.mdpipeline, generation context, retrieval, translation. How the code will be organized.docs/data-model.mdschema decisions: stories, branches, entries, entities, lore, threads, happenings, chapters, delta log.docs/ui/UI design: principles, cross-cutting patterns, and per-screen wireframes (interactive HTML + companion.mdrationale per surface).docs/tech-stack.mdfull stack with rationale.docs/followups.mdopen design questions (current milestone).docs/explorations/dated session records of design decisions.
Stack
- Runtime: Expo SDK 55, React 19, React Native 0.83, React Native Web, Electron 41.
- Styling: NativeWind 4 + Tailwind 3 with shadcn-style theme CSS variables.
- Storage:
expo-sqlite(no external backend). - Build / dev: pnpm 10, Node 24, Vite (via Storybook), TypeScript.
- Quality: ESLint 9, Prettier 3, remark (doc lint), lefthook (pre-commit hooks), Vitest + Playwright (story tests).
Full rationale in docs/tech-stack.md.
Repository layout
.
├── app/ Expo Router routes (mobile + web)
├── electron/ Electron main + preload (desktop shell)
├── components/ Shared UI components (RN + RN Web)
│ └── ui/ Design-system primitives + Storybook stories
├── lib/ hooks/ types/ constants/
├── docs/ Project documentation (the canonical spec)
│ ├── ui/ UI principles, patterns, per-screen designs
│ ├── explorations/ Dated design-session records
│ └── followups.md / parked.md
├── scripts/ Repository scripts
├── .storybook/ Storybook config
├── .github/ CI workflows
└── .claude/ Claude-Code-specific tooling (rules, skills)
Development
Requires Node 24 and pnpm 10 (both pinned via .nvmrc and
packageManager).
pnpm install
Doc tooling
pnpm lint:docs # remark over docs/
Wireframes are static HTML colocated with each screen's .md
under docs/ui/screens/<screen>/. Open the .html directly in a
browser.
Storybook (design-system primitives)
pnpm storybook # http://localhost:6006
Runs the active design-system catalog. Stories under
components/ui/*.stories.tsx.
Web / mobile (Expo)
pnpm web # web build via Expo
pnpm android # Android emulator
pnpm ios # iOS simulator
The app shell is currently the default Expo scaffold, domain implementation hasn't started. These commands work but won't show the writing app itself.
Desktop (Electron)
pnpm desktop # web build + Electron, hot-reloaded
Quality
pnpm lint # ESLint
pnpm format:check # Prettier
pnpm typecheck # tsc --noEmit
pnpm test # Vitest watch
pnpm test:run # Vitest single-run + Playwright story tests
CI runs all of the above on every push / PR.
Workflow
- Pre-commit hooks (
lefthook.yml) run prettier + eslint + remark in parallel on staged files. Don't bypass with--no-verify. - Commits are small and focused. Multiple commits beat a single omnibus commit when the work is logically separable.
- File moves use
git mvto preserve history; inbound references update in the same commit.
Project-specific Claude-Code rules live under
.claude/ (skills + topic-scoped rules that
auto-load when relevant files are read).