agentleFS
ScottDuncanAIScottDuncanAI/HistorianSim/.claude/skills/simulate/SKILL.md

simulate

Skill19 starsChanged 15 days agoMITView on GitHub

Build a realistic chemical-plant historian dataset for a process the user describes, or recommend a process to simulate. The dataset is months of time series with control loops, instrument noise, historian compression and fault episodes, plus a fault answer key. Use when the user types /simulate, describes a process to simulate, asks for a synthetic process / manufacturing / plant / historian / time-series dataset, asks for a fault detection or root cause analysis dataset, or asks what process they could simulate.

  • Installs packages

7 other projects use a version of this.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

26 rules. 0 are common, 15 are distinctive, and 11 are very specific to this project.

  • 0

    Common

    Most of the 7 edited versions we read keep these.

  • 15

    Distinctive

    This author's own choices. Worth a look.

  • 11

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Keep every message to them in plain engineering language:

    line 9
  2. Distinctive:

    never paste code or stack traces at them.

    line 12
  3. Distinctive:

    never ask them to run commands themselves.

    line 13
  4. Distinctive:

    every root cause deducible from the data, the tag list and the process description.

    line 24
  5. Very specific:

    Never leave a challenge folder, a separate plots folder, logs or loose files in output/.

    line 45
  6. Distinctive:

    Read the two reference plants before writing anything:

    line 58
  7. Distinctive:

    Never write numbers into a dataset yourself.

    line 64
  8. Very specific:

    Check that the historiansim command runs.

    line 69
  9. Very specific:

    Use the venv's historiansim for every command below.

    line 76
  10. Distinctive:

    Ask only what changes the design, typically:

    line 92
  11. Distinctive:

    Don't ask about duration, scan rate or fault count.

    line 98
  12. Distinctive:

    If the description is a whole flowsheet, pick the unit with the richest diagnostic story, usually a reactor or a column, and say why.

    line 100
  13. Very specific:

    Run historiansim new-plant <snake_case_name> --equipment <TAG>.

    line 105
  14. Distinctive:

    Check the numbers with a short Python calculation, not by eye.

    line 112
  15. Distinctive:

    Every control valve should sit at 30–70 % at design.

    line 113
  16. Distinctive:

    Every transmitter range should put its normal reading at roughly 20–60 % of span.

    line 114
  17. Distinctive:

    Ask them to reply "approved" or say what to change.

    line 136
  18. Very specific:

    Every evidence tag must exist in tags().

    line 160
  19. Distinctive:

    Writing for the user: All text that reaches the user's files is read by process engineers:

    line 168
  20. Distinctive:

    no rhetorical "it's not X, it's Y" constructions.

    line 173
  21. Very specific:

    Follow pfd-generator/SKILL.md in this skill folder (it has its own scripts/, references/ and examples/).

    line 196
  22. Very specific:

    Tags must match the simulation exactly: Every balloon uses a tag from tags.py, and every control loop in the plant's loops.py, including …

    line 204
  23. Very specific:

    Check that PFD.svg and PFD.png are in the dataset folder.

    line 232
  24. Very specific:

    Always pass --out as shown: without it the plot lands in a separate <dataset>-plots/ folder.

    line 241
  25. Very specific:

    Follow references/validation_checklist.md.

    line 247
  26. Very specific:

    Write a short output/<dataset>-validation/VALIDATION.md:

    line 269

“Common” is measured: kept by at least 6 in 10 of the 7 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

/simulate: build a process dataset

The user is usually a process or chemical engineer, not a software developer. Keep every message to them in plain engineering language:

  • explain what you are doing and what you need from them;
  • never paste code or stack traces at them;
  • never ask them to run commands themselves. You run everything.

You are turning their process description into a validated dataset with this shape (the rca-benchmark recipe):

  • 90 days of historian data at a 10 s scan, plus the same data on a 60 s grid;
  • 14 days of clean normal operation first;
  • 9 fault events, all different. No root cause, mechanism or failed component repeats, and each event has at least 2 days of normal operation either side;
  • 2 deliberate operator moves (a setpoint change, a rate change) that are not faults;
  • every root cause deducible from the data, the tag list and the process description.

The user gets exactly two folders in output/, and nothing else:

output/<dataset>/                 the dataset, e.g. meg-rca-standard-s7
  historian_10s.parquet    full record, 10 s scan, compressed like a real historian
  historian_60s.parquet    same data on a regular 1-minute grid
  tags.csv                 tag dictionary
  PROCESS_DESCRIPTION.md   the plant, for a process engineer
  FAULT_ANSWER_KEY.md      every event: start, end, root cause, evidence
  PFD.svg, PFD.png         conceptual process flow diagram (Step 4b)
  metadata/                per-minute labels, ground truth JSON, config and seed

output/<dataset>-validation/      how the dataset was checked (Step 6)
  VALIDATION.md            checks, difficulty table, blind score, fixes made
  plots/                   one trend plot per event (EP-001.png ...)
  blind-submission.csv     the blind agent's scored submission

Never leave a challenge folder, a separate plots folder, logs or loose files in output/. Anything temporary (the blind-test copy, generation logs) goes in your scratchpad or a temporary directory and is deleted when done.

Quality comes from three places, in order of importance:

  1. The fault catalog. Causes grouped by shared first symptom, each with evidence that confirms it and rules out its competitors.
  2. The physics. Faults masked by control loops the way they are on a real plant.
  3. The process description. It must give every relationship needed to reason from first principles, and never list failure modes.

Read the two reference plants before writing anything:

  • src/historiansim/plants/heated_stirred_tank/, the unit behind HistorianRCA;
  • src/historiansim/plants/exothermic_cstr/, built from a DESIGN.md exactly as this skill describes.

Never write numbers into a dataset yourself. You write the plant; the simulator writes the data.

Step 0: environment (silent unless something is missing)

Check that the historiansim command runs. If it doesn't, follow the first-run setup in CLAUDE.md:

  1. Check for Python 3.11+.
  2. Create .venv.
  3. pip install -e ".[dev]".

Use the venv's historiansim for every command below. If Python itself is missing, tell the user in one sentence to install Python 3.11 or newer from python.org, ticking "Add python.exe to PATH" on Windows. Then wait.

Step 1: understand the request (at most 2 questions)

  • They described a process. Restate it as one unit operation with its controls, in one or two sentences.
  • They asked for a recommendation, or typed /simulate with nothing else. Offer three or four options from references/recommended_processes.md, each with its one-line pitch. Say that the two shipped processes can be generated straight away. Let them pick.
  • They picked a shipped process (cstr-rca or tank-rca). Skip to Step 4b if the plant has no pfd/ folder, otherwise Step 5.

Ask only what changes the design, typically:

  • which unit, if they described a whole plant (simulate one unit, with its utilities and feeds as disturbances);
  • anything about the control scheme or faults they care about.

Don't ask about duration, scan rate or fault count. The recipe fixes them.

If the description is a whole flowsheet, pick the unit with the richest diagnostic story, usually a reactor or a column, and say why.

Step 2: write DESIGN.md and stop for approval

Run historiansim new-plant <snake_case_name> --equipment <TAG>. Then fill in src/historiansim/plants/<name>/DESIGN.md following the template's sections and the R-201 example. It must contain:

  1. Service. What the unit does, its chemistry and the product spec.
  2. Equipment and flow. An ASCII sketch with every tag.
  3. Design point. Flows, temperatures, duties and valve positions.
    • Check the numbers with a short Python calculation, not by eye.
    • Every control valve should sit at 30–70 % at design.
    • Every transmitter range should put its normal reading at roughly 20–60 % of span.
  4. States and physics. The ODEs and algebraic relations, with nonlinearity that is real: valve characteristics, Arrhenius kinetics, sqrt(h) outflow. Keep it to 2–6 states. Treat anything faster than the scan as quasi-steady.
  5. Control. Loops, pairings, cascades and ratio stations, with tuning intent. Deliberately leave one loop loose.
  6. Disturbances. Weather coupling, utility headers, feed variability.
  7. Fault catalog. 12–20 causes in 3–5 symptom classes. See references/fault_design.md. This is the most important section.
  8. The dataset scenario. The 9 pinned causes and severities, plus 2 benign events.

Show the user a short summary in plain language:

  • the process and its control scheme in two or three sentences;
  • a table of the 9 faults with severity;
  • for each fault, one line on what makes it hard to tell apart from its look-alikes;
  • the two operator moves.

Ask them to reply "approved" or say what to change. Wait for approval before writing code.

Step 3: implement the plant

Fill in the scaffolded files, copying patterns from the reference plants:

FileContainsReference
model.pyUnitModel subclass: default_params, derivatives, signals, steady_inputs, steady_stateexothermic_cstr/model.py
loops.pydesign point, LoopConfig list, ChannelConfig disturbancesexothermic_cstr/loops.py
tags.pyTagSpec list and recompute_dcs_calculationsexothermic_cstr/tags.py
faults.pySymptomClasses and RootCauses with Evidenceboth plants
description.pythe plant sections of the process descriptionboth plants
__init__.pyBenignEvents, scenarios, the PLANT objectexothermic_cstr/__init__.py

Rules that matter:

  • Fault handles are parameters: a surviving fraction faulted with scale, or a zero-based quantity faulted with offset.
    • A DisturbanceFault in scale mode multiplies by 1 + severity x magnitude, so a drop needs a negative magnitude.
    • Instrument faults target a historian tag name, for example FIC-201.PV.
  • Every evidence tag must exist in tags(). Every rules_in and rules_out ID must exist in the catalog.
  • A cascade slave or ratio station is mode="CAS", and its configured sp must equal the design equilibrium. Compute it from the model.
  • CALC tags are recomputed from measured tags in recompute_dcs_calculations, never from truth.
  • Give every RootCause a component. Give the 9 pinned causes a grade (Easy/Medium/Hard), a walkthrough and competitors.
  • Writing for the user. All text that reaches the user's files is read by process engineers:
    • mechanisms, walkthroughs, evidence notes, benign-event explanations, and the process description;
    • plain sentences, engineering terms, no em dashes or -- used as a dash;
    • no rhetorical "it's not X, it's Y" constructions.

Step 4: pass the gates, in order

historiansim check-plant <name> --stage 1   # equilibrium; loops hold still
historiansim check-plant <name> --stage 2   # setpoint steps settle
historiansim check-plant <name> --stage 3   # each cause alone moves its evidence as documented
historiansim check-plant <name> --stage 4   # candidates separable; references resolve
historiansim check-plant <name> --stage 5   # quick dataset passes every check

Fix each stage before moving on. When stage 3 reports that evidence did not move or moved the wrong way, decide which is wrong, the physics or the claim. Then fix that one and say which you changed. Never loosen a check to make it pass. Give the user a one-line progress update after each stage.

Step 4b: draw the PFD

The PFD belongs to the plant, like its process description. Draw it once the gates pass, before generating: the tags and loops are final by then. generate copies it into every dataset of that plant.

Follow pfd-generator/SKILL.md in this skill folder (it has its own scripts/, references/ and examples/). The skill's "Deliver" step and its questions are replaced by what follows here.

  • Source. Draw from DESIGN.md (or the plant's description.py for a shipped process) and the tag list in tags.py. Don't ask the user anything; the approved design answers every question the PFD skill would ask.
  • Tags must match the simulation exactly. Every balloon uses a tag from tags.py, and every control loop in the plant's loops.py, including cascades and ratio stations, appears with the same pairing. Leave the neighbouring-equipment tags off the drawing.
  • Plant only. The drawing shows equipment, streams, instruments and loops. Never label a failure, a fault or anything from the answer key.
  • Render and inspect it as the PFD skill requires. If no renderer installs, say so in the hand-over.
  • Files. Save everything in src/historiansim/plants/<name>/pfd/: the generator script build_pfd.py, PFD.svg and PFD.png. Use exactly those two file names; generate looks for them.

A shipped process that has no pfd/ folder yet gets this step too, before Step 5.

Step 5: generate

historiansim generate <scenario> --seed <n> --out output     # about 20-30 min for 90 days

It must end with every check passing, including:

  • recipe;
  • no_range_clamping;
  • dataset_layout;
  • no_answer_leak, which also scans the PFD text.

Check that PFD.svg and PFD.png are in the dataset folder.

Then look at it:

historiansim report output/<dataset>
historiansim plot output/<dataset> --episode EP-001 --out output/<dataset>-validation/plots/EP-001.png   # for each event

Always pass --out as shown: without it the plot lands in a separate <dataset>-plots/ folder.

Step 6: validate like a reviewer

Follow references/validation_checklist.md. At minimum:

  1. Physics review. Plot each event and check two things:
    • the evidence moves as the answer key says;
    • the tags that rule out other causes really stay flat.
  2. Blind diagnosis. Run historiansim make-challenge output/<dataset> --out <scratch>/<dataset>-challenge to make a copy without the answer key, where <scratch> is your scratchpad or another temporary directory outside output/ and outside the repo. Spawn a fresh subagent and give it only that challenge folder. Ask it to work CHALLENGE.md and write a submission CSV inside that folder.

    Score the submission with historiansim score output/<dataset> <submission.csv>, judging each root cause yourself against FAULT_ANSWER_KEY.md. For every miss, decide whose fault it is:

    • the data's: the evidence is absent, ambiguous or misdescribed. Fix and regenerate;
    • the agent's: the evidence is there. Fine; note it.

    Copy the scored submission (with its cause_correct column) to output/<dataset>-validation/blind-submission.csv, then delete the challenge folder.

  3. Write a short output/<dataset>-validation/VALIDATION.md:
    • the checks;
    • the blind score;
    • the fixes made.

Step 7: hand over

Tell the user, in plain language:

  • Where the dataset is, and what each file is, plus what is in the validation folder. Use the two-folder layout above.
  • How to open it. historian_60s.parquet opens in pandas, Power BI, Spotfire or Seeq. Offer to export a CSV copy if they want Excel.
  • The events table from FAULT_ANSWER_KEY.md.
  • The blind-test result.
  • Blind use. To hand the dataset to someone as a blind test, give them everything in the dataset folder except FAULT_ANSWER_KEY.md and metadata/. Offer to build a challenge copy (historiansim make-challenge, which adds a task sheet and submission template) only if they ask for one, and put it wherever they say, not in output/.
  • The PFD, with the engineering assumptions made while drawing it and any design concerns noticed, as the PFD skill describes.

References

  • references/fault_design.md: designing symptom classes and evidence. Read before Step 2.
  • references/unit_library.md: physics templates for common unit operations.
  • references/recommended_processes.md: processes to offer when asked to recommend.
  • references/validation_checklist.md: what to check before calling a dataset done.
  • pfd-generator/: a copy of the PFD generator skill, used in Step 4b.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.