name: nacl-ba-validate model: opus effort: high description: | Validate BA model consistency via Cypher: L1-L8 internal checks, XL1-XL5 cross-validation with SA layer. Read-only, no writes.Use when: validate BA model, check consistency, or the user says "/nacl-ba-validate".
/nacl-ba-validate -- BA Model Validation (Graph)
Purpose
Comprehensive consistency validation of the BA model stored in Neo4j. Runs Cypher queries to detect problems across 8 internal levels (L1-L8: process completeness, decomposition, performers, entity attributes, entity-process matrix, role-process matrix, glossary coverage, rules binding) and 5 cross-validation levels (XL1-XL5: automation coverage, entity mapping, rule traceability, role mapping, glossary alignment with SA layer).
All checks are read-only -- validation NEVER modifies data in the graph.
Note: ActivityStep / UC step-level structure is checked by /nacl-sa-validate (see L3.5, L3.6).
Shared references: nacl-core/SKILL.md
Neo4j Tools
| Tool | Usage |
|---|---|
mcp__neo4j__read-cypher |
ALL validation queries (read-only) |
mcp__neo4j__get-schema |
Introspect current graph schema before running checks |
IMPORTANT: This skill uses ONLY read-cypher. Validation must NEVER write to the graph.
Invocation
/nacl-ba-validate [scope]
Parameters
| Parameter | Values | Description |
|---|---|---|
scope |
internal |
L1-L8: BA-internal consistency checks |
cross |
XL1-XL5: BA-to-SA cross-layer validation | |
full (default) |
All levels: L1-L8 + XL1-XL5 |
Workflow Overview
LAUNCH VALIDATION
|
+----------+-----------+
| |
[scope = internal] [scope = cross]
[scope = full] [scope = full]
| |
+---------+---------+ +-------+-------+
| L1: BP | | XL1: Automa- |
| Completeness | | tion Coverage|
+---------+---------+ +-------+-------+
| |
+---------+---------+ +-------+-------+
| L2: Workflow | | XL2: Entity |
| Coverage | | Coverage |
+---------+---------+ +-------+-------+
| |
+---------+---------+ +-------+-------+
| L3: Step | | XL3: Rule |
| Performers | | Coverage |
+---------+---------+ +-------+-------+
| |
+---------+---------+ +-------+-------+
| L4: Entity | | XL4: Role |
| Attributes | | Coverage |
+---------+---------+ +-------+-------+
| |
+---------+---------+ +-------+-------+
| L5: Entity- | | XL5: Glossary|
| Process Matrix | | Alignment |
+---------+---------+ +-------+-------+
| |
+---------+---------+ |
| L6: Role-Process | |
| Matrix | |
+---------+---------+ |
| |
+---------+---------+ |
| L7: Glossary | |
| Coverage | |
+---------+---------+ |
| |
+---------+---------+ |
| L8: Rules | |
| Binding | |
+---------+---------+ |
| |
+----------+-----------+
|
+----------+-----------+
| FORMAT REPORT |
+----------------------+
Pre-flight Checks
Step 0: Verify BA layer has data
Before running any validation, confirm that the graph contains BA-layer nodes.
// Pre-flight: count BA-layer nodes
MATCH (n)
WHERE n:BusinessProcess OR n:WorkflowStep OR n:BusinessEntity
OR n:BusinessRole OR n:BusinessRule OR n:GlossaryTerm
RETURN labels(n)[0] AS label, count(n) AS count
ORDER BY label
If the result is empty or all counts are 0:
- STOP -- validation is impossible without BA data in the graph.
- Suggest the user runs
/nacl-ba-import-doc,/nacl-ba-from-board, or/nacl-ba-processfirst. - Explain that
/nacl-ba-validateworks only with a populated Neo4j graph.
Step 0b: Verify SA layer exists (for cross / full)
// Pre-flight: count SA-layer nodes
MATCH (n)
WHERE n:UseCase OR n:DomainEntity OR n:SystemRole OR n:Requirement
RETURN labels(n)[0] AS label, count(n) AS count
ORDER BY label
If the result is empty:
scope=cross--> STOP, report that SA layer is not populated. Suggest/nacl-sa-domainor/nacl-sa-architectfirst.scope=full--> Run only L1-L8 (internal), skip XL1-XL5 with a WARNING in the report.
Severity Levels
Every detected problem is assigned a severity:
| Severity | Meaning | Report threshold |
|---|---|---|
| CRITICAL | BA model is broken; blocks handoff to SA | Any CRITICAL --> overall FAIL |
| WARNING | Inconsistency that should be fixed but is not blocking | 5+ WARNINGs --> overall WARN |
| INFO | Observation, optional improvement | Does not affect overall status |
Computing the overall status is delegated — do not roll up the L1-L8 / XL1-XL5 results
by hand. Collect every finding as {check, severity} and pass them to the single-authority
classifier with layer: "ba" (the BA layer has no exemptions; the ba layer ensures the
SA exemption rules for L4.1/L5.1/L6.1 — which are different checks here — never fire).
Emit its overall token verbatim. Same authority as nacl-sa-validate, pinned by
nacl-core/scripts/classify-findings.test.mjs.
node nacl-core/scripts/classify-findings.mjs '{"layer":"ba","findings":[{"check":"L1.1","severity":"CRITICAL"},{"check":"L2.2","severity":"WARNING"}]}'
# stdout: full JSON (findings + counts + overall); stderr: the bare overall token
Validation Levels -- Internal (L1-L8)
Level 1: BP Completeness (L1)
Goal: Every BusinessProcess must have trigger, result, and an owner role.
Named query: val_ba_L1_bp_completeness (from validation-queries.cypher)
Check L1.1: Missing mandatory process properties
// L1.1 -- Severity: CRITICAL
// BusinessProcesses missing trigger, result, or owner
MATCH (bp:BusinessProcess)
WHERE bp.trigger IS NULL OR bp.result IS NULL
OR NOT EXISTS { MATCH (:BusinessRole)-[:OWNS]->(bp) }
RETURN bp.id AS id, bp.name AS name,
CASE WHEN bp.trigger IS NULL THEN 'missing trigger' ELSE '' END +
CASE WHEN bp.result IS NULL THEN ', missing result' ELSE '' END +
CASE WHEN NOT EXISTS { MATCH (:BusinessRole)-[:OWNS]->(bp) } THEN ', missing owner' ELSE '' END AS issues
Check L1.2: BusinessProcess nodes missing mandatory id/name
// L1.2 -- Severity: CRITICAL
// BP nodes without id or name properties
MATCH (bp:BusinessProcess)
WHERE bp.id IS NULL OR bp.name IS NULL
RETURN coalesce(bp.id, 'NO ID') AS id,
coalesce(bp.name, 'NO NAME') AS name,
'BusinessProcess missing mandatory property: id or name' AS problem
Level 2: Workflow Coverage (L2)
Goal: Every BP with has_decomposition=true must have at least one WorkflowStep.
Named query: val_ba_L2_workflow_coverage (from validation-queries.cypher)
Check L2.1: Decomposed BP without steps
// L2.1 -- Severity: CRITICAL
// BPs with has_decomposition=true but no HAS_STEP edges
MATCH (bp:BusinessProcess {has_decomposition: true})
WHERE NOT EXISTS { MATCH (bp)-[:HAS_STEP]->(:WorkflowStep) }
RETURN bp.id AS id, bp.name AS name, 'has_decomposition=true but no steps' AS issue
Check L2.2: Orphaned WorkflowSteps not linked to any BP
// L2.2 -- Severity: WARNING
// WorkflowSteps that have no incoming HAS_STEP from a BusinessProcess
MATCH (ws:WorkflowStep)
WHERE NOT (:BusinessProcess)-[:HAS_STEP]->(ws)
RETURN ws.id AS ws_id, ws.function_name AS step_name,
'WorkflowStep not linked to any BusinessProcess' AS issue
Check L2.3: Empty decomposition (BP with steps but steps have no function_name)
// L2.3 -- Severity: WARNING
// WorkflowSteps missing function_name (empty step content)
MATCH (bp:BusinessProcess)-[:HAS_STEP]->(ws:WorkflowStep)
WHERE ws.function_name IS NULL OR trim(ws.function_name) = ''
RETURN bp.id AS bp_id, ws.id AS ws_id,
'WorkflowStep has no function_name (empty step)' AS issue
Level 3: Step Performers (L3)
Goal: Every WorkflowStep must have a PERFORMED_BY relationship to a BusinessRole.
Named query: val_ba_L3_step_performers (from validation-queries.cypher)
Check L3.1: Steps without performer
// L3.1 -- Severity: CRITICAL
// WorkflowSteps missing PERFORMED_BY edge
MATCH (bp:BusinessProcess)-[:HAS_STEP]->(ws:WorkflowStep)
WHERE NOT EXISTS { MATCH (ws)-[:PERFORMED_BY]->(:BusinessRole) }
RETURN bp.id AS bp_id, ws.id AS ws_id, ws.function_name AS step_name,
'missing PERFORMED_BY' AS issue
Check L3.2: PERFORMED_BY points to a non-existent role
// L3.2 -- Severity: CRITICAL
// Steps referencing roles that don't exist in the BusinessRole set
MATCH (ws:WorkflowStep)-[:PERFORMED_BY]->(r)
WHERE NOT r:BusinessRole
RETURN ws.id AS ws_id, ws.function_name AS step_name,
coalesce(r.id, toString(id(r))) AS target_id,
'PERFORMED_BY points to a node that is not a BusinessRole' AS issue
Level 4: Entity Attributes (L4)
Goal: Every BusinessEntity must have at least one EntityAttribute.
Named query: val_ba_L4_entity_attributes (from validation-queries.cypher)
Check L4.1: Entities without attributes
// L4.1 -- Severity: CRITICAL
// BusinessEntities with zero EntityAttribute children
MATCH (e:BusinessEntity)
WHERE NOT EXISTS { MATCH (e)-[:HAS_ATTRIBUTE]->(:EntityAttribute) }
RETURN e.id AS id, e.name AS name, 'no attributes defined' AS issue
Check L4.2: Orphaned EntityAttributes not linked to any entity
// L4.2 -- Severity: WARNING
// EntityAttributes floating without a parent BusinessEntity
MATCH (ea:EntityAttribute)
WHERE NOT (:BusinessEntity)-[:HAS_ATTRIBUTE]->(ea)
RETURN ea.id AS attr_id, ea.name AS attr_name,
'EntityAttribute not owned by any BusinessEntity' AS issue
Check L4.3: BusinessEntity missing mandatory id/name
// L4.3 -- Severity: CRITICAL
// Entity nodes without id or name
MATCH (e:BusinessEntity)
WHERE e.id IS NULL OR e.name IS NULL
RETURN coalesce(e.id, 'NO ID') AS id,
coalesce(e.name, 'NO NAME') AS name,
'BusinessEntity missing mandatory property' AS issue
Level 5: Entity-Process Matrix (L5)
Goal: Every BusinessEntity should be referenced by at least one workflow step (READS/PRODUCES/MODIFIES).
Named query: val_ba_L5_entity_process_matrix (from validation-queries.cypher)
Check L5.1: Entities not referenced by any workflow step
// L5.1 -- Severity: WARNING
// BusinessEntities not connected to any WorkflowStep via READS/PRODUCES/MODIFIES
MATCH (e:BusinessEntity)
WHERE NOT EXISTS {
MATCH (:WorkflowStep)-[:READS|PRODUCES|MODIFIES]->(e)
}
RETURN e.id AS id, e.name AS name, 'not referenced by any workflow step' AS issue
Check L5.2: WorkflowSteps referencing entities not in the graph
// L5.2 -- Severity: INFO
// Steps with READS/PRODUCES/MODIFIES edges -- verify all targets are BusinessEntity
MATCH (ws:WorkflowStep)-[rel:READS|PRODUCES|MODIFIES]->(target)
WHERE NOT target:BusinessEntity
RETURN ws.id AS ws_id, ws.function_name AS step_name,
type(rel) AS rel_type, labels(target)[0] AS target_label,
'Step references a non-BusinessEntity node' AS issue
Level 6: Role-Process Matrix (L6)
Goal: Every BusinessRole should have at least one OWNS, PARTICIPATES_IN, or PERFORMED_BY relationship.
Named query: val_ba_L6_role_process_matrix (from validation-queries.cypher)
Check L6.1: Roles with no process relationships
// L6.1 -- Severity: WARNING
// BusinessRoles with no OWNS, PARTICIPATES_IN, or PERFORMED_BY
MATCH (r:BusinessRole)
WHERE NOT EXISTS { MATCH (r)-[:OWNS]->(:BusinessProcess) }
AND NOT EXISTS { MATCH (r)-[:PARTICIPATES_IN]->(:BusinessProcess) }
AND NOT EXISTS { MATCH (:WorkflowStep)-[:PERFORMED_BY]->(r) }
RETURN r.id AS id, r.full_name AS name, 'role has no process relationships' AS issue
Check L6.2: Process participation type consistency
// L6.2 -- Severity: INFO
// Roles that are only performers (PERFORMED_BY) but not OWNS or PARTICIPATES_IN
// This may be intentional but is worth flagging for review
MATCH (r:BusinessRole)
WHERE EXISTS { MATCH (:WorkflowStep)-[:PERFORMED_BY]->(r) }
AND NOT EXISTS { MATCH (r)-[:OWNS]->(:BusinessProcess) }
AND NOT EXISTS { MATCH (r)-[:PARTICIPATES_IN]->(:BusinessProcess) }
RETURN r.id AS id, r.full_name AS name,
'Role performs steps but has no OWNS/PARTICIPATES_IN on any process' AS observation
Level 7: Glossary Coverage (L7)
Goal: Key entities and roles should have corresponding GlossaryTerm nodes via DEFINES.
Named query: val_ba_L7_glossary_coverage (from validation-queries.cypher)
Check L7.1: Entities without glossary terms
// L7.1 -- Severity: WARNING
// BusinessEntities not covered by any GlossaryTerm
MATCH (e:BusinessEntity)
WHERE NOT EXISTS { MATCH (:GlossaryTerm)-[:DEFINES]->(e) }
RETURN 'Entity' AS category, e.id AS id, e.name AS name, 'no glossary term' AS issue
Check L7.2: Roles without glossary terms
// L7.2 -- Severity: WARNING
// BusinessRoles not covered by any GlossaryTerm
MATCH (r:BusinessRole)
WHERE NOT EXISTS { MATCH (:GlossaryTerm)-[:DEFINES]->(r) }
RETURN 'Role' AS category, r.id AS id, r.full_name AS name, 'no glossary term' AS issue
Check L7.3: Orphaned glossary terms (not linked to any node)
// L7.3 -- Severity: INFO
// GlossaryTerms that don't DEFINE anything
MATCH (g:GlossaryTerm)
WHERE NOT (g)-[:DEFINES]->()
RETURN g.id AS id, g.term AS term,
'GlossaryTerm not linked to any entity or role via DEFINES' AS observation
Level 8: Rules Binding (L8)
Goal: Every BusinessRule must have at least one traceability link (CONSTRAINS, APPLIES_IN, AFFECTS, or APPLIES_AT_STEP).
Named query: val_ba_L8_rules_binding (from validation-queries.cypher)
Check L8.1: Rules without traceability links
// L8.1 -- Severity: CRITICAL
// BusinessRules with no outgoing traceability edges
MATCH (brq:BusinessRule)
WHERE NOT EXISTS { MATCH (brq)-[:CONSTRAINS]->() }
AND NOT EXISTS { MATCH (brq)-[:APPLIES_IN]->() }
AND NOT EXISTS { MATCH (brq)-[:AFFECTS]->() }
AND NOT EXISTS { MATCH (brq)-[:APPLIES_AT_STEP]->() }
RETURN brq.id AS id, brq.name AS name, 'rule has no traceability links' AS issue
Check L8.2: Rules missing mandatory properties
// L8.2 -- Severity: CRITICAL
// BusinessRules without id or name
MATCH (brq:BusinessRule)
WHERE brq.id IS NULL OR brq.name IS NULL
RETURN coalesce(brq.id, 'NO ID') AS id,
coalesce(brq.name, 'NO NAME') AS name,
'BusinessRule missing mandatory property' AS issue
Check L8.3: Rules referencing non-existent targets
// L8.3 -- Severity: WARNING
// Rules with CONSTRAINS/APPLIES_IN/AFFECTS edges to nodes that lack id
MATCH (brq:BusinessRule)-[rel:CONSTRAINS|APPLIES_IN|AFFECTS|APPLIES_AT_STEP]->(target)
WHERE target.id IS NULL
RETURN brq.id AS rule_id, brq.name AS rule_name,
type(rel) AS rel_type, labels(target)[0] AS target_label,
'Rule traceability target has no id property' AS issue
Validation Levels -- Cross-Layer (XL1-XL5)
These checks verify BA-to-SA traceability via handoff edges. They require both BA and SA layers to be populated in Neo4j.
Source queries: handoff-queries.cypher and val_ba_sa_consistency (from validation-queries.cypher)
XL1: Automation Coverage
Goal: Every BA WorkflowStep with stereotype "Автоматизируется" should have a corresponding UseCase via AUTOMATES_AS.
Check XL1.1: Automated steps without UseCase
// XL1.1 -- Severity: CRITICAL
// Named query: val_ba_sa_consistency (from validation-queries.cypher)
MATCH (bp:BusinessProcess)-[:HAS_STEP]->(ws:WorkflowStep {stereotype: "Автоматизируется"})
OPTIONAL MATCH (ws)-[:AUTOMATES_AS]->(uc:UseCase)
WITH bp, ws, uc
WHERE uc IS NULL
RETURN bp.id AS bp_id, bp.name AS bp_name,
ws.id AS ws_id, ws.function_name AS ws_function,
'Automated step has no AUTOMATES_AS -> UseCase' AS issue
Check XL1.2: UseCases without a BA source step
// XL1.2 -- Severity: INFO
// UseCases that have no incoming AUTOMATES_AS from any WorkflowStep
// (may be system-only UCs, not necessarily an error)
MATCH (uc:UseCase)
WHERE NOT (:WorkflowStep)-[:AUTOMATES_AS]->(uc)
RETURN uc.id AS uc_id, uc.name AS uc_name,
'UseCase has no source BA WorkflowStep (may be system-only)' AS observation
Check XL1.3: Automation coverage statistics
// XL1.3 -- Severity: n/a (statistics)
// Named query: handoff_coverage_stats (automation portion)
MATCH (ws:WorkflowStep {stereotype: "Автоматизируется"})
WITH count(ws) AS total_auto
OPTIONAL MATCH (ws2:WorkflowStep {stereotype: "Автоматизируется"})-[:AUTOMATES_AS]->(:UseCase)
WITH total_auto, count(ws2) AS covered_auto
RETURN total_auto, covered_auto,
CASE WHEN total_auto > 0 THEN round(100.0 * covered_auto / total_auto) ELSE 0 END AS coverage_pct
XL2: Entity Coverage
Goal: Every BusinessEntity of type "Бизнес-объект" should be mapped to a DomainEntity via REALIZED_AS.
Check XL2.1: Business objects without domain mapping
// XL2.1 -- Severity: CRITICAL
// Named query: handoff_uncovered_entities (from handoff-queries.cypher)
MATCH (be:BusinessEntity {type: "Бизнес-объект"})
WHERE NOT (be)-[:REALIZED_AS]->(:DomainEntity)
RETURN be.id AS id, be.name AS name, be.type AS type,
'Business object not mapped to any DomainEntity via REALIZED_AS' AS issue
Check XL2.2: External documents and results (optional mapping)
// XL2.2 -- Severity: INFO
// Entities of type "Внешний документ" or "Результат" without REALIZED_AS
// (mapping is optional for these types, but flagged for awareness)
MATCH (be:BusinessEntity)
WHERE be.type IN ['Внешний документ', 'Результат']
AND NOT (be)-[:REALIZED_AS]->(:DomainEntity)
RETURN be.id AS id, be.name AS name, be.type AS type,
'Non-business-object entity not mapped to domain (optional)' AS observation
Check XL2.3: Entity coverage statistics
// XL2.3 -- Severity: n/a (statistics)
MATCH (be:BusinessEntity {type: "Бизнес-объект"})
WITH count(be) AS total_entities
OPTIONAL MATCH (be2:BusinessEntity {type: "Бизнес-объект"})-[:REALIZED_AS]->(:DomainEntity)
WITH total_entities, count(be2) AS covered_entities
RETURN total_entities, covered_entities,
CASE WHEN total_entities > 0 THEN round(100.0 * covered_entities / total_entities) ELSE 0 END AS coverage_pct
XL3: Rule Coverage
Goal: Every BusinessRule should be traceable to an SA Requirement via IMPLEMENTED_BY.
Check XL3.1: Rules without SA traceability
// XL3.1 -- Severity: CRITICAL
// BusinessRules not linked to any Requirement via IMPLEMENTED_BY
MATCH (brq:BusinessRule)
WHERE NOT (brq)-[:IMPLEMENTED_BY]->(:Requirement)
RETURN brq.id AS id, brq.name AS name,
'BusinessRule not traced to any SA Requirement via IMPLEMENTED_BY' AS issue
Check XL3.2: Rule coverage statistics
// XL3.2 -- Severity: n/a (statistics)
MATCH (brq:BusinessRule)
WITH count(brq) AS total_rules
OPTIONAL MATCH (brq2:BusinessRule)-[:IMPLEMENTED_BY]->(:Requirement)
WITH total_rules, count(brq2) AS covered_rules
RETURN total_rules, covered_rules,
CASE WHEN total_rules > 0 THEN round(100.0 * covered_rules / total_rules) ELSE 0 END AS coverage_pct
XL4: Role Coverage
Goal: Every BusinessRole should be mapped to a SystemRole via MAPPED_TO.
Check XL4.1: Business roles without system role mapping
// XL4.1 -- Severity: WARNING
// BusinessRoles not linked to any SystemRole via MAPPED_TO
MATCH (br:BusinessRole)
WHERE NOT (br)-[:MAPPED_TO]->(:SystemRole)
RETURN br.id AS id, br.full_name AS name,
'BusinessRole not mapped to any SystemRole via MAPPED_TO' AS issue
Check XL4.2: N:M mapping audit
// XL4.2 -- Severity: INFO
// BusinessRoles mapped to multiple SystemRoles or vice versa (valid but worth reviewing)
MATCH (br:BusinessRole)-[:MAPPED_TO]->(sr:SystemRole)
WITH br, collect(sr.name) AS sys_roles, count(sr) AS role_count
WHERE role_count > 1
RETURN br.id AS br_id, br.full_name AS br_name, sys_roles, role_count,
'BusinessRole maps to multiple SystemRoles (N:M)' AS observation
UNION ALL
MATCH (br:BusinessRole)-[:MAPPED_TO]->(sr:SystemRole)
WITH sr, collect(br.full_name) AS biz_roles, count(br) AS role_count
WHERE role_count > 1
RETURN sr.id AS br_id, sr.name AS br_name, biz_roles AS sys_roles, role_count,
'SystemRole mapped from multiple BusinessRoles (N:M)' AS observation
Check XL4.3: Role coverage statistics
// XL4.3 -- Severity: n/a (statistics)
MATCH (br:BusinessRole)
WITH count(br) AS total_roles
OPTIONAL MATCH (br2:BusinessRole)-[:MAPPED_TO]->(:SystemRole)
WITH total_roles, count(br2) AS covered_roles
RETURN total_roles, covered_roles,
CASE WHEN total_roles > 0 THEN round(100.0 * covered_roles / total_roles) ELSE 0 END AS coverage_pct
XL5: Glossary Alignment
Goal: BA GlossaryTerms should cover all SA DomainEntity names. Terms from the SA domain model should have corresponding BA glossary entries.
Check XL5.1: DomainEntities without matching GlossaryTerm
// XL5.1 -- Severity: WARNING
// SA DomainEntities whose name does not appear in any BA GlossaryTerm
MATCH (de:DomainEntity)
WHERE NOT EXISTS {
MATCH (g:GlossaryTerm)
WHERE toLower(g.term) = toLower(de.name)
OR toLower(g.term) CONTAINS toLower(de.name)
}
RETURN de.id AS entity_id, de.name AS entity_name,
'DomainEntity has no matching BA GlossaryTerm' AS issue
Check XL5.2: GlossaryTerms that DEFINE a BusinessEntity which has a REALIZED_AS DomainEntity -- check name consistency
// XL5.2 -- Severity: INFO
// Cross-check: glossary term vs domain entity name for the same business entity
MATCH (g:GlossaryTerm)-[:DEFINES]->(be:BusinessEntity)-[:REALIZED_AS]->(de:DomainEntity)
WHERE toLower(g.term) <> toLower(de.name)
RETURN g.term AS glossary_term, be.name AS ba_entity, de.name AS sa_entity,
'Name mismatch between GlossaryTerm and DomainEntity for same BusinessEntity' AS observation
Report Generation
After all applicable checks complete, format a report and present it directly to the user.
IMPORTANT: Do NOT write report files. Output the report as formatted text in the conversation.
Report Template
============================================================
BA MODEL VALIDATION REPORT
Date: YYYY-MM-DD
Scope: {internal | cross | full}
============================================================
SUMMARY
-------
| Level | Name | Status | Issues |
|-------|---------------------------|---------|--------|
| L1 | BP Completeness | PASS/WARN/FAIL | N |
| L2 | Workflow Coverage | PASS/WARN/FAIL | N |
| L3 | Step Performers | PASS/WARN/FAIL | N |
| L4 | Entity Attributes | PASS/WARN/FAIL | N |
| L5 | Entity-Process Matrix | PASS/WARN/FAIL | N |
| L6 | Role-Process Matrix | PASS/WARN/FAIL | N |
| L7 | Glossary Coverage | PASS/WARN/FAIL | N |
| L8 | Rules Binding | PASS/WARN/FAIL | N |
| XL1 | Automation Coverage | PASS/WARN/FAIL | N |
| XL2 | Entity Coverage | PASS/WARN/FAIL | N |
| XL3 | Rule Coverage | PASS/WARN/FAIL | N |
| XL4 | Role Coverage | PASS/WARN/FAIL | N |
| XL5 | Glossary Alignment | PASS/WARN/FAIL | N |
Overall: PASS / WARN / FAIL
COVERAGE STATISTICS (cross/full only)
--------------------------------------
Automation: NN% (covered/total)
Entities: NN% (covered/total)
Rules: NN% (covered/total)
Roles: NN% (covered/total)
ISSUES
------
| # | Level | Severity | ID | Description |
|---|-------|----------|----------|--------------------------------------|
| 1 | L1 | CRITICAL | BP-003 | missing trigger, missing owner |
| 2 | L3 | CRITICAL | BP-001-S03 | missing PERFORMED_BY |
| 3 | L7 | WARNING | OBJ-005 | no glossary term |
| ... |
RECOMMENDATIONS
---------------
1. [CRITICAL] Fix L1 issues first -- processes must have trigger, result, and owner.
2. [WARNING] Add glossary terms for uncovered entities and roles.
3. [INFO] Review N:M role mappings for correctness.
Status Rules
- PASS: Zero CRITICAL and fewer than 5 WARNING findings at this level.
- WARN: Zero CRITICAL but 5+ WARNING findings.
- FAIL: One or more CRITICAL findings.
Overall Status
- FAIL if any level has CRITICAL findings.
- WARN if any level is WARN (but no CRITICAL anywhere).
- PASS if all levels are PASS.
Reads / Writes
Reads
# Neo4j (read-only via mcp__neo4j__read-cypher):
- BA layer: BusinessProcess, WorkflowStep, BusinessEntity, EntityAttribute,
BusinessRole, BusinessRule, GlossaryTerm
- SA layer (cross/full only): UseCase, DomainEntity, SystemRole, Requirement
- Handoff edges: AUTOMATES_AS, REALIZED_AS, MAPPED_TO, IMPLEMENTED_BY
# Query library (reference only -- queries are embedded above):
- graph-infra/queries/validation-queries.cypher
- graph-infra/queries/handoff-queries.cypher
Writes
# NONE -- this skill is strictly read-only.
# Report is output to the user directly, no files written.
Checklist
Before completing validation, verify:
Pre-flight
- BA-layer nodes exist in the graph (BusinessProcess, WorkflowStep, etc.)
- For scope=cross|full: SA-layer nodes exist (UseCase, DomainEntity, etc.)
L1: BP Completeness
- Every BP has trigger property
- Every BP has result property
- Every BP has at least one OWNS edge from a BusinessRole
- Every BP has id and name properties
L2: Workflow Coverage
- Every BP with has_decomposition=true has at least one HAS_STEP
- No orphaned WorkflowSteps (not linked to any BP)
- All steps have non-empty function_name
L3: Step Performers
- Every WorkflowStep has PERFORMED_BY to a BusinessRole
- PERFORMED_BY targets are actual BusinessRole nodes
L4: Entity Attributes
- Every BusinessEntity has at least one EntityAttribute
- No orphaned EntityAttributes
- Every entity has id and name properties
L5: Entity-Process Matrix
- Every BusinessEntity is referenced by at least one workflow step
- READS/PRODUCES/MODIFIES edges point to BusinessEntity nodes
L6: Role-Process Matrix
- Every BusinessRole has OWNS, PARTICIPATES_IN, or PERFORMED_BY
- Roles with only PERFORMED_BY flagged for review
L7: Glossary Coverage
- Every BusinessEntity has a DEFINES edge from a GlossaryTerm
- Every BusinessRole has a DEFINES edge from a GlossaryTerm
- No orphaned GlossaryTerms
L8: Rules Binding
- Every BusinessRule has CONSTRAINS, APPLIES_IN, AFFECTS, or APPLIES_AT_STEP
- Every rule has id and name properties
- Traceability targets have valid id properties
XL1-XL5 (only for scope=cross|full)
- XL1: All "Автоматизируется" steps have AUTOMATES_AS -> UseCase
- XL2: All "Бизнес-объект" entities have REALIZED_AS -> DomainEntity
- XL3: All BusinessRules have IMPLEMENTED_BY -> Requirement
- XL4: All BusinessRoles have MAPPED_TO -> SystemRole
- XL5: All SA DomainEntity names covered by BA GlossaryTerms
Report
- Summary table formatted and presented to user
- Coverage statistics included (for cross/full)
- All issues listed with severity, ID, and description
- Recommendations prioritized by severity
- Overall status determined correctly (PASS/WARN/FAIL)