← the whole session plugin/skills/intent/SKILL.md
How to write intent statements that a human can validate without guessing. Use when writing intent statements, testable contracts, scope declarations, or any documentation that describes what the system does or what a person experiences. MUST be consumed before writing to the Intent DB, before creating verification contracts, before writing journey documentation, or before any /declare-scope.
How to Articulate Intent
Why This Skill Exists
Agents write intent statements that force humans to guess. A statement like "the extraction fires every 5 messages" sounds precise but leaves out which messages are counted, what "fires" means, what happens when it doesn't fire, and whether this behavior is intentional. The human reading it has to fill those gaps from their own imagination — and if they guess wrong, every decision built on that guess compounds the error. That's hallucination, and it starts in documentation, not in code.
This skill exists to make every intent statement self-validating: a human reads it and can immediately say "yes that's right" or "no that's wrong" without needing to look at the code or ask a follow-up question.
The Two Types of Intent
System Intent
Describes what the system does — the mechanics, the conditions, the behavior. Written for a human who needs to confirm whether the system should work this way.
Format:
When {every condition that must be true, described as what's happening in the person's experience, not as variable names} then {the specific system responsible, named as what it does not what it's called} should {the exact behavior, described as its effect on the person's experience}
UX Intent
Describes what the person experiences — what they see, feel, encounter. Written for a human who needs to confirm whether this is the right experience.
Format:
When {every condition that must be true, described as what the person has done or what state they're in} then {the person in this moment} should {exactly what happens for them, with the precision of the code but in human terms}
The Critical Distinction
System intent and UX intent describe the SAME behavior from two angles. System intent says what the machine does. UX intent says what the person experiences because of what the machine does. Both must be precise. Neither can drop constraints.
The system intent for a feature might say: "When a person has completed a task and closed the app, and their completed-task count for the trailing 7 days has just reached 3, 6, 9, or 12 (counting only tasks they finished themselves, not ones assigned to them, reopened, or completed by a teammate), the weekly-recap system should silently build a summary of that week's completed tasks and save it to their account."
The UX intent for the same feature says: "When a person has completed their 3rd task this week, the system should quietly put together a short recap of what they got done — they won't see anything happen in the moment, but the next time they open the app, that recap will be waiting for them."
Both are precise. Both are complete. Neither uses variable names as substitutes for meaning. The system intent tells you HOW it works. The UX intent tells you WHAT THE PERSON GETS.
Wrong vs Right — System Intent
WRONG:
When a person completes a task and closes the app, the
taskTracker.js:204adds a job toweeklyRecapQueue— this fires on EVERY task completion, for ALL account types (free, trial, paid), with no pre-filter
Why it's wrong:
taskTracker.js:204means nothing to the reader — it's a line number, not a behaviorweeklyRecapQueueis an internal name — the reader doesn't know what this queue does- "adds a job" is implementation detail — the reader needs to know what HAPPENS, not what gets queued
- "fires on EVERY task completion" — the reader can't tell if this is intentional or a bug
- The reader has to guess: is this a problem? Is this by design? What does it mean for the person?
RIGHT:
Every time someone finishes a task and closes the app — whether they're on a free plan, a trial, or paying — the system quietly checks whether it has enough completed tasks from them this week to build a recap worth sending. This happens after every single task completion, no exceptions. The check itself doesn't always trigger the recap (that only happens once the person has completed 3 or more tasks in a 7-day window), but the system is always watching for the right moment. This is intentional — we want the system ready to send the recap the moment there's enough to show, regardless of who the person is or what plan they're on. (
taskTracker.js:204queues this check via the weekly-recap service)
Why it's right:
- Describes what happens to THE PERSON (they finish a task and close the app)
- Names the behavior in human terms (checks whether there's enough to recap)
- States whether it's intentional ("This is intentional — we want...")
- Includes ALL users without using tier names as substitutes
- The code reference is a pointer at the end, not the explanation itself
- The reader can immediately say: "yes, that's what I want" or "no, I only want this for paying users"
Wrong vs Right — UX Intent
WRONG:
When the user's completion count reaches the RECAP_THRESHOLD, the recapPayload is generated and saved to the account document.
Why it's wrong:
- "RECAP_THRESHOLD" is a variable name standing in for its meaning
- "recapPayload" is jargon — the reader doesn't experience a "recap payload"
- "account document" is a database concept, not a user experience
- No indication of what the person sees, feels, or encounters
- No indication of what happens if it fails
RIGHT:
When a person has completed their 3rd task in the last 7 days (counting only tasks they finished themselves — tasks assigned but not completed, reopened tasks, or tasks a teammate finished don't count toward this), the system quietly builds a short recap of what they got done that week and saves it to send the next time they open the app. The person doesn't see anything happen in the moment — their work continues without interruption. But behind the scenes, a summary has been prepared, and it will greet them the next time they return. If building the recap fails for any reason — the summary generator errors, the template is missing, the data can't be read — nothing bad happens to the person. Their work continues. But the recap never gets saved, which means they simply won't see a "here's what you did this week" message next time — no error, no sign anything was supposed to happen.
Why it's right:
- Describes the trigger in terms of what the person has DONE (completed their 3rd task)
- Clarifies the counting rule without using the variable name
- Describes what the system builds in plain terms (a short recap) not data terms (recapPayload)
- Describes what the person EXPERIENCES (nothing in the moment — it's silent)
- Describes the PURPOSE of the recap (waiting for them next time they return)
- Describes every failure mode and its downstream consequence
- A human reading this knows exactly what to validate
When to Use Each Type
| Writing for... | Use... | Because... |
|---|---|---|
| Intent DB entries | UX intent | The human validates whether the EXPERIENCE is right |
| Verification contracts | System intent | The system validates whether the BEHAVIOR is right |
| Journey documentation | Both, woven together | The human needs to see both what happens and why |
| Scope declarations | UX intent | The scope is about what changes for the person |
| Test descriptions | System intent | Tests verify specific behavioral conditions |
| Commit messages | System intent | Developers need to know what changed in the system |
| Proposals to the decision-maker | UX intent first, system intent as supporting detail | They decide based on experience, not mechanics |
Rules
Variable names are pointers, not substitutes. You can include
salesPitchObjectin parentheses after explaining what it IS — but you cannot use it AS the explanation. "The system captures their vision (saved assalesPitchObject)" — yes. "ThesalesPitchObjectis generated" — no.Every statement must make clear: is this intentional? If you're describing existing behavior, say whether it's by design or accidental. "This is intentional — we want X" or "This appears unintentional — the system does X but the likely intent was Y."
Every constraint must be stated. If the code checks 4 conditions before something happens, all 4 appear in the intent statement. Dropping one is not simplification — it's a lie.
Failure modes are part of the intent. What happens when the thing DOESN'T work is just as important as what happens when it does. Silent failures are especially critical because the person doesn't know something went wrong.
Sequence matters. Events unfold in order. The statement should follow the same order the person experiences them, not the order the code executes them.
The reader should never have to guess. If reading your statement requires the reader to fill in any gap from imagination, the statement is incomplete. Guessing is hallucination.
Feedback Loop
If you find this skill doesn't cover a case you're facing — a type of intent statement that doesn't fit either format, a situation where the rules conflict — state what you're trying to articulate, what format you tried, and why it didn't work. This skill is v1 and will evolve.
Composability
This skill is consumed by:
/intent-lifecycle— before writing any intent/declare-scope— before decomposing scope into testable statements/verification-contracts— before writing verification conditions/intent-db— before proposing or writing intent entries/anthropic-proof-its-fixed— when writing the narrative section of evidence packages/intent-journey-documentation(if installed; otherwise/intent-journey-documentation-v2) — any journey documentation in the intent vault