@pdlc-os/pdlc 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,254 @@
1
+ # Constitution
2
+ <!-- This file is the single source of truth for how this project is built.
3
+ PDLC reads it before every phase. Strong defaults are already set.
4
+ Override only what your team explicitly agrees to change.
5
+ Changing this file is a Tier 2 safety event — PDLC will pause and confirm. -->
6
+
7
+ **Version:** 1.0.0
8
+ **Last updated:** <!-- YYYY-MM-DD — update whenever this file changes -->
9
+ **Project:** <!-- Your project name -->
10
+
11
+ ---
12
+
13
+ ## 1. Tech Stack Decisions
14
+
15
+ <!-- Lock in your chosen technologies here. Once set, PDLC treats these as constraints
16
+ and will flag any agent output that deviates from them.
17
+ Format: Technology — chosen option — brief rationale.
18
+ Example:
19
+ - Language: TypeScript (strict mode) — team familiarity, type safety
20
+ - Runtime: Node.js 22 LTS — long-term support, performance
21
+ - Frontend framework: Next.js 14 App Router — SSR, file-based routing
22
+ - Database: PostgreSQL 16 — relational, battle-tested
23
+ - ORM: Drizzle — lightweight, type-safe
24
+ - Styling: Tailwind CSS v4 — utility-first, no runtime overhead
25
+ - Auth: Supabase Auth — managed, supports OAuth flows
26
+ - Hosting: Fly.io — simple deploy, affordable egress
27
+ -->
28
+
29
+ | Layer | Technology | Rationale |
30
+ |-------|-----------|-----------|
31
+ | Language | <!-- e.g. TypeScript 5, strict mode --> | <!-- why --> |
32
+ | Runtime / Framework | <!-- e.g. Node.js 22 LTS, Next.js 14 --> | <!-- why --> |
33
+ | Database | <!-- e.g. PostgreSQL 16 --> | <!-- why --> |
34
+ | ORM / Query layer | <!-- e.g. Drizzle ORM --> | <!-- why --> |
35
+ | Styling | <!-- e.g. Tailwind CSS v4 --> | <!-- why --> |
36
+ | Auth | <!-- e.g. Supabase Auth --> | <!-- why --> |
37
+ | Testing | <!-- e.g. Vitest + Playwright --> | <!-- why --> |
38
+ | Hosting / Deploy | <!-- e.g. Fly.io, Vercel, AWS --> | <!-- why --> |
39
+ | CI/CD | <!-- e.g. GitHub Actions --> | <!-- why --> |
40
+
41
+ ---
42
+
43
+ ## 2. Coding Standards & Style
44
+
45
+ <!-- Define the rules that all code in this project must follow.
46
+ Claude will apply these during Build and flag violations during Review. -->
47
+
48
+ ### Linting & Formatting
49
+
50
+ <!-- Specify your linter/formatter and the configuration file location.
51
+ Example:
52
+ - Linter: ESLint with config at .eslintrc.json
53
+ - Formatter: Prettier with config at .prettierrc
54
+ - Pre-commit: lint-staged via .lintstagedrc
55
+ -->
56
+
57
+ - Linter: <!-- tool + config file path -->
58
+ - Formatter: <!-- tool + config file path -->
59
+ - Pre-commit hook: <!-- lint-staged / husky / none -->
60
+
61
+ ### Naming Conventions
62
+
63
+ <!-- Fill in your agreed conventions. Examples shown.
64
+ Delete rows that don't apply to your stack. -->
65
+
66
+ | Construct | Convention | Example |
67
+ |-----------|-----------|---------|
68
+ | Files (components) | <!-- e.g. PascalCase --> | <!-- UserCard.tsx --> |
69
+ | Files (utilities) | <!-- e.g. kebab-case --> | <!-- format-date.ts --> |
70
+ | Variables / functions | <!-- e.g. camelCase --> | <!-- getUserById --> |
71
+ | Constants | <!-- e.g. SCREAMING_SNAKE_CASE --> | <!-- MAX_RETRY_COUNT --> |
72
+ | Types / Interfaces | <!-- e.g. PascalCase, no I-prefix --> | <!-- UserProfile --> |
73
+ | Database tables | <!-- e.g. snake_case, plural --> | <!-- user_profiles --> |
74
+ | Database columns | <!-- e.g. snake_case --> | <!-- created_at --> |
75
+ | CSS classes | <!-- e.g. Tailwind utilities only --> | <!-- n/a --> |
76
+ | Environment variables | <!-- e.g. SCREAMING_SNAKE_CASE --> | <!-- DATABASE_URL --> |
77
+ | Branch names | <!-- e.g. feature/[slug] --> | <!-- feature/user-auth --> |
78
+
79
+ ### General Rules
80
+
81
+ <!-- Add any project-wide coding rules here. Examples:
82
+ - No `any` in TypeScript without explicit justification comment
83
+ - All functions must have JSDoc comments
84
+ - Max file length: 300 lines
85
+ - No magic numbers — use named constants
86
+ - No commented-out code in committed files
87
+ - All async operations must have error handling
88
+ -->
89
+
90
+ -
91
+ -
92
+ -
93
+
94
+ ---
95
+
96
+ ## 3. Architectural Constraints
97
+
98
+ <!-- Document design decisions that shape the system structure.
99
+ These are guardrails — not just preferences. Claude will flag deviations.
100
+ Examples:
101
+ - All business logic lives in service layer, never in route handlers or components
102
+ - Database access only through the repository pattern — no raw SQL in services
103
+ - No shared mutable state between modules
104
+ - All external API calls must go through a dedicated adapter/client module
105
+ - Feature flags managed via environment variables only
106
+ - No circular dependencies between modules
107
+ -->
108
+
109
+ -
110
+ -
111
+ -
112
+
113
+ ---
114
+
115
+ ## 4. Security & Compliance Requirements
116
+
117
+ <!-- List security standards and compliance obligations.
118
+ Phantom will verify these during every Review sub-phase.
119
+ Examples:
120
+ - OWASP Top 10 must be checked before any feature ships
121
+ - All user input must be validated and sanitized at the service boundary
122
+ - Secrets must never appear in source code or logs — use environment variables
123
+ - All API endpoints require authentication unless explicitly marked public
124
+ - PII must not be written to application logs
125
+ - HTTPS enforced in all environments
126
+ - Dependencies audited via `npm audit` before each release
127
+ - GDPR: user data deletion must be supported
128
+ -->
129
+
130
+ -
131
+ -
132
+ -
133
+
134
+ ---
135
+
136
+ ## 5. Definition of Done
137
+
138
+ <!-- A task is not complete until ALL of the following are true.
139
+ PDLC checks this list before allowing Construction to transition to Operation.
140
+ Adjust to match your team's standards. -->
141
+
142
+ - [ ] Code is committed on the feature branch with a conventional commit message
143
+ - [ ] All unit tests pass (`npm test` or equivalent)
144
+ - [ ] All integration tests pass
145
+ - [ ] Code has been reviewed by Neo, Echo, Phantom, and Jarvis
146
+ - [ ] Review file (`docs/pdlc/reviews/REVIEW_*.md`) exists and is human-approved
147
+ - [ ] No `console.log` / debug statements left in committed code
148
+ - [ ] All public functions/methods have inline documentation
149
+ - [ ] No TypeScript errors (`tsc --noEmit` passes)
150
+ - [ ] Linter passes with zero errors
151
+ - [ ] PR description is complete and references the Beads task ID
152
+ - [ ] Episode file drafted and human-approved
153
+ <!-- Add project-specific requirements below: -->
154
+ -
155
+ -
156
+
157
+ ---
158
+
159
+ ## 6. Git Workflow Rules
160
+
161
+ <!-- Define your branch strategy and commit message format.
162
+ PDLC enforces these during Build and Ship sub-phases. -->
163
+
164
+ ### Branch Strategy
165
+
166
+ <!-- Choose one and delete the others, or define your own: -->
167
+
168
+ - **Feature branch model (default)**: One branch per feature (`feature/[feature-name]`), single PR to `main` at end of Construction.
169
+ - <!-- Alternative: Gitflow (main + develop + feature branches) -->
170
+ - <!-- Alternative: Trunk-based (short-lived branches, merge to main daily) -->
171
+
172
+ **Default branch:** `main`
173
+ **Feature branch naming:** `feature/[kebab-case-feature-name]`
174
+ **Merge strategy:** Merge commit (preserves full branch history)
175
+
176
+ ### Commit Message Format
177
+
178
+ <!-- PDLC defaults to Conventional Commits. Change only if your team prefers otherwise. -->
179
+
180
+ Format: `<type>(<scope>): <description>`
181
+
182
+ Types: `feat` | `fix` | `chore` | `docs` | `test` | `refactor` | `perf` | `ci`
183
+
184
+ Examples:
185
+ - `feat(auth): add OAuth2 login with GitHub`
186
+ - `fix(api): handle null user ID in profile endpoint`
187
+ - `test(billing): add integration tests for Stripe webhook`
188
+
189
+ **Breaking changes:** append `!` after type, e.g. `feat(api)!: rename /users endpoint to /accounts`
190
+
191
+ ### Protected Branches
192
+
193
+ <!-- List branches that require PR review before merging.
194
+ Force-pushing to these is a Tier 1 hard block. -->
195
+
196
+ - `main` — requires PR + human approval
197
+ <!-- - `develop` — requires PR + human approval -->
198
+
199
+ ---
200
+
201
+ ## 7. Test Gates
202
+
203
+ <!-- Check the boxes for test layers that MUST pass before Operation phase can begin.
204
+ Unchecked layers are still run and reported — they just don't hard-block the ship.
205
+ You can also skip a layer entirely via human instruction during Test sub-phase
206
+ (this is a Tier 3 logged warning). -->
207
+
208
+ - [x] Unit tests
209
+ - [x] Integration tests
210
+ - [ ] E2E tests (real Chromium)
211
+ - [ ] Performance / load tests
212
+ - [ ] Accessibility checks
213
+ - [ ] Visual regression tests
214
+
215
+ <!-- Notes on gates: e.g. "E2E gate required for all features touching auth or checkout" -->
216
+
217
+ ---
218
+
219
+ ## 8. Safety Guardrail Overrides
220
+
221
+ <!-- Tier 2 items that your team has deliberately downgraded to Tier 3 (logged, not blocking).
222
+ For each override: state the item, the reason, and the date agreed.
223
+ LEAVE THIS TABLE EMPTY unless your team has explicitly agreed to downgrade an item.
224
+
225
+ Default Tier 2 items (do NOT move here without team agreement):
226
+ - Any `rm -rf` or bulk delete
227
+ - `git reset --hard`
228
+ - Running DB migrations in production
229
+ - Changing CONSTITUTION.md
230
+ - Closing all open Beads tasks at once
231
+ - Any external API call that writes/posts/sends (Slack, email, webhooks)
232
+ -->
233
+
234
+ | Tier 2 Item | Downgraded Reason | Date Agreed | Agreed By |
235
+ |-------------|-------------------|-------------|-----------|
236
+ | <!-- item --> | <!-- reason --> | <!-- YYYY-MM-DD --> | <!-- initials --> |
237
+
238
+ <!-- If no overrides, leave the table with the placeholder row above or delete the row entirely. -->
239
+
240
+ ---
241
+
242
+ ## 9. Additional Rules
243
+
244
+ <!-- Anything that doesn't fit the sections above. Examples:
245
+ - Feature flags must be cleaned up within 2 sprints of full rollout
246
+ - All database migrations must be reversible (include down migration)
247
+ - Third-party packages require team discussion before adding
248
+ - Max bundle size: 200kb gzipped for initial page load
249
+ - All API responses follow the { data, error, meta } envelope format
250
+ -->
251
+
252
+ -
253
+ -
254
+ -
@@ -0,0 +1,120 @@
1
+ # Intent
2
+ <!-- This file defines the core purpose of the product.
3
+ It is set during /pdlc init and should rarely change.
4
+ If the fundamental problem or user changes, update this file and record why in docs/pdlc/memory/DECISIONS.md.
5
+ Claude reads this at the start of every Inception phase to anchor the Discover conversation. -->
6
+
7
+ **Project:** <!-- Your project name -->
8
+ **Created:** <!-- YYYY-MM-DD -->
9
+ **Last updated:** <!-- YYYY-MM-DD -->
10
+
11
+ ---
12
+
13
+ ## Project Name
14
+
15
+ <!-- Full name of the product or service. Include tagline if you have one.
16
+ Example: "Folia — the personal finance tracker that doesn't judge you" -->
17
+
18
+ <!-- Your project name and tagline here -->
19
+
20
+ ---
21
+
22
+ ## Problem Statement
23
+
24
+ <!-- Describe the core problem this product solves. Be concrete — who is suffering, what is the pain,
25
+ and why existing solutions fall short.
26
+ Keep this to 3–5 sentences. Avoid solution language.
27
+ Example:
28
+ Small business owners spend 4–6 hours per week manually reconciling expenses
29
+ in spreadsheets. Existing tools like QuickBooks are powerful but intimidating —
30
+ they require accounting knowledge most owners don't have. The gap between
31
+ "too simple" (a spreadsheet) and "too complex" (full accounting software) is
32
+ where most small businesses live and struggle. -->
33
+
34
+ <!-- Your problem statement here -->
35
+
36
+ ---
37
+
38
+ ## Target User (Persona)
39
+
40
+ <!-- Describe your primary user in enough detail that Claude can make product decisions on their behalf.
41
+ Include: who they are, what they know, what they want, and what frustrates them.
42
+ Example:
43
+ **Primary: The Bootstrapped Founder**
44
+ - Solo founder or 2-person team at an early-stage B2B SaaS startup
45
+ - Technical enough to read code but not their day job
46
+ - Using multiple tools (Stripe, Linear, Notion) with no unified view
47
+ - Frustrated by context-switching; wants answers fast, not dashboards
48
+ - Will pay for something that saves 30 min/day; will churn if onboarding is > 5 min -->
49
+
50
+ <!-- Your target user persona here -->
51
+
52
+ **Secondary users (if any):**
53
+ <!-- Describe secondary users or leave this section blank -->
54
+
55
+ ---
56
+
57
+ ## Core Value Proposition
58
+
59
+ <!-- One or two sentences that capture why your target user would choose this over alternatives.
60
+ Should complete the sentence: "Only [product] lets [target user] [achieve outcome] by [unique mechanism]."
61
+ Example:
62
+ "Only Folia lets bootstrapped founders see their true runway in under 30 seconds,
63
+ by connecting directly to their bank and Stripe — with zero manual entry." -->
64
+
65
+ <!-- Your value proposition here -->
66
+
67
+ ---
68
+
69
+ ## What Success Looks Like
70
+
71
+ <!-- Define concrete, measurable outcomes for the first meaningful milestone (e.g. private beta, v1.0).
72
+ Use specific metrics where possible.
73
+ Example:
74
+ - 50 active users in the first 30 days after launch
75
+ - Average session time > 8 minutes (users are exploring, not bouncing)
76
+ - 70% of users return within 7 days (sticky core loop working)
77
+ - Time-to-value < 5 minutes (user sees their data on first visit)
78
+ - NPS ≥ 40 from first 20 respondents
79
+ - Zero Sev-1 bugs in the first 14 days post-launch -->
80
+
81
+ | Metric | Target | Timeframe |
82
+ |--------|--------|-----------|
83
+ | <!-- metric --> | <!-- target --> | <!-- e.g. 30 days post-launch --> |
84
+ | <!-- metric --> | <!-- target --> | <!-- timeframe --> |
85
+ | <!-- metric --> | <!-- target --> | <!-- timeframe --> |
86
+
87
+ ---
88
+
89
+ ## Out of Scope
90
+
91
+ <!-- List things this product explicitly will NOT do — at least for v1.
92
+ This is as important as what it does. Being clear here prevents scope creep and
93
+ helps Claude make tighter decisions during Discover.
94
+ Example:
95
+ - No mobile app in v1 (web only, mobile-responsive)
96
+ - No multi-user/team support until v2
97
+ - No custom reporting or data exports in v1
98
+ - No integrations with accounting software (QuickBooks, Xero) in v1
99
+ - No white-labelling -->
100
+
101
+ -
102
+ -
103
+ -
104
+
105
+ ---
106
+
107
+ ## Key Constraints
108
+
109
+ <!-- Real-world constraints that Claude must respect.
110
+ Examples: budget, timeline, regulatory, technical, team size.
111
+ Example:
112
+ - Timeline: MVP must be shippable in 8 weeks with a 2-person team
113
+ - Budget: No paid infrastructure over $200/month until first revenue
114
+ - Regulatory: Cannot store raw bank credentials (must use OAuth / Plaid)
115
+ - Team: Two engineers, no dedicated designer — UI must use a component library
116
+ - Existing codebase: Must integrate with existing Rails API (not a greenfield) -->
117
+
118
+ -
119
+ -
120
+ -
@@ -0,0 +1,93 @@
1
+ # Overview
2
+ <!-- This file is the living, aggregated record of everything this product does and has shipped.
3
+ It is updated automatically by PDLC after every successful merge to main (during Reflect sub-phase).
4
+ Use it to orient yourself after time away, onboard a new teammate, or brief Claude in a fresh session.
5
+ Do not edit manually — let PDLC maintain it. If you need to correct something, update and note the reason. -->
6
+
7
+ **Project:** <!-- Project name — set during /pdlc init -->
8
+ **Last updated:** <!-- YYYY-MM-DDTHH:MM:SSZ — set automatically after each merge -->
9
+
10
+ ---
11
+
12
+ ## Project Summary
13
+
14
+ <!-- 1–2 sentences describing what this product is and who it is for.
15
+ Derived from INTENT.md and updated only if the product's core purpose changes.
16
+ Example:
17
+ Folia is a personal finance tracker for bootstrapped founders that connects to Stripe and bank
18
+ accounts to show true runway in under 30 seconds — with zero manual entry. -->
19
+
20
+ <!-- Auto-populated from INTENT.md on first run. Human-editable thereafter. -->
21
+
22
+ ---
23
+
24
+ ## Active Functionality
25
+
26
+ <!-- A plain-language bullet list of everything the product currently does — as of last merge.
27
+ Claude updates this list after every Reflect sub-phase to reflect the current shipped state.
28
+ Think of it as the "what can a user actually do right now?" list.
29
+ Example:
30
+ - Users can sign up and log in via email/password or GitHub OAuth
31
+ - Users can connect a Stripe account and see live MRR and churn
32
+ - Users can set a monthly runway target and see a countdown
33
+ - Admins can view all users and impersonate accounts
34
+ - Automated weekly email digest of key metrics -->
35
+
36
+ <!-- None yet — update after first feature ships. -->
37
+
38
+ ---
39
+
40
+ ## Shipped Features
41
+
42
+ <!-- Auto-populated by PDLC after each successful merge to main.
43
+ Each row added during the Reflect sub-phase.
44
+ Do not delete rows — this is the permanent shipping record. -->
45
+
46
+ | # | Feature | Date Shipped | Episode | PR |
47
+ |---|---------|-------------|---------|-----|
48
+ | <!-- 001 --> | <!-- Feature name --> | <!-- YYYY-MM-DD --> | <!-- [ep-001](../memory/episodes/001_*.md) --> | <!-- [#1](https://github.com/org/repo/pull/1) --> |
49
+
50
+ ---
51
+
52
+ ## Architecture Summary
53
+
54
+ <!-- A concise description of the system architecture.
55
+ Updated when the architecture changes significantly (e.g. new service added, DB migration, infra change).
56
+ Include: tech stack layers, data flow, key integrations, and anything non-obvious.
57
+ Aim for 3–6 bullet points or a short paragraph. Mermaid diagrams welcome.
58
+ Example:
59
+ - Next.js 14 App Router frontend served from Vercel; API routes handle all server-side logic
60
+ - PostgreSQL database on Supabase; accessed via Drizzle ORM
61
+ - Supabase Auth handles all authentication; JWTs passed in Authorization header to API routes
62
+ - Stripe webhooks received at /api/webhooks/stripe, verified and queued for async processing
63
+ - GitHub Actions CI runs lint → test → deploy on every merge to main
64
+ -->
65
+
66
+ <!-- Auto-populated during /pdlc init from CONSTITUTION.md and updated as architecture evolves. -->
67
+
68
+ ---
69
+
70
+ ## Known Tech Debt
71
+
72
+ <!-- A running list of technical debt acknowledged by the team.
73
+ Each item is added during Reflect when a tradeoff was consciously accepted.
74
+ Items are removed when resolved (with a note of when and in which episode).
75
+ Format: - [Added YYYY-MM-DD] [Description] — [why it was accepted] — [episode ref]
76
+ Example:
77
+ - [2026-04-10] Auth tokens stored in localStorage instead of httpOnly cookies —
78
+ accepted to ship faster; should move to cookies before public launch — ep-001
79
+ - [2026-04-17] No pagination on /api/users — table is small now; add before 1k users — ep-002
80
+ -->
81
+
82
+ <!-- None yet. -->
83
+
84
+ ---
85
+
86
+ ## Decision Log Summary
87
+
88
+ <!-- A short summary of the most consequential decisions made across all episodes.
89
+ Full ADR-style decisions live in docs/pdlc/memory/DECISIONS.md.
90
+ This section highlights the 3–5 decisions most likely to affect future work.
91
+ Updated by Claude during Reflect. -->
92
+
93
+ <!-- None yet — see docs/pdlc/memory/DECISIONS.md for the full log. -->
@@ -0,0 +1,212 @@
1
+ # PRD: [Feature Name]
2
+ <!-- Replace [Feature Name] with the full name of the feature.
3
+ File naming convention: PRD_[feature-name]_[YYYY-MM-DD].md
4
+ This file lives at: docs/pdlc/prds/PRD_[feature-name]_[YYYY-MM-DD].md
5
+ Claude auto-generates a draft of this file at the end of the Discover sub-phase.
6
+ Human reviews and approves the draft before Design begins. -->
7
+
8
+ **Date:** <!-- YYYY-MM-DD -->
9
+ **Status:** Draft <!-- Change to "Approved" after human sign-off; do not proceed to Design until Approved -->
10
+ **Feature slug:** <!-- kebab-case-feature-name — used in file paths and branch names -->
11
+ **Episode:** <!-- Will be assigned after delivery, e.g. ep-003 -->
12
+
13
+ ---
14
+
15
+ ## Overview
16
+
17
+ <!-- 2–4 sentences summarising what this feature is and why it is being built now.
18
+ Should connect directly to a goal in INTENT.md.
19
+ Example:
20
+ This feature adds GitHub OAuth login as an alternative to email/password sign-up.
21
+ It reduces friction for technical users who already have a GitHub account and
22
+ eliminates the need to remember yet another password. Shipped before the public launch
23
+ to ensure the primary target audience (developers) can onboard in under 60 seconds. -->
24
+
25
+ <!-- Auto-generated by Claude from Discover conversation. Review and edit as needed. -->
26
+
27
+ ---
28
+
29
+ ## Problem Statement
30
+
31
+ <!-- The specific problem this feature solves. More granular than the product-level problem in INTENT.md.
32
+ Be concrete: what is the user unable to do today, and what is the cost of that gap?
33
+ Example:
34
+ Currently users must create a new email/password account to use the product.
35
+ 40% of our target users (developers) use "Sign in with GitHub" as their preferred
36
+ auth method. Forcing a password creates friction, increases drop-off, and introduces
37
+ a support burden (password resets). -->
38
+
39
+ <!-- Auto-generated by Claude from Discover conversation. Review and edit as needed. -->
40
+
41
+ ---
42
+
43
+ ## Target User
44
+
45
+ <!-- Who specifically benefits from this feature? Reference the persona(s) from INTENT.md.
46
+ If this feature is for a subset of users (e.g. admins only), say so explicitly. -->
47
+
48
+ <!-- Auto-generated by Claude from Discover conversation. Review and edit as needed. -->
49
+
50
+ ---
51
+
52
+ ## Requirements
53
+
54
+ <!-- Numbered list of functional requirements.
55
+ Each requirement should be specific and testable — it will become acceptance criteria and BDD stories.
56
+ Use "must", "should", "may" for priority signalling (RFC 2119 style).
57
+ Example:
58
+ 1. The system MUST provide a "Sign in with GitHub" button on the login page.
59
+ 2. The system MUST redirect users to GitHub's OAuth authorization page when the button is clicked.
60
+ 3. The system MUST create a new user account if the GitHub email is not already registered.
61
+ 4. The system MUST link the GitHub identity to an existing account if the email matches.
62
+ 5. The system SHOULD display the user's GitHub avatar as their profile photo after login.
63
+ 6. The system MAY allow users to unlink their GitHub account from settings. -->
64
+
65
+ 1.
66
+ 2.
67
+ 3.
68
+
69
+ ---
70
+
71
+ ## Assumptions
72
+
73
+ <!-- Things believed to be true that, if wrong, would change the requirements.
74
+ Surfaced during the Discover Socratic session.
75
+ Example:
76
+ - GitHub OAuth app credentials (client ID + secret) will be provisioned before Build begins
77
+ - Users who sign up via GitHub implicitly accept the terms of service (no separate checkbox needed)
78
+ - Email is always available from the GitHub OAuth response (some GitHub accounts hide it — needs handling)
79
+ - This feature does not need to support GitHub Enterprise -->
80
+
81
+ -
82
+ -
83
+ -
84
+
85
+ ---
86
+
87
+ ## Acceptance Criteria
88
+
89
+ <!-- Numbered list of conditions that must be true for this feature to be considered done.
90
+ These are binary — pass or fail. Echo uses these to verify test coverage during Review.
91
+ Example:
92
+ 1. A user with a valid GitHub account can log in and land on their dashboard in under 5 seconds.
93
+ 2. A new account is created on first login with the correct email, name, and avatar pulled from GitHub.
94
+ 3. Logging in with GitHub on an email that already has a local account links the accounts without
95
+ creating a duplicate.
96
+ 4. If GitHub OAuth fails or is denied, the user sees a human-readable error and is not logged in.
97
+ 5. The "Sign in with GitHub" button is visible and accessible (keyboard-navigable, ARIA-labelled). -->
98
+
99
+ 1.
100
+ 2.
101
+ 3.
102
+
103
+ ---
104
+
105
+ ## User Stories
106
+
107
+ <!-- BDD-format stories using Given / When / Then.
108
+ Each story maps to one or more acceptance criteria above (cross-reference by number).
109
+ Label each story with an ID for reference in Beads tasks.
110
+ Example:
111
+ **US-001: Happy path GitHub login**
112
+ *Acceptance criteria: 1, 2*
113
+ Given a user is on the login page
114
+ When they click "Sign in with GitHub" and authorize the app on GitHub
115
+ Then they are redirected back to the dashboard, logged in as themselves
116
+
117
+ **US-002: Duplicate email — account linking**
118
+ *Acceptance criteria: 3*
119
+ Given a user already has an account with email alice@example.com
120
+ When they click "Sign in with GitHub" using an account with the same email
121
+ Then their GitHub identity is linked to the existing account and they are logged in
122
+ And no duplicate account is created
123
+
124
+ **US-003: OAuth failure**
125
+ *Acceptance criteria: 4*
126
+ Given a user is on the login page
127
+ When they click "Sign in with GitHub" but deny authorization on the GitHub page
128
+ Then they are returned to the login page
129
+ And they see the message "GitHub login was cancelled. Please try again or use email."
130
+ And they remain logged out -->
131
+
132
+ **US-001: [Story title]**
133
+ *Acceptance criteria: <!-- reference AC numbers -->*
134
+ Given <!-- starting context -->
135
+ When <!-- action taken -->
136
+ Then <!-- expected outcome -->
137
+
138
+ **US-002: [Story title]**
139
+ *Acceptance criteria: <!-- reference AC numbers -->*
140
+ Given <!-- starting context -->
141
+ When <!-- action taken -->
142
+ Then <!-- expected outcome -->
143
+
144
+ ---
145
+
146
+ ## Non-Functional Requirements
147
+
148
+ <!-- Performance, security, accessibility, and operational requirements.
149
+ These become test criteria for Echo (tests), Phantom (security), and the Test sub-phase.
150
+ Example:
151
+ - OAuth redirect round-trip MUST complete in under 3 seconds on a standard broadband connection
152
+ - No GitHub access tokens may be stored in the database or logged
153
+ - The login flow MUST be keyboard-accessible and meet WCAG 2.1 AA
154
+ - The feature MUST degrade gracefully if the GitHub OAuth service is unavailable
155
+ (fallback to email/password, not a blank screen)
156
+ - Rate limiting: no more than 10 OAuth attempts per IP per minute -->
157
+
158
+ -
159
+ -
160
+ -
161
+
162
+ ---
163
+
164
+ ## Out of Scope
165
+
166
+ <!-- Explicitly list what this PRD does NOT cover.
167
+ Prevents scope creep and sets clear expectations for what comes later.
168
+ Example:
169
+ - Google / Apple / other OAuth providers (separate feature)
170
+ - GitHub Enterprise support
171
+ - Two-factor authentication (2FA) via GitHub
172
+ - Unlinking GitHub from an existing account (follow-up feature)
173
+ - Account merging when two separate accounts have the same email via different providers -->
174
+
175
+ -
176
+ -
177
+ -
178
+
179
+ ---
180
+
181
+ ## Design Docs
182
+
183
+ <!-- Links to design documents produced during the Design sub-phase.
184
+ These are auto-populated by PDLC after Design is complete. Do not fill in during Define. -->
185
+
186
+ - Architecture: <!-- [ARCHITECTURE.md](../../design/[feature-name]/ARCHITECTURE.md) -->
187
+ - Data model: <!-- [data-model.md](../../design/[feature-name]/data-model.md) -->
188
+ - API contracts: <!-- [api-contracts.md](../../design/[feature-name]/api-contracts.md) -->
189
+ - Additional: <!-- links to any other design files, UI direction, sequence diagrams, etc. -->
190
+
191
+ ---
192
+
193
+ ## Related Episodes
194
+
195
+ <!-- Links to episodic memory files for prior features that this feature builds on or is affected by.
196
+ Auto-populated by PDLC when relevant episodes are detected. Review and supplement as needed.
197
+ Example:
198
+ - [ep-001: User Auth foundation](../memory/episodes/001_user_auth_2026-04-03.md)
199
+ — GitHub OAuth builds on the auth session infrastructure introduced here -->
200
+
201
+ <!-- None yet. -->
202
+
203
+ ---
204
+
205
+ ## Approval
206
+
207
+ <!-- Do not proceed to Design until a human has approved this PRD.
208
+ Record the approver's name/initials and date. -->
209
+
210
+ **Approved by:** <!-- Name / initials -->
211
+ **Date approved:** <!-- YYYY-MM-DD -->
212
+ **Notes:** <!-- Any conditions or caveats attached to approval -->