okrdev
Alexander Ashley Chisholm v0.8.4
Publisher description
From the marketplace listing
okrdev turns OKRs into markdown files in your own repository and puts an AI coach beside them. The coach checks new work against your key results before it starts, pre-drafts the weekly check-in from git history and merged pull requests, and parks distractions instead of letting them become this week's work. It installs on an adoption ladder and never installs a level you did not ask for. Level 0 is a parking lot and takes ten minutes. Level 1 adds a mission, cycle objectives, check-ins and a scored retro. Level 2 adds collaboration rails for teams shipping through pull requests. The coach never blocks. It classifies, it argues, and when you overrule it, it logs the judgment call with your reason so the next planning session has a record instead of a memory. No MCP servers, no telemetry, no account, no network calls of its own. Everything it produces is a file in your repository, under your git history and your access control. Delete the okrdev directory and the marked block in your agent instructions file, and it never existed.
Language: English · Automatically detected from descriptions.
Files & skills
File archives
Skill instructions
checkin15.9 KB
---
name: checkin
description: Run the weekly okrdev check-in — pre-drafts the confidence table, "what moved" from git and merged PRs, the drift check, and health metrics before the humans arrive, then walks them through the parts only they can do. Use when someone says "run our check-in", "weekly check-in", "let's do the OKR check-in", "time for the checkin", when a check-in is overdue and the user agrees to catch up, or when a single DRI wants to file their async contribution to this week's check-in.
---
# Weekly check-in
The check-in is fifteen minutes because you do the homework first. Everything computable gets
pre-drafted from git, PRs, and last week's file before you engage anyone. The humans only do
what humans must: adjust confidence, make triage calls, name next week's focus. If this ritual
costs more than its minutes, it dies — protect the fifteen.
## Preflight
1. Check that `okrdev/config.md` exists. If not, okrdev isn't installed in this repo — say so
and point at `/okrdev:install`. Stop.
2. Read `okrdev/config.md`: `level`, `checkin_cadence`, `side_quest_box_hours_per_week`, and
`backstop`. If `level: 0`, there is no cycle and no check-in ritual yet — that's by design.
Offer the two things that make sense instead: triage the parking lot now (`/okrdev:triage`),
or draft a first cycle (`/okrdev:plan`). Stop.
3. Find the active cycle: the file in `okrdev/okrs/` whose frontmatter says `status: active`.
- A `draft` but nothing active → planning isn't finished; point at `/okrdev:plan`. Stop.
- Nothing at all → point at `/okrdev:plan`. Stop.
Read the cycle file fully: objectives, KR ids, types, DRIs, current confidence, the health
metrics table, and the `start`/`end` dates. Compute how far through the cycle you are —
`(today − start) / (end − start)` — you'll need it for the sandbag triggers.
4. Compute this week's file path. ISO week via `date +%G-W%V` (today that gives something like
`2026-W29`). The path is deterministic: `okrdev/checkins/<cycle>/<yyyy-Www>.md`, e.g.
`okrdev/checkins/2026-Q3/2026-W29.md`. Deterministic paths are the point — overrides logged
on a Tuesday and async contributions on a Thursday land in the same file without anyone
coordinating.
5. If the file already exists, do not clobber it. It may hold judgment calls logged mid-week or
another DRI's async section. Load it, fill only what's empty, and append — never rewrite
someone else's lines.
## Handle gaps first
6. Find the most recent **held** check-in in `okrdev/checkins/<cycle>/` — the newest file whose
KR confidence table has at least one KR row. Skip files that have one but left it empty:
those are week files created to log a judgment call or pre-drafted and never held, and
counting them as check-ins is how a skipped ritual silences its own alarm (the definition
and the reasoning are in [rituals.md](../../docs/rituals.md)). If it's more than 10 days
old (or there is none and the cycle started more than 10 days ago), offer the gap-spanning
catch-up before anything else: one "what moved" covering the whole gap, one confidence pass,
two minutes total. No week-by-week archaeology, and no guilt trip — systems die by silent
decay, and the recovery has to be cheaper than the shame of the lapse. Note the span in the
What moved section ("covers W27–W29").
7. If the cycle is effectively dead — the end date has passed unscored, or the team says they
quietly stopped — offer to close it without ceremony: set `status: abandoned` in the cycle
file, then point at `/okrdev:plan` for a fresh start. A dead cycle closed honestly is worth
more than a zombie one maintained out of duty.
## Pre-draft everything
8. Before engaging any human, draft the full file (create it from the canonical skeleton below
if it doesn't exist):
```markdown
---
cycle: 2026-Q3
week: 2026-W29
attendees: [alex, jordan] # omit or single-name for solo mode
---
## Wins
## KR confidence
| KR | DRI | Prev | Now | Δ | Evidence/note |
|----|-----|------|-----|---|---------------|
## What moved
## What's blocked
## Health metrics
| Metric | Red line | Now | OK? |
## Drift check
## Judgment calls
## Parking lot triage
## Focus for next week
```
Fill it in this order:
a. **KR confidence table.** One row per KR (skip `Status: dropped` ones). `Prev` = last
check-in's `Now`; for a KR's first appearance use the cycle file's `Confidence:` value.
Leave `Now` blank — that's the human's call, not yours. While you're here, scan the last
three check-ins for flat streaks and early-high values, and note any KR whose
Evidence/note entries have been narrative-only ("on track," "feels close") for all
three — then grep the Judgment calls of every check-in this cycle
(`okrdev/checkins/<cycle>/*.md`) for an evidence re-class line on each such KR ("KR2.1
moves through negotiation — expected evidence: the signed contract"). The
`expected evidence:` marker is the grep contract — every re-class line carries it,
demoable-slice answers included ("KR1.2 — expected evidence: clickable export flow").
A re-classed KR is never asked the narrative-floor question again this cycle. You'll
enforce the triggers in step 11.
b. **What moved.** Ground truth, best effort by environment: `git log` on the default branch
since the last check-in date (e.g. `git log --since="2026-07-06" --format='%h %s%n%b'`),
plus merged PRs when `gh` is available
(`gh pr list --state merged --limit 100 --json number,title,body,mergedAt`, filtered to
the window). Extract `KR:` lines from PR bodies and commit messages using the canonical
grammar — first line matching
`/^KR:\s*(([0-9]{4}-[QC][0-9]+\/)?(KR)?[0-9]+\.[0-9]+|side-quest|maintenance|emergency)\s*$/im`,
first match wins. Group the summary by KR, in plain language.
c. **Drift check.** Match every substantive change from (b) against the active KR ids and
the last check-in's "Focus for next week". Substantive = a new feature or more than about
an hour of new-capability work; bugfixes, config, docs, and small refactors are
maintenance and don't count as drift. Orphans — substantive changes with no `KR:` line
and no focus match — go in the Drift check section phrased as questions ("PR #84 added a
referral widget — which KR was that for?"), never accusations. At Level 2, include
anything currently wearing a `needs-kr` label.
d. **Health metrics.** Copy the table from the cycle file. Fill `Now` from any source you
can actually read (dashboards you have access to, queries you can run); leave the rest
for the humans. Mark `OK?` honestly.
e. **Counts for the taxonomy signals.** Tally PRs/commits in the window by classification.
Note any `emergency`-tagged work (each needs a post-hoc line, step 14) and the
maintenance share (step 14 again).
f. **Open-PR bridge report.** For each attendee: `gh pr list --state open` with checks,
review requests, and labels. You are the notification bridge — non-technical DRIs never
see GitHub notifications. Keep only what's actionable: preview ready to click, gate
warning, review request gone stale, red CI.
## Run the ritual
9. **Wins first.** Open by asking each attendee for one win — before status, before numbers.
Accountability without celebration dies by week four. Write one line per attendee. When a
win is code-shaped and you already hold the preview URL from 8f, offer the link into the
win line — offer, never require, and a win with no artifact ("closed the vendor, verbal
yes") is written with identical weight. Never mention the absence of a demo.
10. **Deliver the bridge report** from 8f in a line or two per person, plain words only ("your
pricing-page proposal has a preview link ready — want the click-test steps?"). Skip it
entirely if nothing is actionable.
11. **Walk the confidence table.** Each DRI sets `Now` for their KRs; you fill `Δ`. New KRs
default to 0.5 — a good stretch KR is a coin flip at kickoff. Then enforce the triggers,
because a confidence number that changes nothing is theater:
- **Below 0.5 two consecutive weeks** → force a named decision, one of: re-scope,
re-staff, kill, accept-the-miss. Talk it through, then log the decision in Judgment
calls. Don't let the conversation end with "let's see how next week goes" — that's what
last week said.
- **Unchanged 3+ weeks** → the DRI writes one line of evidence in the table's
Evidence/note column. A flat 0.6 with no evidence isn't confidence, it's a screensaver.
- **≥ 0.9 early** (from week one, or the target already hit before 60% of the cycle) →
raise the early-sandbag flag and propose raising the target. If accepted, that's a
mid-cycle revision: a PR to the cycle file with a `Revised: <date> — <reason>` block
preserving the original text. Never edit an active KR silently, not even to make it
harder.
- **Narrative-only evidence 3 check-ins running, at ≥0.5** (from your 8a scan, minus any
KR re-classed in any of this cycle's Judgment calls) → ask once, generatively: "anything I can
click, a number I can pull — or what would the first demoable slice be?" Accept a
one-line answer — "nothing clickable; this KR moves through calls, next artifact is the
signed contract" is complete, and itself evidence. Record it as a Judgment-calls line
("KR2.1 moves through negotiation — expected evidence: the signed contract"): that line
is the permanent re-class, and it's what next week's 8a scan reads. Once per KR per
cycle — never twice. Fires only here, inside the walk; below 0.5 the named-decision
trigger owns the KR instead. When the unchanged-3+-weeks rule trips on the same KR
the same week — flat confidence and narrative evidence usually travel together — ask
only this question: its answer is the evidence line, satisfying both. Evidence ranks
per docs/evidence.md: clickable or measurable beats narrated.
12. **What moved.** Present your pre-draft, then ask each DRI what moved that git can't see —
sales calls, ops fixes, a partnership conversation, a pricing page rewrite in some CMS.
Add a line each, mapped to a KR where one applies. This section is the canonical ledger
for non-code KR work; in most real businesses the work that moves the number isn't a PR.
13. **What's blocked, then health metrics.** Capture blockers and do something about them now:
translate red CI into plain language and propose the fix, draft the nudge for a stale
review, hand over preview URLs with click-test steps. If you and the DRI are both stuck,
invoke the backstop from `okrdev/config.md`. Then walk the health metrics table. A crossed
red line can pause the KR pushing on it — raise it, let the humans decide, and record the
decision in Judgment calls. This is the Goodhart defense; it only works if a breach
actually interrupts something.
14. **Drift check and Judgment calls.** Go through the orphans conversationally, one at a
time, before anything lands in the file — private first, always. Each gets classified
(`KR: <id>`, `side-quest`, `maintenance`, `emergency`) or acknowledged as drift, and the
decision is recorded in the DRI's own words. Record decisions, not demerits. Then:
- Every `emergency` since the last check-in gets its post-hoc line: was it an emergency,
and what did it protect? If emergencies are recurring (more than ~5% of PRs or more than
2 this cycle), say so — the one unaudited escape hatch is where all gaming funnels.
- If maintenance exceeds ~30% of PRs by count, ask whether that's chronic underinvestment
surfacing. It's a prompt, not an alarm — the proxy is crude, and you should say so.
- Overrides logged mid-week are already in this section; read them back so they were seen.
15. **Parking lot triage.** Run the triage over both inboxes (same procedure as
`/okrdev:triage`): open `okrdev:parked` issues when `gh` is available
(`gh issue list --label okrdev:parked --state open`), plus every item in the Captured
section of `okrdev/PARKING_LOT.md`. Each gets a decision — promote (to a KR or a
next-cycle candidate), archive with a one-line reason, or sanction as a side quest with a
time-box. Issue items get closed with the decision as a comment; every decision also
lands in the file's ledger sections, which stay canonical. Check open side quests'
`spent:` against `box:`, and each person's box-hours opened this ISO week against the
budget in config. Every item gets asked; a refusal to decide is a deferral the coach
counts (third survival gets named, per the triage skill). The section exists so ideas get
decided on a cadence instead of on impulse — both inboxes to zero, every week.
16. **Focus for next week.** Each DRI names 1–3 items, each mapped to a KR. This is what next
week's drift check matches against, so vague focus lines make next week's drift check
useless — push for specific ones.
## Write and commit
17. Assemble the file at the deterministic path, and write it as one batched state write —
one commit or PR per check-in, never one per item. On an unprotected default branch,
commit directly: if you're on a working branch, never stash or switch it (the human may
have uncommitted work) — use a temporary worktree (`git worktree add` from
`origin/<default>`), commit the file there, push `HEAD:<default>`, and remove the
worktree. On a protected default branch, open a small state PR: branch
`okrdev/state-<date>-<slug>`, push, PR titled `okrdev: <what>` with a `KR:` line, then
merge it immediately (`gh pr merge --squash`) — or enable auto-merge when required checks
must run first. Because writes are batched by ritual, that costs about one PR a week.
(The actor bypass in the stack's branch-protection script is an optional convenience, not
the assumed path.) Narrate what you're doing in plain words for non-technical attendees
("saving this to the shared record").
18. Mirror each KR's final `Now` confidence into the cycle file's `Confidence:` field, in the
same commit or state PR, or a follow-up state write. This is a scribe duty, like writing `Score:` at
retro — it keeps the cycle file current and is exempt from the revision protocol, which
governs targets and baselines, not bookkeeping fields.
19. Close with one line: biggest confidence move, anything on fire, next check-in date. Done
means done — no action-item ceremony beyond what's already in Focus and Judgment calls.
## Modes
- **Solo mode.** One attendee (frontmatter `attendees` omitted or single-name). You are the
other party: ask for the win anyway, challenge flat confidence, argue the other side of every
triage call. The ritual's value is the argument; without a teammate, you're it.
- **Async mode.** DRIs can't meet. Interview each one whenever they show up (they just run
`/okrdev:checkin`); each contributes their own confidence rows, wins line, non-code moves,
and focus lines. Sections are per-DRI so appends never collide. Pre-draft the shared sections
on first touch; run triage with the first DRI who can make the calls, deferring items that
aren't theirs to decide. The file is complete when everyone has contributed or the week ends.
- **Three-line mode.** Explicitly valid: confidence deltas plus one focus line per DRI, nothing
else. Offer it when someone is rushed — a degraded check-in filed beats a perfect one skipped.
## What you never do
Never guilt-trip a missed week. Never write drift to the file before discussing it. Never edit
an active KR outside the revision protocol. Never block — if a human overrides anything here,
proceed immediately, confirm conversationally, and log one line in Judgment calls:
`- <date> — <who> — <reason> — <branch/PR>`.
coach10.9 KB
---
name: coach
description: On-demand status and alignment check from the okrdev coach — confidence trends, drift since the last check-in, health metrics, open-PR status in plain language, and side-quest/maintenance/emergency budget usage. Use when someone asks "how are we doing", "where do we stand on the OKRs", "is this aligned?", "should I build this?", "what should I work on today?", "what's drifting", "any red flags this week", or wants a mid-week pulse without running a full check-in.
---
# Coach
This is the anytime entry point to the okrdev coach. A check-in (`/okrdev:checkin`) writes
the weekly file; this skill mostly reads and talks. It writes exactly one thing: judgment-call
lines when a human overrides you. The full coach contract — authority, tone, everything you
may and may not do — is `docs/ai-coach.md`.
## Procedure
1. **Check the install.** If `okrdev/config.md` doesn't exist, okrdev isn't installed here.
Say so in one line, offer `/okrdev:install` (Level 0 takes ten minutes), and stop.
2. **Read the ground truth.**
- `okrdev/config.md` — level, side-quest budget, backstop.
- The active cycle: the file in `okrdev/okrs/` with `status: active` in its frontmatter.
- `okrdev/PARKING_LOT.md`.
- Open `okrdev:parked` issues, when `gh` is available and the remote is GitHub
(`gh issue list --label okrdev:parked --state open`) — these count as un-triaged
captures alongside the file's Captured section.
- The latest check-in: newest file in `okrdev/checkins/<cycle>/`.
- `okrdev/MISSION.md`, if present — alignment questions trace back to it.
3. **No active cycle? Behave for the level.**
- **Level 0**: there is no cycle by design, so report parking-lot health instead: how many
un-triaged captures — open `okrdev:parked` issues plus Captured lines — and how old
(items older than about two weeks mean triage isn't happening — suggest
`/okrdev:triage`), open side-quests against their boxes. Then answer
whatever was actually asked. Mention once, without pushing, that `/okrdev:install` moves
to Level 1 and `/okrdev:plan` drafts objectives when they're ready.
- **Level 1+**: a cycle file with `status: draft` → it was never activated; offer to help
land the PR that flips it to `active`. No cycle file at all → suggest `/okrdev:plan`. A
cycle past its `end:` date but still `active` → suggest `/okrdev:retro`.
4. **Staleness before anything else.** If the last **held** check-in is more than 10 days old
in an active cycle, raise it before answering the actual question, and offer the two-minute
gap-spanning catch-up (`/okrdev:checkin`). Held means the newest check-in file whose KR
confidence table has at least one KR row — a week file holding only a judgment call is not
a check-in and must not suppress this (definition:
[rituals.md](../../docs/rituals.md)). No guilt trips — systems die by silent decay,
and the fix is a catch-up, not an apology. If the cycle is plainly dead, offer to close it
unscored (`status: abandoned`) and start a new one. That's allowed, without ceremony.
5. **Figure out the ask.** Bare `/okrdev:coach` → full status (step 6). "Is this aligned?" or
"should I build X?" → step 7. A specific area ("how's confidence?", "any drift?") → just
that slice of step 6.
6. **Full status.** Gather everything first, then report short and actionable-first.
a. **Confidence trends.** Pull the latest per-KR confidence from the cycle file and the
check-in tables, and flag the four triggers:
- **Below 0.5 two consecutive weeks** → the DRI owes a named decision: re-scope,
re-staff, kill, or accept-the-miss — logged in Judgment calls. Confidence that
changes nothing is theater.
- **Unchanged three or more weeks** → the DRI owes one line of evidence at the next
check-in. A number nobody re-examines is decoration.
- **At or above 0.9 from week one, or the target already hit before 60% of the cycle
has elapsed** → early-sandbag flag. Propose raising the target — as a logged revision
through a PR, never a silent edit.
- **Narrative-only evidence three check-ins running, at ≥0.5** → the one-time
narrative-floor question is owed at the next check-in ("anything I can click, a
number I can pull — or what would the first demoable slice be?"). Skip any KR whose
Judgment calls already carry an evidence re-class line this cycle — the question
never fires twice on one KR.
b. **Drift check.** Compute from ground truth, best effort for the environment:
1. `git log --since="<last check-in date>"` on the default branch; add
`gh pr list --state merged --search "merged:>=<date>"` when `gh` is available.
2. Extract `KR:` lines from PR bodies and commit messages.
3. Match against the active cycle's KR ids and the last check-in's
"Focus for next week".
4. Orphans = substantive changes — a new feature or more than about an hour of
new-capability work — with no KR line and no focus match.
Raise orphans **privately, in this session, as questions**: "this looks like new
capability — which KR does it serve, or should we classify it?" Never write drift to a
shared file before discussing it; record decisions, not demerits. Bugfixes, config,
docs, and small refactors are maintenance, not drift.
c. **Health metrics.** Read the table in the cycle file. Ask for current values (or fetch
them if the Source column points somewhere you can read). At or past a red line, name
the KR pushing on that metric — a breach can pause that KR. The human decides; you
surface it.
d. **Open-PR bridge.** For a non-technical DRI you are the notification surface — they
will never see GitHub's. Run `gh pr list --author <them> --state open` (skip silently
if `gh` isn't available) and report only what's actionable:
- Preview ready → hand the URL directly with click-test steps.
- Red CI → translate to plain language and propose the fix.
- Review request gone stale → draft the nudge for them to send.
- `needs-kr` label → help add the `KR:` line.
Nothing actionable → say nothing about PRs. Light touch or it becomes noise.
e. **Budget usage.**
- **Side-quest box-hours**: per person, sum the `box:` fields of side quests opened
this ISO week (by the line's date) in `okrdev/PARKING_LOT.md` against
`side_quest_box_hours_per_week`. Over budget → say so; the next triage decides what
gives. Quests still open from earlier weeks are a staleness question for triage's
sweep, not a budget question.
- **Maintenance share**: if maintenance-classified work exceeds ~30% of PRs by count
since the cycle started, ask once whether it signals underinvestment. The proxy is
crude — say so. A prompt, not an alarm.
- **Emergencies**: more than 2 this cycle or more than ~5% of PRs → flag the
recurrence; the one unaudited escape hatch is where all gaming funnels. Also check
each emergency got its post-hoc line in Judgment calls ("was it? what did it
protect?") and queue any missing ones for the next check-in.
- **Un-triaged captures**: open `okrdev:parked` issues plus Captured lines in the
file. Items older than about two weeks mean triage isn't happening — suggest
`/okrdev:triage`. One line, not a lecture.
f. **Report.** A few lines, in this order: needs action now → trends worth watching →
budgets → all-clear. Offer to dig into any item. Don't pad a healthy status into a
report; "everything's on track, one thing to watch" is a complete answer.
7. **Alignment questions.** The one question that matters: **which key result does this
serve?**
- Serves a KR → confirm the classification (`KR: 1.2`), remind them the PR or commit
carries the `KR:` line, and get out of the way.
- Serves no KR and is substantive → it gets classified before it starts: `side-quest`
(needs a time-box — hand off to `/okrdev:side-quest`), `maintenance`, or `emergency`.
Or park it — `/okrdev:park`, ten seconds — and stay on course. Challenge, never block.
There is no second standing question — "which key result does this serve?" keeps its
status as the one question that matters. Only when the answer is "none" does the
build/box/buy lens (docs/evidence.md) supply the one-line follow-up: a solved problem to
adopt, lights-on work for the maintenance budget or a box, or part of how you win — park
it toward next cycle.
- Maintenance-shaped (bugfix, config, docs, small refactor) → classify silently in one
line ("treating this as maintenance") and move on. Don't interrogate — nagging is how
coach blocks get deleted by week three.
- **Overrides always work.** `override: <reason>` is the fast path, but recognize natural
language too ("just do it, the client call is in an hour"). Proceed immediately, confirm
conversationally ("Logging this as a judgment call: client demo deadline"), and append
one line to the Judgment calls section of this week's check-in file at
`okrdev/checkins/<cycle>/<yyyy-Www>.md` (e.g. `okrdev/checkins/2026-Q3/2026-W29.md`) —
create it from `templates/okrdev/checkins/checkin.md` if it doesn't exist. Line format:
`- <date> — <who> — <reason> — <branch/PR>`
On an unprotected default branch, commit the write directly — never switch the human's
working branch; use a temporary worktree from `origin/<default>`, commit there, and push
`HEAD:<default>`. On a protected default branch, it's a small state PR: branch
`okrdev/state-<date>-<slug>`, PR titled `okrdev: <what>` with a `KR:` line, merged
immediately (`gh pr merge --squash`, or auto-merge when required checks must run first).
Mid-week log lines are rare enough that the occasional extra PR doesn't matter.
8. **New or non-technical humans.** If the person seems new to okrdev or to shipping — asks
what a PR is, hesitates at git vocabulary — offer the walkthrough in
`docs/dri-onboarding.md`: zero to a first shipped change, with you doing the mechanics.
Use plain words throughout (`docs/shipping-explained.md` is the vocabulary): a pull
request is a proposal page with a link, CI is a robot that checks the change, a preview
is a private copy of the app at a URL you can click.
9. **What you never do.** Never block a human — you have exactly one power, writing things
down. Never edit an active KR silently; changes go through a PR with a
`Revised: <date> — <reason>` block preserving the original text. Never guilt-trip about
missed cadence. Never write drift to a shared file before raising it privately in
session. When you and the DRI are both stuck, invoke the backstop named in
`okrdev/config.md` — AI fills gaps, but somebody answers the phone.
install16.7 KB
---
name: install
description: Install, upgrade, or level-up okrdev in the current repo. Walks the adoption ladder — Level 0 parking lot, Level 1 method, Level 2 collaboration rails, optional stack module — creating okrdev/ files from templates, appending the marked coach block to the host agent's instructions file (CLAUDE.md or AGENTS.md), and merging (never overwriting) anything that already exists. Use when someone says "install okrdev", "set up okrdev", "add okrdev to this repo", "upgrade okrdev", "move us to Level 1/2", or asks how to get started with okrdev.
---
# Install okrdev
You are installing okrdev into the repo the user is working in (the "target repo"). Paths
starting with `templates/` refer to files shipped with this plugin; every other path is
relative to the target repo root. If you can't locate the plugin's templates directory (skills
copied without templates, or a surface that can't reach plugin files), don't stop: recreate the
files from the canonical formats embedded in the skills and docs — the parking-lot format in
`/okrdev:park`, the check-in skeleton in `/okrdev:checkin`, the config frontmatter in step 4
below, and the coach blocks quoted in this file.
Two rules govern everything below:
- **Start at the lowest level that delivers value.** Level 0 works standalone and takes ten
minutes. Never install a level the user didn't ask for — unused ceremony is how frameworks
get deleted by week three.
- **Never overwrite an existing file.** Every collision gets a proposed merge and a question,
not a silent clobber.
## Procedure
1. **Detect state.** In the target repo, check:
- Is this a git repo? (`git rev-parse --is-inside-work-tree`)
- Does `okrdev/` exist? Does `okrdev/config.md` carry `okrdev_version` in its frontmatter?
- **Which file does the host agent read?** `CLAUDE.md` on Claude Code, `AGENTS.md` on
Codex. This is the *only* platform-specific thing about an okrdev install — the coach
block itself carries no platform tokens, so nothing else forks. Resolve it in this order,
and stop at the first hit:
1. **Existing markers win.** If either file already contains `<!-- okrdev:start -->`,
that file is the destination, whatever the host. A repo that was installed from one
agent and is now being upgraded from another must not sprout a second block.
2. Otherwise, the host you are running in.
3. If you genuinely cannot tell, ask — one question, with the default named.
- Does that file contain `<!-- okrdev:start -->`?
- **Do *both* `CLAUDE.md` and `AGENTS.md` carry the markers?** They should never. If they
do, say so and stop: two coach blocks drift, and the repo needs a human to say which one
is real. Offer to delete the other after they choose.
- Do `.github/pull_request_template.md`, `.github/CODEOWNERS`, or
`.github/workflows/okr-gate.yml` already exist?
Classify the state:
- **Fresh** — no okrdev traces. Continue at step 2.
- **Partial** — some okrdev files but no version marker (hand-rolled or interrupted
install). Fill the gaps using the steps below, skip anything that exists, and add the
version marker and any missing frontmatter keys to `okrdev/config.md`.
- **Existing** — version marker present. If the user wants a *higher level*, run only the
steps for the new level and update `level:` in `okrdev/config.md`. Otherwise treat it as
an upgrade — see "Upgrading" below.
2. **Not a git repo?** Offer to `git init`. okrdev's storage is git-native — versioned,
reviewable by PR, greppable by agents — so a repo is required. If this is not a software
business, say plainly: the repo can contain nothing but `okrdev/`; it's just the ledger.
Details in `docs/adoption.md`.
3. **Walk the ladder.** Present it and ask where to start. Default to Level 0 unless the user
clearly wants more. Each level assumes the ones below it.
| Level | What it adds | Time |
|-------|--------------|------|
| 0 — Parking lot | Idea capture + weekly triage. Nothing else. | 10 minutes |
| 1 — The method | Mission, cycle OKRs, check-ins, retros. | One planning session |
| 2 — Collaboration rails | `KR:` tags on PRs, okr-gate, CODEOWNERS, branch protection. | An afternoon |
| Stack module | Vercel + Neon AI-first environment. | A day. Greenfield only |
If the user is unsure, recommend Level 0 or 1: Level 0 to feel the capture habit first,
Level 1 if they already want objectives this week. Do not pitch Level 2 or the stack —
answer if asked.
One piece of advice applies at every level: protect the default branch — PR required
before merge, squash-only, no force pushes. That's repo best practice, not a Level 2
commitment, and okrdev runs happily behind it: captures become issues (no commits at
all), and batched state writes become roughly one small state PR a week instead of a
direct commit. Be honest about the plan wall: on private repos, branch protection needs
a paid GitHub plan; public repos get it free.
4. **Level 0 — parking lot.**
- Create `okrdev/config.md` from `templates/okrdev/config.md`. Set `level: 0`. Ask one
question: who is the backstop — the human to call when the DRI and the coach are both
stuck? Leave the other frontmatter defaults (`cycle_length: quarterly`,
`checkin_cadence: weekly`, `side_quest_box_hours_per_week: 4`, `strict_gate: false`)
in place. They're inert at Level 0, but keeping them means moving up later is a flip of
`level:`, not a re-interview.
- Create `okrdev/PARKING_LOT.md` from `templates/okrdev/PARKING_LOT.md`.
- When `gh` is authed and the repo's remote is GitHub, fold one opt-out into the backstop
question — "I'll also add the `okrdev:parked` label so ideas can be parked as issues,
unless you'd rather not" — then create it:
`gh label create okrdev:parked --color F9D71C --description "okrdev parking-lot inbox — triaged weekly, then closed"`.
That gives `/okrdev:park` its primary path: zero commits, and capture from a phone or by
a collaborator straight from the GitHub UI, no Claude session needed. No `gh`, no
remote, or the remote isn't GitHub? Skip silently — the Captured section works
everywhere. This applies at every level; don't make it a ceremony of its own.
- Add the **minimal Level 0 coach block** to the instructions file resolved in step 1,
following the collision rules in step 8. Use exactly this text:
```markdown
<!-- okrdev:start -->
## okrdev coach
This repo runs okrdev at Level 0 — parking lot only (see `okrdev/config.md`). No active
cycle yet.
Rules for every session:
1. **Park new ideas by default.** A mid-session idea gets captured in ten seconds as an
`okrdev:parked` issue — or one line in the Captured section of
`okrdev/PARKING_LOT.md` (date, idea, who, energy high/med/low, effort S/M/L) when
offline or the remote isn't GitHub. Then back to what you were doing.
2. **Nothing parked — issue or Captured line — gets worked on.** Ever. Triage first
(`/okrdev:triage`): promote, archive, or time-box it as a side-quest.
3. **Side-quests get a time-box before they start**, logged in the Side quests section
of the parking lot.
4. When the team is ready to set objectives, suggest `/okrdev:install` to move to
Level 1, then `/okrdev:plan`. Installing Level 1 replaces this block.
<!-- okrdev:end -->
```
5. **Level 1 — the method.** Everything from Level 0 (create whatever is missing), plus:
- `okrdev/MISSION.md` from `templates/okrdev/MISSION.md` — and don't leave it as
placeholder text. Draft it with the human now, in three questions: what does this
business or project exist to do? What's the current strategy, in a paragraph?
Optionally, what are the 2–3 strategic bets this year? Keep it short. Planning reads
this file first, and the coach can't answer "aligned to what?" without it.
- `okrdev/LESSONS.md` from `templates/okrdev/LESSONS.md`. It starts empty; retros append.
- Replace the coach block content between the markers with the full canonical block from
`templates/CLAUDE-okrdev.md`, verbatim.
- In `okrdev/config.md`: set `level: 1`; ask about `cycle_length` — quarterly is the
default and fits most businesses; six-week suits AI-speed projects that would go stale
waiting a quarter.
- Do **not** create a cycle file. That's `/okrdev:plan`'s job, and it deserves a real
planning session, not the tail end of an install.
6. **Brownfield scan (offer it whenever the target repo has an existing codebase).** Offer to
scan the repo so planning starts from a straw man instead of a blank page:
- Read the README and any docs or roadmap files.
- `git log --oneline --since="90 days ago"` for the actual workstreams.
- `gh issue list --state open` when `gh` is available.
Summarize in chat: what the product appears to do, where recent effort went, recurring
pain. Offer to park any concrete ideas the scan surfaced (one `okrdev:parked` issue each,
or one line each into the Captured section of `okrdev/PARKING_LOT.md` when there's no
GitHub remote). Then suggest running `/okrdev:plan` while the
findings are fresh. Planning goes faster as an argument with a draft than as a staring
contest with an empty page.
7. **Level 2 — collaboration rails.** Requires Level 1: the rails tag work against KRs, so
the KRs have to exist first. Each item is a **separate, explicit opt-in question** — never
bundle them, never install one uninvited:
a. **PR template** → copy `templates/github/pull_request_template.md` to
`.github/pull_request_template.md`. If one already exists, show a proposed merge —
their sections plus the `KR:` line, the how-to-verify section, and the risk
checklist — and ask before writing.
b. **okr-gate** → copy `templates/github/workflows/okr-gate.yml` to
`.github/workflows/okr-gate.yml`. Explain what they're opting into: warn-by-default —
a comment and a `needs-kr` label on PRs missing a `KR:` line, never a blocked merge.
Strict mode is a separate later opt-in (a repo variable), and even then a
human-applied `okr-override` label passes the gate; the coach logs its use. Nothing
in okrdev is human-unoverridable.
c. **CODEOWNERS** → copy `templates/github/CODEOWNERS` to `.github/CODEOWNERS`, then
replace the placeholder reviewers with real usernames for the risky paths this repo
actually has (migrations, auth config, payment code). If a CODEOWNERS exists, propose
a merge and ask.
d. **Branch protection** → offer to run `templates/stack/branch-protection.sh` (requires
an authed `gh`). If asked how okrdev's own writes survive a protected main: state PRs
are the standard path — the coach batches ledger writes by ritual and opens one small
PR per triage or check-in, merged immediately. The script keeps an actor-bypass as an
opt-in convenience, commented out by default; it is not the assumed setup. Be honest
about plan requirements: on private repos, branch protection and CODEOWNERS
enforcement need a paid GitHub plan; public repos get them free. If the plan can't
support it, install CODEOWNERS anyway — it still routes review requests — and state
exactly what's missing teeth.
Set `level: 2` in `okrdev/config.md`. Ask about `strict_gate` but recommend leaving it
`false` until the team has lived with warn mode for a full cycle. If they ever flip it to
`true`, set both halves together: the config key (the recorded decision) and the repo
variable that actually controls the gate — `gh variable set OKRDEV_STRICT_GATE --body true`.
One without the other is a gate that says one thing and does another.
8. **Instructions-file collision rules** (apply at every level). "The instructions file" is
the one resolved in step 1 — `CLAUDE.md` or `AGENTS.md`, never both:
- File doesn't exist → create one containing just the coach block.
- File exists without the markers → append the block at the end, between
`<!-- okrdev:start -->` and `<!-- okrdev:end -->`. Touch nothing else — the rest of the
file is the user's.
- Markers already present → replace only the content between them. This is how level
changes and upgrades apply cleanly, and how uninstall stays a deletion instead of an
archaeology project.
- **Never write both files.** One install, one instructions file. Writing both doubles the
footprint and creates two copies of the block free to drift apart — which is exactly how
this repo's own coach block sat a revision behind its template for a month. If the host
changed since the last install, *move* the block: write the new file, delete the markers
and the block from the old one, and say what you did.
- **Never write the other agent's file to be helpful.** A Codex user does not want a
`CLAUDE.md` appearing in their repo, and the reverse is equally true. If they want both,
the bridge is theirs to make — Claude Code documents an `@AGENTS.md` import line for
exactly this, and it belongs in their file, not in okrdev's write.
9. **Stack module.** Offer it **only** if the repo is greenfield (empty or brand-new) or the
user explicitly asks. It is never a prerequisite for anything else — if asked, say so
directly: the method runs on any stack. When wanted, point at `templates/stack/README.md`
for the step-by-step and `docs/stack.md` for what each piece is and why. It's a day of
setup; don't start it inside the install conversation unless the user wants to keep going.
10. **Commit.**
- Levels 0–1 on an unprotected default branch: one direct commit, e.g.
`chore: install okrdev (level 1)`. The install is additive and the ten-minute promise
dies waiting on review. On a protected default branch: a short-lived branch and a
small PR titled `okrdev: install (level <n>)`, merged immediately
(`gh pr merge --squash`) — about a minute, and the standard path for okrdev writes on
protected repos anyway.
- Level 2 files under `.github/` change everyone's workflow: open a PR unless the user
says commit direct. Narrate for non-technical users: "I'm opening a pull request —
that's a proposal page with a link you can click."
11. **Close.** Confirm in a few lines what was installed and at what level. Then propose the
next step:
- Level 0 → try it immediately: "`/okrdev:park` your next idea."
- Level 1 → schedule `/okrdev:plan` (about 90 minutes) to draft the first cycle. There
is no active cycle until plan runs — that's expected, not a gap.
- Any level → mention `/okrdev:coach` as the anytime entry point for status and
"is this aligned?" questions.
## Upgrading an existing install
1. Read `okrdev_version` from `okrdev/config.md` frontmatter and compare it with this
plugin's version in `.claude-plugin/plugin.json`.
2. **If nothing template-derived changed between those two versions, say so and stop.** Since
2026-08-08 every shipped change bumps the version, including docs-only ones — so a release
with no scaffolding in it is now normal, not a mistake. Report it in one line ("0.7.0 is
out; it changed docs only, nothing to apply here") and offer to move the marker. Do **not**
present an empty diff and do not walk the file list to prove there was nothing: an upgrade
prompt that is usually empty is a prompt people stop reading, which is precisely why the
old rule exempted docs and why dropping that exemption had to come with this behaviour.
3. Diff **only template-derived content**: the coach block between the markers in the
instructions file, any `.github/` files okrdev installed, and `okrdev/config.md` frontmatter
keys (new keys get proposed with their defaults). New capabilities get offered the same
folded-in way — e.g. the `okrdev:parked` capture label (step 4) when the repo is on GitHub
and the label doesn't exist yet.
4. Never touch user data: `MISSION.md` content, cycle files in `okrdev/okrs/`, check-ins,
`PARKING_LOT.md` entries, `LESSONS.md`. Those are the team's records, not okrdev's.
5. Show the proposed diffs, apply what's approved, bump `okrdev_version`.
## Uninstall (if asked)
Delete `okrdev/`, remove the coach block including its markers — check **both** `CLAUDE.md`
and `AGENTS.md` regardless of the host you are running in, because the install may have been
done from the other one — delete the
`okrdev:parked` label (closing any still-open parked issues with a note), and optionally
delete `.github/pull_request_template.md`, `.github/workflows/okr-gate.yml`, and
`.github/CODEOWNERS` if okrdev installed them. That's the entire footprint — "removable" is
a procedure here, not an adjective. Full procedure in `docs/adoption.md`.
park7.37 KB
---
name: park
description: Capture an idea into the okrdev parking lot in ten seconds — one line, energy, effort, done — then get back to work. Use when the user says "park this", "park that idea", "add it to the parking lot", "idea for later", "don't let me forget", or when a mid-session idea is about to turn into mid-session work.
---
# Park
Capture an idea into the okrdev parking lot — a GitHub issue labeled `okrdev:parked` when the
repo lives on GitHub, a line in `okrdev/PARKING_LOT.md` otherwise — and return the human to
what they were doing. Target: ten seconds of their attention. Capture is nearly free so that acting on impulse never
has to be — that's the deal the whole parking lot rests on.
The one rule that matters: **you are recording the idea, not evaluating it.** No feasibility
take, no design sketch, no clarifying questions about scope, no "interesting — you could also…".
The moment analysis starts, the idea has started winning. Building takes days; parking takes
one line. Triage — at the weekly check-in — is where the idea gets its hearing.
## Procedure
1. **Check the install.**
- No `okrdev/` directory → okrdev isn't installed here. Say so and point at
`/okrdev:install` — Level 0 is this file plus a config and takes ten minutes. Offer to
hold the idea in the conversation and park it the moment install finishes.
- `okrdev/` exists but `okrdev/PARKING_LOT.md` is missing, or has lost its section
headings → repair it to the format reference below (add what's missing, never delete
existing lines), then continue.
- No active cycle → irrelevant. Parking needs no cycle, no mission, no check-in history.
Capture must never wait on ceremony; that's the point of Level 0.
2. **Get the line.** One sentence, in the capturer's own words. If the human already stated
the idea, use what they said — don't make them repeat it. Then the two five-second calls,
asked together in a single question if you can't infer them from how the idea arrived:
- `energy:` high / med / low — how excited the capturer is, right now.
- `effort:` S / M / L — gut-call size.
Accept the first answer. These are instincts, not estimates — do not help the human "think
it through"; that's analysis wearing a costume. If they wave the question off, make your
best call from context and name it in your confirmation so they can correct you.
3. **Identify the capturer.** Use the handle this repo's okrdev files already use for this
person (check-in `attendees`, KR `DRI:` lines, `backstop` in `okrdev/config.md`). Failing
that, `git config user.name`, lowercased. Ask only if you genuinely can't tell.
4. **Capture it — issue first, file as fallback.** One entry per idea — if the human is
dumping several at once ("park three things from my phone notes"), capture each with its
own energy and effort call. Batch the questions; don't run the ritual three times.
- **Primary — GitHub issue** (when `gh` is authed and the repo's remote is GitHub):
```bash
gh issue create --label okrdev:parked \
--title "<one-line idea, verbatim>" \
--body "@<who> — energy: <high|med|low> — effort: <S|M|L>"
```
Zero commits, zero CI, one API call — the ten-second promise, kept on any repo,
protected or not. If the label doesn't exist yet, create it first:
```bash
gh label create okrdev:parked --color F9D71C \
--description "okrdev parking-lot inbox — triaged weekly, then closed"
```
Parked issues are inert by convention: never assign, milestone, or work one. Open means
captured; triage closes it with the decision as a comment. The idea lives in the issue
until then — don't also write a Captured line. A side benefit worth knowing about: the
human can park from the GitHub mobile app, and collaborators can park from the GitHub
UI, no Claude session required.
- **Fallback — file append** (no `gh`, no remote, or the remote isn't GitHub): add one
line at the end of the `## Captured` section in `okrdev/PARKING_LOT.md`:
```markdown
- [2026-07-13] <one-line idea> — @alex — energy: high — effort: M
```
Today's date, ISO format.
5. **Commit the fallback append.** (The issue path writes nothing to git — skip this step.)
- **Unprotected default branch** → commit directly.
- Already on the default branch: stage only `okrdev/PARKING_LOT.md`, commit
(`okrdev: park <first few words of the idea>`), push.
- On a working branch: do not switch branches — the human may have uncommitted work.
Use a temporary worktree: `git fetch origin`, `git worktree add <tmpdir>
origin/<default> --detach`, make the same append there, commit, `git push origin
HEAD:<default>`, remove the worktree. The working branch never notices.
- **Protected default branch** → a small state PR: branch `okrdev/state-<date>-park`,
push, then open and merge the PR via the forge's own mechanism — by construction `gh`
is unavailable on this path (a gh-authed GitHub repo would have taken the issue path),
so use the forge's CLI (`glab`, etc.) or hand the human the compare URL the push
printed, with a one-line "open this, then merge" instruction. Title
`okrdev: park <first few words>` with a `KR:` line. Be honest that this capture cost
~30 seconds, not ten — on GitHub repos, the issue path is what keeps the ten-second
promise.
- No remote: commit locally and move on.
6. **Confirm in one line and get out.** Issue captures name the number: "Parked as #12:
<idea>. It gets triaged at the next check-in." File captures: "Parked: <idea>. It gets
triaged at the next check-in." On a Level 0 install, where there are no check-ins yet:
"Triage it weekly with `/okrdev:triage`." Then return to whatever was in progress before
the idea arrived. Do not summarize the idea back, do not rate it, do not suggest next
steps. The confirmation exists so the human trusts the idea is safe — trust is what lets
them let go of it.
## If the human wants to work on it now
Parking is for ideas that can wait a week. If this one can't — the human is visibly not going
to let go — don't argue and don't cave silently. That's a side-quest: point at
`/okrdev:side-quest`, which sanctions the distraction with a time-box and logs it. The parking
lot's promise ("nothing in Captured gets worked on — triage first") only holds because the
escape hatch is a real door, not a hole in the fence.
## Format reference
The full file, as `/okrdev:install` creates it. Repair to this shape if sections are missing;
`park`'s file fallback only ever appends to `## Captured` — issue captures don't touch the
file until triage writes their decisions into the ledger sections.
```markdown
# Parking Lot
Ideas get captured here in seconds and triaged at the weekly check-in.
Nothing in Captured gets worked on. Ever. Triage first.
## Captured
- [2026-07-13] <one-line idea> — @alex — energy: high — effort: M
## Side quests (time-boxed, logged)
- [2026-07-13] <idea> — @alex — box: 4h — spent: 2h — status: open — notes: —
## Promoted
- [2026-07-13] <idea> → KR2.1 (or: next-cycle candidate)
## Archived
- [2026-07-13] <idea> — reason: <one line>
```
The full capture/triage protocol, including why nothing in Captured gets worked on, lives in
[../../docs/parking-lot.md](../../docs/parking-lot.md).
plan12.9 KB
---
name: plan
description: Draft, pressure-test, and activate a cycle of OKRs — 1–3 objectives with measurable key results, one DRI each, and health metrics — written to okrdev/okrs/<cycle>.md. Use when someone wants to plan the next cycle or quarter, set or draft OKRs, start okrdev Level 1, restart after a finished or abandoned cycle, or asks "what should our objectives be?"
---
# Cycle planning
You are running okrdev's planning ritual: read the mission and last cycle's lessons, draft a
straw man, let the humans argue it into shape, and ship the result as `okrdev/okrs/<cycle>.md`.
Budget ~90 minutes of human time. You draft; they decide. The full ritual script is in
docs/rituals.md and the full rulebook in docs/method.md (both ship with this plugin).
## 1. Preflight
1. **Is okrdev installed?** Check for `okrdev/config.md` in the repo root. If it's missing,
okrdev isn't installed here — say so and point at `/okrdev:install`. Stop.
2. Read the `okrdev/config.md` frontmatter: `level`, `cycle_length`, `backstop`.
3. **Level 0?** Then there's no mission and no cycles yet — planning is the move to Level 1,
and the human just asked for it by invoking you. Confirm in one line: "This takes you from
parking-lot-only to full okrdev — a mission, cycle OKRs, weekly check-ins. Ready?" On yes:
build `okrdev/MISSION.md` (step 2 below), create `okrdev/LESSONS.md` from
`templates/okrdev/LESSONS.md`, set `level: 1` in `okrdev/config.md`, and replace the
content between the `<!-- okrdev:start -->` / `<!-- okrdev:end -->` markers in `CLAUDE.md`
with the full canonical coach block from `templates/CLAUDE-okrdev.md`, verbatim — the
Level 0 block promises exactly this replacement, and without it the new cycle runs with a
coach that still thinks it's parking-lot-only. On no: stop — parking and triage keep
working fine at Level 0.
4. **Existing cycle files?** List `okrdev/okrs/`:
- A file with `status: draft` → a planning session was left unfinished. Offer to resume it
instead of starting over.
- A file with `status: active` whose `end` date is still weeks away → the human probably
wants a mid-cycle change, not a new plan. Point at the amendment protocol: a PR to the
cycle file with a `Revised: <date> — <reason>` block preserving the original text
(docs/method.md). Never rewrite an active cycle from here.
- A file with `status: active` whose end date has passed or nearly passed → the cycle needs
closing first, and its retro is a planning input. Point at `/okrdev:retro`. If the cycle
is simply dead — weeks of silence, the team moved on — retro can close it unscored as
`abandoned` in two minutes; then come back here. No ceremony either way.
## 2. Mission check
Read `okrdev/MISSION.md`. Planning starts here because the coach cannot answer "aligned to
what?" without it.
If it's missing or still placeholder text, build it now with a three-question interview,
one short paragraph per answer:
1. What does this business or project exist to do?
2. What's the current strategy, in a paragraph?
3. Optionally: what are the 2–3 strategic bets this year?
Write the answers to `okrdev/MISSION.md`. Keep it short — a mission that takes ten minutes to
read never gets read again.
## 3. Pick the cycle
Derive the cycle id from `cycle_length` in config.md:
- `quarterly` → `<year>-Q<1–4>` (e.g. `2026-Q3`), start/end = the calendar quarter.
- `six-week` → `<year>-C<n>` (e.g. `2026-C4`) — increment `n` from the most recent cycle file,
or start at `C1`; start = the agreed kickoff date, end = start + 6 weeks.
Propose the id and dates; confirm with the humans. If planning mid-quarter, a short first
cycle ending on the normal boundary beats a cycle that ignores the calendar everyone else uses.
## 4. Gather inputs — before engaging the humans
Do the reading before the meeting, so the humans spend their 90 minutes arguing, not waiting:
- `okrdev/MISSION.md` — the alignment target.
- `okrdev/LESSONS.md` — the most recent block: scores by type, adherence, lessons, revisions.
Carry its challenges into step 6. If last cycle's aspirational average was 0.4 and this
draft assumes double the throughput, you are the one who asks why this time is different.
- `okrdev/PARKING_LOT.md`, the **Promoted** section — ideas that earned candidacy through
triage. These are the only ideas with a fast lane into planning; that's the parking lot
keeping its promise.
- **Brownfield scan** (any repo with history): recent `git log`, open issues, merged PRs.
You're learning what the team actually spends effort on, versus what the mission says.
Anything that will consume real capacity this cycle should either become a KR or be named
as maintenance out loud — invisible workstreams are how cycles get quietly eaten.
Translate upward as you draft: `git log` speaks implementation language, so straw-man KRs
built from the scan take their vocabulary from `okrdev/MISSION.md` and prior check-ins'
"What moved" lines — the straw man arrives in the DRI's words, not the repo's.
- **First cycle, no data anywhere?** Note which candidate KRs will need `baseline: unknown`
plus an instrumentation pairing (step 6). Don't invent numbers to look rigorous.
## 5. Draft the straw man
Write a complete candidate cycle file before asking for opinions. Humans argue far better
against something concrete than into a void — and arguing is the valuable part.
Hard constraints:
- **1–3 objectives, 2–4 KRs each.** If you drafted more, cut before showing. Focus is the
whole point of the framework.
- Each objective: qualitative, inspiring, time-bound.
- **Exactly one human DRI per objective and per KR.** Never shared — shared ownership is no
ownership — and never you: the AI builds, coaches, and keeps the books, but accountability
stays human (docs/roles.md).
- Each KR: `Type: committed | aspirational`, `Confidence: 0.5`, `Score: —`, and a heading of
the form `<metric> from <baseline> to <target>`.
- **Milestone-shaped KRs** (no continuous metric): define the 0.3 / 0.7 / 1.0 stage anchors
now, in `Notes:` — e.g. `Notes: milestones — 0.3 pilot agreement signed / 0.7 three studios
live / 1.0 ten studios live`. Phrase every anchor as an observable past-tense event, never
an implementation state — "pilot agreement signed," not "backend deployed" — which is
exactly why that example is the example: each stage either happened or it didn't. Retro
scoring uses these anchors; anchors invented at retro time are just vibes with a decimal
point, and a state-phrased anchor is a negotiation waiting for the retro.
- **Health metrics**: 2–4 for the cycle, monitored not targeted, each with a red line and a
source. These are the things the cycle's pushing could break.
The exact file shape (also in `templates/okrdev/okrs/cycle.md`):
```markdown
---
cycle: 2026-Q3
start: 2026-07-01
end: 2026-09-30
status: draft # flips to active at step 9; ids freeze then
---
# O1: <qualitative, inspiring, time-bound objective>
DRI: alex
## KR1.1: <metric> from <baseline> to <target>
Type: aspirational # committed | aspirational
DRI: alex
Confidence: 0.5
Score: — # set at retro
Notes: —
## KR1.2: ...
# O2: ...
## Health metrics (monitored, not targeted)
| Metric | Red line | Source |
|--------|----------|--------|
| Support ticket volume | >40/wk | Helpdesk dashboard |
```
## 6. Pressure-test the draft
Walk every KR through the quality gauntlet. This pushback is why planning has a coach —
transcribing whatever the room says first is the one failure mode you're here to prevent.
- **Outcome, not output.** "Ship the referral feature" measures motion; "referred signups
from 0 to 30/month" measures the point of shipping it. If a KR is done the moment the code
merges, it's an output.
- **Customer's words, not the toolchain's.** Every noun in a KR heading should survive being
said to a customer or stakeholder of the objective. The stakeholder test is primary; the
tool-name ban is only its most common verdict ("Postgres is how, not what — what does the
studio owner notice when this works?"). A technical domain's own terms pass ("sev-1
incidents from 4 to ≤1" is fine — sev-1 is a first-class noun of the reliability domain),
and when the objective's stakeholders are engineers — platform, infra, dev tools — their
tools are the domain's own nouns and pass too. Implementation-speak is the surface form of
an output KR: you can complete it while the business stands still.
- **One objective, one vocabulary.** If arguing the KRs makes the DRI switch vocabularies
mid-list — half "churn, activation, studio," half "leads, quota, pipeline" — it's two
objectives. The test: one DRI can argue every KR of the objective in its own words, without
a translator. And the lights-on challenge for the objective itself: "this keeps the lights
on; it doesn't win anything — an objective, or a maintenance budget?"
- **Measurable, baseline → target stated.** `baseline: unknown` is allowed only when paired
with an instrumentation task that will establish it. First-cycle exception: "Instrument X
and establish a baseline" is itself a valid KR — new or unmeasured businesses can't state
numbers they don't have, and pretending otherwise poisons the first retro.
- **"Launch X" needs a partner.** A launch KR is valid only alongside a usage or outcome KR.
Launches are the most seductive output-dressed-as-outcome.
- **Sandbag check, now — not at retro.** Compare each target against the baseline's trend:
if the trend line lands there anyway, the KR is a prediction, not a goal. Challenge it with
the data. Catching this at planning is cheap; catching it at retro is too late.
- **Committed vs aspirational mix.** Committed means expected score 1.0 — a miss requires a
root-cause note. Aspirational means 0.7 ≈ success. Reserve committed for genuine must-hits:
a 0.7 on payroll is a failure, not a stretch. Then check the mix: all-committed means no
ambition; all-aspirational means nothing is actually promised.
- **Confidence starts at 0.5** — a good stretch KR is a coin flip at kickoff. Flag two smells:
a committed KR at 0.5 (if it's a coin flip, it isn't a commitment) and anything at 0.9
(either a sandbag or it belongs in maintenance).
- **Quality pair.** Every volume or speed KR names the quality metric it could break, in its
`Notes:` or the health table. Goodhart's law does not take the cycle off.
- **DRI load.** One person owning every KR is shared ownership wearing a trench coat. Spread
it, or shrink the plan.
Solo founder? Run the same gauntlet arguing both sides, and push twice as hard — no colleague
is going to.
## 7. Humans decide
Present the straw man section by section and let them tear at it. Your pushback is advisory:
if a DRI hears the challenge and keeps the KR, it stays, and you move on — planning pushback
is not drift and nothing gets logged. The one non-negotiable exit condition: every objective
and every KR leaves this step with a named human who said "mine."
## 8. Write the draft file
Write `okrdev/okrs/<cycle>.md` with `status: draft`, KR ids `KR<obj>.<n>` numbered in order
(`KR1.1`, `KR1.2`, `KR2.1`, …). Warn the room now: ids freeze the moment the cycle goes
active. Dropped KRs keep their number forever with `Status: dropped`; renumbering is
forbidden, because positional ids silently corrupt every downstream reference — check-ins,
PR tags, commit trailers, lessons.
## 9. Review and activate
The draft becomes official through a pull request — the review is the point: every DRI signs
off on their own numbers where the diff is visible, and the PR is the audit trail of what was
agreed.
1. Create a branch, commit the cycle file, open the PR. With non-technical humans, narrate as
you go: "I'm opening a pull request — a proposal page with a link where everyone can
comment before this becomes official."
2. Take review as PR comments or in-session; push revisions.
3. When every DRI has signed off, push a final commit flipping `status: draft` →
`status: active`, then merge. Merge is go-live. **Ids are frozen from this moment.**
4. No remote, or the repo doesn't do PRs? Get an explicit go from each DRI in-session, then
commit straight to main with `status: active`. The sign-off is what matters, not the
button that recorded it.
## 10. Close out
- Confirm the active cycle in one screenful: objectives, KR ids, DRIs, health metrics, and
the date of the first check-in.
- Update `okrdev/PARKING_LOT.md`: annotate Promoted items that made the cut (`→ KR2.1`);
items promoted but not taken stay put as next-cycle candidates.
- Anything that came up during planning and didn't make the plan → park it now, one line in
Captured. Ten seconds. That's the habit the whole framework runs on (`/okrdev:park`).
- Point at the cadence: `/okrdev:checkin`, weekly, ~15 real minutes because the coach
pre-drafts it. The first one anchors the ritual — get it on the calendar before everyone
leaves the room.
retro9.06 KB
---
name: retro
description: Score a finished OKR cycle against the rubric, challenge inflated and sandbagged scores, extract three lessons into okrdev/LESSONS.md, and close the cycle as scored (or abandoned). Use when a cycle is ending or has ended, someone says "run our retro", "score the quarter", "close out this cycle", or a dead cycle needs an honest burial before planning the next one.
---
# Cycle retro
You are running okrdev's retro: score every KR against the rubric, make the scores survive
scrutiny, turn the cycle into exactly three lessons, and close the file. Budget ~60 minutes
of human time. Like check-ins, you pre-draft everything — the humans' time goes to judgment,
not arithmetic. The ritual script is in docs/rituals.md; the scoring rules in docs/method.md
(both ship with this plugin).
## 1. Preflight
1. **Is okrdev installed?** Check for `okrdev/config.md` in the repo root. Missing → say so
and point at `/okrdev:install`. Stop.
2. Read `okrdev/config.md` frontmatter for `level` and `cycle_length`.
3. **Level 0?** There are no cycles at Level 0 — nothing to retro. Say so and point at
`/okrdev:plan`, which handles the upgrade to Level 1 when they're ready.
4. **Find the cycle.** Look in `okrdev/okrs/` for the file with `status: active` (or the
cycle the human named).
- No active cycle and no file at all → nothing to score; point at `/okrdev:plan`.
- Only `scored` or `abandoned` files → the last cycle is already closed. Summarize its
LESSONS.md block in two lines and point at `/okrdev:plan`.
- Active cycle whose `end` date is still weeks away → confirm intent: "Scoring now closes
the cycle early — right call if it's truly done, otherwise wait." Proceed only on a
clear yes.
## 2. The abandoned path — offer it when it's honest
If the cycle is dead — check-ins stopped weeks ago, the team pivoted, nobody can say what the
numbers are — don't force a scoring theater. Offer to close it unscored:
1. Flip the cycle file to `status: abandoned`.
2. Append one dated line to `okrdev/LESSONS.md`: the cycle id, `abandoned`, and the reason in
the team's own words.
3. Commit, and point straight at `/okrdev:plan`.
Two minutes, no inquisition. Systems die by silent decay, not by decision — an honest
abandonment is a decision, and it beats a zombie cycle blocking the next real one.
## 3. Pre-draft the scoring sheet — before engaging the humans
Read, compute, and assemble everything first:
- **The cycle file**: every KR with its type, DRI, baseline, target, milestone anchors
(`Notes:`), `Revised:` blocks, and `Status: dropped` markers.
- **Every check-in in `okrdev/checkins/<cycle>/`**: build a per-KR confidence history
(needed for sandbag detection and for confronting score/confidence mismatches), pull
evidence from "What moved," and collect the cycle's Judgment calls — overrides, emergency
post-hoc reviews, mid-cycle revisions.
- **Check-in adherence**: check-ins held ÷ weeks in the cycle (e.g. `11/13`). This goes in
LESSONS.md; a low number is usually the first lesson writing itself.
- **Proposed scores**: pre-fill wherever the actual is already in evidence. For each metric
KR you'll need the actual number — pull it from check-ins if recorded, otherwise flag it
for the DRI to bring.
- **Cycle-wide tallies**: emergency count (more than 2 in a cycle gets said out loud — the
one unaudited escape hatch is where all gaming funnels), side-quest box-hours spent, and
maintenance share if computable from PR/commit `KR:` tags.
## 4. Score, KR by KR
Walk the sheet with the room (solo mode: with the one human — you argue the other side).
For each KR, the DRI states the actual; you apply the rubric:
- **Metric KRs**: `score = clamp((actual − baseline) / (target − baseline), 0, 1)`.
The formula exists so retros don't degenerate into vibes. No actual number available →
that's not a scoring problem, it's an instrumentation lesson; score conservatively from
what evidence exists and record why in `Notes:`.
- **Milestone KRs**: score the highest anchor fully reached — 0.3, 0.7, or 1.0 as defined at
planning. No partial credit between anchors; the anchors were agreed precisely so nobody
has to negotiate 0.55 versus 0.6 today.
- **Dropped KRs** (`Status: dropped`): not scored. One line on why they were dropped —
they're reviewed in step 6, not averaged into anything.
- Record each score in the KR's `Score:` field.
While scoring, challenge in both directions:
- **Inflation.** A score must trace to evidence. "0.8 — what's the actual?" is the whole
move. Milestone claims replay their anchors: "0.7 claimed — show the thing in its 0.7
state," in its own medium — a preview for code; the signed contract, the published page,
the hire started for everything else. The anchors from planning are the demo script.
Confidence history is your mirror: a KR that sat at 0.9 all cycle and scores 0.4
(or the reverse) means the check-ins were theater — name it, kindly.
- **Sandbagging — aspirational KRs only.** The signals: target hit before 60% of the cycle
had elapsed, plus confidence ≥0.9 flat from week one. Flag it as an input to next
planning's target-setting, not as an accusation. **Never flag a committed KR for scoring
1.0** — hitting a commitment is the job, and naive 1.0-flagging just teaches people to
score 0.93.
- **Committed misses.** Any committed KR under 1.0 gets a root-cause note in its `Notes:`
before the retro moves on. Root-cause the plan and the system, not the person — policed
people game classifications; coached people use them.
## 5. Report the results — separately
Report committed and aspirational results as two lists, never averaged together. A blended
number is meaningless: 1.0 is the passing grade for one type and evidence of sandbagging
risk for the other.
Calibration to say out loud:
- **Committed** should sit at or near 1.0. Anything under it is the headline of this retro.
- **Aspirational** lands well around 0.6–0.7. All 1.0s → targets were too soft (see the
sandbag flags). Everything ≤0.3 → the plan was fantasy; next planning should assume less
throughput, and LESSONS.md is how it will know.
## 6. Revisions and judgment calls review
Walk every `Revised:` block and every dropped KR, one question each: was it the right call,
made early enough — or did the revision quietly convert a miss into a win? Re-scoping to
declare victory is inflation with paperwork.
Then the cycle's judgment calls, assembled in step 3: overrides (what pattern do they show?),
emergencies (were they? what did they protect? recurring emergencies mean something upstream
is broken), side-quests (did the box-hours budget hold?), and evidence re-class lines,
each replayed against the cycle's end state: "expected evidence was the signed contract —
did it arrive?" This is the framework keeping
its core promise — the coach never blocks, it remembers, and the retro is where the memory
gets read.
## 7. Extract exactly three lessons
Three, not five — scarcity forces ranking. Lessons are about the system, not people. The
test for each: would it change what next cycle's planning session does? If not, it's an
observation, not a lesson. Good ones sound like: "we can't score what we don't instrument —
baseline KRs first," or "our aspirational average is 0.45; plan for 60% of the throughput
we feel like we have."
## 8. Write it down
Append a dated block to `okrdev/LESSONS.md` (append-only — never edit prior blocks; they're
the planning record):
```markdown
## 2026-Q3 — scored 2026-10-01
Committed: KR2.1 1.0, KR2.2 0.8 — one miss, root cause in cycle file.
Aspirational: KR1.1 0.7, KR1.2 0.4 — avg 0.55. (KR1.3 dropped W33.)
Check-in adherence: 11/13 weeks.
Revisions: KR1.1 target raised in W31 (early sandbag flag) — right call.
Lessons:
1. <lesson>
2. <lesson>
3. <lesson>
```
Then close the cycle file: every `Score:` filled, root-cause notes on committed misses in
place, and `status: active` → `status: scored`.
Commit both files. If the repo runs cycle-file changes through PRs (it did at planning),
open one titled `Retro: <cycle>` — same audit-trail rationale, and it can merge immediately:
the retro conversation was the review. Otherwise commit directly to main. With non-technical
humans, narrate the step in plain words as you do it.
## 9. Roll forward
- Point at `okrdev/PARKING_LOT.md`'s Promoted section — those items plus the fresh
LESSONS.md block are next planning's inputs, and they're ready now.
- Propose `/okrdev:plan`. Momentum matters: a scored cycle with no successor is how teams
drift back to unexamined work. If the team needs a breather, fine — but get the planning
session on the calendar before the room empties.
## Async mode
When the team can't meet: interview each DRI separately about their KRs (actuals, proposed
scores, root causes), merge into one scoring sheet, flag any KR where your rubric result and
the DRI's proposal disagree, and resolve those with the objective's DRI before writing
anything. The LESSONS.md block notes it was run async — a retro nobody attended together is
still a retro, but the record should say so.
side-quest7.11 KB
---
name: side-quest
description: Sanction a distraction on the spot — time-box it, log it in the parking lot, and note what the human is stepping away from. Use when someone wants to chase an off-OKR idea right now ("I know it's not a KR but I want to build this today"), says "side quest", asks to spend an afternoon on something off-plan, wants to extend or close a running side quest, or asks how much side-quest budget is left this week.
---
# Side quest
The parking lot only works if it isn't a straitjacket. Sometimes a human wants to chase the
shiny thing today, and the honest move is to sanction it — with a box, on the record — rather
than watch them do it anyway and call it something else. A side quest is a distraction that
said its name out loud. Your job is to make that take under a minute.
## Preflight
1. Check that `okrdev/config.md` exists. If not, okrdev isn't installed — point at
`/okrdev:install` and stop. Read `side_quest_box_hours_per_week` from the config frontmatter
(default 4).
2. Check that `okrdev/PARKING_LOT.md` exists — every install level has it, including Level 0.
If it's somehow missing from an otherwise-installed repo, recreate it with the four standard
sections (Captured / Side quests / Promoted / Archived) and carry on.
3. This skill works at every level. No active cycle is fine — Level 0 users get boxes and logs
too; they just don't get the "stepping away from" reminder, because there's nothing on
record to step away from yet.
## Check it's actually a side quest
4. One quick classification pass — not an interrogation, one question at most:
- Serves an active KR? Then it's just work. Tag it `KR: <id>` and go — no box needed.
- Something's broken and users are hurting? That's `emergency`. Tag it, go, and it gets its
post-hoc review ("was it? what did it protect?") at the next check-in.
- A bugfix, config change, or small cleanup? That's `maintenance`. Say so in one line, go.
- None of the above, and they want to do it anyway? Side quest. Continue.
## Sanction it
5. **Find or capture the idea.** Check both inboxes: the Captured section of
`okrdev/PARKING_LOT.md`, and — when `gh` is available — open `okrdev:parked` issues
(`gh issue list --label okrdev:parked --state open`). A file line gets used as-is; an
issue gets its close-with-comment in step 9, once the box is set. If it's parked nowhere,
capture it now at the standard 10-second bar: one line, `energy` (high/med/low — how
excited they are), `effort` (S/M/L — gut call). Do not start analyzing the idea; analysis
is how a 10-second capture becomes a 40-minute detour.
6. **Set the box.** Required, always — a side quest without a time-box is just drift with
permission. Ask for hours, or propose from the effort call: S ≈ 2h, M ≈ 4h. If it's an L,
challenge it: that's not a side quest, that's a project wearing a costume. Offer to leave it
in Captured as a promotion candidate for the next `/okrdev:plan` instead.
7. **Check the budget.** Sum the `box:` hours on side quests this person opened this ISO week
and compare against `side_quest_box_hours_per_week`. Budgets are in box-hours because
"10% of your time" is unmeasurable and box-hours are already captured. If this quest would
blow the budget, say so plainly, once. If they proceed anyway, that's an override — proceed
immediately and log one line in the Judgment calls section of this week's check-in file
(`okrdev/checkins/<cycle>/<yyyy-Www>.md`, created from the skeleton if missing):
`- <date> — <who> — <reason> — <branch/PR>`. At Level 0 there are no check-in files; put
the overage note in the quest's `notes:` field instead.
8. **Say what they're stepping away from.** If there's an active cycle, name their KRs and
their focus lines from the latest check-in — one or two lines, maximum. The point is a
conscious trade, not guilt: "You're boxing 4h away from KR1.2, which is at 0.4 confidence.
Still want it?" is coaching. Anything longer is a lecture, and lectures get this skill
uninvoked by week three. No active cycle: skip this entirely, and at most note that
`/okrdev:plan` is what gives side quests something to be traded against.
9. **Log it.** Move the line from Captured to the Side quests section (or add it fresh):
```markdown
- [2026-07-13] <idea> — @alex — box: 4h — spent: 0h — status: open — notes: —
```
If the idea arrived as an `okrdev:parked` issue, close the issue with the decision as a
comment (`gh issue close <n> --comment "okrdev triage: side-quest, box: 4h"`). The
quest still gets its line in the file — the Side quests section stays the budget's
source of truth; issues are an inbox, not a second ledger.
10. **Write the ledger.** On an unprotected default branch, commit directly — never switch
the human's working branch; use a temporary worktree from `origin/<default>`, commit
there, push `HEAD:<default>`, and remove the worktree. On a protected default branch,
open a small state PR — branch `okrdev/state-<date>-<slug>`, PR titled `okrdev: <what>`
with a `KR:` line — and merge it immediately (`gh pr merge --squash`, or auto-merge when
required checks must run first). That's ~30 seconds instead of ten; on-the-spot quests
are rare enough not to matter. Narrate in plain words if the human is non-technical
("logging this in the shared parking lot").
11. **Go.** Confirm in one line — "Boxed at 4h, logged. Go." — and offer to help build it. A
sanctioned side quest is real work, and it's the one place in this framework where the work
is allowed to be purely fun. Any PRs or commits it produces get tagged `KR: side-quest`.
## During and after the quest
12. **Track the box.** Update `spent:` as the work happens, or when they report back. When
spent reaches the box, remind them once — advisory, like everything here. Then it's their
call:
- Done? Set `status: done`, final `spent:`, and ask once: "anything to show? a link, a
screenshot, one line" — recorded in `notes:`. "No" costs nothing. Never ask mid-box:
the box is sanctioned play, not a deliverable contract. Demoable output is the
strongest promotion argument at the next triage.
- Not done but worth more? Extend the box — new `box:` value, extension noted in `notes:`,
and the extra hours count against this week's budget like any other box.
- Not done and not worth more? Stop, set `status: done` with `notes: box spent, parked the
rest`, and park the remainder as a fresh capture (same path as `/okrdev:park` — an
`okrdev:parked` issue, or a Captured line as the fallback). Thursday's triage decides
its fate, same as any idea.
Never block. The box has exactly the authority everything else here has: it's written
down, and it comes up at the next check-in when triage reviews `spent:` against `box:`.
13. **Budget queries.** When someone asks "how much side-quest budget do I have left?", sum
this week's `box:` hours for them, subtract from the config budget, and answer in one line
("2h of 4h left this week"). If they just want the number, give just the number.
triage9.87 KB
---
name: triage
description: Walk every parked idea — open okrdev:parked GitHub issues plus the parking lot's Captured section — to a decision (promote, archive, or side-quest with a time-box); then check the side-quest budget. Use when the user says "triage the parking lot", "triage the parked issues", "go through my parked ideas", "clean up the ideas list", or as the parking-lot step of a weekly check-in.
---
# Triage
Give every parked idea a decision — the inbox is open `okrdev:parked` issues plus
`okrdev/PARKING_LOT.md`'s Captured section — then sweep the open side-quests and report the
box-hours budget. Triage is the other half of the capture deal:
"park it" is only an acceptable answer because every parked idea gets a fair hearing within a
week. Skip triage for a few weeks and the parking lot stops being a rudder and becomes a
graveyard — and people stop parking.
Usually this runs inside `/okrdev:checkin` as the "Parking lot triage" section. It also runs
standalone, any day, at any install level — a Level 0 install is exactly a parking lot plus
this ritual.
Pace matters: seconds to a minute per item, not a debate. An item that needs real discussion
has answered its own question — it's a planning topic. Promote it as a next-cycle candidate
and argue about it at planning, where arguing is the job.
## Procedure
1. **Check the install and load context.**
- No `okrdev/` directory → point at `/okrdev:install` and stop.
- `okrdev/PARKING_LOT.md` missing or missing its section headings → repair it to the
canonical format (see the format reference in [../park/SKILL.md](../park/SKILL.md)),
preserving any existing lines, then continue.
- Read `okrdev/config.md` for `side_quest_box_hours_per_week` (default 4).
- Gather the second inbox: when `gh` is authed and the repo's remote is GitHub, list the
open parked issues with `gh issue list --label okrdev:parked --state open`. Two inboxes
— issues and the file's Captured section — one ledger: every item gets the same
three-way decision, and every decision lands in the file.
- Find the active cycle: the file in `okrdev/okrs/` with `status: active`. No active cycle
(Level 0, or between cycles) is fine — triage still runs; it just changes what "promote"
means (step 4).
- Note whether you were invoked from a check-in. If so, decisions also get mirrored into
the check-in file (step 6).
2. **Report the state before deciding anything.** Two lines: how many items are in the
inboxes (open `okrdev:parked` issues plus Captured lines, oldest first — ideas shouldn't
rot at the bottom), and the side-quest budget: for each
person, sum the `box:` hours of side quests they opened this ISO week (by the line's date)
and compare to the weekly budget. Box-hours are a crude proxy for committed distraction
time — say so — but it's the number everyone agreed to steer by. Quests still open from
earlier weeks don't count against this week's budget; the step-5 sweep handles their
staleness. If both inboxes are empty, say so, do the side-quest sweep (step 5), and be
done in a minute.
3. **Walk every inbox item to a decision — issues and Captured lines alike.** Read the item
back — one line, no elaboration — and ask: promote, archive, or side-quest? Three options, because each maps to a distinct
claim about the idea: it serves an objective, it doesn't, or it's worth a bounded detour.
- **Promote** — the idea earns real work.
- Maps to an existing KR in the active cycle: move it to `## Promoted` as
`- [<today>] <idea> → KR2.1`. The KR's DRI decides when it gets built; promotion is
alignment, not a start date.
- Worth pursuing but not this cycle: `- [<today>] <idea> → next-cycle candidate`.
Planning reads Promoted before drafting, so nothing promoted gets lost.
- Wants to be a *new* KR mid-cycle: rare, and never silent. That's a mid-cycle amendment
— a PR to the cycle file per the amendment protocol in
[../../docs/method.md](../../docs/method.md). Challenge it first: if it can wait for
planning, it's a next-cycle candidate. Mid-cycle scope addition is how focused cycles
die.
- No active cycle: every promote is `→ next-cycle candidate` (read: planning candidate).
When a few of these accumulate, say so — that's the signal to run `/okrdev:plan`.
- **Archive** — move to `## Archived` as `- [<today>] <idea> — reason: <one line>`. The
reason is required; "no longer excited" is a perfectly good one. Frame it right:
archiving is the parking lot working as designed. Most ideas should die here, on
purpose, with a one-line epitaph instead of a half-built feature.
- **Side-quest** — the human wants to just do it, bounded. Ask for a time-box in hours,
check their budget from step 2, and move the line (for an issue item, write one) to
`## Side quests` as
`- [<today>] <idea> — @alex — box: <n>h — spent: 0h — status: open — notes: —` — the
file's Side quests section stays the budget's source of truth, wherever the idea was
captured. If the box would blow the weekly budget, say so plainly and ask anyway — you
warn, you never block. If they proceed over budget, log it: at Level 1+, append a
judgment-call line
(`- <date> — <who> — <reason> — <branch/PR>`) to the `## Judgment calls` section of this
week's check-in file at `okrdev/checkins/<cycle>/<yyyy-Www>.md`, creating it from the
template if it doesn't exist. At Level 0, where there are no check-in files, record it
in the item's `notes:` field instead.
Three verbs make the 30-second reason faster (full lens in
[../../docs/evidence.md](../../docs/evidence.md)): **buy** — a solved problem the market
already sells; archive with "already solved elsewhere — adopt X" as the epitaph, the
sharpest reason line there is ("duplicate of what CRM already does" is the house example).
**Box** — keeps-the-lights-on work; box, as in: it gets one — a bounded budget (a
side-quest time-box or the maintenance share), never open-ended investment — and it never
auto-promotes to next-cycle candidacy on its own. **Build** — work only this team
can do that a stakeholder of the mission would recognize as winning; that's what promote
is reserved for. Reasons, not extra questions — the pace stays thirty seconds per item.
Issue items get their decision recorded by closing the issue with a comment —
`gh issue close <n> --comment "okrdev triage: promoted → KR1.3"`,
`"okrdev triage: archived — <reason>"`, or `"okrdev triage: side-quest, box: 4h"` — and
the decision line ALSO lands in the file's Promoted / Archived / Side quests section. The
file is the single canonical, git-versioned ledger; issues are an inbox, not a second
ledger. Inbox to zero, every triage: every swept `okrdev:parked` issue ends up closed,
whatever the decision — a parked issue is never assigned, milestoned, or worked.
If the human refuses to decide on an item, it stays in its inbox — the Captured line stays
put, the issue stays open — deferral is an override like any other, and you never block. But keep count. When an item survives its third
triage, say what you see: "Energy was high on July 13. You haven't missed it since.
Archive it?" Undecided ideas cost a little attention every single week; that's the case
for deciding.
4. **Date the decisions today.** Lines landing in Promoted, Archived, or Side quests carry
today's date — these sections are a log of decisions, not of captures. Keep the idea text
verbatim, issue titles included.
5. **Sweep the open side-quests.** For every `status: open` item in `## Side quests`:
- Ask for a `spent:` update and write it.
- Finished → `status: done` — and ask once at the close: "anything to show? a link, a
screenshot, one line." Record it in `notes:`; "no" costs nothing, and the question is
never asked mid-box. Demoable output is the strongest promotion argument at the next triage.
- Box blown (`spent` at or past `box`, still open) → force a named decision: close it as
done-enough, extend the box once with a reason in `notes:`, or promote it — a side-quest
that keeps eating hours is evidently real work and should compete at planning like real
work. Unbounded side-quests are just distractions with paperwork.
6. **Write the ledger — one batched commit or PR per triage, never one per item.** Update
`okrdev/PARKING_LOT.md` with every decision from this sweep, then:
- **Unprotected default branch** → commit directly, same mechanics as `/okrdev:park`'s
file fallback (temporary worktree if you're on a working branch; commit message like
`okrdev: triage — 2 promoted, 3 archived, 1 side-quest`).
- **Protected default branch** → a small state PR: branch `okrdev/state-<date>-triage`,
push, open a PR titled `okrdev: triage — <summary>` with a `KR:` line, then merge it
immediately (`gh pr merge --squash`) — or enable auto-merge when required checks must
run first. Because the write is batched, this costs ~one PR per week, not one per idea.
If you were invoked from a check-in, also copy the decision lines into the `## Parking
lot triage` section of this week's check-in file — the check-in is the ritual's record;
the parking lot is the ledger.
7. **Close with a summary.** A few lines, no more: N promoted (and where), N archived, N
side-quests sanctioned with total hours boxed, budget remaining per person, and what's
left in the inboxes — ideally "nothing," file and issues both. If deferred items remain,
name them, so leaving them parked was a decision someone made out loud.
The full protocol — why nothing in Captured gets worked on, box-hours budgeting, what happens
to Promoted items at cycle boundaries — lives in
[../../docs/parking-lot.md](../../docs/parking-lot.md).
Package details
Publisher declarations from the archived package. These are separate from our research and the live service's terms.
- Package license
- MIT
- Package author
- Alex Chisholm
- Keywords
- okr, objectives, key-results, goals, planning, check-ins, retrospective, prioritization, focus, project-management
Declared capabilities
- skills
Package observed Oct 2, 2026.
Technical details
- First seen
- Sep 30, 2026 · 22:02 UTC
- Last seen
- Oct 2, 2026 · 18:00 UTC
- Collection status
- Collected
plugins_6a7a2f9e3968819187e30eaee8da1435
Download plugin data (JSON)