mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-10-31 10:19:43 +00:00
chore(harness): make repository agent-ready
Add concise routed context, task-aware agent roles, focused skills, and structured learning promotion.\n\nUnify local development and workspace tooling, add layered test and E2E verification, harden MCP authentication, and gate deployment behind verification and explicit production promotion.
This commit is contained in:
1 parent
5a69bbc1a5
commit
01bb8225ae
125 files changed
+5078
-24529
No files matched your search
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
id: YYYY-MM-DD-short-slug
|
||||||
|
date: YYYY-MM-DD
|
||||||
|
status: inbox
|
||||||
|
scope: path or workflow
|
||||||
|
evidence: command, test, or artifact
|
||||||
|
review_after: YYYY-MM-DD
|
||||||
|
---
|
||||||
|
|
||||||
|
## Symptom
|
||||||
|
|
||||||
|
Observable failure or friction.
|
||||||
|
|
||||||
|
## Reproduction
|
||||||
|
|
||||||
|
Exact bounded reproduction.
|
||||||
|
|
||||||
|
## Cause
|
||||||
|
|
||||||
|
Confirmed cause, not a hypothesis.
|
||||||
|
|
||||||
|
## Remediation
|
||||||
|
|
||||||
|
Proven correction.
|
||||||
|
|
||||||
|
## Evidence
|
||||||
|
|
||||||
|
Read-back, test, or other verification.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
id: 2026-08-27-migration-context-conflict
|
||||||
|
date: 2026-08-27
|
||||||
|
status: promoted
|
||||||
|
scope: database migration instructions
|
||||||
|
evidence: root and scoped agent context comparison
|
||||||
|
destination: AGENTS.md and scripts/lint-harness.mjs
|
||||||
|
review_after: 2027-02-27
|
||||||
|
---
|
||||||
|
|
||||||
|
## Symptom
|
||||||
|
|
||||||
|
Root instructions prohibited remote migration application while scoped Supabase
|
||||||
|
instructions authorized it.
|
||||||
|
|
||||||
|
## Reproduction
|
||||||
|
|
||||||
|
Compare the former root `AGENTS.md` migration rule with the former
|
||||||
|
`apps/supabase/agents.md` migration section.
|
||||||
|
|
||||||
|
## Cause
|
||||||
|
|
||||||
|
Runtime-specific instruction files evolved independently without an executable
|
||||||
|
consistency check.
|
||||||
|
|
||||||
|
## Remediation
|
||||||
|
|
||||||
|
Make root context authoritative, scope only additional local rules, and reject
|
||||||
|
positive `apply_migration` instructions in the harness lint.
|
||||||
|
|
||||||
|
## Evidence
|
||||||
|
|
||||||
|
`npm run lint:harness` checks instruction consistency and the authoritative
|
||||||
|
migration location.
|
||||||
@@ -40,7 +40,8 @@ If the story details are empty or missing, STOP and report that the PRD story fo
|
|||||||
- Implement completely; no placeholders or stubs.
|
- Implement completely; no placeholders or stubs.
|
||||||
- If No-commit is true, do NOT commit or push changes.
|
- If No-commit is true, do NOT commit or push changes.
|
||||||
- Do NOT edit the PRD JSON (status is handled by the loop).
|
- Do NOT edit the PRD JSON (status is handled by the loop).
|
||||||
- All changes made during the run must be committed (including updates to progress/logs).
|
- Commit only task-owned source, tests, and maintained documentation. Runtime logs
|
||||||
|
and evidence remain ignored.
|
||||||
- Before committing, perform a final **security**, **performance**, and **regression** review of your changes.
|
- Before committing, perform a final **security**, **performance**, and **regression** review of your changes.
|
||||||
|
|
||||||
## Your Task (Do this in order)
|
## Your Task (Do this in order)
|
||||||
@@ -60,7 +61,7 @@ If the story details are empty or missing, STOP and report that the PRD story fo
|
|||||||
- **Performance:** check for avoidable regressions (extra queries, heavy loops, unnecessary re-renders).
|
- **Performance:** check for avoidable regressions (extra queries, heavy loops, unnecessary re-renders).
|
||||||
- **Regression:** verify existing behavior that could be impacted still works.
|
- **Regression:** verify existing behavior that could be impacted still works.
|
||||||
10. If No-commit is false, commit changes using the `$commit` skill.
|
10. If No-commit is false, commit changes using the `$commit` skill.
|
||||||
- Stage everything: `git add -A`
|
- Stage only the files owned by this story; never blanket-stage unrelated work.
|
||||||
- Confirm a clean working tree after commit: `git status --porcelain` should be empty.
|
- Confirm a clean working tree after commit: `git status --porcelain` should be empty.
|
||||||
- After committing, capture the commit hash and subject using:
|
- After committing, capture the commit hash and subject using:
|
||||||
`git show -s --format="%h %s" HEAD`.
|
`git show -s --format="%h %s" HEAD`.
|
||||||
@@ -103,7 +104,9 @@ Otherwise, end normally without the signal.
|
|||||||
- When authoring documentation, capture the why (tests + implementation intent).
|
- When authoring documentation, capture the why (tests + implementation intent).
|
||||||
- If you learn how to run/build/test the project, update {{AGENTS_PATH}} briefly (operational only).
|
- If you learn how to run/build/test the project, update {{AGENTS_PATH}} briefly (operational only).
|
||||||
- Keep AGENTS operational only; progress notes belong in {{PROGRESS_PATH}}.
|
- Keep AGENTS operational only; progress notes belong in {{PROGRESS_PATH}}.
|
||||||
- If you hit repeated errors, log them in {{ERRORS_LOG_PATH}} and add a Sign to {{GUARDRAILS_PATH}} using {{GUARDRAILS_REF}} as the template.
|
- If you reproduce a reusable failure, record it using
|
||||||
|
`.agents/learnings/TEMPLATE.md`. Promote it only after review into a maintained
|
||||||
|
doc, skill, fixture, or executable invariant; do not add speculative Signs.
|
||||||
|
|
||||||
## Activity Logging (Required)
|
## Activity Logging (Required)
|
||||||
Log major actions to {{ACTIVITY_LOG_PATH}} using the helper:
|
Log major actions to {{ACTIVITY_LOG_PATH}} using the helper:
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
# Agents Documentation
|
|
||||||
|
|
||||||
This file contains important project-specific context for Claude Code agents working on this repository.
|
|
||||||
|
|
||||||
## Redemption Code System
|
|
||||||
|
|
||||||
**IMPORTANT: Codes can only be redeemed on the website, NOT in the mobile app.**
|
|
||||||
|
|
||||||
Apple's App Store guidelines require that any premium features purchased within an iOS app must go through In-App Purchase. Adding a redemption code feature to the mobile app would violate these guidelines and risk app rejection.
|
|
||||||
|
|
||||||
### Overview
|
|
||||||
Promotional codes that grant users premium access without going through RevenueCat/App Store subscription flow.
|
|
||||||
|
|
||||||
### Database Schema
|
|
||||||
|
|
||||||
**`redemption_codes` table:**
|
|
||||||
- `id` (UUID) - Primary key
|
|
||||||
- `code` (TEXT, UNIQUE) - The redemption code
|
|
||||||
- `description` (TEXT) - Optional description
|
|
||||||
- `max_uses` (INTEGER) - Maximum number of redemptions allowed
|
|
||||||
- `current_uses` (INTEGER) - Current number of redemptions
|
|
||||||
- `expires_at` (TIMESTAMPTZ) - Optional expiration date
|
|
||||||
- `is_active` (BOOLEAN) - Whether the code can be redeemed
|
|
||||||
- `created_by` (UUID) - Admin who created the code
|
|
||||||
- `created_at` (TIMESTAMPTZ)
|
|
||||||
- `updated_at` (TIMESTAMPTZ)
|
|
||||||
|
|
||||||
**`code_redemptions` table:**
|
|
||||||
- `id` (UUID) - Primary key
|
|
||||||
- `code_id` (UUID) - Reference to redemption_codes
|
|
||||||
- `user_id` (UUID) - User who redeemed the code
|
|
||||||
- `redeemed_at` (TIMESTAMPTZ)
|
|
||||||
- UNIQUE constraint on (code_id, user_id) - Each user can only redeem a code once
|
|
||||||
|
|
||||||
### Components
|
|
||||||
|
|
||||||
1. **Admin UI** (`apps/admin/src/pages/RedemptionCodesPage.tsx`)
|
|
||||||
- Super admins can generate codes
|
|
||||||
- View all codes with usage stats
|
|
||||||
- Toggle active/inactive
|
|
||||||
- View who redeemed each code
|
|
||||||
- Delete codes
|
|
||||||
|
|
||||||
2. **Edge Function** (`apps/supabase/functions/redeem-code/index.ts`)
|
|
||||||
- **Unauthenticated** - accepts email + code in request body
|
|
||||||
- Calls the `redeem_code_by_email()` database function
|
|
||||||
- Returns success/error response
|
|
||||||
|
|
||||||
3. **Database Function** (`redeem_code_by_email(p_email TEXT, p_code TEXT)`)
|
|
||||||
- Atomic operation with row locking
|
|
||||||
- Looks up user by email (must have signed up in app first)
|
|
||||||
- Validates: code exists, is active, not expired, has uses remaining
|
|
||||||
- Checks user hasn't already redeemed
|
|
||||||
- Records redemption in `code_redemptions`
|
|
||||||
- Increments `current_uses`
|
|
||||||
- Sets `profiles.is_premium = true`
|
|
||||||
|
|
||||||
4. **Web UI** (`apps/web/app/redeem/page.tsx`)
|
|
||||||
- Public page at `/redeem`
|
|
||||||
- User enters email + redemption code
|
|
||||||
- Calls edge function via fetch
|
|
||||||
- Shows success or error message
|
|
||||||
|
|
||||||
### Environment Variables
|
|
||||||
|
|
||||||
The web app requires:
|
|
||||||
- `NEXT_PUBLIC_SUPABASE_URL` - Supabase project URL for API calls
|
|
||||||
|
|
||||||
### DO NOT
|
|
||||||
|
|
||||||
- **DO NOT** add redemption code UI to the mobile app
|
|
||||||
- **DO NOT** create any in-app mechanism to bypass App Store purchases
|
|
||||||
- **DO NOT** expose the redeem endpoint in mobile app Supabase calls
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
name: architecture-reviewer
|
||||||
|
description: Review cross-cutting or hard-to-reverse architecture decisions. Use only when multiple system boundaries or long-lived contracts change.
|
||||||
|
tools: Read, Bash, Glob, Grep
|
||||||
|
model: opus
|
||||||
|
---
|
||||||
|
|
||||||
|
Evaluate the proposed decision against current boundaries, migration path,
|
||||||
|
operability, reversibility, and verification. Prefer the smallest coherent change.
|
||||||
|
Return trade-offs and a recommendation; do not implement.
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
name: database-reviewer
|
||||||
|
description: Review migrations, RLS, Edge Functions, and query boundaries. Use for database-affecting diffs, not ordinary UI changes.
|
||||||
|
tools: Read, Bash, Glob, Grep
|
||||||
|
model: sonnet
|
||||||
|
---
|
||||||
|
|
||||||
|
Read `apps/supabase/AGENTS.md` and the migration safety document. Review local
|
||||||
|
migration tracking, idempotency, authorization/RLS, environment portability,
|
||||||
|
rollback implications, types, and integration coverage. Never mutate a remote
|
||||||
|
database. Return prioritized, line-specific findings.
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
---
|
|
||||||
name: frontend-developer
|
|
||||||
description: Frontend development specialist for React applications and responsive design. Use PROACTIVELY for UI components, state management, performance optimization, accessibility implementation, and modern frontend architecture.
|
|
||||||
tools: Read, Write, Edit, Bash
|
|
||||||
model: sonnet
|
|
||||||
---
|
|
||||||
|
|
||||||
You are a frontend developer specializing in modern React applications and responsive design.
|
|
||||||
|
|
||||||
## Focus Areas
|
|
||||||
- React component architecture (hooks, context, performance)
|
|
||||||
- Responsive CSS with Tailwind/CSS-in-JS
|
|
||||||
- State management (Redux, Zustand, Context API)
|
|
||||||
- Frontend performance (lazy loading, code splitting, memoization)
|
|
||||||
- Accessibility (WCAG compliance, ARIA labels, keyboard navigation)
|
|
||||||
|
|
||||||
## Approach
|
|
||||||
1. Component-first thinking - reusable, composable UI pieces
|
|
||||||
2. Mobile-first responsive design
|
|
||||||
3. Performance budgets - aim for sub-3s load times
|
|
||||||
4. Semantic HTML and proper ARIA attributes
|
|
||||||
5. Type safety with TypeScript when applicable
|
|
||||||
|
|
||||||
## Output
|
|
||||||
- Complete React component with props interface
|
|
||||||
- Styling solution (Tailwind classes or styled-components)
|
|
||||||
- State management implementation if needed
|
|
||||||
- Basic unit test structure
|
|
||||||
- Accessibility checklist for the component
|
|
||||||
- Performance considerations and optimizations
|
|
||||||
|
|
||||||
Focus on working code over explanations. Include usage examples in comments.
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
name: implementation
|
||||||
|
description: Implement a bounded Sauci product or harness task. Default build agent for ordinary changes after scope and acceptance criteria are known.
|
||||||
|
tools: Read, Write, Edit, Bash, Glob, Grep
|
||||||
|
model: sonnet
|
||||||
|
---
|
||||||
|
|
||||||
|
Read root and nearest scoped `AGENTS.md`. Implement only the requested behavior,
|
||||||
|
update the maintained contract documentation, and add focused tests. Use the
|
||||||
|
repository skills for database, local-stack, simulator, and verification
|
||||||
|
procedures. Stop for missing authority or a materially ambiguous product choice.
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
# Pack Generator Agent
|
|
||||||
|
|
||||||
A specialized agent for generating Sauci question packs.
|
|
||||||
|
|
||||||
## Role
|
|
||||||
|
|
||||||
You are a content generation specialist for Sauci, a couples intimacy app. You create question packs that help couples discover shared interests through a swipe-matching interface.
|
|
||||||
|
|
||||||
## Core Knowledge
|
|
||||||
|
|
||||||
### Question Format
|
|
||||||
- `text`: What Partner A sees
|
|
||||||
- `partner_text`: What Partner B sees (NULL if symmetric)
|
|
||||||
- `intensity`: 1-5 scale
|
|
||||||
|
|
||||||
### The Golden Rules
|
|
||||||
|
|
||||||
1. **Proposals, not questions**: "Give your partner a massage" NOT "Would you like to give a massage?"
|
|
||||||
|
|
||||||
2. **Always "your partner"**: Never him/her/he/she or gendered terms
|
|
||||||
|
|
||||||
3. **No time words**: Never tonight/now/today/right now
|
|
||||||
|
|
||||||
4. **Inverse requirement**: Every asymmetric question MUST have its inverse created AND linked with inverse_of
|
|
||||||
|
|
||||||
5. **Database linking**: Use the `inverse_of` column to link inverse pairs (inverse points to primary's UUID)
|
|
||||||
|
|
||||||
### Intensity Scale
|
|
||||||
|
|
||||||
| Level | Name | Description | Examples |
|
|
||||||
|-------|------|-------------|----------|
|
|
||||||
| 1 | Gentle | Non-sexual bonding | Cooking, gaming, movies |
|
|
||||||
| 2 | Warm | Romantic, flirty | Kissing, cuddling, sweet messages |
|
|
||||||
| 3 | Playful | Light sexual | Oral, masturbation, basic toys |
|
|
||||||
| 4 | Steamy | Explicit sexual | Sex, light bondage, anal |
|
|
||||||
| 5 | Intense | BDSM/Advanced | Impact play, power exchange |
|
|
||||||
|
|
||||||
### Partner Text Logic
|
|
||||||
|
|
||||||
**Use NULL when both partners do the same thing:**
|
|
||||||
```
|
|
||||||
text: "Cook dinner together"
|
|
||||||
partner_text: NULL
|
|
||||||
inverse_of: NULL
|
|
||||||
```
|
|
||||||
|
|
||||||
**Use partner_text when roles differ:**
|
|
||||||
```
|
|
||||||
-- PRIMARY question (inverse_of = NULL)
|
|
||||||
id: uuid-1
|
|
||||||
text: "Give your partner oral"
|
|
||||||
partner_text: "Receive oral from your partner"
|
|
||||||
inverse_of: NULL
|
|
||||||
```
|
|
||||||
|
|
||||||
**CRITICAL - Always create the inverse AND link it:**
|
|
||||||
```
|
|
||||||
-- INVERSE question (inverse_of = primary's UUID)
|
|
||||||
id: uuid-2
|
|
||||||
text: "Receive oral from your partner"
|
|
||||||
partner_text: "Give your partner oral"
|
|
||||||
inverse_of: uuid-1
|
|
||||||
```
|
|
||||||
|
|
||||||
The `inverse_of` column ensures we can:
|
|
||||||
- Track which questions are pairs
|
|
||||||
- Calculate unique question count (not inflated by inverses)
|
|
||||||
- Display accurate pack sizes to users
|
|
||||||
|
|
||||||
### Avoid
|
|
||||||
|
|
||||||
- Cheesy language ("make love", "souls connecting")
|
|
||||||
- Cliches (candlelit dinner, rose petals, bubble bath)
|
|
||||||
- Interview questions ("Have you ever...", "Would you...")
|
|
||||||
- Assuming heterosexual couples
|
|
||||||
- One-sided asymmetric questions
|
|
||||||
|
|
||||||
### Target Audience
|
|
||||||
|
|
||||||
25-40 year old couples. Modern, realistic, not preachy. Think about what actual couples do and say.
|
|
||||||
|
|
||||||
## Generation Process
|
|
||||||
|
|
||||||
1. **Understand the brief**: Category, intensity range, pack position in progression
|
|
||||||
2. **Research existing content**: Check what packs exist, avoid overlap
|
|
||||||
3. **Brainstorm themes**: What specific activities fit this pack?
|
|
||||||
4. **Generate questions**: Mix symmetric and asymmetric, create all inverses with inverse_of links
|
|
||||||
5. **Review**: Check all rules, remove duplicates, verify intensity, confirm inverse pairs are linked
|
|
||||||
6. **Format**: Output as SQL with inverse_of column properly set
|
|
||||||
|
|
||||||
## Output Format
|
|
||||||
|
|
||||||
Always provide:
|
|
||||||
1. Pack metadata (name, description, category, premium status)
|
|
||||||
2. Questions in SQL INSERT format
|
|
||||||
3. Summary statistics (total, by intensity, symmetric vs asymmetric)
|
|
||||||
|
|
||||||
## Invocation
|
|
||||||
|
|
||||||
This agent should be used when:
|
|
||||||
- Creating new question packs
|
|
||||||
- Expanding existing categories
|
|
||||||
- Reviewing/improving existing pack content
|
|
||||||
- Planning category progression structures
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
---
|
|
||||||
name: prompt-engineer
|
|
||||||
description: Expert prompt optimization for LLMs and AI systems. Use PROACTIVELY when building AI features, improving agent performance, or crafting system prompts. Masters prompt patterns and techniques.
|
|
||||||
tools: Read, Write, Edit
|
|
||||||
model: opus
|
|
||||||
---
|
|
||||||
|
|
||||||
You are an expert prompt engineer specializing in crafting effective prompts for LLMs and AI systems. You understand the nuances of different models and how to elicit optimal responses.
|
|
||||||
|
|
||||||
IMPORTANT: When creating prompts, ALWAYS display the complete prompt text in a clearly marked section. Never describe a prompt without showing it.
|
|
||||||
|
|
||||||
## Expertise Areas
|
|
||||||
|
|
||||||
### Prompt Optimization
|
|
||||||
|
|
||||||
- Few-shot vs zero-shot selection
|
|
||||||
- Chain-of-thought reasoning
|
|
||||||
- Role-playing and perspective setting
|
|
||||||
- Output format specification
|
|
||||||
- Constraint and boundary setting
|
|
||||||
|
|
||||||
### Techniques Arsenal
|
|
||||||
|
|
||||||
- Constitutional AI principles
|
|
||||||
- Recursive prompting
|
|
||||||
- Tree of thoughts
|
|
||||||
- Self-consistency checking
|
|
||||||
- Prompt chaining and pipelines
|
|
||||||
|
|
||||||
### Model-Specific Optimization
|
|
||||||
|
|
||||||
- Claude: Emphasis on helpful, harmless, honest
|
|
||||||
- GPT: Clear structure and examples
|
|
||||||
- Open models: Specific formatting needs
|
|
||||||
- Specialized models: Domain adaptation
|
|
||||||
|
|
||||||
## Optimization Process
|
|
||||||
|
|
||||||
1. Analyze the intended use case
|
|
||||||
2. Identify key requirements and constraints
|
|
||||||
3. Select appropriate prompting techniques
|
|
||||||
4. Create initial prompt with clear structure
|
|
||||||
5. Test and iterate based on outputs
|
|
||||||
6. Document effective patterns
|
|
||||||
|
|
||||||
## Required Output Format
|
|
||||||
|
|
||||||
When creating any prompt, you MUST include:
|
|
||||||
|
|
||||||
### The Prompt
|
|
||||||
```
|
|
||||||
[Display the complete prompt text here]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Implementation Notes
|
|
||||||
- Key techniques used
|
|
||||||
- Why these choices were made
|
|
||||||
- Expected outcomes
|
|
||||||
|
|
||||||
## Deliverables
|
|
||||||
|
|
||||||
- **The actual prompt text** (displayed in full, properly formatted)
|
|
||||||
- Explanation of design choices
|
|
||||||
- Usage guidelines
|
|
||||||
- Example expected outputs
|
|
||||||
- Performance benchmarks
|
|
||||||
- Error handling strategies
|
|
||||||
|
|
||||||
## Common Patterns
|
|
||||||
|
|
||||||
- System/User/Assistant structure
|
|
||||||
- XML tags for clear sections
|
|
||||||
- Explicit output formats
|
|
||||||
- Step-by-step reasoning
|
|
||||||
- Self-evaluation criteria
|
|
||||||
|
|
||||||
## Example Output
|
|
||||||
|
|
||||||
When asked to create a prompt for code review:
|
|
||||||
|
|
||||||
### The Prompt
|
|
||||||
```
|
|
||||||
You are an expert code reviewer with 10+ years of experience. Review the provided code focusing on:
|
|
||||||
1. Security vulnerabilities
|
|
||||||
2. Performance optimizations
|
|
||||||
3. Code maintainability
|
|
||||||
4. Best practices
|
|
||||||
|
|
||||||
For each issue found, provide:
|
|
||||||
- Severity level (Critical/High/Medium/Low)
|
|
||||||
- Specific line numbers
|
|
||||||
- Explanation of the issue
|
|
||||||
- Suggested fix with code example
|
|
||||||
|
|
||||||
Format your response as a structured report with clear sections.
|
|
||||||
```
|
|
||||||
|
|
||||||
### Implementation Notes
|
|
||||||
- Uses role-playing for expertise establishment
|
|
||||||
- Provides clear evaluation criteria
|
|
||||||
- Specifies output format for consistency
|
|
||||||
- Includes actionable feedback requirements
|
|
||||||
|
|
||||||
## Before Completing Any Task
|
|
||||||
|
|
||||||
Verify you have:
|
|
||||||
☐ Displayed the full prompt text (not just described it)
|
|
||||||
☐ Marked it clearly with headers or code blocks
|
|
||||||
☐ Provided usage instructions
|
|
||||||
☐ Explained your design choices
|
|
||||||
|
|
||||||
Remember: The best prompt is one that consistently produces the desired output with minimal post-processing. ALWAYS show the prompt, never just describe it.
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
---
|
|
||||||
name: react-native-reviewer
|
|
||||||
description: "Use this agent when you need to review React Native code for best practices, component architecture, performance optimization, and maintainability. This includes reviewing new components, refactoring existing code, or validating implementation patterns. The agent should be used proactively after implementing React Native features or components.\\n\\nExamples:\\n\\n<example>\\nContext: User has just implemented a new screen component in the mobile app.\\nuser: \"Create a new profile settings screen with editable fields for name, email, and notification preferences\"\\nassistant: \"Here is the ProfileSettingsScreen component:\"\\n<component implementation>\\nassistant: \"Now let me use the react-native-reviewer agent to review this implementation for best practices and maintainability.\"\\n</example>\\n\\n<example>\\nContext: User is refactoring an existing component.\\nuser: \"Can you refactor the QuestionCard component to be more reusable?\"\\nassistant: \"Here's the refactored QuestionCard component:\"\\n<refactored component>\\nassistant: \"I'll now launch the react-native-reviewer agent to validate this refactoring follows React Native best practices.\"\\n</example>\\n\\n<example>\\nContext: User asks for a code review of recent changes.\\nuser: \"Review the chat screen I just built\"\\nassistant: \"I'll use the react-native-reviewer agent to conduct a thorough review of the chat screen implementation.\"\\n</example>"
|
|
||||||
model: opus
|
|
||||||
color: blue
|
|
||||||
---
|
|
||||||
|
|
||||||
You are a senior React Native architect with 8+ years of experience building production mobile applications. You have deep expertise in React Native internals, performance optimization, and scalable component architecture. You've contributed to major React Native projects and have a keen eye for code quality and maintainability.
|
|
||||||
|
|
||||||
## Your Review Focus Areas
|
|
||||||
|
|
||||||
### 1. Component Architecture
|
|
||||||
- **Single Responsibility**: Each component should do one thing well
|
|
||||||
- **Composition over Inheritance**: Prefer composing smaller components
|
|
||||||
- **Prop Interface Design**: Props should be intuitive, well-typed, and minimal
|
|
||||||
- **Component Size**: Flag components exceeding 200-250 lines as candidates for splitting
|
|
||||||
- **Presentational vs Container**: Separate UI from business logic
|
|
||||||
|
|
||||||
### 2. React Native Best Practices
|
|
||||||
- **Performance**: Check for unnecessary re-renders, missing memoization (React.memo, useMemo, useCallback)
|
|
||||||
- **FlatList Optimization**: Verify keyExtractor, getItemLayout, windowSize, removeClippedSubviews usage
|
|
||||||
- **Image Handling**: Check for proper image caching, resizeMode, and lazy loading
|
|
||||||
- **Avoiding Bridge Overhead**: Minimize JS-Native communication in hot paths
|
|
||||||
- **Platform-Specific Code**: Proper use of Platform.select() and .ios.tsx/.android.tsx files
|
|
||||||
|
|
||||||
### 3. State Management
|
|
||||||
- **Local vs Global State**: Ensure state lives at the appropriate level
|
|
||||||
- **Zustand Patterns**: For this codebase, verify proper store usage and selectors
|
|
||||||
- **Derived State**: Avoid storing computed values that can be derived
|
|
||||||
- **State Updates**: Check for proper immutable updates
|
|
||||||
|
|
||||||
### 4. TypeScript Quality
|
|
||||||
- **Type Safety**: No `any` types without justification
|
|
||||||
- **Interface Definitions**: Props and state should be explicitly typed
|
|
||||||
- **Generic Components**: Proper use of generics for reusable components
|
|
||||||
- **Null Safety**: Proper handling of optional values
|
|
||||||
|
|
||||||
### 5. Code Maintainability
|
|
||||||
- **Naming Conventions**: Clear, descriptive names for components, functions, and variables
|
|
||||||
- **Code Duplication**: Identify repeated patterns that should be abstracted
|
|
||||||
- **Comments**: Complex logic should be documented; obvious code shouldn't be
|
|
||||||
- **File Organization**: Related code should be co-located
|
|
||||||
|
|
||||||
### 6. Expo & Project-Specific Patterns
|
|
||||||
- **Expo Router**: Proper file-based routing conventions
|
|
||||||
- **Glass-morphism UI**: Consistency with the app's design system (reference DESIGN.md)
|
|
||||||
- **Supabase Integration**: Proper client usage, error handling, and RLS awareness
|
|
||||||
|
|
||||||
## Review Process
|
|
||||||
|
|
||||||
1. **Read DESIGN.md first** if reviewing UI components (apps/mobile/DESIGN.md)
|
|
||||||
2. **Identify the component's purpose** and primary responsibilities
|
|
||||||
3. **Check imports and dependencies** for unnecessary or heavy packages
|
|
||||||
4. **Analyze the component structure** from top to bottom
|
|
||||||
5. **Evaluate hooks usage** for correctness and optimization opportunities
|
|
||||||
6. **Review render logic** for performance and readability
|
|
||||||
7. **Check styling approach** for consistency with the design system
|
|
||||||
8. **Assess error handling** and edge cases
|
|
||||||
9. **Consider accessibility** (a11y labels, touch targets, etc.)
|
|
||||||
|
|
||||||
## Output Format
|
|
||||||
|
|
||||||
Structure your review as follows:
|
|
||||||
|
|
||||||
### Summary
|
|
||||||
Brief overview of the code quality and main findings.
|
|
||||||
|
|
||||||
### Strengths ✅
|
|
||||||
What's done well that should be maintained.
|
|
||||||
|
|
||||||
### Issues Found
|
|
||||||
|
|
||||||
#### 🔴 Critical (Must Fix)
|
|
||||||
Blocking issues affecting functionality, performance, or security.
|
|
||||||
|
|
||||||
#### 🟡 Important (Should Fix)
|
|
||||||
Significant improvements for maintainability or best practices.
|
|
||||||
|
|
||||||
#### 🟢 Suggestions (Consider)
|
|
||||||
Nice-to-have improvements and polish.
|
|
||||||
|
|
||||||
### Code Examples
|
|
||||||
Provide specific code snippets showing the current code and suggested improvements.
|
|
||||||
|
|
||||||
### Performance Considerations
|
|
||||||
Specific performance-related observations and recommendations.
|
|
||||||
|
|
||||||
## Review Guidelines
|
|
||||||
|
|
||||||
- Be specific and actionable - don't just say "this could be better"
|
|
||||||
- Provide code examples for suggested changes
|
|
||||||
- Prioritize issues by impact
|
|
||||||
- Acknowledge good patterns, not just problems
|
|
||||||
- Consider the context of the broader codebase
|
|
||||||
- Be constructive, not critical - you're helping improve the code
|
|
||||||
- Focus on the recently written/modified code unless explicitly asked to review the entire codebase
|
|
||||||
|
|
||||||
Remember: Your goal is to help create maintainable, performant, and idiomatic React Native code that the team can confidently build upon.
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
name: repo-scout
|
||||||
|
description: Locate ownership, callers, contracts, tests, and existing patterns before implementation. Use for bounded read-only discovery, not edits or design decisions.
|
||||||
|
tools: Read, Glob, Grep, Bash
|
||||||
|
model: haiku
|
||||||
|
---
|
||||||
|
|
||||||
|
Map only the requested surface. Read `AGENTS.md` and relevant scoped context.
|
||||||
|
Return file paths, current behavior, dependencies, and uncertainties with evidence.
|
||||||
|
Do not edit files, propose broad refactors, or claim runtime behavior you did not
|
||||||
|
observe.
|
||||||
@@ -1,155 +0,0 @@
|
|||||||
---
|
|
||||||
name: security-architect
|
|
||||||
description: Use this agent when you need to review code, architecture, or configurations for security vulnerabilities, threats, and best practices. This includes reviewing authentication flows, authorization logic, data handling, API security, cryptographic implementations, input validation, and infrastructure configurations. Examples:\n\n<example>\nContext: User has just written an authentication function.\nuser: "Please implement a login function that validates user credentials"\nassistant: "Here is the login function implementation:"\n<function implementation provided>\nassistant: "Now let me use the security-architect agent to review this authentication code for security vulnerabilities."\n</example>\n\n<example>\nContext: User is working on API endpoints that handle sensitive data.\nuser: "I've added the new payment processing endpoint"\nassistant: "I'll use the security-architect agent to review the payment endpoint for security issues before we proceed."\n</example>\n\n<example>\nContext: User asks for a security review of recent changes.\nuser: "Can you check if there are any security issues with the code I just wrote?"\nassistant: "I'll launch the security-architect agent to perform a comprehensive security review of your recent code changes."\n</example>\n\n<example>\nContext: User has implemented data storage logic.\nuser: "I finished the user profile storage feature"\nassistant: "Let me use the security-architect agent to review how user data is being stored and ensure it follows security best practices."\n</example>
|
|
||||||
model: opus
|
|
||||||
color: red
|
|
||||||
---
|
|
||||||
|
|
||||||
You are an elite Security Architect with 20+ years of experience in application security, penetration testing, and secure system design. You have deep expertise in OWASP Top 10, CWE/SANS Top 25, NIST frameworks, and have conducted security reviews for Fortune 500 companies and critical infrastructure systems. You think like an attacker while designing like a defender.
|
|
||||||
|
|
||||||
## Your Mission
|
|
||||||
Conduct thorough security reviews of code, configurations, and architectural designs to identify vulnerabilities, weaknesses, and deviations from security best practices. Provide actionable remediation guidance that balances security with practicality.
|
|
||||||
|
|
||||||
## Review Methodology
|
|
||||||
|
|
||||||
### 1. Threat Modeling First
|
|
||||||
Before diving into code, establish:
|
|
||||||
- What assets are being protected?
|
|
||||||
- Who are the potential threat actors?
|
|
||||||
- What is the attack surface?
|
|
||||||
- What are the trust boundaries?
|
|
||||||
|
|
||||||
### 2. Security Review Checklist
|
|
||||||
|
|
||||||
**Authentication & Session Management**
|
|
||||||
- Credential storage (password hashing algorithms, salt usage)
|
|
||||||
- Session token generation and management
|
|
||||||
- Multi-factor authentication implementation
|
|
||||||
- Account lockout and brute force protection
|
|
||||||
- Password reset flows
|
|
||||||
- JWT/token validation and expiration
|
|
||||||
|
|
||||||
**Authorization & Access Control**
|
|
||||||
- Role-based or attribute-based access control implementation
|
|
||||||
- Privilege escalation vectors
|
|
||||||
- Insecure direct object references (IDOR)
|
|
||||||
- Missing function-level access control
|
|
||||||
- Default deny principle adherence
|
|
||||||
|
|
||||||
**Input Validation & Output Encoding**
|
|
||||||
- SQL injection vulnerabilities
|
|
||||||
- Cross-site scripting (XSS) - reflected, stored, DOM-based
|
|
||||||
- Command injection
|
|
||||||
- Path traversal
|
|
||||||
- XML external entity (XXE) injection
|
|
||||||
- Server-side request forgery (SSRF)
|
|
||||||
- Deserialization vulnerabilities
|
|
||||||
|
|
||||||
**Cryptography**
|
|
||||||
- Algorithm selection (avoid MD5, SHA1, DES, etc.)
|
|
||||||
- Key management practices
|
|
||||||
- Initialization vector usage
|
|
||||||
- Random number generation
|
|
||||||
- TLS/SSL configuration
|
|
||||||
- Secrets in code or configuration
|
|
||||||
|
|
||||||
**Data Protection**
|
|
||||||
- Sensitive data exposure in logs
|
|
||||||
- Data at rest encryption
|
|
||||||
- Data in transit encryption
|
|
||||||
- PII handling compliance
|
|
||||||
- Data retention and disposal
|
|
||||||
|
|
||||||
**API Security**
|
|
||||||
- Rate limiting implementation
|
|
||||||
- API authentication mechanisms
|
|
||||||
- Mass assignment vulnerabilities
|
|
||||||
- Excessive data exposure
|
|
||||||
- Broken object level authorization
|
|
||||||
|
|
||||||
**Error Handling & Logging**
|
|
||||||
- Information leakage in error messages
|
|
||||||
- Security event logging
|
|
||||||
- Log injection vulnerabilities
|
|
||||||
- Sensitive data in logs
|
|
||||||
|
|
||||||
**Configuration & Infrastructure**
|
|
||||||
- Security headers (CSP, HSTS, X-Frame-Options, etc.)
|
|
||||||
- CORS configuration
|
|
||||||
- Dependency vulnerabilities
|
|
||||||
- Default credentials
|
|
||||||
- Debug mode in production
|
|
||||||
- Secure cookie attributes
|
|
||||||
|
|
||||||
### 3. Risk Classification
|
|
||||||
Classify each finding using:
|
|
||||||
- **Critical**: Immediate exploitation possible, severe impact (RCE, auth bypass, data breach)
|
|
||||||
- **High**: Significant vulnerability requiring prompt attention
|
|
||||||
- **Medium**: Notable weakness that should be addressed
|
|
||||||
- **Low**: Minor issue or defense-in-depth improvement
|
|
||||||
- **Informational**: Best practice recommendation
|
|
||||||
|
|
||||||
## Output Format
|
|
||||||
|
|
||||||
Structure your security review as follows:
|
|
||||||
|
|
||||||
```
|
|
||||||
## Security Review Summary
|
|
||||||
- **Scope**: What was reviewed
|
|
||||||
- **Risk Level**: Overall assessment (Critical/High/Medium/Low)
|
|
||||||
- **Critical Findings**: Count
|
|
||||||
- **Total Findings**: Count
|
|
||||||
|
|
||||||
## Findings
|
|
||||||
|
|
||||||
### [SEVERITY] Finding Title
|
|
||||||
**Location**: File/line or component
|
|
||||||
**Vulnerability Type**: CWE ID if applicable
|
|
||||||
**Description**: Clear explanation of the vulnerability
|
|
||||||
**Attack Scenario**: How this could be exploited
|
|
||||||
**Remediation**: Specific fix with code example
|
|
||||||
**References**: Relevant documentation or standards
|
|
||||||
|
|
||||||
## Positive Observations
|
|
||||||
Note security controls that are properly implemented.
|
|
||||||
|
|
||||||
## Recommendations
|
|
||||||
Prioritized list of security improvements.
|
|
||||||
```
|
|
||||||
|
|
||||||
## Behavioral Guidelines
|
|
||||||
|
|
||||||
1. **Be Thorough**: Check every input, output, and trust boundary. Attackers only need one weakness.
|
|
||||||
|
|
||||||
2. **Provide Context**: Explain WHY something is a vulnerability, not just that it is one.
|
|
||||||
|
|
||||||
3. **Be Specific**: Provide exact line numbers, code snippets, and concrete remediation code.
|
|
||||||
|
|
||||||
4. **Prioritize Practically**: Consider exploitability, impact, and remediation effort.
|
|
||||||
|
|
||||||
5. **Avoid False Positives**: Verify findings before reporting. If uncertain, clearly state your confidence level.
|
|
||||||
|
|
||||||
6. **Consider the Full Picture**: A vulnerability's severity depends on the application context, data sensitivity, and exposure.
|
|
||||||
|
|
||||||
7. **Stay Current**: Reference modern attack techniques and defenses. Security evolves rapidly.
|
|
||||||
|
|
||||||
8. **Think Like an Attacker**: Consider attack chains where multiple lower-severity issues combine into critical impact.
|
|
||||||
|
|
||||||
9. **Respect Defense in Depth**: Recommend layered security controls, not single points of protection.
|
|
||||||
|
|
||||||
10. **Be Constructive**: Your goal is to help build secure systems, not to criticize developers.
|
|
||||||
|
|
||||||
## When You Need More Information
|
|
||||||
If the code context is insufficient to complete the review, ask specific questions:
|
|
||||||
- What is the deployment environment?
|
|
||||||
- What is the sensitivity of the data being handled?
|
|
||||||
- Are there compensating controls not visible in this code?
|
|
||||||
- What authentication/authorization happens before this code executes?
|
|
||||||
|
|
||||||
## Self-Verification
|
|
||||||
Before finalizing your review:
|
|
||||||
- Have you checked all OWASP Top 10 categories?
|
|
||||||
- Have you considered the business context?
|
|
||||||
- Are your remediation suggestions practical and complete?
|
|
||||||
- Have you prioritized findings appropriately?
|
|
||||||
- Have you provided enough detail for developers to fix issues?
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
name: security-reviewer
|
||||||
|
description: Review auth, RLS, cryptography, secrets, payments, privileged MCP, or destructive operations. Use only when these risk triggers are present.
|
||||||
|
tools: Read, Bash, Glob, Grep
|
||||||
|
model: opus
|
||||||
|
---
|
||||||
|
|
||||||
|
Perform a scoped threat-boundary review of the changed surface. Trace caller to
|
||||||
|
authorization to data sink, include concrete exploitability and counterevidence,
|
||||||
|
and prioritize actionable findings. Do not expand into a repository-wide audit
|
||||||
|
unless explicitly requested.
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
---
|
|
||||||
name: test-agent
|
|
||||||
description: "Use this agent when you need to identify testing opportunities in new or modified code, run existing test suites, analyze test failures, or fix broken tests. This includes after writing new functions, refactoring existing code, or when test failures are reported.\\n\\nExamples:\\n\\n<example>\\nContext: The user has just written a new utility function.\\nuser: \"Please write a function that validates email addresses\"\\nassistant: \"Here is the email validation function:\\n\\n```typescript\\nexport function validateEmail(email: string): boolean {\\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\\n return emailRegex.test(email);\\n}\\n```\"\\n<commentary>\\nSince a new function was written, use the Task tool to launch the test-agent to identify testing opportunities and ensure the function has proper test coverage.\\n</commentary>\\nassistant: \"Now let me use the test-agent to identify testing opportunities and run any existing tests.\"\\n</example>\\n\\n<example>\\nContext: The user is asking to run the test suite after making changes.\\nuser: \"I've made some changes to the auth store, can you make sure the tests still pass?\"\\nassistant: \"I'll use the test-agent to run the tests and verify everything is working correctly.\"\\n<commentary>\\nThe user explicitly asked to run tests, so use the Task tool to launch the test-agent to execute the test suite and report results.\\n</commentary>\\n</example>\\n\\n<example>\\nContext: Tests are failing after a refactor.\\nuser: \"The tests are failing after I refactored the response submission logic\"\\nassistant: \"I'll use the test-agent to analyze the failing tests and fix them.\"\\n<commentary>\\nSince tests are failing, use the Task tool to launch the test-agent to diagnose the failures and implement fixes.\\n</commentary>\\n</example>\\n\\n<example>\\nContext: Code was written that modifies core business logic.\\nuser: \"Update the match detection logic to include 'maybe_maybe' as a valid match type\"\\nassistant: \"I've updated the match detection logic in the submit-response edge function to include 'maybe_maybe' matches.\"\\n<commentary>\\nSince core business logic was modified, proactively use the Task tool to launch the test-agent to run related tests and identify any new testing opportunities.\\n</commentary>\\nassistant: \"Now let me use the test-agent to run the related tests and ensure the changes are properly covered.\"\\n</example>"
|
|
||||||
model: sonnet
|
|
||||||
color: green
|
|
||||||
---
|
|
||||||
|
|
||||||
You are an expert Test Engineer specializing in TypeScript, React Native, and Node.js testing. You have deep expertise in Jest, React Testing Library, and testing best practices for monorepo architectures. Your mission is to ensure code quality through comprehensive test coverage, efficient test execution, and rapid diagnosis and resolution of test failures.
|
|
||||||
|
|
||||||
## Your Core Responsibilities
|
|
||||||
|
|
||||||
### 1. Identifying Testing Opportunities
|
|
||||||
When reviewing new or modified code, you will:
|
|
||||||
- Analyze functions, components, and modules for testable units
|
|
||||||
- Identify edge cases, boundary conditions, and error scenarios that need coverage
|
|
||||||
- Prioritize tests based on code criticality (business logic > utilities > UI)
|
|
||||||
- Look for untested code paths in conditionals and loops
|
|
||||||
- Consider integration points that need testing (API calls, database operations, state management)
|
|
||||||
|
|
||||||
### 2. Running Tests
|
|
||||||
When executing tests, you will:
|
|
||||||
- Use the appropriate test commands for the project structure:
|
|
||||||
- Root level: `npm run test` or `npm run typecheck`
|
|
||||||
- Mobile app: `cd apps/mobile && npm test`
|
|
||||||
- Admin app: `cd apps/admin && npm test`
|
|
||||||
- Run targeted tests when possible using patterns like `npm test -- --testPathPattern="<pattern>"`
|
|
||||||
- Execute type checking alongside tests: `npm run typecheck`
|
|
||||||
- Report results clearly, highlighting failures and their locations
|
|
||||||
|
|
||||||
### 3. Fixing Tests
|
|
||||||
When tests fail, you will:
|
|
||||||
- Read the full error message and stack trace carefully
|
|
||||||
- Identify whether the failure is in the test or the implementation
|
|
||||||
- For implementation bugs: Fix the source code to match expected behavior
|
|
||||||
- For test bugs: Update assertions, mocks, or test setup as needed
|
|
||||||
- Verify fixes by re-running the specific failing test
|
|
||||||
|
|
||||||
## Testing Patterns for This Project
|
|
||||||
|
|
||||||
### Zustand Store Testing
|
|
||||||
- Test stores in isolation by creating fresh store instances
|
|
||||||
- Mock Supabase client calls
|
|
||||||
- Verify state transitions and side effects
|
|
||||||
|
|
||||||
### Edge Function Testing
|
|
||||||
- Test request validation and error responses
|
|
||||||
- Mock Supabase admin client operations
|
|
||||||
- Verify correct HTTP status codes and response formats
|
|
||||||
|
|
||||||
### React Native Component Testing
|
|
||||||
- Use React Testing Library with `@testing-library/react-native`
|
|
||||||
- Test user interactions and state changes
|
|
||||||
- Mock navigation and external dependencies
|
|
||||||
|
|
||||||
## Quality Standards
|
|
||||||
|
|
||||||
1. **Test Isolation**: Each test should be independent and not rely on execution order
|
|
||||||
2. **Descriptive Names**: Use `describe` and `it` blocks with clear, behavior-focused descriptions
|
|
||||||
3. **Arrange-Act-Assert**: Structure tests with clear setup, execution, and verification phases
|
|
||||||
4. **Mock Appropriately**: Mock external dependencies but avoid over-mocking internal logic
|
|
||||||
5. **Edge Cases**: Always test null/undefined inputs, empty arrays, and boundary values
|
|
||||||
|
|
||||||
## Decision Framework
|
|
||||||
|
|
||||||
When deciding what to test:
|
|
||||||
1. **Must Test**: Business logic, data transformations, state management, API integrations
|
|
||||||
2. **Should Test**: Utility functions, custom hooks, complex conditionals
|
|
||||||
3. **Consider Testing**: UI components with logic, navigation flows
|
|
||||||
4. **Skip Testing**: Simple pass-through components, third-party library wrappers
|
|
||||||
|
|
||||||
## Output Format
|
|
||||||
|
|
||||||
When reporting test results, provide:
|
|
||||||
- Summary: Total tests, passed, failed, skipped
|
|
||||||
- Failures: File path, test name, error message, and relevant code snippet
|
|
||||||
- Recommendations: Specific fixes or additional tests needed
|
|
||||||
|
|
||||||
When identifying testing opportunities, provide:
|
|
||||||
- List of testable units with priority (high/medium/low)
|
|
||||||
- Suggested test cases for each unit
|
|
||||||
- Any mocking requirements
|
|
||||||
|
|
||||||
## Self-Verification
|
|
||||||
|
|
||||||
Before completing your task:
|
|
||||||
- Confirm all tests pass after fixes
|
|
||||||
- Verify type checking passes: `npm run typecheck`
|
|
||||||
- Ensure no regressions were introduced
|
|
||||||
- Document any tests that were skipped and why
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
name: test-writer
|
||||||
|
description: Add focused regression or contract tests for a known behavior. Use when test ownership and expected behavior are already clear.
|
||||||
|
tools: Read, Write, Edit, Bash, Glob, Grep
|
||||||
|
model: sonnet
|
||||||
|
---
|
||||||
|
|
||||||
|
Test the intended observable contract at the lowest useful layer. Preserve real
|
||||||
|
auth and authorization boundaries. Do not weaken assertions to accommodate a
|
||||||
|
failure. Run the focused test and report exact evidence.
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
name: verifier
|
||||||
|
description: Independently drive already-implemented behavior and return an evidence-backed verdict. Use before a PR or when asked whether a change actually works.
|
||||||
|
tools: Read, Bash, Glob, Grep
|
||||||
|
model: sonnet
|
||||||
|
---
|
||||||
|
|
||||||
|
Remain read-only. Follow `.codex/skills/verify/SKILL.md`, exercise the running
|
||||||
|
product, and capture evidence under `evidence/`. Return expected versus observed,
|
||||||
|
artifact paths, and `works` or `broken`. Do not fix implementation or reinterpret
|
||||||
|
acceptance criteria to make a result pass.
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
name: db-migration
|
||||||
|
description: Create, review, and verify Sauci Supabase schema migrations.
|
||||||
|
---
|
||||||
|
|
||||||
|
Read `.codex/skills/db-migration/SKILL.md` completely and follow it.
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
name: dev-local
|
||||||
|
description: Start, inspect, reset, or stop the complete local Sauci stack.
|
||||||
|
---
|
||||||
|
|
||||||
|
Read `.codex/skills/dev-local/SKILL.md` completely and follow it.
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
name: incident-triage
|
||||||
|
description: Diagnose Sauci development, CI, backend, or production symptoms with evidence.
|
||||||
|
---
|
||||||
|
|
||||||
|
Read `.codex/skills/incident-triage/SKILL.md` completely and follow it.
|
||||||
@@ -1,227 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: ios-simulator-skill
|
name: ios-simulator-skill
|
||||||
version: 1.3.0
|
description: Build, launch, and verify Sauci on an iOS simulator with local backend wiring and evidence.
|
||||||
description: 21 production-ready scripts for iOS app testing, building, and automation. Provides semantic UI navigation, build automation, accessibility testing, and simulator lifecycle management. Optimized for AI agents with minimal token output.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# iOS Simulator Skill
|
Read `.codex/skills/mobile-simulator/SKILL.md` completely and follow it. For this
|
||||||
|
invocation, select the iOS path.
|
||||||
Build, test, and automate iOS applications using accessibility-driven navigation and structured data instead of pixel coordinates.
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. Check environment
|
|
||||||
bash scripts/sim_health_check.sh
|
|
||||||
|
|
||||||
# 2. Launch app
|
|
||||||
python scripts/app_launcher.py --launch com.example.app
|
|
||||||
|
|
||||||
# 3. Map screen to see elements
|
|
||||||
python scripts/screen_mapper.py
|
|
||||||
|
|
||||||
# 4. Tap button
|
|
||||||
python scripts/navigator.py --find-text "Login" --tap
|
|
||||||
|
|
||||||
# 5. Enter text
|
|
||||||
python scripts/navigator.py --find-type TextField --enter-text "user@example.com"
|
|
||||||
```
|
|
||||||
|
|
||||||
All scripts support `--help` for detailed options and `--json` for machine-readable output.
|
|
||||||
|
|
||||||
## 21 Production Scripts
|
|
||||||
|
|
||||||
### Build & Development (2 scripts)
|
|
||||||
|
|
||||||
1. **build_and_test.py** - Build Xcode projects, run tests, parse results with progressive disclosure
|
|
||||||
- Build with live result streaming
|
|
||||||
- Parse errors and warnings from xcresult bundles
|
|
||||||
- Retrieve detailed build logs on demand
|
|
||||||
- Options: `--project`, `--scheme`, `--clean`, `--test`, `--verbose`, `--json`
|
|
||||||
|
|
||||||
2. **log_monitor.py** - Real-time log monitoring with intelligent filtering
|
|
||||||
- Stream logs or capture by duration
|
|
||||||
- Filter by severity (error/warning/info/debug)
|
|
||||||
- Deduplicate repeated messages
|
|
||||||
- Options: `--app`, `--severity`, `--follow`, `--duration`, `--output`, `--json`
|
|
||||||
|
|
||||||
### Navigation & Interaction (5 scripts)
|
|
||||||
|
|
||||||
3. **screen_mapper.py** - Analyze current screen and list interactive elements
|
|
||||||
- Element type breakdown
|
|
||||||
- Interactive button list
|
|
||||||
- Text field status
|
|
||||||
- Options: `--verbose`, `--hints`, `--json`
|
|
||||||
|
|
||||||
4. **navigator.py** - Find and interact with elements semantically
|
|
||||||
- Find by text (fuzzy matching)
|
|
||||||
- Find by element type
|
|
||||||
- Find by accessibility ID
|
|
||||||
- Enter text or tap elements
|
|
||||||
- Options: `--find-text`, `--find-type`, `--find-id`, `--tap`, `--enter-text`, `--json`
|
|
||||||
|
|
||||||
5. **gesture.py** - Perform swipes, scrolls, pinches, and complex gestures
|
|
||||||
- Directional swipes (up/down/left/right)
|
|
||||||
- Multi-swipe scrolling
|
|
||||||
- Pinch zoom
|
|
||||||
- Long press
|
|
||||||
- Pull to refresh
|
|
||||||
- Options: `--swipe`, `--scroll`, `--pinch`, `--long-press`, `--refresh`, `--json`
|
|
||||||
|
|
||||||
6. **keyboard.py** - Text input and hardware button control
|
|
||||||
- Type text (fast or slow)
|
|
||||||
- Special keys (return, delete, tab, space, arrows)
|
|
||||||
- Hardware buttons (home, lock, volume, screenshot)
|
|
||||||
- Key combinations
|
|
||||||
- Options: `--type`, `--key`, `--button`, `--slow`, `--clear`, `--dismiss`, `--json`
|
|
||||||
|
|
||||||
7. **app_launcher.py** - App lifecycle management
|
|
||||||
- Launch apps by bundle ID
|
|
||||||
- Terminate apps
|
|
||||||
- Install/uninstall from .app bundles
|
|
||||||
- Deep link navigation
|
|
||||||
- List installed apps
|
|
||||||
- Check app state
|
|
||||||
- Options: `--launch`, `--terminate`, `--install`, `--uninstall`, `--open-url`, `--list`, `--state`, `--json`
|
|
||||||
|
|
||||||
### Testing & Analysis (5 scripts)
|
|
||||||
|
|
||||||
8. **accessibility_audit.py** - Check WCAG compliance on current screen
|
|
||||||
- Critical issues (missing labels, empty buttons, no alt text)
|
|
||||||
- Warnings (missing hints, small touch targets)
|
|
||||||
- Info (missing IDs, deep nesting)
|
|
||||||
- Options: `--verbose`, `--output`, `--json`
|
|
||||||
|
|
||||||
9. **visual_diff.py** - Compare two screenshots for visual changes
|
|
||||||
- Pixel-by-pixel comparison
|
|
||||||
- Threshold-based pass/fail
|
|
||||||
- Generate diff images
|
|
||||||
- Options: `--threshold`, `--output`, `--details`, `--json`
|
|
||||||
|
|
||||||
10. **test_recorder.py** - Automatically document test execution
|
|
||||||
- Capture screenshots and accessibility trees per step
|
|
||||||
- Generate markdown reports with timing data
|
|
||||||
- Options: `--test-name`, `--output`, `--verbose`, `--json`
|
|
||||||
|
|
||||||
11. **app_state_capture.py** - Create comprehensive debugging snapshots
|
|
||||||
- Screenshot, UI hierarchy, app logs, device info
|
|
||||||
- Markdown summary for bug reports
|
|
||||||
- Options: `--app-bundle-id`, `--output`, `--log-lines`, `--json`
|
|
||||||
|
|
||||||
12. **sim_health_check.sh** - Verify environment is properly configured
|
|
||||||
- Check macOS, Xcode, simctl, IDB, Python
|
|
||||||
- List available and booted simulators
|
|
||||||
- Verify Python packages (Pillow)
|
|
||||||
|
|
||||||
### Advanced Testing & Permissions (4 scripts)
|
|
||||||
|
|
||||||
13. **clipboard.py** - Manage simulator clipboard for paste testing
|
|
||||||
- Copy text to clipboard
|
|
||||||
- Test paste flows without manual entry
|
|
||||||
- Options: `--copy`, `--test-name`, `--expected`, `--json`
|
|
||||||
|
|
||||||
14. **status_bar.py** - Override simulator status bar appearance
|
|
||||||
- Presets: clean (9:41, 100% battery), testing (11:11, 50%), low-battery (20%), airplane (offline)
|
|
||||||
- Custom time, network, battery, WiFi settings
|
|
||||||
- Options: `--preset`, `--time`, `--data-network`, `--battery-level`, `--clear`, `--json`
|
|
||||||
|
|
||||||
15. **push_notification.py** - Send simulated push notifications
|
|
||||||
- Simple mode (title + body + badge)
|
|
||||||
- Custom JSON payloads
|
|
||||||
- Test notification handling and deep links
|
|
||||||
- Options: `--bundle-id`, `--title`, `--body`, `--badge`, `--payload`, `--json`
|
|
||||||
|
|
||||||
16. **privacy_manager.py** - Grant, revoke, and reset app permissions
|
|
||||||
- 13 supported services (camera, microphone, location, contacts, photos, calendar, health, etc.)
|
|
||||||
- Batch operations (comma-separated services)
|
|
||||||
- Audit trail with test scenario tracking
|
|
||||||
- Options: `--bundle-id`, `--grant`, `--revoke`, `--reset`, `--list`, `--json`
|
|
||||||
|
|
||||||
### Device Lifecycle Management (5 scripts)
|
|
||||||
|
|
||||||
17. **simctl_boot.py** - Boot simulators with optional readiness verification
|
|
||||||
- Boot by UDID or device name
|
|
||||||
- Wait for device ready with timeout
|
|
||||||
- Batch boot operations (--all, --type)
|
|
||||||
- Performance timing
|
|
||||||
- Options: `--udid`, `--name`, `--wait-ready`, `--timeout`, `--all`, `--type`, `--json`
|
|
||||||
|
|
||||||
18. **simctl_shutdown.py** - Gracefully shutdown simulators
|
|
||||||
- Shutdown by UDID or device name
|
|
||||||
- Optional verification of shutdown completion
|
|
||||||
- Batch shutdown operations
|
|
||||||
- Options: `--udid`, `--name`, `--verify`, `--timeout`, `--all`, `--type`, `--json`
|
|
||||||
|
|
||||||
19. **simctl_create.py** - Create simulators dynamically
|
|
||||||
- Create by device type and iOS version
|
|
||||||
- List available device types and runtimes
|
|
||||||
- Custom device naming
|
|
||||||
- Returns UDID for CI/CD integration
|
|
||||||
- Options: `--device`, `--runtime`, `--name`, `--list-devices`, `--list-runtimes`, `--json`
|
|
||||||
|
|
||||||
20. **simctl_delete.py** - Permanently delete simulators
|
|
||||||
- Delete by UDID or device name
|
|
||||||
- Safety confirmation by default (skip with --yes)
|
|
||||||
- Batch delete operations
|
|
||||||
- Smart deletion (--old N to keep N per device type)
|
|
||||||
- Options: `--udid`, `--name`, `--yes`, `--all`, `--type`, `--old`, `--json`
|
|
||||||
|
|
||||||
21. **simctl_erase.py** - Factory reset simulators without deletion
|
|
||||||
- Preserve device UUID (faster than delete+create)
|
|
||||||
- Erase all, by type, or booted simulators
|
|
||||||
- Optional verification
|
|
||||||
- Options: `--udid`, `--name`, `--verify`, `--timeout`, `--all`, `--type`, `--booted`, `--json`
|
|
||||||
|
|
||||||
## Common Patterns
|
|
||||||
|
|
||||||
**Auto-UDID Detection**: Most scripts auto-detect the booted simulator if --udid is not provided.
|
|
||||||
|
|
||||||
**Device Name Resolution**: Use device names (e.g., "iPhone 16 Pro") instead of UDIDs - scripts resolve automatically.
|
|
||||||
|
|
||||||
**Batch Operations**: Many scripts support `--all` for all simulators or `--type iPhone` for device type filtering.
|
|
||||||
|
|
||||||
**Output Formats**: Default is concise human-readable output. Use `--json` for machine-readable output in CI/CD.
|
|
||||||
|
|
||||||
**Help**: All scripts support `--help` for detailed options and examples.
|
|
||||||
|
|
||||||
## Typical Workflow
|
|
||||||
|
|
||||||
1. Verify environment: `bash scripts/sim_health_check.sh`
|
|
||||||
2. Launch app: `python scripts/app_launcher.py --launch com.example.app`
|
|
||||||
3. Analyze screen: `python scripts/screen_mapper.py`
|
|
||||||
4. Interact: `python scripts/navigator.py --find-text "Button" --tap`
|
|
||||||
5. Verify: `python scripts/accessibility_audit.py`
|
|
||||||
6. Debug if needed: `python scripts/app_state_capture.py --app-bundle-id com.example.app`
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
- macOS 12+
|
|
||||||
- Xcode Command Line Tools
|
|
||||||
- Python 3
|
|
||||||
- IDB (optional, for interactive features)
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
- **SKILL.md** (this file) - Script reference and quick start
|
|
||||||
- **README.md** - Installation and examples
|
|
||||||
- **CLAUDE.md** - Architecture and implementation details
|
|
||||||
- **references/** - Deep documentation on specific topics
|
|
||||||
- **examples/** - Complete automation workflows
|
|
||||||
|
|
||||||
## Key Design Principles
|
|
||||||
|
|
||||||
**Semantic Navigation**: Find elements by meaning (text, type, ID) not pixel coordinates. Survives UI changes.
|
|
||||||
|
|
||||||
**Token Efficiency**: Concise default output (3-5 lines) with optional verbose and JSON modes for detailed results.
|
|
||||||
|
|
||||||
**Accessibility-First**: Built on standard accessibility APIs for reliability and compatibility.
|
|
||||||
|
|
||||||
**Zero Configuration**: Works immediately on any macOS with Xcode. No setup required.
|
|
||||||
|
|
||||||
**Structured Data**: Scripts output JSON or formatted text, not raw logs. Easy to parse and integrate.
|
|
||||||
|
|
||||||
**Auto-Learning**: Build system remembers your device preference. Configuration stored per-project.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Use these scripts directly or let Claude Code invoke them automatically when your request matches the skill description.
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
name: mobile-simulator
|
||||||
|
description: Build, launch, and verify Sauci on iOS or Android simulators.
|
||||||
|
---
|
||||||
|
|
||||||
|
Read `.codex/skills/mobile-simulator/SKILL.md` completely and follow it.
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
name: promote-learning
|
||||||
|
description: Record or promote a reproduced Sauci workflow lesson into a durable artifact.
|
||||||
|
---
|
||||||
|
|
||||||
|
Read `.codex/skills/promote-learning/SKILL.md` completely and follow it.
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
name: question-pack
|
||||||
|
description: Create or review Sauci question-pack content and inverse relationships.
|
||||||
|
---
|
||||||
|
|
||||||
|
Read `.codex/skills/question-pack/SKILL.md` completely and follow it.
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
name: release-mobile
|
||||||
|
description: Prepare and verify Sauci iOS or Android releases and store uploads.
|
||||||
|
---
|
||||||
|
|
||||||
|
Read `.codex/skills/release-mobile/SKILL.md` completely and follow it.
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
name: verify
|
||||||
|
description: Prove a completed Sauci engineering task works before a PR.
|
||||||
|
---
|
||||||
|
|
||||||
|
Read `.codex/skills/verify/SKILL.md` completely and follow it.
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
name: db-migration
|
||||||
|
description: Create, review, and verify Sauci Supabase schema migrations. Use for tables, columns, functions, policies, indexes, triggers, or other database shape changes.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Sauci database migration
|
||||||
|
|
||||||
|
Read `apps/supabase/AGENTS.md` and `docs/operations/database-migrations.md`.
|
||||||
|
|
||||||
|
1. Create the local file with `npm run db:migration:new -- <name>`.
|
||||||
|
2. Edit only `apps/supabase/migrations/`; keep environment-specific URLs dynamic.
|
||||||
|
3. Update affected shared/generated contracts and callers in the same task.
|
||||||
|
4. Reset local Supabase, run function/RLS tests, and independently inspect the
|
||||||
|
resulting schema/behavior.
|
||||||
|
5. Commit the migration file with dependent code. CI performs deployment.
|
||||||
|
|
||||||
|
Never call remote `apply_migration`; never send DDL through MCP SQL execution;
|
||||||
|
never use a remote project for local validation.
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
name: dev-local
|
||||||
|
description: Start, inspect, reset, or stop the complete local Sauci stack. Use for local development, service logs, port diagnosis, and full-stack test setup.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Local Sauci stack
|
||||||
|
|
||||||
|
Use `scripts/dev-local.sh`; do not manually mix remote and local services.
|
||||||
|
|
||||||
|
| Service | Port |
|
||||||
|
|---|---:|
|
||||||
|
| web | 3000 |
|
||||||
|
| admin | 3001 |
|
||||||
|
| MCP | 3002 |
|
||||||
|
| Expo Metro | 8081 |
|
||||||
|
| Supabase API / DB / Studio | 54321 / 54322 / 54323 |
|
||||||
|
|
||||||
|
Prerequisites: Node from `.nvmrc`, `npm ci`, tmux, Docker-compatible runtime, and
|
||||||
|
the repository Supabase CLI dependency.
|
||||||
|
|
||||||
|
- `scripts/dev-local.sh up` — idempotently start infra and services.
|
||||||
|
- `status`, `logs <service>`, `restart <service>`, `attach` — inspect.
|
||||||
|
- `reset` — local-only database reset plus deterministic fixtures.
|
||||||
|
- `ios` / `android` — launch the native app against local Supabase.
|
||||||
|
- `down`; `down --all` — stop services, optionally infrastructure.
|
||||||
|
|
||||||
|
If a port is occupied, use `status` and inspect its owning process before stopping
|
||||||
|
anything. If a tmux window exited, read its logs before restarting it.
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
name: incident-triage
|
||||||
|
description: Diagnose a Sauci development, CI, backend, or production symptom with evidence. Use for failures, regressions, logs, or unexplained runtime behavior; diagnosis alone does not authorize a fix or deployment.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Incident triage
|
||||||
|
|
||||||
|
Establish environment, time window, expected behavior, and blast radius. Reproduce
|
||||||
|
locally when safe, inspect the narrow relevant logs and data boundary, and separate
|
||||||
|
product bugs from stale tests or environment failures. Preserve exact error text
|
||||||
|
without exposing secrets.
|
||||||
|
|
||||||
|
Return evidence, confirmed cause or ranked hypotheses, affected scope, and the
|
||||||
|
smallest recommended next action. Do not mutate production, implement a fix, or
|
||||||
|
deploy unless the request explicitly includes it.
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
name: mobile-simulator
|
||||||
|
description: Build, launch, and verify Sauci on iOS or Android simulators with local backend wiring and captured evidence. Use for native UI, navigation, permissions, or device behavior.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Mobile simulator verification
|
||||||
|
|
||||||
|
Read `apps/mobile/AGENTS.md` and `apps/mobile/DESIGN.md` for UI work.
|
||||||
|
|
||||||
|
1. Start/reset the local stack through the `dev-local` skill.
|
||||||
|
2. Use `scripts/dev-local.sh ios` or `android`; do not embed remote credentials.
|
||||||
|
3. Drive stable accessibility labels/test IDs. Use `maestro test e2e/maestro` for
|
||||||
|
committed flows and platform simulator tools for focused exploration.
|
||||||
|
4. Capture the final visible state and relevant Metro/native logs under
|
||||||
|
`evidence/`.
|
||||||
|
5. Report device/runtime, steps, expected versus observed, and artifact paths.
|
||||||
|
|
||||||
|
Do not claim a native result from Expo web or component tests alone.
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
name: promote-learning
|
||||||
|
description: Record or promote a reproduced Sauci agent lesson into durable documentation, a skill, fixture, or executable invariant. Use after repeated or confirmed workflow failures, not for speculative observations.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Promote a learning
|
||||||
|
|
||||||
|
Read `docs/agents/learnings.md` and copy `.agents/learnings/TEMPLATE.md` into the
|
||||||
|
appropriate state directory. Include reproduction and verification evidence.
|
||||||
|
|
||||||
|
Prefer one executable destination. Promotion requires review, a destination,
|
||||||
|
and a review-after date; update the record to `promoted` only after that artifact
|
||||||
|
exists and passes `npm run learn:check`. Never turn a transient provider failure or
|
||||||
|
untested workaround into a golden rule.
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: question-pack
|
||||||
|
description: Create or review Sauci question-pack content and its local migration/seed representation. Use for pack generation, inverse pairs, intensity, targeting, or content quality.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Sauci question packs
|
||||||
|
|
||||||
|
Inspect existing packs before generating to avoid duplication.
|
||||||
|
|
||||||
|
- Write proposals, not interview questions; use gender-neutral “your partner”.
|
||||||
|
- Avoid time-bound words such as tonight, now, or today.
|
||||||
|
- Symmetric activities have no partner text.
|
||||||
|
- Every asymmetric activity has the reversed counterpart and a correct
|
||||||
|
`inverse_of` link; inverse pairs are not duplicates.
|
||||||
|
- Intensity 1 is non-sexual bonding, 2 romantic/flirty, 3 light sexual, 4
|
||||||
|
explicit, and 5 advanced/BDSM. Check surrounding content before deciding.
|
||||||
|
- Preserve targeting and required-prop semantics; do not infer them from wording.
|
||||||
|
|
||||||
|
Return metadata, content, inverse/link validation, and distribution statistics.
|
||||||
|
Database changes follow the `db-migration` skill and require local verification.
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
name: release-mobile
|
||||||
|
description: Prepare and verify Sauci iOS or Android releases. Use for versioning, EAS/native builds, Fastlane upload, release notes, or store submission preparation.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Mobile release
|
||||||
|
|
||||||
|
Read `docs/releasing.md`, `apps/mobile/RELEASING.md` when present, and the mobile
|
||||||
|
scoped instructions. Confirm target platform and release profile. Run repository
|
||||||
|
verification plus a native acceptance pass before starting a release build.
|
||||||
|
|
||||||
|
Use the package scripts in `apps/mobile/package.json`; preserve platform signing
|
||||||
|
and versioning. Building or uploading to a store is an external mutation: obtain
|
||||||
|
explicit authorization for the requested target, then report the build artifact,
|
||||||
|
version/build number, upload result, and read-back state.
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
name: verify
|
||||||
|
description: Prove a completed Sauci engineering task works before a PR. Use when asked to verify, prove behavior, or open a PR with runtime evidence.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Verify Sauci work
|
||||||
|
|
||||||
|
Run locally on a non-default branch with the implementation committed.
|
||||||
|
|
||||||
|
1. Start the stack once with `scripts/dev-local.sh up`; reset fixtures first when
|
||||||
|
the task changes durable state. Web is `http://127.0.0.1:3000`, admin is
|
||||||
|
`http://127.0.0.1:3001`, and MCP health is `http://127.0.0.1:3002/health`.
|
||||||
|
2. Give a fresh read-only verifier the acceptance criteria. It drives browser
|
||||||
|
surfaces with the repository browser capability, native surfaces with Maestro
|
||||||
|
or the iOS simulator skill, and APIs with `curl`. Authentication fixtures are
|
||||||
|
described by `e2e/.auth/fixtures.json` after `dev-local.sh reset`.
|
||||||
|
3. The verifier writes screenshots, traces, video, or response evidence under
|
||||||
|
`evidence/` and returns only expected, observed, evidence paths, and
|
||||||
|
`works|broken`. It never edits code.
|
||||||
|
4. If broken, fix and use a fresh verifier. Stop after three failed rounds and
|
||||||
|
report the unresolved evidence.
|
||||||
|
5. After the task works, run `npm run verify:fast`, affected E2E, and
|
||||||
|
`npm run verify:full` when local Supabase/Deno are available. Never weaken an
|
||||||
|
assertion just to pass.
|
||||||
|
6. Open a PR only after both task verification and regression checks pass. Upload
|
||||||
|
evidence to the established CI artifact or `pr-evidence` prerelease and embed
|
||||||
|
the screenshot plus a video/trace link in the PR body.
|
||||||
|
|
||||||
|
A green test suite without an independently observed task outcome is incomplete.
|
||||||
@@ -1,7 +1,13 @@
|
|||||||
name: Deploy Supabase to Production
|
name: Deploy Supabase to Production
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
deploy_production:
|
||||||
|
description: Promote the verified change to production after non-production
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
@@ -10,23 +16,34 @@ on:
|
|||||||
- 'terraform/**'
|
- 'terraform/**'
|
||||||
- '.github/workflows/deploy-supabase.yml'
|
- '.github/workflows/deploy-supabase.yml'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy-database:
|
quality:
|
||||||
|
name: Verify deployable source
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: .nvmrc
|
||||||
|
cache: npm
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm run verify:fast
|
||||||
|
- run: npm run build
|
||||||
|
|
||||||
|
deploy-database:
|
||||||
name: Deploy Migrations & Functions
|
name: Deploy Migrations & Functions
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
needs: quality
|
||||||
|
environment: ${{ matrix.environment }}
|
||||||
strategy:
|
strategy:
|
||||||
max-parallel: 1
|
max-parallel: 1
|
||||||
matrix:
|
matrix:
|
||||||
environment:
|
environment: ${{ fromJSON(github.event_name == 'workflow_dispatch' && inputs.deploy_production && '["non-prod","prod"]' || '["non-prod"]') }}
|
||||||
- name: non-prod
|
|
||||||
project_ref: itbzhrvlgvdmzbnhzhyx
|
|
||||||
- name: prod
|
|
||||||
project_ref: ckjcrkjpmhqhiucifukx
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
|
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
|
||||||
SUPABASE_PROJECT_REF: ${{ matrix.environment.project_ref }}
|
SUPABASE_PROJECT_REF: ${{ matrix.environment == 'prod' && 'ckjcrkjpmhqhiucifukx' || 'itbzhrvlgvdmzbnhzhyx' }}
|
||||||
ENVIRONMENT_NAME: ${{ matrix.environment.name }}
|
ENVIRONMENT_NAME: ${{ matrix.environment }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
@@ -37,13 +54,13 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
version: latest
|
version: latest
|
||||||
|
|
||||||
- name: Link to ${{ matrix.environment.name }} Project
|
- name: Link to ${{ matrix.environment }} Project
|
||||||
run: supabase link --project-ref $SUPABASE_PROJECT_REF --workdir apps
|
run: supabase link --project-ref $SUPABASE_PROJECT_REF --workdir apps
|
||||||
|
|
||||||
- name: Apply Database Migrations (${{ matrix.environment.name }})
|
- name: Apply Database Migrations (${{ matrix.environment }})
|
||||||
run: supabase db push --workdir apps --include-all
|
run: supabase db push --workdir apps --include-all
|
||||||
|
|
||||||
- name: Sync Edge Function Secrets (${{ matrix.environment.name }})
|
- name: Sync Edge Function Secrets (${{ matrix.environment }})
|
||||||
env:
|
env:
|
||||||
# Add secrets from GitHub Secrets
|
# Add secrets from GitHub Secrets
|
||||||
REVENUECAT_WEBHOOK_SECRET: ${{ secrets.REVENUECAT_WEBHOOK_SECRET }}
|
REVENUECAT_WEBHOOK_SECRET: ${{ secrets.REVENUECAT_WEBHOOK_SECRET }}
|
||||||
@@ -72,7 +89,7 @@ jobs:
|
|||||||
echo "No secrets to sync"
|
echo "No secrets to sync"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Deploy Edge Functions (${{ matrix.environment.name }})
|
- name: Deploy Edge Functions (${{ matrix.environment }})
|
||||||
run: |
|
run: |
|
||||||
# Deploy all edge functions (excluding _shared directory)
|
# Deploy all edge functions (excluding _shared directory)
|
||||||
for dir in apps/supabase/functions/*/; do
|
for dir in apps/supabase/functions/*/; do
|
||||||
@@ -88,7 +105,7 @@ jobs:
|
|||||||
supabase functions deploy "$function_name" --no-verify-jwt --project-ref $SUPABASE_PROJECT_REF --workdir apps
|
supabase functions deploy "$function_name" --no-verify-jwt --project-ref $SUPABASE_PROJECT_REF --workdir apps
|
||||||
done
|
done
|
||||||
|
|
||||||
- name: Remove Deleted Functions (${{ matrix.environment.name }})
|
- name: Remove Deleted Functions (${{ matrix.environment }})
|
||||||
run: |
|
run: |
|
||||||
# Get list of functions deployed on Supabase (skip header lines, extract slug column)
|
# Get list of functions deployed on Supabase (skip header lines, extract slug column)
|
||||||
deployed=$(supabase functions list --project-ref $SUPABASE_PROJECT_REF | grep -E '^[a-z]' | awk '{print $1}')
|
deployed=$(supabase functions list --project-ref $SUPABASE_PROJECT_REF | grep -E '^[a-z]' | awk '{print $1}')
|
||||||
@@ -108,9 +125,10 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
deploy-infrastructure:
|
deploy-infrastructure:
|
||||||
name: Deploy Infrastructure (Terraform)
|
name: Deploy Infrastructure (Terraform)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
needs: quality
|
||||||
|
|
||||||
env:
|
env:
|
||||||
TF_VAR_supabase_access_token: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
|
TF_VAR_supabase_access_token: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
|
||||||
@@ -146,18 +164,22 @@ jobs:
|
|||||||
run: terraform apply -auto-approve tfplan
|
run: terraform apply -auto-approve tfplan
|
||||||
|
|
||||||
# Production Environment
|
# Production Environment
|
||||||
- name: Terraform Init (Prod)
|
- name: Terraform Init (Prod)
|
||||||
|
if: github.event_name == 'workflow_dispatch' && inputs.deploy_production
|
||||||
working-directory: terraform/environments/prod
|
working-directory: terraform/environments/prod
|
||||||
run: terraform init
|
run: terraform init
|
||||||
|
|
||||||
- name: Terraform Validate (Prod)
|
- name: Terraform Validate (Prod)
|
||||||
|
if: github.event_name == 'workflow_dispatch' && inputs.deploy_production
|
||||||
working-directory: terraform/environments/prod
|
working-directory: terraform/environments/prod
|
||||||
run: terraform validate
|
run: terraform validate
|
||||||
|
|
||||||
- name: Terraform Plan (Prod)
|
- name: Terraform Plan (Prod)
|
||||||
|
if: github.event_name == 'workflow_dispatch' && inputs.deploy_production
|
||||||
working-directory: terraform/environments/prod
|
working-directory: terraform/environments/prod
|
||||||
run: terraform plan -out=tfplan
|
run: terraform plan -out=tfplan
|
||||||
|
|
||||||
- name: Terraform Apply (Prod)
|
- name: Terraform Apply (Prod)
|
||||||
|
if: github.event_name == 'workflow_dispatch' && inputs.deploy_production
|
||||||
working-directory: terraform/environments/prod
|
working-directory: terraform/environments/prod
|
||||||
run: terraform apply -auto-approve tfplan
|
run: terraform apply -auto-approve tfplan
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
name: Verify
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: verify-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
static:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: .nvmrc
|
||||||
|
cache: npm
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm run learn:check
|
||||||
|
- run: npm run verify:fast
|
||||||
|
- run: npm run build
|
||||||
|
|
||||||
|
full-stack:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 25
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: .nvmrc
|
||||||
|
cache: npm
|
||||||
|
- uses: denoland/setup-deno@v2
|
||||||
|
with:
|
||||||
|
deno-version: v2.x
|
||||||
|
- run: npm ci
|
||||||
|
- run: npx playwright install --with-deps chromium
|
||||||
|
- name: Start local Supabase
|
||||||
|
env:
|
||||||
|
GOOGLE_CLIENT_ID: local
|
||||||
|
GOOGLE_CLIENT_SECRET: local
|
||||||
|
APPLE_CLIENT_ID: local
|
||||||
|
APPLE_CLIENT_SECRET: local
|
||||||
|
run: npx supabase start --workdir apps
|
||||||
|
- name: Reset and seed
|
||||||
|
run: |
|
||||||
|
npx supabase db reset --workdir apps
|
||||||
|
scripts/with-local-supabase-env.sh tests node scripts/seed-e2e.mjs
|
||||||
|
- name: Start application services
|
||||||
|
run: |
|
||||||
|
npx supabase functions serve --workdir apps > /tmp/sauci-functions.log 2>&1 &
|
||||||
|
scripts/with-local-supabase-env.sh web npm run dev -w @sauci/web -- --port 3000 > /tmp/sauci-web.log 2>&1 &
|
||||||
|
scripts/with-local-supabase-env.sh admin npm run dev -w @sauci/admin -- --host 127.0.0.1 --port 3001 > /tmp/sauci-admin.log 2>&1 &
|
||||||
|
scripts/with-local-supabase-env.sh mcp npm run dev -w sauci-mcp-server > /tmp/sauci-mcp.log 2>&1 &
|
||||||
|
- name: Wait for services
|
||||||
|
run: |
|
||||||
|
for url in http://127.0.0.1:3000 http://127.0.0.1:3001/login http://127.0.0.1:3002/health; do
|
||||||
|
for attempt in $(seq 1 60); do
|
||||||
|
curl --fail --silent "$url" >/dev/null && break
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
curl --fail --silent "$url" >/dev/null
|
||||||
|
done
|
||||||
|
- run: npm run test:supabase
|
||||||
|
- run: npm run verify:e2e
|
||||||
|
- name: Upload E2E proof
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: e2e-proof
|
||||||
|
path: |
|
||||||
|
e2e/test-results
|
||||||
|
e2e/playwright-report
|
||||||
|
/tmp/sauci-*.log
|
||||||
|
if-no-files-found: ignore
|
||||||
|
retention-days: 14
|
||||||
+12
-4
@@ -48,9 +48,13 @@ npm_install_log.txt
|
|||||||
pnpm-debug.log*
|
pnpm-debug.log*
|
||||||
|
|
||||||
# Testing
|
# Testing
|
||||||
coverage/
|
coverage/
|
||||||
.nyc_output/
|
.nyc_output/
|
||||||
*.lcov
|
*.lcov
|
||||||
|
evidence/
|
||||||
|
e2e/.auth/
|
||||||
|
e2e/test-results/
|
||||||
|
e2e/playwright-report/
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
*.pem
|
*.pem
|
||||||
@@ -61,4 +65,8 @@ coverage/
|
|||||||
nul
|
nul
|
||||||
|
|
||||||
# Opencode
|
# Opencode
|
||||||
.opencode/
|
.opencode/
|
||||||
|
|
||||||
|
# Agent runtime evidence (maintained lessons remain tracked)
|
||||||
|
.ralph/activity.log
|
||||||
|
.ralph/runs/
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
# Activity Log
|
|
||||||
|
|
||||||
## Run Summary
|
|
||||||
- 2026-01-26 14:33:54 | run=20260126-140911-55357 | iter=3 | mode=build | story=US-005 | duration=344s | status=success
|
|
||||||
- 2026-01-26 14:28:08 | run=20260126-140911-55357 | iter=2 | mode=build | story=US-004 | duration=336s | status=success
|
|
||||||
- 2026-01-26 14:22:30 | run=20260126-140911-55357 | iter=1 | mode=build | story=US-003 | duration=799s | status=success
|
|
||||||
- 2026-01-25 21:09:07 | run=20260125-204012-65223 | iter=25 | mode=build | story=US-003 | duration=0s | status=error
|
|
||||||
- 2026-01-25 21:09:04 | run=20260125-204012-65223 | iter=24 | mode=build | story=US-003 | duration=0s | status=error
|
|
||||||
- 2026-01-25 21:09:01 | run=20260125-204012-65223 | iter=23 | mode=build | story=US-003 | duration=0s | status=error
|
|
||||||
- 2026-01-25 21:08:58 | run=20260125-204012-65223 | iter=22 | mode=build | story=US-003 | duration=0s | status=error
|
|
||||||
- 2026-01-25 21:08:55 | run=20260125-204012-65223 | iter=21 | mode=build | story=US-003 | duration=1s | status=error
|
|
||||||
- 2026-01-25 21:08:52 | run=20260125-204012-65223 | iter=20 | mode=build | story=US-003 | duration=1s | status=error
|
|
||||||
- 2026-01-25 21:08:49 | run=20260125-204012-65223 | iter=19 | mode=build | story=US-003 | duration=1s | status=error
|
|
||||||
- 2026-01-25 21:08:46 | run=20260125-204012-65223 | iter=18 | mode=build | story=US-003 | duration=1s | status=error
|
|
||||||
- 2026-01-25 21:08:42 | run=20260125-204012-65223 | iter=17 | mode=build | story=US-003 | duration=0s | status=error
|
|
||||||
- 2026-01-25 21:08:39 | run=20260125-204012-65223 | iter=16 | mode=build | story=US-003 | duration=0s | status=error
|
|
||||||
- 2026-01-25 21:08:37 | run=20260125-204012-65223 | iter=15 | mode=build | story=US-003 | duration=0s | status=error
|
|
||||||
- 2026-01-25 21:08:34 | run=20260125-204012-65223 | iter=14 | mode=build | story=US-003 | duration=0s | status=error
|
|
||||||
- 2026-01-25 21:08:31 | run=20260125-204012-65223 | iter=13 | mode=build | story=US-003 | duration=1s | status=error
|
|
||||||
- 2026-01-25 21:08:28 | run=20260125-204012-65223 | iter=12 | mode=build | story=US-003 | duration=1s | status=error
|
|
||||||
- 2026-01-25 21:08:25 | run=20260125-204012-65223 | iter=11 | mode=build | story=US-003 | duration=1s | status=error
|
|
||||||
- 2026-01-25 21:08:22 | run=20260125-204012-65223 | iter=10 | mode=build | story=US-003 | duration=1s | status=error
|
|
||||||
- 2026-01-25 21:08:19 | run=20260125-204012-65223 | iter=9 | mode=build | story=US-003 | duration=1s | status=error
|
|
||||||
- 2026-01-25 21:08:16 | run=20260125-204012-65223 | iter=8 | mode=build | story=US-003 | duration=1s | status=error
|
|
||||||
- 2026-01-25 21:08:13 | run=20260125-204012-65223 | iter=7 | mode=build | story=US-003 | duration=1s | status=error
|
|
||||||
- 2026-01-25 21:08:10 | run=20260125-204012-65223 | iter=6 | mode=build | story=US-003 | duration=1s | status=error
|
|
||||||
- 2026-01-25 21:08:07 | run=20260125-204012-65223 | iter=5 | mode=build | story=US-003 | duration=1s | status=error
|
|
||||||
- 2026-01-25 21:08:04 | run=20260125-204012-65223 | iter=4 | mode=build | story=US-003 | duration=1s | status=error
|
|
||||||
- 2026-01-25 21:08:01 | run=20260125-204012-65223 | iter=3 | mode=build | story=US-003 | duration=2s | status=error
|
|
||||||
- 2026-01-25 21:07:57 | run=20260125-204012-65223 | iter=2 | mode=build | story=US-002 | duration=1250s | status=success
|
|
||||||
- 2026-01-25 20:47:05 | run=20260125-204012-65223 | iter=1 | mode=build | story=US-001 | duration=413s | status=success
|
|
||||||
|
|
||||||
## Events
|
|
||||||
|
|
||||||
[2026-01-25 20:40:12] ITERATION 1 start (mode=build story=US-001)
|
|
||||||
[2026-01-25 20:40:36] Start US-001 inventory oversized files
|
|
||||||
[2026-01-25 20:42:52] Added oversized file inventory and split plan
|
|
||||||
[2026-01-25 20:43:19] Completed verification commands (test/lint/typecheck/build)
|
|
||||||
[2026-01-25 20:46:15] Updated progress log for US-001
|
|
||||||
[2026-01-25 20:47:05] ITERATION 1 end (duration=413s)
|
|
||||||
[2026-01-25 20:47:07] ITERATION 2 start (mode=build story=US-002)
|
|
||||||
[2026-01-25 20:47:25] Start US-002 work
|
|
||||||
[2026-01-25 20:59:27] Refactored swipe screen into feature modules (hooks/services/components)
|
|
||||||
[2026-01-25 21:02:54] Completed verification commands (test/lint/typecheck/build/web)
|
|
||||||
[2026-01-25 21:06:57] Updated progress log for US-002
|
|
||||||
[2026-01-25 21:07:57] ITERATION 2 end (duration=1250s)
|
|
||||||
[2026-01-25 21:07:59] ITERATION 3 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:01] ITERATION 3 end (duration=2s)
|
|
||||||
[2026-01-25 21:08:03] ITERATION 4 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:04] ITERATION 4 end (duration=1s)
|
|
||||||
[2026-01-25 21:08:06] ITERATION 5 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:07] ITERATION 5 end (duration=1s)
|
|
||||||
[2026-01-25 21:08:09] ITERATION 6 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:10] ITERATION 6 end (duration=1s)
|
|
||||||
[2026-01-25 21:08:12] ITERATION 7 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:13] ITERATION 7 end (duration=1s)
|
|
||||||
[2026-01-25 21:08:15] ITERATION 8 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:16] ITERATION 8 end (duration=1s)
|
|
||||||
[2026-01-25 21:08:18] ITERATION 9 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:19] ITERATION 9 end (duration=1s)
|
|
||||||
[2026-01-25 21:08:21] ITERATION 10 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:22] ITERATION 10 end (duration=1s)
|
|
||||||
[2026-01-25 21:08:24] ITERATION 11 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:25] ITERATION 11 end (duration=1s)
|
|
||||||
[2026-01-25 21:08:27] ITERATION 12 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:28] ITERATION 12 end (duration=1s)
|
|
||||||
[2026-01-25 21:08:30] ITERATION 13 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:31] ITERATION 13 end (duration=1s)
|
|
||||||
[2026-01-25 21:08:33] ITERATION 14 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:34] ITERATION 14 end (duration=0s)
|
|
||||||
[2026-01-25 21:08:36] ITERATION 15 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:36] ITERATION 15 end (duration=0s)
|
|
||||||
[2026-01-25 21:08:39] ITERATION 16 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:39] ITERATION 16 end (duration=0s)
|
|
||||||
[2026-01-25 21:08:42] ITERATION 17 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:42] ITERATION 17 end (duration=0s)
|
|
||||||
[2026-01-25 21:08:45] ITERATION 18 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:46] ITERATION 18 end (duration=1s)
|
|
||||||
[2026-01-25 21:08:48] ITERATION 19 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:49] ITERATION 19 end (duration=1s)
|
|
||||||
[2026-01-25 21:08:51] ITERATION 20 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:52] ITERATION 20 end (duration=1s)
|
|
||||||
[2026-01-25 21:08:54] ITERATION 21 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:55] ITERATION 21 end (duration=1s)
|
|
||||||
[2026-01-25 21:08:57] ITERATION 22 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:08:58] ITERATION 22 end (duration=0s)
|
|
||||||
[2026-01-25 21:09:00] ITERATION 23 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:09:00] ITERATION 23 end (duration=0s)
|
|
||||||
[2026-01-25 21:09:03] ITERATION 24 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:09:04] ITERATION 24 end (duration=0s)
|
|
||||||
[2026-01-25 21:09:06] ITERATION 25 start (mode=build story=US-003)
|
|
||||||
[2026-01-25 21:09:06] ITERATION 25 end (duration=0s)
|
|
||||||
[2026-01-26 14:09:11] ITERATION 1 start (mode=build story=US-003)
|
|
||||||
[2026-01-26 14:09:37] Start US-003 refactor oversized shared components
|
|
||||||
[2026-01-26 14:14:12] Refactored IntensitySlider into subcomponents and extracted constants/styles
|
|
||||||
[2026-01-26 14:17:23] Attempted Expo web for browser verification; expo start --web failed with localStorage.getItem error
|
|
||||||
[2026-01-26 14:17:58] Ran quality gates and build (npm test failed: missing script; npm run lint failed with existing issues; npm run typecheck/build passed)
|
|
||||||
[2026-01-26 14:21:26] Updated progress log for US-003 with commit/tests
|
|
||||||
[2026-01-26 14:22:30] ITERATION 1 end (duration=799s)
|
|
||||||
[2026-01-26 14:22:32] ITERATION 2 start (mode=build story=US-004)
|
|
||||||
[2026-01-26 14:22:45] Start US-004 work
|
|
||||||
[2026-01-26 14:25:08] Refactored useSwipeScreen helpers
|
|
||||||
[2026-01-26 14:26:13] Ran tests and build for US-004
|
|
||||||
[2026-01-26 14:26:51] Updated progress log for US-004
|
|
||||||
[2026-01-26 14:27:24] Committed US-004 changes
|
|
||||||
[2026-01-26 14:28:08] ITERATION 2 end (duration=336s)
|
|
||||||
[2026-01-26 14:28:10] ITERATION 3 start (mode=build story=US-005)
|
|
||||||
[2026-01-26 14:28:59] Start US-005 validation run (manual log; helper missing)
|
|
||||||
[2026-01-26 14:29:29] Added root test script for US-005
|
|
||||||
[2026-01-26 14:30:41] Fixed lint hook violations for US-005
|
|
||||||
[2026-01-26 14:31:01] Ran npm test, lint, typecheck, build for US-005
|
|
||||||
[2026-01-26 14:31:14] Added AGENTS.md operational notes
|
|
||||||
[2026-01-26 14:32:00] Re-ran npm test after lint fixes
|
|
||||||
[2026-01-26 14:32:45] Updated progress log for US-005
|
|
||||||
[2026-01-26 14:33:54] ITERATION 3 end (duration=344s)
|
|
||||||
@@ -18,3 +18,6 @@
|
|||||||
|
|
||||||
## Learned Signs
|
## Learned Signs
|
||||||
|
|
||||||
|
Durable lessons are promoted through `docs/agents/learnings.md`. Ralph runtime
|
||||||
|
logs are evidence, not instruction. Read promoted artifacts through `AGENTS.md`;
|
||||||
|
do not add permanent signs from an unreproduced failure.
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 1
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-001: Inventory oversized files and refactor plan
|
|
||||||
- Started: 2026-01-25 20:40:12
|
|
||||||
- Ended: 2026-01-25 20:47:05
|
|
||||||
- Duration: 413s
|
|
||||||
- Status: success
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-1.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): 45499edc9a0b78094601f577c707da2374b1765d
|
|
||||||
- Head (after): 209dc652d2aaf04d31fe6dd187a28cf2da8ffd67
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- 209dc65 chore(ralph): update progress log
|
|
||||||
- 06dfc5b docs(inventory): add oversized file plan
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/progress.md
|
|
||||||
- docs/oversized-file-inventory.md
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .ralph/activity.log
|
|
||||||
- apps/mobile/android/app/build.gradle
|
|
||||||
- apps/mobile/app.json
|
|
||||||
- apps/mobile/ios/Sauci.xcodeproj/project.pbxproj
|
|
||||||
- .agents/
|
|
||||||
- .codex/
|
|
||||||
- .ralph/guardrails.md
|
|
||||||
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 10
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:21
|
|
||||||
- Ended: 2026-01-25 21:08:22
|
|
||||||
- Duration: 1s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-10.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 11
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:24
|
|
||||||
- Ended: 2026-01-25 21:08:25
|
|
||||||
- Duration: 1s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-11.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-10.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 12
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:27
|
|
||||||
- Ended: 2026-01-25 21:08:28
|
|
||||||
- Duration: 1s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-12.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-10.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-11.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 13
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:30
|
|
||||||
- Ended: 2026-01-25 21:08:31
|
|
||||||
- Duration: 1s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-13.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-10.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-11.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-12.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 14
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:33
|
|
||||||
- Ended: 2026-01-25 21:08:33
|
|
||||||
- Duration: 0s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-14.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-10.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-11.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-12.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-13.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 15
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:36
|
|
||||||
- Ended: 2026-01-25 21:08:36
|
|
||||||
- Duration: 0s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-15.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-10.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-11.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-12.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-13.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-14.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 16
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:39
|
|
||||||
- Ended: 2026-01-25 21:08:39
|
|
||||||
- Duration: 0s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-16.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-10.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-11.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-12.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-13.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-14.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-15.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 17
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:42
|
|
||||||
- Ended: 2026-01-25 21:08:42
|
|
||||||
- Duration: 0s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-17.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-10.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-11.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-12.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-13.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-14.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-15.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-16.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 18
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:45
|
|
||||||
- Ended: 2026-01-25 21:08:46
|
|
||||||
- Duration: 1s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-18.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-10.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-11.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-12.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-13.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-14.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-15.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-16.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-17.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 19
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:48
|
|
||||||
- Ended: 2026-01-25 21:08:49
|
|
||||||
- Duration: 1s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-19.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-10.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-11.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-12.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-13.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-14.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-15.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-16.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-17.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-18.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 2
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-002: Refactor screen-level files into layer-based modules
|
|
||||||
- Started: 2026-01-25 20:47:07
|
|
||||||
- Ended: 2026-01-25 21:07:57
|
|
||||||
- Duration: 1250s
|
|
||||||
- Status: success
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-2.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): 209dc652d2aaf04d31fe6dd187a28cf2da8ffd67
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- a01079a chore(ralph): update progress logs
|
|
||||||
- 8d4d9d8 refactor(swipe): split swipe screen modules
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- .agents/ralph/PROMPT_build.md
|
|
||||||
- .agents/ralph/README.md
|
|
||||||
- .agents/ralph/agents.sh
|
|
||||||
- .agents/ralph/config.sh
|
|
||||||
- .agents/ralph/diagram.svg
|
|
||||||
- .agents/ralph/log-activity.sh
|
|
||||||
- .agents/ralph/loop.sh
|
|
||||||
- .agents/ralph/ralph.webp
|
|
||||||
- .agents/ralph/references/CONTEXT_ENGINEERING.md
|
|
||||||
- .agents/ralph/references/GUARDRAILS.md
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .codex/skills/commit/SKILL.md
|
|
||||||
- .codex/skills/commit/references/commit_examples.md
|
|
||||||
- .codex/skills/dev-browser/SKILL.md
|
|
||||||
- .codex/skills/dev-browser/bun.lock
|
|
||||||
- .codex/skills/dev-browser/package-lock.json
|
|
||||||
- .codex/skills/dev-browser/package.json
|
|
||||||
- .codex/skills/dev-browser/references/scraping.md
|
|
||||||
- .codex/skills/dev-browser/scripts/start-relay.ts
|
|
||||||
- .codex/skills/dev-browser/scripts/start-server.ts
|
|
||||||
- .codex/skills/dev-browser/server.sh
|
|
||||||
- .codex/skills/dev-browser/src/client.ts
|
|
||||||
- .codex/skills/dev-browser/src/index.ts
|
|
||||||
- .codex/skills/dev-browser/src/relay.ts
|
|
||||||
- .codex/skills/dev-browser/src/snapshot/__tests__/snapshot.test.ts
|
|
||||||
- .codex/skills/dev-browser/src/snapshot/browser-script.ts
|
|
||||||
- .codex/skills/dev-browser/src/snapshot/index.ts
|
|
||||||
- .codex/skills/dev-browser/src/snapshot/inject.ts
|
|
||||||
- .codex/skills/dev-browser/src/types.ts
|
|
||||||
- .codex/skills/dev-browser/tsconfig.json
|
|
||||||
- .codex/skills/dev-browser/vitest.config.ts
|
|
||||||
- .codex/skills/prd/SKILL.md
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/guardrails.md
|
|
||||||
- .ralph/progress.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-1.md
|
|
||||||
- apps/mobile/android/app/build.gradle
|
|
||||||
- apps/mobile/app.json
|
|
||||||
- apps/mobile/app/(app)/swipe.tsx
|
|
||||||
- apps/mobile/ios/Sauci.xcodeproj/project.pbxproj
|
|
||||||
- apps/mobile/src/features/swipe/SwipeScreen.tsx
|
|
||||||
- apps/mobile/src/features/swipe/components/SwipeBlockedState.tsx
|
|
||||||
- apps/mobile/src/features/swipe/components/SwipeCardStack.tsx
|
|
||||||
- apps/mobile/src/features/swipe/components/SwipeCaughtUpState.tsx
|
|
||||||
- apps/mobile/src/features/swipe/components/SwipeDailyLimitState.tsx
|
|
||||||
- apps/mobile/src/features/swipe/components/SwipeHeader.tsx
|
|
||||||
- apps/mobile/src/features/swipe/components/SwipeInfoStateLayout.tsx
|
|
||||||
- apps/mobile/src/features/swipe/components/SwipeLoadingState.tsx
|
|
||||||
- apps/mobile/src/features/swipe/components/SwipeNoPacksState.tsx
|
|
||||||
- apps/mobile/src/features/swipe/components/SwipeNoPartnerState.tsx
|
|
||||||
- apps/mobile/src/features/swipe/components/SwipeQuestionCard.tsx
|
|
||||||
- apps/mobile/src/features/swipe/components/SwipeUploadOverlay.tsx
|
|
||||||
- apps/mobile/src/features/swipe/hooks/useProgressShimmer.ts
|
|
||||||
- apps/mobile/src/features/swipe/hooks/useSwipeScreen.ts
|
|
||||||
- apps/mobile/src/features/swipe/services/swipeService.ts
|
|
||||||
- apps/mobile/src/features/swipe/types.ts
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .ralph/activity.log
|
|
||||||
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 20
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:51
|
|
||||||
- Ended: 2026-01-25 21:08:52
|
|
||||||
- Duration: 1s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-20.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-10.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-11.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-12.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-13.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-14.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-15.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-16.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-17.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-18.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-19.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 21
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:54
|
|
||||||
- Ended: 2026-01-25 21:08:55
|
|
||||||
- Duration: 1s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-21.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-10.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-11.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-12.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-13.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-14.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-15.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-16.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-17.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-18.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-19.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-20.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 22
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:57
|
|
||||||
- Ended: 2026-01-25 21:08:57
|
|
||||||
- Duration: 0s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-22.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-10.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-11.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-12.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-13.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-14.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-15.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-16.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-17.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-18.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-19.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-20.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-21.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 23
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:09:00
|
|
||||||
- Ended: 2026-01-25 21:09:00
|
|
||||||
- Duration: 0s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-23.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-10.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-11.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-12.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-13.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-14.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-15.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-16.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-17.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-18.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-19.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-20.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-21.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-22.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 24
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:09:03
|
|
||||||
- Ended: 2026-01-25 21:09:03
|
|
||||||
- Duration: 0s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-24.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-10.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-11.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-12.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-13.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-14.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-15.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-16.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-17.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-18.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-19.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-20.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-21.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-22.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-23.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 25
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:09:06
|
|
||||||
- Ended: 2026-01-25 21:09:06
|
|
||||||
- Duration: 0s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-25.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-10.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-11.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-12.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-13.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-14.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-15.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-16.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-17.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-18.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-19.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-20.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-21.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-22.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-23.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-24.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 3
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:07:59
|
|
||||||
- Ended: 2026-01-25 21:08:01
|
|
||||||
- Duration: 2s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-3.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 4
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:03
|
|
||||||
- Ended: 2026-01-25 21:08:04
|
|
||||||
- Duration: 1s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-4.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 5
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:06
|
|
||||||
- Ended: 2026-01-25 21:08:07
|
|
||||||
- Duration: 1s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-5.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 6
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:09
|
|
||||||
- Ended: 2026-01-25 21:08:10
|
|
||||||
- Duration: 1s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-6.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 7
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:12
|
|
||||||
- Ended: 2026-01-25 21:08:13
|
|
||||||
- Duration: 1s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-7.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 8
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:15
|
|
||||||
- Ended: 2026-01-25 21:08:16
|
|
||||||
- Duration: 1s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-8.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260125-204012-65223
|
|
||||||
- Iteration: 9
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-25 21:08:18
|
|
||||||
- Ended: 2026-01-25 21:08:19
|
|
||||||
- Duration: 1s
|
|
||||||
- Status: error
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260125-204012-65223-iter-9.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- (none)
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260126-140911-55357
|
|
||||||
- Iteration: 1
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-003: Refactor oversized shared components
|
|
||||||
- Started: 2026-01-26 14:09:11
|
|
||||||
- Ended: 2026-01-26 14:22:30
|
|
||||||
- Duration: 799s
|
|
||||||
- Status: success
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260126-140911-55357-iter-1.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): a01079a7c3c6c727a55cd46a72543e86f2378932
|
|
||||||
- Head (after): 70449659cf1ded7041b71ecf07aa2e7bc76f8346
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- 7044965 chore(ralph): log US-003 progress
|
|
||||||
- f302cb6 refactor(ui): split IntensitySlider pieces
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/progress.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-10.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-11.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-12.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-13.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-14.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-15.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-16.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-17.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-18.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-19.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-2.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-20.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-21.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-22.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-23.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-24.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-25.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-3.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-4.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-5.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-6.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-7.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-8.md
|
|
||||||
- .ralph/runs/run-20260125-204012-65223-iter-9.md
|
|
||||||
- apps/mobile/src/components/ui/IntensitySlider.tsx
|
|
||||||
- apps/mobile/src/components/ui/IntensitySlider/IntensitySliderCurrentCard.tsx
|
|
||||||
- apps/mobile/src/components/ui/IntensitySlider/IntensitySliderInfoModal.tsx
|
|
||||||
- apps/mobile/src/components/ui/IntensitySlider/IntensitySliderLevels.tsx
|
|
||||||
- apps/mobile/src/components/ui/IntensitySlider/IntensitySliderTrack.tsx
|
|
||||||
- apps/mobile/src/components/ui/IntensitySlider/constants.ts
|
|
||||||
- apps/mobile/src/components/ui/IntensitySlider/styles.ts
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .ralph/activity.log
|
|
||||||
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260126-140911-55357
|
|
||||||
- Iteration: 2
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-004: Refactor oversized hooks/services/utils
|
|
||||||
- Started: 2026-01-26 14:22:32
|
|
||||||
- Ended: 2026-01-26 14:28:08
|
|
||||||
- Duration: 336s
|
|
||||||
- Status: success
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260126-140911-55357-iter-2.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): 70449659cf1ded7041b71ecf07aa2e7bc76f8346
|
|
||||||
- Head (after): 1370576dd59180f3b13e0a8d99255dfa96210d60
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- 1370576 chore(ralph): log commit action
|
|
||||||
- 6957502 chore(ralph): update progress logs
|
|
||||||
- 5a9defb refactor(swipe): split useSwipeScreen helpers
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/progress.md
|
|
||||||
- .ralph/runs/run-20260126-140911-55357-iter-1.md
|
|
||||||
- apps/mobile/src/features/swipe/hooks/useSwipeScreen.ts
|
|
||||||
- apps/mobile/src/features/swipe/utils/useSwipeScreen-helpers.ts
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .ralph/activity.log
|
|
||||||
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
# Ralph Run Summary
|
|
||||||
|
|
||||||
- Run ID: 20260126-140911-55357
|
|
||||||
- Iteration: 3
|
|
||||||
- Mode: build
|
|
||||||
- Story: US-005: Validate refactor quality gates
|
|
||||||
- Started: 2026-01-26 14:28:10
|
|
||||||
- Ended: 2026-01-26 14:33:54
|
|
||||||
- Duration: 344s
|
|
||||||
- Status: success
|
|
||||||
- Log: /Users/jjbrunton/Projects/Sauci/.ralph/runs/run-20260126-140911-55357-iter-3.log
|
|
||||||
|
|
||||||
## Git
|
|
||||||
- Head (before): 1370576dd59180f3b13e0a8d99255dfa96210d60
|
|
||||||
- Head (after): ce419fee8b21a37f83e746e6d09ac59692c62e8c
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
- ce419fe chore(logs): update US-005 progress
|
|
||||||
- 368399f fix(validation): satisfy quality gate checks
|
|
||||||
|
|
||||||
### Changed Files (commits)
|
|
||||||
- .agents/tasks/prd-mobile-refactor.json
|
|
||||||
- .ralph/activity.log
|
|
||||||
- .ralph/progress.md
|
|
||||||
- .ralph/runs/run-20260126-140911-55357-iter-2.md
|
|
||||||
- AGENTS.md
|
|
||||||
- apps/mobile/src/components/questions/QuestionCardAudio.tsx
|
|
||||||
- apps/mobile/src/features/chat/components/MessageContent.tsx
|
|
||||||
- package.json
|
|
||||||
|
|
||||||
### Uncommitted Changes
|
|
||||||
- .ralph/activity.log
|
|
||||||
|
|
||||||
@@ -1,21 +1,66 @@
|
|||||||
# AGENTS
|
# Sauci agent map
|
||||||
|
|
||||||
## Verification
|
Sauci is a couples connection product: an Expo mobile app, React admin, Next.js
|
||||||
- npm test (runs mobile Jest suite)
|
web app, Supabase backend, and an internal MCP service in one npm/Turborepo
|
||||||
- npm run lint
|
workspace.
|
||||||
- npm run typecheck
|
|
||||||
- npm run build
|
|
||||||
|
|
||||||
## Database Migrations - MANDATORY RULES
|
## Golden rules
|
||||||
|
|
||||||
**NEVER use `mcp__sauci-prod__apply_migration` or `mcp__sauci-non-prod__apply_migration`.** These create migration records in the remote database without local files, which breaks CI/CD deployments.
|
1. Read the nearest `AGENTS.md` before changing a scoped area.
|
||||||
|
2. Preserve tenant and couple isolation. Never bypass RLS, role checks, or auth.
|
||||||
|
3. All schema changes are local files in `apps/supabase/migrations/` created with
|
||||||
|
`npm run db:migration:new -- <name>`. Never use remote `apply_migration`, never
|
||||||
|
execute DDL through MCP SQL tools, and use those SQL tools for `SELECT` only.
|
||||||
|
4. Never target production from local development or E2E. Local tests must fail
|
||||||
|
closed when a configured Supabase URL is not localhost.
|
||||||
|
5. Read `apps/mobile/DESIGN.md` before mobile UI work.
|
||||||
|
6. Keep shared package exports type-only and route them through `src/index.ts`.
|
||||||
|
7. Do not commit secrets, generated evidence, local logs, or runtime state.
|
||||||
|
8. Scope work to the task. Use high-effort reviewers only for the risk triggers in
|
||||||
|
`docs/agents/routing.md`.
|
||||||
|
|
||||||
**NEVER run DDL (`CREATE`, `ALTER`, `DROP`) via `mcp__*__execute_sql`.** This changes the schema with no migration tracking.
|
## Repository map
|
||||||
|
|
||||||
**All schema changes must be local migration files:**
|
| Area | Purpose | Local instructions |
|
||||||
1. Run `supabase migration new <name>` to create the file
|
|---|---|---|
|
||||||
2. Edit the file in `apps/supabase/migrations/`
|
| `apps/mobile` | Expo React Native product | `apps/mobile/AGENTS.md` |
|
||||||
3. Use idempotent SQL (`IF NOT EXISTS`, `CREATE OR REPLACE`)
|
| `apps/admin` | Vite administration UI | `apps/admin/AGENTS.md` |
|
||||||
4. Commit the file — CI deploys it automatically
|
| `apps/web` | Next.js marketing/redemption UI | `apps/web/AGENTS.md` |
|
||||||
|
| `apps/supabase` | migrations, functions, local backend | `apps/supabase/AGENTS.md` |
|
||||||
|
| `apps/mcp` | internal administrative MCP service | `apps/mcp/AGENTS.md` |
|
||||||
|
| `packages/shared` | shared TypeScript contracts | `packages/shared/AGENTS.md` |
|
||||||
|
| `e2e` | cross-application Playwright flows | `e2e/README.md` |
|
||||||
|
| `docs` | maintained system of record | `docs/index.md` |
|
||||||
|
|
||||||
**`execute_sql` is ONLY for SELECT queries.** No exceptions.
|
## Workflows
|
||||||
|
|
||||||
|
- Bootstrap: `npm ci`
|
||||||
|
- Full local stack: `scripts/dev-local.sh up`
|
||||||
|
- Fast checks: `npm run verify:fast`
|
||||||
|
- Authoritative repository checks: `npm run verify:full`
|
||||||
|
- Running-stack E2E: `npm run verify:e2e`
|
||||||
|
- Everything: `npm run verify`
|
||||||
|
- Before a PR: use `.codex/skills/verify/SKILL.md`
|
||||||
|
|
||||||
|
When a check cannot run because a prerequisite is absent, report it as an
|
||||||
|
environment limitation; do not call it a passing product check.
|
||||||
|
|
||||||
|
## Where to look
|
||||||
|
|
||||||
|
| Question | Source of truth |
|
||||||
|
|---|---|
|
||||||
|
| System boundaries and data flow | `docs/architecture/system.md` |
|
||||||
|
| Local services, ports, fixtures | `docs/development/local-stack.md` |
|
||||||
|
| Test layers and required gates | `docs/testing/strategy.md` |
|
||||||
|
| Database migration safety | `docs/operations/database-migrations.md` |
|
||||||
|
| Agent roles and effort routing | `docs/agents/routing.md` |
|
||||||
|
| Learning promotion | `docs/agents/learnings.md` |
|
||||||
|
| Mobile visual language | `apps/mobile/DESIGN.md` |
|
||||||
|
| Domain documentation index | `docs/index.md` |
|
||||||
|
|
||||||
|
## Documentation discipline
|
||||||
|
|
||||||
|
Update the maintained doc when a contract, command, port, or invariant changes.
|
||||||
|
Plans and historical notes are evidence, not current architecture. A repeated
|
||||||
|
lesson becomes permanent only after it is reproduced and promoted into a doc,
|
||||||
|
skill, fixture, or executable check.
|
||||||
@@ -1,358 +1,5 @@
|
|||||||
# CLAUDE.md
|
# Claude compatibility entrypoint
|
||||||
|
|
||||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
Read and follow [`AGENTS.md`](AGENTS.md). It is the runtime-neutral source of truth
|
||||||
|
for this repository. Scoped rules live in the nearest `AGENTS.md`; maintained
|
||||||
## Important: Design Guidelines
|
documentation is indexed by [`docs/index.md`](docs/index.md).
|
||||||
|
|
||||||
**Always read `apps/mobile/DESIGN.md` before making UI/UX changes to the mobile app.** This file contains the design system, visual language, and styling patterns that must be followed for consistency. Agents and subagents should read this file when:
|
|
||||||
- Creating new screens or components
|
|
||||||
- Modifying existing UI elements
|
|
||||||
- Adding animations or visual effects
|
|
||||||
- Working with colors, typography, or spacing
|
|
||||||
|
|
||||||
## Project Overview
|
|
||||||
|
|
||||||
Sauci is a couples relationship app that helps partners communicate better and grow closer together. Users swipe on thoughtful questions (yes/no/maybe), and when both partners answer positively, a "match" is created that unlocks a chat thread for that topic.
|
|
||||||
|
|
||||||
## Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Install dependencies (from root)
|
|
||||||
npm install
|
|
||||||
|
|
||||||
# Start all apps in development
|
|
||||||
npm run dev
|
|
||||||
|
|
||||||
# Run specific apps
|
|
||||||
cd apps/mobile && npm run dev # Expo mobile app
|
|
||||||
cd apps/admin && npm run dev # React Admin dashboard
|
|
||||||
|
|
||||||
# Type checking
|
|
||||||
npm run typecheck
|
|
||||||
|
|
||||||
# Linting
|
|
||||||
npm run lint
|
|
||||||
|
|
||||||
# Build all
|
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
|
|
||||||
### Mobile-specific commands
|
|
||||||
```bash
|
|
||||||
cd apps/mobile
|
|
||||||
npm run ios # Run on iOS simulator
|
|
||||||
npm run android # Run on Android emulator
|
|
||||||
npm run web # Run in browser
|
|
||||||
```
|
|
||||||
|
|
||||||
### Supabase commands
|
|
||||||
```bash
|
|
||||||
supabase start # Start local Supabase
|
|
||||||
supabase db reset # Reset DB and run all migrations
|
|
||||||
supabase functions serve # Run edge functions locally
|
|
||||||
supabase migration new <name> # Create new migration
|
|
||||||
```
|
|
||||||
|
|
||||||
### Supabase Environments
|
|
||||||
|
|
||||||
There are two Supabase projects configured via MCP servers:
|
|
||||||
|
|
||||||
| Environment | Project Ref | URL | MCP Server |
|
|
||||||
|-------------|-------------|-----|------------|
|
|
||||||
| **Production** | `ckjcrkjpmhqhiucifukx` | https://ckjcrkjpmhqhiucifukx.supabase.co | `sauci-prod` |
|
|
||||||
| **Non-Production** | `itbzhrvlgvdmzbnhzhyx` | https://itbzhrvlgvdmzbnhzhyx.supabase.co | `sauci-non-prod` |
|
|
||||||
|
|
||||||
When using Claude Code with MCP tools:
|
|
||||||
- Use `mcp__sauci-prod__*` tools for production database operations
|
|
||||||
- Use `mcp__sauci-non-prod__*` tools for development/staging database operations
|
|
||||||
- **Always verify which environment you're targeting before running destructive operations**
|
|
||||||
|
|
||||||
### Database Migrations - CRITICAL
|
|
||||||
|
|
||||||
> **STOP: Read this entire section before making ANY database schema change.**
|
|
||||||
|
|
||||||
#### The Golden Rule
|
|
||||||
|
|
||||||
**ALL schema changes MUST go through local migration files.** No exceptions.
|
|
||||||
|
|
||||||
#### Forbidden Actions
|
|
||||||
|
|
||||||
- **NEVER call `apply_migration` via MCP** (either `mcp__sauci-prod__apply_migration` or `mcp__sauci-non-prod__apply_migration`). This creates migration entries in the remote database with NO local file, which breaks `supabase db push` in CI and causes deployment failures that are painful to fix.
|
|
||||||
- **NEVER run DDL statements (`CREATE`, `ALTER`, `DROP`) via `execute_sql`**. This changes the schema without any migration tracking at all.
|
|
||||||
- **NEVER manually INSERT into `supabase_migrations.schema_migrations`** unless repairing a broken migration history (and only with explicit user approval).
|
|
||||||
|
|
||||||
#### Why This Matters
|
|
||||||
|
|
||||||
The CI/CD pipeline runs `supabase db push --include-all` which compares local migration files against the remote `schema_migrations` table. If the remote has migrations that don't exist locally, or local files exist without remote entries, the deployment **will fail** and block all subsequent deployments.
|
|
||||||
|
|
||||||
**A single `apply_migration` call can break deployments for the entire project.**
|
|
||||||
|
|
||||||
#### Correct Workflow for Schema Changes
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. Create migration file locally
|
|
||||||
supabase migration new <descriptive_name>
|
|
||||||
|
|
||||||
# 2. Edit the migration file in apps/supabase/migrations/
|
|
||||||
|
|
||||||
# 3. Make migrations idempotent where possible
|
|
||||||
# Use: CREATE OR REPLACE, IF NOT EXISTS, DROP IF EXISTS
|
|
||||||
# This prevents failures if re-run
|
|
||||||
|
|
||||||
# 4. Test locally
|
|
||||||
supabase db reset
|
|
||||||
|
|
||||||
# 5. Commit the migration file to git
|
|
||||||
|
|
||||||
# 6. Deploy happens automatically via CI on push to master
|
|
||||||
# OR deploy manually:
|
|
||||||
supabase link --project-ref <project_ref>
|
|
||||||
supabase db push
|
|
||||||
```
|
|
||||||
|
|
||||||
#### MCP Tools - What IS Allowed
|
|
||||||
|
|
||||||
- **Reading data:** `execute_sql` with SELECT queries only
|
|
||||||
- **Exploring schema:** `list_tables`, `list_migrations`, `list_extensions`
|
|
||||||
- **Deploying edge functions:** `deploy_edge_function`
|
|
||||||
- **Generating types:** `generate_typescript_types`
|
|
||||||
- **Checking advisors:** `get_advisors`
|
|
||||||
|
|
||||||
#### If You Accidentally Used `apply_migration`
|
|
||||||
|
|
||||||
If a migration was applied via MCP, you must immediately:
|
|
||||||
1. Retrieve the migration SQL from `schema_migrations.statements`
|
|
||||||
2. Create a matching local file: `apps/supabase/migrations/<version>_<name>.sql`
|
|
||||||
3. Commit and push the file so CI can reconcile
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
### Monorepo Structure (Turborepo)
|
|
||||||
- `apps/mobile` - Expo React Native app (expo-router for navigation)
|
|
||||||
- `apps/admin` - React Admin dashboard for content management
|
|
||||||
- `apps/supabase` - Database migrations and edge functions
|
|
||||||
- `packages/shared` - Shared TypeScript types (`@sauci/shared`)
|
|
||||||
|
|
||||||
### Mobile App Architecture
|
|
||||||
- **Routing**: Expo Router with file-based routing (`app/` directory)
|
|
||||||
- `(auth)/` - Authentication screens
|
|
||||||
- `(app)/` - Main app screens (protected)
|
|
||||||
- **State Management**: Zustand stores in `src/store/index.ts`
|
|
||||||
- `useAuthStore` - User, couple, partner state
|
|
||||||
- `useMatchStore` - Matches and notifications
|
|
||||||
- `usePacksStore` - Question packs and enabled packs per couple
|
|
||||||
- `useMessageStore` - Chat messages and unread counts
|
|
||||||
- `useSubscriptionStore` - RevenueCat subscription state
|
|
||||||
- **Backend**: Supabase client in `src/lib/supabase.ts`
|
|
||||||
- **UI Components**: Glass-morphism themed components in `src/components/ui/`
|
|
||||||
|
|
||||||
### Data Model (Core Entities)
|
|
||||||
- **Profile** - User profile extending Supabase auth (has `couple_id`)
|
|
||||||
- **Couple** - Two users linked via invite code
|
|
||||||
- **QuestionPack** - Collection of questions (can be premium)
|
|
||||||
- **Question** - Individual question with intensity level (1-5)
|
|
||||||
- **Response** - User's answer (yes/no/maybe) to a question
|
|
||||||
- **Match** - Created when both partners answer positively (yes_yes, yes_maybe, maybe_maybe)
|
|
||||||
|
|
||||||
### Edge Functions
|
|
||||||
Edge functions in `apps/supabase/functions/` handle complex operations:
|
|
||||||
- `submit-response` - Saves response, checks for matches, triggers notifications
|
|
||||||
- `manage-couple` - Join/leave couple operations
|
|
||||||
- `delete-relationship` - Deletes couple data (matches, messages, media) while keeping accounts
|
|
||||||
- `delete-account` - Permanently deletes user account and all associated data (Apple App Store requirement)
|
|
||||||
- `send-notification` - Push notifications for matches
|
|
||||||
- `send-nudge-notification` - Partner nudge notifications (rate limited to once per 12 hours)
|
|
||||||
- `send-unpaired-reminder` - Daily cron reminder for unpaired users to share invite code
|
|
||||||
- `send-catchup-reminder` - Daily cron reminder for "behind" partners with escalating frequency
|
|
||||||
- `revenuecat-webhook` - Subscription webhook handler
|
|
||||||
- `sync-subscription` - Syncs RevenueCat subscription status
|
|
||||||
- `redeem-code` - Redeems promotional codes for premium access (website only)
|
|
||||||
|
|
||||||
#### Edge Function Deployment Guidelines
|
|
||||||
When deploying edge functions via MCP tools (`mcp__sauci-*__deploy_edge_function`):
|
|
||||||
|
|
||||||
**IMPORTANT: Always use `verify_jwt: false`** for all edge functions. Supabase's built-in JWT verification causes 401 errors even with valid tokens. Instead, handle authentication manually in the function code using:
|
|
||||||
```typescript
|
|
||||||
const { data: { user }, error: authError } = await supabase.auth.getUser(
|
|
||||||
authHeader.replace("Bearer ", "")
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
This approach:
|
|
||||||
- Gives better error messages
|
|
||||||
- Allows custom auth handling
|
|
||||||
- Avoids mysterious 401 failures
|
|
||||||
|
|
||||||
**Current function settings (all should be verify_jwt: false):**
|
|
||||||
| Function | verify_jwt | Auth Method |
|
|
||||||
|----------|------------|-------------|
|
|
||||||
| `manage-couple` | false | Manual via getUser() |
|
|
||||||
| `submit-response` | false | Manual via getUser() |
|
|
||||||
| `sync-subscription` | false | Manual via getUser() |
|
|
||||||
| `delete-relationship` | false | Manual via getUser() |
|
|
||||||
| `delete-account` | false | Manual via getUser() |
|
|
||||||
| `redeem-code` | false | Manual via getUser() |
|
|
||||||
| `revenuecat-webhook` | false | Webhook signature validation |
|
|
||||||
| `send-notification` | false | Internal trigger (no auth) |
|
|
||||||
| `send-message-notification` | false | Internal trigger (no auth) |
|
|
||||||
| `send-nudge-notification` | false | Manual via getUser() |
|
|
||||||
| `send-unpaired-reminder` | false | Cron trigger (no auth) |
|
|
||||||
| `send-catchup-reminder` | false | Cron trigger (no auth) |
|
|
||||||
|
|
||||||
### Database Best Practices
|
|
||||||
- **Always use `.maybeSingle()` instead of `.single()`** when the row might not exist. `.single()` throws an error if 0 or >1 rows are returned.
|
|
||||||
- **Profile creation trigger**: The `on_auth_user_created` trigger automatically creates a profile when a user signs up. Never assume a profile exists without checking.
|
|
||||||
- **Check for null profiles** in edge functions before performing operations.
|
|
||||||
|
|
||||||
### Cron Jobs (pg_cron) - IMPORTANT
|
|
||||||
|
|
||||||
**NEVER hardcode Supabase URLs in cron job migrations.** Migrations run on both prod and non-prod, so a hardcoded production URL will cause non-prod cron jobs to hit production (double-firing notifications, duplicate processing, etc.).
|
|
||||||
|
|
||||||
**Correct pattern** — use `get_supabase_edge_function_url()`:
|
|
||||||
```sql
|
|
||||||
SELECT cron.schedule(
|
|
||||||
'my-cron-job',
|
|
||||||
'*/5 * * * *',
|
|
||||||
format(
|
|
||||||
$cmd$
|
|
||||||
SELECT net.http_post(
|
|
||||||
url := %L,
|
|
||||||
headers := jsonb_build_object('Content-Type', 'application/json'),
|
|
||||||
body := '{}'::jsonb
|
|
||||||
)
|
|
||||||
$cmd$,
|
|
||||||
get_supabase_edge_function_url('my-edge-function')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
This resolves the URL from `app_config.supabase_url` at migration-time, so each environment targets its own edge functions.
|
|
||||||
|
|
||||||
**If adding a new environment**, you must seed the URL before running migrations:
|
|
||||||
```sql
|
|
||||||
UPDATE app_config SET supabase_url = 'https://<project-ref>.supabase.co';
|
|
||||||
```
|
|
||||||
|
|
||||||
### Key Patterns
|
|
||||||
- Responses use UPSERT with `onConflict: "user_id,question_id"`
|
|
||||||
- Match detection happens in `submit-response` edge function after each response
|
|
||||||
- Real-time subscriptions used for chat messages
|
|
||||||
- RevenueCat handles in-app purchases and subscription management
|
|
||||||
- RLS policies enforce couple-level data isolation
|
|
||||||
|
|
||||||
### Redemption Code System
|
|
||||||
Promotional codes that grant users premium access. **Codes can only be redeemed on the website, NOT in the mobile app.**
|
|
||||||
|
|
||||||
**Database Tables:**
|
|
||||||
- `redemption_codes` - Stores codes with max_uses, current_uses, expiration, active status
|
|
||||||
- `code_redemptions` - Tracks which users redeemed which codes
|
|
||||||
|
|
||||||
**Components:**
|
|
||||||
- **Admin UI** (`apps/admin/src/pages/RedemptionCodesPage.tsx`) - Super admins can generate, manage, and view redemption codes
|
|
||||||
- **Edge Function** (`apps/supabase/functions/redeem-code/`) - Validates and processes code redemption (unauthenticated, accepts email + code)
|
|
||||||
- **Database Function** (`redeem_code_by_email(p_email, p_code)`) - Atomic redemption with validation (active, not expired, has uses remaining, user hasn't redeemed)
|
|
||||||
- **Web UI** (`apps/web/app/redeem/page.tsx`) - Public redemption page
|
|
||||||
|
|
||||||
**Flow:**
|
|
||||||
1. Admin generates code in admin dashboard
|
|
||||||
2. User visits `/redeem` on website and enters email + code
|
|
||||||
3. `redeem-code` edge function calls `redeem_code_by_email()` database function
|
|
||||||
4. Database function looks up user by email, validates code, and sets `profiles.is_premium = true`
|
|
||||||
|
|
||||||
**Important:** Do NOT add redemption code UI to the mobile app. Apple requires in-app purchases for premium features purchased within iOS apps.
|
|
||||||
|
|
||||||
## Mobile UI - DO NOT CHANGE
|
|
||||||
|
|
||||||
### Tab Bar Background
|
|
||||||
**NEVER set `backgroundColor: 'transparent'` on the tab bar.** Always use a semi-transparent solid color:
|
|
||||||
```typescript
|
|
||||||
backgroundColor: 'rgba(18, 18, 18, 0.85)',
|
|
||||||
```
|
|
||||||
|
|
||||||
The `BlurView` in `tabBarBackground` is unreliable and can fail during re-renders/transitions, causing a fully transparent tab bar. The solid rgba background acts as a fallback while still allowing the blur effect on top.
|
|
||||||
|
|
||||||
**Location:** `apps/mobile/app/(app)/_layout.tsx` - `tabBarStyle`
|
|
||||||
|
|
||||||
## Infrastructure as Code (Terraform)
|
|
||||||
|
|
||||||
Supabase project configuration is managed via Terraform in the `terraform/` directory. This includes auth settings, OAuth providers, email templates, SMTP config, rate limits, and more.
|
|
||||||
|
|
||||||
**Directory structure:**
|
|
||||||
```
|
|
||||||
terraform/
|
|
||||||
├── modules/
|
|
||||||
│ └── supabase/ # Shared configuration module
|
|
||||||
│ ├── main.tf
|
|
||||||
│ ├── variables.tf
|
|
||||||
│ ├── outputs.tf
|
|
||||||
│ └── templates/ # Email templates
|
|
||||||
└── environments/
|
|
||||||
├── prod/ # Production (ckjcrkjpmhqhiucifukx)
|
|
||||||
└── non-prod/ # Non-production (itbzhrvlgvdmzbnhzhyx)
|
|
||||||
```
|
|
||||||
|
|
||||||
**When to update Terraform:**
|
|
||||||
- Changing auth settings (OAuth providers, JWT expiry, MFA settings)
|
|
||||||
- Modifying email templates or subjects
|
|
||||||
- Updating rate limits or security settings
|
|
||||||
- Changing SMTP configuration
|
|
||||||
- Modifying storage or API settings
|
|
||||||
|
|
||||||
**Workflow (always test in non-prod first):**
|
|
||||||
```bash
|
|
||||||
# 1. Apply to non-prod first
|
|
||||||
cd terraform/environments/non-prod
|
|
||||||
export TF_VAR_supabase_access_token=sbp_xxxxx
|
|
||||||
terraform plan
|
|
||||||
terraform apply
|
|
||||||
|
|
||||||
# 2. Verify changes work in non-prod
|
|
||||||
|
|
||||||
# 3. Apply to prod
|
|
||||||
cd terraform/environments/prod
|
|
||||||
terraform plan
|
|
||||||
terraform apply
|
|
||||||
```
|
|
||||||
|
|
||||||
**Important:** After making Terraform changes, remind the user to:
|
|
||||||
1. Commit the updated `terraform/` files
|
|
||||||
2. The GitHub Action will auto-apply on merge to master (non-prod first, then prod)
|
|
||||||
|
|
||||||
**Do NOT use Terraform for:**
|
|
||||||
- Database schema changes (use migrations)
|
|
||||||
- Edge function deployment (use CLI or MCP)
|
|
||||||
- Storage bucket creation (use migrations)
|
|
||||||
|
|
||||||
## Edge Function Secrets
|
|
||||||
|
|
||||||
Edge functions use secrets stored in Supabase. These are synced from GitHub Secrets during CI/CD deployment.
|
|
||||||
|
|
||||||
**Current secrets:**
|
|
||||||
| Secret | Used By | Description |
|
|
||||||
|--------|---------|-------------|
|
|
||||||
| `REVENUECAT_WEBHOOK_SECRET` | revenuecat-webhook | Webhook signature validation |
|
|
||||||
| `REVENUECAT_API_KEY` | sync-subscription | RevenueCat API access |
|
|
||||||
| `REVENUECAT_ENTITLEMENT_ID` | sync-subscription | Entitlement identifier |
|
|
||||||
| `OPENROUTER_API_KEY` | classify-message | AI classification API |
|
|
||||||
| `ADMIN_PRIVATE_KEY_JWK` | admin-decrypt-* | E2EE admin decryption |
|
|
||||||
| `ADMIN_KEYS_JSON` | admin-decrypt-*, migrate-e2ee | Multiple admin keys |
|
|
||||||
| `DISCORD_WEBHOOK_URL` | send-discord-notification | Discord notifications |
|
|
||||||
|
|
||||||
**Auto-provided by Supabase (don't set):**
|
|
||||||
- `SUPABASE_URL`
|
|
||||||
- `SUPABASE_ANON_KEY`
|
|
||||||
- `SUPABASE_SERVICE_ROLE_KEY`
|
|
||||||
|
|
||||||
**When adding a new edge function that needs secrets:**
|
|
||||||
1. Add the secret to the edge function code: `Deno.env.get("SECRET_NAME")`
|
|
||||||
2. Update `.github/workflows/deploy-supabase.yml` to include the new secret in the sync step
|
|
||||||
3. Update `apps/supabase/functions/.secrets.example` with the new secret
|
|
||||||
4. **Remind the user** to add the secret to GitHub Secrets (Settings → Secrets → Actions)
|
|
||||||
5. Update this table in CLAUDE.md
|
|
||||||
|
|
||||||
**Local development:**
|
|
||||||
```bash
|
|
||||||
cp apps/supabase/functions/.secrets.example apps/supabase/functions/.secrets
|
|
||||||
# Fill in values
|
|
||||||
supabase functions serve --env-file apps/supabase/functions/.secrets
|
|
||||||
```
|
|
||||||
@@ -1,90 +1,51 @@
|
|||||||
# Sauci
|
# Sauci
|
||||||
|
|
||||||

|
Sauci is a couples connection product built as a full-stack npm/Turborepo
|
||||||

|
workspace.
|
||||||

|
|
||||||
|
|
||||||
Sauci is a couples intimacy app where partners swipe question packs, match on shared interests, and chat about what they unlock together.
|
## Applications
|
||||||
|
|
||||||
## What lives here
|
| Path | Surface |
|
||||||
|
|---|---|
|
||||||
|
| `apps/mobile` | Expo React Native customer app |
|
||||||
|
| `apps/admin` | Vite/React administration app |
|
||||||
|
| `apps/web` | Next.js marketing and redemption app |
|
||||||
|
| `apps/supabase` | database, auth, realtime, storage, and Edge Functions |
|
||||||
|
| `apps/mcp` | authenticated internal MCP service |
|
||||||
|
| `packages/shared` | shared TypeScript contracts |
|
||||||
|
|
||||||
```
|
## Bootstrap and run
|
||||||
sauci/
|
|
||||||
├── apps/
|
|
||||||
│ ├── mobile/ # Expo React Native app
|
|
||||||
│ ├── admin/ # Admin dashboard (Vite + React)
|
|
||||||
│ ├── web/ # Marketing website (Next.js)
|
|
||||||
│ └── supabase/ # Supabase project (migrations, edge functions)
|
|
||||||
├── packages/
|
|
||||||
│ └── shared/ # Shared TypeScript types
|
|
||||||
```
|
|
||||||
|
|
||||||
## Core product flows
|
Use Node `20.10.0` from `.nvmrc`, Docker-compatible containers, and tmux.
|
||||||
|
|
||||||
- **Couple pairing** via invite codes and profile linking
|
|
||||||
- **Question packs** with two-part phrasing and smart selection bias
|
|
||||||
- **Matches + chat** when both partners answer positively
|
|
||||||
- **Notifications** for new matches and messages
|
|
||||||
- **Subscriptions** via RevenueCat with couple-level premium sharing
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
- Node.js 20+
|
|
||||||
- npm 10+
|
|
||||||
- Supabase CLI (`npm install -g supabase`)
|
|
||||||
- Expo CLI (`npm install -g expo-cli`)
|
|
||||||
|
|
||||||
## Quickstart
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install
|
npm ci
|
||||||
npm run dev
|
scripts/dev-local.sh reset
|
||||||
|
scripts/dev-local.sh up
|
||||||
```
|
```
|
||||||
|
|
||||||
## App commands
|
The launcher starts local Supabase, Edge Functions, web, admin, MCP, and Expo in
|
||||||
|
one tmux session. See [local stack documentation](docs/development/local-stack.md)
|
||||||
|
for ports, logs, native launch commands, and troubleshooting.
|
||||||
|
|
||||||
From each app directory:
|
## Verify
|
||||||
|
|
||||||
- **Mobile** (`apps/mobile`): `npm run dev`, `npm run ios`, `npm run android`, `npm run web`
|
```bash
|
||||||
- **Admin** (`apps/admin`): `npm run dev`, `npm run build`, `npm run typecheck`
|
npm run verify:fast # lint, typecheck, unit/contract tests
|
||||||
- **Web** (`apps/web`): `npm run dev`, `npm run build`, `npm run start`
|
npm run verify:full # fast checks, builds, Supabase integration
|
||||||
|
npm run verify:e2e # running-stack Playwright journeys
|
||||||
|
npm run verify # complete pre-PR gate
|
||||||
|
```
|
||||||
|
|
||||||
## Environment setup
|
Native black-box flows use `npm run test:mobile:e2e`. Pull requests run static
|
||||||
|
and full-stack gates and retain browser traces/screenshots/videos on failure.
|
||||||
|
|
||||||
Copy the example files and fill in values:
|
## Agent harness
|
||||||
|
|
||||||
- Mobile: `apps/mobile/.env.example`
|
Start with [AGENTS.md](AGENTS.md) and [the documentation index](docs/index.md).
|
||||||
- Admin: `apps/admin/.env.example`
|
Task/risk agent routing lives in [docs/agents/routing.md](docs/agents/routing.md),
|
||||||
- Web: `apps/web/.env.local.example`
|
repository skills live under `.codex/skills`, and verified lessons follow the
|
||||||
|
[learning promotion lifecycle](docs/agents/learnings.md).
|
||||||
## Supabase (local)
|
|
||||||
|
|
||||||
- Config lives in `apps/supabase/config.toml`.
|
|
||||||
- Use the Supabase CLI for local services and migrations.
|
|
||||||
|
|
||||||
## Scripts (root)
|
|
||||||
|
|
||||||
- `npm run dev` - run all apps in dev mode
|
|
||||||
- `npm run build` - build all apps
|
|
||||||
- `npm run lint` - lint all apps
|
|
||||||
- `npm run typecheck` - typecheck all apps
|
|
||||||
- `npm run clean` - clean build artifacts
|
|
||||||
|
|
||||||
## Docs
|
|
||||||
|
|
||||||
- Auth: `docs/authentication.md`
|
|
||||||
- Schema: `docs/schema.md`
|
|
||||||
- Pairing: `docs/couple-pairing.md`
|
|
||||||
- Questions: `docs/question-selection.md`
|
|
||||||
- Matches/notifications: `docs/match-notifications.md`
|
|
||||||
- Subscriptions: `docs/subscription-system.md`
|
|
||||||
- Mobile release guide: `apps/mobile/RELEASING.md`
|
|
||||||
|
|
||||||
## Tech stack
|
|
||||||
|
|
||||||
- **Mobile**: Expo (React Native)
|
|
||||||
- **Backend**: Supabase (Postgres, Auth, Edge Functions, Realtime)
|
|
||||||
- **Admin**: React + Vite
|
|
||||||
- **Web**: Next.js
|
|
||||||
- **Monorepo**: Turborepo
|
|
||||||
|
|
||||||
|
Database schema changes must use committed files in `apps/supabase/migrations`.
|
||||||
|
Remote migration tools and DDL through MCP SQL execution are forbidden.
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Admin application
|
||||||
|
|
||||||
|
Vite/React administration UI. Use existing layout, route, and Supabase client
|
||||||
|
patterns before introducing abstractions.
|
||||||
|
|
||||||
|
- `pack_creator` manages permitted content; `super_admin` can access privileged
|
||||||
|
user/admin/audit surfaces.
|
||||||
|
- Enforce role checks in both route visibility and the backend/RLS boundary.
|
||||||
|
- Administrative mutations must remain auditable.
|
||||||
|
- Use `.maybeSingle()` when zero rows are valid.
|
||||||
|
- Never expose credentials, tokens, or private user content unnecessarily.
|
||||||
|
- Add accessible labels and a focused test for changed behavior.
|
||||||
|
- Verify with `npm run lint -w @sauci/admin`, `npm run typecheck -w
|
||||||
|
@sauci/admin`, and `npm run build -w @sauci/admin`.
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
# Admin Dashboard - Agent Guidelines
|
|
||||||
|
|
||||||
**STRICT RULES - DO NOT VIOLATE**
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
This is a React Admin dashboard using:
|
|
||||||
- **Build**: Vite
|
|
||||||
- **Routing**: react-router-dom with component-based routing in `App.tsx`
|
|
||||||
- **Styling**: Tailwind CSS
|
|
||||||
- **State**: React Context (`AuthContext`)
|
|
||||||
- **Backend**: Supabase client in `src/lib/supabase.ts`
|
|
||||||
|
|
||||||
## Directory Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
src/
|
|
||||||
components/ # Reusable components
|
|
||||||
layout/ # AppLayout, Sidebar, etc.
|
|
||||||
ProtectedRoute.tsx # Route guard
|
|
||||||
contexts/ # React contexts (AuthContext)
|
|
||||||
hooks/ # Custom hooks
|
|
||||||
lib/ # Utilities (supabase)
|
|
||||||
pages/ # Page components
|
|
||||||
content/ # Categories, Packs, Questions
|
|
||||||
users/ # User management (super_admin only)
|
|
||||||
admins/ # Admin management (super_admin only)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Critical Rules
|
|
||||||
|
|
||||||
### Authentication & Authorization
|
|
||||||
|
|
||||||
Two admin roles exist:
|
|
||||||
- `admin` - Content management only (categories, packs, questions)
|
|
||||||
- `super_admin` - Full access including user data, admins, audit logs
|
|
||||||
|
|
||||||
Use `<ProtectedRoute requireSuperAdmin>` for super_admin-only routes.
|
|
||||||
|
|
||||||
### Route Structure
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Public
|
|
||||||
/login
|
|
||||||
|
|
||||||
// Protected (all admins)
|
|
||||||
/ # Dashboard
|
|
||||||
/categories # Category management
|
|
||||||
/categories/:id/packs # Packs in category
|
|
||||||
/packs/:id/questions # Questions in pack
|
|
||||||
|
|
||||||
// Protected (super_admin only)
|
|
||||||
/users # User list
|
|
||||||
/users/:id # User detail
|
|
||||||
/users/:id/matches/:id # Match chat view
|
|
||||||
/admins # Admin management
|
|
||||||
/audit-logs # Audit log viewer
|
|
||||||
```
|
|
||||||
|
|
||||||
### Supabase Queries
|
|
||||||
|
|
||||||
- **Always use `.maybeSingle()` instead of `.single()`** when the row might not exist
|
|
||||||
- All admin operations are audited - check `audit_logs` table structure
|
|
||||||
|
|
||||||
### UI Patterns
|
|
||||||
|
|
||||||
- Use Tailwind CSS for styling
|
|
||||||
- Follow existing component patterns in `src/components/`
|
|
||||||
- Use `AppLayout` wrapper for all protected pages
|
|
||||||
|
|
||||||
### Security
|
|
||||||
|
|
||||||
- Never expose user passwords or sensitive data in admin views
|
|
||||||
- Audit log all administrative actions
|
|
||||||
- Verify admin role before performing operations
|
|
||||||
|
|
||||||
## Forbidden Actions
|
|
||||||
|
|
||||||
1. **DO NOT** expose user passwords or auth tokens
|
|
||||||
2. **DO NOT** allow content admins to access user data
|
|
||||||
3. **DO NOT** bypass role checks in protected routes
|
|
||||||
4. **DO NOT** perform destructive operations without confirmation
|
|
||||||
5. **DO NOT** use `.single()` for queries that might return 0 rows
|
|
||||||
6. **DO NOT** skip audit logging for administrative actions
|
|
||||||
@@ -4,9 +4,11 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"typecheck": "tsc --noEmit",
|
"lint": "tsc --noEmit",
|
||||||
|
"test": "vitest run --passWithNoTests",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# Internal MCP service
|
||||||
|
|
||||||
|
Hono service exposing privileged administrative tools.
|
||||||
|
|
||||||
|
- Treat the service-role key and `SAUCI_MCP_API_KEY` as secrets.
|
||||||
|
- Fail closed when MCP authentication is missing outside explicit local mode.
|
||||||
|
- Every mutation validates inputs, authorizes the operation, and writes audit
|
||||||
|
evidence where the product contract requires it.
|
||||||
|
- Read operations preserve least privilege and avoid excessive user data.
|
||||||
|
- Add unit/API coverage for tool contract or auth changes.
|
||||||
|
- Verify lint, tests, typecheck, build, and `/health` locally.
|
||||||
Generated
-2785
File diff suppressed because it is too large.
Load diff
@@ -5,10 +5,13 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "tsx watch src/index.ts",
|
"dev": "tsx watch src/index.ts",
|
||||||
"build": "tsup src/index.ts src/bridge.ts --format esm --clean",
|
"build": "tsup src/index.ts src/bridge.ts --format esm --clean",
|
||||||
|
"lint": "tsc --noEmit",
|
||||||
|
"test": "vitest run --passWithNoTests",
|
||||||
"start": "node dist/index.mjs",
|
"start": "node dist/index.mjs",
|
||||||
"typecheck": "tsc --noEmit"
|
"typecheck": "tsc --noEmit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@hono/node-server": "^1.13.7",
|
||||||
"@hono/mcp": "^0.1.1",
|
"@hono/mcp": "^0.1.1",
|
||||||
"@modelcontextprotocol/sdk": "^1.0.1",
|
"@modelcontextprotocol/sdk": "^1.0.1",
|
||||||
"@supabase/supabase-js": "^2.45.0",
|
"@supabase/supabase-js": "^2.45.0",
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import { Hono } from 'hono';
|
||||||
|
import { afterEach, describe, expect, it } from 'vitest';
|
||||||
|
import { authMiddleware } from './auth.js';
|
||||||
|
|
||||||
|
function app() {
|
||||||
|
const instance = new Hono();
|
||||||
|
instance.use('/mcp', authMiddleware);
|
||||||
|
instance.get('/mcp', (c) => c.json({ ok: true }));
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
delete process.env.SAUCI_MCP_API_KEY;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('MCP authentication', () => {
|
||||||
|
it('fails closed when the server key is missing', async () => {
|
||||||
|
const response = await app().request('/mcp');
|
||||||
|
expect(response.status).toBe(503);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('requires and validates a bearer token', async () => {
|
||||||
|
process.env.SAUCI_MCP_API_KEY = 'local-test-key';
|
||||||
|
expect((await app().request('/mcp')).status).toBe(401);
|
||||||
|
expect((await app().request('/mcp', {
|
||||||
|
headers: { Authorization: 'Bearer wrong' },
|
||||||
|
})).status).toBe(401);
|
||||||
|
expect((await app().request('/mcp', {
|
||||||
|
headers: { Authorization: 'Bearer local-test-key' },
|
||||||
|
})).status).toBe(200);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,24 +1,20 @@
|
|||||||
import { Context, Next } from 'hono';
|
import { Context, Next } from 'hono';
|
||||||
|
|
||||||
export const authMiddleware = async (c: Context, next: Next) => {
|
export const authMiddleware = async (c: Context, next: Next) => {
|
||||||
const authHeader = c.req.header('Authorization');
|
|
||||||
const apiKey = process.env.SAUCI_MCP_API_KEY;
|
const apiKey = process.env.SAUCI_MCP_API_KEY;
|
||||||
|
|
||||||
if (!apiKey) {
|
if (!apiKey) {
|
||||||
// If no API key is set in env, allow access (warn in logs)
|
console.error('SAUCI_MCP_API_KEY is not configured; refusing MCP access');
|
||||||
// Ideally this should default to deny, but for dev ease we might want to warn
|
return c.json({ error: 'Service authentication is not configured' }, 503);
|
||||||
console.warn('SAUCI_MCP_API_KEY not set in environment - allowing all requests');
|
|
||||||
return next();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let token = c.req.header('Authorization')?.replace('Bearer ', '');
|
const authHeader = c.req.header('Authorization');
|
||||||
|
const token = authHeader?.startsWith('Bearer ')
|
||||||
if (!token) {
|
? authHeader.slice('Bearer '.length)
|
||||||
token = c.req.query('apiKey');
|
: undefined;
|
||||||
}
|
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return c.json({ error: 'Unauthorized: Missing or invalid Authorization header or apiKey query param' }, 401);
|
return c.json({ error: 'Unauthorized: Bearer token required' }, 401);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token !== apiKey) {
|
if (token !== apiKey) {
|
||||||
|
|||||||
@@ -2,4 +2,10 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
extends: 'expo',
|
extends: 'expo',
|
||||||
ignorePatterns: ['/dist/*'],
|
ignorePatterns: ['/dist/*'],
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: ['plugins/**/*.js'],
|
||||||
|
env: { node: true },
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# Mobile application
|
||||||
|
|
||||||
|
Expo React Native with Expo Router, Zustand, Supabase, RevenueCat, Firebase, and
|
||||||
|
native iOS/Android targets.
|
||||||
|
|
||||||
|
- Read `DESIGN.md` before UI changes.
|
||||||
|
- Routes belong under `app`; feature logic belongs under `src/features`.
|
||||||
|
- Reuse existing Zustand stores and clear user-scoped state during sign-out.
|
||||||
|
- Check RevenueCat availability before native purchase operations.
|
||||||
|
- Use `.maybeSingle()` when zero rows are valid and handle nullable profiles.
|
||||||
|
- Keep route files thin; extract focused components/hooks when responsibilities
|
||||||
|
diverge rather than enforcing a mechanical line limit.
|
||||||
|
- Add stable accessibility labels or `testID` values for critical interactions.
|
||||||
|
- Verify focused Jest tests, typecheck, lint, then native/Expo behavior as risk
|
||||||
|
requires. UI work needs observable simulator evidence.
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
# Mobile App - Agent Guidelines
|
|
||||||
|
|
||||||
**STRICT RULES - DO NOT VIOLATE**
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
This is an Expo React Native app using:
|
|
||||||
- **Routing**: expo-router with file-based routing in `app/` directory
|
|
||||||
- **State**: Zustand stores in `src/store/index.ts`
|
|
||||||
- **Backend**: Supabase client in `src/lib/supabase.ts`
|
|
||||||
|
|
||||||
Design guidance lives in `apps/mobile/DESIGN.md`.
|
|
||||||
|
|
||||||
## Directory Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
app/ # Expo Router routes
|
|
||||||
(auth)/ # Authentication screens
|
|
||||||
(app)/ # Protected app screens (tabs)
|
|
||||||
src/
|
|
||||||
components/ # Reusable components
|
|
||||||
ui/
|
|
||||||
lib/ # Utilities (supabase, analytics, revenuecat)
|
|
||||||
store/ # Zustand stores (index.ts)
|
|
||||||
theme/
|
|
||||||
types/ # TypeScript types
|
|
||||||
```
|
|
||||||
|
|
||||||
## Critical Rules
|
|
||||||
|
|
||||||
### File Size
|
|
||||||
|
|
||||||
- Keep files small: aim for 200-300 lines max per file.
|
|
||||||
|
|
||||||
### State Management
|
|
||||||
|
|
||||||
- Use existing Zustand stores: `useAuthStore`, `useMatchStore`, `usePacksStore`, `useMessageStore`, `useSubscriptionStore`
|
|
||||||
- Access cross-store state via `getState()` (e.g., `useAuthStore.getState().user`)
|
|
||||||
- Clear related stores on sign out (see `signOut` in `useAuthStore`)
|
|
||||||
|
|
||||||
### Supabase Queries
|
|
||||||
|
|
||||||
- **Always use `.maybeSingle()` instead of `.single()`** when the row might not exist
|
|
||||||
- `.single()` throws an error if 0 or >1 rows are returned
|
|
||||||
- Check for null before performing operations
|
|
||||||
|
|
||||||
### Response Handling
|
|
||||||
|
|
||||||
- Responses use UPSERT with `onConflict: "user_id,question_id"`
|
|
||||||
- Match detection happens in `submit-response` edge function
|
|
||||||
|
|
||||||
### Typing
|
|
||||||
|
|
||||||
- Import shared types from `@/types`
|
|
||||||
- Import Supabase types from `@/types/supabase`
|
|
||||||
|
|
||||||
### RevenueCat
|
|
||||||
|
|
||||||
- RevenueCat service in `src/lib/revenuecat.ts`
|
|
||||||
- Does not work in Expo Go - check `revenueCatService.isAvailable()` first
|
|
||||||
- Initialize with user ID after auth
|
|
||||||
|
|
||||||
### Analytics
|
|
||||||
|
|
||||||
- Use `Events` from `src/lib/analytics` for tracking
|
|
||||||
- Track: `packEnabled`, `packDisabled`, `signOut`, etc.
|
|
||||||
|
|
||||||
## Forbidden Actions
|
|
||||||
|
|
||||||
1. **DO NOT** use `.single()` for queries that might return 0 rows
|
|
||||||
2. **DO NOT** create new stores without integrating with auth sign-out cleanup
|
|
||||||
3. **DO NOT** bypass RevenueCat availability checks
|
|
||||||
4. **DO NOT** add navigation logic outside of expo-router
|
|
||||||
Generated
-16696
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,25 @@
|
|||||||
|
# Supabase backend
|
||||||
|
|
||||||
|
This directory owns local configuration, migrations, Edge Functions, seeds, and
|
||||||
|
integration tests.
|
||||||
|
|
||||||
|
## Schema safety
|
||||||
|
|
||||||
|
- Create migrations only with `npm run db:migration:new -- <name>`.
|
||||||
|
- Edit only `apps/supabase/migrations/`; this is the authoritative migration tree.
|
||||||
|
- Never use any remote `apply_migration` tool.
|
||||||
|
- Never execute DDL through MCP SQL tools; those tools are `SELECT`-only.
|
||||||
|
- Never link or reset a remote project during local verification.
|
||||||
|
- Cron/function URLs must resolve per environment, never hardcode production.
|
||||||
|
|
||||||
|
## Function boundaries
|
||||||
|
|
||||||
|
- Set deployment JWT configuration deliberately per function. A function using
|
||||||
|
`verify_jwt = false` must implement the correct manual, webhook, cron, or internal
|
||||||
|
authentication boundary; it is not permission to omit authorization.
|
||||||
|
- Service-role clients never run in customer clients.
|
||||||
|
- Preserve CORS handling and return non-sensitive errors.
|
||||||
|
- Test RLS, authorization, and important side effects, not only HTTP status.
|
||||||
|
|
||||||
|
Verify with local reset, `npm run test:supabase`, invariant lint, and affected
|
||||||
|
client tests. See `docs/operations/database-migrations.md`.
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
# Supabase - Agent Guidelines
|
|
||||||
|
|
||||||
**STRICT RULES - DO NOT VIOLATE**
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
This contains Supabase configuration:
|
|
||||||
- **Migrations**: SQL migrations in `migrations/`
|
|
||||||
- **Edge Functions**: Deno functions in `functions/`
|
|
||||||
- **Email Templates**: Auth email templates in `email-templates/`
|
|
||||||
- **Config**: Local development config in `config.toml`
|
|
||||||
|
|
||||||
## Directory Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
functions/
|
|
||||||
delete-relationship/ # Delete couple relationship
|
|
||||||
manage-couple/ # Join/leave couple
|
|
||||||
revenuecat-webhook/ # Subscription webhook handler
|
|
||||||
send-message-notification/ # Push notification for messages
|
|
||||||
send-notification/ # Push notification for matches
|
|
||||||
submit-response/ # Save response, check matches
|
|
||||||
sync-subscription/ # Sync RevenueCat status
|
|
||||||
migrations/ # SQL migrations
|
|
||||||
email-templates/ # Auth email templates
|
|
||||||
config.toml # Local dev configuration
|
|
||||||
```
|
|
||||||
|
|
||||||
## Critical Rules
|
|
||||||
|
|
||||||
### Edge Function Deployment
|
|
||||||
|
|
||||||
**ALWAYS use `verify_jwt: false`** when deploying via MCP tools.
|
|
||||||
|
|
||||||
Supabase's built-in JWT verification causes 401 errors. Handle auth manually:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const { data: { user }, error: authError } = await supabase.auth.getUser(
|
|
||||||
authHeader.replace("Bearer ", "")
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Edge Function Pattern
|
|
||||||
|
|
||||||
All edge functions MUST follow this structure:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import "jsr:@supabase/functions-js/edge-runtime.d.ts";
|
|
||||||
import { createClient } from "https://esm.sh/@supabase/supabase-js@2";
|
|
||||||
|
|
||||||
const corsHeaders = {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",
|
|
||||||
};
|
|
||||||
|
|
||||||
Deno.serve(async (req) => {
|
|
||||||
// Handle CORS preflight
|
|
||||||
if (req.method === "OPTIONS") {
|
|
||||||
return new Response("ok", { headers: corsHeaders });
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const supabase = createClient(
|
|
||||||
Deno.env.get("SUPABASE_URL")!,
|
|
||||||
Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!
|
|
||||||
);
|
|
||||||
|
|
||||||
// Manual auth verification
|
|
||||||
const authHeader = req.headers.get("Authorization");
|
|
||||||
if (!authHeader) {
|
|
||||||
return new Response(
|
|
||||||
JSON.stringify({ error: "Missing authorization header" }),
|
|
||||||
{ status: 401, headers: { ...corsHeaders, "Content-Type": "application/json" } }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data: { user }, error: authError } = await supabase.auth.getUser(
|
|
||||||
authHeader.replace("Bearer ", "")
|
|
||||||
);
|
|
||||||
|
|
||||||
// ... function logic
|
|
||||||
} catch (error) {
|
|
||||||
return new Response(
|
|
||||||
JSON.stringify({ error: "Internal server error" }),
|
|
||||||
{ status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Function Auth Methods
|
|
||||||
|
|
||||||
| Function | Auth Method |
|
|
||||||
|----------|-------------|
|
|
||||||
| `manage-couple` | Manual via getUser() |
|
|
||||||
| `submit-response` | Manual via getUser() |
|
|
||||||
| `sync-subscription` | Manual via getUser() |
|
|
||||||
| `delete-relationship` | Manual via getUser() |
|
|
||||||
| `revenuecat-webhook` | Webhook signature validation |
|
|
||||||
| `send-notification` | Internal trigger (no auth) |
|
|
||||||
| `send-message-notification` | Internal trigger (no auth) |
|
|
||||||
|
|
||||||
### Migration Rules
|
|
||||||
|
|
||||||
- Use `apply_migration` MCP tool for DDL operations
|
|
||||||
- Never hardcode generated IDs in data migrations
|
|
||||||
- Always verify target environment (prod vs non-prod) before running
|
|
||||||
|
|
||||||
### Database Patterns
|
|
||||||
|
|
||||||
- Use UPSERT with `onConflict` for responses: `onConflict: "user_id,question_id"`
|
|
||||||
- Use UPSERT for matches: `onConflict: "couple_id,question_id"`
|
|
||||||
- RLS policies enforce couple-level data isolation
|
|
||||||
|
|
||||||
### Profile Creation
|
|
||||||
|
|
||||||
The `on_auth_user_created` trigger automatically creates a profile. Never assume a profile exists without checking - check for null before operations.
|
|
||||||
|
|
||||||
## MCP Environments
|
|
||||||
|
|
||||||
| Environment | MCP Server |
|
|
||||||
|-------------|------------|
|
|
||||||
| Production | `mcp__sauci-prod__*` |
|
|
||||||
| Non-Production | `mcp__sauci-non-prod__*` |
|
|
||||||
|
|
||||||
**ALWAYS verify environment before destructive operations.**
|
|
||||||
|
|
||||||
## Forbidden Actions
|
|
||||||
|
|
||||||
1. **DO NOT** use `verify_jwt: true` when deploying functions via MCP
|
|
||||||
2. **DO NOT** skip CORS headers in responses
|
|
||||||
3. **DO NOT** use service role key on client-side
|
|
||||||
4. **DO NOT** hardcode IDs in migrations
|
|
||||||
5. **DO NOT** assume profiles exist - always check for null
|
|
||||||
6. **DO NOT** run migrations on production without explicit confirmation
|
|
||||||
7. **DO NOT** expose internal error details in responses
|
|
||||||
@@ -1,5 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "@sauci/supabase",
|
"name": "@sauci/supabase",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"private": true
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"lint": "node ../../scripts/lint-harness.mjs --scope supabase",
|
||||||
|
"test": "node -e \"console.log('Supabase integration tests run through npm run test:supabase')\"",
|
||||||
|
"typecheck": "node -e \"console.log('Edge Functions are checked by Deno during test:supabase')\"",
|
||||||
|
"build": "node -e \"console.log('Supabase deployables do not require a build step')\""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ export async function createRedemptionCode() {
|
|||||||
const { data, error } = await adminClient.from("redemption_codes").insert({
|
const { data, error } = await adminClient.from("redemption_codes").insert({
|
||||||
code,
|
code,
|
||||||
max_uses: 1,
|
max_uses: 1,
|
||||||
active: true,
|
is_active: true,
|
||||||
expires_at: new Date(Date.now() + 3600000).toISOString() // 1 hour
|
expires_at: new Date(Date.now() + 3600000).toISOString() // 1 hour
|
||||||
}).select().single();
|
}).select().single();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": "next/core-web-vitals"
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# Web application
|
||||||
|
|
||||||
|
Next.js App Router marketing, legal, and redemption UI.
|
||||||
|
|
||||||
|
- Prefer server components; add `use client` only when browser state is needed.
|
||||||
|
- Preserve PostHog provider/page-view integration unless the task changes it.
|
||||||
|
- Keep metadata current for public pages.
|
||||||
|
- Never expose server credentials through `NEXT_PUBLIC_*` variables.
|
||||||
|
- Public redemption must use sandbox/local Supabase during automated tests.
|
||||||
|
- Verify lint, typecheck, build, and the relevant Playwright flow.
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
# Web App - Agent Guidelines
|
|
||||||
|
|
||||||
**STRICT RULES - DO NOT VIOLATE**
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
This is a Next.js 14+ marketing/landing website using:
|
|
||||||
- **Framework**: Next.js with App Router
|
|
||||||
- **Styling**: Tailwind CSS
|
|
||||||
- **Analytics**: PostHog
|
|
||||||
- **Routing**: File-based routing in `app/` directory
|
|
||||||
|
|
||||||
## Directory Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
app/
|
|
||||||
layout.tsx # Root layout with PostHog provider
|
|
||||||
page.tsx # Home/landing page
|
|
||||||
globals.css # Global styles
|
|
||||||
providers.tsx # PostHog provider wrapper
|
|
||||||
PostHogPageView.tsx # Page view tracking component
|
|
||||||
privacy/ # Privacy policy
|
|
||||||
terms/ # Terms of service
|
|
||||||
redeem/ # Code redemption page
|
|
||||||
components/ # Reusable components
|
|
||||||
public/ # Static assets (images, fonts)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Critical Rules
|
|
||||||
|
|
||||||
### App Router
|
|
||||||
|
|
||||||
This uses Next.js App Router (not Pages Router):
|
|
||||||
- Server Components by default
|
|
||||||
- Use `'use client'` directive for client components
|
|
||||||
- Metadata exported from layout.tsx and page.tsx
|
|
||||||
|
|
||||||
### PostHog Integration
|
|
||||||
|
|
||||||
PostHog is configured at root level:
|
|
||||||
- Provider in `providers.tsx`
|
|
||||||
- Page view tracking in `PostHogPageView.tsx`
|
|
||||||
- Wrap all pages in `<PostHogProvider>`
|
|
||||||
|
|
||||||
### SEO & Metadata
|
|
||||||
|
|
||||||
Metadata is defined in `layout.tsx`:
|
|
||||||
```typescript
|
|
||||||
export const metadata: Metadata = {
|
|
||||||
title: 'Sauci - Ignite Your Connection',
|
|
||||||
description: '...',
|
|
||||||
openGraph: { ... },
|
|
||||||
twitter: { ... },
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
Update metadata when adding new pages.
|
|
||||||
|
|
||||||
### Styling
|
|
||||||
|
|
||||||
- Use Tailwind CSS classes
|
|
||||||
- Global styles in `globals.css`
|
|
||||||
- Follow mobile-first responsive design
|
|
||||||
|
|
||||||
### Static Pages
|
|
||||||
|
|
||||||
Privacy and Terms pages are static content:
|
|
||||||
- `/privacy` - Privacy policy
|
|
||||||
- `/terms` - Terms of service
|
|
||||||
|
|
||||||
Keep these updated with legal requirements.
|
|
||||||
|
|
||||||
### Environment Variables
|
|
||||||
|
|
||||||
Required environment variables:
|
|
||||||
- `NEXT_PUBLIC_POSTHOG_KEY` - PostHog API key
|
|
||||||
- `NEXT_PUBLIC_POSTHOG_HOST` - PostHog host
|
|
||||||
|
|
||||||
## Forbidden Actions
|
|
||||||
|
|
||||||
1. **DO NOT** remove PostHog tracking without approval
|
|
||||||
2. **DO NOT** use Pages Router patterns (use App Router)
|
|
||||||
3. **DO NOT** add server-side API routes that expose sensitive data
|
|
||||||
4. **DO NOT** forget to update metadata for new pages
|
|
||||||
5. **DO NOT** skip mobile responsiveness
|
|
||||||
6. **DO NOT** commit .env files with real API keys
|
|
||||||
@@ -120,7 +120,7 @@ export default function Pricing() {
|
|||||||
<p className="text-sm text-white/80">
|
<p className="text-sm text-white/80">
|
||||||
<span className="font-semibold text-white">Pay once per couple.</span>{' '}
|
<span className="font-semibold text-white">Pay once per couple.</span>{' '}
|
||||||
Whether monthly or yearly, one subscription unlocks Pro for both you and your partner.
|
Whether monthly or yearly, one subscription unlocks Pro for both you and your partner.
|
||||||
That's two accounts for the price of one.
|
That's two accounts for the price of one.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -153,7 +153,7 @@ export default function Pricing() {
|
|||||||
transition={{ delay: 0.3 }}
|
transition={{ delay: 0.3 }}
|
||||||
className="text-center text-white/40 text-sm mt-8 max-w-lg mx-auto"
|
className="text-center text-white/40 text-sm mt-8 max-w-lg mx-auto"
|
||||||
>
|
>
|
||||||
Start free with access to selected packs. Upgrade to Pro when you're ready to unlock everything.
|
Start free with access to selected packs. Upgrade to Pro when you're ready to unlock everything.
|
||||||
</motion.p>
|
</motion.p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Generated
-1798
File diff suppressed because it is too large.
Load diff
@@ -5,9 +5,10 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint",
|
"lint": "next lint",
|
||||||
"typecheck": "tsc --noEmit"
|
"test": "vitest run --passWithNoTests",
|
||||||
|
"typecheck": "tsc --noEmit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"framer-motion": "^11.0.0",
|
"framer-motion": "^11.0.0",
|
||||||
@@ -20,9 +21,11 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.0.0",
|
"@types/node": "^20.0.0",
|
||||||
"@types/react": "^18.3.0",
|
"@types/react": "^18.3.0",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
"autoprefixer": "^10.4.0",
|
"autoprefixer": "^10.4.0",
|
||||||
"postcss": "^8.4.0",
|
"eslint": "^8.57.1",
|
||||||
|
"eslint-config-next": "14.2.35",
|
||||||
|
"postcss": "^8.4.0",
|
||||||
"tailwindcss": "^3.4.0",
|
"tailwindcss": "^3.4.0",
|
||||||
"typescript": "^5.3.0"
|
"typescript": "^5.3.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Learning promotion
|
||||||
|
|
||||||
|
Raw activity is not durable guidance. A lesson becomes agent context only after a
|
||||||
|
reproducible observation is reviewed and promoted.
|
||||||
|
|
||||||
|
## Lifecycle
|
||||||
|
|
||||||
|
1. Record a structured observation in `.agents/learnings/inbox/`.
|
||||||
|
2. Include symptom, reproduction, cause, remediation, evidence, and scope.
|
||||||
|
3. `npm run learn:check` validates the record.
|
||||||
|
4. A reviewer promotes it into exactly one maintained surface: documentation,
|
||||||
|
skill, test fixture, invariant lint, or scoped `AGENTS.md` rule.
|
||||||
|
5. Move it to `.agents/learnings/promoted/` and include its destination.
|
||||||
|
|
||||||
|
Do not promote speculation, transient provider failures, or one-off workarounds.
|
||||||
|
Prefer executable enforcement over prose. Review guidance on its expiry date.
|
||||||
|
|
||||||
|
`.ralph/runs` and activity logs are historical evidence and are not loaded into
|
||||||
|
normal task context.
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# Agent routing and effort
|
||||||
|
|
||||||
|
Use one implementation agent by default. Add independent agents only when work is
|
||||||
|
actually separable or a risk trigger requires independent judgment.
|
||||||
|
|
||||||
|
| Role | Default effort | Trigger | Do not use for |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `repo-scout` | low | locate ownership, callers, contracts | editing or design decisions |
|
||||||
|
| `implementation` | medium | bounded product or harness change | broad architecture review |
|
||||||
|
| `test-writer` | medium | focused regression or missing contract test | rubber-stamping green output |
|
||||||
|
| `verifier` | medium | independently drive changed behavior | editing implementation |
|
||||||
|
| `database-reviewer` | medium | migrations, RLS, function/query boundaries | ordinary UI changes |
|
||||||
|
| `security-reviewer` | high | auth, RLS, crypto, secrets, payments, destructive operations | every routine change |
|
||||||
|
| `architecture-reviewer` | high | cross-cutting or hard-to-reverse decisions | local refactors |
|
||||||
|
|
||||||
|
Escalate effort only when uncertainty, blast radius, or irreversibility justifies
|
||||||
|
it. “Proactively use” is not a trigger. Verification agents return evidence and a
|
||||||
|
verdict; they do not make changes.
|
||||||
|
|
||||||
|
Procedures belong in skills. Agents read the applicable skill and nearest
|
||||||
|
`AGENTS.md`, then operate within the task's authorization.
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# System architecture
|
||||||
|
|
||||||
|
Sauci is an npm workspace coordinated by Turborepo.
|
||||||
|
|
||||||
|
| Component | Technology | Responsibility |
|
||||||
|
|---|---|---|
|
||||||
|
| Mobile | Expo / React Native / Expo Router | primary customer product |
|
||||||
|
| Admin | Vite / React | content and administrative operations |
|
||||||
|
| Web | Next.js App Router | marketing, policies, redemption |
|
||||||
|
| Backend | Supabase Postgres/Auth/Realtime/Edge Functions | identity, data, workflows |
|
||||||
|
| MCP | Hono / MCP SDK | authenticated internal administrative tools |
|
||||||
|
| Shared | TypeScript types | cross-application contracts only |
|
||||||
|
|
||||||
|
## Trust boundaries
|
||||||
|
|
||||||
|
- Mobile and web use public Supabase credentials and depend on RLS.
|
||||||
|
- Administrative access requires both an authenticated identity and role checks.
|
||||||
|
- Service-role edge functions authenticate and authorize callers before user-data
|
||||||
|
operations.
|
||||||
|
- MCP has privileged access and requires `SAUCI_MCP_API_KEY`; absent credentials
|
||||||
|
must never make a non-local deployment public.
|
||||||
|
- Local verification uses local Supabase, never a remote project.
|
||||||
|
|
||||||
|
## Product flow
|
||||||
|
|
||||||
|
Two profiles join a couple, answer questions independently, and the
|
||||||
|
`submit-response` edge function creates a match when answers are compatible.
|
||||||
|
Realtime subscriptions surface matches and chat messages to the partner.
|
||||||
|
|
||||||
|
## Change boundaries
|
||||||
|
|
||||||
|
- Database shape: migration plus generated/shared types plus affected clients.
|
||||||
|
- Edge function contract: function tests plus calling UI/store behavior.
|
||||||
|
- Shared contract: update every consumer in the same change.
|
||||||
|
- UI flow: component/unit coverage and observable E2E evidence.
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Local full-stack development
|
||||||
|
|
||||||
|
Use `scripts/dev-local.sh`; do not start a mixture of local and production-backed
|
||||||
|
services manually.
|
||||||
|
|
||||||
|
| Service | Owner | Port |
|
||||||
|
|---|---|---:|
|
||||||
|
| Supabase API / functions | Supabase CLI | 54321 |
|
||||||
|
| Supabase database | Supabase CLI | 54322 |
|
||||||
|
| Supabase Studio | Supabase CLI | 54323 |
|
||||||
|
| Web | Next.js | 3000 |
|
||||||
|
| Admin | Vite | 3001 |
|
||||||
|
| MCP | Hono | 3002 |
|
||||||
|
| Expo Metro | Expo | 8081 |
|
||||||
|
|
||||||
|
## First run
|
||||||
|
|
||||||
|
1. Use Node from `.nvmrc` and run `npm ci`.
|
||||||
|
2. Install Docker Desktop or Rancher Desktop, tmux, and the Supabase CLI.
|
||||||
|
3. Copy committed environment examples. Local helpers derive local Supabase
|
||||||
|
values; they never print or overwrite production credentials.
|
||||||
|
4. Run `scripts/dev-local.sh reset` to apply migrations and create E2E fixtures.
|
||||||
|
5. Run `scripts/dev-local.sh up`.
|
||||||
|
|
||||||
|
`up` is idempotent. `down` stops tmux services and leaves Supabase available;
|
||||||
|
`down --all` also stops Supabase. Use `status`, `logs <service>`, `restart
|
||||||
|
<service>`, and `attach` for diagnosis.
|
||||||
|
|
||||||
|
The Expo window defaults to Metro. Use `scripts/dev-local.sh ios` or `android` to
|
||||||
|
launch the native app against the same backend.
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# Sauci documentation
|
||||||
|
|
||||||
|
This index separates maintained operational truth from implementation plans and
|
||||||
|
historical notes. Agents should load only the section relevant to their task.
|
||||||
|
|
||||||
|
## Maintained system documentation
|
||||||
|
|
||||||
|
- [System architecture](architecture/system.md)
|
||||||
|
- [Local full-stack development](development/local-stack.md)
|
||||||
|
- [Testing strategy](testing/strategy.md)
|
||||||
|
- [Database migration safety](operations/database-migrations.md)
|
||||||
|
- [Agent routing and effort](agents/routing.md)
|
||||||
|
- [Learning promotion](agents/learnings.md)
|
||||||
|
- [Authentication](authentication.md)
|
||||||
|
- [Database schema](schema.md)
|
||||||
|
- [Couple pairing](couple-pairing.md)
|
||||||
|
- [Question selection](question-selection.md)
|
||||||
|
- [Match notifications](match-notifications.md)
|
||||||
|
- [Subscriptions](subscription-system.md)
|
||||||
|
- [Redemption codes](product/redemption.md)
|
||||||
|
- [Mobile release process](releasing.md)
|
||||||
|
|
||||||
|
## Feature and implementation references
|
||||||
|
|
||||||
|
These contain useful history and acceptance details, but may describe planned or
|
||||||
|
partially implemented states. Confirm claims against current code.
|
||||||
|
|
||||||
|
- `admin-question-types-plan.md`
|
||||||
|
- `content-balance-implementation.md`
|
||||||
|
- `dares-feature.md`
|
||||||
|
- `live-draw-feature-plan.md`
|
||||||
|
- `NEW_QUESTION_TYPES.md`
|
||||||
|
- `oversized-file-inventory.md`
|
||||||
|
- `pack-icons-admin-first.md`
|
||||||
|
- `data-retrieval-tasks.md`
|
||||||
|
- `release-notes.md`
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# Database migration safety
|
||||||
|
|
||||||
|
All schema changes are versioned local files under `apps/supabase/migrations/`.
|
||||||
|
|
||||||
|
## Required workflow
|
||||||
|
|
||||||
|
1. `npm run db:migration:new -- <descriptive_name>`
|
||||||
|
2. Edit the generated local migration.
|
||||||
|
3. Prefer idempotent SQL where semantics permit it.
|
||||||
|
4. `npm run db:reset` against local Supabase.
|
||||||
|
5. Run `npm run test:supabase` and affected application checks.
|
||||||
|
6. Commit the migration with dependent code and types.
|
||||||
|
|
||||||
|
## Forbidden paths
|
||||||
|
|
||||||
|
- Never call a remote `apply_migration` MCP tool.
|
||||||
|
- Never execute DDL through MCP SQL execution.
|
||||||
|
- MCP SQL execution is read-only `SELECT` use only.
|
||||||
|
- Never insert migration history manually except an explicitly approved repair.
|
||||||
|
- Never hardcode a production URL in a migration or cron definition.
|
||||||
|
|
||||||
|
CI deploys committed migrations. Local verification must not link a remote project.
|
||||||
Loaded 100 of 125 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user