Skip to content

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) ​

Acts as a namespace wrapper for grouping related models, stores, and state machines. It is entirely optional; if omitted, all primitives are registered to the global namespace. It does not dictate folder structure; it simply prevents naming collisions across large codebases.

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.

dart
backend CoreAPI {
  // Functions go here
}

frontend AdminDashboard {
  // Views go here
}

2. 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
}

3. Execution & Security Primitives ​

These blocks define the actual executable APIs and their Zero-Trust boundaries. They must be declared inside a backendblock.

function ​

Defines an executable endpoint. Arguments must be strictly typed, often referencing store or model fields directly.

dart
function ProcessRefund(orderId: store.Order.id) {
  // Logic goes here
}

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 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

4. Internal Logic & Variables ​

Inside a function, 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(customerId)
fee = 5.0

Conditionals (if / else) ​

Standard control flow.

dart
if (customer.tier == "Gold") {
  fee = 0.0
} else {
  fee = 5.0
}

rejects with ​

Immediately terminates the function and returns an HTTP 400 Bad Request with the specified message. Used for business logic validation.

dart
if (order.ageInDays > 30) {
  rejects with "Refund window has expired"
}

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

5. 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("1").status == Active

// Asserting network side-effects
asserts integration.Stripe.Charge.wasCalledWith(100.0)
asserts integration.Stripe.Refund.wasNotCalled()

// Asserting rejections
asserts ProcessRefund(order.id) fails with "Refund window has expired"