Skip to content

Instantly share code, notes, and snippets.

@escherize
Created July 10, 2026 21:21
Show Gist options
  • Select an option

  • Save escherize/922a5fb56cefd7661aa332a9041aad63 to your computer and use it in GitHub Desktop.

Select an option

Save escherize/922a5fb56cefd7661aa332a9041aad63 to your computer and use it in GitHub Desktop.
Linear project workflow skill family — thin hub + spokes (domain-modeling, grilling, decision-capture, project-retro). Retrofitted from a real project's failure modes; conventions from 2026 ADR/hub-and-spoke research.
name linear-project-workflow
description Opinionated end-to-end workflow for a small multi-dev project (design → grill → issues → build+capture → verify → retro). The thin hub that names the phases and their gates, delegating each to a focused spoke skill. Use when kicking off, running, or wrapping a multi-person project in Linear.

Linear project workflow — the hub

This is a thin orchestrator: it owns the phase flow and the gates between phases, and delegates each phase to a focused spoke. It deliberately does NOT repeat the spokes' content — a monolith that inlines everything dilutes the instructions and rots. The hub stays small so it never becomes the coupling bottleneck.

Every rule was retrofitted from a real project (Native 2FA) where the code shipped in ~90 minutes but key security invariants were designed in commit messages with no durable home, caught only by adversarial review. The workflow's job is to make that catch systematic.

The spokes

Phase Spoke skill Owns
0 Design domain-modeling states + transitions; the "every edge out" smell test
1 Grill grilling (via grill-with-docs) the interview that emits ADRs + glossary
2 Issues linear-workflow, linear-cli issue/branch/PR mechanics
3 Build + capture decision-capture decision→ADR, gotcha→Discoveries, the review gate
4 Verify review-pr, verify, qa-playbook adversarial review, run-it-for-real, manual QA
5 Retro project-retro timeline-from-git → systemic fixes → back to this hub

Project doc set (create once, in the Linear project)

Four docs, four lifecycles — keeping them separate is the point (a living plan and an immutable record read differently).

Doc Answers Lifecycle
Tech Design What are we building? living during design
PRD What must it do? stable; the contract
Decision Log (ADRs) Why this way? append-only, forever true
Retro What we'd change one, at the end

Decision Log opens with a glossary (the domain vocabulary — new readers need the words before the decisions parse). ADRs are canonically in-repo at docs/adr/ (versioned with code, reviewable in the PR that changes them) and mirrored to the Linear doc for team visibility. Plus a low-ceremony Discoveries stream for gotchas (see decision-capture).

The flow

Phase 0  Design       → domain-modeling: model states+transitions. A state with ONE edge out is
                        a decision nobody made yet. Output: sketch + visible TBDs.
Phase 1  Grill        → grilling: relentless interview over the sketch. ADRs + glossary fall OUT
                        of it, into the log, BEFORE issues are cut.
Phase 2  Issues       → linear-workflow / linear-cli: per-PR slices, sequenced by dependency,
                        release bar marked. Parallelize REVIEW, not the build (see gate below).
Phase 3  Build+capture→ decision-capture: as you build, decision→ADR (same PR), gotcha→Discoveries.
                        The gate: every PR review asks "did this produce a decision or gotcha,
                        and where's it written?"
Phase 4  Verify       → review-pr (parallel adversarial passes) + verify (run it for real, not
                        REPL-green) + qa-playbook (manual, doubles as PRD acceptance).
Phase 5  Retro        → project-retro: timeline from git, each stumble → a systemic fix that
                        edits THIS workflow. The loop that keeps it honest.

The gates (what the hub actually enforces between phases)

  1. Design → Grill: every new state/token/boundary in the design has its lifecycle questions asked (answered or TBD). A missing question blocks; an unanswered one is just a build issue.
  2. Grill → Issues: the genuinely-contested TBDs are settled and logged as ADRs. Don't cut underspecified issues — that's churn.
  3. Build → Verify: every PR review runs the capture gate ("decision/gotcha → where written?"). This is the catch layer the whole workflow exists for.
  4. Verify → merge: fresh-JVM/full-suite (not REPL-green), adversarial review clean, QA playbook green.
  5. Retro → next project: recurring misses become new gates or checklist items here.

Parallelization rule

For a small, fast project: do NOT split the build across devs — by the time you split work and sync state, one person has finished. Parallelize review, research, and audit — those are genuinely independent. Reserve multi-dev/multi-agent fan-out for slow, wide phases (large migrations, broad audits).

Anti-patterns (each cost real time on 2FA)

  • Pre-digging every possible issue up front. Waterfall fallacy. Force the questions (Phase 0), defer the answers, rely on the catch layer (Phase 3 gate). Don't over-index on any single up-front miss.
  • Trusting REPL-green. It runs stale definitions after a rename/split. Always fresh-JVM before push.
  • git add -A on a dirty tree. Sweeps local session files into the commit. Explicit paths / git add -p.
  • Feature-registration incompleteness. New feature/setting/enum → grep every enumeration (define site, token map, FE type, stats mirror, tests). Miss one = red CI chased across the matrix.
  • Editing someone else's design doc without a nod. Propose, don't overwrite. Issue comments and factual reconciliation are fine to just do; narrative status updates are humans-only.
name domain-modeling
description Model a feature's entities, states, and transitions BEFORE writing prose or code, so the design's lifecycle questions get forced instead of forgotten. Use in the design phase of any non-trivial feature — especially anything with auth state, sessions, tokens, workflows, or multi-step flows. Spoke of linear-project-workflow (Phase 0).

Domain modeling — force the questions

Prose-first design describes what you already thought of. Modeling the domain surfaces what you didn't. The failure this prevents is real and specific: a design doc that names a piece of state but never interrogates it. (Native 2FA named the "primed session between password and 2FA" state but never modeled its transitions → the challenge-token invalidation decision had no home and was designed later, in commit messages.)

The method

For the feature, enumerate:

  1. Entities — the nouns that persist (User, Session, ChallengeToken, Enrollment…). Name each once.
  2. States — for each entity, the states it can be in (ChallengeToken: issued → consumed → expired).
  3. Transitions — the edges between states, and what triggers each edge.

Then, for every state, ask the lifecycle questions — and write the answer or a visible TBD:

  • Created: how does something enter this state? by whom, with what authority?
  • Invalidated / expired / revoked: what are all the ways out? (This is the one that gets missed.)
  • Replay / double-use: while it's live, what stops it being used twice?
  • Failure / abuse: throttle, lockout, rate bound?
  • Degraded path: license lapse, no network, restart, concurrent request?

The smell test (this is the whole skill)

A state with only one drawn edge out is the tell. Real states have several. The missing edges are the undiscussed decisions.

"Primed session" had one edge drawn (→ verified). The missing edge (→ invalidated / consumed-so-it-can't-mint-twice) was exactly the gap. When you find a state with one edge, you've found a decision nobody made yet.

Output

  • A short entity/state/transition sketch (prose or a diagram — a bulleted transition table is fine).
  • For each state, the lifecycle answers or a TBD owned by a build issue.
  • The TBDs are not failures — they're the build's checklist. A missing question is the bug; an unanswered one is just work.

When to skip

Trivial CRUD, a pure refactor, a one-file change with no new state. Use it the moment a feature introduces a token, a session, a workflow state, a lock, or a trust boundary — anything with a lifecycle.

name grilling
description A relentless design interview that turns contested calls into decisions and emits ADRs + a glossary AS IT GOES (not as a later write-up). Use to pressure-test a design or plan before cutting issues. Runs over a domain-modeling sketch; feeds decision-capture. Spoke of linear-project-workflow (Phase 1).

Grilling — interrogate into the docs

An adversarial interview on a design, run over a domain-modeling sketch. Two rules make it work:

  1. Refuse the first plausible answer. For each decision, ask "why not the obvious alternative?" and keep pushing until the rationale is real, not reflexive. The output of each exchange is a decision with a rejected alternative — that's an ADR.
  2. Capture in the same motion. The ADRs and glossary fall out of the grilling, they are not a meeting someone transcribes later. Grill into the decision log. (Same discipline as capturing a decision in the same PR that makes it — pulled one phase earlier.)

What to grill

Walk the domain-modeling sketch and, for every entity/state/boundary and every TBD it flagged:

  • Lifecycle: how is this created / invalidated / replayed-guarded / throttled? (The TBDs from Phase 0 are the agenda.)
  • The obvious alternative: name it, then say why it loses. If you can't, you haven't decided yet.
  • Degraded paths: what happens on lapse / restart / concurrency / partial failure? These are where invariants hide.
  • Trust boundaries: who is authorized for each transition? What's the attack if they're not?

What it emits (as you go)

  • ADR per settled contested call → hand to decision-capture (one decision, its rationale, the rejected alternative, status accepted).
  • Glossary entry per newly-named term → the decision log opens with these; new readers need the words before the decisions parse.
  • TBD per unresolved fork → flagged in the design doc, owned by a build issue. Don't cut issues until the genuinely-contested TBDs are settled — underspecified issues are churn.

Running it

Solo (interrogate your own design out loud, write as you answer) or as parallel adversarial agents each taking a lens (security, correctness, degraded-path). Either way the artifact is the same: decisions in the log, not in your head or a Slack thread.

The bar

A decision is "grilled" when you can state it, its rationale, and the alternative you rejected — in one breath, without hedging. Anything you can't state that way is still a TBD.

name grill-with-docs
description A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go.
disable-model-invocation true

Run a /grilling session, using the /domain-modeling skill.

name decision-capture
description Capture decisions (ADRs) and hard-won gotchas (Discoveries) as they happen, in the same PR that produces them, so knowledge learned mid-build has a durable home instead of dying in commit messages and Slack. Use whenever a change makes a design decision, adds a security invariant, or teaches a non-obvious fact. Spoke of linear-project-workflow (Phase 3).

Decision capture — the durable home

The knowledge that rots is what you learn during the build. Up-front docs capture what's knowable before code; this captures what's only knowable after. Two homes for two kinds of knowledge, plus the one rule that makes either actually get written.

The failure this fixes (named by the industry)

"Without clarity on when an ADR is required, who reviews it, or where it lives in daily workflow, ADRs become a thing you might write if you remember — which translates in practice to 'you don't write them.'"

So this skill is mostly about the when / who / where, not the template.

Two homes

Decision → ADR. A choice with a rationale and a rejected alternative. (jti consumption, "401 reserved for no-session", email-OTP eviction-on-write.)

Gotcha → Discoveries. A non-obvious fact you paid to learn. Lower ceremony — a dated bullet. (kebab-not-snake keyword bit CI twice; the REPL runs stale defs after a rename, only fresh-JVM catches it; adding a premium feature touches 5 enumerations, here's the list.)

ADR: where, when, who

  • Where (canonical): in-repo, docs/adr/NNNN-title.md. Versioned with the code, shows up in git blame, and — the point — reviewable in the same PR that changes the decision. Mirror to a team-visible doc (Linear project doc) for discoverability, but the repo copy is canonical because it can't drift from the code silently.
  • When: the same PR that makes or alters the decision. Not a separate ceremony — the same diff. If the PR changed why the code is the way it is, it touches an ADR.
  • Who: the reviewer enforces it (see the gate below). Authors don't reliably document their own decisions heads-down; they do it when asked.

ADR shape (keep it to a page)

# NNNN. <decision, as a statement>
Status: proposed | accepted | superseded by NNNN
Context: what forced this decision; the constraint.
Decision: what we chose.
Alternative rejected: the obvious other option, and why it loses.
Consequences: what this makes easy / hard / load-bearing.

Status lifecycle: proposed while under discussion → accepted when active → superseded by NNNN when replaced (link forward). Never delete an ADR; supersede it. The record stays true even when the decision changes.

Discoveries: lower ceremony

A running list (a docs/discoveries.md, a .worklogs/ file, or a pinned issue) of dated bullets. Format: ### YYYY-MM-DD — <fact> + one line of why it bit and how to avoid it. No status, no template. If it cost you time to learn and isn't a decision, it goes here.

The gate (this is the enforcement, and the whole point)

At every PR review, one question:

Did this change add or alter a decision or a gotcha? If yes — where is it written down?

That single line generalizes "does the code match the doc?" into "did the code produce knowledge the docs don't have yet?" — which is the actual failure mode. Make it a review-checklist item, not a hope.

What is NOT a decision (don't ADR these)

Mechanical choices with no rejected alternative, style the linter owns, anything a comment in the code already fully explains. ADRs are for choices a future reader would otherwise re-litigate. Over-logging kills the log as surely as under-logging.

name project-retro
description Write a project retrospective grounded in the git record, where each stumble maps to a systemic fix (a checklist, a phase gate, a skill) rather than a vibe. Use when wrapping a project or milestone. Its output feeds back into the workflow that produced it. Spoke of linear-project-workflow (Phase 5).

Project retro — timeline from git, fixes into the workflow

A retro is only useful if it changes what you do next. This one is engineered to: reconstruct the truth from the record (not memory), and convert each stumble into a systemic fix that feeds back into the workflow.

Reconstruct from the git record, not memory

Memory smooths the sequence, and the sequence is the point (what surfaced when, what caused what). Start here:

git log --format='%h %ad %an %s' --date=format:'%m-%d %H:%M' <first-commit>..HEAD
git log --format='%s' <range> | grep -oE '^(feat|fix|refactor|chore)' | sort | uniq -c   # fix:feat ratio

The fix-to-feature ratio and the timeline are the spine. A 90-minute build with 13 fixes tells a story a paragraph from memory won't.

For each stumble, name three things

  1. What happened — concrete, from the record.
  2. What it cost — commits, CI reds, time. Quantify.
  3. The systemic fix — a checklist item, a phase gate, or a skill. Not "be more careful." If the fix is "remember to X," it's not a fix; find the gate that makes X automatic.

The output is changes to the workflow

The retro's product isn't the document — it's the diff to the process. If a class of miss recurs across projects, it becomes a new phase gate or checklist item in the workflow skill. That feedback loop is what keeps the workflow honest; a retro that doesn't change the next project's setup was theater.

Structure

  • Timeline (from git) — the anchoring facts, including the headline number (build duration, fix ratio).
  • What worked — keep it; name why it worked so it's repeatable.
  • What tripped us up — each with the three things above.
  • Anti-patterns — the specific ones, each tagged with the real cost it incurred (not generic advice).
  • One-line takeaway — the single sentence someone should remember.

Calibration (from a real retro)

  • Don't over-index on any single miss. A gap caught in review and fixed with a test cost ~zero — the system worked. The retro's job is the recurring class, not the one-off.
  • Distinguish "we should have known this up front" (rare, usually false) from "we learned this while building and had nowhere to put it" (common, fixable — that's a decision-capture gate, not a smarter design phase).
  • The best takeaways are structural: "parallelize review not the build for small fast projects" beats "communicate better."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment