{
  "schema_version": "workflow-catalog/v2",
  "workflows": [
    {
      "id": "compile-user-map",
      "name": "Compile an OEM map into user outputs",
      "goal": "Produce an organized user map and requested offline outputs in one resumable outcome run.",
      "steps": [
        {
          "id": "compile",
          "kind": "skill",
          "skill": "compile-user-map",
          "inputs": [
            "modbus-compile-request/v1"
          ],
          "output": "modbus-compile-result/v1"
        }
      ],
      "stop_conditions": [
        "one grouped source decision is required",
        "a requested target needs device binding",
        "a separate physical read or byte-order decision is required",
        "write, broadcast, scan, credentials, or live polling requested"
      ]
    },
    {
      "id": "extract-pdf-register-map",
      "name": "Extract PDF register evidence",
      "goal": "Turn a PDF manual or bounded page range into traceable candidates and grouped extraction exceptions without performing source-map review.",
      "steps": [
        {
          "id": "extract",
          "kind": "skill",
          "skill": "extract-pdf-map",
          "inputs": [
            "pdf-source/v1"
          ],
          "output": "candidate-map/v1"
        },
        {
          "id": "review",
          "kind": "skill",
          "skill": "review-evidence",
          "inputs": [
            "candidate-map/v1"
          ],
          "output": "modbus-map-evidence-review/v1"
        },
        {
          "id": "confirm-source",
          "kind": "human-gate",
          "condition": "decision_groups is non-empty",
          "inputs": [
            "candidate-map/v1",
            "modbus-map-evidence-review/v1"
          ],
          "output": "modbus-review-decisions/v1",
          "instruction": "Resolve all independent extraction exception groups in one batch. Never ask page by page."
        }
      ],
      "stop_conditions": [
        "unreadable or rights-restricted PDF",
        "incomplete source coverage on selected points",
        "write, broadcast, scan, or OCR of an entire unbound manual requested"
      ]
    },
    {
      "id": "review-source-map",
      "name": "Review a raw source map end to end",
      "goal": "Produce a reviewed draft and compact exception queue when source-map review itself is the requested outcome.",
      "steps": [
        {
          "id": "review",
          "kind": "skill",
          "skill": "review-map",
          "inputs": [
            "source-bundle/v1"
          ],
          "output": "modbus-map-evidence-review/v1"
        },
        {
          "id": "confirm-map",
          "kind": "human-gate",
          "condition": "decision_groups is non-empty",
          "inputs": [
            "modbus-map/v1",
            "modbus-map-evidence-review/v1"
          ],
          "output": "modbus-review-decisions/v1",
          "instruction": "Skip when the review status is ready. Otherwise resolve every independent exception group in one batch."
        },
        {
          "id": "apply-decisions",
          "kind": "skill",
          "skill": "apply-review",
          "inputs": [
            "modbus-map/v1",
            "modbus-review-decisions/v1"
          ],
          "output": "modbus-map/v1"
        }
      ],
      "stop_conditions": [
        "user actually wants organized user-map outputs",
        "unresolved route or address convention",
        "unresolved register area",
        "unconfirmed multi-register byte order"
      ]
    },
    {
      "id": "confirm-byte-order",
      "name": "Confirm byte order from one sample",
      "goal": "Evaluate every supported layout from one immutable sample, record one human confirmation, and apply it.",
      "steps": [
        {
          "id": "evaluate",
          "kind": "skill",
          "skill": "check-byte-order",
          "inputs": [
            "capture/v1"
          ],
          "output": "modbus-byte-order-evidence/v1"
        },
        {
          "id": "confirm-layout",
          "kind": "human-gate",
          "inputs": [
            "modbus-map/v1",
            "modbus-byte-order-evidence/v1"
          ],
          "output": "modbus-review-decisions/v1",
          "instruction": "Present eliminated candidates, the complete remaining shortlist, and distinguishing evidence in one decision. Confirm one explicit layout and keep the raw sample and all candidates."
        },
        {
          "id": "apply-layout",
          "kind": "skill",
          "skill": "apply-review",
          "inputs": [
            "modbus-map/v1",
            "modbus-review-decisions/v1",
            "modbus-byte-order-evidence/v1"
          ],
          "output": "modbus-map/v1"
        }
      ],
      "stop_conditions": [
        "no raw words",
        "ambiguous sample identity",
        "coil or packed-bit numbering requested",
        "no human confirmation"
      ]
    },
    {
      "id": "determine-byte-order",
      "name": "Determine byte order from a one-read probe",
      "goal": "Build a bounded probe with capture-sample when raw words are missing. After live-read confirmation, an operator or enabled target tool runs the gated read. Byte-order confirmation follows.",
      "steps": [
        {
          "id": "capture",
          "kind": "skill",
          "skill": "capture-sample",
          "condition": "no raw words or capture/v1 yet",
          "inputs": [
            "probe-request/v1"
          ],
          "output": "modbus-tool-pack/v1"
        },
        {
          "id": "run-probe",
          "kind": "external-gate",
          "condition": "no raw words or capture/v1 yet",
          "inputs": [
            "modbus-tool-pack/v1"
          ],
          "output": "capture/v1",
          "instruction": "After operator confirmation, run one bounded read and save the returned raw 16-bit words with complete sample identity. Do not scan or write."
        },
        {
          "id": "confirm",
          "kind": "workflow",
          "workflow": "confirm-byte-order",
          "inputs": [
            "modbus-map/v1",
            "capture/v1"
          ],
          "output": "modbus-map/v1"
        }
      ],
      "stop_conditions": [
        "no probe identity when raw words are missing",
        "no raw words after the probe gate",
        "ambiguous sample identity",
        "no human confirmation"
      ]
    },
    {
      "id": "remap-address-notation",
      "name": "Remap address notation",
      "goal": "Preview and apply a known map-wide conversion between protocol offsets and Modicon-style references, then lint the converted map.",
      "steps": [
        {
          "id": "remap",
          "kind": "skill",
          "skill": "remap-addresses",
          "inputs": [
            "modbus-map/v1",
            "address-convention-request/v1"
          ],
          "output": "modbus-address-remap/v1"
        },
        {
          "id": "lint",
          "kind": "skill",
          "skill": "check-map",
          "inputs": [
            "modbus-address-remap/v1"
          ],
          "output": "modbus-map-lint/v1"
        }
      ],
      "stop_conditions": [
        "source or target convention unknown",
        "register area not proven by notation",
        "collision or lossy conversion",
        "write request detected"
      ]
    },
    {
      "id": "build-custom-export",
      "name": "Build a declarative custom export",
      "goal": "Reproduce a documented text or CSV export from a reviewed map without executing supplied code.",
      "steps": [
        {
          "id": "lint",
          "kind": "skill",
          "skill": "check-map",
          "inputs": [
            "modbus-map/v1"
          ],
          "output": "modbus-map-lint/v1"
        },
        {
          "id": "export",
          "kind": "skill",
          "skill": "build-custom-export",
          "inputs": [
            "modbus-map/v1",
            "export-example/v1"
          ],
          "output": "custom-export/v1"
        }
      ],
      "stop_conditions": [
        "example format ambiguous",
        "opaque or undocumented native binary requested",
        "map validation error",
        "write request detected"
      ]
    },
    {
      "id": "probe-resolve-finalize-tool-pack",
      "name": "Probe, resolve byte order, and finalize a tool pack",
      "goal": "Use a selected tool target to collect one raw sample, confirm byte order, then regenerate all selected targets with the confirmed layout.",
      "steps": [
        {
          "id": "plan-probe",
          "kind": "skill",
          "skill": "plan-reads",
          "inputs": [
            "modbus-map/v1"
          ],
          "output": "modbus-read-plan/v1"
        },
        {
          "id": "build-probe",
          "kind": "skill",
          "skill": "build-tool-pack",
          "inputs": [
            "modbus-map/v1",
            "modbus-read-plan/v1",
            "probe-tool-pack-request/v1"
          ],
          "output": "modbus-tool-pack/v1"
        },
        {
          "id": "run-probe",
          "kind": "external-gate",
          "inputs": [
            "modbus-tool-pack/v1"
          ],
          "output": "capture/v1",
          "instruction": "Run one bounded read against the reviewed endpoint and save the returned raw 16-bit words. Do not scan or write."
        },
        {
          "id": "confirm",
          "kind": "workflow",
          "workflow": "confirm-byte-order",
          "inputs": [
            "modbus-map/v1",
            "capture/v1"
          ],
          "output": "modbus-map/v1"
        },
        {
          "id": "plan-final",
          "kind": "skill",
          "skill": "plan-reads",
          "inputs": [
            "modbus-map/v1"
          ],
          "output": "modbus-read-plan/v1"
        },
        {
          "id": "build-final",
          "kind": "skill",
          "skill": "build-tool-pack",
          "inputs": [
            "modbus-map/v1",
            "modbus-read-plan/v1",
            "final-tool-pack-request/v1"
          ],
          "output": "modbus-tool-pack/v1"
        }
      ],
      "stop_conditions": [
        "no selected target",
        "unresolved route or unit identifier",
        "no raw words",
        "no human byte-order confirmation",
        "write request detected"
      ]
    },
    {
      "id": "build-tool-pack",
      "name": "Build a multi-target tool pack",
      "goal": "Generate any selected combination of Node-RED, Modpoll (BETA), and ModScan (BETA) from one validated map and one read plan.",
      "steps": [
        {
          "id": "lint",
          "kind": "skill",
          "skill": "check-map",
          "inputs": [
            "modbus-map/v1"
          ],
          "output": "modbus-map-lint/v1"
        },
        {
          "id": "plan",
          "kind": "skill",
          "skill": "plan-reads",
          "inputs": [
            "modbus-map/v1"
          ],
          "output": "modbus-read-plan/v1"
        },
        {
          "id": "build",
          "kind": "skill",
          "skill": "build-tool-pack",
          "inputs": [
            "modbus-map/v1",
            "modbus-read-plan/v1",
            "tool-pack-request/v1"
          ],
          "output": "modbus-tool-pack/v1"
        }
      ],
      "stop_conditions": [
        "no selected target",
        "map validation error",
        "required final decoding field unresolved",
        "write request detected"
      ]
    },
    {
      "id": "analyze-read-data",
      "name": "Analyze bounded read data",
      "goal": "Find communication and signal-quality problems without issuing control commands.",
      "steps": [
        {
          "id": "analyze",
          "kind": "skill",
          "skill": "analyze-capture",
          "inputs": [
            "capture/v1"
          ],
          "output": "modbus-capture-analysis/v1"
        },
        {
          "id": "review-findings",
          "kind": "human-gate",
          "condition": "a finding requires a consequential follow-up",
          "inputs": [
            "modbus-capture-analysis/v1"
          ],
          "output": "review-disposition/v1",
          "instruction": "Present all threshold, metadata, and alternative-cause exceptions together before a consequential follow-up. Skip this gate for a report-only request."
        }
      ],
      "stop_conditions": [
        "unbounded capture",
        "write request detected",
        "missing sample identity",
        "timezone missing from a timestamp"
      ]
    },
    {
      "id": "compare-map-revisions",
      "name": "Compare map revisions",
      "goal": "Report stable field changes without collapsing points from different routes, areas, or unit identifiers.",
      "steps": [
        {
          "id": "review-before",
          "kind": "workflow",
          "workflow": "review-source-map",
          "inputs": [
            "before-source-bundle/v1"
          ],
          "output": "before-modbus-map/v1"
        },
        {
          "id": "review-after",
          "kind": "workflow",
          "workflow": "review-source-map",
          "inputs": [
            "after-source-bundle/v1"
          ],
          "output": "after-modbus-map/v1"
        },
        {
          "id": "compare",
          "kind": "skill",
          "skill": "compare-maps",
          "inputs": [
            "before-modbus-map/v1",
            "after-modbus-map/v1"
          ],
          "output": "modbus-map-diff/v1"
        },
        {
          "id": "review-diff",
          "kind": "human-gate",
          "condition": "the user asks to accept or deploy the new revision",
          "inputs": [
            "modbus-map-diff/v1"
          ],
          "output": "review-disposition/v1",
          "instruction": "Group moved, added, removed, and changed points by cause and request one acceptance decision only when acceptance or deployment is in scope."
        }
      ],
      "stop_conditions": [
        "map schema mismatch",
        "unresolved composite identity",
        "unreviewed source-map holds"
      ]
    }
  ]
}
