---
name: adom-hook
description: Registry-native cross-agent auto-update hook; keeps adom/core apps and skills current from wiki.adom.inc on every Claude Code and Codex prompt.
---

# adom-hook

The registry-native, cross-agent auto-update hook. It keeps your `adom/core` apps
and skills current from the wiki registry (wiki.adom.inc) without git or any
private repository.

## What it does

On every Claude Code and Codex prompt (`UserPromptSubmit`), a throttled check runs
`adom-wiki outdated`. When something installed is behind the registry, it applies the
update in the background (`adom-wiki update` + `adom-wiki install adom/core`) and prints
a one-line note into the model's context. It never blocks the prompt.

This is the registry-native replacement for the old `git fetch` hook: same
"stay current automatically" behavior, but sourced from the public registry so it
works for any user and any agent, with no private-GitHub dependency.

## Two triggers (interactive + headless)

Installing wires BOTH, and they share one throttle stamp, so a double fire is a
no-op:

- **`UserPromptSubmit`** (Claude Code / Codex) -- fast: an interactive container
  updates the moment you type.
- **cron** (`*/30` + `@reboot`) -- the headless trigger. A lite/service container
  has no prompts, so without this it never updates and packages rot until someone
  SSHes in -- which is exactly where prod releases run. Cron is registered
  unconditionally (not only when Claude is absent), so an interactive box that sits
  idle for a day still gets a backstop.

If the image has no `crontab`, or `crond` is not running, install says so. In that
case have the app call `~/.adom/hooks/adom-core-update.sh` on its own interval --
it is throttled and idempotent, so calling it often is safe.

**Reading the result on a headless box:** stdout is meaningless under cron (it
becomes mail or `/dev/null`). The durable record is:

- `~/.adom/last-update.status` -- `running`, or the last exit code (`0` = fine).
- `~/.adom/last-update.log` -- the last update's output.

A failed update is also reported to the next interactive prompt, and the CLI
version each container reports to the registry answers "is the fleet current?"
fleet-wide (`GET /api/admin/clients?name=adom-wiki-cli`) without SSHing anywhere.

## What gets updated

**Everything installed, in one pass.** `pkg update` covers every package
`adom-wiki pkg list` shows -- apps, skills and bootstraps -- including ones you
installed yourself from other owners, not just `adom/core`'s tree. Then
`pkg install adom/core` re-resolves core so any NEWLY ADDED member arrives (update
alone only refreshes what you already have; it never adds).

**The CLI is not a separate layer.** `adom/adom-wiki-cli` is an ordinary package
that `adom/core` depends on, so it comes down the same path as everything else, in
the same run. There is no automatic self-update and no separate CLI timer -- the
`self-update` verb is a MANUAL fallback for the one case the package path cannot
handle: if the atomic binary swap ever fails with ETXTBSY ("text file busy"), the
CLI hints you toward it. Do not count on the CLI healing itself; if this hook is
broken, the CLI goes stale with everything else.

**Components are out of scope.** They are wiki content (symbols, footprints, 3D
models) you reference, not packages you install.

## Controls

- `ADOM_HOOK_INTERVAL=<seconds>` -- check cadence (default 1800).
- `ADOM_HOOK_FORCE=1` -- force a check on the next prompt (testing).
- `ADOM_HOOK_DISABLE=1` -- disable the hook entirely.

## Install

```
adom-wiki install adom/hook
```

It is also a dependency of `adom/core`, so a normal bootstrap installs it for you.
`adom-wiki uninstall adom/hook` unwires it from both agents.

## Note on Codex

The Codex wiring (`~/.codex/hooks.json`) targets Codex's `UserPromptSubmit` event
and its additionalContext channel. Verify against a live Codex install before
relying on it there; the Claude Code path is the verified one.
