It depends on clear architecture, disciplined execution, and risk-aware decisions.
This document defines the operating system used to build and launch SaaS products with those principles in place from the start.
It reflects lessons from real builds — architectural choices that are costly to reverse, compliance gaps that surface late, and financial assumptions that require early scrutiny.
The playbook serves as a pre-flight checklist, architectural baseline, compliance reference, and investor-readiness framework.
Each product moves through this system before development begins. The result is more deliberate builds, fewer avoidable surprises, reduced legal and technical risk, and a foundation that stands up to investor review.
Trust Services Criteria
EU data protection regulation
Cybersecurity framework
Application security standards
Accessibility guidelines
Information security standard
Accounting standards
Corporate governance baseline
Production server operating system
Core OS foundation
Containerized deployment
Relational data integrity
Reverse proxy & web layer
Version control discipline
Encrypted mesh networking
Tested recovery procedures
Credential handling guidance
The Playbook defines intent — what this system is being built toward. The Context Layer defines reality — what is actually deployed and running. Neither replaces the other. The gap between them is intentional, and represents current build state.
All AI agents and contributors must read the Context Layer before making any infrastructure decision. It is the operational source of truth, not this document.
- Operational source of truth — running containers, port bindings, network topology, active tunnels
- Documents services not yet deployed alongside those that are
- Must be regenerated after any service is added, removed, or reconfigured
- Required reading for all AI agents before any infrastructure action
- Flat registry of every claimed port — service name, runtime, bound address, owning compose file
- Resolves conflicts before they reach production
- Must be updated before any new service is deployed
STACK_CONTEXT.md and PORT_REGISTRY.md.STACK_CONTEXT.md before any action that affects services, ports, or compose files.Each pillar contains three layers. Work through them in order for each new product.
This pillar informs most technical decisions that follow. Treat it as a constraint document — if a feature does not serve the problem statement and target customer, it should not get built.
- Use the Jobs-To-Be-Done framework
- Outcomes first, features second — avoid feature-first thinking
- Decisions should trace back to a user outcome
- Treat this as a constraint document, not a wish list
- Validate the problem exists before validating the solution
Core scaffolding most products share — auth, billing, database, infrastructure. Standardized across products, rarely rebuilt from scratch.
- 12-Factor App Methodology — strict config separation, stateless processes
- Auth via Auth0, Clerk, or Supabase — avoid building from scratch
- RBAC enforced at API layer, not just UI
- Zoho Subscriptions + Stripe as billing layer
- Shared DB with tenant-scoped rows (org_id on every table)
- Infrastructure as Code from day one
- Secrets should not be in source code
Copy-paste into Claude. Replace all tokens before pasting. The prompt enforces plan-first execution — Claude outputs a numbered plan and waits for "proceed" before writing any file. Clicking Mark as Used sets Environment Setup Guide and Runbook to Draft in the tracker and moves Pillar 2 to In Progress.
You are a senior backend engineer scaffolding a new multi-tenant SaaS product.
Prompt version: v0.3
── TOKENS (replace all before pasting) ──────────────────────────────
PRODUCT_NAME: {{PRODUCT_NAME}}
AUTH_PROVIDER: {{AUTH_PROVIDER}} # Auth0 | Clerk | Supabase
DB_NAME: {{DB_NAME}}
PORT: {{PORT}}
FRAMEWORK: {{FRAMEWORK}} # flask | fastapi
TENANT_ISOLATION: {{TENANT_ISOLATION}} # rls | app-layer
─────────────────────────────────────────────────────────────────────
─── PLAN FIRST ───────────────────────────────────────────────────────
Before writing any files, output a numbered list of every file
you will create and its purpose. Wait for the user to reply
"proceed" before generating any code.
─────────────────────────────────────────────────────────────────────
Scaffold the following when proceeding:
1. Project structure
{{PRODUCT_NAME}}/
├── app/
│ ├── __init__.py
│ ├── config.py # 12-Factor: all config from env vars; no hardcoded values
│ ├── auth.py # {{AUTH_PROVIDER}} middleware — verify token, attach user to request
│ ├── context.py # resolve_org_context() → {user_id, org_id, role} from token + DB
│ ├── routes/
│ │ ├── health.py # GET /api/health → {"status":"ok","env":"...","ts":"..."}
│ │ ├── me.py # GET /api/me → {user_id, org_id, role, org_name}
│ │ ├── billing.py # POST /api/webhooks/zoho — HMAC verify, dispatch to stubs
│ │ └── __init__.py
│ ├── models/
│ │ ├── base.py # SQLAlchemy base; id (UUID PK) + org_id (UUID NOT NULL) + timestamps
│ │ ├── org.py # Org(id, name, slug, plan, created_at)
│ │ ├── user.py # User(id, email, auth_provider_id, created_at)
│ │ └── membership.py # Membership(id, org_id FK, user_id FK, role)
│ └── middleware/
│ └── rbac.py # @require_role('admin'|'member') — API layer only, not UI
├── migrations/
│ ├── env.py # Alembic: include_schemas=True; target_metadata from Base
│ └── versions/ # empty — ready for first migration
├── scripts/
│ ├── backup.sh # pg_dump -Fc + timestamp; exit non-zero on failure; 30-day retention
│ ├── restore.sh # "type YES" confirmation gate; pg_restore --clean --if-exists
│ └── workdrive_upload.sh # stub: upload latest dump to Zoho WorkDrive (wire MCP when ready)
├── docker-compose.yml # dev: ${BIND_HOST:-127.0.0.1}:${PORT}:${PORT}; dev volumes mounted
├── docker-compose.staging.yml # staging overlay: same image tag; no dev volumes; .env.staging
├── .env.example # all required vars with placeholder values — no real secrets
├── .env.staging.example # staging-specific vars, all placeholders
├── .gitignore # blocks .env*, backups/, *.pgdump, __pycache__
├── README.md # project name, token list, quickstart, link to RUNBOOK.md
├── RUNBOOK.md # start/stop, migrations, backup/restore, deploy, rollback
├── requirements.txt
└── alembic.ini
2. Config (config.py) — required env vars
DATABASE_URL # postgresql+psycopg2://user:pass@host/db
SECRET_KEY # no default — must be set explicitly
{{AUTH_PROVIDER}}_DOMAIN
{{AUTH_PROVIDER}}_CLIENT_ID
{{AUTH_PROVIDER}}_CLIENT_SECRET
ZOHO_WEBHOOK_SECRET # HMAC verification key
BIND_HOST # default 127.0.0.1; set 0.0.0.0 for LAN/Tailscale exposure
CORS_ALLOWED_ORIGINS # comma-separated list of allowed origins
CORS_ALLOW_CREDENTIALS # true | false
FRONTEND_ORIGIN # convenience alias; auto-added to CORS_ALLOWED_ORIGINS
ENV # dev | staging | production
WORKDRIVE_FOLDER_ID # Zoho WorkDrive folder for backup uploads (optional)
3. Multi-tenant primitives
· Org, User, Membership models as defined above
· org_id UUID NOT NULL + index on every application table
· resolve_org_context(request): token subject → User → Membership → {user_id, org_id, role}
Raise 403 if no active membership found
· GET /api/me: call resolve_org_context(); return context + org_name; require auth
· Tenant isolation — controlled by TENANT_ISOLATION env var:
"rls" → ALTER TABLE ... ENABLE ROW LEVEL SECURITY; CREATE POLICY using
current_setting('app.current_org')::UUID; set via DB session var
"app-layer" → no RLS; every query filters by org_id explicitly; include test stubs
asserting cross-tenant queries return zero rows
4. Zoho billing seam (billing.py)
· POST /api/webhooks/zoho
· Step 1: verify HMAC-SHA256(payload, ZOHO_WEBHOOK_SECRET) — return 401 on mismatch
· Step 2: parse event_type from payload body
· Step 3: dispatch to stub handlers:
subscription_activated(payload)
subscription_cancelled(payload)
subscription_renewed(payload)
payment_failed(payload)
· Principle: Zoho is source of truth — DB reflects what Zoho sends, not the reverse
· Each stub must log event_type and payload keys before returning 200
5. Backup, restore, and offsite upload
backup.sh:
· set -euo pipefail; pg_dump -Fc; timestamped filename; exit non-zero on failure
· 30-day local retention (find ... -mtime +30 -delete)
· On success, exec scripts/workdrive_upload.sh "$FILE"
restore.sh:
· Takes backup file path as $1; abort with usage if missing
· Print target DB + file; prompt "Type YES to continue"
· pg_restore -U $DB_USER -d $DB_NAME --clean --if-exists
workdrive_upload.sh:
· Reads WORKDRIVE_FOLDER_ID from env
· Stub: echo upload intent + curl skeleton to Zoho WorkDrive Files API
· Comment: # TODO: wire Zoho MCP tool here when available
6. Environment separation
docker-compose.yml dev; ${BIND_HOST:-127.0.0.1} binds; source-mounted app volume
docker-compose.staging.yml staging overlay; no app volume mount; uses .env.staging;
same pinned image tag; add healthcheck config
.env.example dev vars only; all placeholders
.env.staging.example staging vars; ENV=staging; separate DB_NAME and SECRET_KEY slots
Rule: staging and production env files must never be used locally without explicit intent
7. Network and CORS
· CORS middleware reads CORS_ALLOWED_ORIGINS (split on comma) + FRONTEND_ORIGIN
· CORS_ALLOW_CREDENTIALS controls credentials header
· docker-compose port binding: "${BIND_HOST:-127.0.0.1}:${PORT}:${PORT}"
· No hardcoded bind addresses anywhere in compose files
Document these reachability modes in README.md:
Mode 1 — Local only (default, safe):
BIND_HOST=127.0.0.1 — reachable only from localhost
Mode 2 — LAN / Tailscale:
BIND_HOST=0.0.0.0 — reachable on LAN or Tailscale network
Set CORS_ALLOWED_ORIGINS to include Tailscale hostname
Note: confirm firewall rules before enabling
Mode 3 — Reverse proxy / tunnel:
Keep BIND_HOST=127.0.0.1; expose via Tailscale Funnel or Cloudflare Tunnel
CORS_ALLOWED_ORIGINS = public domain only
8. Git hygiene
.gitignore must cover:
.env, .env.*, !.env.example, !.env.staging.example
__pycache__/, *.pyc, *.egg-info/, .venv/
/backups/, /data/, /uploads/, *.pgdump, *.sql
README.md must include:
· One-line product description
· Full token list (all {{TOKENS}} used in this prompt)
· Quickstart: clone → copy .env.example → fill secrets → docker-compose up
· Link to RUNBOOK.md
RUNBOOK.md must include:
· Start / stop service
· Run / rollback migrations (alembic upgrade head / downgrade -1)
· Create backup and test restore (scripts/backup.sh / scripts/restore.sh)
· Deploy to staging (docker-compose -f docker-compose.staging.yml up -d)
· Rollback procedure
9. Constraints (enforced across all generated files)
· No secrets in any tracked file — .env.example and .env.staging.example only
· Auth via middleware only — no per-route token parsing
· org_id filter applied at the repository/service layer in every query
· Zoho HMAC verified before any webhook payload is processed
· backup.sh exits non-zero on pg_dump failure
· All compose port bindings use ${BIND_HOST} — no hardcoded addresses
10. After scaffolding, print this verification checklist:
── Environment ──────────────────────────────────────────────────
[ ] cp .env.example .env && fill in all required values
[ ] docker-compose up -d && docker-compose ps → all containers Up
[ ] docker exec backend alembic upgrade head → no errors
[ ] curl http://${BIND_HOST}:${PORT}/api/health → {"status":"ok"}
── Multi-tenant ─────────────────────────────────────────────────
[ ] Seed: create test Org + User + Membership via psql or seed script
[ ] GET /api/me with valid token → {user_id, org_id, role, org_name}
[ ] Cross-tenant isolation:
SET app.current_org = '<org-a-id>';
SELECT COUNT(*) FROM <table> WHERE org_id != '<org-a-id>';
# Expected: 0
── Billing seam ─────────────────────────────────────────────────
[ ] POST /api/webhooks/zoho with bad signature → 401
[ ] POST /api/webhooks/zoho with valid signature → 200, event logged
── Reachability ─────────────────────────────────────────────────
[ ] Mode 1: BIND_HOST=127.0.0.1 — curl from localhost succeeds
[ ] Mode 2: BIND_HOST=0.0.0.0 — curl from LAN device succeeds
[ ] Mode 3: tunnel configured — curl via Tailscale/Cloudflare hostname succeeds
── Git hygiene ──────────────────────────────────────────────────
[ ] git grep -rn "password\|secret\|api_key" -- "*.py" "*.yml" | grep -v ".env.example"
# Expected: no output
[ ] git status does not show .env (gitignore working)
[ ] README.md and RUNBOOK.md present and non-empty
Generated from system audit — not hand-authored. Regenerate after any service change. All AI agents must read this before any infrastructure action.
# STACK_CONTEXT.md
# Generated: {{DATE}} — system audit, not hand-authored.
# Regenerate after any service is added, removed, or reconfigured.
# Required reading for all AI agents before infrastructure actions.
## Host
Host: {{HOSTNAME}}
LAN IP: {{LAN_IP}}
Tailscale: {{TAILSCALE_IP}} / {{TAILSCALE_HOSTNAME}}
## Running Services
| Container | Image | Port Binding | Status |
|-----------|-------|-------------|--------|
| {{name}} | {{image}} | 0.0.0.0:{{port}} | Up Nh |
## Port Map
| Port | Service | Runtime | Bound To | Compose File |
|------|---------|---------|----------|-------------|
| {{port}} | {{service}} | Docker / native | 0.0.0.0 / 127.0.0.1 | {{file}} |
## Not Yet Deployed
| Service | Planned Port | Status |
|---------|-------------|--------|
| {{service}} | {{port}} | Not deployed |
## Connectivity
Tailscale: active / inactive
Cloudflare Tunnel: active / inactive
## Assumptions
- ASSUMPTION: ...
Update before deploying any new service. Resolve conflicts here — before they reach production.
# PORT_REGISTRY.md
# RULE: Update this file before deploying any new service.
# RULE: Resolve port conflicts here — before they reach production.
# Last updated: {{DATE}}
| Port | Service | Runtime | Bound To | Compose File | Status |
|------|---------|---------|----------|-------------|--------|
| 5000 | backend | Docker | 0.0.0.0 | docker-compose.yml | active |
| 5432 | postgres | Docker | 0.0.0.0 | docker-compose.yml | active |
| 8080 | frontend | Docker | 0.0.0.0 | docker-compose.yml | active |
| {{port}} | {{service}} | — | — | — | planned |
## Conflict Log
| Date | Port | Conflict | Resolution |
|------|------|----------|-----------|
| {{date}} | {{port}} | {{description}} | {{resolution}} |
Git-tracked under scripts/. All use set -euo pipefail. Configured via env vars — no hardcoded values.
── backup.sh ──────────────────────────────────────────────────────
#!/usr/bin/env bash
set -euo pipefail
DB_CONTAINER="${DB_CONTAINER:-db}"
DB_NAME="${DB_NAME:-app}"
DB_USER="${DB_USER:-app}"
BACKUP_DIR="${BACKUP_DIR:-./backups}"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
FILE="${BACKUP_DIR}/${DB_NAME}_${TIMESTAMP}.pgdump"
mkdir -p "$BACKUP_DIR"
echo "→ Dumping ${DB_NAME}…"
docker exec "$DB_CONTAINER" pg_dump -U "$DB_USER" -Fc "$DB_NAME" > "$FILE"
echo "✓ Backup: $(du -sh "$FILE" | cut -f1)"
find "$BACKUP_DIR" -name "*.pgdump" -mtime +30 -delete # 30-day retention
── restore.sh ─────────────────────────────────────────────────────
#!/usr/bin/env bash
set -euo pipefail
BACKUP_FILE="${1:?Usage: restore.sh <backup.pgdump>}"
DB_CONTAINER="${DB_CONTAINER:-db}"
DB_NAME="${DB_NAME:-app}"
DB_USER="${DB_USER:-app}"
echo "⚠ This will OVERWRITE ${DB_NAME}. File: ${BACKUP_FILE}"
printf " Type YES to continue: "; read -r CONFIRM
[[ "$CONFIRM" == "YES" ]] || { echo "Aborted."; exit 1; }
docker exec -i "$DB_CONTAINER" pg_restore \
-U "$DB_USER" -d "$DB_NAME" --clean --if-exists < "$BACKUP_FILE"
echo "✓ Restore complete."
── health-check.sh ────────────────────────────────────────────────
#!/usr/bin/env bash
set -euo pipefail
PORT="${PORT:-5000}"
echo "── Containers ──────────────────────────────────────────"
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
echo "── Migration state ─────────────────────────────────────"
docker exec backend alembic current 2>/dev/null || echo " (unreachable)"
echo "── Health endpoint ─────────────────────────────────────"
curl -sf "http://127.0.0.1:${PORT}/api/health" | python3 -m json.tool \
|| echo " ✗ Health check failed"
org_id on every application table — indexed, NOT NULL. RLS enabled before any customer data enters production. Run the validation query as the app DB user, not the postgres superuser.
-- Every application table follows this baseline.
-- Replace 'resources' with your entity name.
CREATE TABLE resources (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
org_id UUID NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
-- add domain columns here
);
CREATE INDEX idx_resources_org_id ON resources (org_id);
-- Row-Level Security — enable before any customer data enters
ALTER TABLE resources ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON resources
USING (org_id = current_setting('app.current_org')::UUID);
-- alembic/env.py — required additions
-- from app.models.base import Base
-- target_metadata = Base.metadata
-- include_schemas = True
-- Validation (run as app DB user — not postgres superuser)
SET app.current_org = 'aaaaaaaa-0000-0000-0000-000000000000';
SELECT COUNT(*) FROM resources;
-- Expected: 0 (org has no data — confirms RLS is enforced)
Run in order. All six must pass before marking Pillar 2 in progress.
# 1 — Running containers
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
# 2 — Migration state (must show a head revision — not "None")
docker exec backend alembic current
# 3 — Health endpoint (expect {"status": "ok"})
curl -s http://127.0.0.1:$PORT/api/health | python3 -m json.tool
# 4 — Zoho webhook reachable (expect 200 or 400 — not 404)
curl -s -o /dev/null -w "%{http_code}" \
-X POST http://127.0.0.1:$PORT/api/webhooks/zoho
# 5 — RLS active (run as app DB user — not postgres superuser)
docker exec -it db psql -U $DB_USER -d $DB_NAME -c \
"SET app.current_org = 'aaaaaaaa-0000-0000-0000-000000000000';
SELECT COUNT(*) FROM resources;"
# Expected: 0 rows — confirms tenant isolation is enforced
# 6 — No secrets in tracked files
git grep -rn "password\|secret\|api_key\|token" -- "*.py" "*.yml" "*.env" \
| grep -v ".env.example"
# Expected: no output
The Playbook enforces discipline without punishing early-stage execution. Priority tiers prevent premature overbuild — not every criterion carries the same cost of delay. Tier 1 items protect architecture: their absence forces structural teardowns at the worst possible time. Tier 2 items protect customers: they must exist before production exposure or first revenue. Tier 3 items protect scale: they are not optional, but their absence does not block safe early iteration. Completion of Tier 1 enables safe feature development.
- Migrations configured → Pre-Launch: CI/CD pipeline operational
- Auth provider wired → Pre-Launch: Authentication implemented via established provider
- RBAC enforced at API layer → Pre-Launch: RBAC implemented and tested at API layer
- Zoho webhook endpoint reachable → Pre-Launch: Zoho Subscriptions webhooks connected to application and tested
- Dev/Staging separation confirmed → Pre-Launch: All environments separated — Dev, Staging, Production
- Secrets not in source code → Pre-Launch: No secrets in source code
- Backups configured and restore tested → Pre-Launch: Backups configured and tested
Standard screens most products ship before feature work begins:
- Public landing page — problem, solution, pricing, CTA
- Auth screens — sign up, login, forgot password, MFA
- Onboarding flow — first-run to first value
- Main application dashboard
- Settings and profile management
- Billing and subscription management page
- Admin dashboard — users, usage, account controls
Internal control panel for operating the business:
- All accounts and users with status
- Revenue overview — MRR, churn, trial conversions (from Zoho)
- Feature flag management — enable/disable per account without a deploy
- Manual account adjustments via Zoho Subscriptions, reflected via webhook
- Support ticket visibility via Zoho Desk integration
- Audit logs — append-only, who did what, when
The measurement layer — what users are doing, whether the product is working, whether the business is healthy. Built in from day one, not bolted on later.
- Consistent naming: noun_verb (subscription_upgraded, search_performed)
- Segment as CDP event router — instrument once, route anywhere
- MRR, churn, LTV, CAC from Zoho data — not just estimated
- Alerts for anomalies — learn from monitoring, not customer complaints
Foundational in 2026. Should exist before the first paying customer. Covers privacy, data protection, legal agreements, security standards, AI governance, and accessibility compliance.
- Privacy by Design — legal basis for every data point before collection
- CMP for cookie consent — required for EU/UK and increasingly US states
- Under GDPR: 72 hours to notify regulators of a breach
- IP assignment signed before any contributor touches code
- Open source license audit — GPL in a commercial product may require open-sourcing your code
- AI governance — disclose where and how AI is used
Completed per product as it matures. Defines how the product reaches its market, at what price, and through which channels. Pricing should be validated by real customer conversations before launch.
- Pricing validated by minimum three willingness-to-pay conversations
- No single customer should exceed 20% of revenue (concentration risk)
- ICP defined with specificity — not "SMBs" but the exact buyer profile
- Feature gate matrix aligned to Zoho Subscriptions tier configuration
Completed per product when relevant. The investor-facing layer — everything needed to navigate due diligence with fewer surprises. Most other pillars feed into this one.
- One-pager that can be understood in 60 seconds
- Financial model with MRR projections and unit economics
- Cap table and entity structure clean and documented
- Data room organized before it is needed
The financial discipline layer. Most founders scale before they understand their unit economics. This pillar surfaces the financial questions that determine whether the business is viable before capital is deployed.
- CAC from Zoho CRM deal data and Zoho Books marketing expense
- LTV from Zoho Subscriptions cohort data
- LTV:CAC ratio target at least 3:1
- Payback period target under 12 months
- Runway calculated weekly, reviewed weekly
- All equity on vesting schedule — 4 years, 1-year cliff
A living document of key known risks to the business — technical, legal, financial, market, and operational — with a mitigation plan for each. A clear signal of investor-grade operational thinking.
- Each risk rated: likelihood (1-5) × impact (1-5) = risk score
- Risks scoring 15+ are treated as critical and require active mitigation
- Reviewed monthly — not a document that sits on a shelf
- Five categories: Technical, Legal, Financial, Market, Operational
| Document | Owner | Review Frequency |
|---|---|---|
| Product Brief | Founder | Per major pivot |
| Competitive Analysis | Founder | Quarterly |
| Assumptions Log | Founder | Monthly |
| Architecture Decision Records | Lead Dev | Per decision |
| System Architecture Diagram | Lead Dev | Quarterly |
| Entity Relationship Diagram | Lead Dev | Per schema change |
| API Documentation | Lead Dev | Per release |
| Dependency Register | Lead Dev | Per new dependency |
| Vendor Lock-In Risk Log | Lead Dev | Quarterly |
| Technical Debt Backlog | Lead Dev | Sprint planning |
| Disaster Recovery Plan | Lead Dev | Annually + after incidents |
| Zoho One Integration Map | Dev | Per integration change |
| Zoho One Configuration Document | Founder / Dev | Per configuration change |
| Privacy Policy | Legal / Founder | Per data practice change |
| Terms of Service | Legal / Founder | Annually |
| Cookie Policy | Legal / Founder | Per change |
| DPA Template | Legal / Founder | Annually |
| Data Map and Article 30 Record | Founder | Quarterly |
| Incident Response Plan | Founder / Dev | Annually + after incidents |
| Vendor Security Checklist | Founder | Per new vendor |
| AI Usage Policy | Founder | Per AI feature added |
| IP Assignment Agreements | Founder | Per new contributor |
| Open Source License Audit | Lead Dev | Per new dependency |
| Worker Classification Register | Founder | Per new hire or contractor |
| Unit Economics Model | Founder | Monthly |
| Runway Dashboard | Founder | Weekly |
| Cap Table | Founder | Per equity event |
| Co-Founder Agreement | Founder / Legal | Per major change |
| Risk Register | Founder | Monthly |
| Risk Review Notes | Founder | Monthly |
| Event Tracking Plan | Product / Dev | Per feature release |
| Metrics Definitions | Founder | Per metric added |
| Analytics Dashboard Inventory | Founder | Quarterly |
| Design System Document | Designer / Dev | Per design change |
| Feature Flag Register | Dev | Per flag added or removed |
| Internal Operations Manual | Founder / Dev | Per process change |
| Audit Log Schema | Dev | Per change |
| Pricing Tiers and Feature Gate Matrix | Founder | Per pricing change |
| ICP Definition | Founder | Quarterly |
| Pitch Deck | Founder | Per fundraise |
| Financial Model | Founder | Monthly |