Goal Tracking
Set persistent objectives that guide the agent across sessions.
Goal tracking lets you declare a single overarching objective that the agent carries across every session, compaction, and terminal restart. Where memory captures facts and conventions accumulated over time, a goal is a directive — a statement of intent that shapes how the agent prioritizes and acts until you decide it is done.
What a goal is
A goal is a short piece of text (up to 500 characters) stored in the durable key-value store at ~/.afk/state/kv/kv.db. It has a status — active, paused, or completed — and is injected into the system prompt at the start of every session when it is active.
The agent sees the goal as an <active-goal> block placed between the cross-session memory context and the # Environment section of the system prompt. It is read before the first user message, so it influences how the agent frames every question, every tool invocation, and every plan it builds.
Only one goal can be active at a time. Setting a new goal replaces any existing one, regardless of status.
Why use a goal
Without a goal, each session starts fresh from the user's first message. With a goal, the agent enters every session already oriented toward a broader objective — it can surface whether the current task advances or conflicts with that objective, keep multi-session projects on track, and avoid drift when context window compression has trimmed the conversation history.
Goals are most useful for:
- Multi-session projects — "Ship the authentication refactor before the sprint ends"
- Sustained research — "Understand the performance regression introduced in v2.4"
- Behavioral constraints — "Every response must include a risk assessment"
- Ongoing maintenance — "Keep the test suite green and the type errors at zero"
The /goal slash command
All goal management happens through the /goal slash command in the interactive REPL.
Set a goal
/goal <text>
/goal set <text>Both forms are equivalent. The goal is written to the store immediately. It takes effect at the start of the next session — the running session's system prompt is not rebuilt mid-turn.
/goal Ship the authentication refactor before the sprint ends/goal set Understand the performance regression introduced in v2.4View the current goal
/goal
/goal statusEither form prints the current goal text, its status badge, and the timestamps for when it was set and last updated.
● active Ship the authentication refactor before the sprint ends
set 2026-09-15T14:23:01.000Z · updated 2026-09-15T14:23:01.000ZWhen no goal is set, the command prints: No goal set. Try /goal <objective>.
Pause a goal
/goal pausePauses an active goal. A paused goal is not injected into the system prompt — the agent behaves as if no goal is set until you resume it. Use this when you need to context-switch to unrelated work without clearing the goal entirely.
Only an active goal can be paused. Pausing an already-paused or completed goal is a no-op with a warning.
Resume a goal
/goal resumeTransitions a paused goal back to active. On the next session start, the goal is injected into the system prompt again.
Only a paused goal can be resumed. Resuming an already-active or completed goal is a no-op with a warning.
Mark a goal done
/goal done
/goal completeBoth forms mark the goal as completed. A completed goal is not injected into the system prompt, and it cannot be resumed — if you want to continue the work, set a new goal. You must resume a paused goal before completing it.
Clear a goal
/goal clearRemoves the goal entirely from the store. There is no undo — if you might want the text later, use /goal done instead.
How the agent sees the goal
When a goal is active at session construction, the assembler injects it as:
<active-goal>
Ship the authentication refactor before the sprint ends
(set: 2026-09-15T14:23:01.000Z)
</active-goal>This block appears after the cross-session memory context (<cross-session-memory>) and before the # Environment section. The agent reads it at the start of every turn.
The goal text is sanitized before injection: any XML-like tags are stripped to prevent a crafted goal from injecting structural blocks (such as <cross-session-memory> or <thinking>) into the system prompt.
Only active goals are injected. Paused and completed goals are silently excluded.
Goal changes take effect at the start of the next session. When you run /goal set ... mid-session, the goal is written to the store immediately but the running session's system prompt is not rebuilt. Restart the REPL (or start a new session on any surface) for the agent to see the updated goal.
Status lifecycle
┌──────────────────────────────────────────────────────────┐
│ │
/goal <text> │
│ │
▼ /goal resume
active ──── /goal pause ────► paused ──────────────────────────────┘
│
/goal done
│
▼
completedValid transitions:
| From | To | Command |
|---|---|---|
| (none) | active | /goal <text> or /goal set <text> |
active | active (new text) | /goal <text> replaces the existing goal |
active | paused | /goal pause |
active | completed | /goal done |
paused | active | /goal resume |
paused | active (new text) | /goal <text> replaces the paused goal |
| any | (none) | /goal clear |
There is no path from completed back to active. Complete goals are terminal — set a new one to continue.
Storage
Goals are stored in the shared key-value database at ~/.afk/state/kv/kv.db under namespace goals, key current. This is the same SQLite database used by other durable AFK state, and it is shared across all surfaces that point to the same AFK_STATE_DIR.
The stored document has this shape:
{
"text": "Ship the authentication refactor before the sprint ends",
"status": "active",
"createdAt": "2026-09-15T14:23:01.000Z",
"updatedAt": "2026-09-15T14:23:01.000Z",
"createdBy": "<session-id>"
}The createdBy field records which session set the goal and is informational only.
To relocate the store to a different path, set AFK_STATE_DIR:
export AFK_STATE_DIR=/path/to/shared/stateThe goal database is then resolved under <AFK_STATE_DIR>/kv/kv.db. See Environment Variables for the full list of path overrides.
Cross-surface sharing
Because the goal store lives on disk, it is shared across every AFK surface pointing to the same AFK_STATE_DIR:
- Interactive REPL (
afk interactive) - Telegram bot
- CLI
chat(afk chat "...") - Daemon sessions
- Scheduled tasks
A goal set in a Telegram session is active in the next REPL session, and vice versa.
Example workflow
Here is a complete workflow for a multi-session refactor:
# Start of sprint — set the goal
/goal Ship the authentication refactor before the sprint ends
# Work across multiple sessions — agent sees the goal in every prompt
# Mid-sprint — switch to an urgent unrelated bug fix
/goal pause
# ... fix the bug across one or more sessions ...
/goal resume
# Sprint ends — mark it done
/goal done
# New sprint — start fresh
/goal Ship the data export feature with CSV and JSON supportThroughout this sequence, the agent enters each session already oriented toward the active objective. When the goal is paused, sessions run without it. When it is resumed or replaced, the next session start picks it up automatically.