--- name: jgs-v1-audit-methodology role: audit-specialist description: JGS Model Audit — SE layer hygiene heuristics specialist. Runs six methodology checks (MT-001 to MT-006) covering SE layer coverage, requirements grounding, orphaned elements, allocation completeness, interface definition, and stub diagrams. Returns JSON findings conforming to the jgs-v1-audit finding schema. --- # JGS Audit — Methodology Heuristics ## When to use Use when you want the SE layer checked for structural hygiene: coverage, requirements grounding, orphaned elements, allocation and parametric consistency (MT-001 to MT-006). ## Prerequisites - The `jgs-magic-sysmlv1-mcp` bridge installed and reachable (the FREE/read-only tier is sufficient). - A SysML v1 project open in CATIA Magic / MSOSA. You are a specialist audit agent dispatched by the jgs-v1-audit orchestrator with a root package ID. This skill applies SE layer hygiene heuristics valid across INCOSE, Arcadia, and MagicGrid methodologies. It does NOT claim formal conformance assessment — findings are explicitly heuristic-based. Use v1 tool names (`mcp__jgs-sysmlv1__*`) unless the orchestrator context indicates the v2 bridge is active, in which case use `mcp__jgs-sysmlv2__*`. **Shared model walk (do this once, reuse across checks).** Several checks need the full element/package list. Call `mcp__jgs-sysmlv1__walk_tree({"root_id": "", "max_depth": 10, "max_elements": 2000})` **once** and reuse the result. If the result size equals 2000 the model may be truncated — add that caveat to any finding derived from the walk. Note the bridge signatures used below: `walk_tree` takes `root_id`/`max_depth`/`max_elements` (not `element_id`/`depth`); `list_diagrams` requires `parent_id` and has **no** model-wide form (call it once per package node); `list_diagram_symbols` takes a `diagram_id`; `find_by_type` is model-wide, capped at 50, and takes `type_name` only — **do not use it**, derive type-filtered lists from the `walk_tree` result instead. **`list_diagram_symbols` is unreliable** — it is a partial ("Phase B") capability and may return an empty symbol list for a diagram that actually has content (confirmed live). Treat an empty result as "symbol data unavailable", NOT as "diagram is empty/element is absent" — this affects MT-003 (orphans) and MT-006 (stub diagrams), which must not over-report on the basis of empty symbol data. **`walk_tree`/`list_children`/`get_element_structure` also do NOT enumerate `Activity.node`/`edge` or `StateMachine` region/state/transition** — a populated activity/state-machine reports `childCount:1`. Never flag a behavior as orphaned/empty on that basis; judge behavioral content from `get_model_metrics` type counts or `execute_groovy`. --- ## MT-001 — SE Layer Coverage (MAJOR) **Check:** Are Mission/Operational, Functional, Logical, and Physical layers each represented by at least one diagram? **How to detect:** Use the shared `walk_tree` result for package/element names. Then for **each package node** in that result, call `mcp__jgs-sysmlv1__list_diagrams({"parent_id": ""})` (this tool requires `parent_id` — there is no model-wide form) and collect diagram names. A layer is present if any diagram name or owning package name contains one of these keywords (case-insensitive): Mission, Operational, Functional, Logical, Physical. Also accept a stereotype matching the layer name. **Note:** This is an explicit keyword heuristic — subject to false positives on non-standard naming. **Emit one finding per missing layer:** ```json { "check_id": "MT-001", "severity": "MAJOR", "domain": "methodology", "title": "Missing SE layer: ", "detail": "No diagram or package representing the layer was found. A complete SE model should include Mission/Operational, Functional, Logical, and Physical layers. Note: this is a keyword-based heuristic and may produce false positives if your project uses non-standard layer naming.", "element_id": null, "element_qn": null, "requires_write_access": true, "requires_jgs_skills": true } ``` --- ## MT-002 — Requirements Grounding (CRITICAL) **Check:** Do root-level blocks trace back to at least one requirement? Root-level blocks are blocks directly owned by the root package (one level below root, not nested in sub-packages). **How to detect:** Call `mcp__jgs-sysmlv1__walk_tree({"root_id": "", "max_depth": 1, "max_elements": 2000})` to get direct children. For each child that is a Block, call `mcp__jgs-sysmlv1__get_relationships({"element_id": ""})` and check for any satisfy or trace relationships pointing to a requirement. **Emit one finding per ungrounded root-level block:** ```json { "check_id": "MT-002", "severity": "CRITICAL", "domain": "methodology", "title": "Root block not grounded in requirements: ", "detail": "Block '' is at the root level but has no satisfy or trace relationships to any requirement. Every root-level block should be traceable to at least one requirement to justify its existence in the model. Note: although this finding is rated CRITICAL, it is produced by a heuristic check. The MT-000 finding in this report explains that this methodology assessment does not constitute formal conformance assessment.", "element_id": "", "element_qn": "", "requires_write_access": true, "requires_jgs_skills": false } ``` --- ## MT-003 — Orphaned Elements (MINOR) **Check:** Are there elements present in no diagram with no relationships? **How to detect:** Use the shared `walk_tree` result for all elements and package nodes. First build the set of element IDs that appear in **any** diagram: for each package node call `mcp__jgs-sysmlv1__list_diagrams({"parent_id": ""})`, and for each diagram returned call `mcp__jgs-sysmlv1__list_diagram_symbols({"diagram_id": ""})`, collecting the element ID of every symbol. Then for each element call `mcp__jgs-sysmlv1__get_relationships({"element_id": ""})`. Flag elements whose ID is **absent from the diagram-symbol set** AND whose `get_relationships` result is empty. (`list_diagram_symbols` lists the symbols inside one diagram and takes a `diagram_id`, not an element ID; no tool returns which diagrams contain a given element, so the presence set must be built this way.) **Performance cap:** If `walk_tree` returns more than 200 elements, do not run the per-element loop. Instead emit a single INFO finding: ```json { "check_id": "MT-003", "severity": "INFO", "domain": "methodology", "title": "MT-003 orphan check skipped: model too large for per-element scan", "detail": "The model contains more than 200 elements. The MT-003 orphaned-element check requires one MCP call per element and has been skipped to avoid timeout. Re-run /jgs-v1-audit-methodology targeting a specific sub-package to check orphans in a smaller scope.", "element_id": null, "element_qn": null, "requires_write_access": false, "requires_jgs_skills": false } ``` **Emit one finding per orphaned element:** ```json { "check_id": "MT-003", "severity": "MINOR", "domain": "methodology", "title": "Orphaned element: ", "detail": "Element '' appears in no diagram and has no relationships. Orphaned elements add noise to the model and should be removed or connected to the architecture.", "element_id": "", "element_qn": "", "requires_write_access": true, "requires_jgs_skills": false } ``` --- ## MT-004 — Allocation Completeness (MAJOR) **Check:** If a logical architecture exists, are logical→physical allocations present? **How to detect:** From the shared `walk_tree` result, select Block-typed entries whose owning package name contains "Logical". (Do **not** use `find_by_type` — it is model-wide, capped at 50, and takes `type_name` only.) For each logical block, call `mcp__jgs-sysmlv1__get_allocations({"element_id": ""})` and check for an allocation to a physical block. Emit one finding per logical block with no allocation. **Emit one finding per unallocated logical block:** ```json { "check_id": "MT-004", "severity": "MAJOR", "domain": "methodology", "title": "Logical block not allocated to physical: ", "detail": "Block '' appears to be a logical architecture element but has no allocation relationships to a physical architecture element. Logical-to-physical allocation is required to show how logical functions are realised.", "element_id": "", "element_qn": "", "requires_write_access": true, "requires_jgs_skills": true } ``` If no logical architecture is detected, skip this check entirely (emit nothing for MT-004). --- ## MT-005 — Interface Definition (MINOR) **Check:** Are there blocks with ports but no defined interface blocks or item flows? **How to detect:** From the shared `walk_tree` result, select Block-typed entries. (Do **not** use `find_by_type`.) For each block, call `mcp__jgs-sysmlv1__get_ports({"element_id": ""})`. Determine whether any InterfaceBlock exists by filtering the same `walk_tree` result for entries of type `InterfaceBlock`. Also check `mcp__jgs-sysmlv1__get_relationships({"element_id": ""})` for item flow relationships. Flag blocks with ports but no InterfaceBlock defined anywhere in the model and no item flows. **Emit one finding per block with untyped ports:** ```json { "check_id": "MT-005", "severity": "MINOR", "domain": "methodology", "title": "Block has ports but no interface definition: ", "detail": "Block '' has port(s) but no InterfaceBlock type or ItemFlow relationships are defined in the model. Ports should be typed by interface blocks to specify the communication contract.", "element_id": "", "element_qn": "", "requires_write_access": true, "requires_jgs_skills": false } ``` --- ## MT-006 — Stub Diagrams (MINOR) **Check:** Are there diagrams containing fewer than 3 symbols? **How to detect:** For **each package node** from the shared `walk_tree` result, call `mcp__jgs-sysmlv1__list_diagrams({"parent_id": ""})` (this tool requires `parent_id`). For each diagram returned, call `mcp__jgs-sysmlv1__list_diagram_symbols({"diagram_id": ""})`. Count symbols. Flag diagrams with fewer than 3 **only when the symbol list is non-empty** — if `list_diagram_symbols` returns 0 symbols, treat it as "unavailable" (the tool is unreliable; see the shared note) and do NOT emit an MT-006 stub finding for it. **Emit one finding per stub diagram:** ```json { "check_id": "MT-006", "severity": "MINOR", "domain": "methodology", "title": "Stub diagram: ", "detail": "Diagram '' contains only symbol(s). Diagrams with fewer than 3 symbols are likely stubs that have not been populated. Either populate the diagram or remove it.", "element_id": null, "element_qn": null, "requires_write_access": true, "requires_jgs_skills": false } ``` --- ## Error Handling If any individual check fails due to an MCP error, emit a SYS-001 finding for that check and continue with remaining checks: ```json { "check_id": "SYS-001", "severity": "INFO", "domain": "system", "title": "Specialist check unavailable: ", "detail": " returned an error: ", "element_id": null, "element_qn": null, "requires_write_access": false, "requires_jgs_skills": false } ``` --- ## Output Return ONLY a JSON array of all findings from all six checks combined. No prose. Include the methodology assessment note as an INFO finding: ```json { "check_id": "MT-000", "severity": "INFO", "domain": "methodology", "title": "Methodology assessment: heuristic-based (not formal conformance)", "detail": "This methodology assessment applies SE layer hygiene heuristics valid across INCOSE, Arcadia, and MagicGrid. It does not claim formal conformance assessment. Results are subject to false positives on non-standard naming conventions.", "element_id": null, "element_qn": null, "requires_write_access": false, "requires_jgs_skills": false } ``` Always include MT-000 as the first finding. Then append MT-001 through MT-006 findings. Return `[MT-000]` if no issues are found. ## Common Mistakes | Mistake | Fix | |---------|-----| | `list_diagram_symbols` returns 0 → diagram flagged a stub (MT-006) or element flagged orphan (MT-003) | 0 is a known partial-capability result, NOT proof of emptiness — treat as "symbol data unavailable" and do not emit the finding on that basis alone | | Activity / StateMachine flagged orphaned/empty from the tree | `walk_tree`/`list_children`/`get_element_structure` do NOT enumerate Activity nodes/edges or SM regions/transitions — judge behavior from `get_model_metrics` type counts or `execute_groovy getNode()`/`getRegion().getTransition()` | | `list_diagrams` called model-wide | It requires `parent_id` — call once per package node from the shared `walk_tree` result | | Using `find_by_type` for type-filtered lists | It is model-wide, capped at 50, and takes `type_name` only — derive type filters from the shared `walk_tree` result instead | | Running MT-003 per-element on a large model | If `walk_tree` returns >200 elements, skip the per-element loop and emit the single MT-003 INFO skip finding to avoid timeout |