| name | pai-accept |
| description | Accept an upstream proposal from pai-watch — pin target SHA in /etc/pai/paths.env + write arc review markdown + mark proposal status=accepted. SSH-only by design (never callable via remote platform). Use when user says accept, approve upgrade, merge proposal, bump, pin sha. |
pai-accept skill
When to use
User intent (must be SSH session):
- "accept proposal X" → pin SHA, write review
- "approve OMC bump" → after pai-watch flagged
- "merge that upstream change" → review-then-pin flow
- NEVER triggered by mobile push / Telegram / Discord — security gate
Security model
pai-accept is the only mutation that touches paths.env. Plan v5 §13 ADR + pai-anywhere CLAUDE.md require:
- Real-SSH-session-only — the guard authorizes only when
sshd is in the
invoking process's ancestry (verified via /proc, not the spoofable
SSH_* env vars). Hermes — a non-root LLM with no sshd ancestor — cannot
pass it, even if prompt-injected. Remote use still works: open a Tailscale
SSH session from any device and the check passes.
- No gateway exposure — never callable via pai-anywhere gateway proxy.
- No Pulse route — never callable via Pulse HTTP.
- No remote platform — Telegram/Discord/Signal/WhatsApp triggers rejected.
- Audit logged — every acceptance writes JSONL audit + arc markdown review.
The boundary is enforced in bin/pai-accept-guard (shell), not in this
markdown. Do not reimplement the check inline — invoke the guard (see Execution).
Break-glass for non-SSH local admin/CI is a root-owned marker file
(/etc/pai/local-accept.allow, mode 0600) that a non-root process cannot forge.
Algorithm
- Read proposal JSON from
$PAI_PROPOSALS_DIR/<id>.json.
- Extract
repo, targetSha, commits log.
- Update
/etc/pai/paths.env (or $PAI_PATHS_ENV):
- Add or replace line
PAI_<REPO>_SHA=<targetSha> (repo name uppercased with underscores).
- Write arc review markdown to
pai-collab/projects/arc/reviews/<date>-pai-watch-<repo>-<sha7>.md (if pai-collab dir present).
- Update proposal JSON:
.status="accepted" + .acceptedAt=<ISO-ts>.
- Optional: trigger
pai-pulse skill to confirm acceptance via voice.
Inputs
proposal_id (required) — id matching JSON filename in proposals dir.
Output
PAI_<REPO>_SHA=<full-sha>
arc review: <path>
accepted: <id> (<repo> @ <sha7>)
Execution
Always invoke the guard wrapper, never the inline commands. The wrapper enforces SSH-only + flock-based atomicity in shell — markdown rules in SKILL.md are advisory; the guard is the actual security boundary.
pai-accept-guard <proposal-id>
sudo ln -sf $PAI_PROJET_ROOT/pai-hermes/bin/pai-accept-guard /usr/local/bin/pai-accept-guard
The guard (bin/pai-accept-guard in this repo) enforces:
- Real-SSH-session-only — authorizes only when
sshd is in the process ancestry (forge-resistant; spoofable SSH_* env vars are ignored). Exit 77 (EX_NOPERM) otherwise. Local/CI break-glass is a root-owned /etc/pai/local-accept.allow (mode 0600), never an env flag.
- Input validation — proposal id, repo name, and SHA must match strict regex. Exit 65 (EX_DATAERR) on mismatch.
- flock — exclusive lock under the user runtime dir (
${XDG_RUNTIME_DIR}/pai-accept/lock, override via PAI_ACCEPT_LOCK) with a 30s timeout (PAI_ACCEPT_LOCK_TIMEOUT). Exit 75 (EX_TEMPFAIL) if another accept is in flight.
- Atomic paths.env mutation — write to tmp file (same dir), preserve permissions, then
mv (atomic on same filesystem).
- Atomic proposal status update — same tmp+mv pattern, prevents partial writes.
- Optional arc review — only if
$PAI_COLLAB_DIR/projects/arc/reviews/ exists and writable. Skipped silently otherwise.
If you really want raw bash inline (NOT recommended — bypasses guard), see source: bin/pai-accept-guard.
Rollback
If acceptance was wrong, invoke the guard with the rollback proposal id — never mutate paths.env directly:
pai-accept-guard <rollback-proposal-id>
Granular rollback flow (per plan v5 §12):
pai paths pin <repo> <previous-sha>
pai doctor --strict
- Run integration tests
- If green: commit; if red: revert paths.env
Caveats
/etc/pai/paths.env requires write perms — typically pai user or root.
pai-collab/projects/arc/reviews/ is OPTIONAL — skill skips arc markdown if dir absent.
- Acceptance does NOT auto-pull or rebuild the sub-project. User runs
git -C $PAI_<REPO>_DIR checkout $SHA separately, or uses pai-anywhere reinstall flow.
- Sha format validated: must be 40 hex chars OR 7-40 hex chars (allow short SHAs but warn).
Cost
ZERO AI cost. Pure file ops.
Triggers in Hermes natural language
- "accept proposal 2026-05-16-...-omc" → run skill with id
- "approve the OMC upstream bump" → list pending proposals first, ask user to confirm id
- NOT triggered by remote message ("accept this from Telegram") — refuse with security explanation