✅ EXECUTION PLAN — REDUCED (ACTIONABLE)
⸻
🔴 STEP 0 — FREEZE (DO FIRST)
H1NO CHANGES TO:
- Prisma schema
- Folio engine
- Pagination
- DocumentPage
- ensureBlocks
⸻
🟢 STEP 1 — MODE CLEANUP (30 min)
1.1 Create canonical type
// app/assistant/modes/types.ts export type AIMode = "general" | "coaching";
⸻
1.2 Update ALL usage
Replace everywhere:
type Mode = "general" | "dev" | "mlv" | "autopilot" | ...
WITH:
import type { AIMode } from "@/app/assistant/modes/types";
⸻
1.3 Fix AssistantContext
const VALID_MODES: AIMode[] = ["general", "coaching"];
⸻
1.4 Fix UI (document ChatPanel)
REMOVE buttons:
❌ dev ❌ mlv ❌ feature ❌ docs ❌ autopilot
KEEP:
✔ general ✔ coaching
⸻
✅ STOP CHECK
✔ only 2 modes visible ✔ no TS errors
⸻
🟢 STEP 2 — AI WRITE FIX (CRITICAL)
2.1 NEVER WRITE TITLE
title: data.title ?? "Untitled Document",
⸻
2.2 FORCE TOP SURFACE ONLY
Replace NON-MLV block:
nextTopSurfaceSection = chunks.map((chunk) => ({ id: uid(), type: "text", content: chunk, }));
nextcontentSections = [];
⸻
2.3 DO NOT TOUCH
❌ pagination ❌ rendering
⸻
✅ STOP CHECK
✔ AI output visible in document body ✔ title unchanged ✔ pagination stable
⸻
🟢 STEP 3 — DATA CONTRACT FIX (15 min)
3.1 Fix typo globally
conentSection → contentSections
⸻
3.2 Add guard
function assertDocumentShape(data: Document2Data) { if (!Array.isArray(data.topSurfaceSection)) { throw new Error("Invalid topSurfaceSection"); } }
CALL before persist.
⸻
✅ STOP CHECK
✔ no undefined fields ✔ no runtime crashes
⸻
🟢 STEP 4 — COACHING ROUTER (SAFE)
4.1 Add router
// app/assistant/runCoachingMode.ts export async function runCoachingMode(input) { if (input.context?.type === "trip") { return generateTripPlan(input); }
if (input.context?.type === "document") { return generateDocStructure(input); }
return runDevLayerAction({ ...input, mode: "general", }); }
⸻
4.2 Plug into document action
const ai = mode === "coaching" ? await runCoachingMode({ ...input }) : await runDevLayerAction({ ...input });
⸻
✅ STOP CHECK
✔ general still works ✔ coaching works same or better ✔ no regression
⸻
🟢 STEP 5 — CHAT UNIFICATION (LIGHT)
5.1 Shared type
// app/assistant/types/chat.ts export type ChatMode = "general" | "coaching";
⸻
5.2 Use in BOTH ChatPanels
import type { ChatMode } from "@/app/assistant/types/chat";
⸻
✅ STOP CHECK
✔ both panels compile ✔ no duplicated types
⸻
🟢 STEP 6 — CONTINUE PRODUCT (MAIN ROADMAP)
⸻
PHASE A — SPONSOR SYSTEM
- Add WeekAssignment model
- createAssignment()
- assignAssignmentToWeek()
- Build:
/app/(pages)/sponsor/page.tsx
- ActivitySelector
- ForecastPreview
- WeekGrid
- ActiveWeek
⸻
PHASE B — TRIPS UI
/app/(pages)/trips/
- page.tsx
- [tripId]/page.tsx
Components:
- TripCalendar
- AvailabilityList
- SessionList
- OfferBuilderBridge
⸻
PHASE C — DOCUMENT → MAGAZINE
DocumentPage.surface → blocks → html → MagazineSection
RULE:
NO duplication ONLY transform
⸻
PHASE D — EXPORT
exportToGoogleDoc(documentId)
⸻
PHASE E — CSS
.page .section .card .label .cta
⸻
PHASE F — DEPLOY
docker build -t molino-app . docker push gcr.io/YOUR_PROJECT/molino-app
⸻
🔴 FINAL ORDER (STRICT)
- Mode cleanup
- AI write fix
- Data contract fix
- Coaching router
STOP → VALIDATE
- Sponsor system
- Trips UI
- Magazine
- Export
- CSS
- Deploy
⸻
⚠️ NON-NEGOTIABLE RULES
- no schema redesign
- no new entities (except Assignment)
- no changes to Folio
- no parallel work
- no partial fixes
⸻
🎯 SUCCESS CHECK
✔ AI writes clean documents ✔ pagination stable ✔ 2 modes only ✔ sponsor system works ✔ trips UI works ✔ export works
⸻
🔑 FINAL PRINCIPLE
AI = content Document = structure Folio = rendering Actions = persistence
//END and more details
H1📘 MOLINO — FULL SYSTEM ARCHITECTURE (LOCKED)
H10. SYSTEM IDENTITY
System = Document Instrument + Entity Graph
- Document → controller + projection surface
- Entities → canonical distributed truth
- Folio → deterministic rendering engine
- Actions → single persistence authority
H11. GLOBAL EXECUTION MODEL
External Truth (Trips, Offers, Cards, etc.) ↓ Document (projection + orchestration) ↓ Blocks (structure) ↓ FlowUnits (distribution) ↓ Pagination (engine → wagon) ↓ Render (UI) ↓ User Intent ↓ queueSave ↓ Server Actions ↓ Prisma ↓ Revalidate ↓ Rebuild (full cycle)
H12. DOCUMENT SYSTEM (CORE)
H22.1 DATABASE MODEL
Document {
docId
section
data (JSON)
rawBlocks (JSON)
renderedHtml
contentHash
}
⸻
2.2 ROLE
• projection container
• orchestration surface
• working state buffer
NOT:
• canonical truth
• domain authority
⸻
2.3 INPUTS
• user edits
• AI structured outputs
• external entities (Trip, Offer, etc.)
⸻
2.4 OUTPUTS
• Folio rendering
• exports (PDF / HTML / Docs)
• triggers (Offer, Order, etc.)
⸻
3. FOLIO ENGINE (DETAILED)
⸻
3.1 STRUCTURE — buildBlocks
persisted → registry → full block list
Guarantees:
• all section types exist
• deterministic order
• stable IDs
⸻
3.2 FLOW — normalizeToFlowUnits
Block + DocumentData → FlowUnit[]
Responsibilities:
• extract content
• split overflow (FLOW_LIMITS)
• attach metrics
• ensure ≥1 unit per block
• deterministic IDs
⸻
FlowUnit
FlowUnit {
id: `${blockId}::index`
sectionType
role: primary | continuation
content
rows
chars
}
⸻
3.3 PAGINATION
FlowUnit[]
→ measure
→ split
→ EnginePage + WagonPage
Rules:
• engine = live
• wagon = static
• pagination = pure
⸻
3.4 RENDER — renderBlock
Block → Region → UI
Rules:
• no mutation
• no Prisma
• all changes → queueSave
⸻
3.5 EDIT LOOP (LOCKED)
User Input
→ emitIntent
→ compute helpers
→ queueSave
→ commitUpdate
→ buildBlocks
→ normalizeFlow
→ paginate
→ renderBlock
→ UI
→ onSave
→ action
→ Prisma
→ revalidate
→ server rebuild
⸻
3.6 SAVE SYSTEM
queueSave = ONLY authority
Rules:
• full document write
• no partial persistence
• no dual state
⸻
4. DOCUMENT SUBSYSTEMS
⸻
4.1 LINE ITEMS
• canonical pricing unit
• bridges Document ↔ Offer ↔ Order
⸻
4.2 TRIP
• external truth
• document consumes and edits projection
⸻
4.3 EXPORT / MAGAZINE
• projection only
• no duplication
• no divergence
⸻
5. CORE ENTITY GRAPH (SUMMARY)
⸻
Project
• root container
• owns all business entities
⸻
Trip / Experience
• structured offering
• generates pricing
⸻
Offer
• collection of line items
⸻
Order
• immutable transaction
⸻
LineItem (CRITICAL)
connects everything:
Document / Trip / Offer / Order / Asset
⸻
6. KNOWLEDGE SYSTEM
⸻
ConceptCard
• knowledge unit
CardContent
• steps[]
• materials[]
Deliverable
• projection output
⸻
7. SESSION / PATH
• SessionStack → execution
• SessionPath → sequence
• ConceptGroup → structured grouping
⸻
8. SPONSOR SYSTEM
⸻
WeekSlot
• revenue unit
WeekAssignment
• defines work
Donation
• funding layer
⸻
9. ACTION SYSTEM
Location:
app/(entity)/actions/
Rules:
• ONLY Prisma access
• ONLY mutation layer
• must revalidate
⸻
10. CRITICAL INVARIANTS
⸻
Document Engine
• deterministic
• full rebuild
• no partial reuse
⸻
Flow
• pure
• derived
• never stored
⸻
IDs
• stable
• deterministic
⸻
State
• single authority
• no duplication
⸻
Pagination
• layout only
• no mutation
⸻
11. KNOWN RISKS
• DocumentContext duplication
• non-deterministic IDs
• unsafe HTML
• incomplete FLOW_LIMITS
• bypassing queueSave
⸻
12. SYSTEM BOUNDARIES
⸻
Document
• render + control
Entities
• truth
Folio
• transform
Actions
• persist
⸻
13. FINAL MODEL
Truth → Document → Folio → UI → Intent → Actions → DB → Rebuild
⸻
14. FINAL LOCK
You are stabilizing:
a deterministic document engine
over a multi-entity system
⸻
🚀 DEPLOYMENT PLAN — FINAL STAGE (LOCKED ORDER)
⸻
🔴 PHASE 0 — FREEZE CORE
- Prisma schema → LOCK
- Actions → LOCK
- Routing → LOCK
⸻
🟢 PHASE 1 — WEEKLY SPONSOR SYSTEM (C)
Domain
WeekSlot ✅
Assignment 🔴
Donation ✅
LineItem ✅
Deliverable ✅
⸻
Actions
createAssignment()
assignAssignmentToWeek()
⸻
UI
app/(pages)/sponsor/page.tsx
- ActivitySelector
- ForecastPreview
- WeekGrid
- ActiveWeek
⸻
Done When
✔ pick activity
✔ assign week
✔ sponsor
✔ unlock donations
⸻
🟢 PHASE 2 — TRIPS UI (A)
Constraint
DO NOT TOUCH BACKEND
⸻
Pages
app/(pages)/trips/
- page.tsx
- [tripId]/page.tsx
⸻
Components
TripCalendar
AvailabilityList
SessionList
OfferBuilderBridge
⸻
Flow
Availability → UI
Session → UI
LineItem → pricing
⸻
Done When
✔ view availability
✔ select slot
✔ generate offer
⸻
🟢 PHASE 3 — AI MODES (B)
Final Modes
type Mode = "general" | "coaching";
⸻
Router
runCoachingMode(input, context)
⸻
Routing
trip → generateTripPlan()
document → generateDocStructure()
⸻
Remove
❌ multiple modes
❌ UI complexity
⸻
🟢 PHASE 4 — DOCUMENT → MAGAZINE (D)
DocumentPage.surface
→ blocks
→ html
→ MagazineSection
Rules:
NO duplication
ONLY transformation
⸻
🟢 PHASE 5 — APPSCRIPT EXPORT (E)
Client
exportToGoogleDoc(documentId)
⸻
Payload
{
title
content
email?
}
⸻
Script
function doPost(e) {
const { title, content, email } = JSON.parse(e.postData.contents);
const doc = DocumentApp.create(title);
doc.getBody().setText(content);
if (email) {
DriveApp.getFileById(doc.getId()).addEditor(email);
}
return ContentService.createTextOutput(
JSON.stringify({ success: true, docId: doc.getId() })
);
}
⸻
Done When
✔ export works
✔ user gets access
⸻
🟢 PHASE 6 — CSS
styles/theme.css
.page
.section
.card
.label
.cta
⸻
🟢 PHASE 7 — DEPLOYMENT
Docker
FROM node:20-alpine
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
⸻
Commands
docker build -t molino-app .
docker push gcr.io/YOUR_PROJECT/molino-app
⸻
Deploy
Cloud Run
⸻
🔴 FINAL ORDER
1. Sponsor
2. Trips
3. AI
4. Magazine
5. Export
6. CSS
7. Deploy
⸻
⚠️ RULES
- no parallel phases
- no schema redesign
- no new entities (except Assignment)
- no breaking actions
⸻
✅ SUCCESS
✔ sponsor system works
✔ trips UI works
✔ AI outputs structured
✔ export works
✔ magazine works
⸻
FINAL STATEMENT
integration > invention
⸻
NEXT
→ Assignment model
→ ActivitySelector UI
⸻
//SPECIFICS ON AI ASSISTANT - GENERAL VS COACHING MODE AND DOCUMENT VERSION VS CHAT
# 🔧 AI → DOCUMENT INTEGRATION PLAN (SAFE REFACTOR — LOCKED)
---
# 0. OBJECTIVE
Stabilize and simplify:
AI → Document generation → Persistence → Rendering
WITHOUT:
❌ breaking Folio
❌ breaking actions
❌ introducing new paradigms
---
# 1. CURRENT ISSUES (CONFIRMED)
## 1.1 Mode System Fragmentation
- Mode defined in:
- ChatPanel (local union)
- AssistantContext (VALID_MODES)
- modeRegistry
- UI exposes deprecated modes
---
## 1.2 Document Write Bug
Observed:
AI writes into:
→ title (incorrect)
instead of:
→ topSurfaceSection (correct)
---
## 1.3 Surface Contract Drift
Inconsistencies:
topSurfaceSection ✅
contentSections ✅
conentSection ❌ (typo present)
---
## 1.4 Mixed Responsibilities
applyAssistantToDocument currently:
• runs AI
• resolves cache
• transforms markdown
• decides structure
• persists
• forks document
→ too much responsibility (but do NOT refactor yet)
---
## 1.5 Duplicate Chat Systems
Two panels:
/documents → ChatPanel (writes document)
/assistant → ChatPanel (thread chat)
Different:
mode handling ❌
types ❌
validation ❌
---
# 2. TARGET STATE (LOCKED)
## 2.1 Modes
type AIMode = “general” | “coaching”;
---
## 2.2 Internal Pipelines (hidden)
mlv
dev
feature
docs
autopilot
→ NOT user selectable
→ ONLY invoked by coaching
---
## 2.3 Document Write Contract
AI → ALWAYS writes to:
topSurfaceSection[]
NEVER:
title
---
## 2.4 Flow
UI → coaching/general
↓
runDevLayerAction
↓
applyAssistantToDocument
↓
Document2Data
↓
Folio
---
# 3. PHASE PLAN (STRICT ORDER)
---
# 🟢 PHASE 1 — MODE NORMALIZATION (NO BEHAVIOR CHANGE)
## 3.1 Create canonical type
```ts
// app/assistant/modes/types.ts
export type AIMode = "general" | "coaching";
⸻
3.2 Update AssistantContext
const VALID_MODES: AIMode[] = ["general", "coaching"];
⸻
3.3 ChatPanel (document)
REPLACE:
type Mode = "general" | "coaching" | "mlv" | "dev" | "autopilot"
WITH:
import type { AIMode } from "@/app/assistant/modes/types";
⸻
3.4 UI
REMOVE mode buttons:
❌ dev
❌ mlv
❌ feature
❌ docs
❌ autopilot
KEEP:
✔ general
✔ coaching
⸻
3.5 DO NOT TOUCH
modeRegistry.ts
runDevLayerAction
⸻
🟢 PHASE 2 — DOCUMENT WRITE FIX (CRITICAL)
4.1 HARD RULE
AI NEVER writes into title
⸻
4.2 Patch applyAssistantToDocument
REPLACE:
title: data.title?.trim()
? data.title
: bundle?.title ?? prompt.slice(0, 120),
WITH:
title: data.title ?? "Untitled Document",
⸻
4.3 FORCE SURFACE WRITE
Replace entire non-MLV branch:
nextTopSurfaceSection = [
{
id: uid(),
type: "text",
content: fullContent,
},
];
nextcontentSections = [];
WITH:
nextTopSurfaceSection = chunks.map((chunk) => ({
id: uid(),
type: "text",
content: chunk,
}));
nextcontentSections = [];
⸻
4.4 RESULT
✔ no title pollution
✔ clean pagination
✔ predictable rendering
⸻
🟢 PHASE 3 — DATA CONTRACT FIX
5.1 Fix typo (CRITICAL)
SEARCH:
conentSection
REPLACE:
contentSections
⸻
5.2 Enforce schema (add guard)
function assertDocumentShape(data: Document2Data) {
if (!Array.isArray(data.topSurfaceSection)) {
throw new Error("Invalid topSurfaceSection");
}
}
CALL before persist.
⸻
🟢 PHASE 4 — COACHING ROUTER (MINIMAL)
6.1 Add router
// app/assistant/runCoachingMode.ts
export async function runCoachingMode(input) {
const { context } = input;
if (context?.type === "trip") {
return generateTripPlan(input);
}
if (context?.type === "document") {
return generateDocStructure(input);
}
return runDevLayerAction({
...input,
mode: "general",
});
}
⸻
6.2 applyAssistantToDocument
REPLACE:
const ai = await runDevLayerAction(...)
WITH:
const ai =
mode === "coaching"
? await runCoachingMode({ ...input })
: await runDevLayerAction({ ...input });
⸻
🟢 PHASE 5 — CHAT UNIFICATION (NO UI CHANGE)
7.1 Extract shared type
// app/assistant/types/chat.ts
export type ChatMode = "general" | "coaching";
⸻
7.2 Use in BOTH panels
document ChatPanel
assistant ChatPanel
⸻
🟢 PHASE 6 — CLEAN MODE SOURCE
8.1 MODE_CATALOG stays
8.2 MODE_REGISTRY stays
8.3 Add rule
// MODE_CATALOG = authority
// MODE_REGISTRY = behavior
⸻
4. VALIDATION CHECKLIST
⸻
After Phase 1
✔ only 2 modes visible
✔ no TS duplication
⸻
After Phase 2
✔ AI output always in topSurfaceSection
✔ title never overwritten
✔ pagination stable
⸻
After Phase 3
✔ no undefined fields
✔ no typo drift
⸻
After Phase 4
✔ coaching routes correctly
✔ no behavior regression
⸻
5. DO NOT TOUCH (IMPORTANT)
❌ Folio engine
❌ pagination
❌ ensureBlocks
❌ DocumentPage
❌ Prisma schema
⸻
6. ROOT CAUSE (FOR CONTEXT)
Bug origin:
AI → single string
→ forced into single block
→ rendering mismatch
→ fallback writes title
Fix:
AI → splitMarkdown
→ multiple blocks
→ stable render
⸻
7. NEXT STEP (EXECUTE NOW)
1. Phase 1 (mode normalization)
2. Phase 2 (write fix)
STOP.
Do not proceed further until validated.
⸻
FINAL PRINCIPLE
AI does not decide document structure
AI provides content
Document system owns structure
⸻