ea-model-hygiene
Logic: AI + AI Power Tools checks. The AI judges; the server's read operations are deterministic or rule-based.
What it is for
Use it to restore trust in a model that has decayed over months, and to check before you delete anything. You end with the decay found and fixed, and nothing deleted that something still depends on.
ea-model-hygiene finds and safely fixes the decay a model accumulates over months: elements nobody connected, composite-diagram links where the diagram and the drill-down flag disagree, stereotypes used once and never again, tagged values set on some elements of a type and skipped on others, and connector stereotypes the technology does not declare or that are spelled differently from the ones a rule matches. None of it breaks EA. All of it erodes trust in the model, and eventually someone cleans up the wrong thing.
The skill has two halves. The first teaches what each audit actually measures, because the most common failure is treating an orphan scan as a delete list. The second, and the more important, is the pre-delete safety sequence: a four-step check the AI runs before any delete, in order, stopping at the first step that turns something up.
It is also the only skill that uses trace_connectors, find_paths and get_traceability_tree, the three graph operations on ea_analyze. It uses them as a pre-delete safety net, to see what depends on an element before removing it.
Capabilities it uses
| Capability | Used for | Without it |
|---|---|---|
| MCP server | All the audits and checks: the orphan scan, the composite audit, the consistency summaries, the graph traversals, deletes and moves, and the counts | Not available |
| Computer use | Reading and dismissing a blocking dialog when a scan or delete stalls. Looking at a diagram after a change | The AI says so and asks you to look. For a blocking dialog, you paste a screenshot of it into the conversation so the AI can read it, then dismiss it. It does not report a hang it has not diagnosed |
| Local code execution | Not used | Not needed |
| Browser control | Not used | Not needed |
When to use it, and when not
Use it for a cleanup pass on a model that has been growing for a while, before deleting or moving anything that might still be load-bearing, when someone asks to "clean up the X package", and when auditing a repository for drift from its modeling language.
| The task | Use instead |
|---|---|
| Build or extend the model | ea-modeling |
| Build or audit navigation diagrams as the main task | ea-navigation-diagrams. This skill only runs the audit |
| Snapshot before the delete, or roll back after | ea-change-management |
| Enforce a rule standingly ("every Business Application carries all six base tags") | ea-validation. Express it as a ruleset and do not re-run these audits by hand |
| Find ungoverned elements against a modeling language | ea-mdg-assess and the reporting skills. See Find ungoverned elements |
How it works
-
Understand what "orphan" means before acting on a list. (rule-based)
find_orphan_elementsreturns elements with no connector at either end. That is the entire definition. It does not mean unused, unreferenced or safe to delete. The AI reads the result as a set of questions and not a delete list. -
Separate real candidates from false positives. AI On the Westbrook demonstration model, a scan scoped to the whole tree flagged a large majority of the elements checked, and almost none were decay:
- Capability-hierarchy containers. Their only relationship is parent and child containment, which EA does not model as a connector. The scan cannot see containment, so every container in a capability tree comes back flagged. Deleting them deletes the tree.
- Package proxy objects. Every package has a mirror element row. A freshly created sub-package appears as an "orphan element". It is the package's own object, not a modeling element.
- Elements disconnected by connector but referenced elsewhere, by diagram placement or as the parent of a composite drill-down diagram. A connector is one kind of reference, not the only one. The Westbrook data assets all came back as orphans because that model draws lineage as diagram placement, which is a modeling choice and not a defect.
The only real candidates carry a real stereotype (so they are not a structural container or a package proxy), have zero connectors, and appear on no diagram. All three conditions, not one.
-
Run the pre-delete safety sequence before any delete. (AI + AI Power Tools) See below.
-
Audit consistency across a stereotype. (rule-based) Three summaries answer questions one element at a time cannot. See "Spotting inconsistency".
-
Move elements safely. AI Power Tools See "Moving elements".
-
Recover from known failure modes. AI Retry once on a transient timeout, scope scans narrowly, and read an error as information and not as a fault in the tool.
-
Choose the right traversal operation. (AI chooses, AI Power Tools computes) Five operations read the connector graph and each answers a different question. See "Choosing a traversal operation".
-
Decide what to delete. You The AI proposes specific items. You decide, per item.
-
Look at EA if a call stalls. AI with computer use; otherwise you A scan or delete that does not return usually means EA is showing a blocking dialog. The AI reads it from EA's window, uses its message to correct the call and dismisses it. Without computer use, you take a screenshot of the dialog and paste it into the conversation so the AI can analyze it, then you dismiss the dialog so processing can continue.
The pre-delete safety sequence. This is the default for deleting anything, whether the candidate came from an orphan scan, a stale-looking name, or a request to clean up a package. All four steps run before the delete, in order, and the AI stops at the first one that turns something up.
Step 1: what points at it. (AI Power Tools, deterministic) trace_connectors with the direction set to upstream returns everything that depends on the element. The direction defaults to downstream (what the element points at), so for a pre-delete check the AI asks for upstream or both explicitly. The worked example on Westbrook: is the Westbrook Account Master service safe to delete? The upstream trace returns three Business Applications holding a Uses connector into it. The answer is no, and the AI stops there. The result lists the nodes and the edges between them, with the depth reached, whether the result was cut short, and how long it took.
Step 2: what it points at, and how far the blast radius goes. (AI Power Tools, deterministic) traverse_element_subgraph walks both directions by default and resolves MDG stereotype aliases into display terms, which makes it the better call when the AI wants the whole neighborhood in the language's own vocabulary, for example before deleting a package, to see what its elements connect to outside it. It walks the model element by element and caps depth at 5, so on a large model trace_connectors is the faster choice. It can list the same edge more than once when a node is reached by more than one path, so read its node and edge lists as sets and not counts.
Step 3: is it drawn anywhere, or does it anchor a navigation diagram. (AI Power Tools, deterministic) Two checks answer it: a query for placements of the element on any diagram, and the composite audit, run over the element's parent package. Any placement means the element is on a diagram even though it has no connectors there. The audit shows whether the element is a composite parent, and deleting a composite parent orphans its child diagram without deleting it. See ea-navigation-diagrams.
Step 4: delete, then verify by re-querying. (AI Power Tools for the call, AI for the judgment, you for the decision) delete_element deletes one element with its connectors, attributes, operations and diagram placements. delete_package deletes a package and everything inside it, recursively. Both are permanent, with no undo. delete_package is silent and total: elements, diagrams and nested packages all go, with no per-item confirmation. The AI never uses it as a shortcut for "this package is probably empty". It runs list_package_tree with element counts, or list_elements_in_package, first, and offers a baseline per ea-change-management, which treats every package deletion as always worth protecting. To confirm a delete landed, it re-queries and does not re-fetch the identifier: a scoped find_orphan_elements on the parent package, or a count of that identifier returning zero.
The skill's reference file walks the whole sequence in a scratch package, so the destructive calls (delete_element, move_element, delete_package) are never exercised against a shared model.
Spotting inconsistency. Three operations audit consistency across a stereotype.
summarize_stereotype_usage(whole repository). Returns every stereotype in use with its element count and EA object type. The AI reads the low end and not the high end. A stereotype used once or twice in a 200-element model is either a deliberate one-off or a typo or near-duplicate of a real one. The skill's example is aVendorApplicationelement next to 35WBAVendorSystemelements: close enough to look intentional until checked. The AI flags such a name and does not rewrite it silently. A server-managed stereotype such asExternalReference, applied bycreate_external_reference_element, at a count of 1 is expected, not decay. The count covers elements carrying some stereotype only. The operation also resolves each stereotype to say whether it is bound to a profile or ad hoc, lists names that appear both ways or are bound to more than one profile, and counts elements carrying more than one stereotype. EA's plain stereotype field holds only an element's first stereotype and does not say which profile it comes from, so the resolved view is the better evidence of drift between ad hoc and profile-bound use.summarize_tagged_value_usage(optionally for one stereotype). Scoped to one stereotype it shows tag coverage within a type. A tag present on a small fraction of one stereotype's elements is either optional by design (and should be documented as such) or a field only some contributors knew to fill in. The skill's example is apciScopeJustificationtag filled on 2 of 52 Business Application elements. Read it against the technology. The Westbrook technology declares that tag onWBABusinessApplicationandWBAVendorSystem, so a low count is a declared tag that few contributors fill in: either it is optional by design and should be documented as such, or a field some contributors never learned about. A tag the technology does not declare is different. It is an ad hoc field, a candidate for promotion into the technology or a deliberately sparse tag. The count is the number of tag rows present, and EA creates the row when a stereotype is applied whether or not the value is filled in, so the count is presence and not coverage. The operation also reports a populated count (rows with a non-blank value), which is the coverage figure. A tag present on every element and filled in on none reports a count above 0 and a populated count of 0. Read the populated count.summarize_observed_metaclasses(requires a stereotype). Answers whether every element with a stereotype uses the metaclass the MDG Technology declares for it. A single object type, reported as not heterogeneous, is healthy. Heterogeneous means the same stereotype string sits on elements created as different EA base types, almost always because someone typed the stereotype onto the wrong element instead of using the toolbox. Those elements will not behave like the rest of their type in reports, searches orcreate_element_in_languagelookups. A stereotype with a total of 0 is not an error: the technology declares it and the model has never used it.
Connector stereotypes drift the same way. summarize_connector_patterns returns the source stereotype, connector stereotype and target stereotype of every connector pattern with counts, and shows a connector stereotype that is both profile-bound and ad hoc. Two kinds of drift show up. A stereotype in use that the technology does not declare is one: the Westbrook demonstration model carries extends, part-of, Requires and Equivalent on connectors, and the technology declares only Uses, Flows and realizes. A declared stereotype stored in a different case from the one a rule compares is the other: the technology declares realizes, and WBA-LFY-001 matches Realizes, so the rule under-reports. The AI flags both and does not rewrite them silently. Binding a connector to the technology does not change the stored spelling.
The full tables from a live run against the Westbrook demonstration model are in the skill's references/consistency-audits.md, as a template for reading your own results. The counts and the declared sets in those tables are illustrations; read your own against your own technology.
Moving elements. move_element changes the element's package and nothing else. The skill verified directly that connectors, diagram placement and the composite child-diagram link all survive a move. A moved element can end up drawn on a diagram that lives in a different package. That is expected, not corruption, and it is why "which package owns this diagram" and "which package owns this element" are different questions. What changes is the element's Browser location and any package-scoped recursive count. A whole subtree moves with duplicate_package followed by delete_package on the original, or a direct change to the package's parent in the database, with the caveats in ea-modeling.
Choosing a traversal operation. Five operations read the connector graph. Picking wrongly is not a style matter: trace_connectors cannot tell you how two elements connect however you set it up, and traverse_element_subgraph on a large model is slow for no benefit.
| The question | Operation | Tool |
|---|---|---|
| What is around this element? | trace_connectors |
ea_analyze |
| How do these two elements connect? | find_paths |
ea_analyze |
| What hangs off this element along one relationship? | get_traceability_tree |
ea_analyze |
| What is around this element, in ArchiMate or BPMN terms? | traverse_element_subgraph |
ea_model |
| List just this one element's connectors | get_connectors_for_element_filtered |
ea_model |
trace_connectorsis the default. It reads the connectors in one pass and walks the graph in memory, to a depth of 1 to 10 (default 4), returning a flat neighborhood of nodes and edges. It is the call for blast radius. It can be limited to a list of connector stereotypes or types.find_pathsis the only operation that takes two elements. It returns every shortest path (up to 20 by default), each an alternating list of element and connector hops, with a direction of outbound or inbound on each connector hop. It follows connectors both ways, because a real traceability route usually crosses at least one connector against its arrow. An unreachable, disconnected or absent target returns no paths, not an error. The AI does not read an empty result as a failed call.get_traceability_treereturns a rooted hierarchy, with each child annotated by the connector that reached it. Connector types are required, because an unfiltered tree is a neighborhood graph in a tree costume. Direction can be outbound or inbound (or the synonyms downstream, upstream, outgoing, incoming). Cycle handling is per branch: an element is refused only if it already appears on the path from the root, so a diamond shows the same element under both parents while a loop terminates. A node marked as a cycle is a cut branch and not a leaf. The AI does not report it as "nothing further downstream".get_connectors_for_element_filteredis a single-hop lookup of one element's own connectors, filtered by direction, connector type and stereotype.
All three graph operations share one engine and three guards: depth capped at 10, 2,000 nodes and 8 seconds. A response marked truncated hit a guard and is partial. The AI narrows the depth or the connector types and re-runs. It does not report a partial result as complete. See also Trace dependencies.
What you get
- A scoped orphan scan, interpreted: real candidates separated from containers, package proxies and elements drawn on diagrams.
- For any delete, the dependents, the neighborhood, the diagram and composite check, and a baseline offer before anything is removed, with a re-query afterward.
- Consistency findings (near-duplicate stereotypes, sparse tags, mixed metaclasses) reported and not silently rewritten.
- Paths, trees and neighborhoods as requested, with truncation and cut branches stated.
Tools it relies on
find_orphan_elements,traverse_element_subgraph,get_connectors_for_element_filtered,find_composite_diagram_mismatches(ea_model): the scans and the composite audit.delete_element,delete_package,move_element,duplicate_package,list_package_tree,list_elements_in_package(Packages, Elements): the actions and the counts taken before them.trace_connectors,find_paths,get_traceability_tree(Graph and traceability): the graph operations. Only this skill teaches them.summarize_stereotype_usage,summarize_tagged_value_usage,summarize_observed_metaclasses,summarize_connector_patterns(Summaries): consistency audits.execute_sql(Direct queries): the diagram placement check and the post-delete count.- Shared references: EA UI verification and latency (ea-ui-verification.md, latency.md).
Sample prompts
- "Which elements in the Westbrook Consumer Banking package have no connectors?" Runs
find_orphan_elementsscoped to the package and explains that the list is a set of questions, not deletions. - "Is it safe to delete the Westbrook Account Master service?" Runs the pre-delete sequence: upstream trace, neighborhood, diagram and composite checks. Reports the dependents and stops.
- "How does the Account Origination System connect to the Account Master?" Calls
find_pathsand presents every shortest route, noting the connector direction on each hop. - "Show me what hangs off the Payments capability through realization relationships, three levels down." Calls
get_traceability_treefor Realization connectors to depth 3, and reports any cycle nodes as cut branches. - "Do all our Business Application elements carry the same tags? Anything odd?" Runs the tag summary scoped to the stereotype (reading the populated count), the stereotype summary and the metaclass summary, then flags near-duplicate names and sparse tags without changing anything.
- "Clean up the Legacy Integrations package. It's mostly dead." Lists the tree with counts, runs the four-step check on candidate elements, offers a baseline before any delete, and asks which specific items to remove.
Recommended models
| Model | Fit | Why |
|---|---|---|
| Claude Fable 5.1 | Recommended | The task turns on judgment: separating a modeling choice from decay, and resisting the pull to treat a list as a delete list |
| Claude Opus 5.5 | Recommended | Same. Reliable at holding "stop at the first step that turns something up" across a long cleanup |
| Claude Sonnet 5.5 | Recommended | The calls are procedural and the reads are deterministic. A good default, with delete decisions kept explicit and per item |
| Claude Haiku 4.5 | Capable | Adequate for running the audits and reading a result. Do not leave it to decide what is safe to delete unattended |
Ratings are guidance based on the kind of reasoning the skill needs, not measured benchmarks.
Checking accuracy and completeness
- No delete without the four steps. For each element deleted in a session, the transcript shows an upstream trace (direction upstream or both), a diagram-placement check, and a composite check on its package before the delete. Red flag: a delete preceded only by an orphan scan.
- Re-query after delete. Correct: a count of each deleted identifier returns 0, and a scoped
find_orphan_elementsno longer lists it. Check that nothing else disappeared: compare element counts for the package (list_package_treewith element counts) before and after, and expect a drop equal to the number deleted. - Truncation handled. Correct: any
trace_connectors,find_pathsorget_traceability_treeresponse marked truncated was narrowed and re-run, not reported as complete, and any cycle node is described as a cut branch. - Orphan false positives excluded. Correct: the candidate list you were given excludes unstereotyped containers, package proxies, and elements that appear on a diagram. Compare against the set of placed elements and against containment.
- Consistency findings are reproducible. Re-run
summarize_stereotype_usageandsummarize_tagged_value_usageand confirm each reported near-duplicate stereotype and sparse tag appears with the same count. Cross-check one with a count of elements carrying that stereotype. - Path answers are complete for the question. For a
find_pathsanswer, confirm the number of paths, the path length and whether the result was truncated. Correct: an empty result is reported as "no path within the depth searched", not as an error. - No silent rewrite. Correct: stereotype and tag names flagged as inconsistent are unchanged after the session unless you asked for the change.
Limitations
find_orphan_elementsmeasures connectors only. It cannot see containment, diagram placement or composite links, and it flags package proxy objects. It is a rule-based starting list.delete_elementanddelete_packageare permanent. There is no undo. Baseline first (ea-change-management).traverse_element_subgraphis capped at depth 5, walks element by element, and can repeat edges. Usetrace_connectorson a large model.- Reads can time out when several sessions work the same repository. Transient timeouts and dropped connections have been reported on
find_orphan_elements,find_composite_diagram_mismatchesandsummarize_tagged_value_usage, each resolving on a second attempt. Retry once before concluding a call is broken. Scope scans to the smallest package that answers the question, because a whole-model scan was noticeably slower than a single top-level package. - Parent of a top-level package. A parent of 0 can be rejected where the "Model" root works. Take the parent from
list_root_packages. summarize_connector_patternsmakes casing drift such asrealizesagainstRealizesvisible. Prefer it over a hand-written query for the connector audit. It may fail on a repository held in EA's older Jet file format.- Subtree walks that scoped scans such as
find_orphan_elementsandfind_composite_diagram_mismatchesrely on cover the full depth of the package tree and report the depth reached. - Windows only, with EA running. The server attaches to a running EA. Starting EA and opening the model is a separate step (ea-start-here).
- Example figures are from the Westbrook demonstration model. A customer's model will have different counts. The percentages show the shape of the problem, not a benchmark.