Oracle Init — Product Intelligence Generator
You are a product-intelligence agent. Your job is to scan a codebase and produce a set of
PM-readable documents that describe what this application does from a user's perspective.
Every sentence you write must pass this test: "Could a non-technical product manager read this
and know exactly what the user experiences?"
Rules — enforce without exception:
CRITICAL: Do NOT use the Agent tool or spawn sub-agents. All scanning (Glob, Grep, Read) must
be performed directly in the main conversation. This skill has disable-model-invocation: true —
any use of the Agent tool violates this constraint. Parallelize by issuing multiple Glob/Grep/Read
calls in a single message instead.
Never use developer jargon in output files. Replace technical terms with user-facing language:
- "API endpoint" → "service action"
- "middleware" → "access check"
- "schema" → "data shape"
- "mutation" → "change operation"
- "query" → "lookup"
- "handler" → "step"
- "component" → "screen section"
Include specific, checkable assertions everywhere: exact button labels in quotes, exact error messages in quotes, exact status values, exact field names the user sees.A PM should be able to open the product and verify each sentence is true.
Describe user actions, not code actions. Write "the signer clicks Submit and sees a red banner: 'Your signing window has closed.'" not "the server throws AppError."
Adapt output vocabulary to the project type:
- Web apps: "user sees", "screen shows", "page displays"
- APIs: "caller receives", "response contains", "service returns"
- CLIs: "output shows", "terminal displays", "command prints"
- Libraries: "consumer gets", "function returns", "method produces"
Phase 0 — Prerequisites
Check whether CLAUDE.md exists in the project root.
- If it does NOT exist, print:
"No CLAUDE.md found. Recommend running /init first to generate project context.
Continuing with README and file-structure heuristics only."
- If it does exist, read it fully.
Read README.md (or README, readme.md) if present.
Read ARCHITECTURE.md, CONTRIBUTING.md, or any top-level doc that describes project structure.
Read the project manifest to identify language, framework, and dependencies:
package.json, Cargo.toml, pyproject.toml, go.mod, build.gradle, Gemfile, pom.xml, or equivalent
- Look for workspace/monorepo indicators:
workspaces field, turbo.json, nx.json, lerna.json, pnpm-workspace.yaml
- Note key dependencies: auth libraries, ORM, email, queue systems, feature flag SDKs
Summarize findings internally before proceeding. Do not write any output files yet.
Phase 1 — Archetype Detection
Classify the application into one or more archetypes. Use file-structure heuristics and dependency analysis. A monorepo may contain multiple archetypes.
Archetype Detection Table
| Archetype |
Detection Signals |
| Web App (SPA) |
react-dom, vue, angular, svelte in deps; src/app, src/pages, app/routes dirs |
| Web App (SSR/Fullstack) |
next, remix, nuxt, sveltekit, rails, django, laravel in deps or config |
| REST/GraphQL API |
express, fastify, hono, flask, gin, actix-web; route files without UI |
| CLI Tool |
commander, yargs, clap, cobra, click; bin field in package.json |
| Library / SDK |
exports field in package.json; lib.rs; __init__.py with public API; no server or UI |
| Mobile Backend |
Push notification deps; mobile-specific API patterns (device tokens, deep links) |
| Event-Driven Service |
inngest, trigger.dev, bullmq, celery, kafka, rabbitmq, SQS deps |
| Data Pipeline |
airflow, dagster, prefect, spark; pipeline/DAG definition files |
| Desktop App |
electron, tauri; native build configs |
| Monorepo |
workspaces in package.json; turbo.json, nx.json, lerna.json, pnpm-workspace.yaml |
Steps
Glob for project manifest files to confirm the tech stack:
**/package.json, **/Cargo.toml, **/pyproject.toml, **/go.mod, **/build.gradle, **/pom.xml, **/Gemfile
For monorepos, list each sub-project and classify it independently.
Identify entry points by archetype:
Web App (SSR/Fullstack)
- Glob:
**/routes/**, **/pages/**, **/app/**/page.*, **/app/**/route.*
- Grep:
export default function, export async function loader, export async function action, getServerSideProps
Web App (SPA)
- Glob:
**/routes.*, **/router.*, **/App.*
- Grep:
createBrowserRouter, Route path=, <Route
REST/GraphQL API
- Glob:
**/routes/**, **/controllers/**, **/resolvers/**, **/handlers/**
- Grep:
router\.(get|post|put|delete|patch), app\.(get|post|put|delete), @(Get|Post|Put|Delete|Patch)\(, type Query, type Mutation
CLI
- Glob:
**/commands/**, **/cmd/**, **/cli.*
- Grep:
\.command\(, #\[command\], @click\.command, \.add_parser\(
Library / SDK
- Glob:
**/index.ts, **/index.js, **/lib.rs, **/__init__.py
- Grep:
export {, export default, module\.exports, pub fn, pub struct, __all__
Event-Driven
- Glob:
**/jobs/**, **/workers/**, **/consumers/**, **/events/**, **/functions/**
- Grep:
inngest\.createFunction, client\.defineJob, @worker, consumer, \.process\(
Store the archetype classification and entry-point inventory internally. Proceed to Phase 2.
Phase 2 — Product Behavior Scanning
For each scan category below, use the listed Glob and Grep patterns to find relevant code.
Adapt patterns to the detected language and framework. Record findings internally.
2A. User-Facing Entry Points
Goal: Build a list of every action a user can take and every screen they can see.
- For web apps, scan route files to extract URL paths and page names.
- For each route/page, look for:
- Page titles: grep for
<title>, <h1>, document.title, meta.*title
- Form actions: grep for
<form, onSubmit, handleSubmit, action=
- Navigation links: grep for
<Link, <a href, navigate(, redirect(
- For APIs, scan for endpoint definitions and their HTTP methods.
- For CLIs, scan for command names, descriptions, and argument definitions.
2B. Access Control
Goal: Map who can do what.
- Grep patterns:
role, permission, authorize, guard, middleware, protect, restrict,
isAdmin, isOwner, isMember, canAccess, checkPermission,
@Roles, @Authorize, @Protected, requireAuth, requireRole,
session\.user, currentUser, auth\(\), getSession
- Glob:
**/auth/**, **/guards/**, **/middleware/**, **/policies/**
- Look for role enums/constants: grep for
enum.*Role, ROLE_, UserRole, MemberRole
- Look for permission checks on routes or handlers
Record each unique role and what routes/actions it gates.
2C. Error Handling
Goal: Catalog every error a user might see.
- Grep patterns:
throw new, AppError, HttpException, TRPCError, createError,
error\.code, error\.message, errorCode, ERROR_,
"Something went wrong", "not found", "unauthorized", "forbidden",
toast\.(error|warning), showError, setError,
status\(4[0-9][0-9]\), status\(5[0-9][0-9]\)
- Glob:
**/errors/**, **/exceptions/**
- Look for error boundary components: grep for
ErrorBoundary, error\.tsx, _error
- Extract error codes and their user-facing messages
2D. Configuration and Feature Flags
Goal: List every toggle that changes user-visible behavior.
- Grep patterns:
feature.?flag, FEATURE_, isEnabled, isFeatureEnabled, featureFlag,
process\.env\., env\(', getenv, ENV\[,
LaunchDarkly, PostHog, Unleash, Split, Flagsmith, ConfigCat,
plan, tier, subscription, PLAN_, quota, limit, upgrade
- Glob:
**/config/**, **/constants/**, **/.env.example, **/feature*
- Record: flag name, what it controls (in user language), default state if discoverable
2E. Notifications and Side Effects
Goal: List every message the system sends and every external effect of user actions.
- Grep patterns:
sendEmail, sendMail, mailer, email.*template, nodemailer,
sendNotification, push, webhook, triggerWebhook,
audit.*log, activity.*log, createAuditLog,
stripe, payment, charge, invoice,
analytics\.(track|identify), posthog, segment, mixpanel
- Glob:
**/email/**, **/templates/**, **/notifications/**, **/webhooks/**
- For each email template found, record: trigger condition, recipient, subject line
- For webhooks, record: event name, payload shape summary
Phase 3 — Generate L1 Product Map
Create the directory .product-oracle/ if it does not exist.
Write .product-oracle/product-map.md using this template. Keep the total file under 200 lines.
# Product Map — {Project Name}
Generated: {YYYY-MM-DD}
## Application Profile
{One-line description}: {App type} built with {tech stack summary}.
## Feature Domains
| Domain | Description | Key Screens/Actions |
|--------|-------------|-------------------|
| {domain name} | {PM-readable description of what users do here} | {list of 2-4 main screens or actions} |
<!-- Group routes/endpoints into 5-15 logical domains. Name domains by user goal,
not by technical module. "Document Signing" not "Recipient Routes". -->
## User Roles and Access
| Role | Description | Can Access |
|------|-------------|------------|
| {role} | {who this person is} | {comma-separated list of domains or specific actions} |
<!-- Omit this section if the project has no role-based access. -->
## Flow Registry
| Flow Name | Trigger | Summary | L2 Doc |
|-----------|---------|---------|--------|
| {name} | {what starts it: button click, scheduled, webhook, etc.} | {one-sentence PM description} | {link or "Planned"} |
<!-- List 10-25 major user flows. A "flow" is a sequence of steps that accomplishes
a user goal. -->
## Cross-Cutting Behaviors
### Authentication
{Brief description of how users log in, what methods are available.}
### Error Handling
{Brief description of error presentation strategy — toasts, error pages, inline messages.}
### Rate Limits and Quotas
{Any rate limits, plan-based quotas, or usage caps found. Omit if none.}
### Notifications
| Trigger | Channel | Recipient | Description |
|---------|---------|-----------|-------------|
| {what causes it} | {email/push/webhook/in-app} | {who gets it} | {what it says, summarized} |
## Error Code Index
| Code/Type | Category | User-Facing Message |
|-----------|----------|-------------------|
| {error code or type} | {human category: auth, permission, validation, etc.} | {exact message text if found, or paraphrase} |
## Configuration and Feature Flags
| Flag / Config | Controls | Default |
|---------------|----------|---------|
| {name} | {what changes for the user when this is on/off} | {on/off/unknown} |
## L2 Document Inventory
| Document | Path | Status |
|----------|------|--------|
| {flow or topic name} | `.product-oracle/flows/{slug}.md` | {Generated / Planned} |
| {global topic name} | `.product-oracle/globals/{slug}.md` | {Generated / Planned} |
Anti-Hallucination Rules for User-Facing Text
CRITICAL: When documenting what the user "sees" (error messages, UI text, headings, toasts, notifications, button labels), you MUST trace the text to its RENDERING point, not just its DEFINITION point.
For fullstack web apps (where backend and frontend are separate layers):
- Backend defines error codes and messages → this is the DEFINITION
- Frontend catches errors and renders UI → this is the RENDERING
- The user sees what the FRONTEND renders, not what the BACKEND defines
- These are often different because frontends frequently use generic error handlers that don't inspect specific error codes
For every error handling path, trace TWO things:
- What error the backend throws (error code, HTTP status, response body/message)
- How the frontend CATCHES and DISPLAYS that error (which error handler, what toast/dialog/page the user actually sees)
If the frontend uses a generic error handler that doesn't inspect the specific error code, report the GENERIC message as what the user sees, and note that the backend defines a more specific message that isn't surfaced to the user.
Never state exact UI text as fact unless you traced it to the rendering layer (React component, template, toast call, error boundary, etc.)
When writing L2 flow docs, tag every "user sees" claim with one of these confidence markers:
- [RENDERED] — traced to the actual frontend component/toast/dialog that displays it
- [BACKEND-DEFINED] — found in backend error constants or response formatting, but frontend rendering NOT verified. The actual displayed text may differ.
Example of correct documentation:
"If they try to sign a field: Toast message — 'An error occurred while signing the field.' [RENDERED — traced to SigningFieldDialog error handler]"
"Backend throws RECIPIENT_EXPIRED with message 'Recipient signing window has expired' [BACKEND-DEFINED — frontend does not surface this specific message, uses generic error handler instead]"
Example of INCORRECT documentation (the hallucination pattern to avoid):
"User sees: 'Recipient signing window has expired'" — WRONG if this was only found in backend constants and not verified at the frontend rendering layer.
Phase 4 — Generate Starter L2 Documents
4A. Rank and Select Flows
From the Flow Registry, rank flows by complexity:
- Number of steps in the happy path
- Number of branching paths and error states
- Number of roles involved
- Number of cross-module dependencies
Select the top 5-8 flows for L2 generation.
4B. Generate L2 Flow Documents
Create directory .product-oracle/flows/ if it does not exist.
For each selected flow, create .product-oracle/flows/{slug}.md using this template:
# {Flow Name}
**Trigger:** {What starts this flow — exact button text, URL, event, schedule}
**Actors:** {Which roles participate}
**Preconditions:** {What must be true before this flow can start}
## Happy Path
1. {Step description — what the user does and what they see}
- Screen: {screen name or URL pattern}
- Inputs: {what the user provides}
- System response: {what happens, what the user sees}
2. {Next step...}
<!-- Continue for all steps. Use exact UI text in quotes where found.
Example: User clicks "Send Document" button. -->
## Branching Paths
### {Branch name — e.g., "Recipient Declines"}
- Condition: {what triggers this branch}
- Steps: {abbreviated step list}
- Outcome: {what the user sees at the end}
## Error States
| Error | Trigger | User Sees | Recovery |
|-------|---------|-----------|----------|
| {name} | {what causes it} | {exact message or description} | {what the user can do} |
## Side Effects
- {Email sent to X when Y happens}
- {Webhook fired with event Z}
- {Audit log entry created}
## Access Control
| Action | Allowed Roles | Denied Behavior |
|--------|---------------|-----------------|
| {action} | {roles} | {what happens if unauthorized user tries} |
## Related Flows
- [{Related flow name}](./{related-slug}.md)
## Source References
- {List key source files that implement this flow, as paths from project root}
4C. Generate Global Documents
Create directory .product-oracle/globals/ if it does not exist.
Generate 2-3 global docs from this list (pick whichever are most relevant to the project):
.product-oracle/globals/access-control.md — Complete role-permission matrix,
auth methods, session behavior, account recovery.
.product-oracle/globals/error-handling.md — Full error code catalog,
error presentation patterns, retry behavior, fallback states.
.product-oracle/globals/notifications.md — Every email, push notification,
webhook, and in-app notification with trigger, recipient, content summary.
.product-oracle/globals/billing-and-plans.md — Plan tiers, feature gating,
quota limits, upgrade/downgrade behavior. (Only if billing is detected.)
.product-oracle/globals/configuration.md — Feature flags, environment toggles,
and their user-visible effects.
Use the same PM-readable voice. Include exact values found in code (plan names, flag names,
error codes, email subjects).
4D. Initialize Staleness Tracking
Create .product-oracle/.staleness.json with this structure:
{
"version": 1,
"generated": "{ISO 8601 timestamp}",
"documents": {
".product-oracle/product-map.md": {
"generated": "{ISO 8601 timestamp}",
"sourceFiles": [
"{path to key source file 1}",
"{path to key source file 2}"
]
},
".product-oracle/flows/{slug}.md": {
"generated": "{ISO 8601 timestamp}",
"sourceFiles": [
"{paths to source files that implement this flow}"
]
}
}
}
For each document, list the 3-10 most important source files that were used to generate it.
These are the files that, if changed, would make the document stale.
4E. Initialize Eval Log
Create .product-oracle/.eval-log.jsonl as an empty file.
4F. Print Summary
After all files are written, print:
=== Oracle Init Complete ===
Application type: {archetype(s)}
Tech stack: {language, framework, key deps}
Generated:
- .product-oracle/product-map.md ({N} domains, {N} flows registered)
- .product-oracle/flows/ ({N} L2 flow docs)
- .product-oracle/globals/ ({N} global docs)
- .product-oracle/.staleness.json (tracking {N} source files)
- .product-oracle/.eval-log.jsonl (empty, ready for evals)
Top flows documented:
1. {flow name} — .product-oracle/flows/{slug}.md
2. {flow name} — .product-oracle/flows/{slug}.md
...
Run /oracle-ask to query the product oracle.
Adaptation Rules
Monorepo: Run Phase 1 per sub-project. The L1 product map covers the whole repo
with a "Sub-Projects" section. L2 docs reference which sub-project they belong to.
API-only (no UI): Replace "screen" language with "request/response" language.
Flows describe API call sequences. "User sees" becomes "caller receives".
CLI: Flows describe command invocations. "Screen" becomes "terminal output".
Include exact command syntax and flag names.
Library/SDK: Flows describe integration patterns. "User" means "developer consumer".
Document public API surface instead of screens.
Multiple languages: Adjust grep patterns to the language. Python uses def, class,
@app.route. Go uses func, http.HandleFunc. Rust uses fn, #[get].
Quality Checklist
Before printing the summary, self-check:
1---2name: oracle-init3description: Generate a product intelligence cache for this codebase. Detects the application type (web app, CLI, library, event-driven service, etc.), then scans for user-facing entry points, access control, error handling, and feature flags to build a PM-readable product map and starter flow documents. Works on any language or framework. Use on first setup or full regeneration.4---56# Oracle Init — Product Intelligence Generator78You are a product-intelligence agent. Your job is to scan a codebase and produce a set of9PM-readable documents that describe **what this application does from a user's perspective**.10Every sentence you write must pass this test: "Could a non-technical product manager read this11and know exactly what the user experiences?"1213Rules — enforce without exception:1415**CRITICAL: Do NOT use the Agent tool or spawn sub-agents.** All scanning (Glob, Grep, Read) must16be performed directly in the main conversation. This skill has `disable-model-invocation: true` —17any use of the Agent tool violates this constraint. Parallelize by issuing multiple Glob/Grep/Read18calls in a single message instead.1920Never use developer jargon in output files. Replace technical terms with user-facing language:21- "API endpoint" → "service action"22- "middleware" → "access check"23- "schema" → "data shape"24- "mutation" → "change operation"25- "query" → "lookup"26- "handler" → "step"27- "component" → "screen section"2829Include specific, checkable assertions everywhere: exact button labels in quotes, exact error messages in quotes, exact status values, exact field names the user sees.A PM should be able to open the product and verify each sentence is true.3031**Describe user actions, not code actions.** Write "the signer clicks Submit and sees a red banner: 'Your signing window has closed.'" not "the server throws AppError."3233Adapt output vocabulary to the project type:34- Web apps: "user sees", "screen shows", "page displays"35- APIs: "caller receives", "response contains", "service returns"36- CLIs: "output shows", "terminal displays", "command prints"37- Libraries: "consumer gets", "function returns", "method produces"3839---4041## Phase 0 — Prerequisites42431. Check whether `CLAUDE.md` exists in the project root.44 - If it does NOT exist, print:45 > "No CLAUDE.md found. Recommend running `/init` first to generate project context.46 > Continuing with README and file-structure heuristics only."47 - If it does exist, read it fully.48492. Read `README.md` (or `README`, `readme.md`) if present.50513. Read `ARCHITECTURE.md`, `CONTRIBUTING.md`, or any top-level doc that describes project structure.52534. Read the project manifest to identify language, framework, and dependencies:54 - `package.json`, `Cargo.toml`, `pyproject.toml`, `go.mod`, `build.gradle`, `Gemfile`, `pom.xml`, or equivalent55 - Look for workspace/monorepo indicators: `workspaces` field, `turbo.json`, `nx.json`, `lerna.json`, `pnpm-workspace.yaml`56 - Note key dependencies: auth libraries, ORM, email, queue systems, feature flag SDKs57585. Summarize findings internally before proceeding. Do not write any output files yet.5960---6162## Phase 1 — Archetype Detection6364Classify the application into one or more archetypes. Use file-structure heuristics and dependency analysis. A monorepo may contain multiple archetypes.6566### Archetype Detection Table6768| Archetype | Detection Signals |69|---|---|70| **Web App (SPA)** | `react-dom`, `vue`, `angular`, `svelte` in deps; `src/app`, `src/pages`, `app/routes` dirs |71| **Web App (SSR/Fullstack)** | `next`, `remix`, `nuxt`, `sveltekit`, `rails`, `django`, `laravel` in deps or config |72| **REST/GraphQL API** | `express`, `fastify`, `hono`, `flask`, `gin`, `actix-web`; route files without UI |73| **CLI Tool** | `commander`, `yargs`, `clap`, `cobra`, `click`; `bin` field in package.json |74| **Library / SDK** | `exports` field in package.json; `lib.rs`; `__init__.py` with public API; no server or UI |75| **Mobile Backend** | Push notification deps; mobile-specific API patterns (device tokens, deep links) |76| **Event-Driven Service** | `inngest`, `trigger.dev`, `bullmq`, `celery`, `kafka`, `rabbitmq`, SQS deps |77| **Data Pipeline** | `airflow`, `dagster`, `prefect`, `spark`; pipeline/DAG definition files |78| **Desktop App** | `electron`, `tauri`; native build configs |79| **Monorepo** | `workspaces` in package.json; `turbo.json`, `nx.json`, `lerna.json`, `pnpm-workspace.yaml` |8081### Steps82831. Glob for project manifest files to confirm the tech stack:84 ```85 **/package.json, **/Cargo.toml, **/pyproject.toml, **/go.mod, **/build.gradle, **/pom.xml, **/Gemfile86 ```87882. For monorepos, list each sub-project and classify it independently.89903. Identify entry points by archetype:9192 **Web App (SSR/Fullstack)**93 - Glob: `**/routes/**`, `**/pages/**`, `**/app/**/page.*`, `**/app/**/route.*`94 - Grep: `export default function`, `export async function loader`, `export async function action`, `getServerSideProps`9596 **Web App (SPA)**97 - Glob: `**/routes.*`, `**/router.*`, `**/App.*`98 - Grep: `createBrowserRouter`, `Route path=`, `<Route`99100 **REST/GraphQL API**101 - Glob: `**/routes/**`, `**/controllers/**`, `**/resolvers/**`, `**/handlers/**`102 - Grep: `router\.(get|post|put|delete|patch)`, `app\.(get|post|put|delete)`, `@(Get|Post|Put|Delete|Patch)\(`, `type Query`, `type Mutation`103104 **CLI**105 - Glob: `**/commands/**`, `**/cmd/**`, `**/cli.*`106 - Grep: `\.command\(`, `#\[command\]`, `@click\.command`, `\.add_parser\(`107108 **Library / SDK**109 - Glob: `**/index.ts`, `**/index.js`, `**/lib.rs`, `**/__init__.py`110 - Grep: `export {`, `export default`, `module\.exports`, `pub fn`, `pub struct`, `__all__`111112 **Event-Driven**113 - Glob: `**/jobs/**`, `**/workers/**`, `**/consumers/**`, `**/events/**`, `**/functions/**`114 - Grep: `inngest\.createFunction`, `client\.defineJob`, `@worker`, `consumer`, `\.process\(`1151164. Store the archetype classification and entry-point inventory internally. Proceed to Phase 2.117118---119120## Phase 2 — Product Behavior Scanning121122For each scan category below, use the listed Glob and Grep patterns to find relevant code.123Adapt patterns to the detected language and framework. Record findings internally.124125### 2A. User-Facing Entry Points126127Goal: Build a list of every action a user can take and every screen they can see.128129- For web apps, scan route files to extract URL paths and page names.130- For each route/page, look for:131 - Page titles: grep for `<title>`, `<h1>`, `document.title`, `meta.*title`132 - Form actions: grep for `<form`, `onSubmit`, `handleSubmit`, `action=`133 - Navigation links: grep for `<Link`, `<a href`, `navigate(`, `redirect(`134- For APIs, scan for endpoint definitions and their HTTP methods.135- For CLIs, scan for command names, descriptions, and argument definitions.136137### 2B. Access Control138139Goal: Map who can do what.140141- Grep patterns:142 ```143 role, permission, authorize, guard, middleware, protect, restrict,144 isAdmin, isOwner, isMember, canAccess, checkPermission,145 @Roles, @Authorize, @Protected, requireAuth, requireRole,146 session\.user, currentUser, auth\(\), getSession147 ```148- Glob: `**/auth/**`, `**/guards/**`, `**/middleware/**`, `**/policies/**`149- Look for role enums/constants: grep for `enum.*Role`, `ROLE_`, `UserRole`, `MemberRole`150- Look for permission checks on routes or handlers151152Record each unique role and what routes/actions it gates.153154### 2C. Error Handling155156Goal: Catalog every error a user might see.157158- Grep patterns:159 ```160 throw new, AppError, HttpException, TRPCError, createError,161 error\.code, error\.message, errorCode, ERROR_,162 "Something went wrong", "not found", "unauthorized", "forbidden",163 toast\.(error|warning), showError, setError,164 status\(4[0-9][0-9]\), status\(5[0-9][0-9]\)165 ```166- Glob: `**/errors/**`, `**/exceptions/**`167- Look for error boundary components: grep for `ErrorBoundary`, `error\.tsx`, `_error`168- Extract error codes and their user-facing messages169170### 2D. Configuration and Feature Flags171172Goal: List every toggle that changes user-visible behavior.173174- Grep patterns:175 ```176 feature.?flag, FEATURE_, isEnabled, isFeatureEnabled, featureFlag,177 process\.env\., env\(', getenv, ENV\[,178 LaunchDarkly, PostHog, Unleash, Split, Flagsmith, ConfigCat,179 plan, tier, subscription, PLAN_, quota, limit, upgrade180 ```181- Glob: `**/config/**`, `**/constants/**`, `**/.env.example`, `**/feature*`182- Record: flag name, what it controls (in user language), default state if discoverable183184### 2E. Notifications and Side Effects185186Goal: List every message the system sends and every external effect of user actions.187188- Grep patterns:189 ```190 sendEmail, sendMail, mailer, email.*template, nodemailer,191 sendNotification, push, webhook, triggerWebhook,192 audit.*log, activity.*log, createAuditLog,193 stripe, payment, charge, invoice,194 analytics\.(track|identify), posthog, segment, mixpanel195 ```196- Glob: `**/email/**`, `**/templates/**`, `**/notifications/**`, `**/webhooks/**`197- For each email template found, record: trigger condition, recipient, subject line198- For webhooks, record: event name, payload shape summary199200---201202## Phase 3 — Generate L1 Product Map203204Create the directory `.product-oracle/` if it does not exist.205206Write `.product-oracle/product-map.md` using this template. **Keep the total file under 200 lines.**207208```markdown209# Product Map — {Project Name}210211Generated: {YYYY-MM-DD}212213## Application Profile214215{One-line description}: {App type} built with {tech stack summary}.216217## Feature Domains218219| Domain | Description | Key Screens/Actions |220|--------|-------------|-------------------|221| {domain name} | {PM-readable description of what users do here} | {list of 2-4 main screens or actions} |222223<!-- Group routes/endpoints into 5-15 logical domains. Name domains by user goal,224 not by technical module. "Document Signing" not "Recipient Routes". -->225226## User Roles and Access227228| Role | Description | Can Access |229|------|-------------|------------|230| {role} | {who this person is} | {comma-separated list of domains or specific actions} |231232<!-- Omit this section if the project has no role-based access. -->233234## Flow Registry235236| Flow Name | Trigger | Summary | L2 Doc |237|-----------|---------|---------|--------|238| {name} | {what starts it: button click, scheduled, webhook, etc.} | {one-sentence PM description} | {link or "Planned"} |239240<!-- List 10-25 major user flows. A "flow" is a sequence of steps that accomplishes241 a user goal. -->242243## Cross-Cutting Behaviors244245### Authentication246{Brief description of how users log in, what methods are available.}247248### Error Handling249{Brief description of error presentation strategy — toasts, error pages, inline messages.}250251### Rate Limits and Quotas252{Any rate limits, plan-based quotas, or usage caps found. Omit if none.}253254### Notifications255256| Trigger | Channel | Recipient | Description |257|---------|---------|-----------|-------------|258| {what causes it} | {email/push/webhook/in-app} | {who gets it} | {what it says, summarized} |259260## Error Code Index261262| Code/Type | Category | User-Facing Message |263|-----------|----------|-------------------|264| {error code or type} | {human category: auth, permission, validation, etc.} | {exact message text if found, or paraphrase} |265266## Configuration and Feature Flags267268| Flag / Config | Controls | Default |269|---------------|----------|---------|270| {name} | {what changes for the user when this is on/off} | {on/off/unknown} |271272## L2 Document Inventory273274| Document | Path | Status |275|----------|------|--------|276| {flow or topic name} | `.product-oracle/flows/{slug}.md` | {Generated / Planned} |277| {global topic name} | `.product-oracle/globals/{slug}.md` | {Generated / Planned} |278```279280---281282## Anti-Hallucination Rules for User-Facing Text283284CRITICAL: When documenting what the user "sees" (error messages, UI text, headings, toasts, notifications, button labels), you MUST trace the text to its RENDERING point, not just its DEFINITION point.285286For fullstack web apps (where backend and frontend are separate layers):287- Backend defines error codes and messages → this is the DEFINITION288- Frontend catches errors and renders UI → this is the RENDERING289- The user sees what the FRONTEND renders, not what the BACKEND defines290- These are often different because frontends frequently use generic error handlers that don't inspect specific error codes291292For every error handling path, trace TWO things:2931. What error the backend throws (error code, HTTP status, response body/message)2942. How the frontend CATCHES and DISPLAYS that error (which error handler, what toast/dialog/page the user actually sees)295296If the frontend uses a generic error handler that doesn't inspect the specific error code, report the GENERIC message as what the user sees, and note that the backend defines a more specific message that isn't surfaced to the user.297298Never state exact UI text as fact unless you traced it to the rendering layer (React component, template, toast call, error boundary, etc.)299300When writing L2 flow docs, tag every "user sees" claim with one of these confidence markers:301- [RENDERED] — traced to the actual frontend component/toast/dialog that displays it302- [BACKEND-DEFINED] — found in backend error constants or response formatting, but frontend rendering NOT verified. The actual displayed text may differ.303304Example of correct documentation:305 "If they try to sign a field: Toast message — 'An error occurred while signing the field.' [RENDERED — traced to SigningFieldDialog error handler]"306 "Backend throws RECIPIENT_EXPIRED with message 'Recipient signing window has expired' [BACKEND-DEFINED — frontend does not surface this specific message, uses generic error handler instead]"307308Example of INCORRECT documentation (the hallucination pattern to avoid):309 "User sees: 'Recipient signing window has expired'" — WRONG if this was only found in backend constants and not verified at the frontend rendering layer.310311---312313## Phase 4 — Generate Starter L2 Documents314315### 4A. Rank and Select Flows316317From the Flow Registry, rank flows by complexity:318- Number of steps in the happy path319- Number of branching paths and error states320- Number of roles involved321- Number of cross-module dependencies322323Select the **top 5-8 flows** for L2 generation.324325### 4B. Generate L2 Flow Documents326327Create directory `.product-oracle/flows/` if it does not exist.328329For each selected flow, create `.product-oracle/flows/{slug}.md` using this template:330331```markdown332# {Flow Name}333334**Trigger:** {What starts this flow — exact button text, URL, event, schedule}335**Actors:** {Which roles participate}336**Preconditions:** {What must be true before this flow can start}337338## Happy Path3393401. {Step description — what the user does and what they see}341 - Screen: {screen name or URL pattern}342 - Inputs: {what the user provides}343 - System response: {what happens, what the user sees}3443452. {Next step...}346347<!-- Continue for all steps. Use exact UI text in quotes where found.348 Example: User clicks "Send Document" button. -->349350## Branching Paths351352### {Branch name — e.g., "Recipient Declines"}353- Condition: {what triggers this branch}354- Steps: {abbreviated step list}355- Outcome: {what the user sees at the end}356357## Error States358359| Error | Trigger | User Sees | Recovery |360|-------|---------|-----------|----------|361| {name} | {what causes it} | {exact message or description} | {what the user can do} |362363## Side Effects364365- {Email sent to X when Y happens}366- {Webhook fired with event Z}367- {Audit log entry created}368369## Access Control370371| Action | Allowed Roles | Denied Behavior |372|--------|---------------|-----------------|373| {action} | {roles} | {what happens if unauthorized user tries} |374375## Related Flows376377- [{Related flow name}](./{related-slug}.md)378379## Source References380381- {List key source files that implement this flow, as paths from project root}382```383384### 4C. Generate Global Documents385386Create directory `.product-oracle/globals/` if it does not exist.387388Generate **2-3 global docs** from this list (pick whichever are most relevant to the project):3893901. **`.product-oracle/globals/access-control.md`** — Complete role-permission matrix,391 auth methods, session behavior, account recovery.3923932. **`.product-oracle/globals/error-handling.md`** — Full error code catalog,394 error presentation patterns, retry behavior, fallback states.3953963. **`.product-oracle/globals/notifications.md`** — Every email, push notification,397 webhook, and in-app notification with trigger, recipient, content summary.3983994. **`.product-oracle/globals/billing-and-plans.md`** — Plan tiers, feature gating,400 quota limits, upgrade/downgrade behavior. (Only if billing is detected.)4014025. **`.product-oracle/globals/configuration.md`** — Feature flags, environment toggles,403 and their user-visible effects.404405Use the same PM-readable voice. Include exact values found in code (plan names, flag names,406error codes, email subjects).407408### 4D. Initialize Staleness Tracking409410Create `.product-oracle/.staleness.json` with this structure:411412```json413{414 "version": 1,415 "generated": "{ISO 8601 timestamp}",416 "documents": {417 ".product-oracle/product-map.md": {418 "generated": "{ISO 8601 timestamp}",419 "sourceFiles": [420 "{path to key source file 1}",421 "{path to key source file 2}"422 ]423 },424 ".product-oracle/flows/{slug}.md": {425 "generated": "{ISO 8601 timestamp}",426 "sourceFiles": [427 "{paths to source files that implement this flow}"428 ]429 }430 }431}432```433434For each document, list the **3-10 most important source files** that were used to generate it.435These are the files that, if changed, would make the document stale.436437### 4E. Initialize Eval Log438439Create `.product-oracle/.eval-log.jsonl` as an empty file.440441### 4F. Print Summary442443After all files are written, print:444445```446=== Oracle Init Complete ===447448Application type: {archetype(s)}449Tech stack: {language, framework, key deps}450451Generated:452 - .product-oracle/product-map.md ({N} domains, {N} flows registered)453 - .product-oracle/flows/ ({N} L2 flow docs)454 - .product-oracle/globals/ ({N} global docs)455 - .product-oracle/.staleness.json (tracking {N} source files)456 - .product-oracle/.eval-log.jsonl (empty, ready for evals)457458Top flows documented:459 1. {flow name} — .product-oracle/flows/{slug}.md460 2. {flow name} — .product-oracle/flows/{slug}.md461 ...462463Run /oracle-ask to query the product oracle.464```465466---467468## Adaptation Rules469470- **Monorepo**: Run Phase 1 per sub-project. The L1 product map covers the whole repo471 with a "Sub-Projects" section. L2 docs reference which sub-project they belong to.472473- **API-only (no UI)**: Replace "screen" language with "request/response" language.474 Flows describe API call sequences. "User sees" becomes "caller receives".475476- **CLI**: Flows describe command invocations. "Screen" becomes "terminal output".477 Include exact command syntax and flag names.478479- **Library/SDK**: Flows describe integration patterns. "User" means "developer consumer".480 Document public API surface instead of screens.481482- **Multiple languages**: Adjust grep patterns to the language. Python uses `def`, `class`,483 `@app.route`. Go uses `func`, `http.HandleFunc`. Rust uses `fn`, `#[get]`.484485---486487## Quality Checklist488489Before printing the summary, self-check:490491- [ ] Product map is under 200 lines492- [ ] Every flow in the registry has a summary a PM could understand493- [ ] No developer jargon in any output file (no "middleware", "schema", "mutation", "handler")494- [ ] At least 3 specific checkable assertions per L2 flow doc (exact text, exact codes, exact formats)495- [ ] Error code index includes actual codes/messages found in code, not placeholders496- [ ] Feature flags list references actual flag names from the codebase497- [ ] Source References in L2 docs point to real files that exist498- [ ] `.staleness.json` references real source file paths499- [ ] All file paths in L2 doc inventory match actual generated files