Files
py-dvt-ate/docs/04_development_plan.md
Kai Chappell a60fb4c2b7 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
2025-01-17 13:06:43 +00:00

17 KiB

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