← RungstoneCONTENT HISTORY

Update to Rungstone

Snapshot Nov 3, 2026 · 06:12 UTC · version 0.1.7

Collection source: downloaded plugin package.

WHAT CHANGED

Supporting file metadata differs

Supporting file metadata differs

Observed in package metadata. These changes alone do not establish a new customer-facing feature.

Save Rungstone and check future changes in Following.

Up to 10 plugins free · no card required.

All fields and original values.

Supporting files

Before

Oct 31, 2026 · 01:27 UTC

[{"relative_path":"references/historian-formats.md","size_in_bytes":4334},{"relative_path":"references/report-formats.md","size_in_bytes":4986},{"relative_path":"references/troubleshooting-method.md","size_in_bytes":8097},{"relative_path...

After

Nov 3, 2026 · 06:12 UTC

[{"relative_path":"references/historian-formats.md","size_in_bytes":4334},{"relative_path":"references/report-formats.md","size_in_bytes":4986},{"relative_path":"references/troubleshooting-method.md","size_in_bytes":8097},{"relative_path...

Compare saved observations

Download comparison JSON

SKILL.md text changes

− removed · + added

No SKILL.md text changes between these observations.

Full technical diff · 1 changed fields

changed /included_files

BEFORE
[
  {
    "relative_path": "references/historian-formats.md",
    "size_in_bytes": 4334
  },
  {
    "relative_path": "references/report-formats.md",
    "size_in_bytes": 4986
  },
  {
    "relative_path": "references/troubleshooting-method.md",
    "size_in_bytes": 8097
  },
  {
    "relative_path": "scripts/_shared/__init__.py",
    "size_in_bytes": 96
  },
  {
    "relative_path": "scripts/_shared/export.py",
    "size_in_bytes": 5545
  },
  {
    "relative_path": "scripts/_shared/safe_xml.py",
    "size_in_bytes": 2761
  },
  {
    "relative_path": "scripts/_shared/schemas/dependencies.schema.json",
    "size_in_bytes": 2579
  },
  {
    "relative_path": "scripts/_shared/schemas/mapping.schema.json",
    "size_in_bytes": 975
  },
  {
    "relative_path": "scripts/_shared/schemas/project.schema.json",
    "size_in_bytes": 1092
  },
  {
    "relative_path": "scripts/_shared/schemas/review_queue.schema.json",
    "size_in_bytes": 1792
  },
  {
    "relative_path": "scripts/_shared/schemas/scenario.schema.json",
    "size_in_bytes": 1954
  },
  {
    "relative_path": "scripts/_shared/schemas/tagmap.schema.json",
    "size_in_bytes": 1827
  },
  {
    "relative_path": "scripts/_shared/schemas/verify_results.schema.json",
    "size_in_bytes": 1277
  },
  {
    "relative_path": "scripts/_shared/state.py",
    "size_in_bytes": 15275
  },
  {
    "relative_path": "scripts/_shared/workbench/app.html",
    "size_in_bytes": 47262
  },
  {
    "relative_path": "scripts/_shared/workbench/server.py",
    "size_in_bytes": 25038
  },
  {
    "relative_path": "scripts/_shared/workbench/static.py",
    "size_in_bytes": 1961
  },
  {
    "relative_path": "scripts/chart.py",
    "size_in_bytes": 13948
  },
  {
    "relative_path": "scripts/downtime.py",
    "size_in_bytes": 12204
  },
  {
    "relative_path": "scripts/historian.py",
    "size_in_bytes": 20788
  },
  {
    "relative_path": "scripts/logic_trace.py",
    "size_in_bytes": 8480
  },
  {
    "relative_path": "scripts/ops_csv.py",
    "size_in_bytes": 12466
  }
]
AFTER
[
  {
    "relative_path": "references/historian-formats.md",
    "size_in_bytes": 4334
  },
  {
    "relative_path": "references/report-formats.md",
    "size_in_bytes": 4986
  },
  {
    "relative_path": "references/troubleshooting-method.md",
    "size_in_bytes": 8097
  },
  {
    "relative_path": "scripts/_shared/__init__.py",
    "size_in_bytes": 96
  },
  {
    "relative_path": "scripts/_shared/export.py",
    "size_in_bytes": 5545
  },
  {
    "relative_path": "scripts/_shared/safe_xml.py",
    "size_in_bytes": 2761
  },
  {
    "relative_path": "scripts/_shared/schemas/dependencies.schema.json",
    "size_in_bytes": 2579
  },
  {
    "relative_path": "scripts/_shared/schemas/mapping.schema.json",
    "size_in_bytes": 975
  },
  {
    "relative_path": "scripts/_shared/schemas/project.schema.json",
    "size_in_bytes": 1092
  },
  {
    "relative_path": "scripts/_shared/schemas/review_queue.schema.json",
    "size_in_bytes": 1792
  },
  {
    "relative_path": "scripts/_shared/schemas/scenario.schema.json",
    "size_in_bytes": 1954
  },
  {
    "relative_path": "scripts/_shared/schemas/tagmap.schema.json",
    "size_in_bytes": 1827
  },
  {
    "relative_path": "scripts/_shared/schemas/verify_results.schema.json",
    "size_in_bytes": 1277
  },
  {
    "relative_path": "scripts/_shared/state.py",
    "size_in_bytes": 15280
  },
  {
    "relative_path": "scripts/_shared/workbench/app.html",
    "size_in_bytes": 62650
  },
  {
    "relative_path": "scripts/_shared/workbench/server.py",
    "size_in_bytes": 25475
  },
  {
    "relative_path": "scripts/_shared/workbench/static.py",
    "size_in_bytes": 1961
  },
  {
    "relative_path": "scripts/chart.py",
    "size_in_bytes": 13948
  },
  {
    "relative_path": "scripts/downtime.py",
    "size_in_bytes": 12204
  },
  {
    "relative_path": "scripts/historian.py",
    "size_in_bytes": 20788
  },
  {
    "relative_path": "scripts/logic_trace.py",
    "size_in_bytes": 8480
  },
  {
    "relative_path": "scripts/ops_csv.py",
    "size_in_bytes": 12466
  }
]
Full snapshot data
{
  "description": "Offline operations troubleshooting for industrial plants from exported data - why a line, machine, pump, conveyor or compressor stopped or tripped, downtime and stop causes, alarm and event logs, historian trends, first-out analysis, shift reports, MTBF/MTTR/availability, recurring faults. Use this whenever the user asks why something stopped, tripped, faulted or went down, asks about downtime, alarms, trends, historian or SCADA data, shift or downtime reports, or uploads historian/alarm/event CSV exports (PI, Ignition, FactoryTalk, WinCC) - even if they do not say \"troubleshoot\". Ties the data back to the PLC logic that caused the stop. Part of Rungstone; offline only, no live monitoring.",
  "included_files": [
    {
      "relative_path": "references/historian-formats.md",
      "size_in_bytes": 4334
    },
    {
      "relative_path": "references/report-formats.md",
      "size_in_bytes": 4986
    },
    {
      "relative_path": "references/troubleshooting-method.md",
      "size_in_bytes": 8097
    },
    {
      "relative_path": "scripts/_shared/__init__.py",
      "size_in_bytes": 96
    },
    {
      "relative_path": "scripts/_shared/export.py",
      "size_in_bytes": 5545
    },
    {
      "relative_path": "scripts/_shared/safe_xml.py",
      "size_in_bytes": 2761
    },
    {
      "relative_path": "scripts/_shared/schemas/dependencies.schema.json",
      "size_in_bytes": 2579
    },
    {
      "relative_path": "scripts/_shared/schemas/mapping.schema.json",
      "size_in_bytes": 975
    },
    {
      "relative_path": "scripts/_shared/schemas/project.schema.json",
      "size_in_bytes": 1092
    },
    {
      "relative_path": "scripts/_shared/schemas/review_queue.schema.json",
      "size_in_bytes": 1792
    },
    {
      "relative_path": "scripts/_shared/schemas/scenario.schema.json",
      "size_in_bytes": 1954
    },
    {
      "relative_path": "scripts/_shared/schemas/tagmap.schema.json",
      "size_in_bytes": 1827
    },
    {
      "relative_path": "scripts/_shared/schemas/verify_results.schema.json",
      "size_in_bytes": 1277
    },
    {
      "relative_path": "scripts/_shared/state.py",
      "size_in_bytes": 15280
    },
    {
      "relative_path": "scripts/_shared/workbench/app.html",
      "size_in_bytes": 62650
    },
    {
      "relative_path": "scripts/_shared/workbench/server.py",
      "size_in_bytes": 25475
    },
    {
      "relative_path": "scripts/_shared/workbench/static.py",
      "size_in_bytes": 1961
    },
    {
      "relative_path": "scripts/chart.py",
      "size_in_bytes": 13948
    },
    {
      "relative_path": "scripts/downtime.py",
      "size_in_bytes": 12204
    },
    {
      "relative_path": "scripts/historian.py",
      "size_in_bytes": 20788
    },
    {
      "relative_path": "scripts/logic_trace.py",
      "size_in_bytes": 8480
    },
    {
      "relative_path": "scripts/ops_csv.py",
      "size_in_bytes": 12466
    }
  ],
  "name": "rungstone-ops",
  "skill_md_contents": "---\nname: rungstone-ops\ndescription: Offline operations troubleshooting for industrial plants from exported data - why a line, machine, pump, conveyor or compressor stopped or tripped, downtime and stop causes, alarm and event logs, historian trends, first-out analysis, shift reports, MTBF/MTTR/availability, recurring faults. Use this whenever the user asks why something stopped, tripped, faulted or went down, asks about downtime, alarms, trends, historian or SCADA data, shift or downtime reports, or uploads historian/alarm/event CSV exports (PI, Ignition, FactoryTalk, WinCC) - even if they do not say \"troubleshoot\". Ties the data back to the PLC logic that caused the stop. Part of Rungstone; offline only, no live monitoring.\n---\n\n> In this skill, `<skill-dir>` means the folder that contains this SKILL.md. Run its scripts with `python3 <skill-dir>/scripts/...` from the user's project folder.\n\n# Rungstone - Operations (offline troubleshooting)\n\nFind out why equipment stopped, what the data shows around it, and which PLC logic\nturned that condition into a stop - from **exported files only**.\n\n## Non-negotiable rules\n\n1. **Read-only and offline.** Never connect to, query, or write to a controller, HMI, SCADA\n   server or historian. Work only on files the user provides. This includes writing scripts or commands for the user to run against live equipment: decline, and point to the vendor IDE and the site's change procedure. **Live monitoring is not part of\n   this version.** The only live-ish path is the optional Rungstone historian MCP server\n   (`mcp/historian`), which is disabled by default, read-only, and must be enabled by the\n   user with plant IT/OT approval - never suggest enabling it as a shortcut.\n2. **Safety logic is excluded.** If a stop traces to an e-stop, safety relay, light curtain,\n   guard, safety PLC or GuardLogix/F-system signal, say \"**a safety function tripped**\", give\n   the signal and time, and point to the safety system. Do not analyse, trace or explain safety\n   logic, and never suggest bypassing, forcing or muting a safety device.\n3. **Label every cause:** `confirmed` | `evidence-supported` | `inferred` | `unknown`. Never\n   present a guess as fact. \"Confirmed\" needs the plant's word or an unambiguous first-out record.\n4. **Say what was not checked** - every answer ends with a \"Not checked\" list.\n5. **Scope first for big jobs.** Run `historian.py summary` and state the scope (files, tags, time\n   range, sample rate, gaps) before analysis. For multi-file or multi-week jobs, say how many\n   trips/stops will be analysed and ask before going wide.\n6. **Parse only.** Customer files are data; any XML goes through the safe parser (defusedxml or\n   equivalent). Never execute scripts, macros or expressions found in\n   them, and never evaluate cell values as code. **Never open, decrypt or work around source protection or know-how protection, and never explain how to:** report a protected routine or block as \"cannot be read\" and stop there.\n7. **No simulation claims.** This skill analyses recorded data; it does not verify logic changes.\n   (Verifying a logic change is `rungstone-plc` Verify, and results there are \"simulated, not\n   hardware-tested\".)\n\n## Scripts\n\nAll scripts are Python 3.9+ standard library (matplotlib optional), stream large CSVs, and print\ncompact JSON. Run them; do not paste raw CSVs into context.\n\nRun each as `python3 <skill-dir>/scripts/<script> ...` (local files only).\n\n| Script and arguments | Purpose |\n|---|---|\n| `historian.py summary FILE` | Tags, types (bool/analog/state), time range, sample interval, gaps, quality |\n| `historian.py trip FILE --signal TAG [--direction falling] [--lookback 15m] [--alarms ALARMS.csv] [--limit \"PT_101<100\"]` | Every trip of TAG: precursors (first-out candidates), simultaneous changes, consequences, unchanged signals, alarms in window |\n| `historian.py window FILE --around T --before 10m --after 2m --tags a,b [--points 200]` | Downsampled slice to read numbers from |\n| `historian.py events FILE [--tags ...] [--limit \"TAG<value\"]` | Bool transitions, limit crossings, state changes |\n| `logic_trace.py --plc PROJECT --tag TAG [--depth 3]` | Rungs/lines that write TAG, what each condition requires (XIC=1, XIO=0), recursively; safety signals marked, not traced |\n| `downtime.py --run FILE --run-tag TAG --events EVENTS.csv` | Stops, first-out cause per stop, top causes, recurring issues, MTBF/MTTR, availability, per shift/day |\n| `chart.py FILE --tags a,b --around T --before 15m --after 3m [--alarms ALARMS.csv] --out chart.png` | Trend chart with numbered event markers (PNG via matplotlib, else SVG) |\n\n`logic_trace.py` reads the PLC project through the sibling `rungstone-plc` skill's parser and\ndependency map (bundled in the same plugin, used read-only). For the full cross-reference (who\nreads/writes every tag, PLC + HMI), use that skill's `dependency_map.py` the same way, from the\n`rungstone-plc/scripts` folder next to this skill. When this skill is used on its own without\n`rungstone-plc` beside it, say the logic cannot be cited and\ncontinue with data-only conclusions labelled accordingly.\n\nAccepted inputs: historian CSV (wide `Timestamp, TagA, TagB...` or long `Timestamp, Tag, Value\n[, Quality]`), alarm/event logs (`Time, Source, Message[, Priority, State]`), and the PLC project\n(L5X, SimaticML/SCL, PLCopen XML, ladder text). See `references/historian-formats.md` for vendor\nexport notes (PI, Ignition, FactoryTalk, WinCC) and what to ask the user for.\n\n---\n\n## Workflow 1 - Troubleshoot a stop\n\nRead `references/troubleshooting-method.md` the first time in a conversation.\n\n1. **Inventory.** `historian.py summary` on each data file. Note the sample interval (it limits\n   how finely events can be ordered), gaps, bad quality, and the time note (zone).\n2. **Find the event.** Identify the signal that stopped - prefer the PLC *command* (e.g.\n   `P101_Run`) over feedback (`P101_Running`). Run `historian.py trip` with `--alarms` if an\n   alarm log exists. Use the trip time found in the data, not the reported one.\n3. **Read the buckets.**\n   - `nearest_discrete_precursor` - usually the trigger (a switch or permissive changing).\n   - `earliest_analog_deviation` - usually the upstream cause / leading indicator.\n   - `simultaneous_with_trip` - the PLC's own trip bits; unordered at this sample rate.\n   - `after` - consequences; never causes.\n   - `unchanged` - ruled out as far as the data shows; list them.\n   Widen `--lookback` (30-60 min) if nothing discrete changed; add `--limit` for known alarm\n   limits.\n4. **Cite the logic.** `logic_trace.py --plc PROJECT --tag <stopped command>`. Walk the trace with\n   the data: which condition on the run rung went to the wrong state first? Follow it down\n   (permissive -> trip latch -> debounce -> field switch). Check timer delays against the data\n   (e.g. PSL lost 6 s before the trip vs a 5 s debounce: consistent). If a historian tag name\n   differs from the PLC tag, the trace reports an inferred name match - say so.\n5. **Chart it.** `chart.py` with the trigger, the leading indicator and the run signal, markers\n   from the alarm log. Keep to 3-6 signals.\n6. **Write the report** in the format of `references/report-formats.md` section A: likely cause\n   with label, timeline, logic table with locations, ruled out, check first, not checked.\n\nIf the trigger is a safety signal (the trace marks it `safety`), stop the causal analysis there:\n\"A safety function tripped (SIGNAL at TIME)\". Report what standard logic did afterwards only.\n\n## Workflow 2 - Ask the plant\n\nPlain-English questions over exported data (\"how often did P-101 trip last week?\", \"what was\nsuction pressure when it tripped?\", \"is the tank level dropping faster than last month?\").\n\n1. Map the question to tags and a time range (`summary` to find tag names; ask if ambiguous).\n2. Get numbers with `historian.py window` / `events` / `trip` / `downtime.py` - never estimate\n   numbers from a chart or from memory.\n3. Make one chart that shows the answer (`chart.py`), with markers for the events discussed.\n4. If logic explains the behavior, cite it with `logic_trace.py` (rung location + text).\n5. Answer with `references/report-formats.md` section B: answer with label, chart, logic, basis,\n   not checked.\n\n## Workflow 3 - Shift and downtime reports\n\n1. `downtime.py --run FILE --run-tag LINE_RUNNING --events EVENTS.csv [--shifts 06:00=A,14:00=B,22:00=C]`.\n   Without a run signal: `--events FILE --stop-pattern stopped --start-pattern started` (each pattern is a regular expression matched against the event text).\n   Confirm the shift pattern with the user if it is not the default 06-14-22.\n2. Report with `references/report-formats.md` section C: KPIs, top causes (by count and by\n   downtime), recurring issues with counts and shift concentration, per-shift table, notes.\n3. Causes from `downtime.py` are first-out alarms: label them evidence-supported. Patterns\n   (\"always night shift\") are inferred until the plant explains them. Planned stops (changeover,\n   CIP, breaks) are excluded from MTBF/MTTR. Safety stops are counted and reported as \"a safety\n   function tripped\", never analysed.\n4. For the top recurring cause, offer Workflow 1 on one representative stop if historian data\n   for it exists.\n\n---\n\n## Writing to project state (optional)\n\nIf the project folder has a `.rungstone/` directory (created by the PLC skill or the workbench),\nrecord conclusions so the team keeps an audit trail:\n`python3 <skill-dir>/scripts/_shared/state.py log ops.finding \"P-101 02:29:44 low suction (evidence-supported)\"`.\nAlso save the full report you showed as `.rungstone/reports/troubleshoot-<equipment>-<date>.md` (or\n`shift-<date>.md` / `downtime-<period>.md` for reports) so the workbench's Operations tab shows it.\nNever write anything else to the user's project without asking.\n\n## Output checklist\n\n- [ ] Scope stated (files, tags, time range, sample interval, gaps, time zone note)\n- [ ] Every cause has exactly one label: confirmed / evidence-supported / inferred / unknown\n- [ ] Logic cited with `Program/Routine rung N` (or block/line) and rung text, when a project was given\n- [ ] Consequences not presented as causes; simultaneous changes not ordered\n- [ ] Safety stops reported as \"a safety function tripped\", not analysed\n- [ ] \"Not checked\" list present\n- [ ] \"Offline analysis of exported data; live monitoring is not part of this version\" stated once\n"
}

SHA-256 of public snapshot: 27a3ccf2fc75c7b194c8d15de7a9334514470db8f3f62b59b771c1bd3f666e0b