Introduces the SDD root: a v1.0.0 constitution and machine-readable AGENTS.md grounded in the project's real conventions; six EARS-aware persona spec-review checklists that cross-reference .claude/personas/; feature-spec/ADR/threat-model/ api-contract templates; a fully worked _example feature; a living RTM; and an adrs/ pointer that reuses the existing docs/adr/ archive. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.9 KiB
Persona Review Results — Profile picture upload
Captured from the six persona spec reviews (the comments that, in a real feature, are posted on the Gitea issue). This is the worked example of what a completed review round looks like. All personas APPROVE; the two findings raised were folded into the spec before approval.
Summary
| Persona | Verdict | Blocking FAILs | Notes |
|---|---|---|---|
| Requirements Engineer | APPROVE | none | — |
| Developer | APPROVE | none | — |
| Security | APPROVE | none (2 resolved) | See F-SEC-1, F-SEC-2 |
| DevOps | APPROVE | none | — |
| UI/UX | APPROVE | none (1 resolved) | See F-UX-1 |
| Architect | APPROVE | none (1 resolved) | See F-ARCH-1 |
### Security — Spec Review
| # | Item | Status | Note |
|---|---|---|---|
| 1 | All mutating endpoints have authn + authz If clauses |
PASS | REQ-006 (401), REQ-009 (403) |
| 2 | Each mutating endpoint names least-privilege Permission |
PASS | me = authenticated; {id} = ADMIN_USER |
| 3 | Audit fields server-set, forbidden in body | PASS | avatarObjectKey server-set (design.md) |
| 4 | IDOR surfaces addressed | PASS | /{id} gated by ADMIN_USER + ownership |
| 5 | Untrusted content rendered safely | PASS | image bytes via proxy + nosniff |
| 6 | Upload: type allow-list + size + bytes | PASS | REQ-007 (PNG/JPEG), REQ-008 (2 MB) |
| 7 | No entity internals leaked | PASS | UserProfileView, not AppUser |
| 8 | Conflicts → 409 not raw 500 | N/A | no optimistic-lock surface here |
| 9 | threat-model.md present & STRIDE-complete | PASS | threat-model.md |
| 10 | ASTRIDE if AI tool used | N/A | no AI agent |
| 11 | Secrets from env only | PASS | none introduced |
| 12 | Logs PII-free | PASS | user UUID only |
| 13 | New dependency has ADR + clean audit | N/A | no new dependency |
F-SEC-1 (resolved): initial draft exposed a public S3 URL for avatarUrl →
information disclosure. Resolved: authenticated proxy GET /api/users/{id}/avatar.
F-SEC-2 (resolved): initial draft bound avatarObjectKey from the request body →
mass-assignment. Resolved: server-set only.
Verdict: APPROVE.
### UI/UX — Spec Review
| # | Item | Status | Note |
|---|---|---|---|
| 1 | Every interaction state described | PASS | idle/preview/uploading/error/done (T-10) |
| 2 | Strings via Paraglide i18n | PASS | T-8 |
| 3 | Reuses design tokens/components | PASS | placeholder uses existing initials pattern |
| 4 | Responsive per device split | PASS | control usable on phone + laptop |
| 5 | Errors via getErrorMessage(code) |
PASS | UNSUPPORTED_FILE_TYPE / AVATAR_TOO_LARGE |
| 6 | Keyboard + screen-reader | PASS | labelled file input, alt text on image |
| 7 | Acceptance criteria measurable | PASS | sizes, status codes |
| 8 | E2E scenario per journey | PASS | T-12 |
| 9 | Confirmation for destructive action | PASS | remove asks to confirm |
| 10 | Safe rendering + image dims | PASS | fixed dims avoid layout shift |
| 11 | Live routes verified | PASS | /profile, /users/[id] exist |
| 12 | Token theming respected | PASS | semantic tokens |
F-UX-1 (resolved): no loading state in first draft → spinner during upload added (REQ-... covered by state set in T-10). Verdict: APPROVE.
### Architect — Spec Review
Key items PASS. F-ARCH-1 (resolved): bucket choice was undocumented → captured in adr-001-avatars-reuse-archive-bucket.md. No new domain, no boundary crossing, Person/AppUser separation intact. Verdict: APPROVE.
### Requirements Engineer / Developer / DevOps — Spec Review
All checklist items PASS (see each persona's checklist in .specify/personas/). RE: 9 REQ
ids, all EARS-formed, every limit has an If. Developer: reuses FileService/UserService,
AVATAR_TOO_LARGE four-site update is T-1. DevOps: V78 forward-only + rollback note, no new
bucket/env var, idempotent overwrite. All three: APPROVE.