feat: Task decomposition for Tailwind/Radix/shadcn foundation setup
Decomposed "Foundation Setup - Install Dependencies & Configure Tailwind" phase into 6 executable tasks: 1. Install Tailwind CSS, PostCSS & Autoprefixer 2. Map MUI theme to Tailwind design tokens 3. Setup CSS variables for dynamic theming 4. Install Radix UI primitives 5. Initialize shadcn/ui and setup component directory 6. Move MUI to devDependencies and verify setup Tasks follow logical dependency chain with final human verification checkpoint before proceeding with component migration. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
434
docs/archive/execution-artifacts.md
Normal file
434
docs/archive/execution-artifacts.md
Normal file
@@ -0,0 +1,434 @@
|
||||
# Execution Artifacts
|
||||
|
||||
Execution produces artifacts that document what happened, enable debugging, and provide context for future work.
|
||||
|
||||
## Artifact Types
|
||||
|
||||
| Artifact | Created By | Purpose |
|
||||
|----------|------------|---------|
|
||||
| PLAN.md | Architect | Executable instructions for a plan |
|
||||
| SUMMARY.md | Worker | Record of what actually happened |
|
||||
| VERIFICATION.md | Verifier | Goal-backward verification results |
|
||||
| UAT.md | Verifier + User | User acceptance testing results |
|
||||
| STATE.md | All agents | Session state (see [session-state.md](session-state.md)) |
|
||||
|
||||
---
|
||||
|
||||
## PLAN.md
|
||||
|
||||
Plans are **executable prompts**, not documents that transform into prompts.
|
||||
|
||||
### Structure
|
||||
|
||||
```yaml
|
||||
---
|
||||
# Frontmatter
|
||||
phase: 2
|
||||
plan: 3
|
||||
type: execute # execute | tdd
|
||||
wave: 1
|
||||
depends_on: [2-2-PLAN]
|
||||
files_modified:
|
||||
- src/api/auth/refresh.ts
|
||||
- src/middleware/auth.ts
|
||||
- db/migrations/002_refresh_tokens.sql
|
||||
autonomous: true # false if checkpoints required
|
||||
must_haves:
|
||||
observable_truths:
|
||||
- "Refresh token extends session"
|
||||
- "Old token invalidated after rotation"
|
||||
required_artifacts:
|
||||
- src/api/auth/refresh.ts
|
||||
required_wiring:
|
||||
- "refresh endpoint -> token storage"
|
||||
user_setup: [] # Human prereqs if any
|
||||
---
|
||||
|
||||
# Phase 2, Plan 3: Refresh Token Rotation
|
||||
|
||||
## Objective
|
||||
Implement refresh token rotation to extend user sessions securely while preventing token reuse attacks.
|
||||
|
||||
## Context
|
||||
@file: PROJECT.md (project overview)
|
||||
@file: 2-CONTEXT.md (phase decisions)
|
||||
@file: 2-1-SUMMARY.md (prior work)
|
||||
@file: 2-2-SUMMARY.md (prior work)
|
||||
|
||||
## Tasks
|
||||
|
||||
### Task 1: Create refresh_tokens table
|
||||
- **type:** auto
|
||||
- **files:** db/migrations/002_refresh_tokens.sql, src/db/schema/refreshTokens.ts
|
||||
- **action:** Create table with: id (uuid), user_id (fk), token_hash (sha256), family (uuid for rotation tracking), expires_at, created_at, revoked_at. Index on token_hash and user_id.
|
||||
- **verify:** `cw db migrate` succeeds, schema matches
|
||||
- **done:** Migration applies, drizzle schema matches SQL
|
||||
|
||||
### Task 2: Implement rotation endpoint
|
||||
- **type:** auto
|
||||
- **files:** src/api/auth/refresh.ts
|
||||
- **action:** POST /api/auth/refresh accepts refresh token in httpOnly cookie. Validate token exists and not expired. Generate new access + refresh tokens. Store new refresh, revoke old. Set cookies. Return 200 with new access token.
|
||||
- **verify:** curl with valid refresh cookie returns new tokens
|
||||
- **done:** Rotation works, old token invalidated
|
||||
|
||||
### Task 3: Add token family validation
|
||||
- **type:** auto
|
||||
- **files:** src/api/auth/refresh.ts
|
||||
- **action:** If revoked token reused, revoke entire family (reuse detection). Log security event.
|
||||
- **verify:** Reusing old token revokes all tokens in family
|
||||
- **done:** Reuse detection active
|
||||
|
||||
## Verification Criteria
|
||||
- [ ] New refresh token issued on rotation
|
||||
- [ ] Old refresh token no longer valid
|
||||
- [ ] Reused token triggers family revocation
|
||||
- [ ] Access token returned in response
|
||||
- [ ] Cookies set with correct flags (httpOnly, secure, sameSite)
|
||||
|
||||
## Success Criteria
|
||||
- All tasks complete with passing verify steps
|
||||
- No TypeScript errors
|
||||
- Tests cover happy path and reuse detection
|
||||
```
|
||||
|
||||
### Key Elements
|
||||
|
||||
| Element | Purpose |
|
||||
|---------|---------|
|
||||
| `type: execute\|tdd` | Execution strategy |
|
||||
| `wave` | Parallelization grouping |
|
||||
| `depends_on` | Must complete first |
|
||||
| `files_modified` | Git tracking, conflict detection |
|
||||
| `autonomous` | Can run without checkpoints |
|
||||
| `must_haves` | Verification criteria |
|
||||
| `@file` references | Context to load |
|
||||
|
||||
---
|
||||
|
||||
## SUMMARY.md
|
||||
|
||||
Created after plan execution. Documents what **actually happened**.
|
||||
|
||||
### Structure
|
||||
|
||||
```yaml
|
||||
---
|
||||
phase: 2
|
||||
plan: 3
|
||||
subsystem: auth
|
||||
tags: [jwt, security, tokens]
|
||||
requires:
|
||||
- users table
|
||||
- jose library
|
||||
provides:
|
||||
- refresh token rotation
|
||||
- reuse detection
|
||||
affects:
|
||||
- auth flow
|
||||
- session management
|
||||
tech_stack:
|
||||
- jose (JWT)
|
||||
- drizzle (ORM)
|
||||
- sqlite
|
||||
key_files:
|
||||
- src/api/auth/refresh.ts: "Rotation endpoint"
|
||||
- src/db/schema/refreshTokens.ts: "Token storage"
|
||||
decisions:
|
||||
- "Token family for reuse detection"
|
||||
- "SHA256 hash for token storage"
|
||||
metrics:
|
||||
tasks_completed: 3
|
||||
tasks_total: 3
|
||||
deviations: 2
|
||||
execution_time: "45 minutes"
|
||||
context_usage: "38%"
|
||||
---
|
||||
|
||||
# Phase 2, Plan 3 Summary: Refresh Token Rotation
|
||||
|
||||
## What Was Built
|
||||
Implemented refresh token rotation with security features:
|
||||
- Rotation endpoint at POST /api/auth/refresh
|
||||
- Token storage with family tracking
|
||||
- Reuse detection that revokes entire token family
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
### Token Storage
|
||||
Tokens stored as SHA256 hashes (never plaintext). Family UUID links related tokens for rotation tracking.
|
||||
|
||||
### Rotation Flow
|
||||
1. Receive refresh token in cookie
|
||||
2. Hash and lookup in database
|
||||
3. Verify not expired, not revoked
|
||||
4. Generate new access + refresh tokens
|
||||
5. Store new refresh with same family
|
||||
6. Revoke old refresh token
|
||||
7. Set new cookies, return access token
|
||||
|
||||
### Reuse Detection
|
||||
If a revoked token is presented, the entire family is revoked. This catches scenarios where an attacker captured an old token.
|
||||
|
||||
## Deviations
|
||||
|
||||
### Rule 2: Added rate limiting
|
||||
```yaml
|
||||
deviation:
|
||||
rule: 2
|
||||
type: missing_critical
|
||||
description: "Added rate limiting to refresh endpoint"
|
||||
location: src/api/auth/refresh.ts:12
|
||||
reason: "Prevent brute force token guessing"
|
||||
```
|
||||
|
||||
### Rule 1: Fixed async handler
|
||||
```yaml
|
||||
deviation:
|
||||
rule: 1
|
||||
type: bug_fix
|
||||
description: "Added await to database query"
|
||||
location: src/api/auth/refresh.ts:34
|
||||
reason: "Query returned promise, not result"
|
||||
```
|
||||
|
||||
## Commits
|
||||
- `feat(2-3): create refresh_tokens table and schema`
|
||||
- `feat(2-3): implement token rotation endpoint`
|
||||
- `feat(2-3): add token family reuse detection`
|
||||
- `fix(2-3): add await to token lookup query`
|
||||
- `feat(2-3): add rate limiting to refresh endpoint`
|
||||
|
||||
## Verification Status
|
||||
- [x] New refresh token issued on rotation
|
||||
- [x] Old refresh token invalidated
|
||||
- [x] Reuse detection works
|
||||
- [x] Cookies set correctly
|
||||
- [ ] **Pending human verification:** Cookie flags in production
|
||||
|
||||
## Notes for Next Plan
|
||||
- Rate limiting added; may need tuning based on load
|
||||
- Token family approach may need cleanup job for old families
|
||||
```
|
||||
|
||||
### What to Include
|
||||
|
||||
| Section | Content |
|
||||
|---------|---------|
|
||||
| Frontmatter | Metadata for future queries |
|
||||
| What Was Built | High-level summary |
|
||||
| Implementation Notes | Technical details worth preserving |
|
||||
| Deviations | All Rules 1-4 deviations with details |
|
||||
| Commits | Git commit messages created |
|
||||
| Verification Status | What passed, what's pending |
|
||||
| Notes for Next Plan | Context for future work |
|
||||
|
||||
---
|
||||
|
||||
## VERIFICATION.md
|
||||
|
||||
Created by Verifier after phase completion.
|
||||
|
||||
### Structure
|
||||
|
||||
```yaml
|
||||
---
|
||||
phase: 2
|
||||
status: PASS # PASS | GAPS_FOUND
|
||||
verified_at: 2024-01-15T10:30:00Z
|
||||
verified_by: verifier-agent
|
||||
---
|
||||
|
||||
# Phase 2 Verification: JWT Implementation
|
||||
|
||||
## Observable Truths
|
||||
|
||||
| Truth | Status | Evidence |
|
||||
|-------|--------|----------|
|
||||
| User can log in with email/password | VERIFIED | Login endpoint returns tokens, sets cookies |
|
||||
| Sessions persist across page refresh | VERIFIED | Cookie-based token survives reload |
|
||||
| Token refresh extends session | VERIFIED | Refresh endpoint issues new tokens |
|
||||
| Expired tokens rejected | VERIFIED | 401 returned for expired access token |
|
||||
|
||||
## Required Artifacts
|
||||
|
||||
| Artifact | Status | Check |
|
||||
|----------|--------|-------|
|
||||
| src/api/auth/login.ts | EXISTS | Exports login handler |
|
||||
| src/api/auth/refresh.ts | EXISTS | Exports refresh handler |
|
||||
| src/middleware/auth.ts | EXISTS | Exports auth middleware |
|
||||
| db/migrations/002_refresh_tokens.sql | EXISTS | Creates table |
|
||||
|
||||
## Required Wiring
|
||||
|
||||
| From | To | Status | Evidence |
|
||||
|------|-----|--------|----------|
|
||||
| Login handler | Token generation | WIRED | login.ts:45 calls createTokens |
|
||||
| Auth middleware | Token validation | WIRED | auth.ts:23 calls verifyToken |
|
||||
| Refresh handler | Token rotation | WIRED | refresh.ts:67 calls rotateToken |
|
||||
| Protected routes | Auth middleware | WIRED | routes.ts uses auth middleware |
|
||||
|
||||
## Anti-Patterns
|
||||
|
||||
| Pattern | Found | Location |
|
||||
|---------|-------|----------|
|
||||
| TODO comments | NO | - |
|
||||
| Stub implementations | NO | - |
|
||||
| Console.log in handlers | YES | src/api/auth/login.ts:34 (debug log) |
|
||||
| Empty catch blocks | NO | - |
|
||||
|
||||
## Human Verification Needed
|
||||
|
||||
| Check | Reason |
|
||||
|-------|--------|
|
||||
| Cookie flags in production | Requires deployed environment |
|
||||
| Token timing accuracy | Requires wall-clock testing |
|
||||
|
||||
## Gaps Found
|
||||
None blocking. One console.log should be removed before production.
|
||||
|
||||
## Remediation
|
||||
- Task created: "Remove debug console.log from login handler"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## UAT.md
|
||||
|
||||
User Acceptance Testing results.
|
||||
|
||||
### Structure
|
||||
|
||||
```yaml
|
||||
---
|
||||
phase: 2
|
||||
tested_by: user
|
||||
tested_at: 2024-01-15T14:00:00Z
|
||||
status: PASS # PASS | ISSUES_FOUND
|
||||
---
|
||||
|
||||
# Phase 2 UAT: JWT Implementation
|
||||
|
||||
## Test Cases
|
||||
|
||||
### 1. Login with email and password
|
||||
**Prompt:** "Can you log in with your email and password?"
|
||||
**Result:** PASS
|
||||
**Notes:** Login successful, redirected to dashboard
|
||||
|
||||
### 2. Session persists on refresh
|
||||
**Prompt:** "Refresh the page. Are you still logged in?"
|
||||
**Result:** PASS
|
||||
**Notes:** Still authenticated after refresh
|
||||
|
||||
### 3. Logout clears session
|
||||
**Prompt:** "Click logout. Can you access the dashboard?"
|
||||
**Result:** PASS
|
||||
**Notes:** Redirected to login page
|
||||
|
||||
### 4. Expired session prompts re-login
|
||||
**Prompt:** "Wait 15 minutes (or we can simulate). Does the session refresh?"
|
||||
**Result:** SKIPPED
|
||||
**Reason:** "User chose to trust token rotation implementation"
|
||||
|
||||
## Issues Found
|
||||
None.
|
||||
|
||||
## Sign-Off
|
||||
User confirms Phase 2 JWT Implementation meets requirements.
|
||||
Next: Proceed to Phase 3 (OAuth Integration)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Artifact Storage
|
||||
|
||||
### File Structure
|
||||
|
||||
```
|
||||
.planning/
|
||||
├── phases/
|
||||
│ ├── 1/
|
||||
│ │ ├── 1-CONTEXT.md
|
||||
│ │ ├── 1-1-PLAN.md
|
||||
│ │ ├── 1-1-SUMMARY.md
|
||||
│ │ ├── 1-2-PLAN.md
|
||||
│ │ ├── 1-2-SUMMARY.md
|
||||
│ │ └── 1-VERIFICATION.md
|
||||
│ └── 2/
|
||||
│ ├── 2-CONTEXT.md
|
||||
│ ├── 2-1-PLAN.md
|
||||
│ ├── 2-1-SUMMARY.md
|
||||
│ ├── 2-2-PLAN.md
|
||||
│ ├── 2-2-SUMMARY.md
|
||||
│ ├── 2-3-PLAN.md
|
||||
│ ├── 2-3-SUMMARY.md
|
||||
│ ├── 2-VERIFICATION.md
|
||||
│ └── 2-UAT.md
|
||||
├── STATE.md
|
||||
└── config.json
|
||||
```
|
||||
|
||||
### Naming Convention
|
||||
|
||||
| Pattern | Meaning |
|
||||
|---------|---------|
|
||||
| `{phase}-CONTEXT.md` | Discussion decisions for phase |
|
||||
| `{phase}-{plan}-PLAN.md` | Executable plan |
|
||||
| `{phase}-{plan}-SUMMARY.md` | Execution record |
|
||||
| `{phase}-VERIFICATION.md` | Phase verification |
|
||||
| `{phase}-UAT.md` | User acceptance testing |
|
||||
|
||||
---
|
||||
|
||||
## Commit Strategy
|
||||
|
||||
Each task produces an atomic commit:
|
||||
|
||||
```
|
||||
{type}({phase}-{plan}): {description}
|
||||
|
||||
- Detail 1
|
||||
- Detail 2
|
||||
```
|
||||
|
||||
### Types
|
||||
- `feat`: New functionality
|
||||
- `fix`: Bug fix
|
||||
- `test`: Test additions
|
||||
- `refactor`: Code restructuring
|
||||
- `perf`: Performance improvement
|
||||
- `docs`: Documentation
|
||||
- `style`: Formatting only
|
||||
- `chore`: Maintenance
|
||||
|
||||
### Examples
|
||||
```
|
||||
feat(2-3): implement refresh token rotation
|
||||
|
||||
- Add refresh_tokens table with family tracking
|
||||
- Implement rotation endpoint at POST /api/auth/refresh
|
||||
- Add reuse detection with family revocation
|
||||
|
||||
fix(2-3): add await to token lookup query
|
||||
|
||||
- Token lookup was returning promise instead of result
|
||||
- Added proper await in refresh handler
|
||||
|
||||
feat(2-3): add rate limiting to refresh endpoint
|
||||
|
||||
- [Deviation Rule 2] Added express-rate-limit
|
||||
- 10 requests per minute per IP
|
||||
- Prevents brute force token guessing
|
||||
```
|
||||
|
||||
### Metadata Commit
|
||||
|
||||
After plan completion:
|
||||
```
|
||||
chore(2-3): complete plan execution
|
||||
|
||||
Artifacts:
|
||||
- 2-3-SUMMARY.md created
|
||||
- STATE.md updated
|
||||
- 3 tasks completed, 2 deviations handled
|
||||
```
|
||||
Reference in New Issue
Block a user