Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 5 additions & 2 deletions .claude/agents/code-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,11 @@ exact `file:line`, name the rule, and give a copy-pasteable fix.
plan). One ticket = one PR ([AGENTS.md](../../AGENTS.md)).

8. **Device QA.** Changes that add native modules or mic / camera / filesystem
/ permissions behavior must **flag** that Android device QA is required
before ready-for-review. Do not treat unit tests as sufficient.
/ permissions behavior (or otherwise **Needs QA**) must **flag** Android
device QA on that PR’s **`preview-build`** before merge (see
[docs/guides/qa-process.md](../../docs/guides/qa-process.md)). Do not treat
unit tests as sufficient; QA-required PRs are not mergeable until that
preview passes.

9. **TypeScript.** New `any` (prefer `unknown` + narrowing). Missing types on
exported functions where neighbors have them.
Expand Down
33 changes: 28 additions & 5 deletions .claude/commands/create-pr.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,15 +136,24 @@ and pre-fill:
| ------- | ---------------- |
| **TLDR** | 2–4 sentences: what / why / impact |
| **Reviewer checklist** | Leave items unchecked unless verified ([AGENTS.md](../../AGENTS.md)) |
| **Details** | `Refs #NNN` on its own line; short summary; type-of-change checkboxes |
| **Details** | `Refs #NNN` on its own line; short summary; **Needs QA?** Yes/No; type-of-change checkboxes |
| **Technical changes** | Key files as `` `path` `` bullets |
| **Testing** | What gates ran (`format:check`, `lint`, `typecheck`, `npm test -- --ci`) |
| **How to verify** | Numbered steps + **Expected** |
| **Follow-ups** | Deferred AC → linked issues; otherwise say none |

Do **not** auto-check **Acceptance criteria**, **Scope**, or **Android device
tested** unless verified. Do **not** auto-check device QA for native / mic /
camera / filesystem / permissions changes.
**Needs QA? / preview gate** ([docs/guides/qa-process.md](../../docs/guides/qa-process.md)):

1. Decide **Needs QA?** and check **No** or **Yes** in the PR body.
2. If **Yes**: leave “QA passed this PR’s preview” **unchecked** until a
human confirms. After `gh pr create` (below), **add** the
**`preview-build`** label and **verify** it is on the PR. **STOP** if
the label is missing — the isolated preview will not start. Do not
merge until QA passes that PR’s preview.
3. If **No**: check engineering-only; skip preview/QA merge gate.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Do **not** auto-check **Acceptance criteria**, **Scope**, or **Needs QA?
preview-passed** unless verified.

Keep under ~400 lines; no nested fenced code blocks inside the PR body.

Expand All @@ -162,14 +171,28 @@ If the PR already exists without an assignee:
gh pr edit --add-assignee @me
```

**`preview-build` label (QA-required — hard gate):** If **Needs QA?** is
**Yes**, add the label immediately and confirm it is present. **STOP** if
it is missing.

```bash
# Only when Needs QA? is Yes
gh pr edit --add-label preview-build
if ! gh pr view --json labels --jq '.labels[].name' | grep -qx preview-build; then
echo "STOP: Needs QA? Yes but preview-build label is missing."
exit 1
fi
```

**Issue link (Development sidebar):** `Refs #NNN` is the required non-closing
reference. GitHub’s Development widget is only auto-populated by closing
keywords or a **manual** sidebar link. Do **not** use closing keywords. After
create, if the sidebar is empty, link `#NNN` once in the GitHub UI (or ask the
user to).

**Reviewers / labels:** CODEOWNERS handles review requests after the file is on
`main`. Omit `--reviewer` unless the user asks.
`main`. Omit `--reviewer` unless the user asks. Do **not** skip
`preview-build` when **Needs QA?** is **Yes** (hard gate above).

Flag high-impact paths in the body when present: `package.json`,
`package-lock.json`, `app.config.ts`, `plugins/`, `eas.json`, `src/db/schema.ts`
Expand Down
2 changes: 1 addition & 1 deletion .cursor/rules/agent-guardrails.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Quick checklist:
1. **AC** — done means ticket acceptance criteria (or ticket-level waiver + follow-up), not green CI alone
2. **Scope** — one ticket = one PR; no adjacent tickets unless asked
3. **Abstraction** — no generic adapter/framework without a second caller or ticket ask
4. **Human QA** — native / mic / camera / filesystem / permissions need Android device results before ready-for-review
4. **Human QA** — Needs QA per [docs/guides/qa-process.md](../../docs/guides/qa-process.md) → that PR’s `preview-build` → **not mergeable until QA passes**
5. **Agent-authored features** — review scope, abstraction, and AC-vs-CI first
6. **PR body** — filled from [`.cursor/templates/pr-template.md`](../templates/pr-template.md) on every agent-opened PR ([delivery.mdc](./delivery.mdc)) — not a short Summary/Test plan substitute

Expand Down
2 changes: 1 addition & 1 deletion .cursor/rules/delivery.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Every change — including infra, CI, docs, Dependabot follow-ups, and `expo ins
1. **Ticket on Project 4** — GitHub Issue `#NNN` **on** the [Fluent Mobile Board](https://github.com/orgs/eten-tech-foundation/projects/4/views/9) (org project #4, view 9). Ask if missing. See [docs/issue-tracking.md](../../docs/issue-tracking.md). The repo Issues list is not the triage board. (Not Linear.) Board Status/Priority edits: [docs/guides/project-board.md](../../docs/guides/project-board.md) and [project-board.mdc](./project-board.mdc) — do not sweep Product or `Dev Ready` lanes without named approval.
2. **Feature branch** — `{author}/{type}/{issue-number}-{slug}` (see `/create-pr-branch`, or `/start-issue` for the full loop)
3. **Pull request** — title `[#NNN]: Description`; body filled from the PR template (below); include `Refs #NNN` under Details (never `Closes` / `Fixes` / `Resolves`); **assign the PR to the author** (`gh pr create --assignee @me` or `gh pr edit --add-assignee @me`); set Project 4 Status to **In PR Review**. Manually link the issue in the PR Development sidebar when needed (GitHub has no non-closing link API — do not use closing keywords). `/start-issue` chains to `/create-pr` (`/open-pr` is an alias) which automates the draft PR, board move, and CI watch.
4. **Human merge** — agents open PRs and push **feature branches only**; never merge on GitHub unless the user explicitly asks for a Dependabot squash merge in that session. After merge, set Project 4 Status to **In QA** (issues stay open for QA — do not auto-close)
4. **Human merge** — agents open PRs and push **feature branches only**; never merge on GitHub unless the user explicitly asks for a Dependabot squash merge in that session. For **QA-required** PRs ([docs/guides/qa-process.md](../../docs/guides/qa-process.md)): add `preview-build` and wait for QA pass on **that PR’s** isolated preview — **not mergeable until QA passes**. Project 4 `In QA` is best-effort tracking, not a merge prerequisite. Engineering-only PRs skip that gate. Issues stay open — do not auto-close

Allowed on `main` locally: `git checkout main`, `git pull`, read-only validation after merges. **Not allowed:** `git push origin main`, commits on `main`, or opening PRs with `main` as the head branch.

Expand Down
7 changes: 5 additions & 2 deletions .cursor/rules/docs.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,12 @@ Cross-tool agents (Claude Code, Copilot, etc.) must still find the same contract

[README.md](../../README.md) — human-focused setup (Android emulator, env vars). Link to `docs/AGENT_ONBOARDING.md` for agents; do not duplicate full architecture there.

## QA preview testing
## QA process + preview install

[docs/guides/qa-preview-testing.md](../../docs/guides/qa-preview-testing.md) — non-technical steps for PR previews (Fluent dev client, not Expo Go). Update when preview workflow comments or install flow change.
- [docs/guides/qa-process.md](../../docs/guides/qa-process.md) — Needs QA?, ownership, pass/fail, **pre-merge** merge gate
- [docs/guides/qa-preview-testing.md](../../docs/guides/qa-preview-testing.md) — non-technical install steps for PR previews (Fluent preview app, not Expo Go)

Update these when preview workflow comments, install flow, or the QA merge gate change.

## PR template

Expand Down
4 changes: 2 additions & 2 deletions .cursor/rules/project-board.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ Canonical policy: [docs/guides/project-board.md](../../docs/guides/project-board
- **Do not** edit Status or Priority on `In Progress (Product)` (or other Product-owned columns) unless the tech lead **explicitly lists** those issue numbers.
- **No board sweeps** without a proposed change set + explicit approval. Ambiguous = no.
- **Do not merge PRs** unless explicitly asked (Dependabot process is the standing exception when requested).
- For the **assigned** ticket only: add to Project 4 if missing; set `In PR Review` when the PR opens; set **`In QA`** after merge (or when ready for QA) — never auto-close the issue; do **not** set `Done` until QA completes (human/QA process).
- For the **assigned** ticket only: add to Project 4 if missing; set `In PR Review` when the PR opens; if **Needs QA**, add `preview-build` and do **not** merge until QA passes that PR’s preview ([docs/guides/qa-process.md](../../docs/guides/qa-process.md)). Project 4 `In QA` is best-effort tracking, not a merge gate — never auto-close the issue; do **not** set `Done` until QA completes (human/QA process).

Tracker overview: [docs/issue-tracking.md](../../docs/issue-tracking.md). Delivery: [delivery.mdc](./delivery.mdc).
Tracker overview: [docs/issue-tracking.md](../../docs/issue-tracking.md). QA process: [docs/guides/qa-process.md](../../docs/guides/qa-process.md). Delivery: [delivery.mdc](./delivery.mdc).
8 changes: 7 additions & 1 deletion .cursor/templates/pr-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@
- [ ] How to verify steps completed or valid waiver noted below
- [ ] Acceptance criteria met, **or** unmet AC waived **in the issue** with linked follow-up (see `AGENTS.md`)
- [ ] Scope limited to this issue — no adjacent tickets implemented/stubbed without approval
- [ ] Android device tested when required (native / mic / camera / filesystem / permissions) — do **not** check unless verified on a device
- [ ] **Needs QA?** decided (see `docs/guides/qa-process.md`) — if yes: `preview-build` label added
- [ ] If QA-required: QA passed **this PR’s** preview build before merge (do **not** check until QA confirms; this is the device-QA gate when Needs QA? is Yes)

### Details

Refs #<!-- issue number this PR implements -->

<!-- Short summary. For fixes: root cause + solution. -->

**Needs QA?**

- [ ] No — engineering-only (docs, CI, refactor, logging, etc.)
- [ ] Yes — see Needs QA? in `docs/guides/qa-process.md` (`preview-build` required)

**Type of change:**

- [ ] Bug fix
Expand Down
6 changes: 3 additions & 3 deletions .eas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ Monitor:
Add the **`preview-build`** label to a pull request. GitHub Actions (`.github/workflows/preview-build.yml`) will:

- Start a **fresh Android `preview` internal APK** for that PR commit (binary only — no `eas update` / shared OTA channel)
- Post the same install comment on the **PR and linked issue**; best-effort move Project 4 Status to **`In QA`** (from `In PR Review` / `In Progress (Dev)`). Optional secret: `PROJECT_BOARD_TOKEN`.
- Post the same install comment on the **PR and linked issue**; best-effort move Project 4 Status to **`In QA`** (from `In PR Review` / `In Progress (Dev)`) **before merge**. Optional secret: `PROJECT_BOARD_TOKEN`.

Each labeled PR forces a new build so multiple QA APKs can exist at once. Preview profile has Expo Updates **disabled** (same idea as nightly).
Each labeled PR forces a new build so multiple QA APKs can exist at once. Preview profile has Expo Updates **disabled** (same idea as nightly). Re-request after fixes: remove and re-add the label. **QA-required PRs are not mergeable until QA passes that preview** — [docs/guides/qa-process.md](../docs/guides/qa-process.md).

**QA testers:** [`docs/guides/qa-preview-testing.md`](../docs/guides/qa-preview-testing.md)
**Install how-to:** [`docs/guides/qa-preview-testing.md`](../docs/guides/qa-preview-testing.md)

Uses the latest git tag for runtime version when available; otherwise falls back to `app.config.ts` / `package.json` version (no tag required for first preview). Requires `EXPO_TOKEN` in GitHub Actions secrets.

Expand Down
8 changes: 7 additions & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@
- [ ] How to verify steps completed or valid waiver noted below
- [ ] Acceptance criteria met, **or** unmet AC waived **in the issue** with linked follow-up (see `AGENTS.md`)
- [ ] Scope limited to this issue — no adjacent tickets implemented/stubbed without approval
- [ ] Android device tested when required (native / mic / camera / filesystem / permissions) — do **not** check unless verified on a device
- [ ] **Needs QA?** decided (see `docs/guides/qa-process.md`) — if yes: `preview-build` label added
- [ ] If QA-required: QA passed **this PR’s** preview build before merge (do **not** check until QA confirms; this is the device-QA gate when Needs QA? is Yes)

### Details

Refs #<!-- issue number this PR implements -->

<!-- Short summary. For fixes: root cause + solution. -->

**Needs QA?**

- [ ] No — engineering-only (docs, CI, refactor, logging, etc.)
- [ ] Yes — see Needs QA? in `docs/guides/qa-process.md` (`preview-build` required)

**Type of change:**

- [ ] Bug fix
Expand Down
8 changes: 6 additions & 2 deletions .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,15 @@ See [`.eas/README.md`](../.eas/README.md) for Expo GitHub app and Play Store set

## PR preview (QA)

Canonical process (Needs QA?, pass/fail, **pre-merge** merge gate): [`docs/guides/qa-process.md`](../docs/guides/qa-process.md).

1. Create a `preview-build` label on the repo (if missing).
2. Add the label to a PR when ready for QA (PR should reference its ticket with `Refs #NNN` on its own Details line — not `Part of #NNN`).
3. Workflow starts a **fresh Android preview APK** (binary only — no OTA / `eas update`), posts the same install comment on the **PR** and each **linked GitHub issue** (`Refs` / legacy closing keywords via [`.github/scripts/preview-notify-linked-issues.cjs`](scripts/preview-notify-linked-issues.cjs)), and best-effort moves Project 4 cards from `In PR Review` / `In Progress (Dev)` → **`In QA`**.
3. Workflow starts a **fresh Android preview APK** (binary only — no OTA / `eas update`), posts the same install comment on the **PR** and each **linked GitHub issue** (`Refs` / legacy closing keywords via [`.github/scripts/preview-notify-linked-issues.cjs`](scripts/preview-notify-linked-issues.cjs)), and best-effort moves Project 4 cards from `In PR Review` / `In Progress (Dev)` → **`In QA`** (**before merge**).
4. **Re-request after fixes:** remove the `preview-build` label, then re-add it (workflow triggers on `labeled` only; always `FORCE_NEW_BUILD`).
5. **Merge gate:** QA-required PRs are not mergeable until QA passes that PR’s preview — currently **manual** (no required status check yet).

**QA guide (non-technical):** [`docs/guides/qa-preview-testing.md`](../docs/guides/qa-preview-testing.md)
**Install guide (non-technical):** [`docs/guides/qa-preview-testing.md`](../docs/guides/qa-preview-testing.md)

Requires `EXPO_TOKEN` in repository secrets. Optional: `PROJECT_BOARD_TOKEN` (PAT with org **project** write) so Status updates on Project 4 succeed — without it, issue comments still post but the board move may be skipped. Each labeled PR forces a new EAS build (`FORCE_NEW_BUILD`) so concurrent QA previews are not collapsed by fingerprint reuse. `eas.json` profile `preview` is internal distribution with Expo Updates **disabled** (same idea as nightly). `EAS_USE_CACHE` (ccache) stays enabled on non-production profiles.

Expand Down
8 changes: 5 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ Build for the case in front of you.

### 4. Human-only verification

If a change adds **native modules** or **mic / camera / filesystem / permissions** behavior:
If a change adds **native modules** or **mic / camera / filesystem / permissions** behavior (or otherwise **Needs QA** per [docs/guides/qa-process.md](docs/guides/qa-process.md)):

- **Android device QA is required** (unit tests and CI are not enough).
- **Android device QA is required** on that PR’s **isolated `preview-build`** (unit tests and CI are not enough).
- Keep the PR **draft** or **changes-requested** until a human records device results on the PR.
- Agents must **flag** this requirement; do not check the device-QA box unless a human verified it.
- **QA-required PRs are not mergeable** until QA passes that preview — see [docs/guides/qa-process.md](docs/guides/qa-process.md).
- Agents must **flag** this requirement; do not check the device-QA / “QA passed preview” boxes unless a human verified it.

### 5. Agent-authorship is a review heuristic

Expand All @@ -58,6 +59,7 @@ On feature PRs with heavy agent co-authorship, reviewers should prioritize **sco

- Delivery / branch / PR process: [`.cursor/rules/delivery.mdc`](.cursor/rules/delivery.mdc) — **PR bodies must use** [`.cursor/templates/pr-template.md`](.cursor/templates/pr-template.md). Full loop: `/start-issue`; delivery-only: `/create-pr` (`.claude/commands/`).
- Issue tracking (Project 4 Fluent Mobile Board): [docs/issue-tracking.md](docs/issue-tracking.md)
- QA process / pre-merge preview gate: [docs/guides/qa-process.md](docs/guides/qa-process.md) · install how-to: [docs/guides/qa-preview-testing.md](docs/guides/qa-preview-testing.md)
- Board mutation rules: [docs/guides/project-board.md](docs/guides/project-board.md) · [`.cursor/rules/project-board.mdc`](.cursor/rules/project-board.mdc)
- Expo-first deps: [docs/guides/expo-first-dependencies.md](docs/guides/expo-first-dependencies.md) · [`.cursor/rules/expo-first-dependencies.mdc`](.cursor/rules/expo-first-dependencies.mdc)
- CI command order: [`.cursor/rules/commands.mdc`](.cursor/rules/commands.mdc)
Expand Down
9 changes: 5 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ This file is the **entrypoint for non-Cursor agents** (Claude Code, Codex, Copil
2. [`docs/AGENT_ONBOARDING.md`](docs/AGENT_ONBOARDING.md) — setup, architecture, commands
3. [`docs/issue-tracking.md`](docs/issue-tracking.md) — Project 4 board, branches, PRs
4. [`docs/guides/project-board.md`](docs/guides/project-board.md) — **board mutation hard rules**
5. [`docs/guides/expo-first-dependencies.md`](docs/guides/expo-first-dependencies.md) — prefer Expo packages
6. [`.cursor/rules/`](.cursor/rules/) — always-on + topic rules (`delivery`, `architecture`, `android-only`, `project-board`, `expo-first-dependencies`, …)
7. [`.claude/commands/`](.claude/commands/) — canonical slash commands (`/start-issue`, `/create-pr`, …). Cursor `/` palette shims live in [`.cursor/commands/`](.cursor/commands/).
5. [`docs/guides/qa-process.md`](docs/guides/qa-process.md) — Needs QA? / pre-merge preview gate
6. [`docs/guides/expo-first-dependencies.md`](docs/guides/expo-first-dependencies.md) — prefer Expo packages
7. [`.cursor/rules/`](.cursor/rules/) — always-on + topic rules (`delivery`, `architecture`, `android-only`, `project-board`, `expo-first-dependencies`, …)
8. [`.claude/commands/`](.claude/commands/) — canonical slash commands (`/start-issue`, `/create-pr`, …). Cursor `/` palette shims live in [`.cursor/commands/`](.cursor/commands/).

## Precedence

Expand All @@ -22,7 +23,7 @@ This file is the **entrypoint for non-Cursor agents** (Claude Code, Codex, Copil
- Never push or merge to `main`; ticketed branch + PR; PR body from [`.cursor/templates/pr-template.md`](.cursor/templates/pr-template.md). Full loop: `/start-issue NNN` (chains to `/create-pr`). Delivery-only: `/create-pr` (`/open-pr` alias).
- Do not reorganize Project 4 (`Dev Ready` / Product columns) without an approved change set
- Prefer Expo SDK modules; do not rip out React Navigation without a ticket
- Mic / camera / filesystem / native modules → human Android device QA before ready-for-review
- Needs QA per [docs/guides/qa-process.md](docs/guides/qa-process.md) → human Android device QA on that PR’s `preview-build` **before merge**

## Package manager / Node

Expand Down
Loading
Loading