Skip to content

Month 1 Plan

canquesse edited this page Jul 29, 2026 · 2 revisions

Month 1 — Solid Foundation and Two-Service Skeleton

This month's sentence: We start not with AI, but with the ground AI will stand on.

This month is theory-heavy and partly tiring. But it's the highest-return month: the knowledge here doesn't age as frameworks change; it stays valid a decade from now. Also, the skeleton the whole project sits on is built this month — you'll feel the cost or the benefit of the schema decision you make in Month 1 all the way in Month 5.

Why don't we start with AI? Because an agent's memory, tool results, and step records live in a database. You can't build a reliable agent without understanding the database well. Also, the vast majority of interviews are system design and database questions, and most candidates are superficial exactly here. This month turns you from someone who "uses frameworks" into someone who "understands the infrastructure".

Who does what? This plan groups the work by task, not by person. The two of you split the tasks yourselves (each task has a GitHub issue and a branch), and swap areas at the mid-month rotation.


1. Learning core — you both learn the same thing

This list is not divided. Code is divided, learning is not.

What you'll learn

Topic Scope
Relational database depth (PostgreSQL) How a query runs inside the database, what the query planner does, how indexes speed up a query
How HTTP and REST actually work Request/response cycle, status codes, headers, idempotency, connection lifecycle
Service-to-service contract How two independent services talk over a clean, versionable interface
Containerization basics (Docker) Why and how a service is containerized, the difference between an image and a container
Reading Designing Data-Intensive Applications — Chapters 1, 2, 3

Which concepts you'll master

By the end of the month you must be able to explain each one at a whiteboard, without notes. A concept you can't explain hasn't been learned.

  • B-tree index — why it's the default structure for most indexes, which query types it speeds up
  • EXPLAIN ANALYZE output — sequential scan vs index scan, row estimates, actual time
  • N+1 query problem — how it arises, why it's a sneaky performance killer, how to detect and cure it
  • Transactions and ACID — what atomicity, consistency, isolation, durability mean in practice
  • Isolation levels — Read Committed vs Repeatable Read; dirty read, non-repeatable read, phantom read
  • Connection pool — why database connections are expensive, how the pool amortizes that cost
  • REST resource design — resource-oriented URLs, correct HTTP verb, status code discipline
  • Idempotency — which verbs are idempotent, why it matters
  • API contract — OpenAPI, backward compatibility, breaking vs non-breaking changes
  • Docker image and container — an image is a template, a container is a running instance of that template

2. Weekly flow

Week 1 — Ground: HTTP/REST + both services come up

Shared learning (~5 hours)

  • HTTP request/response cycle, status codes, headers, keep-alive
  • REST resource design, correct verb choice, idempotency
  • DDIA Chapter 1 (reliable, scalable, maintainable applications)
  • What OpenAPI is, why the contract is written first

Task: control-plane skeleton (Java) — issue #12, branch feat/12-control-plane-skeleton

  • Spring Boot project: layered structure (apiservicerepository)
  • /health endpoint + Actuator
  • Configuration read from environment variables (application.yml)
  • OpenAPI UI working via springdoc

Task: agent-runtime skeleton (Python) — issue #13, branch feat/13-agent-runtime-skeleton

  • FastAPI project: clean directory structure (api, core, agent, tools, db)
  • /health endpoint
  • Environment-variable configuration via pydantic-settings
  • POST /v1/tasks/run — an endpoint returning a stub response for now

Together (pairing, Wednesday) — issue #14, branch feat/14-service-contract

  • Design the service-to-service contract together: RunTaskRequest / RunTaskResponse / AgentStep
  • Write this contract into agent-runtime/app/api/schemas.py and both sides conform to it

Why write the contract together? Because the contract is the one place the two services meet. A contract written by one person misses the other side's needs and comes back two weeks later as a breaking change.

End-of-week check: Do both services respond to curl separately?


Week 2 — Database: schema + PostgreSQL depth

Shared learning (~6 hours)

  • Transactions, ACID, isolation levels (this week's most important topic)
  • How a B-tree index works
  • Connection pool logic
  • DDIA Chapter 2 (data models) and Chapter 3 (storage engines)

Task: schema and persistence (Java) — issue #15, branch feat/15-db-schema-flyway

  • Flyway V1__initial_schema.sql: app_user, agent_task, agent_step
  • Foreign keys, CHECK constraints, UNIQUE (task_id, step_index)
  • JPA entities + repository layer
  • HikariCP pool settings — with the answer to why these numbers

Task: Docker and environment — issue #16, branch feat/16-docker-compose-env

  • Multi-stage Dockerfile for both services
  • docker-compose.yml: postgres + both services, healthcheck and depends_on set up correctly
  • make up brings everything up with one command
  • .env.example complete

Together (pairing)

  • Review the schema together. Especially: why is agent_step a separate table?
  • An isolation-level experiment: open two psql sessions, update the same row, see with your own eyes the difference between Read Committed and Repeatable Read

Why is agent_step a separate table? An agent doesn't finish work in a single step: it thinks → calls a tool → sees the result → thinks again. If you don't keep each step as a separate record, you can't later answer "why did this agent make this decision". The entire observability claim of the project rests on the schema decision made this week.

End-of-week check: Does make up work from scratch, is the schema in place, can you see the tables via make db-shell?


Week 3 — End-to-end flow + rotation

⚠️ Roles swap in the middle of this week. The teaching session is held on the 15th, then the two of you swap areas (whoever did Java moves to Docker/profiling, and vice versa).

Shared learning (~4 hours)

  • Service-to-service calls: timeout, retry, error propagation
  • Breaking vs non-breaking API changes
  • The N+1 query problem

Build the task flow together — issue #17, branch feat/17-end-to-end-flow

  • POST /v1/tasks (control-plane) → an agent_task record is created (status=pending)
  • control-plane calls the agent-runtime's /v1/tasks/run endpoint
  • agent-runtime returns a stub AgentStep
  • control-plane writes this step to the agent_step table and sets the task to succeeded
  • GET /v1/tasks/{id} returns the task with all its steps
  • The HTTP client on the Java side has a timeout; on error the task becomes failed

Teaching session (the 15th, 60–90 min) — split the concepts between you:

  • One of you explains: transactions & ACID, isolation levels, connection pool, N+1
  • The other explains: B-tree index, EXPLAIN ANALYZE, Docker image/container, REST + idempotency
  • Mark the concepts you couldn't explain, repeat them until the end of the month

End-of-week check: Can you create a task with a single curl and read it back with its step?


Week 4 — Measurement: EXPLAIN ANALYZE, index, documentation

This week's output is the thing that will help you most all month: database knowledge proven with numbers.

Shared learning (~4 hours)

  • How the query planner decides
  • When a sequential scan is better than an index scan (yes, such cases exist)
  • Why column order matters in a composite index

Together — profiling study — issue #18, branch feat/18-explain-analyze-index

  • Generate at least 500,000 rows in the agent_step table (via a script)
  • Run this query: fetch all steps of a task in step_index order
  • Take the EXPLAIN ANALYZE output and read it line by line: which scan type, estimated vs actual rows, time
  • Add the index via V2__add_indexes.sql: CREATE INDEX idx_agent_step_task_id_step_index ON agent_step (task_id, step_index);
  • Run the same query again, see that the plan changed
  • Write the before/after times under docs/ and in the README

Then try (multiplies the learning)

  • Compare an index on task_id alone with the composite index — is there a difference, why?
  • Index on agent_task.status: when selectivity is low, does the planner use the index?
  • Build an N+1 scenario (fetch a task's steps one by one in a loop), count the queries, then convert to a single query

Month close

  • Exit-criteria check (below)
  • The three retro questions (Weekly Rhythm)
  • Month 1 social media content
  • Month 2 issues opened

3. Tasks and how they split

The two of you decide who takes what — this is just the shape of the work. Task branches are ready (feat/12-…chore/19-…).

Work Mode
control-plane skeleton + schema (Java) solo — one of you
agent-runtime skeleton + Docker (Python) solo — the other
Contract design (#14) together
End-to-end flow (#17) together
EXPLAIN ANALYZE profiling study (#18) together
Review of every PR cross, mandatory

Whoever starts on Java swaps to the other side at the mid-month rotation, so both of you touch both stacks.

Why are some things "together"? Contract, schema, and measurement — all three are decisions that affect everything later. Letting one person make them puts the other person on top of a foundation they don't understand for six months.


4. Month 1 exit criteria

You don't move to Month 2 until all of these boxes are checked.

Product

  • make up works from scratch on a clean machine
  • Both services healthy; /health returns 200 on both
  • app_user, agent_task, agent_step schema set up via Flyway
  • End-to-end flow works: request → task record → runtime call → step record → read back
  • The service contract is defined in schemas.py and both services conform to it
  • CI green (python + java + compose)
  • At least a few meaningful tests in each service

Measurement

  • EXPLAIN ANALYZE study done on agent_step
  • Before/after index time difference with numbers in the README
  • N+1 scenario tried and fixed

Learning

  • Both people can explain all 10 concepts
  • The Month 1 rows on the Glossary page are filled in your own words
  • DDIA's first three chapters read

Documentation

  • ADR-0001, 0002, 0003 read and understood (updated if needed)
  • This wiki page is up to date, retro notes written

5. What you'll gain in the end

  • A working, two-language (Python + Java) microservice skeleton — a strong resume line on its own
  • Understanding database internals in a measurement-proven way — the backbone of interviews
  • A data model that can record multi-step agent work, on which everything will be built
  • A one-command, Dockerized development environment

Technologies learned: Java, Spring Boot, Python, FastAPI, PostgreSQL, REST API design, OpenAPI, Docker, docker-compose, Flyway, Git, SQL and query optimization (EXPLAIN ANALYZE, indexing).


6. This month's content plan

Episode 1 of the series — the goal is to bring people into the journey. (Who films what is up to the two of you.)

Content Note
Intro video (2–3 min) "We're building an open-source AI agent platform from scratch in 6 months" — explain the goal and why you chose agents
Architecture whiteboard clip Screen-record drawing the two-service architecture in Excalidraw, share as a timelapse
"People are surprised" short clip Show the EXPLAIN ANALYZE before/after time in large type (a concrete number like "900 ms → 12 ms" lands well)
Repo banner / cover image Clean, professional

Tip: At the end of every post, say "the repo is at the skeleton stage right now, leave a star and follow the series". Early followers are the fuel for the Month 6 launch.


7. Retro (to be filled at month end)

A decision that went well and why:

What took longer than expected and why:

The one thing we'll do differently next month:

Clone this wiki locally