Playbook: Web App / SaaS
What an agent looks for and models when calibrating a web app or SaaS product: features, experiments and flags, customer feedback, plans.
For Calibrate, Phase 2b. Index: Playbooks.
Evidence first. This playbook is a list of things to look for, not a template: no database, column or row gets created unless this project's code, docs or history shows it.
Pick it when
A web framework in the manifest — next, nuxt, @remix-run/*, @sveltejs/kit,
astro, django, rails, laravel/framework — plus at least two product signals:
user routes (app/, pages/, src/routes/), auth (next-auth, @auth/*, devise,
@clerk/*, @supabase/*), billing (stripe, @paddle/*), feature flags or product
analytics (posthog-js, launchdarkly-*, @vercel/flags, unleash-*), pricing or
marketing pages, locale message files. A framework alone is a website, not a product.
Concepts to model
Features (conceptType: feature) — the product as users meet it, named the way the
app's own navigation names it; never the route or component list.
Columns: Area select (from the navigation) · Status status (Idea, Planned → Building
→ Shipped, Retired) · Audience select (from the plans: Free, Pro, Admin…) ·
Shipped date · Flag text (the key that gates it, if any).
Experiments & flags (experiment) — only with a flag or experiment SDK in use.
Flag key text · Status status (Draft → Running → Rolled out, Removed) ·
Metric text · Started date · Ended date.
Customer feedback (feedback) — only when feedback exists: issue labels such as
bug/feature-request, a support export, a feedback model in the code, notes you were
given. Type select (Bug, Request, Praise, Churn reason) · Area select ·
Source select (Support, Issue, Interview, Review) · Received date ·
Link url.
Plans & pricing (plan) — only when prices or limits live in code (price ids, a
limits constant). Price number · Interval select (Monthly, Yearly) ·
Status select (Live, Legacy). Body: the limits, quoted from the code.
Example rows
- Features — Team invitations · Area
Workspace· StatusShipped· AudiencePro. Body: "Owners invite by email; the link expires after 7 days (INVITE_TTLinsrc/lib/invites.ts). Seats are checked when the invite is accepted, not when it's sent, so an over-limit invite fails late — see the gotcha." - Customer feedback — Export loses table formatting · Type
Bug· AreaExport· SourceIssue· Link to the issue. Body: "Three reports since v2.3; nested tables flatten to text. Affects the PDF path only."
Status screen
Product status, next to the overview:
metricFeatures, filter Status equalsBuilding, unit "building"chartdonut, Features grouped by StatuslistFeatures, filter Status equalsPlanned, showColumns Area, AudiencemetricFeedback, trend on Received over 30 days — only if Feedback existschartbar, Feedback grouped by Arealinksoverview, Decisions, Features
Don't
- Turn the route tree or component folder into Features — that is one grep away; a feature is what a user would name.
- Import every issue as feedback. Model the recurring themes with a few representative rows, and link the tracker.
- Copy prices from marketing copy when the code disagrees. Write what the code says and log the mismatch as an open question.