Skip to content
Back to skills

Anti Hall Update

ASecurity

Check or update anti-hall from the local marketplace clone. Use when the user asks to update anti-hall, check whether anti-hall is current, or refresh the Codex port files.

  • 2 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added October 2, 2026
ai-agentsgobashnodegit

Works with

  • claude code
  • cli
  • mcp

Security analysis

A100/100

Scanned October 3, 2026

npx -y skills add talas9/anti-hall --skill anti-hall-update --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Anti Hall Update?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Anti Hall Update
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/talas9-anti-hall-update/badge)](https://www.skillsdirectory.com/skills/talas9-anti-hall-update)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: anti-hall-update
description: Check or update anti-hall from the local marketplace clone. Use when the user asks to update anti-hall, check whether anti-hall is current, or refresh the Codex port files.
---

# anti-hall update for Codex

> **UPGRADE NOTE (Claude Code side only):** a user who also runs the Claude Code plugin on
> 0.107.x or earlier must run `claude plugin update anti-hall@anti-hall` once, then restart
> Claude Code — the 0.107.x `update.js` cannot register 0.108.0 with the Claude harness.
> The Codex port loads from the marketplace clone and needs no extra step.

## Resolve the plugin root

Codex does not expand `${PLUGIN_ROOT}` inside a skill's own instructions — that
variable is only set for plugin-bundled hook commands (see
`docs/KB-codex-platform-hooks-plugins.md` in the anti-hall source repository). Codex does show you this skill's own
file path when it selects the skill ("Codex starts with each skill's name,
description, and file path" — official Codex Skills doc). Resolve the plugin
root from that path before running anything below:

```bash
# SKILL_FILE = the absolute path Codex showed you for this SKILL.md.
ANTI_HALL_ROOT="$(cd "$(dirname "$SKILL_FILE")/../../.." && pwd)"
test -f "$ANTI_HALL_ROOT/.codex-plugin/plugin.json" || { echo "anti-hall plugin root not found relative to $SKILL_FILE — aborting" >&2; exit 1; }
```

Use the existing pure-Node update helper:

```bash
node "$ANTI_HALL_ROOT/skills/update/scripts/update.js" --check
node "$ANTI_HALL_ROOT/skills/update/scripts/update.js"
```

This is already the STALE-VERSION-SAFE path — `$ANTI_HALL_ROOT` is derived
above from the file path Codex itself just showed you for this SKILL.md, i.e.
wherever THIS invocation's skill file physically lives, not a separate
version-pinned cache mirror (Codex's clone-based distribution has no such
mirror step). Never hardcode a different, potentially-stale root here (see
the Claude-side SKILL.md's own note on the P0 field bug this parallels:
`${CLAUDE_PLUGIN_ROOT}` there resolves to a cache dir that can lag the
freshly-pulled marketplace clone). `update.js` itself also re-execs the
freshly-pulled version's own copy internally as a second line of defense.

For Codex, also re-run the Codex hook installer after a successful update:

```bash
node "$ANTI_HALL_ROOT/codex/install-codex.js"
```

or for global Codex hooks:

```bash
node "$ANTI_HALL_ROOT/codex/install-codex.js" --global
```

Do not force-pull, rebase, or delete plugin cache directories. If the update helper reports a dirty tree, diverged branch, offline state, or missing marketplace clone, surface that result and stop.

## DevSwarm ingest daemon durability (auto-heal, gated, fail-open)

`install-devswarm-ingest.js`'s daemon unit used to bake an install-time script path
(`__dirname`) that could go stale across a plugin update — the plugin manager relocating
the version-pinned cache dir the daemon was baked from, orphaning/crash-looping the
daemon. The installer now bakes the **git marketplace clone's own copy** of
`devswarm-ingest.js` (the exact path the update helper above just `git pull --ff-only`ed
**in place**), so a fresh install never goes stale again.

The update helper (`skills/update/scripts/update.js`) ALSO attempts to heal an already-installed daemon
in-process via `healIngestDaemon` — no separate step needed. **v0.86.0 — the heal fires
when EITHER this run synced new bytes into the cache OR the installed unit fails to
classify `ok`.** Gating it on a cache sync alone made it unreachable in exactly the state
it was written for: a daemon goes stale with NO version bump, and in that steady state the
installed version already equals latest, `syncCache` no-ops, and the classifier that would
have spotted the dangling script path never ran. The extra arm is read-only on a no-sync
run (a unit enumeration plus a few `statSync`s — no spawn, no writes) and deliberately
does NOT treat `absent` as "needs heal", so a no-op update can never first-install an
opt-in daemon for a user who never enabled it. It runs ONLY under the same
DevSwarm-session-only gate
`hooks/lib/doctor-repair.js`'s own gated ingest fix uses
(`isDevswarmActive(env) && resolveWorktree(cwd) !== null`), and re-runs the
(freshly-pulled) installer only when the unit is genuinely `wrong-path` or `stale-script`
— an `ok` or `absent` unit is left untouched. The daemon also now logs
(startup / lock-refusal / ERROR+stack) to `~/.anti-hall/devswarm-ingest.log` instead of
discarding output. Reported as `ingestHeal: {attempted, healed, detail}` on the update
helper's JSON status line (`{installed, latest, updated, cacheSynced, ingestHeal,
action}`) — absent on a STOP/offline report, since those paths never reach cache sync.
Gate-closed, nothing-to-heal, or an internal error are all reported and NEVER fatal to
the update. This is independent of — and does not replace — the ingest-daemon
install-or-refresh step further below (which also covers a FIRST install).

## Reconcile (auto, DevSwarm-session-only, fail-open — v0.58.1)

Every update run ALSO drains `node scripts/devswarm.js reconcile` in-process via
`reconcilePostUpdate` — no separate step needed. `reconcile` (v0.58.0) drains every
worktree registered in this project's shared store once, recovering messages stranded in
a per-worktree native hivecontrol queue whose child never ran `inbox pull` itself (e.g. a
worktree torn down before it drained). Previously a MANUAL-only verb; now auto-run
whenever `isDevswarmActive(process.env)` — `DEVSWARM_REPO_ID` set, i.e. an actual
DevSwarm session (do NOT trigger on machine-level descriptor/registry-file presence
alone) — regardless of whether the cache actually synced this run (a stranded queue is
unrelated to whether the plugin version changed — the same reasoning that, in v0.86.0,
freed the ingest heal above from its own cache-sync gate). Safe to
auto-run: idempotent (content-hash dedup), lock-respecting (a worktree a live child is
already draining is skipped, never raced), and loss-free (a short-received batch fails
loud rather than silently dropping messages). Reported as
`reconcile: {attempted, count, imported, results, detail}` on the JSON status line.
Gate-closed or an internal error are both reported and NEVER fatal to the update. The
manual verb (`node scripts/devswarm.js reconcile`) stays available for an on-demand sweep
outside an update.

**Promote unclaimed sessions (auto, fail-open — `promoteUnclaimedPostUpdate`, v0.90.0):**
every update run also sweeps every descriptor for the `unclaimed:` forward migration,
promoting a row to its real session id wherever an independent source (a heartbeat's own
recorded `sessionId`) proves one — see `docs/KB-devswarm-hivecontrol.md` §40 for the
sourcing rules this is a forward migration of.

**(v0.94.0) Bounded reconcile.** `reconcile` now applies a total wall-clock budget across all
its per-row drains — `ANTIHALL_RECONCILE_BUDGET_MS` (default `60000`; `0` = unlimited) or
`--budget-ms` on a direct CLI call — so a large stranded backlog can no longer hang `update`
indefinitely (defect f3c1bc827d89). A row whose worktree no longer exists on disk is skipped
before it costs any budget; whatever is still deferred when the budget runs out is written to
a resume marker and drained FIRST on the next sweep. Separately, `update.js`'s stdout contract
(the JSON status line + human summary) is unchanged, but it now also prints a `[update]
<stage> start` / `done <ms>ms` line to **stderr** around each post-update stage so a slow
stage is visible while it runs; `ANTIHALL_UPDATE_QUIET=1` suppresses these lines.

**Overall post-pull budget (v0.96.0, D11-C, defect e7307778b614 — `postPullBudgetMs`):** a
single wall-clock budget (`ANTIHALL_UPDATE_POSTPULL_BUDGET_MS`, default 90000ms; `0` =
unlimited) now bounds every DevSwarm post-pull stage COMBINED — reconcile, fold,
fold-all-stores, heal-orphan-partitions, fold-archived-rows, and heal-registry-rows — checked
BEFORE each stage starts (never mid-stage). A stage that would start past the deadline is
deferred WHOLE, reported as `deferred: true` on its stage result, and picked up on the NEXT
`update`/`doctor` call rather than lost: every one of these stages is independently
idempotent/resumable (fold/heal/fold-archived-rows persist their own resume markers; the
one-time-per-version stages simply re-attempt next call). As of v0.96.1, the periodic
supervisor sweep (`companion/devswarm-supervisor.js`) also picks up `fold-all-stores`,
`heal-orphan-partitions`, `fold-archived-rows` and (v0.102.1) `heal-registry-rows` — one
deferred stage per supervisor pass,
within `ANTIHALL_SUPERVISOR_SWEEP_BUDGET_MS` (default 20000ms) — so a machine that always
exhausts the post-pull budget is no longer stuck waiting on the next explicit `update`/`doctor`
call to make progress on those stages.

After a successful update, also run the capability scan to find what's missing on this machine vs what this build ships:

```bash
node "$ANTI_HALL_ROOT/scripts/capability-scan.js"
```

Read-only — it never installs anything. It reports each opt-in capability (companions under `companion/install-*.js`, statusline, pending state migrations) as `{name, available, active, how}`. Present a concise available-vs-active summary:
- `state-migrations` at `active: false` — run `node "$ANTI_HALL_ROOT/scripts/migrate-state.js"` (idempotent, safe to re-run) to fold it, same as the Claude-side update flow. It never folds or moves `.planning/`: the GSD fold is the explicit, copy-only `migrate-state.js --planning` (skips git-tracked `.planning/`, linked/child worktrees and submodules). If `doctor` reports moved `.planning/` files (pre-0.108.5 damage), restore with the printed `git -C <worktree> checkout -- .planning` or the opt-in `migrate-state.js --restore-planning --dir <worktree>`.
- **DevSwarm liveness supervisor** — **autonomously install-or-refresh it
  whenever this update is running inside a DevSwarm session, no offer, no
  ask.** Check `devswarm-detect`'s `isDevswarmActive(process.env)` — true only
  when `DEVSWARM_REPO_ID` is set, i.e. the current session really is a DevSwarm
  workspace (do NOT trigger on machine-level descriptor presence alone; the
  session might be running outside DevSwarm). If inside a DevSwarm session, run
  its `how` command (`node companion/install-devswarm-supervisor.js`)
  regardless of the capability scan's `active` value. The installer is
  idempotent (`launchctl unload && load` on macOS / systemd reload on Linux),
  so this both first-installs when absent and refreshes an already-installed
  supervisor so the next sweep runs this build's code. **Report it** plainly
  ("DevSwarm session detected — installed/refreshed the liveness supervisor to
  `<version>`"). Fail-open: an install/refresh failure is reported, never fatal
  to the update. If NOT inside a DevSwarm session, do **not** install — just
  note it's available. (Safe to do unprompted: the supervisor's automatic
  sweep never kills — killing is only the separate on-demand
  `devswarm-recover` CLI. Defense in depth: the installed daemon is inert
  without work — it only ever acts on descriptors under
  `~/.anti-hall/devswarm/workspaces/`, so it no-ops when DevSwarm isn't
  actually running.)
- **DevSwarm ingest daemon** — install-or-refresh it under the **same
  DevSwarm-session-only, no-offer, no-ask posture as the supervisor above**, in
  the SAME `isDevswarmActive(process.env)` branch. When inside a DevSwarm
  session, also run its `how` command
  (`node companion/install-devswarm-ingest.js`) regardless of the scan's
  `active` value. It is idempotent (`launchctl unload && load` on macOS /
  `systemctl --user daemon-reload` + `restart` on Linux), so it first-installs
  when absent and refreshes an already-installed daemon to this build's code.
  Unlike the supervisor (a periodic sweep), the ingest daemon runs
  **continuously** — the unit uses `KeepAlive`/`Restart=always` to re-exec it on
  exit; hence a distinct label (`com.anti-hall.devswarm-ingest`) and log
  (`~/.anti-hall/devswarm-ingest.log`). It is the single native consumer that
  wraps `hivecontrol workspace monitor` and folds messages into the store;
  nothing else auto-starts it, so a DevSwarm session without it silently ingests
  nothing. Safe to install unprompted and idempotently: the daemon takes an
  O_EXCL single-consumer lock, so only ONE instance ever runs even if installs
  race. **Report it** plainly ("DevSwarm session detected — installed/refreshed
  the ingest daemon to `<version>`"). Fail-open: an install/refresh failure is
  reported, never fatal to the update. If NOT inside a DevSwarm session, do
  **not** install — just note it's available.
- Any other opt-in capability at `active: false` (e.g. mcp-reaper — no
  active-integration signal) — guide, don't auto-install: print its `how`
  command and let the user decide.
- `active: 'unknown'` — the probe couldn't determine state (fail-open); mention it as unverified rather than claiming either state.
- `active: true` for everything — say so briefly; no gaps to report.

After updating, restart Codex or start a fresh session if plugin/skill discovery does not reflect the new files immediately.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.