← index2026-05-03 06:44 (Beirut)(backfill from DOCUMENTATION/)

09 — Operations & Common Tasks

09 — Operations & Common Tasks

Quick reference for routine ARG operations.

"Can Brian do X right now?"

arg list capabilities                       # browse cap-ids
arg resolve cap.<area>.<action>             # JSON verdict
arg resolve cap.<area>.<action> | jq '.state, .blocking, .required_actions'

If verdict is yes-after-probe, run the listed probes. If yes-after-approval, ask Jonah. If no, fix the red dep. If blocked-by-policy, the rule explanation is in blocking.

Add a new capability

cat <<JSON | arg add capabilities --json -
{
  "id": "cap.<area>.<action>",
  "name": "Human-readable name",
  "requires": {"resources": ["acc.brian.foo", "key.foo_token"], "tools": ["skill.foo"]},
  "side_effects": ["writes-external"],
  "risk_level": "medium",
  "cost_class": "free",
  "idempotency": "non-idempotent",
  "approval_required": false,
  "freshness_budget_hours": 24
}
JSON
arg validate
arg render-views
arg resolve cap.<area>.<action>

Add a new atom (account / key / host / channel / etc.)

cat <<JSON | arg add accounts --json -
{
  "id": "acc.brian.<platform>",
  "name": "Brian's <Platform>",
  "platform": "<platform>",
  "identity": "<handle/id>",
  "where_secret": "/opt/agent/core/.env <ENV_VAR_NAME>",
  "freshness_budget_hours": 24,
  "critical": true,
  "probe": {"command": "/opt/agent/scripts/probes/<platform>.sh", "timeout_sec": 10}
}
JSON
arg validate

Wire a new probe script

cat > /opt/agent/scripts/probes/<name>.sh <<'EOF'
#!/bin/bash
. /opt/agent/scripts/probes/_lib.sh
START=$(now_ms)
# ... do the check, set OK or HINT ...
probe_emit_ok "auth" "<evidence>" "$(($(now_ms) - START))"
# OR: probe_emit_fail "auth" "<hint>" "$(($(now_ms) - START))"
EOF
chmod +x /opt/agent/scripts/probes/<name>.sh

# Test it
/opt/agent/scripts/probes/<name>.sh

# Wire it into the row's probe block in resources/<cat>.json:
#   "probe": {"command": "/opt/agent/scripts/probes/<name>.sh", "timeout_sec": 10}

arg probe <id>      # confirm registry picks it up
  1. Edit /opt/agent/core/.env (use Python or single-quoted heredoc — never source/eval).
  2. Manually re-probe ONCE: /opt/agent/scripts/probes/li_brian.sh (direct call, bypasses min_interval).
  3. If ok, persist confirmed state into probe_status.json + the row's last_probe via Python (avoids re-probing and tripping rate-limit flags).
  4. Don't probe again for min_interval_seconds — let cron pick it up naturally.

Example of step 3:

import json, pathlib
from datetime import datetime, timezone
NOW = datetime.now(timezone.utc).astimezone().isoformat(timespec="seconds")
GOOD = {"ok": True, "layer": "auth", "evidence": "...", "latency_ms": 0, "checked_at": NOW}
ps = pathlib.Path("/root/.claude/system/observability/probe_status.json")
d = json.load(open(ps)); d["acc.brian.linkedin"] = GOOD
json.dump(d, open(ps, "w"), indent=2)

Add a boundary

# Edit /root/.claude/system/policies/boundaries.json directly (it's small)
# After editing:
arg validate                                # confirm jsonschema + invariants pass
arg resolve <some-affected-cap-id>          # confirm verdict matches intent

Match clauses are AND within a rule. Be specific:
- capability_id_regex over side_effects_any when possible.
- cost_class: paidcost_class: metered. The first is for paid LLM endpoints; the second for stripe/ads/etc.

Process the inbox

arg inbox list
arg inbox accept prop-XXX                   # promote to canonical
arg inbox reject prop-XXX --reason "..."    # drop with audit reason

Both emit events. Mined proposals default approval_required: True; even after accept, the cap must still resolve yes-after-approval (= ask Jonah before invoking).

Inspect what the policy hook caught today

arg events grep policy_block

Each entry has rule_id, decision, tool_name, ts. If you see a rule firing on a tool you intended to allow, the rule is too broad — tighten the match clause.

Run the bypass corpus

/opt/agent/venv/bin/python3 /opt/agent/scripts/test_arg_policy_hook.py

Expect 12/12 passed. If a case fails, the hook regressed — see 05_policy_hook.md for what each case proves.

Render fresh markdown views

arg render-views
ls /root/.claude/system/views/

Run after any registry edit. The views/ directory is generated; never edit by hand.

Validate after a batch edit

arg validate

Three layers run: jsonschema → ad-hoc shape → invariants. Exit 0 = clean. Exit 1 = N problems printed.

Sanitize for OSS template

/opt/agent/scripts/arg_sanitize.py --idempotence-test
ls /tmp/arg-template-out/arg-template/

Output should include idempotence: ok. Never ship if FAILED.

Recover from a corrupted JSON file

# Show what changed in the last commit (if /root/.claude/system is a git repo)
cd /root/.claude/system && git diff HEAD~1 -- resources/

# Or restore from backup
cp /opt/agent/backups/daily/<latest>.tar.gz /tmp/
tar xzf /tmp/<latest>.tar.gz -C /tmp/restore/
diff /tmp/restore/root/.claude/system/resources/<bad-file>.json /root/.claude/system/resources/<bad-file>.json

Pause autofix for a row

Add the row to ALWAYS_ASK_PATTERNS in /opt/agent/scripts/arg_autofix.py:

ALWAYS_ASK_PATTERNS = [
    ("acc.brian.linkedin", "auth"),
    # ... your row + layer ...
]

Effect: autofix escalates instead of attempting any SAFE_FIX. Reverse by removing the line.