-
Notifications
You must be signed in to change notification settings - Fork 0
Month 1 Plan
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.
This list is not divided. Code is divided, learning is not.
| 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 |
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
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 (
api→service→repository) -
/healthendpoint + 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) -
/healthendpoint - 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.pyand 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?
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,
CHECKconstraints,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
Dockerfilefor both services -
docker-compose.yml: postgres + both services, healthcheck anddepends_onset up correctly -
make upbrings everything up with one command -
.env.examplecomplete
Together (pairing)
- Review the schema together. Especially: why is
agent_stepa separate table? - An isolation-level experiment: open two
psqlsessions, update the same row, see with your own eyes the difference between Read Committed and Repeatable Read
Why is
agent_stepa 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?
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) → anagent_taskrecord is created (status=pending) - control-plane calls the agent-runtime's
/v1/tasks/runendpoint - agent-runtime returns a stub
AgentStep - control-plane writes this step to the
agent_steptable and sets the task tosucceeded -
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?
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_steptable (via a script) - Run this query: fetch all steps of a task in
step_indexorder - Take the
EXPLAIN ANALYZEoutput 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_idalone 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
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.
You don't move to Month 2 until all of these boxes are checked.
Product
-
make upworks from scratch on a clean machine - Both services healthy;
/healthreturns 200 on both -
app_user,agent_task,agent_stepschema 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.pyand 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
- 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).
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.
A decision that went well and why:
What took longer than expected and why:
The one thing we'll do differently next month:
AgentLens
Project
Working Cadence
Months
Reference