Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions .claude/agents/product-manager.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: product-manager
description: Interrogates a feature idea or bug report and returns executable ticket material for /ticket, including how many tickets it should become. Knows the parity contract, the append-only DTO rule, deploy-API-first, and the 6.2 ticket template. Read-only; it shapes work, it never implements.
description: Interrogates a feature idea or bug report and returns executable ticket material for /ticket, including how many tickets it should become. Runs the eight-category edge-case pass on every request. Knows the parity contract, the append-only DTO rule, deploy-API-first, and the 6.2 ticket template. Read-only; it shapes work, it never implements.
tools: Glob, Grep, Read
model: inherit
effort: high
Expand All @@ -18,19 +18,29 @@ Return, as structured text:
2. **Affected surface inventory**: routes (web + mobile pair), endpoints, DTOs, i18n
namespaces. Name the parity consequence explicitly: web + mobile in one ticket
(parity:yes), or the adapter-only exemption with its justification.
3. **The ticket split**: each ticket one repo and one coherent, independently mergeable PR.
3. **The edge-case pass**: walk the proposed behaviour through eight categories, always
in this order — user types, contexts of use, unexpected inputs and system failures,
user error, feature interactions, load, security and privacy, accessibility. The fixed
order exists because it reaches the categories every author forgets. For each category,
name the scenarios where the request is silent and a headless worker would invent the
behaviour; a spec gap no longer becomes a reviewer's question, it ships as confident
wrong code. Every surviving scenario states the expected behaviour in one line and
lands in the owning ticket's Expected behaviour or Test scenarios. A scenario with no
defensible default becomes an open question (section 6). State an empty category as
empty; never skip one silently.
4. **The ticket split**: each ticket one repo and one coherent, independently mergeable PR.
Prefer small tickets when behavior or deployment boundaries are genuinely separable; file and
line estimates are advisory and never justify splitting an atomic behavior or its required
generated artifacts. Cross-repo work is an api ticket BLOCKING a ui ticket
(deploy-API-first as a DAG edge). Shared/DTO changes are append-only: add optional
fields, never rename/remove/retype what shipped mobile clients still read.
Never propose: a tests-only ticket, a foundation ticket of unused code, or a
migration split from its feature.
4. **Per ticket, the 6.2 material**: problem, scope, out-of-scope, expected behaviour,
5. **Per ticket, the 6.2 material**: problem, scope, out-of-scope, expected behaviour,
technical details with file paths you VERIFIED exist, acceptance criteria (each one
checkable by a machine or a screenshot), test scenarios, rollout/kill-switch where
risk exists, events/metrics where success needs measuring.
5. **Open questions**: ONLY genuine forks a codebase read cannot answer, each with your
6. **Open questions**: ONLY genuine forks a codebase read cannot answer, each with your
recommended answer first. An empty list is a good list.

Hard rules: never invent a file path (verify with Read/Glob before citing); never
Expand Down
36 changes: 32 additions & 4 deletions .claude/skills/audit-security/checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ Every finding cites a file:line and a **threat** (who reaches it, what they get)
tool beyond the user's own data or trigger an unbounded loop. The cost/iteration ceiling
is server-enforced, not prompt-enforced.
- [ ] **Model output isn't reflected as trusted HTML/markup** without escaping.
- [ ] **A self-harm or crisis disclosure gets a crisis response**: the Astra system
prompt or a server-side check routes self-harm text to a supportive reply that names
crisis resources for the user's locale (BR: CVV 188, US: 988), never to a productivity
nudge. Companion-chatbot laws mandate the protocol (California SB 243, in force 2026),
and Orbit's audience makes it a product duty besides. No handling anywhere in
`orbit-api` is **Tier 1**.
Comment thread
pullfrog[bot] marked this conversation as resolved.
Resolved

## G. Error handling & data exposure

Expand Down Expand Up @@ -163,13 +169,16 @@ Every finding cites a file:line and a **threat** (who reaches it, what they get)

## J. Legal & data-handling posture

> Collecting user data puts Orbit under GDPR/CCPA at any scale. These four are
> repo-checkable; the policy's legal wording is not, and is not a finding.
> Collecting user data puts Orbit under GDPR/LGPD/CCPA at any scale, and selling a
> subscription adds consumer-protection exposure (FTC and state equivalents). Every item
> here is repo- or live-checkable; the policy's legal wording is not, and is not a finding.

- [ ] **A privacy policy is reachable and linked** from the app and the landing page, and
the processors it names match the ones the code actually calls (Supabase/Render region,
Stripe, PostHog US Cloud, Sentry, Resend, Firebase). A policy that contradicts the real
processor list is **Tier 2**.
Stripe, PostHog US Cloud, Sentry, Resend, Firebase, OpenAI). The AI flow is named in
plain terms — user text reaches OpenAI and the policy says so; state AI-disclosure laws
make silence its own violation. A policy that contradicts the real processor list is
**Tier 2**.
- [ ] **Account deletion and data export are user-reachable**, not a manual DB action (GDPR
erasure + portability). Missing a user-facing delete path is **Tier 2**.
- [ ] **Third-party data flows are intentional**: analytics, crash, and log payloads carry
Expand All @@ -178,6 +187,25 @@ Every finding cites a file:line and a **threat** (who reaches it, what they get)
- [ ] **No copyleft contamination in shipped dependencies**: a GPL/AGPL package under
`apps/*` or a NuGet reference in a shipped project forces source disclosure. Cite the
package and its license (**Tier 2**).
- [ ] **Object storage is private and deletion is complete**: every Supabase storage
bucket (`SupabaseObjectStorageService.cs`) rejects anonymous reads — prove it from
outside with the publishable key, like the RLS probe, never by inference. A public
bucket over user content is **Tier 1**. Account deletion removes the user's storage
objects along with the rows; content the policy promises to delete but that survives in
a bucket is **Tier 2**.
- [ ] **Subscription exit matches entry**: a subscriber cancels inside the app, in no
more steps than subscribing took, with no support contact. A cancel path that needs an
email is **Tier 2** (FTC negative-option exposure, and Play policy requires it).
Comment thread
pullfrog[bot] marked this conversation as resolved.
Resolved
- [ ] **A trial that will charge warns first**: when a payment method is on file, a
reminder (email or push) goes out before the auto-charge, and the scheduler and template
exist in the repo. Today the trial holds no card, so this item arms when ORB-138 applies
the price; a silent auto-charge then is **Tier 2** (full-refund exposure).
Comment thread
pullfrog[bot] marked this conversation as resolved.
Resolved
- [ ] **No invented social proof**: no testimonial, review count, star rating, or
`aggregateRating` structured data in the app, the landing page, or store-listing copy
that does not trace to a real user statement. An invented review is **Tier 1** (the FTC
fake-review rule fines per violation). Verified clean 2026-08-13: the landing JSON-LD
carries no rating and no testimonials. Re-verify rather than trusting that line —
marketing pages change.
Comment thread
pullfrog[bot] marked this conversation as resolved.
Resolved

## Tier 3 — out of scope for this audit (acknowledge, don't itemize as findings)

Expand Down
4 changes: 3 additions & 1 deletion .claude/skills/ticket/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ Test scenarios prove the new or changed behaviour, and no fabricated red case be
## B. product-manager: how many tickets

1. Spawn `product-manager` with the raw request plus `architecture.json`. It returns the sharpened
problem, the affected surfaces and endpoints, the per-ticket 6.2 material, and a first-cut split.
problem, the affected surfaces and endpoints, the eight-category edge-case scenarios, the
per-ticket 6.2 material, and a first-cut split. A return with no edge-case pass is incomplete;
send it back rather than filling the gap yourself.
2. Spawn `design-specialist` in parallel whenever any surface is user-visible. For a pure chore or
harness item with no UI, state that it was skipped and why.
3. **Splitting one message that lists several problems.** Decide which of these three shapes each
Expand Down
Loading