How a Spec Becomes a Full-Stack App: The Three-Layer Model Remy, a product agent developed by MindStudio, compiles annotated markdown specifications into full-stack applications through a three-layer model consisting of a spec, a backend contract, and interfaces. The spec, written in MindStudio-Flavored Markdown and stored in `src/app.md`, serves as the source of truth, while the backend contract in `dist/methods/` is compiled TypeScript code derived from that spec. Eight interface types—including web, API, Discord, and Telegram—project the same backend contract, enabling a single `git push` to parse the spec, generate code, build interfaces, apply schema changes, and deploy the application. How a Spec Becomes a Full-Stack App: The Three-Layer Model The canonical architectural diagram of Remy explained: how annotated prose compiles into methods, tables, and roles, then projects onto eight interfaces. At a Glance Three layers: Spec annotated prose → Backend contract methods, tables, roles → Interfaces web, API, Discord, Telegram, cron, webhook, email, MCP, agent The spec is source: Lives in src/app.md , written in MSFM MindStudio-Flavored Markdown . The application’s intent, domain knowledge, and rules. The backend is compiled output: Lives in dist/methods/ , TypeScript methods and table definitions generated from the spec. In the same way .js is a compiled derivation of .ts , the backend code is a compiled derivation of the spec. Interfaces are projections: Eight ways to interact with the same backend contract. One method powers all of them. Two SDKs enforce the contract: @mindstudio-ai/agent backend and @mindstudio-ai/interface frontend . Type-safe, sandboxed, managed. Deploy is a compile step: git push → parse spec → generate code → build interfaces → apply schema changes → go live. Remy is a product agent that compiles annotated markdown into a full-stack app — backend, database, frontend, auth, tests, and deployment — in a single step. The three-layer model is how that compilation works. What Are the Three Layers? Every Remy app has the same structure: Layer 1: The Spec. A natural language document describing what the app does. Written in MSFM MindStudio-Flavored Markdown , it captures the domain, the rules, the workflows. This is the source of truth. An AI agent reads the spec and generates the code, or you write the code directly. Either way, the spec is the application; the code is a derivation. Layer 2: The Backend Contract. Methods, tables, and roles. Methods are TypeScript functions that implement the logic. Tables define the data model. Roles define who can do what. This lives in dist/ . In the same way .js is a compiled derivation of .ts , the backend code is a compiled derivation of the spec. Layer 3: Interfaces. Ways for users to interact with the contract. A web app, a REST API, a Discord bot, a Telegram bot, a cron job, a webhook, an email trigger, an MCP tool server, a conversational agent. The same methods power all of them. Interfaces can be as complex and polished as you want, but they’re always safe, because the backend contract is where anything real happens. The interface can’t break business logic or corrupt data. The directory structure makes this visible: my-app/ mindstudio.json ← the manifest declares everything src/ app.md ← Layer 1: the spec the application references/ ← supporting material dist/ methods/ ← Layer 2: backend contract compiled from spec src/ .ts methods src/tables/ .ts table definitions .scenarios/ seed scripts for testing interfaces/ ← Layer 3: projections of the contract web/ React SPA api/ REST API config discord/ bot config ... The src/ directory is authored source. Natural language specs, brand guidelines, reference materials. No code. The dist/ directory is compiled output. TypeScript methods, React frontends, JSON configs. Generated from src/ by an AI agent or written directly . How Does Layer 1 Work? The Spec as Source The spec is the most important file in your project. It lives in src/app.md and describes what the app does: the data model, the business rules, the workflows, the edge cases. Here’s a fragment from a vendor approval app: --- name: Procure-to-Pay P2P description: Procure-to-Pay process for all domestic U.S. spend. version: 1 --- Procure-to-Pay When requesting a new vendor, there are three areas of review: governance, legal, and accounting, with approvals flowing in that order. ~~~ The spec says "three areas" but lists four names. From the process flowchart, it is three sequential stages: 1. Governance, Risk & Compliance GRC , one combined stage 2. Legal 3. Accounts Payable AP These are sequential. Each stage must complete before the next is notified. If any stage rejects, the entire request is rejected. ~~~ All invoices can be sent to the Accounts Payable {The AP team in this context refers to the internal accounts payable department, not a vendor's AP. Only users with the "ap" or "admin" role can process invoices.} team for processing against the PO. The spec is written in MSFM MindStudio-Flavored Markdown , which extends standard Markdown with two primitives: Block annotations fenced with ~~~ attach to the content immediately above them. They clarify ambiguities, pin down edge cases, specify data representations. Inline annotations text {content} attach to a specific word or phrase. Good for definitions, units, and clarifications. Annotations are just more context. They’re not typed or structured. They can be a word, a paragraph, or a code snippet. Each annotation makes compilation more deterministic. A spec with good annotations compiles the same way every time. When you want to change the app’s behavior, update the spec and the agent regenerates the code. Other agents ship a demo. Remy ships an app. Real backend. Real database. Real auth. Real plumbing. Remy has it all. You can also write code directly in dist/ without a spec. That works too. But the spec is what makes the project maintainable over time. Code shows what the app does; the spec captures why . What Is the Backend Contract? Layer 2: Methods, Tables, Roles The backend contract is the core of the app: the methods and data model. It lives in dist/methods/ . Methods A method is a named async function that runs on the platform. It’s the universal unit of backend logic. Every interface web, API, Discord, cron, webhook is just a different way to invoke a method. One file per method, one named export: js // dist/methods/src/submitVendorRequest.ts import { db, auth } from '@mindstudio-ai/agent'; import { Vendors } from './tables/vendors'; export async function submitVendorRequest input: { name: string; contactEmail: string; taxId: string; } { auth.requireRole 'requester' ; const vendor = await Vendors.push { name: input.name, contactEmail: input.contactEmail, taxId: input.taxId, status: 'pending', requestedBy: auth.userId, } ; return { vendorId: vendor.id, status: vendor.status }; } Methods receive a single input parameter an object and return an object. Both must be JSON-serializable. Methods run in isolated sandboxes with npm packages pre-installed. No servers to manage. The @mindstudio-ai/agent SDK provides db and auth namespaces that just work, plus access to 200+ AI models, 1,000+ integrations, and platform actions like file uploads and web scraping. Tables Each table is a TypeScript file with a typed interface and a defineTable