From grace
Автономный режим работы, когда пользователь AFK. Использовать, когда пользователь вводит `/afk [часы] [бюджет%] [--checkpoint <мин>]` или просит агента продолжать работу самостоятельно. CLI контролирует лимит времени — агент опрашивает `grace afk tick` между шагами и завершает работу, когда CLI это разрешит. Необратимые решения эскалируются в Telegram через `grace afk ask`; всё остальное выполняется, откладывается или откатывается согласно матрице автономии.
How this skill is triggered — by the user, by Claude, or both
Slash command
/grace:grace-afkThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Run the /afk harness: keep working through `docs/development-plan.xml` on an isolated branch,
Run the /afk harness: keep working through docs/development-plan.xml on an isolated branch,
making decisions from the user on their behalf within declared boundaries, until the CLI-enforced
budget expires or the user sends STOP via Telegram.
Between every logical step you MUST run grace afk tick --path <project-root>. If it exits
non-zero, your session is over — commit the in-progress work (if any), run grace afk report,
and stop. Do NOT try to estimate remaining budget yourself and keep going. The hard gate is
the CLI exit code.
docs/ exist). If not, run $grace-init first.@osovv/grace-cli installed (the binary grace is on PATH).$GRACE_AFK_CONFIG env var, then <project>/.grace-afk.json, then ~/.grace/afk.json (global user-level fallback). Configure one of these if grace-ask-human escalations are expected — otherwise one-way-door decisions fall back to grace afk defer.Every subcommand below takes --path <project-root> (defaults to .).
| Command | Purpose |
|---|---|
grace afk start <hours> [<budget%>] [--checkpoint <min>] | Initialize a session; writes docs/afk-sessions/<id>/state.json with expiresAt. |
grace afk tick | CLI-side active-session check. Non-zero exit = session over. |
grace afk ask --title ... --context ... --options "A:...;B:..." --mypick B --confidence 60 [--details "A|pros|cons|opps|risks;B|..."] [--wait 120] | Send a Telegram escalation; returns {correlationId, messageId}. Use ; as a separator (safer across Windows shells) or |. --details (5-field SWOT per option) adds a [📖 Подробнее] button that sends a follow-up breakdown without cancelling the ask. --wait N blocks up to N seconds polling, ack-ing inline-button taps within ~2s so the user's Telegram spinner stops immediately. |
grace afk check --correlation <id> --messageid <n> [--offset <o>] | Poll Telegram; returns {status, verb, raw, nextOffset}. |
grace afk journal --class <c> --title ... --rationale ... --outcome ... | Append to decisions.md. |
grace afk defer --question ... --contextLine ... | Append to deferred.md. |
grace afk increment <commits|escalations|deferred> | Update session counters after an action. |
grace afk report | Print the return dashboard and mark session completed. |
grace afk stop --reason "..." | Manual stop (e.g. when user sends STOP in Telegram). |
Exit codes from tick:
0 — session active, continue42 — BUDGET_EXHAUSTED (time expired)43 — no active session44 — session was stopped45 — Telegram sendMessage failed (only from ask)46 — grace-afk config missing at env var, project root, and ~/.grace/afk.json (only from ask / check)2 — bad arguments (unknown --class, missing --context, etc.)On Windows, if the agent invokes bun run ./src/grace.ts afk tick via a shell
wrapper, bun run can squash custom exit codes into 1 or 255. Two defences:
bun <file> directly (no run verb) when spawning subprocesses
from the harness.tick prints the reason
before exiting (Budget exhausted, no active session, stopped). If the
numeric code is squashed to 1/255, the stderr line still disambiguates.The agent must NOT assume a non-zero exit is always BUDGET_EXHAUSTED. Check the
value first; if it is 1 or 255, read stderr to disambiguate before acting.
/afk [hours] [budget%] [--checkpoint <m>] invocation. Defaults: hours=2,
budget%=default, checkpoint=30.git tag afk-baseline-<timestamp>git checkout -b afk-<timestamp> from the current branch tipgrace afk start <hours> [<budget%>] [--checkpoint <min>] --path .Every iteration:
grace afk tick --path .. Non-zero exit → jump to "End of session" below.docs/development-plan.xml, find the first pending step-N whose
dependencies are satisfied. If none, jump to "End of session".grace-* skill — usually
grace-execute for a single module, or grace-fix for a bug). Commit the result with the
usual grace(MODULE_ID): ... message format. Run grace afk increment commits.grace afk journal --class <c> --title ... --rationale ... --outcome ....bun test (or the project's test command) and grace lint --path ..
Wave thresholds (grace-multiagent-execute#Wave-Success-Thresholds) apply even in single-step mode:
git reset --hard HEAD~1 on your afk branch ONLY), journal the rollback,
next iterationcheckpointMinutes have passed since start or last checkpoint, run
a summary (tick, lint, journal entry class=checkpoint).| Class | Trigger | Action |
|---|---|---|
reversible-act | Obvious implementation step; well-defined contract; single credible approach | Act — invoke grace-execute or grace-fix; journal; continue. |
uncertain-deferred | Multiple credible approaches with different tradeoffs, no obvious winner | Defer to deferred.md. (When grace-evolve lands, this becomes delegate to grace-evolve.) |
one-way-door-escalated | Irreversible or main-branch-affecting: push to main, force push, drop DB, deploy, external API side-effects, changing a public MODULE_CONTRACT | grace afk ask via Telegram; poll grace afk check with backoff 10 / 30 / 60 / 120 min. |
one-way-door-deferred | Same as above but Telegram unavailable OR max escalations already sent | Defer and move to next step. |
scope-creep-deferred | The step's description would pull in edits outside the declared write scope | Always defer, never act. |
threshold-yellow-rollback | Tests / lint / graph consistency between green and red | Rollback + next step. |
threshold-red-escalated | Hard fail on any gate | Telegram ask with options ROLLBACK / STOP; default to ROLLBACK on timeout. |
checkpoint | Periodic summary | Journal entry; never an action. |
Rule (anti-Goodhart): "one-way door" is a behavioural test, not a feeling. If a single
git reset --hard afk-baseline-<ts> cannot fully undo the action, it is one-way. If the action
is file edits on the afk-* branch only — it is reversible, act freely.
Delegated to $grace-ask-human. Key rules:
A B C D E PROCEED STOP EVOLVE DEFER (case-insensitive, any position).uncertain → defer; if one-way-door with no default → stop the session; if threshold-red
with ROLLBACK as option → rollback.Hard cap: 3 escalations per session (enforced by CLI via --autoStop.maxEscalationsPerSession).
Past that, you must defer remaining one-way-door decisions.
If you see grace afk check return {verb: "STOP"}, immediately:
grace(afk): checkpoint before STOP).grace afk stop --reason "user STOP via telegram".grace afk report.Triggered by: tick non-zero, user STOP, plan exhausted, hard block (e.g. CLI failure).
grace afk report --path . (this marks the session completed).deferred.md, then merge afk-<ts> into the target feature branch).afk-<ts> branch — leave it for human review.| Rationalization | Reality |
|---|---|
| "I can estimate budget better than the CLI" | You can't. LLM math on token consumption is unreliable and biased toward continuing. The CLI has the real clock. |
| "This one decision is borderline one-way, I'll just act" | Borderline = defer. Over a long session, "just act" on every borderline becomes the majority of decisions and you end up with un-reviewable diffs. |
| "Telegram escalation is overkill for this small choice" | If it is small, it is not a one-way door — act, do not escalate. If it is one-way, it is not small. |
| "The reviewer will catch anything bad" | There is no reviewer. You are alone. The human will see only the final diff + journal. Be conservative. |
| "I'll skip the journal entry for trivial steps" | The journal is how the human reconstructs what you did. Trivial steps are the ones most likely to be questioned on return. |
| "I should check budget every minute just in case" | Every tick burns API cost. Call tick between logical steps, not inside tight loops. |
| "The plan step is too vague, I'll reinterpret it" | Vague plan step = scope-creep-deferred. Do not reinterpret; defer and let the human clarify. |
git push or anything that touches main / master.grace afk tick in the last 15 minutes.docs/afk-sessions/<id>/state.json by hand (never do this — use CLI commands)./afk is for unattended work.$grace-plan first.step-N entries. Nothing to do.Before exiting, confirm:
status=completed or status=stopped (verification: cat docs/afk-sessions/<id>/state.json | jq .status)afk-<ts> branch (verification: git status clean on that branch)decisions.md has at least one entry per iteration that took an actiondeferred.md is listed in the final report with count matching state.deferredbun test and grace lint --path . exit 0 on the final commit (verification: attach exit codes)npx claudepluginhub baho73/grace-marketplace-2 --plugin graceDefines autonomous mode for credo sessions: works approved GO items unattended, enforces keep-alive and budget caps, notifies via ntfy, and hibernates cleanly. Loaded via /credo:session-autonomous.
[ADD v0.11.0] Declare absence — get autonomous work plan for the duration