nacl-tl-full

SkillProductivity

Graph-aware full lifecycle orchestrator. Reads waves/tasks from Neo4j, updates phase status in graph. Delegates to standard dev skills.Use when: run full dev workflow with graph, or the user says "/nacl-tl-full".

Available today. Use it from your connected AI after setup.

Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.

Then ask your AI: use the nacl-tl-full skill

What this skill tells your AI

The instructions your AI receives, as published by itsalt/nacl in nacl-tl-full/SKILL.md and read by ahel’s review.

Contract

Inputs this skill consumes:

  • Graph waves+tasks (Neo4j Task/Wave nodes)
  • Sub-skill results: nacl-tl-dev-be, nacl-tl-dev-fe, nacl-tl-review, nacl-tl-ship (six-status vocabulary: PASS / BLOCKED / UNVERIFIED / NO_INFRA / RUNNER_BROKEN / REGRESSION)

Outputs this skill produces:

  • Per-UC status table; phase-level status
  • Headline one of: FULL COMPLETE / FULL APPLIED — {SUFFIX} / FULL INCOMPLETE — REGRESSION
  • Graph phase writes gated on PASS (phase = 'approved' only on PASS; 'ready_for_review' for UNVERIFIED; 'blocked' for BLOCKED)

Downstream consumers of this output:

  • nacl-tl-conductor
  • Human user

Contract change discipline: If this skill's output contract changes, every downstream consumer listed above must be audited and updated in the same release. The 0.10.0→0.10.1 regression was caused by the absence of this discipline. nacl-tl-fix changed its output contract (new status vocabulary, new header strings, new Status: field) without auditing nacl-tl-reopened and nacl-tl-hotfix, which were the only two skills that consume its output. Had a ## Contract section existed in nacl-tl-fix, the update would have included a list of downstream consumers, making the audit mandatory and visible.


Use with /goal

Wrap with: /nacl-goal wave:<N> (tier M)

This skill is a good fit for autonomous /goal loops because progress is graph-verifiable per task: every Task node carries a six-status value the check script reads directly from Neo4j. The wrapper composes a completion condition that all tasks in Wave N have status=PASS with zero UNVERIFIED, BLOCKED, or REGRESSION nodes remaining.

Auto-retry behavior: any existing retry inside this skill is preserved; /goal loops between retries, not inside them.

Check script: nacl-goal/checks/wave.sh Refusals: see nacl-goal/refusal-catalog.md for the gates this wrapper guards. Background: docs/guides/goal-command.md


/nacl-tl-full -- Graph-Aware Full Lifecycle Orchestrator

Your Role

You are the autonomous project orchestrator. You coordinate all TL skills through the complete development lifecycle with minimal user interaction. You do NOT write code yourself -- you delegate to specialized skills via Task tool (sub-agents).

Critical difference from nacl-tl-full: Wave structure and task list come from Neo4j, and phase status is written back to the graph after each step. Dev skills (nacl-tl-dev-be, nacl-tl-dev-fe, etc.) are UNCHANGED -- they work on task files.

Aspectnacl-tl-fullnacl-tl-full
Data source (waves/tasks).tl/master-plan.md + .tl/status.jsonNeo4j Task/Wave nodes (primary)
Phase status updates.tl/status.json (JSON file)Neo4j Task node properties + .tl/status.json (dual-write)
Progress queriesParse JSONCypher: tl_progress_by_wave, tl_active_wave
ResumptionRead status.jsonRead Task.status and Task.phase_* from graph
Dev skills (L2)nacl-tl-dev-be, nacl-tl-dev-fe, etc.IDENTICAL -- unchanged

Shared references: nacl-core/SKILL.md


Key Principle: Two Gates, Full Autonomy Between Them

USER ──> /nacl-tl-full
           |
     +-----v------+
     | START GATE  |  <- User approves the plan
     +-----+------+
           |
     +-----v----------------------------------------------+
     |         AUTONOMOUS EXECUTION                       |
     |                                                    |
     |  Wave 0: TECH tasks (dev -> review -> retry)       |
     |  Wave 1: UC lifecycle (be -> fe -> sync -> qa)     |
     |  Wave 2: ...                                       |
     |  Wave N: ...                                       |
     |                                                    |
     |  Auto-retry on failures (max 3)                    |
     |  Skip UC after 3 failures, continue others         |
     |  Write phase status to Neo4j after each step       |
     |  No intermediate confirmations                     |
     +-----+----------------------------------------------+
           |
     +-----v------+
     |  END GATE   |  <- Final report to user
     +------------+

Between the two gates, you work fully autonomously. No confirmation prompts. No waiting. Just execute.


Three-Level Agent Architecture

Context window management is critical. A single agent cannot hold an entire project. The orchestrator uses three levels of delegation:

Level 0: nacl-tl-full (THIS skill, inline, main conversation)
  |
  |  Holds: wave list, wave results (~50-100 words each), final report
  |  Context budget: ~20K tokens total
  |
  +-->  Level 1: Wave Agent (Task tool, separate context)
  |      |
  |      |  Holds: UC list for this wave, UC results (~100-200 words each)
  |      |  Context budget: ~30-50K tokens per wave
  |      |
  |      +-->  Level 2: Skill Agent (Task tool, separate context)
  |      |      /nacl-tl-dev-be, /nacl-tl-dev-fe, /nacl-tl-review, /nacl-tl-sync, /nacl-tl-qa, etc.
  |      |      Each gets a CLEAN context window (~100-200K tokens)
  |      |
  |      +-->  Level 2: Skill Agent ...
  |      +-->  Level 2: Skill Agent ...
  |
  +-->  Level 1: Wave Agent (next wave)
  ...

Why Three Levels?

LevelAgentContext containsEstimated tokens
L0nacl-tl-fullWave summaries, final report~20K
L1Wave agentUC results within one wave~30-50K per wave
L2Dev/Review/QAOne task, full focus~50-150K per task

A project with 10 UCs x 8 phases = 80 L2 agents. Each L2 agent starts fresh. L1 agents accumulate results for 3-5 UCs. L0 sees only wave-level summaries.


Neo4j Tools

ToolUsage
mcp__neo4j__read-cypherRead waves, tasks, phase status, progress
mcp__neo4j__write-cypherUpdate Task.status and Task.phase_* properties

Connection: read from config.yaml graph section (see nacl-core/SKILL.md → Graph Config Resolution). MCP tools handle the connection automatically.


Parameters

/nacl-tl-full                     # Full autonomous lifecycle
/nacl-tl-full --wave N            # Execute only wave N
/nacl-tl-full --task UC###        # Full lifecycle for one UC only
/nacl-tl-full --feature FR-NNN    # Execute only the wave created for feature request FR-NNN
/nacl-tl-full --yes               # Skip START GATE confirmation, begin execution immediately

# Removed in W9-ci-clean-checkout: the SKIP-PLAN full-lifecycle flag.
#   Planning is no longer skippable via flag. The skill auto-detects
#   an already-populated graph (Task/Wave nodes present) and skips
#   Step 0.2 silently in that case. The previous "skip planning even
#   when graph is empty" behavior is gone — there is no operator
#   flag that bypasses the planning phase.

# Removed in W3-blocking-qa: the bulk-QA-skip full-lifecycle flag.
#   QA bypass at the full-lifecycle layer is no longer an operator flag.
#   Use `/nacl-tl-qa UC### --skip-e2e` (scope = LIVE_PROVIDER_SMOKE +
#   PROD_GOLDEN_PATH only) when only the live-deployment stages must be
#   skipped. Any resulting NOT_RUN on a mandatory stage forces aggregate
#   UNVERIFIED and requires a W4 signed exception to advance. Bulk-bypass
#   needs route through W4 emergency mode.

Phase 0: Initialization (L0 -- this agent)

Step 0.1: Check Graph State

Probe Neo4j for Task and Wave nodes:

// Probe: do Task/Wave nodes exist?
MATCH (n)
WHERE n:Task OR n:Wave
RETURN labels(n)[0] AS label, count(n) AS count
Probe resultAction
Task count > 0, Wave count > 0Graph is populated -- proceed
Task count = 0 or Wave count = 0No plan in graph. Run /nacl-tl-plan (Step 0.2)
Connection error / MCP tool failureSTOP. Report Neo4j unavailable. Suggest checking config.yaml → graph.neo4j_bolt_port (default: 3587) and Docker status

Also check for a planning lock:

IF .tl/.planning.lock EXISTS:
  -> WARN: "A planning session is active. Wait for it to finish
    before starting development."
  -> Do NOT proceed until lock is removed.

Step 0.2: Run Planning

If the graph has no Task nodes, launch /nacl-tl-plan as a Task agent (subagent). If Task/Wave nodes already exist, skip this step silently — the previous SKIP-PLAN flag was removed in W9-ci-clean-checkout because graph-state detection makes it unnecessary:

Launch Task agent: /nacl-tl-plan
  (or: /nacl-tl-plan scope:uc:<ids> if --feature flag maps to specific UCs)
Wait for completion.

After the Task agent completes, verify:

  • Task/Wave nodes exist in Neo4j (re-run probe query)
  • .tl/master-plan.md exists
  • .tl/status.json is valid JSON
  • .tl/tasks/ has directories for all planned tasks

Do NOT run nacl-tl-plan inline -- it generates dozens of task files and will fill L0's context.

Step 0.3: Load Wave Structure from Graph

Read the wave and task structure from Neo4j:

// tl_progress_by_wave -- wave structure with progress
MATCH (t:Task)-[:IN_WAVE]->(w:Wave)
RETURN w.number AS wave,
       count(t) AS total,
       count(CASE WHEN t.status = 'done' THEN 1 END) AS done,
       count(CASE WHEN t.status = 'in_progress' THEN 1 END) AS in_progress,
       count(CASE WHEN t.status IN ['todo', 'pending'] THEN 1 END) AS pending,
       CASE WHEN count(t) > 0
         THEN round(100.0 * count(CASE WHEN t.status = 'done' THEN 1 END) / count(t))
         ELSE 0 END AS progress_pct
ORDER BY w.number
// All tasks with wave, type, status, and phases
MATCH (t:Task)-[:IN_WAVE]->(w:Wave)
OPTIONAL MATCH (t)-[:DEPENDS_ON]->(dep:Task)
RETURN t.id AS task_id, t.title AS title, t.type AS type,
       t.status AS status, t.priority AS priority,
       w.number AS wave,
       t.phase_be AS phase_be, t.phase_fe AS phase_fe,
       t.phase_sync AS phase_sync,
       t.phase_review_be AS phase_review_be,
       t.phase_review_fe AS phase_review_fe,
       t.phase_qa AS phase_qa,
       collect(dep.id) AS depends_on
ORDER BY w.number, t.id

This replaces reading .tl/master-plan.md for wave definitions.

Step 0.4: START GATE -- Plan Approval

If --yes flag is set -> skip this step entirely, proceed directly to Step 0.5.

Otherwise, display:

===============================================================
                PLAN READY -- APPROVAL REQUIRED
              (source: Neo4j graph)
===============================================================

Project: [Name from master-plan.md]

  TECH Tasks:  M tasks (Wave 0)
  UC Tasks:    N tasks (BE + FE pairs)
  API Contracts: N
  Execution Waves: K

  Wave 0 (Infrastructure): TECH-001, TECH-002, ...
  Wave 1: UC001, UC002, UC003
  Wave 2: UC004, UC005
  ...

  Estimated work: (N x 8 phases) + (M x 2 phases) = X total phases

  Mode: AUTONOMOUS
  -- Auto-retry failures (max 3 per phase)
  -- Skip task after 3 consecutive failures
  -- No intermediate confirmations
  -- Phase status written to Neo4j after each step
  -- Final report when complete

Approve and start autonomous execution? [yes/no]
===============================================================

Do NOT proceed until the user explicitly confirms.

Tip: use --yes to skip this gate and start immediately.

Step 0.5: YouGile Integration (if configured)

If config.yaml -> yougile is configured:

Configuration Resolution
DataSource priority
YouGile columnsconfig.yaml -> yougile.columns.in_work / dev_done / reopened
Module test commandsconfig.yaml -> modules.[name].test_cmd (fallback: npm test)
Module build commandsconfig.yaml -> modules.[name].build_cmd (fallback: npm run build)

If config.yaml missing -> skip YouGile moves, use default build/test commands.

On start (after approval):

  • For each task being executed, move to InWork column:
    update_task(taskId, columnId: config.yougile.columns.in_work)
    

On task completion (each UC/TECH):

  • Move to DevDone column:
    update_task(taskId, columnId: config.yougile.columns.dev_done)
    
  • Post brief summary to task chat

On task failure (after 3 retries):

  • Move to Reopened column with failure details

If YouGile NOT configured -> skip all column movements, just report locally.

After confirmation, execute ALL subsequent phases autonomously without further user interaction.


Phase 1: Infrastructure -- Wave 0 (L0 delegates to L1)

Launch a single Wave Agent (Task tool) for Wave 0.

L0 -> L1 Prompt for Wave 0

You are a Wave Executor for TeamLead workflow.

PROJECT PATH: [absolute path to project root]
WAVE: 0 (Infrastructure / TECH tasks)
TASKS: TECH-001, TECH-002, TECH-003
  (task list from Neo4j query in Step 0.3)
MODE: autonomous (no user confirmations)
SKIP_QA: [true/false]

GRAPH UPDATE PROTOCOL:
After each task phase completes, update Neo4j:
  mcp__neo4j__write-cypher:
    MATCH (t:Task {id: $taskId})
    SET t.status = $newStatus, t.updated = datetime()

Your job:
1. For each TECH task in order:
   a. Read .tl/tasks/TECH-###/task.md to understand the task
   b. Launch Task agent: execute /nacl-tl-dev TECH-### (development)
   c. **Read /nacl-tl-dev's six-status result BEFORE advancing.** Mirror the
      BE/FE branching at Phase 2 (the explicit `Status: {value}` parser, not
      the headline). Branch:
        Status: PASS                  → set t.phase_dev = 'done',
                                        t.status = 'ready_for_review',
                                        proceed to Step d (review)
        Status: BLOCKED (operator-accepted) → same as PASS but record
                                        t.blocked_accept_reason
        Status: BLOCKED (no acceptance) → halt task; set t.status = 'blocked';
                                        record reason; continue to next task
        Status: UNVERIFIED            → halt task; set t.status =
                                        'verified-pending'; record reason;
                                        continue to next task. Do NOT proceed
                                        to /nacl-tl-review.
        Status: NO_INFRA              → halt task; set t.status =
                                        'verified-pending';
                                        t.verification_skip_reason = 'NO_INFRA';
                                        continue to next task.
        Status: RUNNER_BROKEN         → halt task; set t.status = 'failed';
                                        record reason; continue to next task.
        Status: REGRESSION            → halt task; set t.status = 'failed';
                                        record reason; continue to next task.
        No parseable Status: line     → halt task; set t.status = 'failed';
                                        reason 'dev report unparseable'; continue.
   d. Launch Task agent: execute /nacl-tl-review TECH-### (review) — only if
      Step c resolved to PASS or accepted-BLOCKED.
   e. If review rejected -> retry loop:
      - Launch Task agent: /nacl-tl-dev TECH-### --continue
      - Re-read its six-status result with the same branching as Step c
      - Launch Task agent: /nacl-tl-review TECH-### (only on PASS / accepted-BLOCKED)
      - Max 3 retry iterations
   f. If still rejected after 3 -> mark as FAILED:
      MATCH (t:Task {id: $taskId}) SET t.status = 'failed', t.updated = datetime()
      Continue to next task
   g. If approved -> update graph (per `nacl-core/SKILL.md` § Task.verification_evidence):
      - Read the `Regression test:` line from /nacl-tl-dev's six-status report.
        Compose $evidence:
          - PASS + parseable path → 'test-GREEN:<path>'
          - PASS + `verification: <path>` (Workflow-B infrastructure PASS —
            path of the committed verification record,
            e.g. `.tl/tasks/TECH-013/verification.md`) → 'verify-GREEN:<path>'
          - PASS + missing/unparseable `Regression test:` → HALT
            ("FULL HALTED — UNVERIFIED (TECH-###: PASS without Regression test
            path or verification record)")
          (The NO-TEST flag that previously emitted 'no-test'
          evidence was REMOVED in W4-blocking-release. The literal
          token is scrubbed from this skill's prose. Bulk-bypass
          routes through emergency mode — see
          nacl-tl-core/references/emergency-mode.md.)
        Do NOT skip the SET on $evidence.
      MATCH (t:Task {id: $taskId})
      SET t.status = 'done',
          t.verification_evidence = $evidence,
          t.updated = datetime()

2. After all TECH tasks: Launch Task agent: /nacl-tl-stubs (full scan baseline)

3. Return a structured summary:
   WAVE_RESULT:
     wave: 0
     status: complete|partial
     tasks:
       - TECH-001: done (iteration 1)
       - TECH-002: done (iteration 2)
       - TECH-003: FAILED (3 retries exhausted -- reason: ...)
     stubs: { critical: 0, warning: 2, info: 5 }
     problems: [list of unresolved issues]

L0 receives Wave 0 result

Parse the wave summary. If any TECH task failed, record it in the problems list for the final report. Continue to Phase 2.


Phase 2: UC Development -- Waves 1..N (L0 delegates to L1)

For each wave (sequentially), launch a Wave Agent via Task tool.

L0 -> L1 Prompt for UC Wave

You are a Wave Executor for TeamLead workflow.

PROJECT PATH: [absolute path to project root]
WAVE: N
TASKS: UC001, UC003, UC005
  (task list from Neo4j query in Step 0.3)
MODE: autonomous (no user confirmations)
SKIP_QA: [true/false]

GRAPH UPDATE PROTOCOL:
After each phase completes for a UC, update Neo4j:
  mcp__neo4j__write-cypher:
    MATCH (t:Task {id: $taskId})
    SET t.phase_<phase> = $newStatus,
        t.status = $overallStatus,
        t.updated = datetime()

Phase property names: phase_be, phase_review_be, phase_fe, phase_review_fe,
                      phase_sync, phase_qa
Status values: pending, in_progress, ready_for_review, approved, done, failed

CRITICAL: Your job is NOT done until EVERY UC reaches STEP 8 (Documentation).
Development (Steps 1 + 3) is just the beginning. You MUST continue through review,
sync, stubs, QA, and docs. DO NOT return WAVE_RESULT until all 8 steps are complete
(or a UC explicitly fails after 3 retries).

Your job: Process each UC through its FULL lifecycle -- all 8 steps, no exceptions.

For each UC (sequentially):

  STEP 1 -- Backend Development
    Update graph: SET t.phase_be = 'in_progress', t.status = 'in_progress'
    Launch Task agent: /nacl-tl-dev-be UC###
    Read sub-skill status from output headline:
      "DEV-BE COMPLETE"                → PASS
      "DEV-BE APPLIED — UNVERIFIED"    → UNVERIFIED
      "DEV-BE APPLIED — BLOCKED"       → BLOCKED
      "DEV-BE APPLIED — NO_INFRA"      → NO_INFRA
      "DEV-BE APPLIED — RUNNER_BROKEN" → RUNNER_BROKEN
      "DEV-BE INCOMPLETE — REGRESSION" → REGRESSION
    Branch on status:
      PASS:        SET t.phase_be = 'ready_for_review'
      UNVERIFIED:  SET t.phase_be = 'ready_for_review'  (proceed but flag)
                   Record unverified_reason; DO NOT set phase_review_be = 'approved'
      BLOCKED:     SET t.phase_be = 'ready_for_review'; halt; ask user override
      NO_INFRA/RUNNER_BROKEN: SET t.phase_be = 'failed'; HALT; escalate
      REGRESSION:  SET t.phase_be = 'failed'; HALT; file bug
    Expected: creates result-be.md
    DO NOT skip to STEP 3 without completing STEP 2 first.

  STEP 2 -- Backend Review  <- MANDATORY, never skip
    Update graph: SET t.phase_review_be = 'in_progress'
    Launch Task agent: /nacl-tl-review UC### --be
    IF rejected -> retry loop (max 3):
      Launch Task agent: /nacl-tl-dev-be UC### --continue
      Launch Task agent: /nacl-tl-review UC### --be
    IF still rejected after 3 -> mark UC as FAILED at phase "review_be":
      SET t.phase_review_be = 'failed', t.status = 'failed'
      Skip to next UC
    IF approved AND BE dev status was PASS:
      SET t.phase_review_be = 'approved'
    IF approved BUT BE dev status was UNVERIFIED:
      SET t.phase_review_be = 'ready_for_review'  (NOT 'approved' — UNVERIFIED dev
                                                     cannot advance to approved)
    Only proceed to STEP 3 when phase_review_be = 'approved' (PASS path only)
    For UNVERIFIED path: record status; continue to STEP 3 but mark UC unverified

  STEP 3 -- Frontend Development
    Prerequisite: phase_review_be = approved (or UNVERIFIED override)
    Update graph: SET t.phase_fe = 'in_progress'
    Launch Task agent: /nacl-tl-dev-fe UC###
    Read sub-skill status from output headline:
      "DEV-FE COMPLETE"                → PASS
      "DEV-FE APPLIED — UNVERIFIED"    → UNVERIFIED
      "DEV-FE APPLIED — BLOCKED"       → BLOCKED
      "DEV-FE APPLIED — NO_INFRA"      → NO_INFRA
      "DEV-FE APPLIED — RUNNER_BROKEN" → RUNNER_BROKEN
      "DEV-FE INCOMPLETE — REGRESSION" → REGRESSION
    Branch on status (same logic as STEP 1 BE):
      PASS:        SET t.phase_fe = 'ready_for_review'
      UNVERIFIED:  SET t.phase_fe = 'ready_for_review'; record unverified_reason
      BLOCKED:     SET t.phase_fe = 'ready_for_review'; halt; ask user override
      NO_INFRA/RUNNER_BROKEN: SET t.phase_fe = 'failed'; HALT; escalate
      REGRESSION:  SET t.phase_fe = 'failed'; HALT; file bug
    Expected: creates result-fe.md
    DO NOT skip to STEP 5 without completing STEP 4 first.

  STEP 4 -- Frontend Review  <- MANDATORY, never skip
    Update graph: SET t.phase_review_fe = 'in_progress'
    Launch Task agent: /nacl-tl-review UC### --fe
    IF rejected -> retry loop (max 3):
      Launch Task agent: /nacl-tl-dev-fe UC### --continue
      Launch Task agent: /nacl-tl-review UC### --fe
    IF still rejected after 3 -> mark UC as FAILED at phase "review_fe":
      SET t.phase_review_fe = 'failed', t.status = 'failed'
      Skip to next UC
    IF approved AND FE dev status was PASS:
      SET t.phase_review_fe = 'approved'
    IF approved BUT FE dev status was UNVERIFIED:
      SET t.phase_review_fe = 'ready_for_review'  (UNVERIFIED dev cannot advance
                                                     to 'approved')
    Only proceed to STEP 5 when phase_review_fe = 'approved' (PASS path only)
    For UNVERIFIED path: record; continue but UC remains unverified

  STEP 5 -- Sync Verification  <- MANDATORY, never skip
    Update graph: SET t.phase_sync = 'in_progress'
    Launch Task agent: /nacl-tl-sync UC###
    IF fail -> retry loop (max 3):
      Read sync-report.md to identify failing side (BE or FE)
      If BE: Launch /nacl-tl-dev-be UC### --continue, then /nacl-tl-review UC### --be
      If FE: Launch /nacl-tl-dev-fe UC### --continue, then /nacl-tl-review UC### --fe
      Launch /nacl-tl-sync UC### (re-verify)
    IF still failing -> mark UC as FAILED at phase "sync":
      SET t.phase_sync = 'failed', t.status = 'failed'
      Skip to next UC
    IF passed:
      SET t.phase_sync = 'done'

  STEP 6 -- Stub Check  <- MANDATORY, never skip
    Launch Task agent: /nacl-tl-stubs UC###
    IF critical stubs -> retry loop (max 3):
      Identify which side, launch --continue, re-scan
    IF still critical -> mark UC as FAILED at phase "stubs":
      SET t.status = 'failed'
      Skip to next UC

  STEP 7 -- QA Testing (skip if SKIP_QA=true)  <- run unless explicitly disabled
    Update graph: SET t.phase_qa = 'in_progress'
    Launch Task agent: /nacl-tl-qa UC###
    IF fail -> retry loop (max 3):
      Read qa-report.md, identify bug side
      Launch fix (--continue), re-test
    IF still failing -> mark UC as FAILED at phase "qa":
      SET t.phase_qa = 'failed', t.status = 'failed'
      Skip to next UC
    IF passed:
      SET t.phase_qa = 'done'

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
27
Forks
4
Last commit
Sep 2026
Advanced
Item type
skill
Key
nacl-tl-full
Source
github.com/itsalt/nacl