Skip to content

FE-544: Turn tree schema and API#13

Merged
lunelson merged 9 commits into
mainfrom
ln/fe-544-turn-tree-schema
Apr 2, 2026
Merged

FE-544: Turn tree schema and API#13
lunelson merged 9 commits into
mainfrom
ln/fe-544-turn-tree-schema

Conversation

@lunelson
Copy link
Copy Markdown
Contributor

@lunelson lunelson commented Apr 1, 2026

chore: align Linear issues with PLAN.md slices

feat: migrate from flat message table to turn-tree schema

Replace the message table with the full schema.dbml entity model (13 tables:
project, turn, option, decision, assumption, requirement, criterion + 6 join
tables). Project gains active_turn_id as HEAD pointer. POST /api/chat creates
turns with parent chain and advances HEAD. GET /api/projects/current returns
turns on the active path via recursive CTE. Client hydrates useChat from turns.

Integer autoincrement PKs replace TEXT UUIDs. Entity/join tables beyond
turn/option are created but unpopulated until later slices.

39 tests passing (18 db + 9 app + 12 sse-adapter).

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

docs: record transitional turn-field mapping and integer PK decisions

Add D15 (transitional turn-field inversion — answer=user, question=agent
during pre-structured-interview phase) and D16 (integer autoincrement PKs
replace TEXT UUIDs). Both surfaced during slice 3 build.

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

@linear
Copy link
Copy Markdown

linear Bot commented Apr 1, 2026

FE-544 Turn tree schema + API

project_snapshot table. Auto-snapshot at phase transitions. Manual snapshot button. Restore from previous. Client-side diff view.

@lunelson lunelson changed the title chore: align Linear issues with PLAN.md slices FE-544: Turn tree schema and API Apr 1, 2026
Copy link
Copy Markdown
Contributor Author

lunelson commented Apr 1, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@lunelson lunelson marked this pull request as ready for review April 1, 2026 12:39
@augmentcode
Copy link
Copy Markdown

augmentcode Bot commented Apr 1, 2026

🤖 Augment PR Summary

Summary: This PR migrates Brunch’s persistence layer from a flat message log to a turn-tree schema and updates the API/client hydration to follow the project’s active-path HEAD model.

Changes:

  • Introduces a 13-table SQLite schema (project, turn, option, decision, assumption, requirement, criterion + join tables) with integer autoincrement IDs.
  • Adds project.active_turn_id as a HEAD pointer and implements active-path retrieval via a recursive CTE.
  • Updates POST /api/chat to create a turn row, stream the assistant response, then persist it onto the turn and advance HEAD.
  • Updates GET /api/projects/current to return turns (active path) instead of messages.
  • Updates the React client to hydrate useChat from turns (mapping turn.answer→user, turn.question→assistant per the transitional inversion).
  • Reworks server/db tests to validate turn CRUD, option constraints, HEAD advancement, and active-path resolution (including fork scenarios).
  • Expands planning/spec docs (PLAN/SPEC) and adds new agent skills docs for cmux/cdp-based manual verification workflows.

Technical Notes: Active-path resolution is performed in SQLite using a recursive query from active_turn_id back through parent_turn_id, and the server now persists turn records rather than role-tagged message rows.

🤖 Was this summary useful? React with 👍 or 👎

Copy link
Copy Markdown

@augmentcode augmentcode Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 3 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

Comment thread src/server/db.ts
id TEXT PRIMARY KEY,
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
active_turn_id INTEGER,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

project.active_turn_id isn’t declared as a foreign key, and SQLite won’t enforce any REFERENCES constraints unless PRAGMA foreign_keys=ON is set, so HEAD/parent pointers can silently become invalid and break getActivePath() semantics.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Comment thread src/server/db.ts

return db.prepare(`
WITH RECURSIVE path AS (
SELECT * FROM turn WHERE id = ?
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getActivePath()’s recursive CTE doesn’t constrain by project_id, so if a parent_turn_id chain ever crosses projects (which the current schema allows), this can traverse into another project’s turns and leak history.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Comment thread src/server/app.ts
saveMessage(db, project.id, 'assistant', assistantText);
updateTurn(db, turn.id, { question: assistantText });
}
advanceHead(db, project.id, turn.id);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the error path, assistantText stays empty but advanceHead() still runs, leaving HEAD pointing at a turn with question=''; subsequent formatHistory() will omit the assistant side of that exchange and degrade prompt context.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Copy link
Copy Markdown
Contributor Author

lunelson commented Apr 2, 2026

Merge activity

  • Apr 2, 6:20 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Apr 2, 6:23 AM UTC: Graphite rebased this pull request as part of a merge.
  • Apr 2, 6:24 AM UTC: @lunelson merged this pull request with Graphite.

@lunelson lunelson changed the base branch from ln/fe-535-sqlite-persistence to graphite-base/13 April 2, 2026 06:21
@lunelson lunelson changed the base branch from graphite-base/13 to main April 2, 2026 06:22
lunelson and others added 9 commits April 2, 2026 06:23
Replace the message table with the full schema.dbml entity model (13 tables:
project, turn, option, decision, assumption, requirement, criterion + 6 join
tables). Project gains active_turn_id as HEAD pointer. POST /api/chat creates
turns with parent chain and advances HEAD. GET /api/projects/current returns
turns on the active path via recursive CTE. Client hydrates useChat from turns.

Integer autoincrement PKs replace TEXT UUIDs. Entity/join tables beyond
turn/option are created but unpopulated until later slices.

39 tests passing (18 db + 9 app + 12 sse-adapter).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add D15 (transitional turn-field inversion — answer=user, question=agent
during pre-structured-interview phase) and D16 (integer autoincrement PKs
replace TEXT UUIDs). Both surfaced during slice 3 build.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fully superseded by docs/design/schema.dbml (entity model) and
memory/SPEC.md (domain semantics, decisions, lexicon).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Grill session findings added to SPEC.md:
- D17: two invalidation mechanisms (path exclusion + flag propagation)
- D18: Drizzle ORM replaces raw DDL (single source of truth)
- D19: layered architecture with DomainEvent streaming (core → adapters)
- D20: CLI executable with subcommands
- A18/A19: Drizzle migrations and AsyncIterable assumptions
- Lexicon: branch, checkout, path exclusion, flag propagation, core,
  domain event; soft invalidation updated
- Architecture section rewritten for db → core → adapters layering
- Constraint updated: "no automatic deletion cascading" replaces
  "no belief invalidation cascading"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Maps 3 places (project list, interview workspace, export preview),
UI affordances per place, 20 API routes grouped by concern, data
stores, and 5 key wiring flows (page load, interview turn, decision
revisit, assumption falsification, phase transition).

Identifies 5 candidate slices and 3 open uncertainties for ln-plan.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Type-safe routing with route loaders for data fetching on navigation.
Three MVP routes per breadboard: project list, interview workspace,
export preview.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Major re-plan incorporating grill + breadboard findings:
- Phase 2 gains 3c (Drizzle + core extraction) and 3d (multi-project
  routing with TanStack Router) as architecture infrastructure
- Phase 5 restructured: 11 (branch+checkout), 12 (entity lifecycle API
  with flag propagation), 13 (export)
- Horizon updated: CLI interview, MCP adapter, graph visualizations
- Dependencies and parallelism updated for new slice topology
- Breadboard cross-references added to UI-touching slices

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add .agents/skills/cli-cdp/ and .agents/skills/cli-cmux/ skill defs
- Update AGENTS.md manual testing section: cli-cmux for terminal panes
  only (not browser), cli-cdp for Chrome DevTools interaction
- Include design scratch docs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@lunelson lunelson force-pushed the ln/fe-544-turn-tree-schema branch from ea42210 to 95d8dd0 Compare April 2, 2026 06:23
@lunelson lunelson merged commit afe51ce into main Apr 2, 2026
1 check passed
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