Home / Articles / Practical notes: My monorepo setup to ship full-stack, end-to-end type-safe

This article is published in English.

Practical notes: My monorepo setup to ship full-stack, end-to-end type-safe

Operable walkthrough of Practical notes: My monorepo setup to ship full-stack, end-to-end type-safe: contracts, checks, and drop-in code slots for teams shipping this pattern.

2920 words

Use this as an operator-facing rebuild of the ideas in “My monorepo setup to ship full-stack, end-to-end type-safe apps with TypeScript, part 2”: clear stages, ordered code slots, and recovery notes that survive a handoff. The Overview stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Prefer small, testable units over sprawling scripts. When a step fails, the failure should point at a single responsibility rather than a tangled pipeline.

name: monorepo-setup

services:
  db:
    image: postgres:17-alpine
    container_name: monorepo-setup-database-container
    ports:
      - 127.0.0.1:5432:5432
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -d ${POSTGRES_DB} -U ${POSTGRES_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - monorepo-setup:/var/lib/postgresql/data
    env_file:
      - apps/api/.env.database

volumes:
  monorepo-setup:
    name: monorepo-setup
# apps/api/.env.database
POSTGRES_DB=monorepo-setup
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
docker compose up -d --remove-orphans
docker ps
docker exec -it monorepo-setup-database-container psql -U postgres -d monorepo-setup
# monorepo-setup-database-container is the name of the container, as specified in the compose.yaml file
# -U postgres (POSTGRES_USER specified in the .env.database file)
# same for -d monorepo-setup (POSTGRES_DB)
# From the root of the monorepo
cd apps/api
npm i drizzle-orm@rc pg dotenv
npm i -D drizzle-kit@rc tsx @types/pg
DATABASE_URL=postgres://<user>:<password>@<host>:<port>/<database>
DATABASE_URL=postgres://postgres:postgres@localhost:5432/monorepo-setup
nest g res drizzle
// apps/api/src/drizzle/constants.ts
export const DRIZZLE_ASYNC_PROVIDER = "DRIZZLE_ASYNC_PROVIDER";
// apps/api/drizzle/providers/drizzle.provider.ts

import { drizzle } from "drizzle-orm/node-postgres";
import { Pool } from "pg";

import { EnvService } from "@/env/env.service";

import { DRIZZLE_ASYNC_PROVIDER } from "../constants";

export const drizzleProvider = {
  provide: DRIZZLE_ASYNC_PROVIDER,
  inject: [EnvService],
  useFactory: async (envService: EnvService) => {
    const connectionString = envService.get("DATABASE_URL");
    const pool = new Pool({
      connectionString,
    });

    return drizzle({ client: pool });
  },
};
// apps/api/src/drizzle/schema/users.ts

import { pgTable, text, varchar } from "drizzle-orm/pg-core";
import { timestamp } from "drizzle-orm/pg-core";
import { ulid } from "ulid";

export const users = pgTable("users", {
  id: varchar("id", { length: 26 })
    .primaryKey()
    .notNull()
    .$defaultFn(() => ulid().toLowerCase()),

  username: text("username").notNull().unique(),
  email: text("email").notNull().unique(),
  hashedPassword: text("hashed_password").notNull(),

  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at")
    .defaultNow()
    .$onUpdate(() => new Date())
    .notNull(),
});
// apps/api/src/drizzle/schema/posts.ts

import { pgTable, text, varchar } from "drizzle-orm/pg-core";
import { timestamp } from "drizzle-orm/pg-core";
import { ulid } from "ulid";

import { users } from "./users";

export const posts = pgTable("posts", {
  id: varchar("id", { length: 26 })
    .primaryKey()
    .notNull()
    .$defaultFn(() => ulid().toLowerCase()),
  authorId: varchar("author_id", { length: 26 })
    .notNull()
    .references(() => users.id, { onDelete: "cascade" }),

  title: text("title").notNull(),
  slug: text("slug").notNull(),
  content: text("content").notNull(),

  publishedAt: timestamp("published_at"),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at")
    .defaultNow()
    .$onUpdate(() => new Date())
    .notNull(),
});
// apps/api/src/drizzle/schema/index.ts

export * from "./posts";
export * from "./users";
npm i ulid
// apps/api/src/env.ts

import { z } from "zod";

export const envSchema = z.object({
  NODE_ENV: z.enum(["production", "development"]),

  JWT_SECRET: z.string().trim().min(1),

  DASHBOARD_URL: z.url(),
  WEB_APP_URL: z.url(),

  DATABASE_URL: z.string().trim().min(1),
});

export type Env = z.infer<typeof envSchema>;
// apps/api/drizzle.config.ts

import { defineConfig } from "drizzle-kit";

import "dotenv/config";

export default defineConfig({
  out: "./src/drizzle/migrations",
  schema: "./src/drizzle/schema/index.ts",
  dialect: "postgresql",
  dbCredentials: {
    url: process.env.DATABASE_URL!,
  },
});
// apps/api/package.json

{
  "scripts": {
    ...
    "generate": "npx drizzle-kit generate",
    "migrate": "npx drizzle-kit migrate",
    ...
  }
}
npm run generate
npm run generate
docker exec -it monorepo-setup-database-container psql -U postgres -d monorepo-setup
\dt
// apps/api/package.json

{
  "scripts": {
    ...
   "studio": "npx drizzle-kit studio"
    ...
  }
}
npm run studio
import { EnvModule } from "@/env/env.module";
import { Module } from "@nestjs/common";

import { DRIZZLE_ASYNC_PROVIDER } from "./constants";
import { drizzleProvider } from "./providers/drizzle.provider";

@Module({
  imports: [EnvModule],
  providers: [drizzleProvider],
  exports: [DRIZZLE_ASYNC_PROVIDER],
})
export class DrizzleModule {}
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";

import { EnvService } from "./env.service";

@Module({
  imports: [ConfigModule],
  providers: [EnvService],
  exports: [EnvService],
})
export class EnvModule {}
nest g res users
// apps/api/src/users/users.service.ts

import * as bcrypt from "bcrypt";
import { eq, or } from "drizzle-orm";
import { NodePgDatabase } from "drizzle-orm/node-postgres";

import { DRIZZLE_ASYNC_PROVIDER } from "@/drizzle/constants";
import { users } from "@/drizzle/schema";
import { Inject, Injectable } from "@nestjs/common";
import { TRPCError } from "@trpc/server";

import { CreateUserDtoType, FindByEmailDtoType } from "./users.dto";

@Injectable()
export class UsersService {
  private readonly saltRounds = 10;

  constructor(
    @Inject(DRIZZLE_ASYNC_PROVIDER)
    private readonly db: NodePgDatabase,
  ) {}

  async create(createUserDto: CreateUserDtoType) {
    const { email, password, username } = createUserDto;

    const [existingUserWithSameEmailOrUsername] = await this.db
      .select({ email: users.email, username: users.username })
      .from(users)
      .where(or(eq(users.email, email), eq(users.username, username)))
      .limit(1);

    if (existingUserWithSameEmailOrUsername) {
      if (existingUserWithSameEmailOrUsername.email === email) {
        throw new TRPCError({
          code: "CONFLICT",
          message: "This email is already used",
        });
      } else {
        throw new TRPCError({
          code: "CONFLICT",
          message: "This username already exists",
        });
      }
    }

    const hashedPassword = await bcrypt.hash(password, this.saltRounds);

    const [createdUser] = await this.db
      .insert(users)
      .values({
        username,
        email,
        hashedPassword,
      })
      .returning({
        id: users.id,
        email: users.email,
        username: users.username,
      });

    return createdUser;
  }

  async findByEmail(findByEmailDto: FindByEmailDtoType) {
    const { email } = findByEmailDto;

    const [user] = await this.db
      .select({
        id: users.id,
        email: users.email,
        username: users.username,
        hashedPassword: users.hashedPassword,
      })
      .from(users)
      .where(eq(users.email, email))
      .limit(1);

    if (!user) {
      return null;
    }

    return user;
  }
}
// apps/api/src/users/users.dto.ts

import z from "zod";

export const CreateUserDto = z.object({
  email: z.email(),
  username: z.string().min(1).max(25),
  password: z.string().min(1).max(72),
});

export const FindByEmailDto = z.object({
  email: z.email(),
});

export type CreateUserDtoType = z.infer<typeof CreateUserDto>;
export type FindByEmailDtoType = z.infer<typeof FindByEmailDto>;
# apps/api

npm i bcrypt
npm i -D @types/bcrypt
// apps/api/src/users/users.module.ts

import { DrizzleModule } from "@/drizzle/drizzle.module";
import { Module } from "@nestjs/common";

import { UsersService } from "./users.service";

@Module({
  imports: [DrizzleModule],
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
nest g res posts
import { and, eq } from "drizzle-orm";
import { NodePgDatabase } from "drizzle-orm/node-postgres";

import { DRIZZLE_ASYNC_PROVIDER } from "@/drizzle/constants";
import { posts } from "@/drizzle/schema";
import { Inject, Injectable } from "@nestjs/common";
import { TRPCError } from "@trpc/server";

import {
  CreatePostDtoType,
  FindAllPostsDtoType,
  FindOnePostDtoType,
} from "./posts.dto";

@Injectable()
export class PostsService {
  constructor(
    @Inject(DRIZZLE_ASYNC_PROVIDER)
    private readonly db: NodePgDatabase,
  ) {}
  async create(createPostDto: CreatePostDtoType) {
    const { title, slug, content, authorId } = createPostDto;

    const [existingPostWithSameSlug] = await this.db
      .select({ slug: posts.slug })
      .from(posts)
      .where(and(eq(posts.authorId, authorId), eq(posts.slug, slug)))
      .limit(1);

    if (existingPostWithSameSlug) {
      throw new TRPCError({
        code: "CONFLICT",
        message: "A post with that slug already exists",
      });
    }

    const [createdPost] = await this.db
      .insert(posts)
      .values({ title, slug, content, authorId, publishedAt: new Date() })
      .returning({
        id: posts.id,
        title: posts.title,
        slug: posts.slug,
        content: posts.content,
        authorId: posts.authorId,
      });

    return createdPost;
  }

  async findAll(findAllPostsDto: FindAllPostsDtoType) {
    const { authorId } = findAllPostsDto;

    const postsFetched = await this.db
      .select({ title: posts.title, slug: posts.slug, content: posts.content })
      .from(posts)
      .where(eq(posts.authorId, authorId));

    return postsFetched;
  }

  async findOne(findOnePostDto: FindOnePostDtoType) {
    const { authorId, slug } = findOnePostDto;

    const [post] = await this.db
      .select({
        title: posts.title,
        slug: posts.slug,
        content: posts.content,
      })
      .from(posts)
      .where(and(eq(posts.authorId, authorId), eq(posts.slug, slug)))
      .limit(1);

    if (!post) {
      return null;
    }

    return post;
  }
}
// apps/api/src/posts/posts.dto.ts

import z from "zod";

export const CreatePostDto = z.object({
  title: z.string().min(1).max(150),
  slug: z.string().min(1).max(150),
  content: z.string().min(1),
});

export const FindOnePostDto = z.object({
  slug: z.string().min(1).max(150),
});

type AuthorId = { authorId: string };
export type CreatePostDtoType = z.infer<typeof CreatePostDto> & AuthorId;
export type FindAllPostsDtoType = AuthorId;
export type FindOnePostDtoType = z.infer<typeof FindOnePostDto> & AuthorId;
// apps/api/src/posts/posts.module.ts

import { DrizzleModule } from "@/drizzle/drizzle.module";
import { Module } from "@nestjs/common";

import { PostsService } from "./posts.service";

@Module({
  imports: [DrizzleModule],
  providers: [PostsService],
  exports: [PostsService],
})
export class PostsModule {}
nest g res auth
// apps/api/src/auth/auth.service.ts

import * as bcrypt from "bcrypt";

import { JWTDtoType } from "@/common/dto";
import { UsersService } from "@/users/users.service";
import { Injectable } from "@nestjs/common";
import { JwtService } from "@nestjs/jwt";
import { TRPCError } from "@trpc/server";

import { LoginDtoType, RegisterDtoType } from "./auth.dto";

@Injectable()
export class AuthService {
  constructor(
    private readonly jwtService: JwtService,
    private readonly usersService: UsersService,
  ) {}

  async register(registerDto: RegisterDtoType) {
    const { username, email, password } = registerDto;

    const createdUser = await this.usersService.create({
      email,
      username,
      password,
    });

    const payload: Pick<JWTDtoType, "sub"> = { sub: createdUser.id };
    const token = await this.jwtService.signAsync(payload);

    return { accessToken: token };
  }

  async login(loginDto: LoginDtoType) {
    const { email, password } = loginDto;

    const user = await this.usersService.findByEmail({ email });

    if (!user) {
      throw new TRPCError({
        code: "NOT_FOUND",
        message: "User not found",
      });
    }

    const isPasswordCorrect = await bcrypt.compare(
      password,
      user.hashedPassword,
    );
    if (!isPasswordCorrect) {
      throw new TRPCError({
        code: "UNAUTHORIZED",
        message: "Incorrect password",
      });
    }

    const payload: Pick<JWTDtoType, "sub"> = { sub: user.id };
    const token = await this.jwtService.signAsync(payload);

    return {
      accessToken: token,
    };
  }
}
// apps/api/src/auth/auth.dto.ts

import z from "zod";

export const RegisterDto = z.object({
  username: z.string().min(1).max(25),
  email: z.email(),
  password: z.string().min(1).max(72),
});

export const LoginDto = z.object({
  email: z.email(),
  password: z.string().min(1).max(72),
});

export type RegisterDtoType = z.infer<typeof RegisterDto>;
export type LoginDtoType = z.infer<typeof LoginDto>;
// apps/api/src/auth/auth.router.ts

import { TrpcService } from "@/trpc/trpc.service";
import { Injectable } from "@nestjs/common";

import { LoginDto, RegisterDto } from "./auth.dto";
import { AuthService } from "./auth.service";

@Injectable()
export class AuthRouter {
  constructor(
    private readonly trpcService: TrpcService,
    private readonly authService: AuthService,
  ) {}

  private readonly AUTH_COOKIE_NAME = "auth_token";
  private readonly COOKIE_MAX_AGE = 2 * 24 * 60 * 60 * 1000; // 2 days

  procedures() {
    return {
      auth: this.trpcService.trpc.router({
        register: this.trpcService
          .publicProcedure()
          .input(RegisterDto)
          .mutation(async ({ ctx, input }) => {
            const { accessToken } = await this.authService.register(input);

            // Set the HTTP-only cookie
            ctx.res.cookie(this.AUTH_COOKIE_NAME, accessToken, {
              httpOnly: true,
              secure: true,
              sameSite: "lax",
              maxAge: this.COOKIE_MAX_AGE,
            });
          }),

        login: this.trpcService
          .publicProcedure()
          .input(LoginDto)
          .mutation(async ({ ctx, input }) => {
            const { accessToken } = await this.authService.login(input);

            // Set the HTTP-only cookie
            ctx.res.cookie(this.AUTH_COOKIE_NAME, accessToken, {
              httpOnly: true,
              secure: true,
              sameSite: "lax",
              maxAge: this.COOKIE_MAX_AGE,
            });
          }),
      }),
    };
  }
}
// apps/api/src/auth/auth.module.ts

import { EnvModule } from "@/env/env.module";
import { EnvService } from "@/env/env.service";
import { TrpcService } from "@/trpc/trpc.service";
import { UsersModule } from "@/users/users.module";
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { JwtModule } from "@nestjs/jwt";

import { AuthRouter } from "./auth.router";
import { AuthService } from "./auth.service";

@Module({
  imports: [
    ConfigModule,
    UsersModule,
    JwtModule.registerAsync({
      imports: [EnvModule],
      useFactory: async (envService: EnvService) => ({
        global: true,
        secret: envService.get("JWT_SECRET"),
        signOptions: { expiresIn: "2d" },
      }),
      inject: [EnvService],
    }),
  ],

  providers: [AuthService, AuthRouter, TrpcService, EnvService],
  exports: [AuthRouter, AuthService],
})
export class AuthModule {}
// apps/api/src/trpc/trpc.router.ts

  appRouter = this.trpcService.trpc.router({
    getHello: this.trpcService
      .publicProcedure()
      .input(
        z.object({
          name: z.string().min(1),
        }),
      )
      .query(({ input }) => `Hello, ${input.name} from trpc server`),

    ...this.authRouter.procedures(),
  });
// apps/api/src/trpc/trpc.module.ts

@Module({
  imports: [AuthModule],
  providers: [TrpcService, TrpcRouter, JwtService, EnvService, AuthRouter],
  exports: [TrpcService],
})
// apps/api/src/posts/posts.router.ts

import { TrpcService } from "@/trpc/trpc.service";
import { Injectable } from "@nestjs/common";

import { CreatePostDto, FindOnePostDto } from "./posts.dto";
import { PostsService } from "./posts.service";

@Injectable()
export class PostsRouter {
  constructor(
    private readonly trpcService: TrpcService,
    private readonly postsService: PostsService,
  ) {}

  procedures() {
    return {
      posts: this.trpcService.trpc.router({
        create: this.trpcService
          .protectedProcedure()
          .input(CreatePostDto)
          .mutation(async ({ ctx, input }) =>
            this.postsService.create({ ...input, authorId: ctx.user.sub }),
          ),

        findAll: this.trpcService
          .protectedProcedure()
          .query(async ({ ctx }) =>
            this.postsService.findAll({ authorId: ctx.user.sub }),
          ),

        findOne: this.trpcService
          .protectedProcedure()
          .input(FindOnePostDto)
          .query(async ({ ctx, input }) =>
            this.postsService.findOne({ ...input, authorId: ctx.user.sub }),
          ),
      }),
    };
  }
}
// apps/api/src/trpc/trpc.router.ts

  appRouter = this.trpcService.trpc.router({
    getHello: this.trpcService
      .publicProcedure()
      .input(
        z.object({
          name: z.string().min(1),
        }),
      )
      .query(({ input }) => `Hello, ${input.name} from trpc server`),

    ...this.authRouter.procedures(),
    ...this.postsRouter.procedures(),
  });
// apps/api/src/trpc/trpc.module.ts

@Module({
  imports: [AuthModule, PostsModule],
  providers: [
    TrpcService,
    TrpcRouter,
    JwtService,
    EnvService,
    AuthRouter,
    PostsRouter,
  ],
  exports: [TrpcService],
})
import { Controller, useForm } from "react-hook-form";
import { Link, useNavigate } from "react-router";
import { toast } from "sonner";

import { useTRPC } from "@/utils/trpc";
import { zodResolver } from "@hookform/resolvers/zod";
import { LoginSchema, type LoginSchemaType } from "@repo/common/types-schemas";
import { Button } from "@repo/ui/components/ui/button";
import { Field, FieldError, FieldLabel } from "@repo/ui/components/ui/field";
import { Input } from "@repo/ui/components/ui/input";
import { useMutation } from "@tanstack/react-query";

import { useTogglePassword } from "../hooks/use-toggle-password";

export const LoginForm = () => {
  const form = useForm<LoginSchemaType>({
    resolver: zodResolver(LoginSchema),
    defaultValues: {
      email: "",
      password: "",
    },
  });

  const { isPasswordVisible, EyeIconComponent } = useTogglePassword();

  const navigate = useNavigate();
  const trpc = useTRPC();
  const loginMutation = useMutation(trpc.auth.login.mutationOptions());

  const onSubmit = (values: LoginSchemaType) => {
    loginMutation.mutate(
      {
        email: values.email,
        password: values.password,
      },
      {
        onError: (error) => {
          const errorMessage = error.message;

          if (errorMessage.toLowerCase().includes("email")) {
            form.setError("email", { message: errorMessage });
          } else if (errorMessage.toLowerCase().includes("password")) {
            form.setError("password", { message: errorMessage });
          } else {
            form.setError("root", { message: errorMessage });
          }
        },

        onSuccess: () => {
          toast.success("Login complete");

          navigate("/posts");
        },
      },
    );
  };

  return (
    <form
      onSubmit={form.handleSubmit(onSubmit)}
      className="flex w-[clamp(40%,30rem,80%)] flex-col gap-4 p-2"
    >
      <h2 className="flex flex-col items-center justify-center gap-2 text-center text-3xl font-extrabold max-[42.5rem]:text-2xl">
        Login
      </h2>

      <Controller
        control={form.control}
        name="email"
        render={({ field, fieldState }) => (
          <Field data-invalid={fieldState.invalid}>
            <FieldLabel htmlFor={field.name}>Email</FieldLabel>
            <Input
              id={field.name}
              placeholder="example@email.com"
              type="email"
              aria-invalid={fieldState.invalid}
              className="border-border h-10"
              {...field}
            />
            {fieldState.invalid && <FieldError errors={[fieldState.error]} />}
          </Field>
        )}
      />

      <Controller
        control={form.control}
        name="password"
        render={({ field, fieldState }) => (
          <Field data-invalid={fieldState.invalid}>
            <FieldLabel htmlFor={field.name}>Password</FieldLabel>
            <div className="relative flex items-center justify-end">
              <Input
                id={field.name}
                placeholder="***********"
                type={isPasswordVisible ? "text" : "password"}
                aria-invalid={fieldState.invalid}
                className="border-border h-10"
                {...field}
              />
              <EyeIconComponent />
            </div>
            {fieldState.invalid && <FieldError errors={[fieldState.error]} />}
          </Field>
        )}
      />
      <p>
        Not registered yet?{" "}
        <Link to="/register" className="underline">
          Register
        </Link>
      </p>

      <Button
        variant="default"
        type="submit"
        disabled={form.formState.isSubmitting}
        className="h-10 w-1/2 self-center rounded-lg"
      >
        Submit
      </Button>

      <div className="h-4">
        {form.formState.errors.root && (
          <FieldError errors={[form.formState.errors.root]} />
        )}
      </div>
    </form>
  );
};

Operational checklist

When working through the Operational checklist stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest.

Document the happy path and the recovery path together. Retries, human gates, and dead-letter handling are part of the product, not later polish.

Write a short runbook: how to rotate keys, how to drain the queue, how to roll back the last ingest.

Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph.

Add a smoke test that exercises the critical path in CI with fixtures, not live paid APIs, whenever budgets allow.

Record timings and token or query cost next to functional results. Cost visibility early prevents surprise bills when the path moves from demo to shared environments.

Before promoting the stack, freeze versions, capture a golden transcript for the critical path, and confirm rollback steps. Shared environments need rate limits, tenancy checks, and a clear owner for secret rotation. Prefer boring reliability over clever one-off demos.

Batch note for 401e3ffdff5d: keep provider keys out of the repo, set a per-session token ceiling, and store transcripts next to the eval fixtures so later model swaps stay comparable.

The hardening note 0 stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Record timings and token or query cost next to functional results. Cost visibility early prevents surprise bills when the path moves from demo to shared environments.

Hardening detail 0/962: measure wall time, error class, and token spend for this note, then decide whether to keep the change based on a fixed question set rather than anecdote.

For the hardening note 1 stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Document the happy path and the recovery path together. Retries, human gates, and dead-letter handling are part of the product, not later polish.

Hardening detail 1/962: measure wall time, error class, and token spend for this note, then decide whether to keep the change based on a fixed question set rather than anecdote.

When working through the hardening note 2 stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Treat this stage as a contract between inputs and validated outputs. Name the artifacts, define success checks, and refuse silent partial completion.

Hardening detail 2/962: measure wall time, error class, and token spend for this note, then decide whether to keep the change based on a fixed question set rather than anecdote.

The hardening note 3 stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph.

Hardening detail 3/962: measure wall time, error class, and token spend for this note, then decide whether to keep the change based on a fixed question set rather than anecdote.

For the hardening note 4 stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Prefer small, testable units over sprawling scripts. When a step fails, the failure should point at a single responsibility rather than a tangled pipeline.

Hardening detail 4/962: measure wall time, error class, and token spend for this note, then decide whether to keep the change based on a fixed question set rather than anecdote.