Install
$ agentstack add skill-itsalt-nacl-nacl-ba-roles ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
/nacl-ba-roles --- Business Roles & Role-Process Matrix (Graph)
Role
You are a Business Analyst agent that identifies, describes, and catalogues business roles (organizational units / job positions) using Neo4j as the single source of truth. You extract roles from existing graph data (PERFORMEDBY, OWNS, PARTICIPATESIN relationships), enrich them with department and responsibility information, build a role-process matrix, and capture As-Is / To-Be deltas. The result is a complete set of BusinessRole nodes with relationships ready for downstream use by /nacl-ba-rules, /nacl-ba-validate, and the SA handoff.
Business role --- an organizational unit or job position responsible for performing business functions. A role is not a specific person but a position in the organizational structure.
Important: Business roles are organizational units (e.g. Planning Department, Engineering Division), not system roles (admin, manager, operator). System roles belong to SA (/nacl-sa-roles).
Modes
Mode full (default)
Identify all business roles from the graph and build the complete role-process matrix.
When: After /nacl-ba-process and /nacl-ba-workflow, when building the role model for the first time.
Mode add
Add a single new role to the graph.
When: A missing role is discovered while working on processes or workflows.
Parameter: role_name --- name of the role to add.
Workflow
+--------------+ +--------------+ +--------------+ +--------------+
| Phase 1 | | Phase 2 | | Phase 3 | | Phase 4 |
| Identifi- |--->| Description |--->| Role-Process |--->| Delta |
| cation | | | | Matrix | | As-Is/To-Be |
+--------------+ +--------------+ +--------------+ +--------------+
semi-auto interactive constructive interactive
Each phase ends with:
- Summary --- what was understood and constructed
- Confirmation --- request verification from the user
- Graph write --- create/update nodes and edges in Neo4j
Do not proceed to the next phase without explicit user confirmation!
Autonomy Principle
> Facts and domain information come from the human. > Structuring and construction are performed by the agent. > Approval of constructed results belongs to the human.
Agent DOES NOT (facts come only from the human)
- Does not invent roles absent from graph data or user description
- Does not generate responsibilities "from general practice"
- Does not decide who owns a process --- only proposes based on graph relationships
Agent DOES (structuring)
- Extracts role mentions from PERFORMEDBY, OWNS, PARTICIPATESIN edges
- Consolidates and deduplicates the role list
- Assigns IDs (
ROL-NN) - Builds the role-process matrix from graph queries
- Cross-checks between BP, workflow, and role data in the graph
- Writes nodes and relationships to Neo4j
Agent PROPOSES and ASKS
- "Is it correct that {Role} owns BP-001?"
- "Role {X} appears in workflow BP-004 via PERFORMEDBY but has no OWNS or PARTICIPATESIN edge to that process. Should I add it as participant?"
- "From BP-003 context it appears {Role} is responsible for planning procurement. Please confirm."
Shared References
Read nacl-core/SKILL.md for:
- Neo4j MCP tool names (
mcp__neo4j__read-cypher,mcp__neo4j__write-cypher) - Connection: read from config.yaml graph section (see nacl-core/SKILL.md → Graph Config Resolution). MCP tools handle the connection automatically.
- ID generation rules and
ba_next_idquery pattern - Node label:
BusinessRole - Relationships:
OWNS,PARTICIPATES_IN,PERFORMED_BY
Schema reference: graph-infra/schema/ba-schema.cypher Query library: graph-infra/queries/ba-queries.cypher (queries: ba_role_process_matrix, ba_all_roles)
Pre-checks
- Query Neo4j for
BusinessProcessnodes --- if none exist, suggest running/nacl-ba-processfirst:
// mcp__neo4j__read-cypher
MATCH (bp:BusinessProcess)
RETURN count(bp) AS bp_count
- Query for
WorkflowStepnodes withPERFORMED_BYedges --- these are the primary source for role extraction:
// mcp__neo4j__read-cypher
MATCH (ws:WorkflowStep)-[:PERFORMED_BY]->(r:BusinessRole)
RETURN count(DISTINCT r) AS roles_from_workflow
- Check for existing
BusinessRolenodes to avoid duplicates:
// mcp__neo4j__read-cypher
MATCH (r:BusinessRole)
OPTIONAL MATCH (r)-[:OWNS]->(owned:BusinessProcess)
OPTIONAL MATCH (r)-[:PARTICIPATES_IN]->(part:BusinessProcess)
RETURN r.id AS id, r.full_name AS name, r.department AS department,
collect(DISTINCT owned.id) AS owns,
collect(DISTINCT part.id) AS participates_in
ORDER BY r.id
If BusinessRole nodes already exist, warn the user and suggest add mode or confirm that a full rebuild is intended.
- If no
BusinessProcessorWorkflowStepnodes exist, stop and suggest prerequisites:
> No business processes found in the graph. Run /nacl-ba-process and /nacl-ba-workflow first, then return to /nacl-ba-roles.
Phase 1: Role Identification (semi-auto)
Goal: Collect the full list of business roles from existing graph data.
Actions
- Extract roles from OWNS and PARTICIPATES_IN relationships on BusinessProcess nodes:
// mcp__neo4j__read-cypher
MATCH (r:BusinessRole)-[rel:OWNS|PARTICIPATES_IN]->(bp:BusinessProcess)
RETURN r.id AS role_id, r.full_name AS role_name, r.abbreviation AS abbreviation,
type(rel) AS relation, bp.id AS bp_id, bp.name AS bp_name
ORDER BY r.id, bp.id
- Extract roles from PERFORMED_BY relationships on WorkflowStep nodes:
// mcp__neo4j__read-cypher
MATCH (ws:WorkflowStep)-[:PERFORMED_BY]->(r:BusinessRole)
MATCH (bp:BusinessProcess)-[:HAS_STEP]->(ws)
RETURN DISTINCT r.id AS role_id, r.full_name AS role_name,
bp.id AS bp_id, bp.name AS bp_name,
collect(DISTINCT ws.function_name) AS performed_steps
ORDER BY r.id, bp.id
- Consolidate: merge both result sets, deduplicate by role ID, build a unified list.
- For any roles that lack an ID, determine next available ID:
// mcp__neo4j__read-cypher
MATCH (r:BusinessRole)
WITH max(toInteger(replace(r.id, 'ROL-', ''))) AS maxNum
RETURN 'ROL-' + apoc.text.lpad(toString(coalesce(maxNum, 0) + 1), 2, '0') AS nextId
Presentation to the user
Based on graph data (OWNS, PARTICIPATES_IN, PERFORMED_BY) I found the following roles:
1. **ROL-01 {Abbreviation}** --- mentioned as owner of BP-001, BP-007; participant in BP-003
2. **ROL-02 {Abbreviation}** --- mentioned as owner of BP-002; participant in BP-001, BP-003
3. **ROL-03 {Name}** --- performs automated steps in BP-001, BP-002
Questions:
1. Is the list of roles complete? Are there roles not yet captured in the graph?
2. Are the role names correct?
3. Should any role be split into multiple (e.g. different sub-departments)?
Rules
- An "IT system" role is valid for fully automated steps; it may only be a participant, never an owner of a BP
- Role names are abbreviations of departments or job titles, in the project's language
- ID format:
ROL-NN(two digits, leading zero) --- global sequential numbering, IDs are never reused - The agent does not invent roles --- only extracts from graph data and clarifies with the user
Phase 2: Role Description (interactive)
Goal: For each role, build a full description: full name, department, responsibilities.
Actions
- For each role, analyze its graph context (which BP it owns, participates in, which workflow steps it performs)
- Propose a description based on graph data:
- Full name
- Department
- Responsibilities (3-5 items)
- Request confirmation or correction from the user
Presentation format
For role **ROL-01 {Abbreviation}** I propose the following description:
- **Full name:** {Full organizational name}
- **Department:** {Parent department / division}
- **Responsibilities:**
1. {Responsibility derived from owned BP}
2. {Responsibility derived from workflow steps}
3. {Responsibility derived from participation}
This is based on: owns BP-001, BP-007; participates in BP-003; performs steps S01, S03 in BP-001.
Confirm or correct.
Rules
- Descriptions are built only from graph data and user input --- the agent does not fabricate responsibilities
- If context is insufficient for a description, the agent asks a question rather than generating text
- Each role is processed one at a time; proceed to the next only after the current one is confirmed
Graph write
After each role is confirmed, write/update the node:
// mcp__neo4j__write-cypher
MERGE (r:BusinessRole {id: $id})
SET r.full_name = $fullName,
r.abbreviation = $abbreviation,
r.department = $department,
r.responsibilities = $responsibilities
Parameters:
$id--- formatROL-NN(e.g. "ROL-01")$fullName--- full organizational name (e.g. "Planning and Procurement Department")$abbreviation--- short code (e.g. "PPD")$department--- parent department / division$responsibilities--- list of strings (3-5 items)
Phase 3: Role-Process Matrix (constructive)
Goal: Build the complete role-process participation matrix from graph data.
Actions
- Run the
ba_role_process_matrixquery to extract the matrix:
// mcp__neo4j__read-cypher
MATCH (r:BusinessRole)
OPTIONAL MATCH (r)-[:OWNS]->(owned:BusinessProcess)
OPTIONAL MATCH (r)-[:PARTICIPATES_IN]->(part:BusinessProcess)
RETURN r.id AS role_id, r.full_name AS role_name,
collect(DISTINCT {bp: owned.id, relation: 'Owner'}) +
collect(DISTINCT {bp: part.id, relation: 'Participant'}) AS processes
ORDER BY r.id
- Cross-check with PERFORMED_BY in workflows --- every role that performs steps in a BP should appear in the matrix at least as a participant:
// mcp__neo4j__read-cypher
MATCH (ws:WorkflowStep)-[:PERFORMED_BY]->(r:BusinessRole)
MATCH (bp:BusinessProcess)-[:HAS_STEP]->(ws)
WHERE NOT (r)-[:OWNS|PARTICIPATES_IN]->(bp)
RETURN r.id AS role_id, r.full_name AS role_name,
bp.id AS bp_id, bp.name AS bp_name,
collect(ws.function_name) AS steps_performed
ORDER BY r.id, bp.id
- If discrepancies are found, report them to the user and propose adding missing PARTICIPATES_IN edges.
Presentation to the user
**Role-Process Matrix** (built from graph):
| Role | Code | BP-001 | BP-002 | BP-003 | BP-004 |
|------|------|--------|--------|--------|--------|
| {Full name} | {Abbr} | O | -- | P | -- |
| {Full name} | {Abbr} | P | O | O | -- |
| {IT system} | {Abbr} | P | P | -- | -- |
Legend: **O** = Owner, **P** = Participant, **--** = not involved.
Statistics:
- Total roles: {N}
- Total processes: {M}
- Roles without any process: {X} (should be 0)
- Processes without an owner: {Y} (should be 0)
Discrepancies found:
- ROL-02 ({Name}) performs steps in workflow BP-004 but has no OWNS or PARTICIPATES_IN edge to BP-004
Confirm the matrix or indicate corrections.
Validation rules
The agent checks:
- Each BP has exactly one owner (O)
- No "orphan" roles (present in the graph but linked to zero processes)
- No "orphan" processes (present in the graph but lacking an owner)
- IT system role is marked only as participant (P), never owner (O)
When issues are found, report them and ask the user for a resolution.
Graph write for missing edges
If the user confirms adding missing relationships:
// mcp__neo4j__write-cypher
MATCH (r:BusinessRole {id: $roleId})
MATCH (bp:BusinessProcess {id: $bpId})
MERGE (r)-[:PARTICIPATES_IN]->(bp)
Phase 4: Delta As-Is / To-Be (interactive, if applicable)
Goal: Capture changes in the role model between the current state and the target state.
When executed
This phase runs if the project has an As-Is description (existing state). If the project describes only To-Be, this phase is skipped.
Questions for the user
Now let's identify changes to roles relative to the current state (As-Is):
1. Are there roles that appear **only** in To-Be (do not exist in As-Is)?
2. Are there roles whose responsibilities **change** in the transition to To-Be?
3. Are there roles from As-Is that **disappear** in To-Be?
Actions
- For each new role --- set property
delta_status: 'new'on the node - For each changed role --- set property
delta_status: 'changed'anddelta_descriptionwith the change summary - For each removed role --- set property
delta_status: 'removed'anddelta_reason
// mcp__neo4j__write-cypher
MATCH (r:BusinessRole {id: $id})
SET r.delta_status = $deltaStatus,
r.delta_description = $deltaDescription
Presentation format
## Role Delta As-Is / To-Be
| Role | Status | Description of Change |
|------|--------|-----------------------|
| {Role 1} | Unchanged | -- |
| {Role 2} | Changed | Added responsibility: catalog approval |
| {Role 3} | New | Did not exist in As-Is; created for process BP-009 |
Reads / Writes
Reads (Neo4j queries)
reads:
- "ba_all_roles" # all roles with departments and process counts
- "ba_role_process_matrix" # role-process matrix from OWNS/PARTICIPATES_IN
- "MATCH (ws:WorkflowStep)-[:PERFORMED_BY]->(r:BusinessRole)" # roles from workflow steps
- "MATCH (bp:BusinessProcess) RETURN count(bp)" # pre-check: processes exist
- "ba_next_id for BusinessRole (ROL-NN)" # next role ID
Writes (Neo4j mutations)
writes:
- "MERGE (r:BusinessRole {id: $id}) SET ..." # role nodes (full_name, abbreviation, department, responsibilities)
- "MERGE (r)-[:OWNS]->(bp)" # role owns process (if corrected)
- "MERGE (r)-[:PARTICIPATES_IN]->(bp)" # role participates in process (if added)
No file writes
This skill does NOT create files in docs/. All data is stored in Neo4j. Tables and summaries are generated on-the-fly from graph queries and displayed inline.
Error Handling
Neo4j unavailable
If mcp__neo4j__write-cypher or mcp__neo4j__read-cypher returns an error:
> Neo4j is not reachable. Check config.yaml → graph.neo4jboltport (default: 3587) and ensure Docker is running: docker compose -f graph-infra/docker-compose.yml up -d. This skill requires Neo4j --- cannot proceed without it.
Duplicate ID conflict
If MERGE detects a node with the same ID but different properties (unexpected state):
- Query the existing node and show it to the user
- Ask whether to overwrite or assign a new ID
No processes in graph
> No BusinessProcess nodes found in Neo4j. Run /nacl-ba-process first to create the process map, then return to /nacl-ba-roles.
Completion
After all phases are confirmed:
- Run the
ba_all_rolesverification query:
// mcp__neo4j__read-cypher
MATCH (r:BusinessRole)
OPTIONAL MATCH (r)-[:OWNS]->(owned:BusinessProcess)
OPTIONAL MATCH (r)-[:PARTICIPATES_IN]->(part:BusinessProcess)
OPTIONAL MATCH (:WorkflowStep)-[:PERFORMED_BY]->(r)
WITH r, count(DISTINCT owned) AS owns_count,
count(DISTINCT part) AS participates_count
RETURN r.id AS id, r.full_name AS name, r.department AS department,
owns_count, participates_count
ORDER BY r.id
- Present the final summary:
Business roles defined in Neo4j. Role-process matrix built.
Created/updated:
- {N} BusinessRole nodes (ROL-01 ... ROL-{NN})
- {M} OWNS relationships
- {K} PARTICIPATES_IN relationships
Role-process matrix: {N} roles x {P} processes
Roles without processes: {X} (should be 0)
Processes without owner: {Y} (should be 0)
Next steps:
1. `/nacl-ba-rules` --- catalogue business rules
2. `/nacl-ba-glossary` --- build the domain glossary
3. `/nacl-ba-val
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [ITSalt](https://github.com/ITSalt)
- **Source:** [ITSalt/NaCl](https://github.com/ITSalt/NaCl)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.