Files
mintel.me/apps/web/app/(site)/process/page.tsx
T

165 lines
6.5 KiB
TypeScript

import type { Metadata } from "next";
import {
ButtonLink,
Container,
SectionHeader,
TerminalCard,
} from "@/src/components/site";
import { ProcessStepCard } from "@/src/components/process/ProcessStepCard";
import { PROCESS_STEPS } from "@/src/components/process/processSteps";
import { SAMPLE_DELIVERY_REPORT } from "@/src/components/process/sampleDeliveryReport";
import { formatDeliveryReport } from "@/src/domain/deliveryReport";
const TITLE = "Process: AI speed, engineering proof";
const DESCRIPTION =
"How I ship AI-accelerated code that holds up: spec first, red, green, mutation check and a delivery report with exact commands and results on every pull request.";
export const metadata: Metadata = {
title: TITLE,
description: DESCRIPTION,
alternates: { canonical: "/process" },
openGraph: {
title: TITLE,
description: DESCRIPTION,
url: "/process",
type: "website",
},
};
const GUARDRAILS = [
{
title: "Pre-commit gate",
text: "Formatting and lint on staged files, then typecheck and the unit tests, run before a commit is created. Broken code does not enter history.",
},
{
title: "Pre-push gate",
text: "Coverage runs before a push leaves my machine, and the mutation check runs when the domain logic changed. The remote only receives green work.",
},
{
title: "CI gates the deploy",
text: "On client projects the same checks run again in CI, and a deploy only starts when they pass. My machine is not the only line of defense.",
},
{
title: "Tests are never weakened",
text: "If a test blocks a change, I do not skip, loosen or delete it to get green. If the test is wrong, I tell you why and the spec changes with your agreement.",
},
] as const;
const reportLines = formatDeliveryReport(SAMPLE_DELIVERY_REPORT);
export default function Page() {
return (
<Container className="py-16 md:py-24">
<SectionHeader
as="h1"
kicker="/process"
title="How I ship AI-accelerated code that holds up"
lead="AI makes code cheap to produce. What you pay for is code that is correct. Every change goes through the same five steps, and you get the evidence for each of them every week."
/>
<section aria-labelledby="steps" className="mt-16">
<h2 id="steps" className="sr-only">
The five steps
</h2>
<p className="!mb-6 max-w-2xl text-base text-muted">
One running example: parsing an availability, meaning a date and
weekly hours. The date 2026-02-30 must be rejected, 2028-02-29 must be
accepted, and 168 hours is the upper boundary of a week.
</p>
<ol className="list-none !p-0">
{PROCESS_STEPS.map((step, index) => (
<ProcessStepCard key={step.id} step={step} index={index} />
))}
</ol>
</section>
<section aria-labelledby="report" className="mt-16">
<SectionHeader
kicker="evidence"
title="A delivery report"
lead="This is what arrives with a pull request. The example below is illustrative: the numbers are made up for the availability parsing case and are not from a client project."
/>
<TerminalCard
title="delivery report (illustrative example)"
className="mt-8 max-w-3xl"
>
{reportLines.map((line) => (
<p key={line} className="!mb-0 whitespace-pre">
{line}
</p>
))}
</TerminalCard>
<p className="!mb-0 mt-4">
<a
href="/sample-delivery-report.md"
download
className="font-mono text-sm text-accent underline underline-offset-4"
>
Download the sample report (sample-delivery-report.md)
</a>
</p>
</section>
<section aria-labelledby="weak" className="mt-16 max-w-2xl">
<h2 id="weak" className="!mt-0 !text-2xl">
What I do when tests are weak or missing
</h2>
<p className="text-base leading-relaxed text-muted">
AI-built code often arrives with few tests, or with tests that only
repeat the implementation. I do not start by rewriting. I write the
expected behavior as cases for the parts that matter most, run them
against the existing code, and let the failures show what is really
broken. Then I add a mutation baseline so you can see which tests
would not notice a bug.
</p>
<h2 className="!text-2xl">Why mutation testing</h2>
<p className="text-base leading-relaxed text-muted">
Coverage tells you which lines ran during the tests. It does not tell
you whether the tests would notice a bug in those lines. Mutation
testing changes the code on purpose and checks that a test fails. That
is the question you care about. Coverage stays useful as a gap finder:
it points at code nothing exercises. It is not a goal, and a high
number alone proves little.
</p>
<p className="text-base leading-relaxed text-muted">
Two systems where I run this: a Rust and Solidity liquidation system
across 7 chains, with a zero-survivor mutation gate and a coverage
ratchet, and the domain core of this website, which has its own tests
and mutation gate.
</p>
</section>
<section aria-labelledby="guardrails" className="mt-16">
<SectionHeader
kicker="guardrails"
title="Gates that run without me"
lead="The process does not depend on my discipline on a good day."
/>
<ul className="mt-8 grid list-none gap-6 !p-0 md:grid-cols-2">
{GUARDRAILS.map((item) => (
<li
key={item.title}
className="rounded-lg border border-border bg-surface p-5"
>
<h3 className="!mb-2 !mt-0 text-lg font-semibold">
{item.title}
</h3>
<p className="!mb-0 text-base leading-relaxed text-muted">
{item.text}
</p>
</li>
))}
</ul>
</section>
<section className="mt-16 border-t border-border pt-10">
<h2 className="!mt-0 !text-2xl">Want this on your codebase?</h2>
<p className="mb-6 max-w-2xl text-base text-muted">
A 20-minute intro call is enough to see whether this fits your team.
</p>
<ButtonLink href="/book">Book a 20-minute intro call</ButtonLink>
</section>
</Container>
);
}