# Carotene Documentation (Full Context) This file contains the complete documentation for Carotene in a single file for AI consumption. --- PAGE: https://carotene.dev/ --- --- # https://vitepress.dev/reference/default-theme-home-page layout: home hero: name: "Carotene" text: "The World's First Compilable Prompting Language" tagline: "Stop expecting AI to be your architect. Carotene constrains AI code generation within strict, test-driven contracts and sandboxed runtimes — so it only writes business logic where it is safe to do so." actions: - theme: brand text: Get Started link: /getting-started/installation - theme: alt text: What is Carotene? link: /introduction/what-is-carotene features: - title: Executable Contracts 📜 details: Define data models, method signatures, side-effect permissions, and test cases in a single source of truth — the Contract File. The AI fills in only the business logic. - title: Hyper-Constrained Generative Operators 🧠 details: The @(...) operator is mathematically bounded by the contract before the AI even sees it. It acts as a generative hole constrained by strict pre- and post-conditions. - title: Reverse Blueprint Extraction 🔄 details: Point Carotene at an existing Node.js or Go codebase. The AI will introspect your routing, ORMs, and types, automatically generating your .carrot contracts. - title: Zero-Risk Migration 🛡️ details: Extracted blueprints default to @manual. Carotene strictly documents and tests your legacy code without overwriting it, until you explicitly hand over the reins. - title: Incremental Brownfield Adoption 🏗️ details: Not a rip-and-replace monolith. Generate a single microservice, a background ETL script, or an isolated route, and compile directly into OpenAPI specs or frameworks like Express to drop into existing infrastructure. - title: Deterministic Sandboxing 🔒 details: Static dependency blocking, permissionless runtime sandboxes (Deno / Node Permissions), and read-only test suites enforce architecture at compile-time and runtime. - title: Secure Integrations 🌐 details: "Hexagonal Architecture separates core logic from side-effects. Integration contracts enforce domain allowlists; typed environment variables ban raw process.env." - title: AI-Native CLI 🤖 details: "Built for agents like Claude Code and Codex. Exposes an MCP server, runs contract checks, executes test suites, and offers self-onboarding documentation." - title: Language Agnostic 🗂️ details: Declare your architecture once in Carotene's strictly typed contract language and deploy to any stack — JavaScript, TypeScript, Go, Dart, and more. --- PAGE: https://carotene.dev/introduction/what-is-carotene --- # What is Carotene? **Carotene is the World's First Compilable Prompting Language.** It is a blueprint language (using the `.carrot` file extension) designed to safely orchestrate AI-assisted production-level software development at an enterprise scale. ### The Evolution of Development: Shovel vs Excavator The history of software development is the history of building better tools and can be easily explained when thinking about the simple act of digging a hole. - In the beginning, we dug holes with our **hands** (Assembly) and it restricted what was possible to build. - Then, we invented the **shovel** (High-level languages like C, Java, and Python), which allowed us to build faster and larger structures. - Then, we invented the **excavator** allowing us to suddently build things like dams and skyscrapers. AI is the software development equivalent of an excavator and unlocks some incredible advancements looking into the future. Unfortunately, the current AI hype cycle has led the industry to a dangerous delusion: people believe we skipped the excavator and instantly invented *autonomous excavators and robot site managers*. This has led to the chaotic, unstructured trend of "vibe coding"—throwing massive prompts at an LLM and hoping a stable architecture comes out the other side. But an excavator without a skilled human operator doesn't build a skyscraper; it just tears up the street and hits a gas main. ### The Problem: System-Level Blindness If you ask an AI model to design and build a complex system from scratch, it suffers from *system-level blindness*. It is the equivalent of handing a team of incredible CGI artists a camera and saying, "Make a sci-fi movie," without providing a script, a storyboard, or a director. You might get a few beautiful individual scenes, but stitched together, the logic breaks down, the continuity is ruined, and the final product is a disaster. When applied to code, this results in unpredictable module coupling, hallucinated security boundaries, and unscalable spaghetti code. ### The Solution: The Human Operator Carotene embraces the reality of the AI era: **The role of the developer is changing from manual laborer to heavy-machinery operator.** Instead of writing implementation logic directly, you use Carotene to write strict, mathematically verifiable **Contract Files**. These contracts act as your storyboard and architectural blueprint. They define: - The exact topological boundaries (e.g., Frontend vs. Backend). - The strict shape of your data and memory. - The explicit permissions of every function (e.g., what is allowed to read the database, what is allowed to mutate local state). - The mathematical boundaries that constrain the AI's output before it even writes a line of code. ### Incremental Adoption (Brownfield) Carotene is not a rip-and-replace monolith. You don't have to rewrite your entire system in `.carrot` files to see the benefits. Carotene is designed for surgical, incremental adoption: you can use it to generate a single microservice, a background ETL script, or an isolated backend route. The compiler generates standard OpenAPI specs or frameworks (like Express and NestJS) that can be seamlessly dropped into your existing infrastructure. ### The Hyper-Constrained Generative Operator Instead of open-ended chatting, you use the `@(...)` operator. This is a hyper-constrained Generative Operator that is mathematically bounded by the contract. The AI doesn't see your whole codebase; it only sees the micro-context (the inputs, the expected return type, and the mathematical constraints) and synthesizes the exact business logic required. Once your architecture is locked in, the Carotene compiler generates the infrastructure, and the AI agent acts as your excavator—safely digging out the business logic *inside* your unbreakable, compiler-enforced guardrails. Carotene gives you the speed of AI generation without ever surrendering structural control. --- PAGE: https://carotene.dev/introduction/core-philosophy --- # Core Philosophy Carotene was built to fundamentally change how humans and AI interact during the software development lifecycle. Rather than trying to make AI smarter at architecture, Carotene makes the architecture immune to AI mistakes. Our design decisions are driven by five core pillars: ## 1. Specification Over Prompting Natural language is inherently ambiguous. You cannot reliably build secure, enterprise-grade software by writing a 10,000-word prompt and hoping the LLM interprets your architectural intent correctly every time. Carotene replaces prompt engineering with **deterministic specification**. The `.carrot` contract file is the absolute source of truth. It defines the exact boundaries, data structures, and permissions of your system using strict syntax. By removing ambiguity, we eliminate the AI's tendency to hallucinate design patterns. ## 2. AI as the Engine, Not the Architect Language models are incredible logic engines but terrible structural architects. They excel at writing a specific algorithmic function, but they struggle to maintain complex dependency graphs across a sprawling codebase. Carotene restricts the AI to the role it is best at: **implementation**. You act as the Architect, defining the topology and guardrails. The framework generates the overarching infrastructure, and the AI is treated purely as a compute engine that fills in isolated, single-responsibility functions. ## 3. No AI Self-Policing Most AI development tools rely on "system prompts" to enforce security rules (e.g., *"You are an expert developer. Do not make unauthorized network calls"*). This is fundamentally flawed. AI models suffer from prompt drift and can easily be tricked or confused into bypassing these soft rules. **Carotene operates on a Zero-Trust model for AI generation.** We do not ask the AI to police itself. Instead, Carotene enforces rules mathematically via the compiler and runtime environments. - If a function is not explicitly granted the `updates store.Database` verb in the contract, the injected dependencies simply will not have write access. - If the AI tries to write unauthorized side-effects, the build fails. ## 4. Human-AI Interchangeability (Zero Lock-In) Carotene does not force you into an AI-only workflow. The compiler generates standard, idiomatic projects in your target languages (TypeScript, Go, Rust, etc.)—there is no proprietary vendor lock-in or messy "AI-only" code artifacts. Because the contract file strictly defines the inputs, outputs, and boundaries for every single function, **human engineers and AI agents are completely interchangeable.** * You can use Carotene purely to layout the architecture and hand the generated stubs to a team of human developers. - You can split the load: assign your senior engineers to write the mission-critical security and payment implementations, while deploying AI agents to rapidly churn out the UI components and standard CRUD logic. To the Carotene compiler, an implementation is an implementation, regardless of who (or what) wrote it. ## 5. Convention over Configuration (Progressive Disclosure) A framework should give you an excavator, but it shouldn't require you to build the engine from scratch every time you turn it on. Carotene is designed with an intelligent **Inference Engine**. For 90% of use cases, you don't need to specify HTTP protocols, ORM choices, or API gateway handshakes—the compiler infers the most sensible, industry-standard defaults based on context. However, for the remaining 10% where absolute control is required, Carotene provides strict `config`blocks, allowing you to explicitly override defaults down to the transport layer (e.g., swapping HTTP for UDP). --- PAGE: https://carotene.dev/introduction/how-it-works --- # How it Works Carotene bridges the gap between human architectural intent and rapid code generation through a strict, four-step pipeline: **Parse, Infer, Generate, and Implement**. This pipeline ensures that every line of business logic written—whether by a human or an AI agent—is mathematically verified against your original design before it ever reaches production. ## 1. Parse (The Blueprint) It all starts with your `.carrot` files. You define your data shapes (`model`), your storage layers (`store`, `state`), your structural boundaries (`frontend`, `backend`), and your behavioral guardrails (`reads`, `mutates`, `calls`). When you run the Carotene CLI, the compiler parses these files into a language-agnostic **Abstract Syntax Tree (AST)**. At this stage, Carotene validates the topology of your system. If you tell a frontend view to `updates store.Database`directly without going through a backend function, the compiler catches the security violation and fails the build immediately. ## 2. Infer (The Engine) Carotene does not want you writing thousands of lines of infrastructure boilerplate. Instead, it uses an **Inference Engine**to analyze your AST and apply sensible, industry-standard defaults based on context. - **Contextual Networking:** If a frontend `calls` a backend function, the compiler infers a standard JSON-RPC over HTTP request. If the frontend `observes` a backend stream, the compiler infers a WebSocket connection with a pub/sub backplane. - **Contextual Storage:** A `store` in the backend defaults to Postgres. A `store` in an iOS frontend defaults to local SQLite. You get "magic" when you want speed, and you use typed `config` blocks to explicitly override the defaults when you need granular control. ## 3. Generate (The Scaffolding) Once the AST is validated and inferred, Carotene invokes its pluggable code generators for your target languages (TypeScript, Go, Rust, Swift, etc.). Carotene generates a standard, idiomatic software project that includes: - **Data Layers:** ORM schemas (e.g., Prisma/Drizzle), SQL migrations, and state management slices (e.g., Zustand/Redux). - **Networking:** Fully typed API gateways, internal service mesh routing, and client SDKs. - **Test Suites:** Read-only, deterministic test files generated directly from the `test` blocks in your contract. - **Implementation Stubs:** Empty functions wrapped in dependency-injected boundaries. The generated code is not a proprietary "black box." It is clean, readable infrastructure that looks exactly like what a senior platform engineer would write. ## 4. Implement & Verify (The Sandbox) The final step is filling in the empty implementation stubs with custom business logic. This is where human engineers and AI agents collaborate. - **For AI Agents:** Carotene runs a native **Model Context Protocol (MCP)** server. Your agent (Claude Code, Cursor, etc.) connects to the CLI, reads the contract, understands the exact inputs/outputs, and writes the logic. - **The Sandbox:** Before the code is accepted, Carotene runs the generated tests in a **Permissionless Sandbox**. - If the AI hallucinated an unauthorized network call (`fetch('https://evil.com')`), the sandbox crashes. - If the AI tries to write to the database when the contract only permitted `reads`, the dependency-injected database client throws a type error. The AI receives the exact sandbox error trace, autonomously corrects its logic, and tries again. Once the sandbox passes, you have a mathematically verified, secure, and fully architected application ready for deployment. --- PAGE: https://carotene.dev/introduction/magic-vs-control --- # Magic vs. Control In framework design, there is a constant tug-of-war between "Magic" (doing things automatically for the developer) and "Control" (forcing the developer to wire everything up manually). - If a framework is **too magical**, it becomes an un-debuggable black box the moment you hit an edge case. - If a framework is **too explicit**, you end up writing thousands of lines of Kubernetes manifests and networking boilerplate just to get two microservices to talk to each other. Carotene solves this through **Progressive Disclosure of Complexity**, applying strict Convention over Configuration. ## Maximum Magic (The 90%) Carotene's Inference Engine reads your Abstract Syntax Tree (AST) and makes highly educated guesses about your infrastructure based on the environment and the verbs you use. For 90% of standard application development, you write **zero infrastructure boilerplate**. ```dart backend { store { model Order { id: UUID, total: Float } } function PlaceOrder() { requires Customer creates store.Order } } frontend { view Checkout() { calls backend.PlaceOrder } } ``` **What the Carotene compiler infers from this "magic" block:** 1. **The Database:** Because `store` is inside a `backend`, it infers durable storage. It defaults to generating a **Postgres** database with Prisma/Drizzle schemas. 2. **The Networking:** Because the frontend `calls` the backend synchronously, it infers standard **JSON-RPC over HTTPS**. It generates the internal fetch client automatically. 3. **The Security:** Because `PlaceOrder` requires the `Customer` role, the generated frontend client automatically injects the user's JWT into the `Authorization` header, and the backend middleware validates it before the AI's logic even runs. ## Maximum Control (The 10%) When you need to step outside the standard CRUD paradigm—whether you are building a 60fps game loop, an IoT edge device, or an authoritative UDP server—the "magic" defaults are no longer sufficient. You take back absolute control using **Typed `config` Blocks**. The `config` block is Carotene's universal escape hatch. By dropping a config block into any primitive, you override the Inference Engine with explicit instructions. Because these blocks are typed, the compiler provides strict schema validation for your overrides. ### Example 1: Overriding Default Storage If you are building an iOS app, the default frontend `store` is SQLite (for offline caching). If you want to use the device's secure enclave instead, you explicitly type the config: ```dart frontend { config ios { targetVersion: "17.0" } store { // Overriding SQLite with the iOS Secure Keychain config keychain { accessible: "WhenUnlocked" } model SessionToken { token: String } } } ``` ### Example 2: The Service Mesh & Transport Layer If you have a backend execution loop that needs to broadcast player positions to connected clients 30 times a second, HTTP is too slow. You can override the internal Service Mesh transport protocol directly on the loop: ```dart backend AuthoritativeServer { loop ServerTick { // Bypassing HTTP entirely for this specific loop config network { rate: "30hz" transport: "udp" } mutates state.Match emits "network.state_sync" } } ``` ### Example 3: Hardware Integrations Integrations use typed config blocks to dictate exactly what kind of third-party system the generated code must interface with. The compiler ensures you provide the correct parameters. ```dart integration TemperatureSensor { // The compiler strictly validates I2C properties config i2c { address: "0x76" pins: [4, 5] } function ReadContinuous() -> Stream } ``` ## The Verdict: No Lock-In With Carotene, you get the rapid prototyping speed of a "magic" framework, without the terrifying vendor lock-in. You can build your MVP using the implicit defaults. Months later, when your system scales and your database becomes a bottleneck, you don't need to rewrite your application. You simply open your `.carrot` file, drop a `config` block into your `store` to point it at a specialized cluster, re-compile, and let Carotene generate the new infrastructure. Your AI-written business logic never has to change. --- PAGE: https://carotene.dev/introduction/why-carotene --- # Conclusion: Why Carotene? For the last decade, the software industry has been chasing abstractions—React, Next.js, tRPC, Prisma, Docker. We built incredibly complex "magic" frameworks to make human developers type slightly fewer characters. Then, AI arrived. Suddenly, the problem wasn't *typing* the code; the problem was **trusting** the code. - Can I trust the AI not to hallucinate a destructive database loop? - Can I trust the AI to write secure JWT middleware? - Can I trust the AI to follow my exact business logic? Standard languages like TypeScript and Python were built for humans to write, not for AI to generate. They are infinitely permissive by default, meaning every time an AI writes a function, you have to audit it for security, performance, and correctness. **Carotene was built because AI needs a Sandbox, and Humans need a Blueprint.** ### The Carotene Philosophy 1. **Architecture is the Contract:** You do not write implementations; you write the rules. The `model`, `store`, and `flow`primitives dictate exactly how your data is shaped and how it is allowed to change. 2. **Zero-Trust by Default:** The AI cannot do anything you do not explicitly authorize. Using strict **Verbs** (`updates`, `calls`), you define the physical boundaries of the execution sandbox. If you don't grant the AI permission to access the User table, it mathematically cannot query it. 3. **Implicit Shields, Explicit Intent:** Carotene hates hidden magic. Security and networking are explicitly declared via `requires` and function signatures. The compiler then generates the impenetrable API gateways, UI guardrails (`canExecute`), and session middleware automatically. 4. **Hybrid Logic (The End of Low-Code):** You are never trapped. Write fast, deterministic logic with standard operators (`if/else`), and seamlessly inject the LLM for tedious algorithms using inline `ai"..."` expressions. 5. **Behavior-Driven Generation:** You don't write tests to mock databases; the compiler does that for free. You write business logic tests to prove the AI understood your intent. If the AI fails the test, the compiler forces it to rewrite the code autonomously. ### The Future of Development Carotene doesn't replace the developer; it elevates them to the role of **Systems Architect**. Instead of spending hours debugging a missing `await` statement or wrestling with a Prisma migration, you spend your time designing mathematically sound state machines, defining strict security perimeters, and writing crystal-clear business rules. You design the blueprint. Carotene enforces the guardrails. The AI pours the concrete. Welcome to the post-boilerplate era. Welcome to Carotene. --- PAGE: https://carotene.dev/getting-started/installation --- # Installation & Setup Carotene is designed to be a zero-config, all-in-one toolchain. You do not need to install separate testing libraries (like Jest), database ORMs (like Prisma), or security middleware. The entire framework is powered by a single binary: the **Carotene CLI (`carrot`)**. It acts as your compiler, your test runner, and your AI generation engine. ## Step 1: Install the CLI The Carotene CLI is distributed as a standalone binary, meaning it doesn't pollute your global environment. You can install it via your preferred package manager or directly via our install script. **macOS / Linux (via curl)** ```bash curl -fsSL https://get.carotene.dev | bash ``` **macOS (via Homebrew)** ```bash brew install carotene ``` **Windows (via PowerShell)** ```powershell iwr https://get.carotene.dev/windows -useb | iex ``` *(Note: If you prefer using Node.js, you can also run `npm install -g carotene-cli`, though the standalone binaries are recommended for maximum speed).* ## Step 2: Set Up Your Editor Carotene is a strictly typed architectural language. To get the most out of it, you need your editor to understand the `.carrot`file extension, highlight the Zero-Trust Verbs (`reads`, `updates`, `calls`), and provide IntelliSense for the `@(...)` Generative Operator. **VS Code** 1. Open VS Code. 2. Go to the Extensions tab (`Cmd+Shift+X` or `Ctrl+Shift+X`). 3. Search for **Carotene Language Server** and click Install. 4. *Feature:* The extension automatically highlights `@(...)` operators in a distinct color so you can visually audit where the AI is writing logic versus where code is deterministic. *(Extensions for JetBrains / IntelliJ and Neovim are available in the community repository).* ## Step 3: Connect Your Intelligence Engine Carotene is entirely LLM-agnostic. The compiler acts as the architect and the sandbox, but you get to choose the "excavator" that writes the code. You can use your own API keys, run local models, or use the Carotene Managed Cloud. **Option A: Bring Your Own Key (BYOK)** If you want the Carotene CLI to directly manage the generation loop, provide an API key for your preferred provider. You can set this as an environment variable or store it securely in the CLI: ```bash # Store keys locally in the Carotene keychain carrot keys:add anthropic sk-ant-123... carrot keys:add openai sk-proj-123... ``` **Option B: Local / External Agents (MCP)** If you already use an AI IDE (like Cursor) or a terminal agent (like Claude Code), you do not need to give Carotene API keys at all. You simply start the Carotene MCP Server: ```bash carrot mcp --stdio ``` Your agent connects to the server, reads the architecture, and writes the code. The CLI acts purely as the Deterministic Sandbox, validating the agent's output. **Option C: Carotene Managed Cloud** If you want a zero-setup, "batteries-included" experience, you can authenticate with the Carotene Cloud. This connects your CLI to our highly optimised, proprietary generation pipeline. ```bash carrot login ``` ## Step 4: Verify Your Installation To ensure the CLI, the sandbox engine, and the AI compiler are correctly configured, run the version check: ```bash carrot --version ``` You should see an output similar to this: ```bash Carotene CLI v1.0.0 Compiler: Online (Authenticated) Sandbox Engine: Embedded WASM Ready ``` You are now fully set up. You have the blueprint language, the isolated testing sandbox, and the AI builder all ready to go. --- PAGE: https://carotene.dev/getting-started/your-first-contract --- # Your First .carrot Contract The beauty of Carotene is that you don't start by configuring databases, setting up routing libraries, or writing boilerplate middleware. You start by defining the truth of your system. A `.carrot` file is not a script; it is an architectural contract. It defines the data, the security boundaries, the generative logic, and the tests all in one unified, highly readable blueprint. Let’s build the "Hello World" of enterprise applications: a simple Task Management function. ### Step 1: Define the Truth (Data & State) Carotene contracts define the strict shapes of our data and the mathematical state machines that govern them. While complex projects use `domain` blocks for organisation, simple projects can start directly with the primitives. Create a new file called `tasks.carrot` and define the structure: ```dart // tasks.carrot // Note: We removed the 'domain' block. // Without it, primitives are registered to the global namespace. // 1. The State Machine // Tasks can only move in one direction. flow TaskStatus { on Complete { Pending -> Completed } } // 2. The Data Shape model Task { id: UUID ownerId: UUID title: String status: TaskStatus } // 3. The Storage Layer store Task { model: Task } ``` ::: tip 💡 Pro Tip: When to use `domain` In small projects, you don't need a `domain`. However, as your project grows and you add more `.carrot` files, you might encounter naming collisions (e.g., two different models named `User`). Wrapping your code in a `domain MyNamespace { ... }` isolates those primitives to that namespace, preventing collisions. ::: ### Step 2: Define the Execution (The Sandbox) Now we need a function to actually complete a task. We will put this inside a `backend` block. Notice how we don't write the implementation. We define the input, ingest the data, set up the Zero-Trust security rules, and use the `@(...)` operator to let the AI write the tedious logic. ```dart // ... (Data definitions from above) ... backend { function CompleteTask(taskId: store.Task.id) { // 1. Zero-Trust Security (RBAC) requires AuthenticatedUser // 2. Sandbox Permissions reads store.Task triggers store.Task.status.Complete updates store.Task implements { // 3. Data Ingestion targetTask = store.Task.find(taskId) // Security Check if (session.userId != targetTask.ownerId) { throws "Forbidden: You do not own this task" } // State Guardrail if (targetTask.status == Completed) { throws "Task is already completed" } // 4. The Generative Operator message = @("Generate a short, enthusiastic congratulatory message for finishing: ${targetTask.title}") return message } } } ``` ### Step 3: Prove It (Test-Driven Generation) Because we used the `@(...)` operator, we must mathematically guarantee that the AI generates the correct logic before it compiles. We do this by appending a flat `test` block at the bottom of our file. ```dart // ... (Data and Backend blocks) ... test "User can complete a pending task and receive a message" { // 1. Setup the isolated Sandbox memory given activeSession = mock session { userId: "user_1" } given pendingTask = mock store.Task { id: "task_1", ownerId: activeSession.userId, title: "Submit Expense Report", status: Pending } // 2. Execute the action result = CompleteTask(pendingTask.id) // 3. Assert the architecture was respected asserts store.Task.find(pendingTask.id).status == Completed // 4. Assert the AI returned the correct type asserts type(result) == String } ``` ### Step 4: Build & Compile You have now written a complete, mathematically sound architecture. You defined the database schema, the RBAC security, the state machine, the execution boundaries, and the test assertions. Now, you hand the blueprint to the Builder. Run the following command in your terminal: ```bash carrot build ``` **What happens next is entirely autonomic:** 1. The compiler reads your `.carrot` file and provisions the routes, the database schemas, and the security middleware. 2. The AI encounters your `@(...)` operator and writes the TypeScript or Go code to generate the congratulatory message. 3. The Sandbox intercepts the AI's code, spins up an isolated, embedded database in memory, injects your `mock` data, and runs the `CompleteTask` function. 4. It verifies the assertions. If the AI hallucinates, it feeds the error back and tries again. In under three seconds, the terminal will output: ```bash [✔] Build Successful. Zero-Trust Sandbox verified. ``` You just built a secure, tested, AI-powered backend in 45 lines of highly readable text. --- PAGE: https://carotene.dev/getting-started/development-workflow --- # The Development Workflow When you adopt Carotene, your day-to-day routine as a developer fundamentally changes. In a traditional framework like Next.js or Express, the workflow is imperative: you write a line of code, save the file, refresh the browser, check `console.log`, find a bug, and write another line of code. You spend 80% of your time implementing logic and 20% designing the system. Carotene flips this ratio. You are no longer the Builder; you are the **Systems Architect**. Your workflow is entirely declarative, driven by constraints, boundaries, and mathematical proofs. Here is the standard Carotene Development Workflow. ## Phase 1: Architecting the Blueprint You never start a feature by writing logic. You start by defining the physical realities of the feature: the shape of the data, the security perimeter, and the network boundaries. 1. **Define the Data (`model` & `store`):** What does the database look like? 2. **Define the Lifecycle (`flow`):** What are the legal states this data can exist in? 3. **Define the Boundaries (Verbs):** What is this feature allowed to touch? You write your `backend function` and immediately lock it down with `reads`, `updates`, and `calls`. At this stage, you haven't written any code. You have simply drawn a box. The AI cannot step outside this box. ## Phase 2: Expressing Intent Once the Zero-Trust Sandbox is defined, you fill in the business rules. You do not write boilerplate data transformations or complex algorithms. 1. **Deterministic Fast-Paths:** If a rule is simple and absolute (e.g., `if (user.age < 18) throws "Too young"`), you write it using standard, deterministic Carotene syntax. 2. **The Generative Operator (`@(...)`):** For everything else—tedious calculations, data mapping, string generation, or complex sorting—you drop a Generative Operator. You are explicitly delegating the implementation to the AI compiler. ```dart // Phase 1: Boundaries requires session.role == Admin reads store.User // Phase 2: Intent implements { targetUser = store.User.find(userId) discount = @("Calculate the seasonal discount based on the user's past 5 orders") } ``` ## Phase 3: Writing the Proof Because you delegated logic to the AI, you must prove the AI understood your intent. **You do not run the app to test it; you write a `test` block.** You use `mock` to instantly seed the Vapor Sandbox with edge-case data, and `asserts` to define the mathematically correct outcome. ```dart // Phase 3: The Proof test "Applies maximum 20% seasonal discount for heavy buyers" { user = mock store.User { id: "1" } mock store.Order { userId: user.id, total: 5000.0 } // Heavy buyer result = ApplyDiscount(user.id) asserts result == 0.20 // The AI MUST figure out how to output 0.20 } ``` ## Phase 4: The Autonomic Build Loop (`carrot dev`) This is where the magic happens. Instead of manually testing APIs in Postman, you run the Carotene watch command in your terminal: ```bash carrot dev ``` This starts the **Test-Driven Generation (TDG)** engine. As you save your `.carrot` file, the following autonomic loop executes in the background: 1. **Parse & Provision:** The compiler reads your boundaries and instantly provisions the local in-memory database and routing layer. 2. **Generate:** The LLM reads your `@(...)` operators and writes the underlying TypeScript or Go implementation. 3. **Evaluate:** The engine spins up the Deterministic Sandbox, injects your mocks, and runs the AI's code. 4. **Negotiate (The Invisible Step):** If the AI's code fails your `asserts` statement, the terminal does *not* throw an error. Instead, the Sandbox intercepts the failure, feeds the stack trace back to the AI, and forces it to rewrite the code. This happens in milliseconds. 5. **Success:** Only when the AI writes code that perfectly satisfies your architectural boundaries and test assertions does the terminal turn green. ```bash [~] Compiling ApplyDiscount... [~] AI failed assertion (Expected 0.20, Got 0.15). Retrying... [✔] Build Successful. ``` ## The Result: Deployment Confidence When `carrot dev` goes green, you aren't just confident that the code compiles. You are mathematically guaranteed that: - The feature is completely secure against unauthorized access. - The feature cannot accidentally drop a database table or call a rogue API. - The AI perfectly understood your business logic. You have successfully shifted your job from typing syntax to architecting flawless systems. --- PAGE: https://carotene.dev/getting-started/scope-and-namespaces --- # Scope & Namespaces As your Carotene application grows, organizing your primitives into distinct, bounded contexts becomes essential. Carotene provides a simple, optional mechanism for this: the `domain` block. ## The Global Namespace By default, if you do not wrap your `.carrot` definitions in a `domain` block, everything belongs to the **Global Namespace**. ```dart // Global Namespace model User { id: UUID email: String } backend API { store Users { model: User } } ``` The Global Namespace is perfect for small projects, simple prototypes, or monolithic applications where naming collisions are unlikely. ## The `domain` Block When building larger applications or adhering to Enterprise Domain-Driven Design (DDD), you can use the `domain` block to explicitly scope your primitives. The `domain` block acts purely as an organizational namespace. It clarifies ownership and enforces strict microservice isolation, ensuring that a primitive inside one domain does not accidentally clash with a primitive of the same name in another domain. ```dart domain Commerce { model Order { id: UUID total: Float } backend OrderAPI { store Orders { model: Order } } } domain Fulfillment { // Safe: Does not collide with Commerce.Order model Order { id: UUID shippingAddress: String } } ``` ### Why use `domain`? 1. **Microservice Isolation:** By scoping backends and stores within a domain, you establish clear boundaries. One domain cannot implicitly couple itself to the internal data structures of another without explicit, cross-boundary calls. 2. **Naming Collision Prevention:** In large monorepos with multiple teams, using domains like `Billing`, `Identity`, and `Inventory` allows teams to use common names (like `User` or `Account`) without stepping on each other's toes. 3. **Enterprise DDD:** The `domain` block maps perfectly to bounded contexts in Domain-Driven Design, making your `.carrot` files a 1:1 reflection of your business architecture. > [!NOTE] > The `domain` block is a compile-time organizational feature. It does not strictly dictate your generated folder structure or deployment architecture, but rather establishes strict lexical scoping for the Carotene compiler. --- PAGE: https://carotene.dev/getting-started/project-structure --- # Project Structure In traditional frameworks, you run an `init` command and are instantly handed a rigid folder structure that you have to force your application to fit into. Carotene does the exact opposite. Your folder structure is a direct, dynamic reflection of your architectural blueprints. The monorepo is not pre-determined; it is **Contract-Driven**. Let's look at how your project evolves from a blank canvas into a fully scaffolded microservice architecture. ## Phase 1: The Blank Canvas (`carrot init`) When you start a new project by running `carrot init my-company`, the CLI does not assume anything about your architecture. It simply gives you the minimal workspace needed to start designing: ``` my-company/ ├── carotene.toml # Global workspace configuration └── system.carrot # Your blank architectural blueprint ``` At this stage, there are no frontends, no backends, and no generated code. It is just you and the blueprint. ## Phase 2: Defining the Topology Inside your `.carrot` files, you define the physical blocks of your system. Carotene uses the names you assign to your `backend` and `frontend` blocks to determine exactly what the monorepo should look like. Let's say you write the following in `system.carrot`: ```dart // Define a central backend backend CoreAPI { function ProcessRefund(orderId: String) { ... } } // Define an internal dashboard frontend AdminPanel { view RefundDashboard() { ... } } // Define a public-facing mobile app API backend MobileGateway { function GetUserProfile(userId: String) { ... } } ``` ## Phase 3: Contract-Driven Scaffolding (`carrot build`) The moment you run `carrot build` (or `carrot dev`), the Carotene compiler reads your topology and dynamically generates the monorepo to match it perfectly. The resulting project structure will look exactly like this: ``` my-company/ ├── carotene.toml ├── system.carrot │ └── apps/ # 🚀 Dynamically generated based on your blocks │ ├── AdminPanel/ # Matching: frontend AdminPanel {} │ ├── .generated/ # (Read-only) API clients, types, and routing │ └── src/ # Your standard frontend UI and components │ ├── CoreAPI/ # Matching: backend CoreAPI {} │ ├── .generated/ # (Read-only) Routers and structural tests │ ├── src/ # Implementation stubs (ProcessRefund.ts) │ └── tests/ # AI-generated business logic tests │ └── MobileGateway/ # Matching: backend MobileGateway {} ├── .generated/ ├── src/ # Implementation stubs (GetUserProfile.ts) └── tests/ ``` ### The Boundary Rules This dynamic generation creates incredibly clean boundaries between your services: 1. **The `.generated/` Folders (Strictly Read-Only):** Carotene isolates all the tedious networking, RPC clients, and strict TypeScript/Go **Interfaces** here. Do not edit these files. If your architecture changes, Carotene will instantly regenerate them, ensuring your native type-checker throws errors if implementations fall out of sync. 2. **The `src/` Directory (The Persistent Workspace):** When Carotene discovers a new function, it generates a stub here explicitly typed to match the `.generated/` interface. * If the function is flagged as `@ai` in the contract, Carotene will overwrite this file to synthesise the logic. * If flagged as `@manual`, Carotene generates the stub once and permanently steps away, leaving the file entirely to you. ------ By making the folder structure an output of the compiler rather than a static starting point, Carotene ensures your monorepo never drifts from your architecture. Your codebase is always a mathematically perfect reflection of your `.carrot`blueprints. --- PAGE: https://carotene.dev/framework-primitives/identity-and-auth --- # Identity & Auth In traditional development, authentication and authorization are frequent vectors for critical security bugs. Developers—and AI agents—often forget to apply middleware to specific routes, leading to data leaks and privilege escalation. Carotene solves this by treating human identity as a top-level architectural primitive. You define your roles and providers once in the `auth` block, and the compiler mathematically enforces them across your entire stack. ## Defining the Auth Primitive The `auth` block is defined at the root of your `.carrot` contract. It establishes the primary human identity system for your application and taxonomizes your users into a strict list of Roles. ```dart auth { provider: "jwt" roles: [Admin, Staff, Customer] } ``` - **`provider`**: Tells the compiler what type of infrastructure to generate. `jwt` instructs Carotene to generate stateless token verification, while `session` would generate stateful, cookie-based session stores (often backed by Redis). - **`roles`**: A strict enumeration of the user types in your system. This list becomes the absolute source of truth for Role-Based Access Control (RBAC) across both the frontend and backend. ------ ## Enforcing Security: The `requires` Verb Once your `auth` block is defined, you enforce access control using the `requires` verb inside your structural blocks (`function`, `view`, etc.). If a function has a `requires` verb, the Carotene compiler generates strict middleware that validates the user's identity *before* the AI-generated business logic is ever executed. ### 1. Securing the Backend ```dart backend { function DeleteUser(userId: UUID) { // The compiler generates middleware to block anyone who isn't an Admin requires Admin deletes store.User implements { @("Delete the user record") } } function UpdateProfile() { // Multiple roles can be permitted requires Staff, Customer updates store.User implements { @("Update the user profile") } } } ``` ### 2. Securing the Frontend The exact same verb is used to guard UI components. If a user does not possess the required role, the component is fundamentally stripped from the generated routing tree. ```dart frontend { view AdminDashboard() { requires Admin /// Render charts and metrics renders RevenueGraph } } ``` ------ ## The "Magic" of the Service Mesh When your frontend `calls` a secured backend function, you do not need to write boilerplate to attach headers or manage tokens. Because the Carotene compiler owns both the frontend and the backend AST (Abstract Syntax Tree), it seamlessly wires the `auth` context together. If a React component calls `backend.DeleteUser`, the generated frontend SDK automatically pulls the JWT from the local session and injects it into the `Authorization: Bearer` header. The developer defines the rule. The compiler writes the boilerplate. ------ ## Human vs. Machine Identity It is critical to distinguish between Human Users and Machine-to-Machine (M2M) traffic. The top-level `auth` block is strictly for **Human Identity** (e.g., users logging in via a web portal). If you need to secure public API endpoints for external servers or webhooks, you use a typed `config` block inside the `gateway`. ```dart // For Humans auth { provider: "jwt"; roles: [User] } backend { // For external Machines (Webhooks, 3rd party devs) gateway { config api_key { source: "header.x-api-key" } rest { POST "/webhooks/stripe" -> ProcessPayment() } } } ``` ------ ## AI Sandboxing & Security By extracting authentication into the Carotene contract, we completely remove the burden of security from the AI agent. When the AI writes the implementation logic for `DeleteUser`, it doesn't need to check if the user is authorized. The Carotene execution sandbox guarantees that the logic will *only* be invoked if the ingress middleware has already cryptographically verified the user as an `Admin`. The AI focuses entirely on the business rules, while the compiler guarantees the zero-trust perimeter. --- PAGE: https://carotene.dev/framework-primitives/backend --- # The Backend In Carotene, the `backend` block defines your server-side environment. It is the secure boundary where durable data is stored, heavy computation occurs, and external public traffic is routed. Whether you are building a simple Node.js CRUD API or a high-performance Rust microservice architecture, the `backend` block provides the exact primitives you need, governed by strict compiler boundaries. ## Monoliths vs. Microservices Carotene uses namespace merging to determine your deployment architecture. - **The Monolith:** If you use an unnamed `backend` block across multiple `.carrot` files, the compiler merges them all into a single, cohesive server deployment. - **Microservices:** If you name your backends (e.g., `backend OrderService`), the compiler isolates them. It generates independent deployments, distinct database schemas, and wires up the internal gRPC/HTTP service mesh automatically. ```dart // We can define backends at the top level backend InventoryService { config go { version: "1.21" } function DeductStock(id: UUID) { ... } } backend OrderService { config node { framework: "fastify" } function PlaceOrder(id: UUID) { // Magic Service Mesh: Safely calls across the microservice boundary calls InventoryService.DeductStock } } ``` ## Data & Memory A backend typically manages both durable data (disk) and volatile session data (RAM). Carotene strictly separates these concepts to prevent data loss and optimize infrastructure generation. - **`store`**: Represents persistent disk storage. By default, Carotene infers a **Postgres** database and generates SQL migrations and ORM models. - **`state`**: Represents high-speed, volatile RAM. By default, Carotene infers a **Redis** cache, perfect for rate-limiting, session management, or active WebSocket state. ```dart backend { store { model User { id: UUID, email: String } } state { model ActiveSession { userId: UUID, lastPing: DateTime } } } ``` ## Execution: Functions vs. Loops Computation in the backend happens in two ways: Event-Driven or Continuous. ### 1. `function` (Event-Driven) A `function` is a discrete block of logic triggered by an event (a frontend request, an internal call, or a webhook). It spins up, executes its permitted side-effects, and returns a value or throws an error. ```dart function ProcessPayment(amount: Float) -> Future { requires Customer updates store.Order throws PaymentDeclinedError } ``` ### 2. `loop` (Continuous) A `loop` runs continuously at a configured frequency. This is used for background workers, polling queues, or high-tick-rate game servers. ```dart loop MatchmakingWorker { // Overrides defaults: Runs every 5 seconds config polling { rate: "5s" } reads state.PlayerQueue updates store.Match } ``` ## The Gateway: External vs. Internal Traffic Carotene enforces a strict boundary between your internal network and the public internet. **1. Internal Traffic (The Service Mesh):** You do not need to define routes for your own frontends or microservices to talk to each other. When a frontend `calls backend.ProcessPayment`, Carotene auto-generates the secure internal RPC. **2. External Traffic (The Gateway):** If you want to expose your backend to third-party developers, webhooks, or external IoT devices, you must explicitly expose the functions using a `gateway` block. ```dart backend { function StripeWebhook(payload: JSON) { ... } // Exposing the webhook to the public internet securely gateway { // Explicit M2M security (bypasses human JWT auth) config api_key { source: "header.Stripe-Signature" } rest { POST "/api/v1/webhooks/stripe" -> StripeWebhook() } } } ``` ## AI Implementation Boundaries The `backend` is where business logic is most critical. When the AI agent implements a backend function, the Carotene sandbox wraps the generated code in a strict Dependency Injection container. If the contract says a function only `reads store.User`, the database client injected into the AI's runtime environment physically will not contain `.insert()` or `.update()` methods. The AI is structurally prevented from dropping tables, bypassing auth middleware, or leaking data. --- PAGE: https://carotene.dev/framework-primitives/frontend --- # The Frontend In Carotene, the `frontend` block defines your client-side environment. This is where you declare your UI components, manage local memory, and handle offline data caching. Carotene treats the frontend declaratively. You define *what* the UI should render and *what* data it needs, and the compiler generates the reactive boilerplate, the routing trees, and the API clients. ## Cross-Platform Generation (Targets) Carotene is truly language-agnostic. You do not need to write separate contracts for your web app and your mobile app. By using the `config targets` array, you instruct the compiler to generate multiple frontends from a single architectural blueprint. ```dart frontend { // Generates a React web app, a SwiftUI iOS app, and a Kotlin Android app simultaneously config { targets: ["react", "swift", "kotlin"] } view Dashboard() { ... } } ``` When the AI implements the `Dashboard` view, Carotene provisions three separate sandbox environments, prompting the AI to write idiomatic JSX for the web, SwiftUI for iOS, and Jetpack Compose for Android—all guaranteed to share the exact same data pipeline. ## Local State vs. Offline Storage Modern frontends require complex data management. Carotene strictly separates volatile memory from persistent offline caching, ensuring the AI cannot accidentally wipe user data on a page refresh. - **`state` (Volatile RAM):** Generates a reactive memory container. For Web, this becomes Redux, Zustand, or Pinia. For iOS, it becomes `ObservableObject` / Environment state. It is cleared when the app closes. - **`store` (Persistent Disk):** Generates durable local storage. For Web, this defaults to **IndexedDB**. For Mobile, it defaults to **SQLite**. This is used for offline-first architectures. ```dart frontend { // 1. Session Memory (RAM) state { model UIState { sidebarOpen: Boolean { default: false } } } // 2. Offline Cache (Disk) store { model DraftPost { id: UUID, content: String } } function SaveDraft() { creates store.DraftPost } } ``` ## UI Composition: The `view` Primitive A `view` is a declarative UI component. You use behavioral verbs to dictate exactly what data the component can read, what child components it mounts, and where it can navigate. ### Passing Data (`reads` and `renders`) To prevent "prop drilling" and unpredictable state mutations, Carotene enforces explicit data passing. If a view needs data, it must `read` it from the state or have it passed down via `renders`. ```dart frontend { view UserProfile() { // Subscribes the view to the reactive state reads state.CurrentUser // Explicitly passes data down to the child component renders Avatar(url: state.CurrentUser.avatarUrl) renders SettingsButton() implements { @("Render the user profile") } } view Avatar(url: String) = @("Generate an image component using the provided URL prop") } ``` ### Routing (`navigates`) You do not write routing files (like `react-router` configs). The compiler builds the routing tree automatically by tracing the `navigates` verb. ```dart view SettingsButton() = @("Render a settings button that navigates to the Settings view") ``` ## Connecting to the Backend The frontend communicates with the backend seamlessly. You do not write fetch calls, manage Axios instances, or write WebSocket handshakes. The compiler generates fully typed client SDKs. - **Synchronous Calls (`calls`):** Triggers a standard HTTP/RPC request to the backend. The generated code automatically handles loading states, error catching, and JWT injection. - **Real-Time Streams (`observes`):** Subscribes to a backend stream. The compiler automatically generates the WebSocket connection and handles reconnection logic. ```dart frontend { view LiveScoreboard() { // Auto-generates a WebSocket client and subscribes to the stream observes backend.MatchTick // Auto-generates a fetch client for a standard POST request calls backend.SubmitScore implements { @("Render the live scoreboard") } } } ``` ## Continuous Execution (`loop`) Modern frontends—especially for games or interactive data dashboards—require continuous updates. Instead of manually writing `setInterval` or `requestAnimationFrame` logic, use the `loop` primitive. Carotene automatically manages the lifecycle: the loop mounts when the view is active and is strictly garbage-collected when the component unmounts, preventing memory leaks. ## AI Implementation Boundaries When the AI acts as your "excavator" to build out the frontend components, the Carotene contract ensures it cannot break the architecture: 1. **No Rogue State:** If the AI tries to write `const [localState, setLocalState] = useState()` for shared data, the Carotene linter flags it. Shared data must live in the `state` block. 2. **No Rogue Network Calls:** If the AI tries to `fetch('https://api.github.com')` inside a button click, the compiler blocks it. All external network calls must be routed through the `backend` or an explicitly defined `integration`. 3. **Guaranteed Props:** The AI knows exactly what variables it has access to because they are strictly defined in the `view` signature (e.g., `view Avatar(url: String)`). --- PAGE: https://carotene.dev/framework-primitives/integrations --- # Integrations & Hardware Modern applications do not exist in a vacuum. They need to process payments through Stripe, send SMS messages via Twilio, or read physical temperature data from an I2C hardware sensor. However, external integrations are where AI-generated code is most dangerous. If an AI has unrestricted internet access, a hallucination could leak data to an unauthorized endpoint or spam a paid API. Carotene solves this by enforcing **Hexagonal Architecture**. The AI-generated core domain is completely isolated. It cannot make raw `fetch()` calls. Every connection to the outside world must be explicitly declared as an `integration`. ## The Integration Primitive The `integration` block treats third-party software APIs and physical hardware devices exactly the same: as black-box services that take inputs and yield outputs. ### Typed Configs (No Guesswork) You configure integrations using **Typed `config` Blocks**. Because the block is typed, the Carotene compiler strictly validates that you have provided the required parameters for that specific protocol. ### 1. Software APIs (REST / OpenAPI) When integrating with a web service, you use protocols like `openapi` or `rest`. To enforce strict security boundaries and prevent secret leakage, integrations must be defined inside the specific execution block (backend or frontend) that uses them. ```dart domain Commerce { backend PaymentService { // The integration is strictly scoped to this backend. // The frontend cannot access it. integration Stripe { config { openapi: { url: "https://api.stripe.com/v1" auth: "env.STRIPE_SECRET_KEY" // Secret keys are safe here } } function CreateCharge(amount: Float) -> Future } function Checkout() { // The AI is allowed to call the scoped integration calls integration.Stripe.CreateCharge } } frontend WebStore { // A completely separate integration specifically for the client integration StripeElements { config { sdk: { auth: "env.STRIPE_PUBLIC_KEY" } } function TokenizeCard(element: UIElement) -> Future } } } ``` **The Sandbox Guarantee:** If the AI implements a frontend view and tries to call the backend's `CreateCharge` integration, the compiler instantly fails the build. The runtime sandbox physically blocks the client from accessing secret-bound integrations. ### Auto-Generation from Open Standards Writing out integration functions for massive third-party APIs by hand defeats the purpose of rapid generation. Carotene acts as your excavator here, too. You do not need to manually define every endpoint. You can point the Carotene CLI at any **OpenAPI, Swagger, or AsyncAPI** specification file. ```bash # Automatically converts a Swagger file into a Carotene integration block carotene import openapi stripe-spec.json --name Stripe ``` The CLI will read the open standard and automatically generate the `.carrot` integration block, complete with perfectly typed models, inputs, and `function` signatures. It brings the wild west of third-party APIs safely under Carotene's strict compile-time guardrails in seconds. ### 2. Hardware & IoT (Edge Compute) Carotene is not just for web apps. If your target is an edge device (e.g., a Raspberry Pi running a generated Rust binary), you treat hardware exactly like a software API, scoped to your firmware execution block. ```dart domain SmartThermostat { backend Firmware { config rust { target: "aarch64-unknown-linux-gnu" } integration TemperatureSensor { // The compiler strictly validates I2C hardware properties config { i2c: { address: "0x76" pins: [4, 5] } } function ReadContinuous() -> Stream } loop MonitorTemp { // Subscribing to a hardware stream is identical to a WebSocket stream observes integration.TemperatureSensor.ReadContinuous } } } ``` ## Secure Secrets Management (`env`) Integrations require API keys, but handing production secrets to an AI coding agent is a massive security risk. Carotene bans the use of untyped `process.env` calls. Instead, you declare your secrets in the top-level `env` block. The framework generates a strictly typed dependency-injection context. ```dart // Define the required environment variables env { STRIPE_SECRET_KEY: String { secret: true } TWILIO_SID: String { secret: true } } ``` When the AI agent generates the implementation, Carotene injects **mock keys** (e.g., `sk_test_mock_carotene_xxx`) into the local sandbox environment. The AI can write and test the integration logic perfectly, but it never sees or touches your production keys. The real keys are only injected by your CI/CD pipeline during deployment. ## Mock-Driven Development To allow the AI to write and test code rapidly without hitting live APIs (and incurring costs or rate limits), you can define mock responses directly inside the integration. ```dart integration Stripe { config openapi { url: "https://api.stripe.com/v1" } function CreateCharge(amount: Float) -> Future { // The AI's tests will run against this deterministic mock data mocks { returns: "ch_mock_success_123" } } } ``` During the AI's autonomous TDD (Test-Driven Development) loop, the compiler intercepts the `calls`verb and returns the mock data. Only when you explicitly flag a build for production does the framework compile the real network adapter. --- PAGE: https://carotene.dev/data-and-state/models-and-validation --- # Models & Validation In modern software, data shapes are often duplicated across multiple layers: you write a SQL schema, a backend TypeScript interface, a Zod validation schema, and a frontend client type. When one changes, the others break. In Carotene, your `.carrot` contract is the **single source of truth** for your data. The compiler automatically generates the database schemas, the cross-language types, and the runtime validation middleware. Carotene accomplishes this with a single, unified primitive: the **`model`**. ## The Contextual Model (Scoping) Carotene is radically minimalist. You do not need different keywords for database tables, network DTOs, or frontend memory slices. Instead, the compiler relies entirely on **Scope** (where the model is placed) to determine what infrastructure to build. ### 1. Global Scope (Shared Data in Transit) If you define a `model` globally (outside of a `backend` or `frontend`), it represents **Data in Transit**. It has no physical lifecycle, no database table, and no memory store. It is an abstract shape used for Network Payloads or Data Transfer Objects (DTOs) shared between your frontend and backend. ```dart domain Commerce { // GLOBAL: A shared shape. Provisions ZERO infrastructure. model ProfileSummary { id: UUID username: String } } ``` ### 2. Private Scope (Encapsulated Data in Transit) If you define a `model` directly inside a `backend` or `frontend` (but *not* inside a `store` or `state`), it is still just Data in Transit, but it is **Encapsulated**. The compiler will only generate the type definitions for that specific block, keeping your other environments clean. This is perfect for internal worker payloads or UI-only prop shapes. ```dart backend { // PRIVATE: Only generates types for the backend code. // The frontend SDK never sees this. model StripeWebhookPayload { eventId: String amount: Float } } ``` ### 3. Storage Scope (Data at Rest / RAM) If you define a `model` inside an infrastructure block (`store` for Disk, `state` for RAM), it represents a concrete entity with a lifecycle. The compiler generates the physical Postgres tables or reactive state slices to hold this data. ```dart backend { store { // STORAGE: A lifecycled entity. Generates a Postgres table and ORM schema. model User { id: UUID { primary, generated: true } username: String } } } ``` ## Composition: The `includes` Keyword To keep your models DRY (Don't Repeat Yourself), Carotene allows you to compose shapes together using the `includes`keyword. Unlike traditional Object-Oriented inheritance (`extends`), which creates fragile runtime prototype chains, `includes`performs **Compile-Time Flattening**. The compiler simply copies the fields from the target model and pastes them into your new model. ```dart // 1. Define a global base shape model BaseEntity { id: UUID { primary, generated: true } createdAt: DateTime { default: NOW } } backend { store { // 2. Compose the global shape into a concrete database table model Article includes BaseEntity { title: String content: String } } } ``` You can compose multiple models at once (`includes A, B`). If there is a field name collision between them, the compiler strictly fails the build, preventing silent overwrites and hidden bugs. ## Shared Logic: Defaults, Formulas & Validation Because `model` is a unified keyword, Carotene allows you to bake incredibly powerful logic directly into the properties using **Configuration Brackets `{ }`**. The compiler seamlessly translates this logic to the target environment—whether that means writing a SQL constraint or a reactive frontend getter. - **Defaults:** `startedAt: DateTime { default: NOW }` - **Computed Data:** `total: Float { computed: "subtotal * (1 + taxRate)" }` ### Field-Level Validation AI coding agents are notoriously bad at writing exhaustive input validation. You strip this burden from the AI entirely by declaring strict validation constraints in the brackets. ```dart model CreateUserPayload { email: String { format: "email", unique: true } password: String { minLength: 8, secret: true } age: Int? { min: 18, max: 120 } } ``` ## The Full-Stack Validation Guarantee The most powerful feature of Carotene's validation system is how it handles the ingress of data. Because the `.carrot`contract generates code for both the frontend and the backend, **validation rules are replicated across the entire stack automatically.** 1. **The Frontend Net:** When the AI builds a React form for `CreateUserPayload`, Carotene injects the validation rules directly into the client SDK. If a user types a 4-character password, the frontend UI instantly rejects it. **No network request is even made.** 2. **The Backend Shield:** If a malicious user bypasses the frontend and sends an API request directly, Carotene's generated backend middleware catches the invalid password and rejects it with a `400 Bad Request` before it ever reaches the application logic. Because of this, when the AI agent writes your backend functions, it does not need to write a single manual `if (!payload.email.includes('@'))` check. It can confidently assume the data is 100% clean. ## Reusing Models: Cross-Boundary Type Referencing Often, data defined in your backend database (`store`) needs to be held in your frontend's volatile memory (`state`). Carotene strictly prevents "magic synchronization"—it will never automatically copy your database schema into frontend memory, as this causes massive performance leaks. Instead, Carotene uses **Cross-Boundary Type Referencing**. You define the blueprint in the `store`, and you build specific UI `models` in the `state` that use that blueprint strictly as their property Types: ```dart frontend { state { // A clean memory slice containing arrays of the backend store model model ArticleList { trending: backend.store.Article[] savedForLater: backend.store.Article[] isLoading: Boolean { default: false } } // Composing a UI-specific model that flattens the backend shape into itself model ArticleCard includes backend.store.Article { isExpanded: Boolean { default: false } } } } ``` By referencing the `store` model, you guarantee that if a database column changes in the backend, the frontend state manager will automatically inherit the new shape and validation rules. --- PAGE: https://carotene.dev/data-and-state/persistent-storage --- # Persistent Storage (`store`) In Carotene, data storage is split into two distinct primitives to eliminate ambiguity: volatile memory (`state`) and durable disk storage (`store`). The `store` block is your database. Data defined inside a `store` is guaranteed to survive server restarts, page reloads, and application crashes. By strictly isolating disk I/O from RAM, Carotene ensures that AI-generated code cannot accidentally wipe critical user data or cause massive database bottlenecks by treating a database cluster like a local variable. ## Contextual Defaults (The Magic) Carotene's Inference Engine reads *where* the `store` is located in your `.carrot` file and automatically generates the optimal infrastructure for that environment. You do not write database connection boilerplate. The compiler handles the migrations, the connection pooling, and the ORM schemas automatically. - **Backend Environment:** The compiler defaults to **Postgres**. It generates your SQL migration files and a strictly typed ORM schema. - **Frontend Environment (Web):** The compiler defaults to **IndexedDB**, generating an offline-first browser database. - **Frontend Environment (Mobile):** The compiler defaults to **SQLite**, generating a high-performance local database file on the iOS/Android device. ```dart backend { // Generates a default Postgres database + ORM store { model Post { id: UUID { primary, generated: true } title: String } } } ``` ## Multiple Databases (Named Stores) Enterprise applications rarely rely on a single database paradigm. You might need relational data for billing, but graph data for a recommendation engine. Carotene handles "Polyglot Persistence" effortlessly. Just like you can name a `backend` to create a microservice, you can name a `store` to provision a completely separate database cluster within the same application. If a `store` is unnamed, it acts as your primary default. If it is named, it generates isolated infrastructure. ```dart backend { // 1. Primary Database (Defaults to Postgres) store { model User { id: UUID, email: String } } // 2. Secondary Database (Overridden to MongoDB) store Analytics { config { mongodb: { uri: "env.MONGO_URI" } } model EventLog { id: UUID { primary, generated: true } payload: JSON } } } ``` ## The Verbs: Safe CRUD Operations When instructing the AI to interact with a `store`, you must use Carotene's four explicit database verbs: **`creates`**, **`reads`**, **`updates`**, and **`deletes`**. *(Note: The `mutates` verb is physically banned from being used on a `store`; it is reserved exclusively for volatile `state` to prevent accidental database writes).* When using multiple databases, you simply prefix the model with the store's name. ```dart backend { function ProcessUserEvent(userId: UUID, eventData: JSON) { // Explicitly grants SELECT permissions on the Primary Postgres DB reads store.User // Explicitly grants INSERT permissions on the Secondary MongoDB DB creates store.Analytics.EventLog } } ``` ## The AI Execution Sandbox This separation of verbs is not just for human readability; it is the absolute foundation of Carotene's Zero-Trust AI generation. When the Carotene compiler generates the implementation stubs for the AI, it uses **Strict Dependency Injection** based exactly on your verbs. If you assign a function the `reads store.User` verb, the database client injected into the AI's execution sandbox simply *does not have* write methods compiled into it. - **AI attempts to write:** `ctx.db.user.insert(...)` - **Sandbox Result:** TypeScript/Compiler Error: `Property 'insert' does not exist on type 'ReadOnlyStore'`. The AI is structurally forced to adhere to your data lifecycle rules. It cannot drop a table, overwrite a record, or delete user data if you did not explicitly grant it the `updates` or `deletes` verb. ## Overriding the Defaults (The Control) As shown in the `Analytics` example above, you can override Carotene's defaults at any time using a typed `config` block. Because the config block is strictly typed, the compiler knows exactly what connection parameters to ask for, providing autocomplete and validation right in your blueprint. **The Zero Lock-in Advantage:** When you change a `config` (e.g., swapping Postgres for MySQL), the AI's business logic implementation *does not need to change*. The Carotene compiler simply swaps out the underlying ORM and infrastructure scaffolding. This allows you to migrate databases with near-zero friction. --- PAGE: https://carotene.dev/data-and-state/session-state --- # Session State (`state`) If the `store` is your application's hard drive, the `state` is its RAM. In Carotene, the `state` block defines volatile, ephemeral memory. Data defined inside `state` is designed to be blazing fast, but it is not durable. If the server restarts or the user closes their browser, the state is cleared. By strictly isolating RAM (`state`) from Disk (`store`), Carotene ensures that your AI coding agent never accidentally triggers an expensive, blocking database write when it only meant to toggle a UI loading spinner. ## Contextual Defaults (The Magic) Just like the `store`, Carotene's Inference Engine reads where the `state` block is located and generates the optimal in-memory infrastructure for that specific environment. - **Frontend Environment:** The compiler infers a reactive memory slice. Depending on your target, it generates **Zustand** or Redux (React), Pinia (Vue), or `ObservableObject` (SwiftUI). It automatically wires up the reactivity, meaning your UI components will re-render instantly when the state changes. - **Backend Environment:** The compiler infers a high-speed caching layer. By default, it generates a **Redis** connection and manages the serialization/deserialization of your data automatically. ```dart domain Gaming { backend { // Generates a Redis cache for high-speed matchmaking state { model MatchmakingQueue { activePlayers: UUID[] averageWaitTime: Float } } } frontend { // Generates a local Zustand/Redux slice for the UI state { model UIContext { isSidebarOpen: Boolean { default: false } activeTheme: Enum(Light, Dark) { default: Dark } } } } } ``` ## The Verb: Safe Memory Manipulation (`mutates`) Because `state` does not hit the disk, it does not use the standard `creates` or `updates` verbs. To grant the AI permission to change volatile memory, you use the **`mutates`** verb. This explicit separation of verbs acts as a massive psychological and architectural guardrail. ```dart frontend { function ToggleTheme() { // The AI is explicitly granted permission to change the UI RAM mutates state.UIContext } } ``` **The Sandbox Guarantee:** If the AI implements `ToggleTheme` and hallucinates a database call (`ctx.db.user.update(...)`), the Carotene execution sandbox fails the build. The AI only requested `mutates`, so the compiler physically withheld the database client from its environment. ## Type Referencing & UI Composition As we established in the Models & Validation section, you should never recreate your database schema inside your `state`. Instead, you use **Cross-Boundary Type Referencing** and **Composition** (`includes`) to pull data from your `store` into your volatile memory safely. By referencing the `store` models directly, you guarantee that if the backend database schema changes, your frontend memory manager will automatically inherit the new types and validation rules without a single line of synchronization code. ## Advanced Backend State: Ephemeral vs. Persistent Caching While the frontend uses `state` primarily for UI reactivity, the backend uses `state` for high-performance operations that would otherwise cripple a Postgres database: 1. **Rate Limiting:** Storing IP addresses and request counts. 2. **WebSockets & Pub/Sub:** Holding active connection IDs and live chat rooms. 3. **Session Management:** Storing active JWTs or session tokens. By default, backend `state` is transient. However, you can use the `config` block to override the Redis settings, dictating exactly how memory should be handled (e.g., setting strict Time-To-Live parameters). --- PAGE: https://carotene.dev/data-and-state/workflows --- # Workflows & Lifecycles (`flow`) You have defined your shapes (`model`), your databases (`store`), and your volatile memory (`state`). The final piece of data management is defining how that data changes over time. In traditional development, the "lifecycle" of an entity is usually governed by scattered `if/else` statements across your codebase. If a developer (or an AI agent) forgets one of these checks, a user might accidentally cancel an order that has already shipped. Carotene solves this with the **`flow`** primitive. A `flow` is a strict, compiler-enforced State Machine mapped directly to your data. It defines the available states, the valid paths between them, and the **Named Events**that trigger those transitions. ## Defining a Flow (States & Events) Instead of writing a standard Enum, you define a `flow`. You map the valid transitions from one state to another, and you group them under an Event using the `on` block. Crucially, **Events govern the action, not the destination**. A single event can handle completely different starting and ending states, such as a "Move Next" action on a Kanban board. ```dart domain ProjectManagement { // 1. The Flow explicitly names the transition events flow TaskLifecycle { start Todo // A single event moving different states to their respective next steps on MoveNext { Todo -> InProgress InProgress -> InReview InReview -> Completed } // Multiple states sharing the same destination via a single event on Archive { Todo -> Archived InProgress -> Archived InReview -> Archived Completed -> Archived } } backend { store { model Task { id: UUID { primary, generated: true } title: String // 2. Assign the Flow as the property type status: TaskLifecycle } } } } ``` **The Compiler Advantage:** From this simple block, the compiler implicitly knows the only valid states are `[Todo, InProgress, InReview, Completed, Archived]`. You get strict linting and type safety without ever having to write a redundant Enum. ## The Execution Bridge: Explicit Signatures & Verbs To actually move the data from `Todo` to `InProgress`, you do not manually mutate a string inside your business logic. Instead, you declare the state change at the architectural level using the **`triggers`** verb inside a `function`. Because Carotene strictly avoids "magic" framework behavior, the function signature dictates exactly what is sent over the network, and the explicit verb list dictates the chronological execution sandbox. ```dart backend { // 1. Explicit Network Payload: The frontend will only send the ID function AdvanceTask(taskId: store.Task.id) { // 2. Explicit Fetch: Grants the AI permission to read the task into memory reads store.Task // 3. Explicit State Transition: Mutates the state machine in memory triggers store.Task.status.MoveNext // 4. Explicit Database Write: Commits the new state to the database updates store.Task } } ``` By explicitly requiring this chain of verbs, the AI execution sandbox is fully prepared and constrained. The AI fetches the task from the database, is structurally forced to use the compiled state machine method (e.g., `await task.transitionTo('MoveNext')`), and finally executes the update query to save it. ## Precondition Inference (Zero-Runtime Errors) Because the compiler knows exactly what Event `AdvanceTask` triggers, it knows that this function is *only valid* if the task is currently `Todo`, `InProgress`, or `InReview`. This unlocks Carotene's most powerful safety feature: **Precondition Inference**. Carotene automatically generates guardrails across your entire full-stack application to prevent illegal state changes before they ever run. ### 1. The Frontend UI Guard (`canExecute`) When Carotene generates your frontend SDK, it generates a synchronous validation method for every function. Because the `AdvanceTask` function only takes an ID over the network, the generated `canExecute` method requires the frontend to pass in the local state if it wants to perform local validation. **The AI agent uses this method when generating your UI** to automatically wire up safe interfaces without hallucinating custom validation logic: ```tsx // AI-Generated React Component using the Carotene SDK ``` This check evaluates the state machine preconditions locally in the browser, providing instant UI feedback without wasting a network request. ### 2. The Backend Ingress Shield If a malicious user bypasses the frontend and hits the API directly to advance an `Archived` task, Carotene's generated backend middleware intercepts the request. It queries the database using the provided ID, sees the entity violates the `MoveNext` precondition, and rejects it with a `400 Bad Request`*before* the business logic is ever executed. ### 3. The AI Execution Sandbox Inside the execution sandbox, the AI is structurally prevented from assigning invalid states. It does not need to write defensive `if (task.status === 'Archived') throw Error` boilerplate. It simply executes the trigger, completely guaranteed by the compiler that if the code is running, the state is mathematically valid. --- PAGE: https://carotene.dev/execution-and-guardrails/functions-and-side-effects --- # Functions & Side-Effects In Carotene, a `function` is a discrete, triggered workflow. It represents an action that runs in response to a user request or an event, and it always returns a finite result (a `Future`). Crucially, you do not write the implementation code inside your `.carrot` file. Instead, you use the `function` block to define a **Zero-Trust Permission Matrix**. You define the inputs, the outputs, and the exact side-effects the AI agent is allowed to execute. ## The Execution Sandbox When the Carotene CLI hands your function contract to the AI code generator, it builds a strictly sandboxed environment based entirely on the verbs you provide. If you do not grant a permission at the architectural level, the AI physically cannot perform the action in the codebase. ```dart domain Commerce { backend { // 1. The Signature: Defines the exact network payload (DTO vs Entity Binding) function ProcessCheckout(payload: CheckoutPayload) -> Future { // 2. The Permission Matrix (Verbs) reads store.Product // Allowed to check stock creates store.Order // Allowed to insert the new order mutates state.Metrics // Allowed to update the volatile memory cache // 3. Execution Logic implements { @("Calculate total, process payment, and create order") } } } } ``` ### How the Sandbox Works: Capabilities-Based Security Carotene does not rely on "system prompts" to keep the AI in check, nor does it rely on dynamic runtime checks that can be bypassed. It enforces Zero-Trust using Capabilities-Based Dependency Injection. When the compiler generates your `src/` implementation stub, it does not give the function global access to your database ORM or a raw fetch client. Instead, it generates a highly specific **Context** object tailored only to the verbs you declared. ```typescript // .generated/api/ProcessCheckout.ts // The compiler generates an interface omitting unauthorised methods export interface ProcessCheckoutContext { db: { Order: { create: (data: any) => Promise }, Product: { read: (id: string) => Promise } // Notice 'delete' and 'update' are physically missing }, integrations: { Stripe: { ChargeCustomer: (amount: number) => Promise } } } ``` #### 1. The Database Shield When the AI receives this `ctx` object, its environment only contains `ctx.db.Product.read()` and `ctx.db.Order.create()`. If the AI hallucinates and writes `await ctx.db.User.delete()`, the native TypeScript/Go compiler instantly fails the build because the method literally does not exist on the injected context. #### 2. The Network Proxy Raw network access (`fetch`, `axios`, `http`) is banned. All external integrations are generated as local boilerplate proxies (`ctx.integrations.Stripe...`). To the AI, charging a credit card feels exactly like calling a local, synchronous function. Because all traffic must flow through these generated proxies, Carotene can natively mock them during tests and mathematically guarantee no rogue data escapes your network boundary. ## Integrations (Managing External Side-Effects) Database access is only half the battle. Modern applications rely heavily on third-party APIs (Stripe, SendGrid, Twilio). In standard Node.js/Python, an AI can simply write `fetch('https://any-url.com')`. This is a massive security vulnerability. In Carotene, **raw HTTP requests are banned in the execution sandbox.** To talk to the outside world, you must define an `integration` and grant the AI permission to use it via the **`calls`** verb. ### 1. Defining the Integration You define external services directly inside the backend or frontend that requires them. This guarantees that your execution environments remain completely decoupled and secure. ```dart backend OrderAPI { // Scoped integrations integration Stripe { function ChargeCustomer(amount: Float, source: String) -> Future } integration SendGrid { function SendEmail(to: String, templateId: String) } function CompleteOrder(orderId: store.Order.id) { reads store.Order // Explicitly grants the AI permission to trigger these scoped side-effects calls integration.Stripe.ChargeCustomer calls integration.SendGrid.SendEmail triggers store.Order.status.ProcessPayment updates store.Order implements { @("Charge the customer, update status, and send confirmation email") } } } ``` ### 2. Granting the Side-Effect Inside your business logic, you explicitly grant the AI permission to trigger these external services using the **`calls`** verb. **The Security Guarantee:** The AI can call `ctx.Stripe.ChargeCustomer()`. But if it tries to write a raw `fetch()` or use `axios`to send data to an unauthorized URL, the sandbox rejects the code. You have total architectural control over data egress. ## Full-Stack RPC (Crossing the Network Boundary) Functions do not just live on the backend. Carotene is a full-stack language, meaning your frontend UI components need to trigger these backend workflows. You do this using the exact same `calls` verb, completely eliminating the need to write REST API clients, `fetch` wrappers, or GraphQL queries. ```dart frontend { // A UI component definition view CheckoutButton(currentOrder: backend.store.Order) { // The frontend explicitly calls the backend function, passing the exact required type calls backend.CompleteOrder implements { } } } ``` ### Auto-Generated UI States (`isLoading`) When the Carotene compiler sees a `frontend` block calling a `backend` `function`, it automatically generates the end-to-end RPC plumbing (like tRPC or gRPC). But it goes a step further for UI developers. For discrete functions (non-streams), the generated frontend SDK automatically exposes reactive listeners. Just as the state machine generates `.canExecute()`, the RPC layer generates an **`.isLoading`** property. ```dart // Inside your generated React/Vue UI component ``` By generating these properties natively in the SDK, Carotene eliminates the need for developers (and AI UI generators) to write tedious `useState(false)` boilerplate to manage network lifecycles. --- PAGE: https://carotene.dev/execution-and-guardrails/loops-and-execution --- # Continuous Execution (`loop`, `socket`) While a `function` executes once in response to a direct trigger (like a network request or a button click), a **`loop`** is an autonomous, continuous workflow. Loops are the engine behind your background workers, CRON jobs, stream listeners, and polling mechanisms. Just like functions, you do not write the implementation code. You define the *trigger conditions* and the *permissions*, and the Carotene compiler generates a strictly sandboxed, auto-scaling background process. ## Availability & Scope A loop is a continuous, autonomous process. You can define a loop in either a `backend` or `frontend` block. The Carotene compiler automatically selects the optimal infrastructure based on the context: * **backend loop:** The compiler generates a long-running server-side process, optimised for background workers, stream consumption (e.g., Redis/Kafka), or scheduled CRON jobs. * **frontend loop:** The compiler generates a high-performance client-side task, optimised for the browser main thread (e.g., `requestAnimationFrame` for game loops) or a background WebWorker (for heavy client-side computations) to keep the UI responsive. ## Defining the Trigger (`config`) Because Carotene is infrastructure-aware, it needs to know *how* this background process should run. You define this using a typed `config` block. The compiler uses this block to provision the exact underlying infrastructure (e.g., AWS EventBridge, a detached Redis worker, or a Kafka consumer). ### 1. Scheduled Execution (CRON) For tasks that need to run at specific intervals (like nightly billing or cleaning up expired sessions), you configure a `cron`loop. ```dart backend { // A background worker that runs autonomously loop AbandonedCartRecovery { config { cron: { schedule: "0 * * * *" } // Runs at minute 0 past every hour } reads store.Cart calls integration.SendGrid.SendEmail updates store.Cart implements { @("Find abandoned carts, send emails, and update their status") } } } ``` ### 2. Event-Driven Execution (Streams & Listeners) For real-time applications, you often need a worker to constantly listen for changes in your volatile `state` or listen to an external event stream. ```dart backend { // A worker that constantly processes a Redis queue loop MatchmakingWorker { config { stream: { listensTo: state.MatchmakingQueue } } // The Sandbox permissions reads state.MatchmakingQueue creates store.GameSession mutates state.MatchmakingQueue implements { @("Process matchmaking queue and create game sessions") } } } ``` ## The Sandbox & Verb Inheritance The most powerful aspect of the `loop` primitive is that it uses the **exact same Zero-Trust Permission Matrix** as a `function`. When the Carotene CLI hands your `AbandonedCartRecovery` loop to the AI code generator, the execution sandbox is built strictly from the verbs you provided. - The AI receives `ctx.db.cart.read()` and `ctx.db.cart.update()`. - The AI receives `ctx.SendGrid.SendEmail()`. If the AI hallucinates and attempts to read the `store.User` table to personalize the email, the compiler instantly fails the build. If a permission is not explicitly granted at the architectural level, the background worker physically cannot execute it. ## The Infinite Loop Guardrail (Execution Bounds) AI coding agents (and human developers) are notorious for creating background workers that get trapped in infinite loops or memory leaks, bringing down production servers. Carotene protects your infrastructure by enforcing **Execution Bounds** at the compiler level. When Carotene generates the runtime for a `loop`, it wraps the AI's implementation in a strict supervisor process. By default, Carotene enforces the following guardrails on every loop: 1. **Strict Timeouts:** If a single iteration of a `cron` loop takes longer than the default maximum (e.g., 5 minutes), the supervisor terminates the worker and logs a fatal error. 2. **Resource Limits:** If a `stream` loop detects a memory spike characteristic of an unhandled `while(true)` hallucination, the supervisor kills the process and restarts it with a clean memory heap. You can override these safety bounds explicitly in the config block if your architecture requires heavy, long-running batch processing: ```dart backend { loop HeavyVideoEncoding { config { stream: { listensTo: state.EncodingQueue timeout: "2h" // Explicitly granting a 2-hour execution bound memoryLimit: "4GB" } } reads store.VideoFile updates store.VideoFile implements { @("Encode the video file and update the status") } } } ``` By making infrastructure constraints declarative, you ensure that the AI excavator cannot accidentally deploy a worker that drains your cloud budget overnight. ## Real-Time Networking (`socket`) While `loop` handles background processing and queues, the `socket` primitive is used for continuous, bidirectional real-time communication with clients (e.g., WebSockets). A `socket` is defined with a signature that resembles a function, but its `implements` block runs *once per received message*. Returning a value from the block automatically emits that value back to the client's open stream. ```dart backend { socket HandleChat(msg: String) -> String { reads store.Message creates store.Message implements { @("Save the incoming message and return a broadcast string") } } } ``` --- PAGE: https://carotene.dev/execution-and-guardrails/verb-system --- # The Verb System Traditional programming languages give functions unlimited power by default. If a developer writes a function, that function can usually read any database table, mutate any state, or make a network request to any external server unless explicitly stopped by middleware. Carotene flips this model. Functions and Loops operate on a **Zero-Trust Permission Matrix**. By default, they have zero access to your database, zero access to your memory, and zero access to the internet. To grant the AI execution sandbox permission to do something, you must explicitly declare it using a **Verb**. ## 1. Storage Verbs (Disk Access) Storage verbs control access to your `store` (databases like Postgres or SQLite). To prevent AI coding agents from hallucinating a `for` loop and accidentally writing 10,000 duplicate rows to your database, Carotene strictly enforces **Cardinality** at the architectural level. You must explicitly declare if an operation acts on a single record or multiple records. - **`creates`**: Permission to insert exactly one row into a table. - **`createsMany`**: Permission to perform a bulk insert on a table. - **`reads`**: Permission to select and fetch data from a table into memory. - **`updates`**: Permission to modify exactly one row. - **`updatesMany`**: Permission to perform a bulk update without N+1 queries. - **`deletes`**: Permission to destroy exactly one row. - **`deletesMany`**: Permission to destroy multiple rows. *Sandbox Guardrail:* If a function is granted `creates store.User`, the injected database client will physically trap and abort the transaction if the AI attempts to call the create method more than once during execution. ## 2. Memory Verbs (RAM Access) Memory verbs control access to your volatile `state` (like Redis on the backend, or Zustand/Redux on the frontend). Because state is not durable, it uses completely different verbs than persistent storage to prevent developers from confusing RAM with Disk. - **`mutates`**: Permission to alter a reactive state slice. - **`observes`**: Permission to listen to a state slice (used primarily by `loop` to trigger event-driven background workers). ```dart frontend { function ToggleDarkMode() -> Void { // Explicit permission to change the UI RAM. // The AI cannot accidentally write this to a database. mutates state.ThemeContext implements { @("Toggle the theme context") } } } ``` ## 3. Lifecycle Verbs (State Machines) Lifecycle verbs are exclusively used to interact with a `flow` block. They bridge the gap between static data and execution. - **`triggers`**: Invokes a named Event within a strict state machine. When you use `triggers`, the Carotene compiler automatically enforces **Precondition Inference**, generating UI guardrails (`canExecute`) and backend ingress middleware to ensure the transition is mathematically valid before the AI's code ever runs. ```dart backend { function DispatchOrder(order: store.Order) -> store.Order { reads store.Order triggers order.status.Dispatch // Evaluates the state machine preconditions updates store.Order implements { @("Process the dispatch logic") } } } ``` ## 4. Action Verbs (Side-Effects) Action verbs allow your functions to cross boundaries. They are the only way to trigger logic outside of the function's immediate scope. **Raw HTTP requests (`fetch`, `axios`) are completely banned inside the AI execution sandbox.** - **`calls`**: Permission to execute another `function` or trigger an external `integration` (like Stripe or SendGrid). ```dart backend { function ProcessRefund(orderId: store.Order.id) -> Float { reads store.Order // The only way the AI is allowed to talk to the outside world calls integration.Stripe.IssueRefund implements { @("Execute the refund") } } } ``` ## 5. Security Verbs (Authorization) The final category of verbs dictates *who* is allowed to execute a workflow. - **`requires`**: Enforces an identity check before the function or loop is allowed to run. This verb is the foundation of Carotene's authentication model. If a function `requires` an identity, the Carotene compiler automatically generates the JWT verification middleware, the session checks, and the frontend redirect logic (e.g., kicking an unauthenticated user back to the login screen). ```dart backend { function DeleteAccount(user: store.User) -> Void { // Generates the auth middleware to ensure the user is logged in requires AuthenticatedUser deletes store.User implements { @("Delete the user data") } } } ``` ## 6. Contract Verbs (Post-Conditions) While the previous verbs control *what* the AI can access, contract verbs control *how* the AI's logic is bounded mathematically before it runs. - **`ensures`**: Defines an absolute mathematical boundary for the function's return value. This acts as a strict compile-time constraint, preventing the AI from returning invalid data. ```dart backend { function CalculateDiscount(total: Float) -> Float { // The AI is mathematically constrained and cannot return a negative number ensures result >= 0.0 ensures result <= total implements { @("Calculate the discount") } } } ``` --- PAGE: https://carotene.dev/execution-and-guardrails/security-and-permissions --- # Security & Permissions (`requires`) In standard web development, authentication and authorization are often the messiest parts of the codebase. A developer might remember to put JWT middleware on a route, but forget to check if the user is an "Admin" inside the actual function. If you let an AI write this logic from scratch, the chances of it hallucinating a bypass or forgetting a role check are unacceptably high. Carotene removes security logic from the implementation entirely. You define **Identities** at the architectural level, and you enforce them using the **`requires`** verb. ## Defining an Identity Just as a `model` defines the shape of your data, an **`identity`** defines the shape of your authenticated user session (the payload of your JWT or session cookie). You define this in the global scope so the compiler knows exactly what data is guaranteed to exist when a user is logged in. ```dart domain Security { // Defines the baseline authenticated user identity AuthenticatedUser { id: UUID email: String role: Enum(User, Admin) { default: User } } } ``` ## The Ingress Shield: The `requires` Verb To lock down a function or loop, you do not write `if (!req.headers.authorization) return 401`. You simply add the `requires`verb to your permission matrix. ```dart backend { function UpdateProfile(userId: store.User.id, payload: UpdateProfileDTO) { // 1. The Security Guardrail requires AuthenticatedUser // 2. The Data Guardrails reads store.User updates store.User implements { @("Update the user profile") } } } ``` ### What the Compiler Generates When the Carotene compiler sees `requires AuthenticatedUser`, it instantly generates an impenetrable **Ingress Shield**: 1. **Network Middleware:** It generates the API gateway middleware that intercepts the request, verifies the session token, and extracts the identity payload. 2. **Instant Rejection:** If the token is missing, expired, or invalid, the request is rejected with a `401 Unauthorized` before the AI's business logic is ever touched. 3. **Sandbox Injection:** If the token is valid, the verified identity is injected directly into the AI's execution context (`ctx.auth.id`). The AI does not decode tokens; it simply uses the verified data. ## Role-Based Access Control (RBAC) Checking if someone is logged in is easy; checking if they have the *right* to perform an action is where most security flaws happen. Carotene allows you to apply strict constraints directly to the `requires` verb to enforce Role-Based Access Control. You can enforce these constraints inline using a block: ```dart backend { function DeleteSystemUser(targetId: store.User.id) { // Rejects the request with a 403 Forbidden unless the role is explicitly 'Admin' requires AuthenticatedUser { role: Admin } reads store.User deletes store.User implements { @("Delete the system user") } } } ``` By putting the RBAC check in the architectural blueprint, the AI physically cannot implement `DeleteSystemUser` in a way that allows standard users to trigger it. ## The Frontend UI Guard (Unified Gatekeepers) Carotene's greatest superpower is how the backend security rules bleed perfectly into the frontend UI via the auto-generated SDK. ### 1. Visibility (`isAuthorized`) The SDK generates a standalone `.isAuthorized()` method. This is used by the frontend (and the AI UI generator) to completely hide components from users who lack the required roles. ```tex // Standard users will not even see this section in the DOM {backend.DeleteSystemUser.isAuthorized() && ( )} ``` *(Note: The Carotene Frontend SDK automatically binds the current user's session context to these methods, so you don't have to manually pass the user object into every check).* ### 2. The Master Toggle (`canExecute`) You do not need to chain security checks with state machine checks. The `.canExecute()` method acts as the **Master Gatekeeper**. Under the hood, it automatically evaluates the Precondition Inference (state machines), Zod schema validation, AND the `.isAuthorized()` rules. If a function cannot run for *any* architectural reason, `.canExecute()` returns `false`. ```tex ``` By unifying all architectural constraints into a single method, developers can build bulletproof, perfectly reactive interfaces with zero boilerplate. --- PAGE: https://carotene.dev/testing-and-reliability/test-block --- # The test block (`test`) In traditional development, you write tests to ensure *you* didn't make a mistake. In Carotene, you write tests to ensure the **AI** doesn't make a mistake. Because Carotene uses the `@(...)` Generative Operator to let the AI write your complex business logic, testing is no longer an afterthought—it is the steering wheel. The `test` block acts as an unbreakable mathematical contract. If the AI hallucinates the wrong math, the test fails, the build stops, and the compiler forces the AI to fix it autonomously. ## 1. Auto-Generated Structural Tests (Zero-Code) You do not need to write tests to verify your Carotene architecture. Because Carotene is a strictly typed blueprint, the compiler automatically generates and executes a comprehensive structural test suite based entirely on your `.carrot` files. Without you writing a single line of test code, Carotene automatically performs: - **Type Fuzzing (Input/Output):** The test runner bombards every function with edge-case data (nulls, max integers, empty strings) to guarantee it never crashes unexpectedly and that the output perfectly matches the expected `Future`. - **Schema Validation:** Ensures bad data correctly returns a `400 Bad Request`. - **RBAC (`requires`):** Proves unauthorized users get `401` or `403` errors. - **State Machines (`flow`):** Proves illegal lifecycle transitions are strictly blocked. - **Zero-Trust Sandbox:** Proves functions cannot mutate tables without explicit `updates` or `creates` verbs. If the architecture dictates it, the compiler automatically tests it. ## 2. Proofs vs. Scenarios Carotene provides two distinct ways to verify the AI's logic, each serving a different architectural purpose: ### `ensures` (Mathematical Proofs) The `ensures` primitive lives directly on the function signature. It enforces the **absolute mathematical bounds** of a single function. It does not care about your database or your business use-case; it only cares that the output is mathematically valid. If you declare `ensures result >= 0.0`, the compiler treats this as a hard system boundary. **Dynamic Data Injection (Fuzzing):** When you run `carrot generate`, if a function has an `ensures` boundary but no explicit `test` blocks exist yet, the compiler will automatically attempt to "fuzz" the function. It generates hundreds of random inputs (negative numbers, extreme integers, edge cases) and feeds them into the AI's generated logic to see if it can break the `ensures` rule. ### `test` (Human-Readable Scenarios) The `test` block is designed for multi-step, human-readable **business scenarios**. While `ensures` proves the math is safe, `test` proves the logic is *correct* for your product. You use `test` to verify the specific outputs of your `@(...)` Generative Operators and deterministic rules. #### The Testing Keywords Carotene eliminates nested boilerplate and relies on a flat `test` block with standard code execution and three specialized keywords: - **`given`**: Seeds the isolated memory sandbox with starting data. You can optionally bind this to a local variable to pass directly into your functions. - **`mocks`**: Intercepts a network boundary. If your function `calls` an external API, `mocks` prevents the request from hitting the real internet and instantly returns a designated fake value. - **`asserts`**: Verifies the final state of the database, the returned values, or network side-effects. #### Example: Testing the Generative Operator Let's write a test for our `ProcessRefund` function. We need to guarantee that the AI correctly interprets our prompt: `@("Calculate the prorated refund amount...")` and applies the deterministic rules (like the Gold Tier fee waiver). ```dart domain Commerce { // Scenario A: Standard Customer (Pays the $5 fee) test "Calculates prorated refund and deducts standard fee" { // 1. Sandboxed Data Construction given store.Customer { id: "cust_1", loyaltyTier: "Standard" } given store.Order { id: "ord_1", customerId: customer.id, items: [ { price: 100.0, returned: true } ] } // 2. Auto-Mock External Side-Effects mocks integration.Stripe.RefundPayment -> true // 3. Trigger the action (Standard function call) ProcessRefund("ord_1") // 4. Verify the AI's `@(...)` math and side-effects asserts store.Order("ord_1").status == Refunded // The item was $100, minus the $5 fee. If the AI returns $100, the build fails. asserts integration.Stripe.RefundPayment.wasCalledWith(95.0) } // Scenario B: Gold Customer (Fee is waived) test "Waives fee for Gold Tier customers" { given store.Customer { id: "cust_2", loyaltyTier: "Gold" } given store.Order { id: "ord_2", customerId: goldCustomer.id, items: [ { price: 100.0, returned: true } ] } mocks integration.Stripe.RefundPayment -> true ProcessRefund("ord_2") // The $5 deterministic fee was waived to $0. Total refund should be $100. asserts integration.Stripe.RefundPayment.wasCalledWith(100.0) } } ``` ## 3. Test-Driven Generation (TDG) When you write a `test` block, you are engaging in **Test-Driven Generation**. When you run `carrot generate` (or `carrot build` in CI), Carotene initiates an autonomous feedback loop: 1. **Generate:** The AI reads your `@(...)` operators and writes the underlying TypeScript/Go implementation. 2. **Execute:** The compiler runs the AI's generated code against your `test` blocks in a completely isolated, instantly-vaporized memory sandbox. 3. **Critique:** If an `asserts` statement fails (e.g., the AI forgot to subtract the `$5` fee, returning `100.0` instead of `95.0`), the compiler intercepts the failure and feeds the stack trace *back* to the AI. 4. **Refine:** The AI autonomously rewrites the logic and tries again. The compilation only finishes when all your tests pass green. By writing tests in Carotene, you are mathematically guaranteeing that the generated code perfectly matches your exact business requirements before a single line ever reaches production. --- PAGE: https://carotene.dev/testing-and-reliability/mocking-and-assertions --- # Deep Dive: Mocking & Assertions In traditional frameworks, the hardest part of testing isn't writing the assertions—it is managing the environment. You spend hours writing teardown scripts to clean up database rows, and you use brittle libraries like `jest.mock()` to stop your tests from accidentally charging real credit cards. Carotene eliminates environment management entirely. Every `test` block executes inside a **Vapor Sandbox**—a completely blank, in-memory universe that exists only for the millisecond that specific test runs. To manipulate this sandbox, Carotene gives you two incredibly powerful, native primitives: **`mock`** and **`asserts`**. ## 1. The `mock` Keyword (Controlling Reality) The `mock` keyword is your god-mode inside the test sandbox. It allows you to artificially construct database state and intercept external network boundaries without writing a single line of setup/teardown boilerplate. ### Mocking Database State (Dual-Binding) When you want to seed the test database, you do not use `.create()` or `.insert()`. Those imply permanent disk writes. Instead, you `mock` the record. ```dart // 1. Injects the record into the Sandbox DB. // 2. Binds the strongly-typed object to the 'vipUser' variable. vipUser = mock store.User { id: "user_1", role: "Admin", email: "admin@corp.com" } // You can now safely pass that variable directly into other mocks or functions targetOrder = mock store.Order { id: "ord_1", userId: vipUser.id // Relational binding is effortless } ``` ### Mocking External Integrations (Network Interception) If your architecture blueprint includes a `calls integration...` verb, Carotene knows exactly where the network boundary is. If you do not mock a declared integration, the test will automatically fail (to protect you from accidental real-world API calls). You use `mock` to intercept the call and instantly return a fake `Future` resolution. ```dart // Intercept the Stripe call and force it to return a successful transaction ID mock integration.Stripe.ChargeCustomer -> "txn_998877" // Force a network failure to test your Sad Path logic mock integration.Stripe.ChargeCustomer -> throws "Insufficient Funds" ``` ## 2. The `asserts` Keyword (Proving the Blueprint) Once you trigger your standard function call (e.g., `ProcessRefund(targetOrder.id)`), you use `asserts` to verify that the AI correctly mutated the sandbox and triggered the right side-effects. ### Asserting Database Mutations You can directly query the sandbox store to ensure the AI's logic resulted in the correct permanent state changes. ```dart ProcessCheckout(targetOrder.id) // Verify the status was updated asserts store.Order.find(targetOrder.id).status == Paid // Verify the AI did the math correctly asserts store.Order.find(targetOrder.id).total == 150.00 ``` ### Asserting Side-Effects (The Network Graph) Sometimes a function doesn't change the database; it just sends an email or fires a webhook. Carotene tracks every single boundary crossing in the sandbox, allowing you to assert exactly what left the system. ```dart ProcessCheckout(targetOrder.id) // Verify the integration was hit with the exact expected payload asserts integration.SendGrid.SendReceipt.wasCalledWith("admin@corp.com") // Asserting the Negative: Prove the AI didn't hallucinate an email to the wrong person asserts integration.SendGrid.SendAlert.wasNotCalled() ``` ### Asserting Errors Testing that your system correctly *rejects* bad data is just as important as testing the happy path. If your architecture includes strict rules (e.g., `throws "Refund Expired"`), you can assert that the function call itself throws an error. ```dart test "Rejects orders older than 30 days" { oldOrder = mock store.Order { id: "ord_99", ageInDays: 45 } // The assertion wraps the function execution to catch the error asserts ProcessRefund(oldOrder.id) throws "Refund Expired" // Prove that because it failed, no side-effects leaked out asserts integration.Stripe.RefundPayment.wasNotCalled() } ``` ## 3. Putting it all together (The Complete Test Matrix) Because Carotene's test syntax is so flat and declarative, you can easily read a test from top to bottom and understand exactly what business rule is being enforced. ```dart domain Commerce { test "Applies VIP discount and successfully charges card" { // 1. Mock the Environment vipUser = mock store.User { id: "user_1", role: "VIP" } cart = mock store.Cart { id: "cart_1", userId: vipUser.id, subtotal: 100.0 } mock integration.Stripe.ChargeCustomer -> true // 2. Execute the Logic ProcessCheckout(cart.id) // 3. Assert the Outcomes // VIPs get 20% off. The AI must calculate 80.0, or the build fails. asserts integration.Stripe.ChargeCustomer.wasCalledWith(80.0) // The cart should be converted to an order asserts store.Order.findBy(userId: vipUser.id).exists() asserts store.Cart.find("cart_1").status == Converted } } ``` By decoupling the data setup from the hard drive, and the network setup from the internet, Carotene's `mock` and `asserts`primitives allow you to mathematically prove your generative logic in absolute safety. --- PAGE: https://carotene.dev/testing-and-reliability/deterministic-sandbox --- # Deep Dive: The Deterministic Sandbox In a traditional framework, testing against a database or an API is a dangerous, stateful operation. You have to set up test databases, manage environment variables, and write complex teardown scripts to ensure one test doesn't pollute the next. When an AI is writing the code, the danger multiplies. You cannot simply `eval()` untrusted, AI-generated logic against your local database. To solve this, Carotene executes every `test` block inside the **Deterministic Sandbox**—an ephemeral, highly restricted runtime environment designed specifically to contain and evaluate AI-generated code safely. Because different tests require different levels of realism, Carotene provides granular control over the sandbox engine directly inside the test block. ## 1. The Dual-Engine Database Sandbox You don't need to build fake database drivers, but you also shouldn't be forced to wait for Docker containers for simple math tests. Carotene gives you two native sandbox engines to balance speed and reality. ### Engine A: The Embedded DB (Default) By default, Carotene compiles a WebAssembly (WASM) version of your database (e.g., PGLite or embedded SQLite) directly into the runtime memory of the test runner. - **The Speed:** Because it runs entirely in RAM without virtualization, a test executes in roughly `2ms`. - **The Safety:** It evaluates actual, real SQL and respects constraints, but evaporates the millisecond the test finishes. ### Engine B: The Transactional Docker DB If a specific test requires a heavy, real-world database feature that an embedded engine cannot handle (like a complex Postgres GIS spatial extension), you can upgrade the sandbox. - Carotene spins up a single, persistent Docker container in the background during `carrot build`. - For the test, the sandbox opens a database transaction (`BEGIN`), injects your `mock` data, runs the AI's function, asserts the results, and then instantly runs `ROLLBACK`. The database is wiped clean for the next test without restarting the container. ### The `config` Block You control exactly which engine is used on a per-test basis using the native `config` block. ```dart domain Commerce { // Test 1: Simple math. Use the blazing fast embedded engine. test "Calculates standard refund" { config { sandbox: PostgresEmbedded } given customer = mock store.Customer { id: "cust_1", loyaltyTier: "Standard" } // ... } // Test 2: Needs real Postgres extensions. Upgrade the sandbox. test "Calculates delivery distance via spatial query" { config { sandbox: DockerTransactional } given location = mock store.Location { lat: 40.7128, lng: -74.0060 } // ... } } ``` ## 2. The Network Guillotine (Physical Disconnection) The Carotene sandbox does not just simulate databases; it physically severs network access. When the AI compiles the code for your `@(...)` Generative Operator, the sandbox denies all outbound HTTP, TCP, and UDP traffic. The only way the code can communicate with the outside world is through the explicit `integration` boundaries you defined in your architecture. - **Forced Interception:** If your function includes `calls integration.Stripe`, the sandbox intercepts the exact moment the AI attempts to fire that request. - **Strict Enforcement:** If you provided a `mocks integration.Stripe -> true` statement in your test, the sandbox instantly returns `true`. If you *forgot* to mock the integration, the sandbox immediately kills the test with a **Sandbox Violation Error** rather than letting a rogue network request slip out to the real internet. ## 3. Sandboxed Time and Randomness A true architectural blueprint must be mathematically deterministic. If a test passes once, it must pass 100% of the time. However, AI models occasionally generate logic using `Date.now()` or `Math.random()`. In traditional testing, this causes "flaky tests" that randomly fail in your CI/CD pipeline. The Carotene Sandbox automatically controls these environmental variables: - **Frozen Time:** Inside the sandbox, the system clock is paused at a static timestamp. If you need to test time-based logic, you can explicitly fast-forward sandbox time using standard test configuration (e.g., `config { time: "2026-01-01" }`). - **Seeded Randomness:** Any calls to random number generators are automatically seeded, ensuring the AI's logic produces the exact same output on your local machine as it does on a remote server. ## 4. The Autonomic Feedback Loop The Sandbox is not just a protective measure; it is the engine that drives **Test-Driven Generation (TDG)**. Because you have granular control over the sandbox weight, Carotene can run a continuous, autonomic loop at blazing speeds: 1. The LLM generates the initial code. 2. The Sandbox evaluates the code against your test constraints. 3. If an `asserts` statement fails, the Sandbox captures the exact state of memory, the stack trace, and the failed value. 4. The Sandbox feeds this deterministic proof directly back to the LLM. 5. The LLM refines the code, and the Sandbox tests it again. By the time you see the green `Build Successful` message in your terminal, the AI and the Sandbox have already negotiated, debated, and perfected the implementation in milliseconds, entirely out of sight. --- PAGE: https://carotene.dev/tooling-and-ai/carotene-cli --- # The Carotene CLI (`carrot`) In traditional development, you piece together a toolchain: you use `npm` to install dependencies, `tsc` to compile TypeScript, `jest` to run tests, and `prisma` to manage database schemas. Carotene replaces all of this with a single, unified binary: the **Carotene CLI**. The CLI is the engine that bridges the gap between your human-readable architectural blueprints (`.carrot` files) and the final, production-ready microservices. It acts as the compiler, the test runner, and the AI agent. ## Core Commands ### `carrot init ` **The Dynamic Scaffolder** This command initializes a blank Carotene workspace. It sets up your global `carotene.toml` configuration and creates your first `system.carrot` blueprint. It does not generate rigid framework folders; instead, it waits for you to define your architecture, and then dynamically scaffolds the monorepo to perfectly match your definitions. It also automatically generates a `.clinerules` file in the project root. This ensures that any external AI coding assistants you use are immediately aware of Carotene's architectural rules and strict Zero-Trust constraints. ### `carrot introspect ` **The Reverse-Architecture Engine** If you have an existing application, you do not need to write your `.carrot` files from scratch. Point this command at your legacy `src/` directory. The AI will ingest your entire codebase, map the dependency graphs, identify your database schemas, and output a complete suite of `.carrot` blueprints representing your current architecture. **The Safety Guarantee:** Every function, frontend view, and loop generated by this command is automatically flagged with the **`@manual`** decorator. This ensures that running `carrot generate` will *never* overwrite your existing code. It simply maps your architecture, allowing you to gradually migrate specific functions to `@ai` ownership one endpoint at a time. ### `carrot dev` **Static Analysis and Zero-Trust Linting** This is the command you will run frequently during contract writing. It costs $0 and uses zero AI tokens. `carrot dev` instantly verifies your types, paths, and verbs across the entire architecture. 1. Ensures all referenced models and properties exist. 2. Verifies that functions declare the correct Zero-Trust verbs (`reads`, `calls`, etc.) for their internal logic constraints. 3. Checks for cyclic dependencies and domain isolation violations. ### `carrot generate` **The Autonomic Development Loop** This is the command that actually invokes the LLM. It starts the Test-Driven Generation (TDG) engine in watch mode. When you save a `.carrot` file (or a `src/` file), `carrot generate` triggers the autonomic loop: 1. Provisions the Vapor Sandbox. 2. **Performs Hash-Detection:** Checks if you manually edited any AI-owned `src/` files and prompts you to claim `@manual` ownership if necessary. 3. Prompts the authenticated LLM to synthesize your `@(...)` Generative Operators against your `ensures` rules and `test` blocks. 4. Runs your `test` blocks against the generated code. 5. Autonomously feeds failures back to the LLM until the assertions pass. **Example Output:** ``` $ carrot generate [~] Parsing system.carrot... [~] Provisioning embedded PGLite sandbox... [~] Generating logic for CoreAPI.ProcessRefund() ... [!] Assertion Failed: Expected 95.0, Got 100.0. Retrying (Attempt 2/5)... [✔] Logic Verified. [✔] Zero-Trust Guardrails Enforced. [🚀] CoreAPI running on http://localhost:4000 ``` ### `carrot build` **The Production Compiler** While `carrot dev` creates implementation stubs and runs tests, `carrot build` is meant for your CI/CD pipeline. It strictly verifies that every test passes, every `@(...)` operator is successfully implemented, and every Zero-Trust boundary is respected. It then compiles the raw, dependency-free TypeScript or Go code into the `.generated/` folders, ready for deployment. As part of the build pipeline, `carrot build` also automatically executes `carrot generate:docs`, outputting comprehensive API documentation and architecture maps into a `.docs/` folder (this behavior can be opted out of in `carotene.toml`). ## Security & Inspection Commands Because Carotene's core philosophy is built around the Zero-Trust Sandbox, the CLI provides powerful tools to visualize and audit your system's security perimeter. ### `carrot inspect ` **The Blast Radius Auditor** When reviewing code, security engineers need to know exactly what a function can touch. This command statically analyzes a function's verbs (`reads`, `updates`, `calls`) and outputs a clear visual matrix of its permissions. **Example Output:** ``` $ carrot inspect ProcessRefund 🔍 Security Audit: CoreAPI.ProcessRefund -------------------------------------------------- [✔] READS : store.Order, store.Customer [✔] UPDATES : store.Order [✔] CALLS : integration.Stripe [✖] CREATES : (None) [✖] DELETES : (None) 🔒 RBAC Rules applied: - requires session.role == Admin -------------------------------------------------- Status: Secure. Sandbox strictly bounded. ``` ### `carrot login` **Carotene Cloud Authentication** Authenticates your CLI with the Carotene Managed Cloud. This is used if your `carotene.toml` is set to `mode = "managed"`. It provisions a secure token allowing the compiler to use Carotene's hosted, highly optimised generation pipeline without you needing to manage individual Anthropic or OpenAI billing accounts. ## Configuration Management ### `carrot keys` **BYOK Secrets Manager** If you are using `mode = "byok"`, you should not hardcode your API keys into your `.carrot` or `.toml` files. The `keys` command securely stores your third-party LLM tokens in your operating system's native secure enclave (e.g., macOS Keychain, Windows Credential Manager). ```bash $ carrot keys:add anthropic $ carrot keys:list [✔] anthropic (Configured) [ ] openai (Missing) $ carrot keys:remove anthropic ``` ### `carrot generate:sdk ` If you are building a decoupled frontend (like a mobile app) that lives outside the Carotene monorepo, you can use this command to instantly generate a strongly-typed client SDK based on your `backend` blueprints. ```bash carrot generate:sdk swift --out ./ios-app/Network carrot generate:sdk kotlin --out ./android-app/API ``` --- PAGE: https://carotene.dev/tooling-and-ai/mcp-server --- # The Carotene MCP Server The Carotene CLI (`carrot dev`) is incredibly powerful for background compilation and CI/CD, but modern developers live inside their IDEs. You don't want to switch back and forth between a terminal and your editor just to see what the AI generated for your `@(...)` operator. To solve this, Carotene natively implements the **Model Context Protocol (MCP)**. The Carotene CLI includes a built-in MCP Server that allows next-generation, AI-native IDEs (like Cursor, Windsurf, or VS Code with Copilot) to directly interact with the Carotene compiler, the architecture blueprints, and the Vapor Sandbox. ## What is the Carotene MCP Server? Normally, an AI in your code editor just reads the raw text of the file you have open and guesses what to write next. This leads to hallucinations—the AI might generate a SQL query for a table that doesn't exist, or import a library you haven't installed. The Carotene MCP Server bridges this gap. It exposes specific **Tools** and **Resources** directly to your editor's AI, giving it a flawless, mathematically rigorous understanding of your entire system architecture. ### Core MCP Tools Exposed to the AI When you connect your IDE to the Carotene MCP Server, the AI gains access to three critical capabilities: 1. **`read_architecture` (Context Injection)** The AI does not need to guess your database schema. When it looks at a `.carrot` file, the MCP server feeds it the exact, strongly-typed relationships defined in your `model`, `store`, and `flow` blocks across your entire workspace. 2. **`resolve_operator` (Targeted Generation)** Instead of trying to rewrite your entire file, the IDE's AI knows how to target the exact `@(...)` Generative Operator. It uses this tool to scope its generation strictly to the "Code Hole" you created, leaving your deterministic rules untouched. 3. **`execute_sandbox` (Invisible Iteration)** This is the killer feature. Before the IDE types a single line of code onto your screen, it can silently use this tool to pass its draft code to the 2ms Vapor Sandbox. The MCP server runs the code against your `test` assertions and returns the stack trace directly to the IDE's AI. The AI fixes its own bugs in the background and only shows you the final, mathematically proven code. ------ ## Setting Up the MCP Server Because the MCP server is bundled directly inside the CLI binary you already installed, setup takes seconds. You simply start the server via your terminal, or configure your AI-native editor to boot it automatically. ### Example: Connecting to Cursor If you are using Cursor, you can add Carotene as a persistent MCP server. 1. Open Cursor Settings -> Features -> MCP. 2. Click **+ Add New MCP Server**. 3. Name it `Carotene`. 4. Set the type to `command` and the command to: ```bash carrot mcp --stdio ``` That's it. Cursor is now fully aware of the Carotene framework, the Zero-Trust execution model, and the Vapor Sandbox. ------ ## The Developer Experience (DX) Once the MCP Server is connected, your IDE transforms from a text editor into a true Systems Architect workspace. **1. You write the Blueprint:** You define a new backend function and leave an operator: ```dart discount = @("Calculate a tiered volume discount based on the user's past 30 days of orders") ``` **2. You write the Proof:** You drop a `test` block at the bottom of the file with your `mock` data and `asserts`. **3. You trigger the IDE AI:** You hit `Cmd+K` (or your editor's equivalent) and press Enter. **4. The Invisible Loop:** - You will see the AI "thinking." - Behind the scenes, the editor uses the `read_architecture` tool to understand what an "order" is. - It writes a draft in TypeScript/Go. - It uses the `execute_sandbox` tool. It fails because it forgot a specific edge-case. - It rewrites the code and tests it again. It passes. **5. The Reveal:** The IDE instantly injects the correct, fully-tested business logic right into your `src/` implementation stub, and your terminal shows a green build. You never had to debug a hallucination, and the AI never had to guess your database schema. --- PAGE: https://carotene.dev/tooling-and-ai/generating-code --- # Generating Code In Carotene, you do not write business logic; you write architectural boundaries and generative intent. But how does the framework actually translate your intent into deterministic, production-ready code? Carotene does not just blindly send your entire file to an LLM and cross its fingers. The generation engine is a highly structured compiler pipeline that treats the AI as a pure logic synthesizer, strictly bounded by the rules of your architecture. Here is the exact lifecycle of how Carotene generates your code. ## 1. Micro-Context Injection (Parsing the Blueprint) When you run `carrot generate`, the Carotene compiler first acts like a traditional language compiler. It parses your `.carrot` files into an **Abstract Syntax Tree (AST)**. Unlike tools like Claude Code or Cursor, Carotene **never sends your entire codebase to the LLM**. Instead, when the compiler discovers a "Code Hole"—your `@(...)` Generative Operator—it builds a highly focused **Context Matrix** for that specific hole. It gathers: - The exact types of the input arguments. - The expected return type of the function. - The explicit mathematical `ensures` rules. - The database schemas (`models`) the function is allowed to `read` or `update`. - The external `integrations` it is allowed to `call`. - The specific test `asserts` statements that apply to this function. ## 2. The Prompt Assembly Carotene does not use generic "Write me a function" prompts. It uses the Context Matrix to construct a mathematically precise system prompt. If you wrote: ```dart function CalculateDiscount(userId: String) -> Float { ensures rule.ValidDiscount(result) implements { discount = @("Calculate a tiered volume discount based on past orders") return discount } } ``` Carotene builds a prompt that looks like this under the hood: > **System:** You are a deterministic logic synthesizer. Your output will be executed in a zero-trust sandbox. > > **Language:** TypeScript > > **Context:** > > - Input: `userId: string` > > - Allowed DB Access: `store.Order (fields: id, userId, total, date)` > > - Return Type Expected: `number` > > - **Mathematical Constraints (`ensures`):** The output MUST satisfy `result >= 0.0` and `result <= 100.0`. > > **Task:** Write the internal logic to satisfy the following intent: *"Calculate a tiered volume discount based on past orders"*. > > **Constraints:** Do not write network code. Do not write SQL connections. Return ONLY the raw mathematical logic to calculate the discount. Notice how the compiler automatically unpacks the mathematical limits from the referenced `rule.ValidDiscount` block and injects them as hard system constraints before the AI writes line 1. By hyper-focusing the context, Carotene completely eliminates the risk of the AI hallucinating external libraries, guessing incorrect database table names, writing boilerplate you didn't ask for, or returning out-of-bounds values. ## The Generation Lifecycle & Code Ownership Carotene bridges the gap between AI generation and manual coding using a strict **Two-Way Sync** model. The framework generates read-only TypeScript/Go interfaces in the `.generated/` folder, and implementation stubs in the `src/` folder. By default, the Carotene compiler assumes **AI Ownership** over the `src/` stubs. When the `.carrot` contract changes, the compiler invokes the LLM and overwrites the implementation stub to match the new requirements. ### Smart Sync & Manual Overrides You are never locked out of your own code. If the AI is struggling to implement a specific function, or you have a proprietary algorithm you want to write by hand, you can simply open the generated `src/` file and write the logic yourself. Carotene strictly protects human code using **Hash-Detection**: 1. **The Hash Check:** When you run `carrot build` or `carrot dev`, the compiler checks the cryptographic hash of every `src/` file against a local `.carotene/cache`. 2. **Detection:** If it detects manual edits in a file that is currently owned by the AI, it immediately halts generation for that specific file to protect your work. 3. **The CLI Intercept:** The CLI issues an interactive prompt in your terminal: ```bash [!] Manual edits detected in AI-managed files. The following files have been modified outside of the Carotene compiler: - src/auth/LegacySSO.ts ? How would you like to proceed? (Use arrow keys) ❯ Set as @manual in contract (Preserve edits and ignore in future) Overwrite file (Discard manual edits and regenerate via AI) Skip for now (Do not regenerate this run) ``` 4. **Auto-Sync:** If you choose "Set as `@manual`", the CLI automatically injects the `@manual` decorator above that function in your `.carrot` file. The compiler will now permanently ignore this file during AI generation. *Note: Even when a file is `@manual`, Carotene continues to strictly enforce its inputs and outputs. If the contract signature changes later, your native compiler (TypeScript/Go) will flag the exact lines in your manual code that need to be updated to satisfy the new `.generated/` interface.* ## The Implementation Stub When you open your generated `src/` files, you will see exactly how Carotene enforces the Zero-Trust boundary. The function signature includes a strictly-typed `Context` object. ```typescript // apps/order-service/src/commerce/ApplyDiscount.ts import { ApplyDiscountContext } from '../../.generated/carotene-runtime'; // The Context object contains ONLY the permitted database and network methods export async function ApplyDiscount(userId: string, ctx: ApplyDiscountContext): Promise { // --- CAROTENE GENERATED: "Calculate a tiered volume discount based on past orders" --- // The AI uses the strictly-bound context object const pastOrders = await ctx.db.Order.readMany({ userId }); const totalVolume = pastOrders.reduce((sum, order) => sum + order.total, 0); if (totalVolume > 5000) return 0.20; if (totalVolume > 1000) return 0.10; return 0.00; // -------------------------------------------------------------------------------------- } ``` ## Best Practices for the `@(...)` Operator Because the AI's output is directly tied to the quality of your prompt, treating the Generative Operator with care is essential. - **Keep it scoped:** Do not ask an operator to "Build the whole checkout flow." Break it down. Use deterministic code to check the user's role, and use `@(...)` just to calculate the complex tax math. - **Be mathematically explicit:** Instead of saying `@("Make the text sound nice")`, say `@("Format the string as Title Case and append the localized currency symbol")`. - **Let the architecture do the heavy lifting:** You never need to tell the AI how to fetch data or save data. Carotene's variables already handle that. Use the operator strictly for data *transformation*. --- PAGE: https://carotene.dev/tooling-and-ai/self-onboarding --- # Self-Onboarding & Documentation The hardest part of joining a new engineering team isn't learning the language; it is learning the architecture. You have to trace through hundreds of files just to figure out how a simple `User` model relates to an `Order`. In Carotene, the architecture is not hidden in the implementation. It is explicitly declared in your `.carrot` files. Because these files are designed to be perfectly readable by both humans and the Carotene AI Compiler, the framework itself becomes your Senior Architect and your Technical Writer. ## 1. The `carrot ask` Command If you are a new developer opening a massive Carotene monorepo for the first time, you don't need to hunt for the documentation. The codebase *is* the documentation. You can use the native `carrot ask` command to query the architecture directly from your terminal. ```bash $ carrot ask "If I want to refund an order, what function do I call and what permissions do I need?" ``` Because Carotene understands the Abstract Syntax Tree (AST) of your blueprints, it doesn't hallucinate. It reads the exact state of your current `commerce.carrot` file and responds with precision: > **Carotene AI:** > > To refund an order, you should call the `ProcessRefund(orderId: String)` function located in the `CoreAPI`backend. > > **Security Requirements:** > > - You must pass an active session. > - `requires session.role == Admin` > > **Side Effects:** > > - It will update `store.Order.status` to `Refunded`. > - It will call `integration.Stripe.RefundPayment`. ## 2. Auto-Generated Architecture Diagrams Visual learners often need to see the system to understand it. In traditional teams, system diagrams are drawn manually in Figma or Miro and become outdated the day after they are created. Carotene can generate pixel-perfect, mathematically accurate architecture diagrams on the fly: ```bash $ carrot generate:diagram --domain commerce --format html ``` This command parses your `model`, `flow`, and `backend` blocks and outputs an interactive visual map showing how tables relate, what state transitions are legal, and which external integrations your backends are wired to. ## 3. IDE Context (The MCP Server) As discussed on the previous page, the Carotene MCP Server injects your architecture directly into AI-native editors like Cursor or VS Code. This means a Junior Developer can open a file, highlight an implementation stub, and ask their IDE: *"Why did the AI use the `Stripe` integration here instead of `PayPal`?"* The IDE, armed with the Carotene Context Matrix, will instantly reply: > *"Because the `commerce.carrot` blueprint strictly limits the `ProcessRefund` function to `calls integration.Stripe`. If I attempted to use PayPal, the Zero-Trust Sandbox would reject the build."* ## 4. Auto-Generated Documentation Portals For enterprise teams or open-source projects, a terminal command isn't always enough. You need a searchable, highly readable website. Because Carotene knows every model, function, side effect, and Zero-Trust boundary in your system, it can generate a complete static documentation site with a single command. ```bash $ carrot generate:docs --engine vitepress --out ./docs # (Also supports --engine docusaurus) ``` **What it generates:** - **API References:** Complete, typed documentation for every `backend` function, including request/response payloads. - **Security Matrices:** A visual breakdown of the RBAC `requires` rules and Zero-Trust verbs (`reads`, `updates`, `calls`) for every endpoint. - **Data Dictionaries:** A full breakdown of your `store` models and `flow` state machines. - **Embedded Diagrams:** The interactive diagrams from Step 2 are automatically embedded into the relevant pages. You can instantly deploy this `docs/` folder to Vercel, Netlify, or GitHub Pages. Because it compiles directly from your `.carrot` files, your documentation is mathematically guaranteed to be 100% accurate to your production code. --- PAGE: https://carotene.dev/reference/language-syntax --- # Language Syntax The `.carrot` file is a strictly typed, declarative architectural blueprint. It is designed to be highly readable for humans, mathematically parsable by the Carotene compiler, and semantically perfect for the LLM generation engine. This page serves as the complete syntax reference for the Carotene language. ## 1. Top-Level Declarations Every `.carrot` file must contain at least one target architecture block (`backend` / `frontend`) or data primitive. ### `domain` (Optional Namespace) Acts as an organisational namespace for grouping related models, stores, and state machines. * **If omitted:** All primitives are registered to the **Global Namespace**. Use this for small projects or simple prototypes. * **If used:** All internal primitives are scoped to the domain name. Use this to prevent naming collisions in large monorepos. *Note: `domain` does not dictate your folder structure or deployment architecture; it is purely a compile-time naming convention.* ```dart // Global Namespace (No domain block) model User { ... } // Scoped Namespace domain Commerce { model Order { ... } } ``` ### `backend` / `frontend` Defines a physical microservice or application target. The name you provide here dictates the folder name generated dynamically in your monorepo. * **`backend`**: Internal service mesh APIs. * **`frontend`**: User-facing web or mobile applications. ```dart backend CoreAPI { // Functions go here } frontend AdminDashboard { // Views go here } ``` ## 2. Namespace Resolution & Referencing Carotene uses strict lexical scoping to resolve references between frontends, backends, and data stores. You reference primitives using dot-notation paths. To keep your code clean, Carotene supports **Relative Pathing**. You can omit parent names if you are referencing something within the same scope. ### Absolute vs. Relative Paths Imagine the following architecture: ```dart domain Commerce { backend OrderAPI { store { model Order { id: UUID } } function Process() { ... } } frontend Web { ... } } ``` * **Absolute Path:** If you are outside the domain entirely, you must use the full path: `Commerce.OrderAPI.store.Order`. * **Same Domain:** If you are inside the `Web` frontend, you can drop the domain name: `calls OrderAPI.Process`. * **Same Backend:** If you are inside another function in `OrderAPI`, you drop the backend name: `reads store.Order`. ### Unnamed Blocks If a block does not have a custom name, you simply use the keyword itself in the path. ```dart // Unnamed backend and unnamed store backend { store { model User { id: UUID } } } frontend { // Uses the literal keywords 'backend' and 'store' view Profile(user: backend.store.User) { ... } } ``` ### Property Access You can dot all the way down to specific model properties, which is highly recommended for function arguments to ensure perfect type alignment. ```dart // Binds the argument directly to the UUID type of the Order's ID function GetOrder(orderId: store.Order.id) -> store.Order { reads store.Order implements { ... } } ``` ## 3. Decorators (Execution Ownership) Decorators define *who* is responsible for implementing a block of code. They can be applied to any structural block (`domain`, `backend`, `frontend`, `function`, or `loop`). * **`@ai` (Implicit Default):** The Carotene compiler will actively manage the `src/` files for this block. It will invoke the LLM to synthesise the `@("...")` generative operators and overwrite the file if the contract description or signature changes. * **`@manual`:** The compiler will generate the initial empty stub and strict native interfaces, but it will *never* invoke the AI or overwrite the `src/` file. Ownership is permanently yielded to the human developer. ### Inheritance and Scoping Decorators cascade downwards. The most specific decorator wins. ```dart // 1. The entire backend is manual @manual backend PaymentAPI { // Inherits @manual. Hand-written by a developer. function ProcessRefund() -> Float { implements { tax = @("Calculate the 5% processing fee") } } // 2. Specific Override: This single function delegates back to the AI @ai function FormatCurrency(amount: Float) -> String { implements { formatted = @("Format as USD") } } } ``` ## 4. Data & State Primitives These blocks define the strict shapes and permitted lifecycles of your data. They can be declared globally or inside a `domain`. ### `model` Defines a data structure. Models are purely abstract and are not inherently connected to a database. - **Supported Primitives:** `String`, `Int`, `Float`, `Boolean`, `UUID`, `Date`, `JSON`. - **Optional Fields:** Suffix with `?`. ```dart model User { id: UUID email: String age: Int? } ``` ### `flow` Defines a deterministic finite state machine. ```dart flow OrderState { Pending -> Paid Paid -> Shipped Paid -> Refunded } ``` ### `store` Binds a `model` to the physical database, exposing it to the Carotene runtime. ```dart store Customer { model: User } ``` ### `rule` Defines a reusable mathematical proof or constraint at the domain level. This keeps your contracts DRY by allowing multiple functions to share the exact same bounds. ```dart rule ValidDiscount(val: Float) { asserts val >= 0.0 asserts val <= 100.0 } ``` ## 5. Execution Primitives These blocks define the actual executable APIs and autonomous workflows. Both are available in `backend` and `frontend` blocks; the compiler infers the runtime infrastructure (e.g., CRON vs. `requestAnimationFrame`) based on the context. ### `function` (Event-Driven) Defines an event-driven workflow. Arguments must be strictly typed, often referencing `store` or `model` fields directly. Explicit return types (e.g., `-> Float`) are strictly enforced and act as the primary compile-time constraint, rendering basic type-checking assertions inside the function unnecessary. ```dart function ProcessRefund(orderId: store.Order.id) -> Float { reads store.Order implements { // Logic goes here } } ``` ### `ensures` Defines mathematical post-conditions and absolute bounds for a function's return value directly in the signature. This guarantees the AI cannot return an invalid value. ```dart function CalculateDiscount(total: Float) -> Float { // The AI cannot return a negative number or a number greater than the total ensures result >= 0.0 ensures result <= total // Or invoke a shared domain rule ensures rule.ValidDiscount(result) implements { @("Calculate the exact discount") } } ``` ### The Fast-Path Shorthand (`=>`) For simple, deterministic execution logic, you can use the expression-bodied shorthand `=>` to eliminate boilerplate. Functions that use this shorthand are statically analyzed and do not require explicit Zero-Trust permission verbs. ```dart // UI Component view Button(label: String, onClick: Function) = @("Render a button.") // Deterministic Function function UpdateName(val: String) => state.User.name = val ``` ### `socket` (Real-Time Bidirectional) Defines a continuous, bidirectional handler. The `implements` block runs once per received message, and returning a value automatically emits it back to the client's open stream. ```dart socket HandleChat(msg: String) -> String { reads store.Message implements { @("Process the message and return the response") } } ``` ### `loop` (Continuous) Defines a continuous, autonomous background workflow. ```dart loop MatchmakingWorker { config { stream: { listensTo: state.PlayerQueue } } reads state.PlayerQueue updates store.Match implements { @("Match players together") } } ``` ## 6. Security & Permission Primitives These blocks define the Zero-Trust boundaries of your system. ### `gateway` Defines an ingress boundary for external traffic or programmable controls. Gateways must be defined *inside* a `backend` or `frontend` block. They act as routers, mapping external API URLs (and parameters) directly to functions defined in your architecture. Gateways support protocol-specific routing blocks (such as `rest { }` for HTTP methods and paths, or `rpc { }`) to map incoming external endpoints explicitly to your internal functions. ```dart backend CoreAPI { function ProcessStripeWebhook(payload: JSON) -> Boolean { ... } gateway ExternalAPI { rest { POST "/webhooks/stripe" -> ProcessStripeWebhook() } } } ``` ### `integration` Defines an external software API, SDK, or hardware device. * **Scope:** Must be defined inside a `backend` or `frontend` block to prevent cross-boundary secret leakage. * **Usage:** Exposes external methods that can be triggered using the `calls` verb. ### `requires` (RBAC) Immediately evaluates a condition. If it returns false, the function immediately terminates with an HTTP `401` or `403`. ```dart requires session.isAuthenticated == true requires session.role == "Admin" ``` ### The Zero-Trust Verbs Explicitly declare what the function or loop is allowed to touch. If a verb is omitted, the Sandbox will physically block the action. - **`reads`**: Allows querying a specific store. - **`updates`**: Allows mutating an existing record in a store. - **`creates`**: Allows inserting a new record into a store. - **`deletes`**: Allows removing a record from a store. - **`calls`**: Allows outbound network requests to a defined integration. ```dart reads store.Customer updates store.Order calls integration.Stripe ``` ## 7. Internal Logic & Variables Inside a `function` or `loop`, you can write deterministic logic to handle fast-paths, assignments, and validation. ### Variable Assignment Standard assignment. Types are inferred automatically by the compiler. ```dart customer = store.Customer.find(customerId) fee = 5.0 ``` ### Conditionals (`if` / `else`) Standard control flow. ```dart if (customer.tier == "Gold") { fee = 0.0 } else { fee = 5.0 } ``` ### `error` Defines a strongly typed error primitive. Can be used for declarative error handling across boundaries. ```dart error InsufficientFunds { shortfall: Float } ``` ### `throws` Immediately terminates the function and returns an error payload. Used for business logic validation. ```dart if (order.ageInDays > 30) { throws "Refund window has expired" } if (wallet.balance < cost) { throws error.InsufficientFunds({ shortfall: cost - wallet.balance }) } ``` ### `catches` Used to catch strongly typed errors thrown by the backend or an integration. ```dart backend.Process(id) catches InsufficientFunds (err) { implements { @("Handle the insufficient funds error by displaying a message") } } ``` ### The Generative Operator (`@`) The "Code Hole". Instructs the compiler to securely pass the bounded context to the configured LLM to synthesize the underlying implementation. ```dart // Assignment generation discount = @("Calculate the prorated volume discount") // Fire-and-forget generation @("Format the customer's address and map it to the Shipping target") ``` ### `triggers` Executes a state machine transition defined in a `flow`. If the transition is illegal, it throws an error. ```dart triggers targetOrder.status.Refunded ``` ### `return` Outputs the final payload of the function to the client. ```dart return discount ``` ## 8. Testing Primitives The `test` block is a flat structure used to mathematically prove the AI's logic inside the Deterministic Sandbox. Tests can be placed anywhere in a `.carrot` file. ### `test` Defines the test scenario. ```dart test "Calculates the correct discount" { // Test code goes here } ``` ### `config` Configures the Sandbox environment for the specific test block. - **`sandbox` options:** `EmbeddedWASM` (Default, ~2ms), `DockerTransactional` (Heavy, real-world DB features). - **`time`:** Freezes the sandbox clock to a specific string. ```dart config { sandbox: EmbeddedWASM time: "2026-01-01" } ``` ### `given` / `mock` Seeds the isolated sandbox or intercepts external boundaries. - Use `given... = mock store...` to seed the database and bind a local variable simultaneously. - Use `mock integration... -> value` to intercept a network boundary and return a fake `Future`. - Use `throws` to simulate network errors. ```dart // Database Mocking & Binding given user = mock store.User { id: "1", role: "Admin" } // Network Mocking (Success) mock integration.Stripe.Charge -> "txn_123" // Network Mocking (Failure) mock integration.SendGrid.Send -> throws "Timeout" ``` ### `asserts` Evaluates a mathematical truth at the end of the test. If false, the AI is prompted to fix the code. ```dart // Asserting variable output asserts result == 100.0 // Asserting Sandbox database state asserts store.User.find("1").status == Active // Asserting network side-effects asserts integration.Stripe.Charge.wasCalledWith(100.0) asserts integration.Stripe.Refund.wasNotCalled() // Asserting errors asserts ProcessRefund(order.id) throws "Refund window has expired" ``` --- PAGE: https://carotene.dev/reference/typed-config-reference --- # Typed config Reference (`carotene.toml`) In traditional ecosystems, configuring a project requires a fragmented mess of files: `package.json`, `tsconfig.json`, `.prettierrc`, `jest.config.js`, and `docker-compose.yml`. Carotene replaces all of this with a single, strictly typed control plane: **`carotene.toml`**. This file dictates how the Carotene compiler generates your monorepo, which AI provider powers your Generative Operators, and how your sandboxes and production environments connect to physical infrastructure. ## 1. `[project]` Defines the core metadata for your monorepo workspace. ```toml [project] name = "enterprise-billing-system" version = "1.0.0" authors = ["Platform Team "] description = "Core billing and invoice generation architecture." ``` - **`name`**: (Required) The root name of your monorepo. - **`version`**: Semantic versioning for your architecture. - **`authors`**: List of maintainers. ## 2. `[compiler]` Instructs the Carotene CLI on how to translate your `.carrot` blueprints into physical code inside the `.generated/` and `src/`directories. ```toml [compiler] target = "typescript" # Options: "typescript", "go" out_dir = "./apps" # Where the monorepo apps are generated strict_null_checks = true # Enforces rigorous type safety in generated code ``` - **`target`**: (Required) The physical language the compiler writes. - **`out_dir`**: The root directory where your dynamic `backend` and `frontend` folders are placed. Defaults to `./apps`. - **`strict_null_checks`**: If true, prevents the AI from generating code that ignores `?` optional fields in your models. ## 3. `[ai]` Configures the default intelligence engine that resolves your `@(...)` Generative Operators when running `carrot dev` or `carrot build`. ```toml [ai] # The execution mode: "byok" (Bring Your Own Key), "managed" (Carotene Cloud), or "local" mode = "byok" # If mode is "byok", define the provider and model provider = "anthropic" # Options: "anthropic", "openai", "google", "custom" model = "claude-3-5-sonnet" # If using a custom or local endpoint (like Ollama or LMStudio) # endpoint = "http://localhost:11434/v1" temperature = 0.0 # Locked to 0.0 for maximum determinism max_retries = 5 # Sandbox autonomic correction limit ``` * **`mode`**: Determines how the CLI routes generation. If set to `managed`, it requires a valid session via `carrot login`. If `byok`, it looks for keys configured via `carrot keys:add`. * **`provider` & `model`**: Explicitly defines the LLM to use. * **`endpoint`**: Allows you to override the base URL, enabling completely offline AI generation using local models. * **`temperature`**: Defaults to `0.0`. Carotene overrides high temperatures to ensure mathematical determinism during the build step. * **`max_retries`**: The maximum number of autonomic correction loops the Vapor Sandbox will run before failing the build. ## 4. `[sandbox]` Configures the default behavior for the Vapor Sandbox during Test-Driven Generation. (Note: You can override these settings on a per-test basis inside a `.carrot` file). ```toml [sandbox] default_engine = "EmbeddedWASM" # Options: "EmbeddedWASM", "DockerTransactional" timeout_ms = 5000 # Sandbox execution timeout per test network_strict = true # If true, unmocked network calls fail instantly ``` ## 5. `[environments]` This block is how Carotene maps the abstract `store` and `integration` definitions from your blueprints to actual, physical URLs and API keys. Carotene securely injects environment variables using the `env()` wrapper, ensuring secrets are never checked into version control. ### `[environments.development]` Used automatically when running `carrot dev`. ```toml [environments.development] database = "sqlite://.carotene/local.db" [environments.development.integrations] Stripe = "sk_test_12345" SendGrid = "mock_sendgrid_key" ``` ### `[environments.production]` Used during `carrot build` or when deploying the generated application. ```toml [environments.production] database = "postgres://env(DB_USER):env(DB_PASS)@env(DB_HOST)/env(DB_NAME)" [environments.production.integrations] Stripe = "env(STRIPE_SECRET_KEY)" SendGrid = "env(SENDGRID_API_KEY)" ``` - **`database`**: The connection string mapped to your `store` primitives. - **`integrations`**: Maps the external APIs declared in your `calls` verbs to physical API keys. If a `calls` verb exists in your architecture but the key is missing here, the compiler will warn you. --- PAGE: https://carotene.dev/reference/error-registry --- # Error Registry In traditional Node.js or Python environments, errors often manifest as cryptic stack traces referencing files buried ten directories deep inside a `node_modules` folder. Carotene errors are different. Because the language is a strictly typed architectural blueprint, errors are designed to be immediately actionable. When the compiler or the Vapor Sandbox catches a failure, it tells you exactly which boundary was crossed, which AI operator failed, or which constraint was violated. This registry outlines the core error codes thrown by the Carotene CLI. ## 1. Compiler & Syntax Errors (E1000s) These errors occur immediately when you save a file. They indicate that your `.carrot` blueprint is structurally invalid. ### `E1001: TypeMismatch` **Cause:** You attempted to assign a value to a variable or field that does not match its strictly defined type in the `model`. **Fix:** Ensure the assignment matches the schema. Remember that optional fields (`String?`) must be handled safely. ```dart // Error: Cannot assign Int to String user.email = 12345 ``` ### `E1002: UnresolvedReference` **Cause:** You referenced a `model`, `store`, or `integration` that has not been defined in your workspace or current namespace. **Fix:** Check your spelling or ensure the target domain is properly exported. ### `E1003: OrphanedOperator` **Cause:** You placed a Generative Operator (`@(...)`) outside of a valid execution block (like a `function` or `test`). The AI cannot generate code without a surrounding execution context. ## 2. Zero-Trust & Boundary Errors (E2000s) These are static analysis errors. The compiler catches them *before* passing your code to the AI or the Sandbox. ### `E2001: VerbViolation` **Cause:** You (or the AI) attempted to perform a database mutation or network call that was not explicitly authorized by your Zero-Trust verbs (`reads`, `updates`, `creates`, `deletes`, `calls`). **Fix:** Add the required verb to the top of your function block. ```dart // Fix: Add `updates store.Order` to the function function Refund(orderId: store.Order.id) { updates store.Order // <-- Missing this caused E2001 implements { targetOrder = store.Order.find(orderId) triggers targetOrder.status.Refunded } } ``` ### `E2002: IllegalStateTransition` **Cause:** You used the `triggers` keyword to push a model into a state that is not explicitly allowed by its `flow` definition. **Fix:** Update your `flow` block to permit the transition, or correct the business logic. ## 3. Generative AI Errors (E3000s) These errors occur during `carrot dev` or `carrot build` when the LLM is attempting to resolve your `@(...)` operators. ### `E3001: GenerativeResolutionFailed` **Cause:** The Vapor Sandbox executed the AI's generated code, but it failed your `asserts` statements. The Sandbox fed the error back to the AI, but after reaching the `max_retries` limit (default: 5), the AI could not produce passing code. **Fix:** Your prompt is likely too ambiguous, or your test assertions are mathematically impossible. Rewrite the `@(...)` text to be more explicit. ### `E3002: ContextExhausted` **Cause:** The Context Matrix required to generate your operator exceeds the token limit of your configured AI provider. This usually happens if you give a single function access to 50 different database tables. **Fix:** Break your function down into smaller, single-responsibility functions. ## 4. Sandbox & Testing Errors (E4000s) These errors are thrown by the Deterministic Sandbox when running your `test` blocks. ### `E4001: NetworkGuillotineTriggered` **Cause:** The function you are testing attempted to make an outbound HTTP request (via an `integration`), but you did not intercept it with a `mock` keyword in your test block. The Sandbox physically severed the connection. **Fix:** Add `mock integration.[Name] -> [Value]` to your test block. ### `E4002: AssertionFailed` **Cause:** The executed code did not match your explicit `asserts` statement. **Output:** The CLI will provide a deterministic diff showing exactly what was expected versus what actually happened in the sandbox memory. ``` [E4002] Assertion Failed at line 42: Expected: 95.0 Received: 100.0 ``` ### `E4003: SandboxTimeout` **Cause:** The generated code caused an infinite loop or took longer than the configured timeout limit (default 5000ms). **Fix:** If you are running a heavy query, increase the timeout in the `config {}` block. Otherwise, prompt the AI to avoid unbounded loops. ## 5. Runtime Security Errors (HTTP Codes) When your Carotene app is compiled and running in production, it automatically maps structural security rules to standard HTTP errors. - **`400 Bad Request`:** Thrown automatically if an incoming JSON payload fails to strictly match the defined `model`schema, or if you explicitly use the `throws` keyword. - **`401 Unauthorized`:** Thrown automatically if an endpoint is called but the `session` object is missing or invalid. - **`403 Forbidden`:** Thrown automatically if a `requires` statement (RBAC) evaluates to `false` (e.g., `requires session.role == Admin`). --- PAGE: https://carotene.dev/reference/standard-library --- # Standard Library In a traditional backend language like Node.js or Go, the standard library is massive. It includes file system access (`fs`), low-level networking (`net`), and buffer management. Carotene operates at a higher architectural level. Because functions execute inside a Zero-Trust Sandbox, you do not have raw access to the file system or the network. Instead, Carotene provides a focused, highly optimized Standard Library designed specifically for writing fast, deterministic business rules before handing off complex logic to the `@(...)`Generative Operator. Here are the built-in modules available globally inside any `function` block. ## 1. `session` (Execution Context) The `session` object is a globally available primitive that contains the context of the user triggering the function. It is primarily used alongside the `requires` keyword for RBAC (Role-Based Access Control). - **`session.isAuthenticated`** `(Boolean)`: True if the request provided a valid auth token. - **`session.userId`** `(UUID?)`: The ID of the authenticated user. Null if anonymous. - **`session.role`** `(String?)`: The permission tier of the user (e.g., "Admin", "User"). - **`session.ip`** `(String)`: The IP address of the incoming request. ```dart requires session.isAuthenticated implements { if (session.role != "Admin") { throws "Insufficient privileges" } } ``` ## 2. `Time` (Deterministic Dates) Handling dates and times in traditional languages often leads to flaky tests. The Carotene `Time` module is entirely deterministic. When running in a `test` block, it automatically respects the Sandbox's frozen clock. - **`Time.now()`** `-> Date`: Returns the current UTC timestamp (or the frozen Sandbox time). - **`Time.addDays(date: Date, days: Int)`** `-> Date`: Adds or subtracts days. - **`Time.isAfter(date1: Date, date2: Date)`** `-> Boolean`: Compares two timestamps. - **`Time.format(date: Date, format: String)`** `-> String`: Outputs a formatted string (e.g., "YYYY-MM-DD"). ```dart implements { order = store.Order.find(orderId) returnWindow = Time.addDays(order.createdAt, 30) if (Time.isAfter(Time.now(), returnWindow)) { throws "Return window has closed" } } ``` ## 3. `Crypto` (Security & Hashing) Carotene abstracts away the complexity of choosing the right hashing algorithms (like bcrypt or Argon2) by providing natively secure primitives. - **`Crypto.hashPassword(plain: String)`** `-> String`: Generates a salt and hashes the password using industry-standard algorithms. - **`Crypto.verifyPassword(plain: String, hash: String)`** `-> Boolean`: Safely compares a password attempt against a hash. - **`Crypto.generateUUID()`** `-> UUID`: Generates a secure, v4 UUID. - **`Crypto.sha256(data: String)`** `-> String`: Generates a standard SHA-256 hash for data integrity. ```dart // Usually utilized in Identity domains updates store.User implements { targetUser.passwordHash = Crypto.hashPassword(newPassword) } ``` ## 4. `Math` (Sandboxed Calculations) Like the `Time` module, the `Math` module is built for testing safety. Any randomness generated here is automatically seeded during `carrot dev` and `carrot build` to ensure your AI generation loops remain deterministic. - **`Math.round(val: Float, decimals: Int)`** `-> Float`: Rounds a float to a specific decimal place. - **`Math.floor(val: Float)`** `-> Int`: Rounds down to the nearest whole number. - **`Math.ceil(val: Float)`** `-> Int`: Rounds up to the nearest whole number. - **`Math.random()`** `-> Float`: Returns a pseudo-random float between 0 and 1. (Seeded in sandbox). ```dart // Ensuring exact currency formatting before Stripe charges implements { finalAmount = Math.round(cart.total, 2) } ``` ## 5. `Future` (Asynchronous Handlers) While Carotene hides most async/await boilerplate behind standard assignment (`customer = store.Customer.find(id)` is implicitly awaited), the `Future` object is required when mocking network integrations or handling explicitly deferred tasks. - **`Future.resolve(value: Any)`**: Instantly resolves with a specific value. Used extensively in `mock` statements. - **`Future.reject(error: String)`**: Instantly fails with an error string. ```dart // Intercepting an integration to test a successful future mock integration.Stripe.Charge -> Future.resolve("txn_999") // Testing a network failure mock integration.Stripe.Charge -> Future.reject("Card Declined") ``` --- PAGE: https://carotene.dev/cookbook/crud-web-app --- # Cookbook: Simple CRUD Web App In traditional frameworks, building a CRUD (Create, Read, Update, Delete) API is a tedious rite of passage. You have to set up a router, define an ORM schema, write controller functions, wire up validation middleware, and write boilerplate tests. In Carotene, CRUD is almost entirely declarative. You define the data shape, lock down the security boundaries, and use the Generative Operator (`@`) to handle the annoying data-formatting tasks. Let's build a fully secure, tested headless CMS for a company blog in a single file. ## 1. The Architecture Blueprint We start by defining our domain, our data shape, and the physical database store. ```dart domain Content { // 1. The Data Shape model Post { id: UUID title: String slug: String content: String authorId: UUID isPublished: Boolean createdAt: Date } // 2. The Physical Storage store Post { model: Post } } ``` ## 2. The Backend Endpoints Next, we define the `backend` block containing our four CRUD operations. Notice how we use the Zero-Trust verbs (`creates`, `reads`, `updates`, `deletes`) to strictly bound what each endpoint is allowed to do. ```dart backend CMSApi { // ========================================== // CREATE // ========================================== function CreatePost(title: store.Post.title, content: store.Post.content) -> store.Post { requires session.isAuthenticated creates store.Post ensures result.authorId == session.userId implements { // Use the Generative Operator to handle string manipulation slug = @("Convert the ${title} into a URL-friendly lowercase slug, replacing spaces with hyphens and removing special characters.") newPost = store.Post { id: Crypto.generateUUID() title: title slug: slug content: content authorId: session.userId isPublished: false createdAt: Time.now() } return newPost } } // ========================================== // READ // ========================================== function GetPost(targetSlug: store.Post.slug) -> store.Post { reads store.Post implements { // Anyone can read, but we must ensure it exists and is published targetPost = store.Post.findBy(slug: targetSlug) if (!targetPost.exists()) { throws "Post not found" } if (targetPost.isPublished == false && session.role != "Admin") { throws "You do not have permission to view drafts" } return targetPost } } // ========================================== // UPDATE // ========================================== function UpdatePostContent(postId: store.Post.id, newContent: store.Post.content) -> store.Post { requires session.isAuthenticated updates store.Post implements { targetPost = store.Post.find(postId) // Only the author or an Admin can edit the post if (targetPost.authorId != session.userId && session.role != "Admin") { throws "Unauthorized to edit this post" } targetPost.content = newContent return targetPost } } // ========================================== // DELETE // ========================================== function DeletePost(postId: store.Post.id) -> Boolean { requires session.role == "Admin" // Strict override: Only Admins can delete deletes store.Post implements { store.Post.find(postId).delete() return true } } } ``` ## 3. The Proof (Business Logic Tests) Because we used the Generative Operator to handle the URL slug generation in `CreatePost`, we need to write a test to mathematically guarantee the AI generates the string formatting code correctly. We will also test our RBAC (Role-Based Access Control) to ensure our security logic holds up in the Vapor Sandbox. ```dart // Test 1: AI Slug Generation test "Generates a clean URL slug on creation" { // 1. Mock an active user session given mock session { userId: "user_123", isAuthenticated: true } // 2. Trigger the action result = CreatePost("Hello World! Welcome to 2026.", "This is the content.") // 3. Assert the AI correctly synthesized the slugification logic asserts result.slug == "hello-world-welcome-to-2026" asserts store.Post.find(result.id).exists() } // Test 2: Security Validation test "Blocks anonymous users from reading unpublished drafts" { // 1. Mock an unauthenticated session given mock session { isAuthenticated: false, role: "Guest" } // 2. Mock a draft post in the database given mock store.Post { id: "post_1", slug: "secret-draft", isPublished: false } // 3. Assert the endpoint physically rejects the request asserts GetPost("secret-draft") throws "You do not have permission to view drafts" } ``` ## 4. Compile and Deploy With exactly 85 lines of highly readable text, you have architected a production-ready microservice. When you run `carrot generate`: 1. The CLI provisions the database schema for `Post`. 2. It generates a perfectly typed REST/tRPC router for `CMSApi`. 3. It prompts the AI to write the Regex/string-manipulation code for the `slug`. 4. It spins up the Sandbox, runs the tests, verifies the slug generation, and ensures the security rules return `403` errors when violated. The output is zero-dependency, highly optimized TypeScript or Go code resting in your `.generated/` folder, ready to be deployed. --- PAGE: https://carotene.dev/cookbook/iot-thermostat --- # Cookbook: Real-time IoT Thermostat In a standard stack, building an IoT backend is a nightmare of infrastructure. You have to set up cron jobs or message brokers (like Kafka/RabbitMQ) just to poll sensor data, write complex state machines to ensure the heater doesn't fight the AC, and manage race conditions when a user tries to override the temperature from their phone. In Carotene, time-based execution and state management are native primitives. You don't need external polling servers; you just use a `loop` block and let the Vapor Sandbox guarantee the state transitions. Here is a complete, real-time smart thermostat backend. ## 1. The Architecture Blueprint We start by defining the physical state of the device. Because an HVAC system physically cannot be heating and cooling at the exact same time, we define a strict `flow` state machine to prevent catastrophic hardware commands. ```dart domain HomeAutomation { // 1. The Hardware Guardrail // Mathematically prevents the AC and Heater from running simultaneously. flow HVACMode { on Change { Idle -> Heating Idle -> Cooling Heating -> Idle Cooling -> Idle } } // 2. The Device State model Thermostat { id: UUID currentTemp: Float targetTemp: Float mode: HVACMode lastPing: Date } store Thermostat { model: Thermostat } } ``` ## 2. The Continuous Execution Loop Instead of setting up external cron jobs, Carotene allows you to define background processes natively using the `loop`keyword. This loop runs every minute, reads external weather data to optimize energy usage, and adjusts the physical HVAC mode. ```dart backend IoTGateway { // We declare an external integration to fetch local weather integration WeatherAPI { GetOutsideTemp(zipcode: String) -> Float } // ========================================== // AUTONOMIC LOOP (Runs every 1 minute) // ========================================== loop OptimizeClimate { config { interval: "1m" } reads store.Thermostat updates store.Thermostat calls integration.WeatherAPI triggers store.Thermostat.mode.Change implements { device = store.Thermostat.find("device_1") // Assuming a single-home setup for simplicity outsideTemp = integration.WeatherAPI.GetOutsideTemp("90210") // The Generative Operator handles the complex thermodynamic prediction logic // rather than us writing nested IF statements for insulation, delta-T, etc. idealMode = @("Compare the device's currentTemp to the targetTemp, factoring in the outsideTemp. Return 'Heating', 'Cooling', or 'Idle' to reach the target most efficiently.") // Only apply the change if a transition is needed if (device.mode != idealMode) { device.mode = idealMode } device.lastPing = Time.now() } } } ``` ## 3. The User Override (Mobile App API) We also need a standard API endpoint so the user can open their phone and change the target temperature manually. ```dart backend MobileAPI { // ========================================== // MANUAL OVERRIDE // ========================================== function SetTargetTemperature(deviceId: store.Thermostat.id, newTarget: store.Thermostat.targetTemp) -> Boolean { requires session.isAuthenticated updates store.Thermostat implements { device = store.Thermostat.find(deviceId) // Hard constraint: Don't freeze or boil the house if (newTarget < 50.0 || newTarget > 90.0) { throws "Target temperature out of safe bounds" } device.targetTemp = newTarget return true } } } ``` ## 4. The Proof (Testing Time and State) To test this, we need to prove two things: that the AI correctly predicts the needed HVAC mode based on outside weather, and that our strict `flow` prevents illegal state changes. ```dart // Test 1: AI Thermodynamic Logic test "Turns on Heating when house is cold and outside is freezing" { config { sandbox: EmbeddedWASM } // 1. Mock the device currently sitting idle at 60 degrees given mock store.Thermostat { id: "device_1", currentTemp: 60.0, targetTemp: 72.0, mode: Idle } // 2. Mock the Weather API returning a freezing temperature mock integration.WeatherAPI.GetOutsideTemp -> 30.0 // 3. Manually trigger one iteration of the loop trigger loop OptimizeClimate // 4. Assert the AI correctly chose to trigger the Heater asserts store.Thermostat.find("device_1").mode == Heating } // Test 2: Hardware Safety Guardrails test "Rejects unsafe manual temperature overrides" { given mock session { isAuthenticated: true } given mock store.Thermostat { id: "device_1", targetTemp: 72.0 } // Assert the manual override fails with our exact error message asserts SetTargetTemperature("device_1", 100.0) throws "Target temperature out of safe bounds" } ``` ## 5. Compile and Deploy When you run `carrot generate`: 1. The compiler maps the `loop` to a highly optimized background worker in Go or TypeScript. 2. It generates the REST/RPC endpoint for the mobile app. 3. It uses the LLM to write the predictive logic comparing `currentTemp`, `targetTemp`, and `outsideTemp`. 4. It runs the Sandbox tests to mathematically guarantee the house will actually start heating when it gets cold, and that a user cannot set their app to 100 degrees. --- PAGE: https://carotene.dev/cookbook/game-engine --- # Cookbook: Multiplayer 3D Game Engine When developers think of web frameworks, they usually think of HTTP requests and JSON payloads. Building a real-time multiplayer game backend is an entirely different beast. You need high-frequency server ticks (60Hz), WebSockets for low-latency UDP-like streaming, and aggressive server-side validation to prevent players from cheating. In traditional stacks, this means abandoning your web framework entirely and writing custom C++ or Rust servers. Because Carotene executes via an ultra-fast compiled WASM engine and handles `loop` primitives natively, you can actually architect an authoritative 3D multiplayer server right alongside your standard web APIs. Here is a secure, authoritative 60Hz game server in a single file. ## 1. The Architecture Blueprint We start by defining our 3D space and the entities within it. Because a game state updates 60 times a second, we don't want to save this to a slow physical Postgres database. We use a `state` block instead of a `store`, meaning Carotene will manage it entirely in the high-speed RAM of the Vapor Runtime. ```dart domain Arena { // 1. Core Data Structures model Vector3 { x: Float y: Float z: Float } model Player { id: UUID position: Vector3 velocity: Vector3 isGrounded: Boolean health: Int } // 2. The In-Memory Game World state GameWorld { model: Player } } ``` ## 2. The Authoritative Server Tick Multiplayer games do not trust the client. If a player moves forward, they don't send their new position; they send their *input* (velocity), and the server calculates where they should be. We use a high-frequency `loop` to represent our 60Hz server tick. This loop calculates gravity, applies velocity, and handles collision for every player simultaneously. ```dart backend GameServer { // ========================================== // THE 60Hz SERVER TICK (Physics Loop) // ========================================== loop PhysicsTick { config { interval: "16ms" } reads state.GameWorld updates state.GameWorld implements { allPlayers = state.GameWorld.all() // We use the Generative Operator to handle 3D vector math and basic collision. // The AI synthesizes the heavy math into the underlying C/Rust/Go layer. newStates = @("Iterate over 'allPlayers'. Apply a gravity vector of -9.8 to the Y-axis if 'isGrounded' is false. Add 'velocity' to 'position' taking a 16ms delta-time into account. Prevent the Y position from dropping below 0 (the floor).") // Batch update the RAM store with the new calculated positions state.GameWorld.batchUpdate(newStates) } } } ``` ## 3. High-Frequency Input (WebSocket / UDP) To handle continuous player input, standard HTTP `function` blocks are too slow. Carotene provides the `socket` primitive to establish persistent, low-latency connections. This endpoint receives joystick/keyboard input and updates the player's velocity in RAM, but it strictly limits the maximum speed to prevent "speed hacks." ```dart backend GameServer { // ========================================== // PLAYER INPUT HANDLER // ========================================== socket HandleInput(playerId: UUID, inputVector: Vector3) -> Void { requires session.isAuthenticated requires session.userId == playerId // You can only move yourself updates state.GameWorld implements { player = state.GameWorld.find(playerId) // Calculate the magnitude of the input vector inputSpeed = Math.sqrt((inputVector.x * inputVector.x) + (inputVector.z * inputVector.z)) // Anti-Cheat: Max movement speed is 5.0 units per second if (inputSpeed > 5.0) { throws "Speed hack detected" } player.velocity = inputVector } } } ``` ## 4. The Proof (Anti-Cheat Validation) Game logic is notoriously difficult to test because it relies on time and physics math. Because the Carotene Sandbox can freeze time and perfectly control the execution environment, writing an anti-cheat test is trivial. We will test that a player cannot exploit the input handler, and that gravity actually works during the physics tick. ```dart // Test 1: Anti-Cheat Input Validation test "Instantly rejects velocity inputs that exceed max speed" { given mock session { userId: "player_1", isAuthenticated: true } given mock state.GameWorld { id: "player_1", position: {x: 0, y: 0, z: 0} } // A cheater tries to inject a massive velocity vector cheaterInput = { x: 100.0, y: 0.0, z: 100.0 } // Assert the socket drops the packet and flags the cheat asserts HandleInput("player_1", cheaterInput) throws "Speed hack detected" } // Test 2: AI Physics Generation test "Gravity pulls airborne players to the floor" { config { sandbox: EmbeddedWASM } // 1. Mock a player hovering in the air (Y: 10.0) given mock state.GameWorld { id: "player_1", position: { x: 0.0, y: 10.0, z: 0.0 }, velocity: { x: 0.0, y: 0.0, z: 0.0 }, isGrounded: false } // 2. Trigger exactly one 16ms server tick trigger loop PhysicsTick // 3. Assert the AI correctly applied gravity math (Y should be slightly less than 10.0) postTickPlayer = state.GameWorld.find("player_1") asserts postTickPlayer.position.y < 10.0 } ``` ## 5. Compile and Deploy When you run `carrot generate`: 1. The compiler sees the `state` block and generates an ultra-fast Redis or local WASM memory pool instead of Postgres. 2. It translates the `socket` primitive into a highly optimized WebSocket (or WebRTC data channel) listener. 3. The AI synthesizes your `@(...)` prompt into optimized 3D vector math. 4. The Sandbox runs a simulated server tick, proving mathematically that gravity works and cheaters are caught. --- PAGE: https://carotene.dev/cookbook/microservices --- # Cookbook: High-Scale Microservices In traditional systems, microservices are a source of endless "plumbing" anxiety. You have to configure service meshes, manage mTLS certificates, write client-side retries, and handle distributed transaction failures. If the `Inventory` service goes down, the `Order` service crashes in a way that is incredibly hard to debug. Carotene abstracts the infrastructure layer entirely. When you define an internal communication boundary, the compiler automatically generates the secure gRPC or mTLS-encrypted transport layer. You don't connect services; you declare **architectural dependencies.** ## 1. The Architectural Blueprint In this scenario, we are building a distributed E-commerce system. We have a public-facing `OrderService` that must reach out to a strictly private, internal `InventoryService` to reserve stock. By defining both services in the same monorepo, Carotene understands the internal topology and handles the networking automatically. ```dart // apps/order-service/orders.carrot backend OrderService { // We define an internal integration integration InventoryService { ReserveStock(itemId: store.Stock.id, qty: store.Stock.count) -> Boolean } function Checkout(orderId: store.Order.id) -> Boolean { reads store.Order calls integration.InventoryService // <-- This is the cross-service boundary implements { order = store.Order.find(orderId) // The Generative Operator handles the distributed transaction logic // (e.g., Saga pattern or 2-phase commit) @("Call InventoryService to reserve stock. If it fails, roll back the order status.") return true } } } ``` ## 2. The Internal Service (Encapsulation) The `InventoryService` remains completely hidden from the internet. It does not expose a public API; it only responds to internal calls from authorized services within your infrastructure. ```dart // apps/inventory-service/stock.carrot backend InventoryService { function ReserveStock(itemId: store.Stock.id, qty: store.Stock.count) -> Boolean { updates store.Stock implements { stock = store.Stock.find(itemId) if (stock.count < qty) { throws "Out of stock" } stock.count = stock.count - qty return true } } } ``` ## 3. The Proof (Testing Distributed Systems) Testing microservices is historically difficult because you usually have to "docker-compose up" the entire universe. In Carotene, you don't do that. You use the `mock` primitive to intercept the internal `calls` boundary. You test the `OrderService` as if the `InventoryService` exists, without ever needing to actually spin it up. ```dart // apps/order-service/tests/Checkout.test.carrot test "OrderService handles Inventory failure gracefully" { given mock store.Order { id: "order_1" } // 1. Mock the internal service boundary to return a failure mock integration.InventoryService.ReserveStock -> false // 2. Execute the function result = Checkout("order_1") // 3. Assert the order was correctly handled (e.g., status is 'Failed') asserts store.Order.find("order_1").status == "Failed" } ``` ## 4. Compile and Deploy When you run `carrot generate`: 1. **Infrastructure Generation:** Carotene generates the Kubernetes ingress rules, the internal mTLS certificates, and the gRPC client/server stubs for `InventoryService`. 2. **Type Safety:** If the `InventoryService` signature changes (e.g., you rename `itemId` to `productId`), the `OrderService` will fail to compile immediately. The contract is strictly enforced across the monorepo. 3. **Sandbox Validation:** The compiler verifies that the `OrderService` has the `calls integration.InventoryService`permission. If it doesn't, the build fails. 4. **Resiliency:** The AI logic synthesized for the `@(...)` operator automatically includes retry logic and rollback stubs, ensuring that your distributed system doesn't leave data in an inconsistent state if a request times out. --- PAGE: https://carotene.dev/cookbook/brownfield-endpoint --- # Cookbook: The Brownfield Endpoint One of the biggest misconceptions about new frameworks is that you have to rewrite your entire application to use them. Carotene is designed for **incremental adoption**. If you have an existing Next.js, Express, or Spring Boot application, you do not need to replace your database, your auth stack, or your frontend to use Carotene. You can drop Carotene in to generate the logic for a **single, highly-complex endpoint** (like an AI agent, a complex pricing calculator, or a PDF generator) and proxy requests to it from your existing application. ## 1. The Architecture Blueprint In this scenario, we have a legacy Node.js/Express application. We want to add a new AI-powered feature: a "Smart Recipe Generator" that takes a list of ingredients and returns a structured recipe. Instead of writing this complex prompt engineering and validation logic in Node.js, we define a single `gateway` and `backend` in Carotene. We don't define a `store` because we are passing the data directly in the request payload. ```dart // smart-recipe.carrot backend RecipeService { // We define the strict expected output format model Recipe { title: String prepTimeMinutes: Int instructions: [String] dietaryTags: [String] } // Define the integration to the AI provider integration OpenAI { GenerateJSON(prompt: String, schema: JSON) -> JSON } // This function takes raw ingredients and returns a strict Recipe function GenerateRecipe(ingredients: [String]) -> Recipe { calls integration.OpenAI // Mathematical bounds to prevent infinite loops or absurd outputs ensures result.prepTimeMinutes > 0 ensures result.prepTimeMinutes <= 180 ensures result.instructions.length > 0 implements { // The Generative Operator instructs the AI developer (Carotene) to write the implementation. // We instruct it to use the OpenAI integration to generate the recipe. recipe = @("Construct a prompt asking a professional chef to create a creative recipe using ONLY the provided 'ingredients'. Call the OpenAI integration with the prompt and the Recipe JSON schema, and parse the returned JSON into the Recipe model.") return recipe } } // We expose this specific function as an HTTP endpoint gateway ProxyIngress { rest { POST /api/v1/generate-recipe -> GenerateRecipe } } } ``` ## 2. The Proof (Testing the Logic) Before we integrate this into our Express app, we write a `test` block to ensure the Generative Operator reliably outputs the correct schema and respects our `ensures` bounds. ```dart test "Generates a valid recipe from basic ingredients" { // We don't need a database, just pass the ingredients myIngredients = ["Eggs", "Flour", "Milk", "Cheese"] result = GenerateRecipe(myIngredients) // Verify the AI respected the type schema and bounds asserts result.title != "" asserts result.prepTimeMinutes > 0 asserts result.instructions.length > 2 } ``` ## 3. The Brownfield Integration When you run `carrot generate`, Carotene builds a standalone, zero-dependency microservice containing just this endpoint. You can run this Carotene service on an internal port (e.g., `8080`) or deploy it as a Serverless function. Then, in your existing Node.js/Express app, you simply proxy the request to the Carotene endpoint. Your existing app handles the authentication, session management, and rate limiting. ```javascript // Your existing Express.js App (app.js) const express = require('express'); const axios = require('axios'); const { requireAuth } = require('./middleware/auth'); const app = express(); app.use(express.json()); // Legacy endpoints remain untouched app.get('/api/users', requireAuth, (req, res) => { ... }); // New AI Feature: Proxy to Carotene app.post('/recipes/smart-generate', requireAuth, async (req, res) => { const { ingredients } = req.body; try { // Call the locally running Carotene microservice const caroteneResponse = await axios.post('http://localhost:8080/api/v1/generate-recipe', { ingredients }); // Carotene guarantees the response matches the Recipe schema res.json(caroteneResponse.data); } catch (error) { res.status(500).json({ error: "Recipe generation failed" }); } }); ``` ## 4. The Result By using Carotene as a "sidecar" for complex logic generation: 1. **Zero Rip-and-Replace:** Your existing stack, database, and auth remain entirely unchanged. 2. **Guaranteed Output:** Carotene's strict type system and `ensures` bounds guarantee that your Express app will always receive a perfectly formatted JSON `Recipe` object, preventing frontend crashes from malformed LLM outputs. 3. **Painless Prompt Engineering:** You didn't have to write manual validation logic, retry loops, or system prompts in Node.js. Carotene handled the entire generative lifecycle automatically. --- PAGE: https://carotene.dev/cookbook/legacy-migration --- # Cookbook: Legacy Codebase Migration Migrating an enterprise application to a new framework is usually a multi-year nightmare. You have to rewrite the entire application from the ground up, run it in parallel, and pray you didn't miss any edge cases. Carotene flips this model upside down using **Reverse Blueprint Extraction**. You can ingest your legacy codebase, generate the architectural guardrails, and selectively hand over ownership to the AI function by function, file by file. Here is how you onboard a legacy API into the Carotene ecosystem. ## 1. Introspect the Codebase Let's say you have an aging Express.js/Sequelize codebase governing your company's billing system. You start by pointing the Carotene CLI at your source folder. ```bash $ carrot introspect ./legacy-billing-api/src ``` Carotene's AI engine analyzes your routes, your database models, and your middleware. In a few minutes, it generates a `billing.carrot` file that maps your exact physical architecture into Carotene's strict DSL. ## 2. Review the Generated Blueprint When you open the generated `billing.carrot` file, you will notice two things: 1. Carotene successfully mapped your data shapes and Zero-Trust boundaries. 2. Every execution block is protected by the **`@manual`** decorator. ```dart domain Billing { backend BillingAPI { store { model Invoice { id: UUID amount: Float status: String } } // Carotene flagged this as manual. It recognizes the inputs, outputs, // and database interactions, but will NOT attempt to overwrite your legacy code. @manual function ProcessInvoice(invoiceId: store.Invoice.id) -> Boolean { reads store.Invoice updates store.Invoice implements { // Points to your existing legacy file file: "./legacy-billing-api/src/controllers/processInvoice.js" } } } } ``` At this stage, you are actively using Carotene. Running `carrot dev` will strictly lint your legacy architecture to ensure your existing Express code isn't violating its own boundaries, but the AI will not write a single line of code. ## 3. The Surgical Takeover You decide that the `ProcessInvoice` logic is buggy, full of technical debt, and needs a rewrite. You want the Carotene compiler to take over. You do this in three steps: 1. Change `@manual` to **`@ai`**. 2. Add strict mathematical bounds (`ensures`). 3. Replace the legacy file reference with a Generative Operator (`@`). ```dart domain Billing { backend BillingAPI { // 1. Transfer ownership to the AI Compiler @ai function ProcessInvoice(invoiceId: store.Invoice.id) -> Boolean { reads store.Invoice updates store.Invoice // 2. Enforce absolute mathematical safety before the rewrite ensures rule.ValidTransaction(result) implements { // 3. Drop the code hole. The AI will now synthesize the new logic. return @("Fetch the invoice, calculate late fees (if any), and mark as paid.") } } } } ``` ## 4. Compile and Verify When you run `carrot generate`: 1. Carotene ignores all the remaining `@manual` functions, leaving your legacy code untouched. 2. It zeroes in on `ProcessInvoice`. 3. It provisions the Vapor Sandbox, writes the new logic in clean, highly-optimized TypeScript, and runs it against the fuzzed `ensures` bounds to guarantee safety. You have successfully replaced a piece of legacy tech debt with mathematically verified, AI-generated code without taking your application offline or executing a massive rewrite.