5.4 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Purpose
This repository generates runnable Curtin ICS-SimLab scenarios from textual descriptions. It produces:
configuration.jsoncompatible with Curtin ICS-SimLablogic/*.pyfiles implementing PLC control logic and HIL process physics
Hard boundary: Do NOT modify the Curtin ICS-SimLab repository. Only change files inside this repository.
Common Commands
# Activate virtual environment
source .venv/bin/activate
# Generate configuration.json from text input (requires OPENAI_API_KEY in .env)
python3 main.py --input-file prompts/input_testuale.txt
# Build complete scenario (config -> IR -> logic)
python3 build_scenario.py --out outputs/scenario_run --overwrite
# Validate PLC callback retry fix is present
python3 validate_fix.py
# Validate logic against configuration
python3 -m tools.validate_logic \
--config outputs/configuration.json \
--logic-dir outputs/scenario_run/logic \
--check-callbacks \
--check-hil-init
# Run scenario in ICS-SimLab (use ABSOLUTE paths with sudo)
cd /home/stefano/projects/ICS-SimLab-main/curtin-ics-simlab
sudo ./start.sh /home/stefano/projects/ics-simlab-config-gen_claude/outputs/scenario_run
Architecture
The pipeline follows a deterministic approach:
text input -> LLM -> configuration.json -> IR (ir_v1.json) -> logic/*.py
Key Components
Entry Points:
main.py- LLM-based generation: text -> configuration.jsonbuild_scenario.py- Orchestrates full build: config -> IR -> logic (calls tools/*.py)
IR Pipeline (tools/):
make_ir_from_config.py- Extracts IR from configuration.json using keyword-based heuristicscompile_ir.py- Deterministic compiler: IR -> Python logic files (includes_safe_callbackfix)validate_logic.py- Validates generated logic against config
Models (models/):
ics_simlab_config.py- Pydantic models for configuration.json (PLC, HIL, registers)ir_v1.py- Intermediate Representation:IRSpeccontainsIRPLC(rules) andIRHIL(blocks)
LLM Pipeline (services/):
pipeline.py- Generate -> validate -> repair loopgeneration.py- OpenAI API callspatches.py- Auto-fix common config issuesvalidation/- Validators for config, PLC callbacks, HIL initialization
ICS-SimLab Contract
PLC Logic
File referenced by plcs[].logic becomes src/logic.py in container.
Required signature:
def logic(input_registers, output_registers, state_update_callbacks):
Rules:
- Read only registers with
io: "input"(frominput_registers) - Write only registers with
io: "output"(tooutput_registers) - After EVERY write to an output register, call
state_update_callbacks[id]() - Access by logical
id/name, never by Modbus address
HIL Logic
File referenced by hils[].logic becomes src/logic.py in container.
Required signature:
def logic(physical_values):
Rules:
- Initialize ALL keys declared in
hils[].physical_values - Update only keys marked as
io: "output"
Known Runtime Pitfall
PLC startup race condition: PLC2 can crash when writing to PLC1 before it's ready (ConnectionRefusedError).
Solution implemented in tools/compile_ir.py: The _safe_callback() wrapper retries failed callbacks with exponential backoff (30 attempts x 0.2s).
Always validate after rebuilding:
python3 validate_fix.py
IR System
The IR (Intermediate Representation) enables deterministic code generation.
PLC Rules (models/ir_v1.py):
HysteresisFillRule- Tank level control with low/high thresholdsThresholdOutputRule- Simple threshold-based output
HIL Blocks (models/ir_v1.py):
TankLevelBlock- Water tank dynamics (level, inlet, outlet)BottleLineBlock- Conveyor + bottle fill simulation
To add new process physics: create a structured spec (not free-form Python via LLM), then add a deterministic compiler.
Project Notes (appunti.txt)
Maintain appunti.txt in the repo root with bullet points (in Italian) documenting:
- Important discoveries about the repo or runtime
- Code changes, validations, generation behavior modifications
- Root causes of bugs
- Verification commands used
Include appunti.txt in diffs when updated.
Validation Rules
Validators catch:
- PLC callback invoked after each output write
- HIL initializes all declared physical_values keys
- HIL updates only
io: "output"keys - No reads from output-only registers, no writes to input-only registers
- No missing IDs referenced by generated code
Prefer adding a validator over adding generation complexity when a runtime crash is possible.
Research-Plan-Implement Framework
This repository uses the Research-Plan-Implement framework with the following workflow commands:
/1_research_codebase- Deep codebase exploration with parallel AI agents/2_create_plan- Create detailed, phased implementation plans/3_validate_plan- Verify implementation matches plan/4_implement_plan- Execute plan systematically/5_save_progress- Save work session state/6_resume_work- Resume from saved session/7_research_cloud- Analyze cloud infrastructure (READ-ONLY)
Research findings are saved in thoughts/shared/research/
Implementation plans are saved in thoughts/shared/plans/
Session summaries are saved in thoughts/shared/sessions/
Cloud analyses are saved in thoughts/shared/cloud/