./01 Introduction

Ship
Fast.
Break Nothing.

We take AI-generated codebases from prototype to production. More features, less work, nothing broken.

AI tools get you to a working prototype fast. But as your product grows, generating code without architecture makes every change a risk.

We put the systems in place that catch mistakes before they reach production: type safety, automated testing, CI/CD pipelines, and infrastructure as code.

A codebase your team can trust.

./02 References

References

What our clients say

Ranta Labs carried out an effective security and architecture analysis for our AI-generated software. We got a clear view of the risk areas and practical guidance on how to get the product safely into production. Strong recommendation.

OA

Onni Ahonen

CEO @ Floy

Ranta Labs set up our Infrastructure as Code and refactored the codebase to modern standard libraries and a clearer architecture. Since then, our AI-assisted development has sped up over 3x. We ship more features to production with a smaller team.

VR

Veeti Roponen

CTO @ MailMoo

./03 How we work

How it works

Automated guardrails that catch errors at every step. From type checking to deployment. Every change is verified before it reaches production.

Step 1

Type Safety

Catches bugs before they ship

I need to fetch house data by ID for the banner component. I'll use the tRPC houses.get endpoint with the id parameter... wait, the router expects a number but I'm passing a string.
houses.ts / [banner].tsx
1export const housesRouter = router({
2 get: publicProcedure
3 .input(z.object({ id: z.number() }))
4 .query(async ({ input }) => {
5 return await db.house.findUnique({
6 where: { id: input.id }
7 });
8 }),
9});
10
11const HouseBanner = () => {
12 // ❌ Type error: id is string, expected number
13 const { data } = trpc.houses.get.useQuery({ id: 'Atreides' });
14 ← Error
15 return <div>{data?.emblem}</div>;
16};
Terminal
$ pnpm typecheck
src/pages/houses/[banner].tsx:17:62 - error TS2345:
Argument of type 'string' is not assignable to parameter of type 'number'.
17 const { data } = trpc.houses.get.useQuery({ id: 'Atreides' });
~~~~~~~~~
Found 1 error.
[banner].tsx
1const HouseBanner = () => {
2 // ✓ Fixed: convert to number
3 const { data } = trpc.houses.get.useQuery({
4 id: 1265
5 });
6
7 return <div>{data?.emblem}</div>;
8 };
spice-allocation.test.ts
1export function calculateWaterDiscipline(
2 harvestYield: number,
3 carryWeight: number,
4 stillsuitEfficiency: number
5): { rations: number; surplus: number } {
6 const baseNeed = harvestYield * 0.45;
7 const adjustedNeed = carryWeight > 100 ? baseNeed * 0.8 : baseNeed;
8 const recycled = adjustedNeed * (stillsuitEfficiency / 100);
9
10 return {
11 rations: Math.floor(adjustedNeed - recycled),
12 surplus: Math.floor(recycled * 0.3),
13 };
14}
15
16describe('calculateWaterDiscipline', () => {
17 it('should optimize rations for heavy loads in deep desert', () => {
18 const result = calculateWaterDiscipline(1000, 150, 95);
19 // ❌ Test fails - logic error in carryWeight threshold
20 expect(result.rations).toBe(45);← Error
21 expect(result.surplus).toBe(28);
22 });
23});
Terminal
$ pnpm test
FAIL __tests__/spice-allocation.test.ts
calculateWaterDiscipline > should optimize rations for heavy loads in deep desert
Expected: 45
Received: 180
Logic error: carryWeight threshold should be >= 150, not > 100
1 test failed, 0 tests passed
spice-allocation.test.ts
1export function calculateWaterDiscipline(
2 harvestYield: number,
3 carryWeight: number,
4 stillsuitEfficiency: number
5): { rations: number; surplus: number } {
6 const baseNeed = harvestYield * 0.45;
7 // ✓ Fixed: correct threshold for heavy loads
8 const adjustedNeed = carryWeight >= 150 ? baseNeed * 0.8 : baseNeed;
9 const recycled = adjustedNeed * (stillsuitEfficiency / 100);
10
11 return {
12 rations: Math.floor(adjustedNeed - recycled),
13 surplus: Math.floor(recycled * 0.3),
14 };
15}
16
17describe('calculateWaterDiscipline', () => {
18 it('should optimize rations for heavy loads in deep desert', () => {
19 const result = calculateWaterDiscipline(1000, 150, 95);
20 expect(result.rations).toBe(45);
21 expect(result.surplus).toBe(28);
22 });
23
24 it('should handle light patrols differently', () => {
25 const result = calculateWaterDiscipline(1000, 80, 90);
26 expect(result.rations).toBe(225);
27 });
28});
Terminal
$ git add . && git commit -m 'fix: correct carryWeight threshold'
$ git push origin main
→ CI pipeline triggered...
→ Running typecheck... ✓
→ Running tests... ✓
→ Running lint... ✓
→ Building application... ✓
→ Pulumi preview...
Previewing update (dev):
+ aws:lambda/function:Function harvest-reports
+ aws:iam/role:Role lambda-exec-role
Resources: +2 to create
lambda.ts
1import * as aws from "@pulumi/aws";
2
3// Create Lambda function for harvest reports
4const harvestReports = new aws.lambda.Function("harvest-reports", {
5 runtime: "nodejs20.x",
6 handler: "index.handler",
7 code: new pulumi.asset.FileArchive("./lambda"),
8 role: lambdaRole.arn,
9 environment: {
10 variables: {
11 DATABASE_URL: dbUrl,
12 },
13 },
14});
Terminal
$ pulumi up -y
Updating (dev):
+ aws:lambda/function:Function harvest-reports created
+ aws:iam/role:Role lambda-exec-role created
Resources: +2 created
--- Invoke harvest-reports ---
ERROR: connect ECONNREFUSED 10.0.1.45:5432
at TCPConnectWrap.afterConnect [as oncomplete]
code: 'ECONNREFUSED',
syscall: 'connect',
lambda.ts
1import * as aws from "@pulumi/aws";
2
3const harvestReports = new aws.lambda.Function("harvest-reports", {
4 runtime: "nodejs20.x",
5 handler: "index.handler",
6 code: new pulumi.asset.FileArchive("./lambda"),
7 role: lambdaRole.arn,
8 environment: {
9 variables: { DATABASE_URL: dbUrl },
10 },
11 // ✓ Fixed: Add VPC configuration to access RDS
12 vpcConfig: {
13 subnetIds: [privateSubnet1.id, privateSubnet2.id],
14 securityGroupIds: [lambdaSecurityGroup.id],
15 },
16});
Terminal
$ pulumi up -y
Updating (dev):
~ aws:lambda/function:Function harvest-reports updating
~ aws:lambda/function:Function harvest-reports updated
Resources: 1 changed
--- Invoke harvest-reports ---
Status: 200 OK
{ "crawlerId": "C-8492", "yield": 847.5, "region": "deep-desert" }
✓ Connection successful!
Terminal
✓ TypeScript type checking passed
✓ Unit tests passed (42/42)
✓ Integration tests passed
✓ Linting passed
✓ Security scan passed
✓ Infrastructure deployed
✓ Smoke tests passed
─────────────────────────────
🚀 Deployed successfully to:
https://api.rantalabs.dev
─────────────────────────────
Shipped safely with guardrails!
./05 Blog

Blog

Practical guides for shipping AI-generated code to production

./04 Get started

Ready to ship safely?

Tell us what you're building. We'll assess your codebase and show you how we can take it to production.