Best for
- Use when deploying updates to this machine: pull, sync deps, verify, restart services.
tomcounsell/ai/.claude/skills/update/SKILL.md
Use when deploying updates to this machine: pull, sync deps, verify, restart services. Triggered by 'update', 'deploy', 'pull and restart', or after git pull.
Decision brief
Bring this machine to latest main: deps synced, environment verified, services restarted and healthy. The orchestrator does the work — your job is to run it, read its output, and report every warning or error.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/tomcounsell/ai --skill ".claude/skills/update"Inspect the Agent Skill "update" from https://github.com/tomcounsell/ai/blob/0a092490b991ac87d3c2acd8a72961f8c98c64e7/.claude/skills/update/SKILL.md at commit 0a092490b991ac87d3c2acd8a72961f8c98c64e7. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
PREREQUISITE: Must be on latest main branch before running.
The final action of runupdate invokes the valor-catchup CLI (issue 1709, see Agent-Judgment Catchup): it reads each owned chat's recent thread, asks an LLM judge which inbound human messages are genuinely unanswered, and enqueues recovery sessions only for those.
To check the environment without making changes:
Every run checks PyPI for newer anthropic and claude-agent-sdk versions (only the lockfile-maintainer machine runs auto-bump; others skip to avoid racing). When a newer version is available:
When pyproject.toml changes via git pull with critical dep version changes (telethon, anthropic, claude-agent-sdk), the cron job (remote-update.sh) writes data/upgrade-pending; running /update manually applies the upgrade with proper verification.
Permission review
No configured static risk pattern was detected
This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.
Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 95/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 22 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Bring this machine to latest main: deps synced, environment verified, services restarted and healthy. The orchestrator does the work — your job is to run it, read its output, and report every warning or error.
PREREQUISITE: Must be on latest main branch before running.
cd ~/src/ai && git checkout main && git fetch origin main && git merge --ff-only origin/main
Fetch-then-merge-a-named-ref rather than git pull (#2650): .git/FETCH_HEAD is shared by every worktree of the repo, so with concurrent lanes on this machine a peer's fetch can retarget a bare pull's merge.
If there are local changes, stash them first: git stash. The update orchestrator also handles this, but being on main is required.
Run the full update orchestrator and report the results:
cd ~/src/ai && .venv/bin/python scripts/update/run.py --full
The orchestrator will:
.claude hardlinks and audit skill hooksscutil --get ComputerName, matches against the machine field in ~/Desktop/Valor/projects.json, reports which projects this machine handlesprojects.json (green-light gate) — runs bridge/config_validation.py::validate_projects_config over the full config (Step 4.6). Enforces that every bridge-contact identifier (DM contact id, Telegram group, email contact, email domain wildcard) resolves to exactly one machine. On failure: log the error, skip the service restart, leave the running bridge serving on the previously-validated config. See Single-Machine Ownership.com.valor.reflection-worker — installed right after the worker so at most a brief zero-scheduler window; issue #1828), nightly-tests, caffeinate, and log-rotateAfter running, report the result. List every warning or error clearly.
Warning channel (#2845): the --cron summary format (up to date at <sha> (N warnings) / update failed at <sha> plus their bullets) is what both the Telegram reply and any auto-spawned fix session detect against — not a handful of legacy prefixes. gws auth, Redis ACL drift, and env-completeness warn once per state transition rather than every cycle (via warn_state); when any of those are currently suppressed, a suppressed: ... line appears in the reply naming them, with python -m scripts.update.warn_state and a full (non---quick) python -m tools.doctor run as the on-demand answers for what is suppressed right now. See /update Warning Channel for the full producer/consumer contract.
First-install backfill reminder (markitdown): the first run that installs the [knowledge] extra appends a one-time tip to the Telegram summary: run 'valor-ingest --scan ~/work-vault/' to backfill existing binary files into sidecars (gated by ~/.cache/valor/markitdown-backfill-reminded). If the user asks why pre-existing vault PDFs/docs aren't indexed, point them at that command — the watcher only picks up files modified after it starts.
Log rotation: every --full run installs the user-space LaunchAgent com.valor.log-rotate.plist (content-idempotent, no sudo) which rotates any logs/*.log over 10 MB every 30 minutes. A stale root-era /etc/newsyslog.d/valor.conf is removed via non-interactive sudo -n rm; if sudo needs a password, cleanup is skipped with a warning and retried next run.
Obsolete launchd-job sweep (Step 1.56): every run boots out and deletes LaunchAgents for features that have been fully removed from the codebase, so a deleted feature's plist doesn't keep loading and failing on already-provisioned machines forever. The list of removed jobs lives in scripts/update/service.py::OBSOLETE_SERVICE_SUFFIXES — this is the launchd analog of RENAMED_REMOVALS in hardlinks.py: when you delete a launchd-backed feature (its install script + code), add its label suffix there so /update cleans up the stale job on every machine. The sweep is idempotent and fail-soft (a machine that never had the job is a no-op); removals are logged and reported in the run summary. Runs unconditionally alongside the plist-PATH heal (Step 1.55), not gated on the service-restart step.
Session cleanup (Step 5.5): corrupted sessions are deleted and indexes rebuilt; running/pending sessions older than 120 min with no live process transition to killed; terminal sessions are preserved for reflections (which handles its own 90-day expiry).
The final action of run_update invokes the valor-catchup CLI (issue #1709, see Agent-Judgment Catchup): it reads each owned chat's recent thread, asks an LLM judge which inbound human messages are genuinely unanswered, and enqueues recovery sessions only for those.
Best-effort contract — the step never blocks or fails /update:
do_service_restart is set (verify-only and follower-skip runs never trigger recovery enqueues). Otherwise it logs catchup: skipped — ... and returns.CATCHUP_STEP_TIMEOUT_SECONDS (90s); a hung Telethon connect or stalled LLM call is killed on expiry.catchup: ... (swallowed)) and never flips UpdateResult.success.The CLI propagates via pip install -e . during the dependency-sync step ([project.scripts] entry) — no extra wiring.
Every run checks PyPI for newer anthropic and claude-agent-sdk versions (only the lockfile-maintainer machine runs auto-bump; others skip to avoid racing). When a newer version is available:
pyproject.tomluv sync to install the new versionpytest tests/unit/test_docs_auditor_substrate.py -x -q)pyproject.toml and re-syncs old versionsWhen pyproject.toml changes via git pull with critical dep version changes (telethon, anthropic, claude-agent-sdk), the cron job (remote-update.sh) writes data/upgrade-pending; running /update manually applies the upgrade with proper verification.
If data/upgrade-pending exists:
# Check what's pending
cat ~/src/ai/data/upgrade-pending
# After /update applies the upgrade and verifies the bridge starts:
rm ~/src/ai/data/upgrade-pending
To check the environment without making changes:
cd ~/src/ai
.venv/bin/python scripts/update/run.py --verify
After update, reinstall launchd plists to pick up any template changes. The reflection scheduler runs in its own launchd subprocess (python -m reflections, label com.valor.reflection-worker) — out-of-process from the worker since issue #1828 — so three installers cover the set:
cd ~/src/ai
./scripts/install_worker.sh
./scripts/install_reflection_worker.sh
./scripts/install_sdlc_reflection.sh
install_reflection_worker.sh self-gates on worker role (any project's machine matches this host; fail-open) and removes its stale plist on non-worker machines. Verify with python -m reflections --dry-run (loads the registry, exits 0) and tail -f logs/reflection_worker.log. Install scripts substitute __PROJECT_DIR__ and __HOME_DIR__ placeholders, so plists work on any machine without hardcoded usernames.
| Sub-file | Load when... |
|---|---|
references/troubleshooting.md | An update run fails or the environment misbehaves afterward (venv, deps, calendar, machine identity, bridge/worker/reflection-scheduler won't start) |
references/modules.md | Debugging orchestrator internals or calling a scripts/update/ module directly (git.py, deps.py, verify.py, gws_auth.py, calendar.py, MCP registration, service.py) |
Machines that run the do-design-system skill also need Node + npm (for npx @google/design.md). remote-update.sh runs npm ci --omit=dev guarded by:
if [ -f "$PROJECT_DIR/package.json" ] && command -v npm >/dev/null 2>&1; then
( set +o pipefail; cd "$PROJECT_DIR" && npm ci --omit=dev ) \
|| echo "[update] npm ci failed (non-fatal); continuing"
fi
The non-pipefail subshell + || echo trailer guarantee a missing npm or a transient install failure never aborts the parent update. Machines without Node skip the block silently; design-system tooling falls back to Python-only emission (--generate --no-node). Lint and DTCG / Tailwind exports still require Node. See docs/features/design-system-tooling.md.
Frequently asked questions
Bring this machine to latest main: deps synced, environment verified, services restarted and healthy. The orchestrator does the work — your job is to run it, read its output, and report every warning or error.
The source record exposes this install command: npx skills add https://github.com/tomcounsell/ai --skill ".claude/skills/update". Inspect the command and pinned source before running it.
Alternatives
Postpartum-genushyacinthus29/dotnet-skills
Build long-running .NET background services with `BackgroundService`, Generic Host, graceful shutdown, configuration, logging, and deployment patterns suited to workers and daemons.
vasilyu1983/AI-Agents-public
Guides iOS testing with XCTest, XCUITest, Swift Testing, simctl, and xcresult. Use when choosing destinations, controlling flakes, or parsing test artifacts for native apps.
garrytan/gbrain
Generate a publication-quality PDF from any brain page via the gstack make-pdf binary. Strips YAML frontmatter, sanitizes emoji, applies running headers and page numbers. Brain page is always the source of truth; PDF is a rendering.
NVIDIA/skills
How to swap the DeepStream CV detection model in the VSS Alerts Blueprint verification (2d_cv) mode - covers ONNX export, custom bbox parsers, compose mount gotchas, nvinfer config, runtime TRT engine build, deployment, and a segmentation-capable model addendum handoff.