From 3a0fd0e0924a4e15479046216023218b90fb8f38 Mon Sep 17 00:00:00 2001 From: Kai Chappell Date: Fri, 17 Jan 2025 13:06:43 +0000 Subject: [PATCH] docs: add iterative development plan for Phase 1 - Break Phase 1 into 25 sprints with atomic tasks - Define stub-first approach for manageable complexity - Specify commit messages for each task - Include LLM optimisation notes for context management --- docs/04_development_plan.md | 542 ++++++++++++++++++++++++++++++++++++ 1 file changed, 542 insertions(+) create mode 100644 docs/04_development_plan.md diff --git a/docs/04_development_plan.md b/docs/04_development_plan.md new file mode 100644 index 0000000..aa24e11 --- /dev/null +++ b/docs/04_development_plan.md @@ -0,0 +1,542 @@ +# Development Plan +## Phase 1: Vertical Slice (MVP) + +| Document ID | DEV-001 | +|-------------|---------| +| Version | 1.0.0 | +| Status | Active | +| Author | Kai Chappell | +| Created | 2025-12-01 | + +--- + +## Approach + +This plan follows an **iterative, stub-first development** strategy optimised for incremental progress: + +1. **Interfaces First** - Define protocols/interfaces before implementations +2. **Stubs Before Logic** - Create skeleton classes that pass type checks before adding behaviour +3. **Bottom-Up Construction** - Build foundational layers before dependent layers +4. **Frequent Commits** - Small, atomic commits after each meaningful change +5. **Minimal Context** - Each iteration should be completable with minimal codebase knowledge + +--- + +## Sprint Structure + +Each sprint represents ~2-4 hours of focused work. Sprints are designed to be self-contained with clear deliverables. + +--- + +## Sprint 1: Project Scaffolding + +**Goal:** Create project structure and build configuration. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 1.1 | Create `pyproject.toml` with project metadata and dependencies | `chore: add pyproject.toml with dependencies` | +| 1.2 | Create `src/thermaulate/__init__.py` with version | `chore: create package structure` | +| 1.3 | Create empty subpackage `__init__.py` files for all modules | `chore: add subpackage stubs` | +| 1.4 | Create `py.typed` marker file | `chore: add py.typed marker for PEP 561` | +| 1.5 | Create `config/default.yaml` with basic structure | `chore: add default configuration file` | + +### Deliverables +- `pip install -e .` works +- All imports resolve (empty packages) +- Type checker can be run + +--- + +## Sprint 2: Configuration System + +**Goal:** Load and validate configuration. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 2.1 | Create `config/models.py` with Pydantic config classes | `feat(config): add Pydantic configuration models` | +| 2.2 | Create `config/loader.py` to load YAML and return AppConfig | `feat(config): add configuration loader` | +| 2.3 | Add unit tests for config loading | `test(config): add configuration tests` | + +### Deliverables +- Can load `config/default.yaml` into typed Python objects +- Invalid configs raise clear errors + +--- + +## Sprint 3: Transport Layer (Stubs) + +**Goal:** Define transport abstractions. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 3.1 | Create `transport/base.py` with `Transport` Protocol | `feat(transport): add Transport protocol` | +| 3.2 | Create `transport/tcp.py` with `TCPTransport` stub class | `feat(transport): add TCPTransport stub` | + +### Deliverables +- Transport interface defined +- TCPTransport class exists with NotImplementedError methods + +--- + +## Sprint 4: Transport Layer (Implementation) + +**Goal:** Implement TCP transport. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 4.1 | Implement `TCPTransport.connect()` and `disconnect()` | `feat(transport): implement TCP connect/disconnect` | +| 4.2 | Implement `TCPTransport.write()` and `read()` | `feat(transport): implement TCP read/write` | +| 4.3 | Implement `TCPTransport.query()` | `feat(transport): implement TCP query` | +| 4.4 | Add unit tests with mock socket | `test(transport): add TCP transport tests` | + +### Deliverables +- Can connect to TCP server and exchange messages +- Handles connection errors gracefully + +--- + +## Sprint 5: SCPI Parser + +**Goal:** Parse SCPI command strings. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 5.1 | Create `instruments/scpi_parser.py` with `SCPICommand` dataclass | `feat(scpi): add SCPICommand dataclass` | +| 5.2 | Implement `SCPIParser.parse()` method | `feat(scpi): implement SCPI parser` | +| 5.3 | Add comprehensive parser tests | `test(scpi): add parser tests` | + +### Deliverables +- Can parse `*IDN?`, `VOLT 3.3`, `TEMP:SETPOINT?`, etc. +- Returns structured command objects + +--- + +## Sprint 6: Physics Engine (Stubs) + +**Goal:** Define physics simulation interfaces. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 6.1 | Create `physics/engine.py` with state dataclasses | `feat(physics): add ThermalState and ElectricalState` | +| 6.2 | Create `PhysicsEngine` class with stub methods | `feat(physics): add PhysicsEngine stub` | +| 6.3 | Create `physics/dut/base.py` with `DUTModel` Protocol | `feat(physics): add DUT model protocol` | + +### Deliverables +- Physics interfaces defined +- State objects can be instantiated + +--- + +## Sprint 7: Physics Engine (Thermal) + +**Goal:** Implement thermal simulation. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 7.1 | Implement `PhysicsEngine.step()` thermal calculations | `feat(physics): implement thermal step` | +| 7.2 | Implement `PhysicsEngine.set_chamber_setpoint()` | `feat(physics): implement chamber setpoint` | +| 7.3 | Implement `PhysicsEngine.get_thermal_state()` | `feat(physics): implement thermal state getter` | +| 7.4 | Add thermal simulation tests | `test(physics): add thermal simulation tests` | + +### Deliverables +- Chamber temperature ramps toward setpoint +- Case temperature follows with time constant + +--- + +## Sprint 8: LDO DUT Model + +**Goal:** Implement LDO electrical model. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 8.1 | Create `physics/dut/ldo.py` with `LDOModel` class | `feat(physics): add LDO model stub` | +| 8.2 | Implement temperature-dependent output voltage | `feat(physics): implement LDO Vout vs temperature` | +| 8.3 | Implement power dissipation calculation | `feat(physics): implement LDO power dissipation` | +| 8.4 | Implement quiescent current model | `feat(physics): implement LDO quiescent current` | +| 8.5 | Add LDO model tests | `test(physics): add LDO model tests` | + +### Deliverables +- LDO output voltage varies with temperature (TempCo) +- Power dissipation calculated correctly + +--- + +## Sprint 9: Physics Engine (Electrical Coupling) + +**Goal:** Connect electrical and thermal domains. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 9.1 | Integrate LDO model into PhysicsEngine | `feat(physics): integrate DUT model` | +| 9.2 | Implement self-heating feedback loop | `feat(physics): implement self-heating` | +| 9.3 | Implement `get_electrical_state()` | `feat(physics): implement electrical state getter` | +| 9.4 | Add coupled physics tests | `test(physics): add thermal-electrical coupling tests` | + +### Deliverables +- Higher load current causes self-heating +- Junction temperature affects output voltage + +--- + +## Sprint 10: Virtual Instruments (Stubs) + +**Goal:** Define virtual instrument classes. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 10.1 | Create `instruments/base.py` with `VirtualInstrument` base class | `feat(instruments): add VirtualInstrument base` | +| 10.2 | Create `instruments/thermal_chamber.py` stub | `feat(instruments): add ThermalChamberSim stub` | +| 10.3 | Create `instruments/power_supply.py` stub | `feat(instruments): add PowerSupplySim stub` | +| 10.4 | Create `instruments/multimeter.py` stub | `feat(instruments): add MultimeterSim stub` | + +### Deliverables +- All instrument classes exist +- Common SCPI commands stubbed (IDN, RST) + +--- + +## Sprint 11: Thermal Chamber Simulator + +**Goal:** Implement thermal chamber SCPI commands. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 11.1 | Implement `TEMP:SETPOINT` command | `feat(instruments): implement chamber TEMP:SETPOINT` | +| 11.2 | Implement `TEMP:ACTUAL?` query | `feat(instruments): implement chamber TEMP:ACTUAL?` | +| 11.3 | Implement `TEMP:STAB?` query | `feat(instruments): implement chamber stability query` | +| 11.4 | Add thermal chamber tests | `test(instruments): add thermal chamber tests` | + +### Deliverables +- Chamber responds to SCPI commands +- Reads from physics engine state + +--- + +## Sprint 12: Power Supply Simulator + +**Goal:** Implement power supply SCPI commands. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 12.1 | Implement `VOLT`, `CURR`, `OUTP` commands | `feat(instruments): implement PSU control commands` | +| 12.2 | Implement `MEAS:VOLT?`, `MEAS:CURR?` queries | `feat(instruments): implement PSU measurements` | +| 12.3 | Add power supply tests | `test(instruments): add power supply tests` | + +### Deliverables +- PSU responds to voltage/current/output commands +- Measurements reflect physics state + +--- + +## Sprint 13: Multimeter Simulator + +**Goal:** Implement DMM SCPI commands. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 13.1 | Implement `MEAS:VOLT:DC?` query | `feat(instruments): implement DMM voltage measurement` | +| 13.2 | Implement `SENS:VOLT:DC:NPLC` command | `feat(instruments): implement DMM NPLC setting` | +| 13.3 | Add multimeter tests | `test(instruments): add multimeter tests` | + +### Deliverables +- DMM returns DUT output voltage from physics +- Integration time configurable + +--- + +## Sprint 14: TCP Server + +**Goal:** Create async TCP server for instruments. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 14.1 | Create `server/tcp_server.py` with async server class | `feat(server): add async TCP server` | +| 14.2 | Implement connection handling and command dispatch | `feat(server): implement command dispatch` | +| 14.3 | Create `server/main.py` entry point | `feat(server): add server entry point` | +| 14.4 | Add server integration tests | `test(server): add TCP server tests` | + +### Deliverables +- Server listens on configured ports +- Routes commands to correct instrument +- Runs physics engine in background + +--- + +## Sprint 15: HAL Interfaces + +**Goal:** Define hardware abstraction protocols. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 15.1 | Create `hal/interfaces.py` with all Protocol classes | `feat(hal): add HAL protocol definitions` | +| 15.2 | Create `hal/factory.py` with `InstrumentSet` and stub factory | `feat(hal): add instrument factory stub` | + +### Deliverables +- IThermalChamber, IPowerSupply, IMultimeter defined +- Factory interface established + +--- + +## Sprint 16: SCPI Drivers + +**Goal:** Create client-side SCPI drivers. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 16.1 | Create `drivers/base.py` with common driver functionality | `feat(drivers): add driver base class` | +| 16.2 | Create `drivers/thermal_chamber.py` | `feat(drivers): add thermal chamber driver` | +| 16.3 | Create `drivers/power_supply.py` | `feat(drivers): add power supply driver` | +| 16.4 | Create `drivers/multimeter.py` | `feat(drivers): add multimeter driver` | + +### Deliverables +- Drivers send SCPI commands via transport +- Parse responses into Python types + +--- + +## Sprint 17: HAL Implementations + +**Goal:** Implement HAL using drivers. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 17.1 | Create `hal/impl/thermal_chamber.py` | `feat(hal): implement ThermalChamberHAL` | +| 17.2 | Create `hal/impl/power_supply.py` | `feat(hal): implement PowerSupplyHAL` | +| 17.3 | Create `hal/impl/multimeter.py` | `feat(hal): implement MultimeterHAL` | +| 17.4 | Implement `InstrumentFactory.create()` | `feat(hal): implement instrument factory` | +| 17.5 | Add HAL integration tests | `test(hal): add HAL integration tests` | + +### Deliverables +- HAL classes wrap drivers +- Factory creates connected instrument set + +--- + +## Sprint 18: Test Executive (Core) + +**Goal:** Create test execution framework. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 18.1 | Create `executive/models.py` with domain models | `feat(executive): add test domain models` | +| 18.2 | Create `executive/context.py` with TestContext | `feat(executive): add test context` | +| 18.3 | Create `executive/logger.py` with test logger | `feat(executive): add test logger` | +| 18.4 | Create `executive/limits.py` with limit checker | `feat(executive): add limit checker` | + +### Deliverables +- Can create test contexts +- Can log measurements +- Can evaluate limits + +--- + +## Sprint 19: Test Executive (Sequencer) + +**Goal:** Implement test sequencer. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 19.1 | Create `executive/sequencer.py` with TestSequencer class | `feat(executive): add test sequencer` | +| 19.2 | Create `tests/base.py` with ITest protocol | `feat(tests): add test base class` | +| 19.3 | Add sequencer tests | `test(executive): add sequencer tests` | + +### Deliverables +- Sequencer runs test instances +- Manages context lifecycle + +--- + +## Sprint 20: TempCo Test Implementation + +**Goal:** Implement temperature coefficient characterisation test. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 20.1 | Create `tests/tempco.py` with TempCoTest class | `feat(tests): add TempCo test stub` | +| 20.2 | Implement temperature sweep logic | `feat(tests): implement TempCo temperature sweep` | +| 20.3 | Implement TempCo calculation | `feat(tests): implement TempCo calculation` | +| 20.4 | Add TempCo test tests | `test(tests): add TempCo test coverage` | + +### Deliverables +- Complete TempCo characterisation test +- Calculates ppm/°C result + +--- + +## Sprint 21: Data Persistence (Schema) + +**Goal:** Set up data storage. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 21.1 | Create `data/models.py` with data models | `feat(data): add data models` | +| 21.2 | Create `data/migrations/001_initial.sql` | `feat(data): add initial schema migration` | +| 21.3 | Create `data/repository.py` with repository interface | `feat(data): add repository interface` | + +### Deliverables +- SQLite schema defined +- Repository interface established + +--- + +## Sprint 22: Data Persistence (Implementation) + +**Goal:** Implement data repository. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 22.1 | Implement SQLite repository for test runs | `feat(data): implement test run persistence` | +| 22.2 | Implement Parquet writer for measurements | `feat(data): implement measurement persistence` | +| 22.3 | Add repository tests | `test(data): add repository tests` | + +### Deliverables +- Test runs persisted to SQLite +- Measurements saved as Parquet files + +--- + +## Sprint 23: CLI (Basic) + +**Goal:** Create command-line interface. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 23.1 | Create `cli/main.py` with Typer app | `feat(cli): add CLI application` | +| 23.2 | Add `server start` command | `feat(cli): add server start command` | +| 23.3 | Add `test run` command | `feat(cli): add test run command` | +| 23.4 | Add `test list` command | `feat(cli): add test list command` | + +### Deliverables +- `thermaulate server start` launches simulation +- `thermaulate test run tempco` executes test + +--- + +## Sprint 24: Streamlit Dashboard (Basic) + +**Goal:** Create real-time monitoring dashboard. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 24.1 | Create `dashboard/app.py` with main Streamlit app | `feat(dashboard): add Streamlit app` | +| 24.2 | Create instruments status page | `feat(dashboard): add instruments page` | +| 24.3 | Add real-time temperature chart | `feat(dashboard): add temperature chart` | + +### Deliverables +- Dashboard shows instrument status +- Temperature updates in real-time + +--- + +## Sprint 25: Integration & Polish + +**Goal:** End-to-end testing and refinement. + +### Tasks + +| # | Task | Commit Message | +|---|------|----------------| +| 25.1 | Run full TempCo test end-to-end | `test: add end-to-end TempCo test` | +| 25.2 | Fix any integration issues discovered | `fix: resolve integration issues` | +| 25.3 | Add demo script | `docs: add demo script` | +| 25.4 | Update README with usage instructions | `docs: update README with usage` | +| 25.5 | Verify 80% test coverage on core modules | `test: ensure coverage targets met` | + +### Deliverables +- Complete working vertical slice +- Demo-able system +- Documentation updated + +--- + +## Sprint Summary + +| Sprint | Focus | Estimated Tasks | +|--------|-------|-----------------| +| 1 | Project scaffolding | 5 | +| 2 | Configuration | 3 | +| 3-4 | Transport layer | 7 | +| 5 | SCPI parser | 3 | +| 6-9 | Physics engine | 16 | +| 10-13 | Virtual instruments | 14 | +| 14 | TCP server | 4 | +| 15-17 | HAL layer | 10 | +| 18-19 | Test executive | 7 | +| 20 | TempCo test | 4 | +| 21-22 | Data persistence | 6 | +| 23 | CLI | 4 | +| 24 | Dashboard | 3 | +| 25 | Integration | 5 | + +**Total: 25 sprints, ~91 tasks, ~91 commits** + +--- + +## LLM Optimisation Notes + +Each sprint is designed for LLM execution with: + +1. **Minimal Context Required** - Each sprint focuses on 1-2 files +2. **Clear Boundaries** - Interfaces defined before implementations +3. **Testable Increments** - Each sprint has verification criteria +4. **Atomic Commits** - Small, focused changes that are easy to review +5. **Stub-First Approach** - Type-safe placeholders before full logic + +When starting a sprint: +1. Read only the relevant module's existing code +2. Reference interfaces/protocols, not implementations +3. Complete all tasks before moving to next sprint +4. Commit after each task + +--- + +**End of Development Plan**