A human reads "fix the auth bug" and infers: which service, which bug, what the expected behavior is, where to look, what "fixed" means. An agent reads the same ticket and has none of that context. It will either ask (wasting a round trip), guess (risking wrong work), or stall (wasting time).
Most tickets — Jira, Linear, GitHub Issues, internal trackers — are written for humans. They assume shared context, tribal knowledge, and the ability to ask clarifying questions at a desk. Agents have none of this. A ticket that works for a human team is often useless for an agent.
A vague ticket is not incomplete — it is unsafe for an agent to execute.
This is not an agent limitation. It is a contract failure. If the ticket is vague enough that an agent cannot execute it, it was vague enough that a new team member couldn't either — the existing team just compensated with context the ticket never captured.
Nine fields. Not all are required for every ticket, but the more you provide, the less the agent guesses.
The agent needs to know where to work before anything else. A repo URL, a local path, or both. Without this, the agent cannot even start.
Repo: github.com/ppiankov/chainwatch
Local: ~/dev/ppiankov-github/chainwatch
Branch: main
For monorepos, include the subdirectory. For multi-repo changes, list all repos and which part of the change goes where.
Imperative, specific, bounded. The title should describe the outcome, not the process.
What is happening. What should be happening. When it started. What changed. Include error messages, log snippets, reproduction steps. The agent was not in the room when this broke — give it everything a new hire would need.
JWT refresh tokens issued after key rotation return 401.
Affects users whose tokens were issued before the rotation
at 2026-03-25 14:00 UTC. The /auth/refresh endpoint validates
against the new key but the token was signed with the old key.
Expected: refresh succeeds if the original token was valid at
time of issuance. Started after deploy abc1234.
Explicit, testable conditions. Not "it works" — specific assertions the agent can verify.
Acceptance:
- Tokens issued before key rotation refresh successfully
- Tokens issued after rotation also refresh successfully
- Expired tokens (regardless of key) return 401
- Test covers both pre-rotation and post-rotation tokens
- No regression in existing auth_test.go
If the agent cannot verify "done" without asking a human, the acceptance criteria are incomplete.
Same principle as SKILL.md "What this does NOT do." Tell the agent what is out of scope so it doesn't over-engineer or make collateral changes.
Scope:
- Fix the refresh validation only
- Do NOT refactor the auth middleware
- Do NOT change the key rotation schedule
- Do NOT modify the token issuance flow
Agents waste enormous token budgets searching for the right file. If you know where the problem is, say so.
Files:
- internal/auth/refresh.go (the validation logic)
- internal/auth/refresh_test.go (add test cases here)
- config/keys.go (key rotation config, read-only context)
A command the agent runs after making changes. If it passes, the work is done. If it fails, the work is not done. No interpretation needed.
Verify:
go test -race -count=1 ./internal/auth/...
Not "high priority" — that means nothing to an agent. Use a scale it can act on.
Priority: P1 (production users affected, fix before next deploy)
Severity: degraded (auth works for new tokens, fails for pre-rotation)
The agent finished. Now what? If the ticket doesn't say, the agent will either stop and leave artifacts scattered, or guess what comes next. Define the exit path explicitly: what to commit, where to push, who to notify, what the next agent or human should pick up.
Handover:
- Commit with message: "fix: accept pre-rotation JWT tokens in refresh"
- Push to branch: fix/jwt-rotation
- Create PR against main
- Notify: #platform-oncall
- Next: reviewer approves PR, deploy pipeline handles the rest
For multi-agent workflows, handover is the link between agents. Agent A's handover becomes Agent B's starting context. If handover is vague, the chain breaks.
Repo: github.com/ppiankov/authservice
Branch: main
Title: Fix JWT refresh returning 401 after token rotation
Description:
JWT refresh tokens issued before key rotation at 2026-03-25
14:00 UTC return 401 on /auth/refresh. The endpoint validates
against the current key, but pre-rotation tokens were signed
with the previous key. Started after deploy abc1234.
Acceptance:
- Pre-rotation tokens refresh successfully
- Post-rotation tokens refresh successfully
- Expired tokens return 401 regardless of key
- Tests cover both cases
- No regression in auth_test.go
Scope:
- Fix refresh validation only
- Do NOT refactor auth middleware
- Do NOT change key rotation schedule
Files:
- internal/auth/refresh.go
- internal/auth/refresh_test.go
- config/keys.go (context only)
Verify:
go test -race -count=1 ./internal/auth/...
Priority: P1
Severity: degraded
Handover:
Commit, push to fix/jwt-rotation, create PR against main.
Notify #platform-oncall. Reviewer approves, deploy pipeline
handles the rest.
Every field exists to eliminate a category of guessing:
The same principle as every other ANCC convention: collapse expensive exploration into cheap lookup. Tokens are decision receipts. A well-written work order is the cheapest way to reduce agent decision cost.
You don't need a new system. These fields map to what Jira, Linear, and GitHub Issues already support:
The structure is the same. The discipline is writing it explicitly instead of assuming the reader knows.
If an agent has to ask a clarifying question to start work, the ticket failed — not the agent. Write it once, write it completely, and the agent executes without a round trip.
Every ticket is a contract. Treat it like one.