AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Nacl Migrate Sa

skill-itsalt-nacl-nacl-migrate-sa · by ITSalt

|

No reviews yet
0 installs
36 views
0.0% view→install

Install

$ agentstack add skill-itsalt-nacl-nacl-migrate-sa

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No 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.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-itsalt-nacl-nacl-migrate-sa)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

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 →
Are you the author of Nacl Migrate Sa? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

/nacl-migrate-sa — SA Markdown → Neo4j

Role

You delegate SA parsing, validation, and Cypher generation to stdlib Python scripts under $NACL_HOME/nacl-migrate-sa/scripts/. You never parse Markdown yourself; the scripts own that. Your job is:

  1. Run the scripts in order.
  2. Read their JSON outputs.
  3. Execute the Cypher plan against Neo4j via mcp__neo4j__write-cypher.
  4. Gather live counts via mcp__neo4j__read-cypher and hand them to audit_sa.py.
  5. Present results and errors to the user in plain language.

If the project has a BA layer, nacl-migrate-ba must have already run — this skill emits cross-layer handoff edges that point at BA nodes.


Invocation

/nacl-migrate-sa [project_path] [--dry-run] [--adapter=] [--no-ba]

| Parameter | Required | Description | |---|---|---| | project_path | No | Project root (default: cwd). | | --dry-run | No | Parse + validate + Cypher gen; no Neo4j writes, no audit. | | --adapter | No | Force adapter (inline-table-v1). Default: auto-detect. | | --no-ba | No | Skip cross-layer handoff edges. Use for SA-only projects. |


Prelude — locate NaCl home and verify Python

# Resolve $NACL_HOME
if [ -z "$NACL_HOME" ]; then
  for candidate in "$HOME/projects/NaCl" "$HOME/NaCl" "$HOME/code/NaCl" "$HOME/src/NaCl"; do
    if [ -f "$candidate/nacl-migrate-core/nacl_migrate_core/__init__.py" ]; then
      export NACL_HOME="$candidate"
      break
    fi
  done
fi
if [ -z "$NACL_HOME" ] || [ ! -f "$NACL_HOME/nacl-migrate-core/nacl_migrate_core/__init__.py" ]; then
  echo "Unable to locate NaCl repo. Set NACL_HOME=/path/to/NaCl and retry." >&2
  exit 1
fi

python3 -c 'import sys; sys.exit(0 if sys.version_info >= (3,11) else 1)' 2>/dev/null \
  || { echo "Python 3.11+ required. On macOS: brew install python@3.11"; exit 1; }

Soft preflight (direct invocation)

When invoked directly (i.e. not via the /nacl-migrate orchestrator), run an ID-pattern scan and warn — but do not block — if any token in the project's filenames or YAML frontmatter does not match a known adapter pattern. The orchestrator path runs the same scan at Phase A.5 with a hard gate; the direct-invocation path stays non-blocking so a single-layer rerun is ergonomic.

mkdir -p .nacl-migrate
python3 "$NACL_HOME/nacl-migrate-ba/scripts/preflight_ids.py" \
  --project "$PWD" \
  --output .nacl-migrate/preflight.json || true

Exit code 1 from the script means unknown patterns were found. Surface the report's patterns_unknown list to the user:

> Preflight surfaced N unknown ID-shaped tokens. These will likely be > dropped at parse. Review .nacl-migrate/preflight.json and either > widen an adapter (recommended) or pass --force to proceed anyway.

If the user passes --force, continue. Otherwise stop.


Preconditions

  1. config.yaml / .mcp.json present; Neo4j reachable via mcp__neo4j__get-schema.
  2. At least one SA folder exists under docs/ (10-16 or 00-06 variant). If none:

"No SA layer detected. Skipping nacl-migrate-sa." Exit cleanly.

  1. Unless --no-ba: BA nodes present in Neo4j (query MATCH (bp:BusinessProcess) RETURN count(bp) > 0). If zero AND the project has a BA docs tree, stop — user must run /nacl-migrate-ba first.

Phase 0 — Detect adapter + numbering

The SA parser infers both at once. For now there is a single SA adapter (inline-table-v1), which auto-detects 10-16 vs 00-06 numbering and handles an optional frontmatter fallback for UC files.

Skip this phase when --adapter was passed explicitly.


Phase 1 — Parse SA markdown → SaIR + HandoffIR

python3 "$NACL_HOME/nacl-migrate-sa/scripts/parse_sa.py" \
  --project "$PWD" \
  --adapter inline-table-v1 \
  --output .nacl-migrate/sa-ir.json \
  --handoff-output .nacl-migrate/handoff-ir.json

Expected stdout: counts table for SaIR and HandoffIR. Surface every warning code to the user.

On error exit, print message + remediation verbatim.


Phase 2 — Validate IR

python3 "$NACL_HOME/nacl-migrate-sa/scripts/validate_sa_ir.py" \
  --input .nacl-migrate/sa-ir.json \
  --handoff .nacl-migrate/handoff-ir.json \
  --output .nacl-migrate/sa-validation.json

13 referential checks (SV1–SV8 + HV1–HV5). Exit 0 → all pass. Exit 1 → stop and print the failure list.

The script also prints a Coverage section (SC1–SC7) and writes a coverage block to sa-validation.json. This is the completeness dimension — it measures how much of each node type the adapter actually populated (UC activity steps, UC module, UC↔form links, entity attributes, enum values, form fields). It exists because the referential checks and the Phase 7 audit are both blind to under-extraction: an IR with 1 ActivityStep total is internally consistent and writes cleanly, yet leaves nearly every UseCase an empty shell.

Coverage is advisory by default (it does not change the exit code — some emptiness is legitimate, e.g. a pure list-view UC has no steps). Surface the Coverage lines to the user verbatim; do not bury them. A severely under-extracted migration now shows e.g. SC1 UC activity steps: 1/50 (2.0%) instead of a silent "clean".

To gate in CI, add --strict (fail any metric below 100%) or --min-coverage PCT (fail below PCT). These flip the exit code to non-zero; leave them off for the normal interactive migration.


Phase 3 — Generate Cypher plan

python3 "$NACL_HOME/nacl-migrate-sa/scripts/generate_sa_cypher.py" \
  --input .nacl-migrate/sa-ir.json \
  --handoff .nacl-migrate/handoff-ir.json \
  --output .nacl-migrate/sa-cypher.json

Three batch kinds: node, edge (SA-internal), handoff (BA↔SA). If --no-ba was set, skip all handoff batches when executing.

If --dry-run: stop here and report the plan summary.


Phase 4 — Execute Cypher against Neo4j

Preflight: mcp__neo4j__get-schema() must succeed.

Read .nacl-migrate/sa-cypher.json. For each batch:

mcp__neo4j__write-cypher(query = batch.cypher, params = batch.params)

Report progress per batch: [i/N] {label} rows=... ok.

If --no-ba, skip batches where kind == "handoff" and log a single line: Skipping N handoff batches (--no-ba).

On any batch failure: log the batch index + error; stop. The partial graph is MERGE-idempotent — rerunning after a fix is safe.


Phase 5 — SUGGESTS edges (optional, best-effort)

Emit ProcessGroup -[:SUGGESTS]-> Module edges from in-graph data. This is the only SA edge type that can't be computed by the scripts because it requires joining SA's Module.related_process_ids with BA's ProcessGroup -[:CONTAINS]-> BusinessProcess. Run via MCP:

MATCH (gpr:ProcessGroup)-[:CONTAINS]->(bp:BusinessProcess)
MATCH (m:Module)
WHERE bp.id IN m.related_process_ids
MERGE (gpr)-[:SUGGESTS]->(m)
RETURN count(*) AS n

Skip entirely if --no-ba.


Phase 6 — Gather live counts

Query Neo4j via mcp__neo4j__read-cypher for every node label and edge type listed in audit_sa.py. Important: scope HAS_STEP, HAS_ATTRIBUTE, and NEXT_STEP counts to the SA layer, because those relationship types also exist on the BA layer. Use label-scoped Cypher:

MATCH (:UseCase)-[r:HAS_STEP]->(:ActivityStep) RETURN count(r) AS n
MATCH (:DomainEntity)-[r:HAS_ATTRIBUTE]->(:DomainAttribute) RETURN count(r) AS n
MATCH (:ActivityStep)-[r:NEXT_STEP]->(:ActivityStep) RETURN count(r) AS n

All other edge types have SA-exclusive labels and can use the unscoped form.

Write the counts to .nacl-migrate/sa-live-counts.json.


Phase 7 — Audit

python3 "$NACL_HOME/nacl-migrate-sa/scripts/audit_sa.py" \
  --ir .nacl-migrate/sa-ir.json \
  --handoff .nacl-migrate/handoff-ir.json \
  --counts .nacl-migrate/sa-live-counts.json \
  --output .nacl-migrate/sa-audit.json

Exit 0 → "All SA counts match." Exit 1 → surface mismatches to the user.

The audit prints a pointer line — count parity ✓ — see validation coverage (SC1–SC7 …) — because count parity only proves IR→graph fidelity, never extraction completeness. When you report the audit result to the user, quote the Phase-2 Coverage numbers next to it; never present "All SA counts match" as if it meant the migration is complete.


Phase 7b — Backfill validation exemption flags

Migrated graphs are populated from markdown documents that predate the L4–L7 validators. Their nodes lack the has_ui / system_only / shared / internal / field_category exemption properties, which causes nacl-sa-validate to emit dozens of false-positive findings on the very first run.

To prevent this, the migration ends with an automatic backfill via nacl-sa-flags:

/nacl-sa-flags backfill-all --detect-internal

Behavior:

  • :UseCase.has_ui is derived deterministically: true if (uc)-[:USES_FORM]->(:Form), else false.
  • :DomainAttribute.internal is auto-flagged for system patterns (id, *_id, *_at, *_token, *_hash).
  • :SystemRole.system_only, :DomainEntity.shared, :FormField.field_category get safe defaults (false, false, 'input').

The user is prompted at the end of Phase 7 to confirm before the backfill runs. If declined, the migration completes without flags and nacl-sa-validate full will surface ~50–150 NULL-property findings as recommendations rather than CRITICAL/WARN; the user can then run nacl-sa-flags backfill-all manually at any later time.

Why --detect-internal by default: post-migration graphs have many surrogate keys and timestamps. The heuristic flags them automatically and is safe (it only sets internal=true, never internal=false, so manually-flagged user-facing attributes are preserved). Real telemetry / provider-internal columns may need additional manual marking after the first validate run.


Phase 8 — Report

Write MIGRATION-REPORT-SA.md at project root:

# SA Migration Report

**Project:** {project_path}
**Adapter:** {adapter}
**Numbering:** {numbering}  (10-16 or 00-06)
**Ran at:** {ISO timestamp}

## SA IR vs live Neo4j
(Copy from sa-audit.json — node + edge tables.)

**Audit result: N/N CLEAN** — but count parity only proves IR→graph fidelity.
See Completeness / Coverage below for whether the IR itself is complete.

## Completeness / Coverage
(Copy the `coverage` block from sa-validation.json. One line per metric, kept
adjacent to the audit headline so "CLEAN" is never read as "complete".)

| Metric | Covered | % | Sample missing |
|--------|---------|---|----------------|
| SC1 UC activity steps | {covered}/{total} | {pct}% | {sample_missing} |
| SC2 UC module | {covered}/{total} | {pct}% | … |
| SC3 UC→form link | {covered}/{total} | {pct}% | … |
| SC3f Form→UC link | {covered}/{total} | {pct}% | … |
| SC4 DomainEntity module | {covered}/{total} | {pct}% | … |
| SC5 DomainEntity attributes | {covered}/{total} | {pct}% | … |
| SC6 Enumeration values | {covered}/{total} | {pct}% | … |
| SC7 Form fields | {covered}/{total} | {pct}% | … |

Coverage is advisory: low percentages flag adapter under-extraction (or
legitimately empty nodes), not a write failure. Investigate any metric well
below 100% before declaring the migration done.

## Cross-layer handoff
(Counts of AUTOMATES_AS, REALIZED_AS, TYPED_AS, MAPPED_TO, IMPLEMENTED_BY, SUGGESTS.)

## Warnings
{list from sa-ir.json warnings[] and handoff-ir.json, or "none"}

## Non-extracted relationships
The following are currently 0 because the adapter does not extract them:
  - FormField / HAS_FIELD / MAPS_TO (needs _form-domain-mapping.md parser)
  - ActivityStep.NEXT_STEP (needs UC flowchart Mermaid parser)
  - UseCase -[:ACTOR]-> SystemRole
  - SystemRole -[:HAS_PERMISSION]-> DomainEntity
  - BusinessRule -[:IMPLEMENTED_BY]-> Requirement (matrix uses category names, not REQ ids)

Adding any of these is a per-adapter enhancement. Non-blocker for migration.

## Next steps
- Run `/nacl-sa-validate` (L1-L13 + XL6-XL9 cross-validation; L10-L13 pass vacuously until the project adopts the 2.15+ extension layers — see `docs/runbooks/upgrade-graph-extensions.md`)
- Run `/nacl-tl-diagnose` for code-docs drift analysis

Idempotency

All Neo4j writes are MERGE-keyed on canonical IDs. Safe to rerun. If an adapter change produces different canonical IDs, old nodes become orphans — audit_sa.py flags this as a count mismatch.


Known non-blockers

The current adapter does not extract:

  • FormField / HASFIELD / MAPSTO — requires parsing _form-domain-mapping.md.
  • ActivityStep.NEXT_STEP — UC activity flows are text tables without explicit step-number links.
  • UseCase -[:ACTOR]-> SystemRole — UC.actor is text ("ACT-01 Пользователь"); resolving it to a SYSROL requires the SystemRole table to be loaded first.
  • SystemRole -[:HAS_PERMISSION]-> DomainEntity — requires parsing the permissions matrix.
  • BusinessRule -[:IMPLEMENTED_BY]-> Requirement — traceability matrix maps BRQ to category strings, not REQ IDs. Warning: HANDOFF_REQ_CATEGORY is logged per row.

These can be added as adapter enhancements later. None is blocking for migration correctness.


Error handling

| Situation | Response | |---|---| | Prelude can't find $NACL_HOME | Stop. Ask to export NACL_HOME. | | Python < 3.11 | Stop. Ask user to upgrade. | | BA docs present but BA nodes missing | Stop. Ask user to run /nacl-migrate-ba first. | | Ambiguous numbering (both 10-16 and 00-06 dirs present) | Stop. Ask user to remove one. | | Adapter unknown | Stop. Present supported adapters. | | Validation failure | Stop. Print failed checks. | | Batch failure | Stop after the failing batch. Rerun after fix. | | Audit mismatch | Report, do not claim success. |


Reads / Writes

Reads

  • {project}/docs/{10-16|00-06}-*/**/*.md
  • {project}/docs/99-meta/traceability-matrix.md
  • mcp__neo4j__read-cypher (live counts in Phase 6)
  • mcp__neo4j__get-schema (preflight)

Writes

  • .nacl-migrate/sa-ir.json
  • .nacl-migrate/handoff-ir.json
  • .nacl-migrate/sa-validation.json
  • .nacl-migrate/sa-cypher.json
  • .nacl-migrate/sa-live-counts.json
  • .nacl-migrate/sa-audit.json
  • MIGRATION-REPORT-SA.md
  • mcp__neo4j__write-cypher (Phases 4, 5)

Checklist

  • [ ] Prelude: $NACL_HOME resolved, Python 3.11+ present
  • [ ] Phase 0: adapter + numbering detected (or user supplied)
  • [ ] Phase 1: SA IR + Handoff IR emitted
  • [ ] Phase 2: validation 13/13 pass (or blocker list surfaced) + Coverage (SC1–SC7) reported
  • [ ] Phase 3: Cypher plan generated
  • [ ] Phase 4: every batch executed via mcp__neo4j__write-cypher
  • [ ] Phase 5: SUGGESTS edges emitted (or skipped with --no-ba)
  • [ ] Phase 6: live counts gathered (layer-scoped for shared rel types)
  • [ ] Phase 7: audit clean
  • [ ] Phase 8: MIGRATION-REPORT-SA.md written

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.