From nacl
Monitor CI/CD deployment (GitHub Actions), run health checks, update YouGile. Deployment is triggered by git push (nacl-tl-ship), this skill monitors the result. Use when: deploy, check deploy status, verify deployment, or the user says "/nacl:tl-deploy".
How this skill is triggered — by the user, by Claude, or both
Slash command
/nacl:tl-deploysonnetThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Inputs this skill consumes:**
Inputs this skill consumes:
Outputs this skill produces:
Downstream consumers of this output:
nacl-tl-deliver (staging) — reads: headline, per-task verification-status tablenacl-tl-release (production) — reads: headline, per-task verification-status tablenacl-tl-conductor — reads: headline to decide next orchestration phasenacl-tl-hotfix — reads: headline to decide whether a hotfix deploy passedField schema each downstream consumer requires:
Headline: DEPLOY COMPLETE
DEPLOY HALTED — REGRESSION
DEPLOY HALTED — NO_INFRA
DEPLOY HALTED — RUNNER_BROKEN
DEPLOY HALTED — UNVERIFIED
DEPLOY HALTED — BLOCKED (clean-checkout-artifact-missing)
DEPLOY HALTED — BLOCKED (clean-checkout-commit-mismatch)
DEPLOY HALTED — BLOCKED (clean-checkout-<blocker_detail>)
DEPLOY INCOMPLETE — UNVERIFIED (health probe timeout)
DEPLOY HALTED — NO_INFRA (health contract undefined)
Per-task status table (one row per deployed SHA):
SHA | source-task | source-verification-status | CI-status | health-status
Health-status values: PASS | FAIL | TIMEOUT | SKIPPED
CI-status values: PASS | FAIL | SKIPPED
source-verification-status: done (PASS) | verified-pending (UNVERIFIED) | blocked | failed | not-found
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.
You monitor deployments triggered by CI/CD pipelines (GitHub Actions) and verify they succeed. You do NOT trigger deploys directly — that happens via git push in /nacl:tl-ship. You watch the CI/CD pipeline, run health checks, and update YouGile.
Deploy is triggered by push (nacl-tl-ship does this).
This skill MONITORS the result and verifies health.
If health check fails → alert + suggest rollback.
/nacl:tl-deploy --staging # monitor staging deploy (feature branch push)
/nacl:tl-deploy --production # monitor production deploy (main branch push)
/nacl:tl-deploy --watch # watch currently running pipeline/workflow
| Data | Source priority |
|---|---|
| Staging URL | config.yaml → deploy.staging.url |
| Production URL | config.yaml → deploy.production.url |
| Health endpoint | config.yaml → deploy.[env].health_endpoint (fallback: /api/health) |
| YouGile done column | config.yaml → yougile.columns.done |
| VPS staging | config.yaml → vps.staging (ip, user, ssh_key) — SSH-диагностика при сбое health-check |
| VPS production | config.yaml → vps.production (ip, user, ssh_key) — аналогично |
| Clean-checkout artifact | .tl/clean-checkout/<commit>.json — produced by nacl-tl-deliver Step 4b. Required for every deploy (W9). Absent / mismatch / BLOCKED without exception → DEPLOY HALTED — BLOCKED (clean-checkout-*). |
If deploy section missing → error (cannot monitor deployment without URL). If YouGile missing → skip task moves, report locally.
Detect CI/CD platform from the project:
config.yaml → deploy.ci_platform (if set, use it).github/workflows/ directory → GitHub Actions (use gh)| Platform | CLI | List runs | Watch run | View logs |
|---|---|---|---|---|
| GitHub Actions | gh | gh run list | gh run watch | gh run view --log-failed |
Pre-monitor clean-checkout artifact gate (W9-ci-clean-checkout):
Before evaluating the upstream verification gate (0a), confirm that a clean-checkout evidence artifact exists for the commit being deployed.
commit = the SHA selected by Step 0 / Step 1.1
artifact = .tl/clean-checkout/<commit>.json (in the repo root
of the deploying workspace)
| Artifact state | Deploy action |
|---|---|
Present, terminal_status: PASS, commit field matches the deployed SHA | Proceed to step 0a (upstream verification). |
Present, commit field DOES NOT match the deployed SHA | HALT: DEPLOY HALTED — BLOCKED (clean-checkout-commit-mismatch). The wave-tip evidence is for a different commit; deploy refuses to ship a commit that was never clean-checkout-verified. |
Present, terminal_status: BLOCKED, no signed exception covering the named blocker_detail | HALT: DEPLOY HALTED — BLOCKED (clean-checkout-<blocker_detail>). |
Present, terminal_status: BLOCKED, signed exception covers blocker_detail | Proceed with a (clean-checkout-bypass) banner on the final report and an event in .tl/emergencies/ if the bypass route was emergency-mode (not exception). |
| Absent | HALT unconditionally: DEPLOY HALTED — BLOCKED (clean-checkout-artifact-missing). There is NO inline override flag. The operator must (a) re-run /nacl:tl-deliver (which produces the artifact in Step 4b) or (b) file a signed exception with affected_gates: [clean-checkout-artifact-missing] for a one-shot carve-out. |
The clean-checkout artifact is the gate-quality evidence that the
deployed commit was built + smoked from a fresh tree, not a warm
local cache. Without a matching artifact, deploy emits BLOCKED.
0a. Pre-monitor verification gate:
Before monitoring any pipeline, confirm the code being deployed came from tasks with verified development status. Read from graph or status.json:
// Find tasks associated with the commit SHA being deployed
MATCH (t:Task)
WHERE t.commit = $commitSha
RETURN t.id AS task_id, t.status AS status
Or read .tl/status.json and .tl/conductor-state.json to find tasks
associated with the branch/commit being deployed.
| Task status | Deploy action |
|---|---|
| done (PASS) | Proceed with deployment monitoring |
| verified-pending (UNVERIFIED) | HALT by default: DEPLOY HALTED — UNVERIFIED (upstream verified-pending). Operator override is permitted (explicit "yes" prompt; NOT auto-confirmed by --yes). On override → headline DEPLOY APPLIED — UNVERIFIED (operator override); Task.verification_skip_reason = 'deploy operator-override'; the source Task is NOT moved to done / released (Cross-cutting principle P4). |
| blocked | Same gate as UNVERIFIED. On override → DEPLOY APPLIED — UNVERIFIED (blocked, operator override); no source-task state movement. |
| failed / REGRESSION | HALT immediately: DEPLOY HALTED — REGRESSION. Do NOT proceed |
| Not found in graph | HALT unconditionally: DEPLOY HALTED — UNVERIFIED (upstream status unknown). The previous "Warn and proceed (backward-compat)" path is removed. The operator must populate the Task node (via the appropriate dev / fix / verify skill) and re-run; there is no override that promotes unknown to verified. |
config.yaml → deploy for target environment config${CLAUDE_PLUGIN_ROOT}/nacl-core/scripts/wait-for-ci.test.sh):
bash ${CLAUDE_PLUGIN_ROOT}/nacl-core/scripts/wait-for-ci.sh watch --branch {target_branch} --timeout "${ci_timeout:-600}"
# exit 0 → CI_OK | NO_CI (no `.github/workflows`) | NO_RUN ("no deployment in progress")
# exit 1 → CI_FAILED (the failed-log tail is already printed)
If wait-for-ci.sh exited non-zero (CI_FAILED):
gh run view --log-failed | tail -50).After pipeline succeeds:
config.yaml → deploy.[env].health_endpoint
(fallback: /api/health — allowed only if a health contract is also defined; see step 3 below)config.yaml → deploy.[env].urlconfig.yaml → deploy.[env].health_contract
health_contract must define at minimum: expected_keys (list of top-level response keys that must be present).expected_values (key→value pairs that must match exactly).health_contract is absent or empty → HALT immediately:
DEPLOY HALTED — NO_INFRA (health contract undefined)
Do NOT proceed. A 200 response with no shape contract is unverifiable.curl -s -w "\n%{http_code}" [url][health_endpoint].BODY=$(curl -s [url][health_endpoint])
# For each key in health_contract.expected_keys:
echo "$BODY" | jq --exit-status 'has("[key]")'
# For each entry in health_contract.expected_values:
echo "$BODY" | jq --exit-status '.[key] == [expected_value]'
expected_keys key is absent → FAIL shape validation.expected_values value mismatches → FAIL shape validation.version field from response body if present.config.yaml → vps.[env] is populated,
run SSH diagnostics before halting:
ssh -i {ssh_key} {user}@{ip}pm2 status or docker psjournalctl -u app --since '5m ago' or docker logs --since 5mdf -h, free -mThe report opens with a per-task status table. One row per deployed SHA. Per-task verification status is required in every report; this is the single source of truth that downstream readers consume.
Per-task status table (mandatory — include in every report):
| SHA | source-task | source-verification-status | CI-status | health-status |
|---------|-------------|---------------------------|-----------|---------------|
| abc1234 | UC-042 | done (PASS) | PASS | PASS |
| def5678 | TECH-007 | done (PASS) | PASS | PASS |
SHA: short commit hash (7 chars) being deployedsource-task: task ID from graph/status.json (or not-found if absent)source-verification-status: one of done (PASS) / verified-pending (UNVERIFIED) / blocked / failed / not-foundCI-status: PASS / FAIL / SKIPPEDhealth-status: PASS / FAIL / TIMEOUT / SKIPPEDFollowed by the aggregated headline on a line by itself:
Headline: DEPLOY COMPLETE
On success (pipeline passed AND health check passed):
Deployed to [staging/production]
URL: https://example.com
Health: 200 OK
Version: 1.2.3
Commit: abc1234
Time: 2m 15s
Next: /nacl:tl-release (for production deploys)
On pipeline failure (Step 2):
On health check failure (Step 3):
On pre-monitor gate halt (Step 1.0):
Without YouGile: Just report locally with headline.
GitHub Actions uses workflow files in .github/workflows/. Templates are in ${CLAUDE_PLUGIN_ROOT}/nacl-tl-core/templates/:
deploy-backend.yml — backend build + deploydeploy-frontend.yml — frontend build + deployThese are created during project setup by /nacl:tl-dev TECH-001 (infrastructure task) or by /nacl:init.
The templates are a Node/npm reference profile with unpinned versions. Before first use, fill ${NODE_VERSION} (and any image versions) from the project's own toolchain — config.yaml → modules.<m>.stack or the detected runtime — and replace ecosystem-specific steps if the project is not Node. NaCl never supplies a default version.
config.yaml → deploy section (URLs, health endpoints).tl/clean-checkout/<commit>.json — required clean-checkout evidence
artifact produced by nacl-tl-deliver Step 4b (W9). Schema:
.tl/clean-checkout/_template.json.nacl-tl-ship/SKILL.md — triggers the deploy via pushnacl-tl-deliver/SKILL.md § "Step 4b: CLEAN-CHECKOUT GATE" — the
upstream producer of the artifact this skill consumes.nacl-tl-release/SKILL.md — follows after successful production deploynpx claudepluginhub itsalt/nacl --plugin naclUse when code is ready to ship and you want a structured deployment with readiness checks and rollback criteria. Supports direct, canary, blue-green, and rolling strategies. Keywords: deploy, ship, release, rollout, canary, blue-green, rollback, production.
[ADD v0.11.0] Environment-aware commit, push, and deploy workflow
Deploys applications to Vercel, Netlify, AWS, GCP, DigitalOcean, and VPS with pre-deploy verification, security scans, health checks, and rollback support.