crastinating.pro
Public beta · Self-host or crastinating.pro Cloud

Every stalled ticket is an unmade decision.

crastinating reads your repo, Linear and calendar, finds the blocker hiding inside each stalled ticket, drafts the smallest memo that could unblock it, and routes it to the one person who can actually decide.

First-run latency: under 60s from PR to decision request. Works with GitHub + Linear today. Jira and Notion next.

Decision types
14
Adapters
6
Median decide time
4h 12m
Price per reader seat
$0
Decision queue · Payments team
3 open · 1 overdue
PAY-812
Which idempotency key shape for refund retries?
Awaiting decider
  • (a) refund_id + attempt — stable across retries
  • (b) new UUID per retry, dedup server-side
  • (c) tenant_id + refund_id hash
Decider: @maren · staff engdue in 3h
PAY-841
Should settlement webhooks move to the new queue?
Open · drafting memo
  • Move all webhooks · breaks partner contracts
  • Dual-write for 30 days · recommended
  • Pause until partner confirms
Decider: @jun · eng managerdue 2d
OVERDUE · PAY-799
Choose auth provider for internal tools
Waiting on @kai for 6 days · routed for escalation
The decision types

Six ways a ticket hides a decision. One queue to surface them.

Each decision type is a typed schema you import from @crast/decisions. Crastinating spots the matching pattern, drafts the memo and asks the named decider.

Tech choice· Unopinionated

@crast/decisions

A pick between two-plus packages, protocols or patterns. Crastinating drafts the tradeoff table from your repo and links the artifacts.

INFRA-212
Which queue for settlement webhooks?
Awaiting decider
  • SQS · ships in 3h, $0/mo
  • Temporal · higher ceiling, 2w ramp
  • Defer — ask again in 2 weeks
Decider: @maren · staff engdue 1d

Scope cut· Editorial

@crast/decisions

Someone needs to say the explicit no. We summarise what's in, what's out, and what moves to the next release.

ONBOARD-55
Does v1 support multi-seat at launch?
Open · drafting memo
  • Ship solo-only, multi-seat in v2
  • Hold launch for multi-seat
Decider: @jun · eng managerdue 3d

Access request· Unblock

@crast/decisions

Stuck because a human has the key. Crastinating routes to the named grantor with the smallest ask that proves need.

SEC-104
Read-only prod DB for migration dry-run?
Awaiting decider
  • Grant 24h read role scoped to migrations schema
  • Provide a sanitized dump instead
Decider: @rae · securitydue 4h

Policy gate· Compliance

@crast/decisions

A decision that needs a reviewer outside engineering — legal, finance, design. Same queue, different routing.

LEGAL-38
Keep PII in analytics export for 90 days?
Open · drafting memo
  • Keep 90d with DPA in force
  • Hash + 30d retention
  • Drop PII entirely
Decider: @elena · legaldue 2d

Vendor pick· Buy vs build

@crast/decisions

Another SaaS bill vs another service to run. We pull pricing, SLAs, and the last six months of incidents.

PLAT-76
Hosted search: Typesense vs Algolia vs self-host?
Open · drafting memo
  • Typesense Cloud · $199/mo
  • Algolia · $0 → $500/mo at scale
  • Self-host on Fluid · 1 dev-week
Decider: @isak · eng directordue 5d

Rollout gate· Launch

@crast/decisions

The staged rollout step that always stalls at the halfway flag. Crastinating checks criteria and asks the on-call owner.

REL-19
Promote settlement-v2 from 25% to 100%?
Overdue
  • Promote · error rate 0.04% under budget
  • Hold · wait 24h more
Decider: @on-call · paymentsdue now
One file, one queue

A queue is a file. A routing change is a commit.

Drop a TypeScript file in queue.crastinating.ts, export a defineQueue() result, and crastinating reads your sources, classifies blockers and asks deciders exactly the way the file declares.

  • Typed decision schemas — techChoice(), scopeCut(), rollout(), policy().
  • Review routing like code — a PR that changes who decides what is the right diff.
  • Every decision becomes a searchable memo with context, options and the chosen path.
// queue.crastinating.ts
import { defineQueue, deciders, on } from "@crast/runtime";
import { techChoice, scopeCut, rollout, policy } from "@crast/decisions";

export default defineQueue({
  team: "payments",
  sources: [
    "github:acme/payments",
    "linear:PAY",
    "calendar:team-payments@acme.com",
  ],
  deciders: deciders({
    "staff-eng": ["@maren", "@isak"],
    "eng-manager": "@jun",
    "security": "@rae",
    "legal": "@elena",
  }),
  escalate: { afterHours: 48, to: "eng-manager" },
  route: [
    on(techChoice()).askOne("staff-eng"),
    on(scopeCut()).askOne("eng-manager"),
    on(rollout({ rolloutKey: /^promote:/ })).askOne("on-call"),
    on(policy({ kind: "pii" })).askBoth("legal", "eng-manager"),
  ],
});
From stalled ticket to decided

Three steps. One git workflow. Zero "waiting on" limbo.

  1. 01
    Install the CLI

    pnpm add -D @crast/cli, run crastinating init. The CLI writes queue.crastinating.ts, installs the GitHub App and connects Linear.

  2. 02
    Declare deciders

    Name the handful of people who can actually say yes: staff eng, eng manager, security, legal. That's your routing table.

  3. 03
    Ship the queue

    Merge the PR. Crastinating watches PRs and tickets, spots blockers, drafts memos, and routes each one exactly where it should go.

# bootstrap crastinating in any repo
pnpm add -D @crast/cli
pnpm crastinating init

# scaffold a queue for one team
pnpm crastinating new payments

# ship it
git checkout -b feat/crastinating-payments \
  && git commit -am "feat: decision queue for payments" \
  && gh pr create
What teams ship

Four kinds of stalled tickets most of us already have.

Platform

Infra choices, out of DMs

Queue, cache, auth, tracing — the picks that drift in Slack for weeks. Crastinating turns each into a PR-reviewable decision with a named owner.

Launch

Rollout gates that actually gate

25% → 50% → 100% steps get a real owner and a real timer. No more dashboards watched by nobody at 02:00.

Scope

Cutting without the meeting

Ship v1 without multi-seat? Keep the flag or delete it? The answer is a memo, not a three-hour call.

Cross-org

Legal, finance, design in-loop

Decisions that need a non-engineer reviewer stay in the same queue — routed to the right reviewer with the smallest ask that proves need.

The stack

Opinionated where it matters. Boring where it should be.

TypeScript-first

Decisions, deciders, routes and context are typed. Autocomplete every field, catch routing regressions at build time.

Git-native

Version, review, revert. A routing change is a diff. Who can decide what is the same artifact as the code that needs to decide.

Model-assisted, human-decided

Claude and GPT-5 draft the tradeoff, Crastinating never decides. The memo is a starting point, not an answer.

Next.js 16 runtime

Server Components, Cache Components per queue, typed routes. Installs into any Next.js repo with zero config.

Vercel Fluid Compute

Watchers reuse instances with graceful shutdown. 300s default timeouts for the deepest Linear backfill.

Self-host or Cloud

Ship into your own Next.js app with @crast/runtime, or point the CLI at crastinating.pro Cloud. Same code either way.

Pricing

Free to self-host. Priced per decider — readers don't pay.

Open core

$0self-host

The crastinating runtime, decisions and routing engine — MIT-licensed. Drop into any Next.js repo.

  • @crast/runtime · @crast/decisions · @crast/routing
  • MIT licence, MIT-forever
  • GitHub App + Linear adapter included
  • Unlimited decisions, unlimited readers

Cloud

Most popular
$24/ decider / month

Hosted watchers, memo drafting, escalation, analytics and a console at app.crastinating.pro.

  • Everything in Open core
  • AI-drafted memos (Claude + GPT-5)
  • Escalation timers + on-call handoff
  • Decision analytics + weekly digest
  • Readers are free, forever

Business

$99/ decider / month

SSO, private queues, audit log and an SLA — for teams running decisions as infra.

  • Everything in Cloud
  • Unlimited private queues
  • SSO (SAML · OIDC) + SCIM
  • Immutable audit log + export
  • 99.95% uptime SLA

Stop waiting. Start deciding.

Install the CLI, name three deciders, merge the PR. The queue starts classifying blockers and asking for decisions within the hour — no new tool to babysit.