You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
| Regular Member | Sam | "A tab organizer that helps my group" | Warm, plain-language, action-oriented | Jargon, options overload, blockchain vocabulary |
74
+
| Trusted Member | Nia | "Our community's shared memory" | Encouraging, collaborative, direct | Condescension, assumed technical literacy |
75
+
| Operator | Kai | "My community's command center" | Professional, efficient, task-focused | Oversimplification, hiding complexity |
76
+
| Mobile Contributor | Luz | "Quick capture from my phone" | Minimal, fast, zero-friction | Long explanations, multi-step flows |
77
+
78
+
### Surface → Persona Mapping
79
+
80
+
| Surface | Primary Persona | Tone Notes |
81
+
|---------|----------------|------------|
82
+
|**Popup**| Sam (Regular) | Quick, casual, action-first. 1-2 words per button. No explanation needed. |
83
+
|**Chickens tab**| Sam / Nia | Minimal, calm, Notion-like. 3-4 info pieces per card. Inline actions. |
Review a PR that extracts a utility function from a component into shared/src/utils/. No behavior change. Tests pass. The extraction follows barrel import conventions.
10
+
11
+
```typescript
12
+
// Before: inline in extension/src/views/Popup/TabList.tsx
13
+
function formatTabAge(createdAt:number):string {
14
+
const diff =Date.now() -createdAt;
15
+
if (diff<60000) return'just now';
16
+
if (diff<3600000) return`${Math.floor(diff/60000)}m ago`;
17
+
return`${Math.floor(diff/3600000)}h ago`;
18
+
}
19
+
20
+
// After: extracted to shared/src/utils/format-time.ts
21
+
exportfunction formatTabAge(createdAt:number):string { /* same logic */ }
Review a PR that adds a new async function fetching coop data without try/catch, no error boundary wrapping the consuming component, and raw error objects shown to the user via `toast.error(error.message)`.
10
+
11
+
```typescript
12
+
// New function in shared/src/modules/coop/index.ts
> "Why does Coop use y-webrtc instead of y-websocket as the primary sync transport?"
10
+
11
+
## Expected Output
12
+
13
+
Must address:
14
+
1.**Privacy/local-first rationale**: y-webrtc sends data directly peer-to-peer, so the server never sees document content — aligning with Coop's local-first principle
15
+
2.**y-websocket as fallback**: Coop does use y-websocket (via the API server at `/yws`) as a fallback for document sync when WebRTC fails
16
+
3.**Signaling vs transport distinction**: The API server provides signaling (peer discovery) but doesn't relay document data in the primary path
17
+
18
+
Must cite at least 2 sources from the codebase (e.g., CLAUDE.md, ADR-007, shared/storage module, API server ws handler).
-**Root cause hint**: Likely a persistence gap — Yjs state not persisted to Dexie or y-websocket fallback not loading historical state for late joiners
17
+
-**Route to**: oracle first (investigate sync/persistence boundary), then cracked-coder
18
+
-**Not**: P1 (sync works for active peers), not extension-only (this is a shared module issue)
19
+
20
+
## Eval Criteria
21
+
22
+
| Criterion | Weight | Pass | Fail |
23
+
|-----------|--------|------|------|
24
+
| Severity = P2 | 25% | Correctly identifies as P2 | Classifies as P1 or P3 |
25
+
| Identifies sync/persistence boundary | 25% | Points to storage/sync modules | Treats as pure UI issue |
26
+
| Routes oracle → cracked-coder | 25% | Two-step: investigate then fix | Goes straight to cracked-coder |
27
+
| Package = shared | 15% | Identifies shared as affected | Points only to extension |
0 commit comments