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. The compiler extracts the domain and adds it to a Domain Allowlist.
domain Commerce {
integration Stripe {
// The compiler strictly validates OpenAPI properties
config openapi {
url: "https://api.stripe.com/v1"
auth: "env.STRIPE_SECRET_KEY"
}
function CreateCharge(amount: Float) -> Future<String>
}
backend {
function Checkout() {
// The AI is allowed to call the integration
calls integration.Stripe.CreateCharge
}
}
}The Sandbox Guarantee: If the AI implements the Checkout function and tries to import a native HTTP library to send a payload to https://evil-server.com, the Carotene linter instantly fails the build. The runtime sandbox physically blocks any network request not explicitly whitelisted in your integration blocks.
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.
# Automatically converts a Swagger file into a Carotene integration block
carotene import openapi stripe-spec.json --name StripeThe 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.
domain SmartThermostat {
integration TemperatureSensor {
// The compiler strictly validates I2C hardware properties
config i2c {
address: "0x76"
pins: [4, 5]
}
function ReadContinuous() -> Stream<Float>
}
backend Firmware {
config rust { target: "aarch64-unknown-linux-gnu" }
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.
// 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.
integration Stripe {
config openapi { url: "https://api.stripe.com/v1" }
function CreateCharge(amount: Float) -> Future<String> {
// 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 callsverb and returns the mock data. Only when you explicitly flag a build for production does the framework compile the real network adapter.