Prayog: Build Plan for Claude Code (MVP)¶
Version 1.2 · 3 Oct 2026 (Spring Boot 4; confirmed defaults and milestones in section 16) · Owner: Raj Joshi
0. How to use this file¶
Before any code is written, Claude Code must list every default it will use (section 8 and anything implied elsewhere) and wait for Raj to confirm. Build tool is Maven, not Gradle.
- Create an empty GitHub repo named
prayogand clone it. - Save this file as
docs/BUILD_PLAN.md. - Open the repo in Claude Code and send this first prompt:
Read docs/BUILD_PLAN.md. Create CLAUDE.md in the repo root using section 1 exactly. Create docs/PROGRESS.md with the session list from section 10, all unchecked. Then show me your plan for Session S1. Do not write any other code yet.
- For every later session, use the prompt template in section 9.
1. CLAUDE.md (copy this block into the repo root as-is)¶
# CLAUDE.md
Prayog is a simulated stock exchange and bot arena: simulated traders create the market; people trade by hand or with bots. Full plan: docs/BUILD_PLAN.md. Progress: docs/PROGRESS.md.
## Rules
- No employer code, data, names or designs. Public knowledge and textbook algorithms only.
- Tests first for core logic. A change is done only when its tests pass.
- Measure, don't guess: every performance number comes from a benchmark recorded in docs/benchmarks.md (command, machine, date).
- Ask before adding any dependency not listed in docs/BUILD_PLAN.md section 8.
- No secrets in git. Use .env files (git-ignored) and .env.example.
- Conventional commits. Commit after every green test run.
## Stack
- Java 21, Spring Boot 4, Maven (multi-module, Maven Wrapper), jOOQ (no JPA, no MyBatis), Flyway, LMAX Disruptor, JUnit 5, jqwik, Testcontainers, JMH.
- Python 3.12, uv, Ruff, pytest (agents and SDK).
- React, TypeScript, Vite, Redux Toolkit, pnpm (web).
- Kafka (KRaft), PostgreSQL 16, Redis 7, Keycloak, Traefik, Docker Compose.
## Engine invariants (never break)
- Prices and quantities are integers (price in paise as long). Never use floating point for money.
- One writer thread per shard. No locks in matching logic.
- Time comes from the simulated clock passed in as input, never from the system clock.
- Same seed and inputs must produce a byte-identical event log.
- The order path never calls the network or a database.
## Token hygiene
- Read only the files named in the task, plus what you need to find. Never read target/, generated/, node_modules/ or dist/.
- Run only the tests for the module you changed; run the full suite before the final commit of a session.
- When a command fails, show only the relevant error lines.
- Keep answers short; no recap of unchanged code.
## Session workflow
1. Restate the session goal and acceptance criteria from docs/BUILD_PLAN.md section 10.
2. Propose a plan of at most 10 steps. Wait for approval.
3. Implement in small steps with tests.
4. Run tests, commit.
5. Ask me 5 explain-back questions about what was built (design choices, failure modes, trade-offs). Do not continue until I answer.
6. Tick the session in docs/PROGRESS.md and note decisions in docs/adr/ when a choice was made.
2. Product summary¶
- Prayog is a realistic simulated exchange with fictitious NSE-style stocks. A hidden fair-value path per stock drives simulated traders; the market emerges from their orders.
- MVP goal: a live simulated market you can trade by hand or with a Python bot, with exact replay and P&L, running on one machine with
make up. - Why this project: flagship CV project for trading-technology and banking roles; it needs no external market data.
- Design docs (for humans, written in Claude Docs): Prayog BRD v0.1 and Prayog Technical Discovery v0.1.
3. MVP scope¶
In the MVP
- Order book and matching for 3-5 fictitious stocks: limit, market, cancel, modify; price-time priority; price bands; continuous trading only.
- Input journal and deterministic replay with a checksum test.
- Gateway: REST and WebSocket, bot API keys, rate limits, kill switch.
- Market data: top of book, depth, trades, with sequence numbers.
- Simulated traders: market maker, noise, momentum; seeded fair value; scenarios
calmandvolatile. - After the trade: Kafka to a post-trade service that keeps positions and P&L with a simple charge model (PostgreSQL via jOOQ).
- Web: trading terminal (order entry, depth ladder, chart, blotter, P&L) and a minimal ops page.
- Python bot SDK with one sample bot and a quick-start guide.
- Leaderboard by net P&L (Redis).
- Keycloak sign-in, metrics, a JMH benchmark, CI with order-book and replay tests.
Not in the MVP (do not build yet): opening auction, IOC and stop-loss orders, surveillance and Elasticsearch, contract-note PDFs, settlement, replay viewer UI, risk-adjusted scoring, seasons, hosted bots, FIX, ETF baskets, options, AI assistant, cloud deployment.
4. Architecture (MVP)¶
| Deployable | Tech | Role |
|---|---|---|
services/exchange |
Java 21, Spring Boot 4, Disruptor | Gateway + sequencer + matching engine + market-data publisher in one process |
services/post-trade |
Java 21, Spring Boot, jOOQ, Flyway | Kafka consumer: positions, P&L, charges; leaderboard updates |
services/agents |
Python, asyncio | Simulated traders using the public API (no back door) |
apps/web |
React, TypeScript, Vite, Redux Toolkit | Terminal and ops page |
sdk/python |
Python | Bot client library and sample bot |
| Infra | Kafka (KRaft), PostgreSQL, Redis, Keycloak, Traefik | Local via Docker Compose |
Order path: gateway validates and rate-limits → Disruptor ring → single matching thread per shard (pre-trade checks, matching) → events to: journal writer, market-data publisher, Kafka publisher.
After the trade: the Kafka publisher runs on its own thread, off the order path. The journal is the source of truth; if Kafka is down, trading continues and the publisher catches up from the journal. Post-trade consumers are idempotent (unique event IDs).
Determinism: every input gets a sequence number; the simulated clock is an input; agents use seeded random numbers; replaying the journal must reproduce a byte-identical event log.
5. Domain basics¶
- Instrument: symbol, tick size (paise), lot size (1 for MVP), daily price band (percent of reference price), reference price.
- Order: order ID (server-assigned, monotonic), client order ID, account ID, symbol, side, type (LIMIT, MARKET), price (paise, long), quantity (long), sim timestamp.
- Matching rules:
- Price, then time priority.
- Market orders take liquidity up to the price band; any unfilled remainder is cancelled.
- Modify: reducing quantity keeps priority; increasing quantity or changing price loses priority.
- Self-trade prevention: cancel the incoming order.
- Orders priced outside the band are rejected.
- Events: OrderAccepted, OrderRejected (with reason), OrderCancelled, OrderModified, Trade (aggressor side, both order IDs), BookUpdate, SessionStateChanged. Each event has a sequence number and sim time.
- Charges (simple MVP model): configurable per-trade brokerage plus percentage fees; detailed Indian charge model comes later.
6. Repository layout¶
prayog/
services/exchange/ services/post-trade/ services/agents/
apps/web/ sdk/python/ contracts/
deploy/compose/ docs/ (BUILD_PLAN.md, PROGRESS.md, adr/, benchmarks.md, failure-modes.md)
Makefile CLAUDE.md README.md .github/workflows/
contracts/ holds the REST and WebSocket message schemas and the Kafka event schemas (JSON Schema for the MVP).
7. Container contract¶
- One process per container; one Dockerfile per deployable (multi-stage).
- Configuration only through environment variables; no hostnames in images.
- Health and readiness endpoints; clean shutdown on stop signal.
- JSON logs to standard output.
- Stateless except declared volumes (exchange journal, PostgreSQL, Kafka).
- Images built for ARM and x86, non-root user, pinned base images, tagged by Git commit.
- Flyway migrations run as a one-off job before services start.
- JVM memory set as a percentage of the container limit.
- Exactly one exchange instance may run at a time (single writer).
Local addresses (Traefik): app.prayog.localhost (web), api.prayog.localhost (gateway), auth.prayog.localhost (Keycloak), grafana.prayog.localhost.
8. Decisions¶
Taken: Java 21; Spring Boot 4 (changed from 3 on 3 Oct 2026); Maven (multi-module parent POM, Maven Wrapper); jOOQ; Flyway; LMAX Disruptor; Kafka for everything after the trade; PostgreSQL; Redis; Keycloak; Traefik subdomains; monorepo; synthetic market; bring-your-own bots before hosted bots.
Defaults for open decisions (change only if Raj says so):
| Decision | Default for MVP | Revisit |
|---|---|---|
| Journal | Simple append-only file journal behind a Journal interface |
Chronicle Queue if performance demands |
| Gateway transport | Spring WebFlux WebSockets | Netty directly if latency demands |
| Kafka message format | JSON validated by JSON Schema in contracts/ |
Avro with a schema registry later |
| Product after equities | Not decided | After MVP |
Defaults to confirm before Session S1: Java and Spring Boot versions; Maven layout (parent POM, module names, Maven Wrapper); jOOQ and Flyway setup; Disruptor configuration (ring size, wait strategy); journal format; gateway transport; message format and schema location; Keycloak realm and clients; Traefik subdomains and ports; Python tooling (uv, Ruff, pytest); web tooling (pnpm, Vite, Redux Toolkit, charting library); folder layout; Makefile targets; CI steps.
Approved dependency list (ask before adding others): Spring Boot starters (web, webflux, actuator, security, oauth2-resource-server), jOOQ, Flyway, PostgreSQL driver, spring-kafka, Lettuce (Redis), LMAX Disruptor, Agrona, SBE (Simple Binary Encoding: sbe-tool at build time, for the journal codec; approved 2026-10-04), Micrometer + Prometheus registry, JUnit 5, jqwik, Testcontainers, JMH, HdrHistogram, Cucumber-JVM; Python: websockets or httpx, pydantic, numpy, pytest, ruff; Web: react, redux toolkit, react-router, a charting library (ask first).
9. Session prompt template¶
Session S<n>: <title> (docs/BUILD_PLAN.md section 10).
Restate the goal and acceptance criteria, then propose a plan of at most 10 steps and wait.
Only touch: <folders>.
Stop when the acceptance criteria pass; commit; then ask me the 5 explain-back questions.
10. Sessions (MVP, about 110-130 hours)¶
Estimates are rough. One session fits one 5-hour usage window.
Phase A: Foundation¶
- S1 Repo skeleton and tooling (5 h) — Maven multi-module (parent POM, Maven Wrapper
./mvnw) for Java services, uv project for Python, pnpm workspace for web, Makefile (up,down,test,fmt), GitHub Actions running build and tests,.env.example. Done when:make testpasses on an empty skeleton and CI is green. - S2 Local infrastructure (5 h) — Compose with profiles: PostgreSQL, Kafka (KRaft), Redis, Keycloak (realm import with a web client and a bot client), Traefik with the subdomains. Health checks and start order. Done when:
make upbrings everything healthy and the subdomains respond. - S3 Contracts and domain types (5 h) — JSON Schemas for orders, events and market data; Java domain types (Price and Quantity as longs, IDs, enums). Done when: schemas validate sample messages in tests.
Phase B: Matching engine¶
- S4 Order book and limit matching (6 h) — Book per symbol, price levels, FIFO queues, limit orders, trades. Property tests: book never crossed; quantity conserved. Done when: unit and property tests pass.
- S5 Market, cancel, modify (6 h) — Rules from section 5, including priority on modify. Done when: tests cover every rule.
- S6 Price bands, sessions, self-trade prevention (5 h) — Band rejection, session states (closed, open, halted), cancel-incoming STP. Done when: tests pass.
- S7 Sequencer and single-writer pipeline (6 h) — Disruptor ring, sequence numbers, sim clock as input, event fan-out handlers. Done when: concurrent submit test shows deterministic ordering.
- S8 Journal and deterministic replay (6 h) — Append-only journal behind an interface; replay tool; checksum test in CI. Done when: replaying a recorded session gives an identical event-log checksum.
- S9 Benchmarks (4 h) — JMH for book operations (as a separate Maven module); end-to-end latency harness with HdrHistogram. Done when: numbers recorded in docs/benchmarks.md with method and machine.
Phase C: Gateway and market data¶
- S10 Gateway (6 h) — REST and WebSocket order entry; Keycloak JWT for web users and client-credentials for bots; per-account rate limits; kill switch. Done when: integration tests place, modify and cancel orders through the API.
- S11 Market data (5 h) — Top of book, depth and trades over WebSocket with sequence numbers; snapshot then deltas. Done when: a test client rebuilds the book exactly from the feed.
Phase D: Market life¶
- S12 Python SDK and sample bot (5 h) — Connect, authenticate, subscribe, place and cancel; a simple sample bot; quick-start README. Done when: the sample bot trades against the local exchange.
- S13 Simulated traders (7 h) — Fair-value process (mean-reverting with jumps), market maker, noise and momentum traders; scenarios
calmandvolatile; seeded. Done when: a 30-minute simulated session runs with continuous two-sided quotes. - S14 Realism checks (4 h) — Script reporting return distribution, volatility clustering and spread statistics per scenario. Done when: report saved for both scenarios.
Phase E: After the trade¶
- S15 Kafka publisher (5 h) — Publisher thread off the order path; catch-up from the journal after Kafka downtime. Done when: killing Kafka mid-session loses no events after restart.
- S16 Post-trade service (7 h) — Flyway schema, jOOQ code generation with the jooq-codegen-maven plugin (generate from a Flyway-migrated PostgreSQL started by Testcontainers), idempotent consumer, positions, realised and unrealised P&L, simple charges. Done when: P&L reconciles exactly with the trade log in a test.
- S17 Leaderboard (3 h) — Redis sorted set by net P&L; REST endpoint. Done when: leaderboard updates during a live session.
Phase F: Web¶
- S18 Trading terminal (8 h) — Sign-in, order entry, depth ladder, trade tape, price chart. Done when: manual trading works end to end in the browser.
- S19 Blotter, P&L and ops page (6 h) — Orders and trades blotter, P&L panel, leaderboard view; ops page to start, stop and switch scenarios. Done when: a full simulated day can be run from the ops page.
Phase G: Hardening and showcase¶
- S20 Exchange rules as Cucumber scenarios (5 h) — Key matching rules written as Given/When/Then and run in CI. Done when: scenarios pass in CI.
- S21 Observability (4 h) — Micrometer metrics, Prometheus and Grafana dashboards: latency, throughput, queue depth, consumer lag. Done when: dashboards show a live session.
- S22 Docs and demo (5 h) — README with architecture diagram (Mermaid), docs/failure-modes.md, ADRs, a 3-minute demo script, recorded demo. Done when: a newcomer can run
make upand follow the README.
11. Definition of done¶
Per session: acceptance criteria met; tests green; committed; explain-back answered; PROGRESS.md ticked; ADR written if a decision was made.
MVP: make up starts everything; a simulated day runs; a person and the sample bot can trade; replay checksum passes in CI; P&L reconciles; benchmarks published; README and demo done.
12. Testing strategy¶
- Unit and property-based tests (jqwik) for the order book.
- Cucumber scenarios for exchange rules.
- Integration tests with Testcontainers (PostgreSQL, Kafka, Redis, Keycloak).
- Replay determinism test in CI.
- Chaos checks: stop Kafka or the post-trade service mid-session and verify recovery.
13. Interview notes to keep as you go¶
docs/adr/— one short record per decision: context, options, choice, trade-off.docs/benchmarks.md— every measured number with command, machine and date.docs/failure-modes.md— what breaks, how it is detected, how it recovers.
14. Usage-window hygiene (5-hour limit)¶
- Start a session only when ready for a full block; one session per window.
/clearbetween sessions;/compactin long ones;/usageto check headroom.- Name exact files and folders in prompts; keep CLAUDE.md short.
- Prefer the default model; use the most capable model only for hard design questions.
- Keep heavy chat in claude.ai to a minimum on build days: chat and Claude Code share one usage pool.
15. After the MVP (do not build now)¶
v1.1: opening auction, IOC and stop-loss, fuller ops console, replay viewer. Phase 2: contract notes, settlement, surveillance with Elasticsearch, risk-adjusted leaderboards, backtester, outside bots. Phase 3: RJ's Trading Challenge seasons, hosted sandbox bots, ETF basket and options, FIX. Phase 4: AI assistant. Cloud deployment (ECS or Kubernetes) when hosting is decided.
16. Confirmed decisions (3 Oct 2026)¶
Confirmed by Raj before M0. These override earlier sections where they differ.
16.1 Technical defaults¶
| # | Item | Decision |
|---|---|---|
| 1 | Java | 21 LTS (Temurin in CI and images) |
| 2 | Spring Boot | 4.x (Spring Framework 7, Jakarta EE 11, Jackson 3 tools.jackson, modular starters such as spring-boot-starter-flyway, -jooq, -kafka). Pinned versions are in section 16.5 |
| 3 | Build | Maven 3.9 + Maven Wrapper (./mvnw). The root pom.xml is both parent and aggregator, with dependencyManagement and pluginManagement |
| 4 | Maven modules | contracts (JSON Schemas + Java event records), services/exchange/exchange-core (plain Java engine, no Spring), services/exchange/exchange-app (Spring Boot), services/exchange/exchange-bench (JMH), services/post-trade |
| 5 | Java package / groupId | dev.prayog |
| 6 | Java formatting | Spotless + palantir-java-format (make fmt; checked in CI) |
| 7 | Logging | Spring Boot structured logging (JSON to stdout) |
| 8 | Java tests | JUnit + jqwik + AssertJ; unit tests via Surefire run without Docker; integration tests (*IT) via Failsafe use Testcontainers |
| 9 | Flyway | Migrations in services/post-trade/src/main/resources/db/migration; Spring auto-migrate off; one-off flyway/flyway job in Compose |
| 10 | jOOQ | 3.21.x OSS (managed by Spring Boot); code generated at build time by testcontainers-jooq-codegen-maven-plugin from a Flyway-migrated Testcontainers PostgreSQL; generated code not committed (build needs Docker) |
| 11 | Disruptor | 4.x; ring size 65,536; ProducerType.MULTI; wait strategy set by env var (default BLOCKING; BUSY_SPIN/YIELDING for benchmarks) |
| 12 | Shards | 1 shard (all symbols on one matching thread) for the MVP |
| 13 | Sequencing | Input sequence and event sequence assigned on the matching thread |
| 14 | Journal | Two append-only files. Input journal: every command received (used for replay). Event log: every event the engine produced (used for the checksum and Kafka catch-up). Custom binary records [len][seq][type][payload][crc32c], segment files under /data/journal, fsync at end of each Disruptor batch. Determinism checksum: SHA-256 over the event-log bytes |
| 15 | Determinism scope | Replaying the input journal reproduces a byte-identical event log. Re-running agents with the same seed does not reproduce a session, because their orders arrive over the network with nondeterministic timing |
| 16 | Sim clock | A clock thread off the order path reads wall time every 100 ms and publishes ClockTick(simTime) commands, which are journaled. simTime = sessionStart + wallElapsed × multiplier. Configurable: multiplier, day open and day close come from env vars (defaults 1, 09:15, 15:30) and the multiplier can be changed at runtime from the ops page. The clock thread changes only the tick rate, so replay stays deterministic. S13's "30-minute session" means 30 wall minutes at 1× |
| 17 | Gateway | Spring WebFlux for REST and WebSocket (no MVC in the exchange); JSON envelopes with type and seq; prices are integer paise |
| 18 | Kafka | apache/kafka 4.x in KRaft mode, single node; topic prayog.exchange.events.v1, 3 partitions, keyed by symbol; JSON validated against JSON Schema; at-least-once delivery; eventId = exchange event sequence; consumers idempotent |
| 19 | Kafka catch-up | The publisher reads the event log from "last published sequence + 1", so Kafka downtime never stops trading and loses no events. Code comments explain offsets, at-least-once delivery and idempotency |
| 20 | Schemas | JSON Schema draft 2020-12 in contracts/schemas/{rest,ws,events}/; validated in tests by com.networknt:json-schema-validator (Java) and jsonschema (Python) |
| 21 | Auth | Keycloak 26.x, realm prayog imported from deploy/compose/keycloak/. Clients: prayog-web (public, PKCE), prayog-api (resource-server audience), prayog-bot-demo and prayog-agents (confidential, client credentials). A bot "API key" = Keycloak client ID + secret. Realm roles trader, ops, bot; seed users trader1, ops1 (dev passwords in .env) |
| 22 | Rate limits | Token bucket per account in the gateway (no library); limits set by env var; agents get a high limit through config. A separate agent rate-limit tier is Phase 2 |
| 23 | Kill switch | Global (ops sets session HALTED) and per account (disable account, cancel its resting orders) |
| 24 | Infra images | postgres:16-alpine, redis:7-alpine, apache/kafka:4.x, Keycloak 26, Traefik v3; pinned |
| 25 | Redis / leaderboard | Lettuce; post-trade writes sorted set prayog:leaderboard and serves GET /leaderboard |
| 26 | Traefik | v3, HTTP only on host port 80; app., api., auth., grafana., traefik. .prayog.localhost; /etc/hosts entries documented for non-browser clients; KC_HOSTNAME=http://auth.prayog.localhost |
| 27 | Ports | Inside containers: exchange 8080, post-trade 8081, Keycloak 8080, web 80. Exposed to the host for dev: Postgres 5432, Kafka 9094, Redis 6379 |
| 28 | Compose | deploy/compose/compose.yaml; profiles infra, app, obs; health checks + depends_on conditions |
| 29 | Container images | Multi-stage; eclipse-temurin:21-jre runtime; non-root; -XX:MaxRAMPercentage=75; multi-arch through docker buildx (registry push deferred until hosting is decided) |
| 30 | Python | 3.12 (.python-version, installed by uv); one uv workspace at the root with sdk/python (prayog_sdk) and services/agents; Ruff, pytest, pytest-asyncio, httpx + websockets, pydantic, numpy |
| 31 | Web | Node 22 LTS; pnpm 10 through corepack; pnpm-workspace.yaml at the root; React 19, TypeScript 6 strict, Vite 8, Redux Toolkit + RTK Query, react-router 7, oidc-client-ts, TradingView Lightweight Charts (attribution link required), ESLint (replaces the oxlint that the Vite template now ships), Prettier, Vitest + jsdom, Testing Library |
| 32 | Makefile | up, down, test, fmt, lint, build, logs, clean, help; bench and replay-check added in S8/S9 |
| 33 | make test |
./mvnw -B verify, uv run pytest, pnpm -r test |
| 34 | CI | GitHub Actions ci.yml on push and PR; parallel jobs: java (./mvnw -B verify), python (ruff check, ruff format --check, pytest), web (install with frozen lockfile, lint, typecheck, test, build) |
| 35 | ADRs | docs/adr/NNNN-title.md (Nygard format) |
| 36 | Git | GitHub repo prayog; main branch; conventional commits |
| 37 | Local tools | Homebrew: Docker Desktop, maven (only to create the wrapper once), uv, gh; pnpm through corepack; Python 3.12 through uv |
16.2 Approved additions to the dependency list (section 8)¶
networknt json-schema-validator, Python jsonschema, pytest-asyncio, testcontainers-jooq-codegen-maven-plugin, Spotless + palantir-java-format, ESLint, Prettier, Vitest, Testing Library, oidc-client-ts, TradingView Lightweight Charts. S14 analysis libraries (pandas, scipy, matplotlib) still need approval when S14 starts.
Approved 2026-10-04 for Step 1.5: MkDocs Material (docs site build only, never shipped in the app) and react-grid-layout (web workspace: drag, drop and resize panels).
16.3 Rule clarifications¶
- A modify that reduces quantity to the filled amount or below becomes a cancel.
- A market order that finds no liquidity is cancelled with a reason.
- The band reference price is static per instrument for the MVP (no day rollover).
16.4 Milestones¶
Work proceeds by milestone. Sessions keep their section 10 definitions.
| Milestone | Sessions | Done when |
|---|---|---|
| M0 Setup | tool installs, git and GitHub setup, CLAUDE.md, PROGRESS.md, S1 | make test passes on the empty skeleton, pushed to GitHub, CI green |
| M1 First module | S3, S4 | contracts and exchange-core (limit matching) compile, unit and property tests pass, pushed |
| M2 Engine complete | S5, S6, S7, S8 | All matching rules tested; Disruptor pipeline; replay checksum test passes in CI |
| M3 Runnable app | S2, S10, S11, S12, S13, S15, S16, S17, S18, S19 | make up; sign in at app.prayog.localhost; trade by hand; the sample bot trades; P&L and leaderboard update |
| M4 Hardening layers | S9, S14, S20, S21, S22 + multi-arch images + Phase 2 items (e.g. agent rate-limit tier) | MVP definition of done (section 11) met |
16.5 Pinned versions (verified in M0, 3 Oct 2026)¶
| Component | Version | Note |
|---|---|---|
| Spring Boot | 4.1.1 | Latest stable 4.x; parent POM spring-boot-starter-parent |
| Maven (wrapper) | 3.9.16 | ./mvnw; wrapper 3.3.4 |
| JUnit Jupiter | 6.0.3 | Managed by Spring Boot |
| jqwik | 1.10.1 | Runs on JUnit Platform 6 (verified by ToolchainSmokeTest) |
| AssertJ | 3.27.7 | Managed by Spring Boot |
| jOOQ | 3.21.7 | Managed by Spring Boot |
| Flyway | 12.4.0 | Managed by Spring Boot |
| Testcontainers | 2.0.5 | Managed by Spring Boot |
| Kafka client / spring-kafka | 4.2.1 / 4.1.1 | Managed by Spring Boot |
| Jackson | 3.1.5 | Managed by Spring Boot |
| LMAX Disruptor | 4.0.0 | |
| JMH | 1.37 | |
| HdrHistogram | 2.2.2 | |
| networknt json-schema-validator | 3.0.8 | |
| Spotless / palantir-java-format | 3.10.3 / 2.101.0 | |
| Python | 3.12.15 | uv 0.12 |
| Node / pnpm | 22 / 10.34.6 | |
| React / TypeScript / Vite / Vitest | 19.2 / 6.0 / 8.3 / 5.0 |
Risk for S16: testcontainers-jooq-codegen-maven-plugin was last released in April 2024 (0.0.4) and targets Testcontainers 1.x. If it fails with Testcontainers 2 and Flyway 12, the fallback is jOOQ's DDLDatabase (generates from the Flyway SQL files without a database) or a small Testcontainers-driven codegen step. Decide in S16 and record an ADR.