Quick reference for routine ARG operations.
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.
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>
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
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
/opt/agent/core/.env (use Python or single-quoted heredoc — never source/eval)./opt/agent/scripts/probes/li_brian.sh (direct call, bypasses min_interval).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)
# 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: paid ≠ cost_class: metered. The first is for paid LLM endpoints; the second for stripe/ads/etc.
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).
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.
/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.
arg render-views
ls /root/.claude/system/views/
Run after any registry edit. The views/ directory is generated; never edit by hand.
arg validate
Three layers run: jsonschema → ad-hoc shape → invariants. Exit 0 = clean. Exit 1 = N problems printed.
/opt/agent/scripts/arg_sanitize.py --idempotence-test
ls /tmp/arg-template-out/arg-template/
Output should include idempotence: ok. Never ship if FAILED.
# 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
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.