---
description: Full post-release runtime redeploy — syncs bare clones, updates Dockerfile plugin pins, rebuilds Docker runtime, seeds Infisical, and verifies health
mode: full
version: 1.0.0
level: advanced
debug: false
category: workflow
tags: [deploy, runtime, docker, infisical, post-release]
author: OmniClaude Team
composable: false
inputs:
  - name: versions
    type: str
    description: "Comma-separated plugin version pins: omniintelligence=0.8.0,omninode-claude=0.4.0,omninode-memory=0.6.1. If omitted, auto-detected from the latest git tags in bare clones."
    required: false
  - name: skip_sync
    type: bool
    description: Skip SYNC phase (bare clones already current)
    required: false
  - name: skip_dockerfile_update
    type: bool
    description: Skip PIN_UPDATE phase
    required: false
  - name: skip_infisical
    type: bool
    description: Skip INFISICAL phase unconditionally
    required: false
  - name: worktree_ticket
    type: str
    description: "Worktree name prefix (default: redeploy-<run_id>)"
    required: false
  - name: verify_only
    type: bool
    description: Skip to VERIFY phase only (assumes runtime already running)
    required: false
  - name: dry_run
    type: bool
    description: Print step commands without execution
    required: false
  - name: resume
    type: str
    description: Resume from first non-completed phase in state file by run_id
    required: false
outputs:
  - name: skill_result
    type: ModelSkillResult
    description: "Written to $ONEX_STATE_DIR/skill-results/{context_id}/redeploy.json"
    fields:
      - status: success | failed | dry_run
      - run_id: str
      - phases: "dict[str, phase_status]"
      - pins_applied: "dict[str, str] | null"
args:
  - name: --versions
    description: "Comma-separated plugin pins: pkg=version,pkg2=version2. If omitted, auto-detected from latest git tags."
    required: false
  - name: --skip-sync
    description: Skip SYNC phase
    required: false
  - name: --skip-dockerfile-update
    description: Skip PIN_UPDATE phase
    required: false
  - name: --skip-infisical
    description: Skip INFISICAL phase unconditionally
    required: false
  - name: --worktree-ticket
    description: "Worktree name prefix (default: redeploy-<run_id>)"
    required: false
  - name: --verify-only
    description: Skip all phases except VERIFY
    required: false
  - name: --dry-run
    description: Print step commands, no execution
    required: false
  - name: --resume
    description: Resume from state file by run_id
    required: false
---

# Redeploy

## Dispatch Surface

**Target**: Headless claude -p

## Overview

Full post-release runtime redeploy for the OmniNode platform. Runs after a coordinated
release to sync all bare clones, update `Dockerfile.runtime` plugin pins, rebuild and
restart Docker runtime services, optionally seed Infisical with new contract keys,
and verify that health endpoints and pinned package versions match expectations.

**Announce at start:** "I'm using the redeploy skill to redeploy the runtime."

## Quick Start

```
/redeploy                                          # auto-detect latest versions from git tags
/redeploy --versions "omniintelligence=0.8.0,omninode-claude=0.4.0,omninode-memory=0.6.1"
/redeploy --versions "omniintelligence=0.8.0" --skip-sync --dry-run
/redeploy --verify-only --versions "omniintelligence=0.8.0,omninode-claude=0.4.0,omninode-memory=0.6.1"
/redeploy --resume redeploy-20260301-abc123
```

## Phase Sequence

| # | Phase | Core Action | Idempotency |
|---|-------|-------------|-------------|
| 0 | `PREFLIGHT` | `preflight-check.sh` — env var gate, bus tunnel, VirtioFS check | Read-only; exit 1 halts pipeline, exit 2 advisory |
| 1 | `SYNC` | `pull-all.sh` — fast-forward all bare clones on `main` | Safe: ff-only is a no-op if already current |
| 2 | `ENV_CHECK` | Per-phase env validation | Read-only, always safe |
| 3 | `WORKTREE` | Create `omni_worktrees/<ticket>/omnibase_infra` from main HEAD | Skip if path exists and branch matches |
| 4 | `PIN_UPDATE` | Run `update-plugin-pins.py` to rewrite `Dockerfile.runtime` version pins | Skip if already at target versions |
| 5 | `DEPLOY` | `deploy-runtime.sh --execute --restart` from worktree | Safe: rsync + rebuild + `--force-recreate` |
| 5b | `SCHEMA_SYNC` | `check_schema_fingerprint.py verify` — auto-stamp if stale | Idempotent: verify-then-stamp pattern |
| 6 | `INFISICAL` | Seed new contract keys to Infisical | `seed-infisical.py` is idempotent |
| 7 | `VERIFY` | Container manifest check via `verify_container_manifest.py` (`docker ps -a`) + curl health endpoints + in-container version checks. Restart-once policy for non-running containers. Profile-aware (core/runtime/memory). | Read-only (except restart-once recovery attempt), always safe |
| 7b | `K8S_VERIFY` | `k8s-pod-readiness-check.sh` — SSM-based cloud k8s pod READY gate | Read-only; exit 2 advisory when SSM unreachable |
| 7c | `OMNIDASH_VERIFY` | `verify-omnidash-health.sh` — >= 3 live data sources at localhost:3000 | Read-only; exit 2 advisory when omnidash offline |
| 8 | `NOTIFY` | Slack via `node_slack_alerter_effect` (FULL_ONEX only) | Idempotent (run_id in message) |

## ENV_CHECK: Required Variables per Phase

| Phase Gated | Required Vars | On Failure |
|-------------|--------------|------------|
| SYNC | `OMNI_HOME` (default: `/Volumes/PRO-G40/Code/omni_home`) | Fail with message | <!-- local-path-ok -->
| DEPLOY | `POSTGRES_PASSWORD`, `KAFKA_BOOTSTRAP_SERVERS` | Fail before deploy |
| INFISICAL | `INFISICAL_ADDR`, `INFISICAL_CLIENT_ID`, `INFISICAL_CLIENT_SECRET` | Skip if `INFISICAL_ADDR` unset; fail if set but creds missing |

## Tier-Aware Notifications

| Tier | Notification |
|------|-------------|
| `FULL_ONEX` | Slack via `node_slack_alerter_effect` (start + done) |
| `EVENT_BUS` | stdout only (no Kafka notification topic) |
| `STANDALONE` | stdout only |

Tier detection: see `@_lib/tier-routing/helpers.md`.

## State File

`$ONEX_STATE_DIR/state/redeploy/<run_id>.json` — written atomically after each phase completes.

```json
{
  "run_id": "redeploy-20260301-abc123",
  "worktree_path": "/Volumes/PRO-G40/Code/omni_worktrees/redeploy-20260301-abc123/omnibase_infra", // local-path-ok
  "worktree_ref": "main",
  "versions_requested": {"omniintelligence": "0.8.0", "omninode-claude": "0.4.0"},
  "phases": {
    "PREFLIGHT":       {"status": "completed", "ts": "2026-03-01T09:59:58Z"},
    "SYNC":            {"status": "completed", "ts": "2026-03-01T10:00:00Z"},
    "ENV_CHECK":       {"status": "completed", "ts": "2026-03-01T10:00:01Z"},
    "WORKTREE":        {"status": "completed", "ts": "2026-03-01T10:00:05Z", "path": "..."},
    "PIN_UPDATE":      {"status": "completed", "ts": "2026-03-01T10:00:10Z", "pins_applied": {"omniintelligence": "0.8.0"}},
    "DEPLOY":          {"status": "pending"},
    "SCHEMA_SYNC":     {"status": "pending"},
    "INFISICAL":       {"status": "pending"},
    "VERIFY":          {"status": "pending"},
    "K8S_VERIFY":      {"status": "pending"},
    "OMNIDASH_VERIFY": {"status": "pending"},
    "NOTIFY":          {"status": "pending"}
  }
}
```

Resume: `--resume <run_id>` skips all phases with `status: completed`.
Cleanup: worktree is retained; pass `--cleanup` (v2) to remove after success.

## VERIFY Phase Details

Beyond `curl /health`, runs the standalone version verification script (OMN-5608):

```bash
uv run python scripts/verify_deployed_versions.py \
    --versions "omniintelligence=0.8.0,omninode-claude=0.4.0,omninode-memory=0.6.1" \
    --container omninode-runtime
```

The script (`omnibase_infra/scripts/verify_deployed_versions.py`) queries each package
version inside the container via `docker exec ... uv pip show`, compares actual vs expected,
and exits with clear status codes:
- Exit 0: all versions match
- Exit 1: version mismatch detected (fail-fast with expected vs actual in output)
- Exit 2: infrastructure error (container unreachable)

Unit tests: `omnibase_infra/tests/unit/test_verify_deployed_versions.py` (21 tests covering
mismatch detection, infra errors, CLI exit codes, and report formatting).

## INFISICAL Phase Logic

```
IF INFISICAL_ADDR unset -> status: skipped_no_infisical (not an error)
IF INFISICAL_ADDR set AND creds missing -> fail before DEPLOY (validated in ENV_CHECK)
IF INFISICAL_ADDR set AND creds present:
  IF sync-omnibase-env.sh exists in worktree -> run it (dapper-soaring-falcon wrapper)
  ELSE -> uv run python seed-infisical.py --contracts-dir .../nodes --execute
```

## Skill Result Output

Written to `$ONEX_STATE_DIR/skill-results/{context_id}/redeploy.json`:

```json
{
  "skill": "redeploy",
  "status": "success",
  "run_id": "redeploy-20260301-abc123",
  "phases": {
    "PREFLIGHT": "completed",
    "SYNC": "completed",
    "ENV_CHECK": "completed",
    "WORKTREE": "completed",
    "PIN_UPDATE": "completed",
    "DEPLOY": "completed",
    "SCHEMA_SYNC": "completed",
    "INFISICAL": "skipped_no_infisical",
    "VERIFY": "completed",
    "K8S_VERIFY": "completed",
    "OMNIDASH_VERIFY": "completed",
    "NOTIFY": "completed"
  },
  "pins_applied": {
    "omniintelligence": "0.8.0",
    "omninode-claude": "0.4.0",
    "omninode-memory": "0.6.1"
  }
}
```

**Status values**: `success` | `failed` | `dry_run`

## v1 Constraints

- No `--no-deps` inference; existing Dockerfile install flags are preserved as-is
- `--cleanup` flag not implemented in v1 (worktree retained after success)

## See Also

- `prompt.md` — authoritative phase execution logic
- `release` skill — run before redeploy to coordinate version bumps across repos
- `_lib/tier-routing/helpers.md` — tier detection
- `_lib/slack-gate/helpers.md` — Slack credential resolution
- `omnibase_infra/scripts/deploy-runtime.sh` — DEPLOY phase core script
- `omnibase_infra/scripts/update-plugin-pins.py` — PIN_UPDATE phase helper
- `omnibase_infra/scripts/verify_deployed_versions.py` — VERIFY phase version checker (OMN-5608)
- `omnibase_infra/scripts/seed-infisical.py` — INFISICAL phase fallback
