Frontend PR Process
This guide explains how to create, review, and merge a pull request against arda-frontend-app. It is the human companion to the pr-steward agent skill — the mechanics described here are what the skill automates when it shepherds a PR.
For the design behind these conventions, see the Phase 2 — Queued PRs and Tiered Gates roadmap entry.
When this guide applies
Section titled “When this guide applies”Follow this process for every PR against main in Arda-cards/arda-frontend-app. The same conventions are implemented (with minor variations) in other Arda repositories that use the merge queue; this guide documents the frontend specifically.
- Branch from latest
mainas<github-username>/<topic>. - Make your change. Run
make ci(or lint + tsc + jest + build) before pushing. - Open a PR. Fill out the
## CHANGELOGsection in the description (the template scaffolds it). - The Fast Gate runs (~5 min). Address any review comments and re-push.
- Get at least one approving review.
- Click “Merge when ready” → PR enters the merge queue.
- Queue Gate runs (~10–15 min). On success the PR merges automatically.
- Post-merge automation handles the rest (CHANGELOG assembly, version bump, GitHub Release, deploy).
Step-by-step
Section titled “Step-by-step”1. Branch from latest main
Section titled “1. Branch from latest main”Paths below assume the standard Arda workspace layout (the arda/ workspace root with arda-frontend-app/ as a sibling clone). Adjust to your local layout if different.
git -C <workspace>/arda-frontend-app fetch origin maingit -C <workspace>/arda-frontend-app checkout -b <username>/<topic> origin/mainFor project work, prefer a worktree under projects/<project-name>-worktrees/ rather than touching the main clone.
2. Make the change
Section titled “2. Make the change”Follow the repo conventions in arda-frontend-app/CLAUDE.md. Notable rules:
- Path alias —
@/maps tosrc/. - Authentication —
useAuth()fromsrc/store/hooks/useAuth.tsis the authoritative auth hook. LegacyAuthContextis being phased out. - API client — never call the ARDA backend directly from the browser. Use
src/lib/ardaClient.ts, which routes throughsrc/app/api/arda/.... - Mock mode —
npm run dev:mock(ormake dev-mock) runs the app with MSW handlers. E2E tests always run in mock mode.
3. Pre-push gate
Section titled “3. Pre-push gate”Run the full local check suite before every push, even for “trivial” changes. The frontend repo has a Makefile target that mirrors the Fast Gate:
cd <workspace>/arda-frontend-appmake checkEquivalent manual sequence:
npm run lintnpx tsc --noEmitnpx jest --no-coverage --watchAll=false --forceExitnpm run buildIf you changed E2E specs, also run a relevant subset locally:
NEXT_PUBLIC_MOCK_MODE=true npm run test:e2e -- --grep "@sanity"The pre-push rule applies to every push, not just the first one. Fix-up commits also need to clear the local gate before being pushed.
4. Open the PR
Section titled “4. Open the PR”The repository’s PR template scaffolds the structure. Fill in:
- Summary — what the PR does and why.
- CHANGELOG — the section the merge automation reads. See CHANGELOG conventions below.
- Closes —
Closes #<issue>lines for any issues this PR resolves. - Test Plan — checklist of what you verified (or what should be verified post-merge).
PR title follows conventional commits: <type>: <short description> where type is one of feat, fix, refactor, test, docs, chore.
If you are an agent or contributing on someone’s behalf, append the attribution block to the PR body and to every comment you post:
> [!note]> Authored by <Tool Name> for <github-username>5. Watch the Fast Gate
Section titled “5. Watch the Fast Gate”| Required check | Typical time | What it does |
|---|---|---|
lint | ~30s | ESLint |
build | ~3 min | Next.js production build (includes typecheck) |
unit-tests-coverage | ~3 min | Jest + coverage threshold enforcement |
changelog-check | ~10s | Validates the ## CHANGELOG section in the PR body |
e2e | ~5s | Pass-through summary on PR — shards skip on pull_request |
quarantine-check | ~5s | Validates @quarantine tags + budget |
If a check fails, fix the issue locally, re-run make ci, and push the fix. The Fast Gate reruns automatically. Do not push to a branch that is already in the merge queue — the push is rejected.
6. Review comments
Section titled “6. Review comments”Address every reviewer comment before approval. The conventions:
- Code change — make it locally, run
make ci, push. Reply to the comment with the commit SHA:Fixed in <sha> — <one-line summary>. - Reply only — explain the rationale.
- Defer — open a follow-up issue using
/gh-ticket(orgh issue create) and reply withTracked in <ticket-url>. - Ignore — reply with the rationale.
Resolve every review thread once it has been addressed. The pr-steward skill automates this.
7. Approval and merge queue entry
Section titled “7. Approval and merge queue entry”The repository requires at least one approving review and no pending “request changes” review. Once approved:
mergeStateStatus: BLOCKED → CLEANClick “Merge when ready” in the GitHub UI (or run gh pr merge <num> --auto --squash). The PR enters the merge queue.
8. Watch the Queue Gate
Section titled “8. Watch the Queue Gate”The Queue Gate runs against the rebased merge commit (gh-readonly-queue/main/pr-<num>-<sha>):
| Required check | Typical time | What it does |
|---|---|---|
lint, build, unit-tests-coverage | ~5 min | Re-run on the rebased code (zero added wall time — finishes before E2E) |
changelog-check | pass-through | Already validated on PR; passes through in queue |
e2e-sanity-{alpha,bravo} | ~5–8 min | Sanity E2E shards |
e2e-acceptance-{alpha,bravo,charlie} | ~10–15 min | Acceptance E2E shards |
quarantine-check | ~5s | Quarantine tag + budget validation on the rebased commit |
Possible outcomes
Section titled “Possible outcomes”- Success — PR merges automatically. Skip to post-merge.
- Bisection re-queue — your PR was batched with others; the batch failed and GitHub bisected. The offending PR is removed and your PR re-enters the queue automatically. No action needed.
- Ejection (your PR caused the failure) — your PR is removed from the queue and reopened. Investigate the failure, fix it on a new push, re-approve if needed, and re-enter the queue.
9. Post-merge
Section titled “9. Post-merge”Three workflows run automatically on main after the merge commit lands:
- Changelog Assembly (
changelog-assembly.yaml)- Extracts the
## CHANGELOGentries from your PR description (or the last## CHANGELOGcomment). - Computes the SemVer bump from
.github/clq/changemap.json. - Updates
CHANGELOG.md,package.json,package-lock.json. - Pushes a
[changelog-assembly]commit usingCHANGELOG_ASSEMBLY_TOKEN(a PAT, so the push triggers downstream workflows). - Runs CLQ validation.
- Creates the GitHub Release.
- Extracts the
- Deploy Frontend (
deploy.yaml) — triggered by the assembly’s success viaworkflow_run.- Runs
source-info→deploy-dev→deploy-stagein series. - In parallel, runs
quality-gate-build→quality-gate-{alpha,bravo}(Extended E2E) →quality-gate-evaluate. - Also runs the non-blocking
quality-gate-quarantinejob. deploy-demoanddeploy-prodrun after stage and a successful evaluate. Prod requires environment-protection approval in the GitHub UI before it actually deploys.
- Runs
- Post-Merge: Changelog Assembly (skipped) — the assembly’s own commit re-enters the assembly workflow, which checks for the
[changelog-assembly]marker and skips. This is the loop-prevention guard.
You do not need to do anything for steps 1 and 2 unless one of them fails (you will be tagged on the auto-created bug issue).
CHANGELOG conventions
Section titled “CHANGELOG conventions”The PR description must include a ## CHANGELOG section with at least one valid category:
## CHANGELOG
### Added- New search-by-tag feature for the items page.
### Fixed- TC-NAV-004 sidebar toggle no longer hangs on slow connections.Valid categories
Section titled “Valid categories”| Category | SemVer bump | Use for |
|---|---|---|
Added | minor | New features |
Changed | major | Intentional breaking changes to existing functionality |
Deprecated | minor | Features marked for future removal |
Fixed | patch | Bugfixes (most common) |
Removed | major | Removed functionality |
Security | patch | Vulnerability fixes |
Be deliberate about category choice — it directly determines the version bump. Internal-only changes belong under Fixed. Reserve Changed and Removed for real breaking changes.
Amending
Section titled “Amending”To amend the CHANGELOG after PR creation, post a comment with a new ## CHANGELOG section. The last ## CHANGELOG found in either the description or in author comments wins.
Do not edit CHANGELOG.md directly
Section titled “Do not edit CHANGELOG.md directly”CI rejects PRs that modify CHANGELOG.md directly (the file is the assembly’s output, not its input). The changelog-check job enforces this.
Quarantining a flaky test
Section titled “Quarantining a flaky test”If a test fails intermittently and you need to ship the change anyway:
- Open an issue describing the flake. Note the test path and a sample failure.
- Tag the test title with
@quarantine(YYYY-MM-DD, #<issue>):test('TC-NAV-004 sidebar toggle @acceptance @quarantine(2026-05-04, #795)', ...); - The expiry date must be ≤ the budget’s
maxExpiryDaysfrom today (default: 7). - The total quarantined count must be ≤ the budget’s
maxQuarantined(default: 5). If you would exceed it, fix or unquarantine an existing test first. - The
quarantine-checkaction validates the tag on every PR.
The quarantined test is excluded from the merge gate but still runs post-merge in the non-blocking quality-gate-quarantine job — its outcome flows into the weekly flaky-test aggregation.
See knowledge-base/flaky-test-quarantine.md for the full lifecycle.
When things go wrong
Section titled “When things go wrong”| Symptom | What to do |
|---|---|
npm error 401 Unauthorized for @arda-cards/* | The repo’s .npmrc reads _authToken=${GITHUB_TOKEN}; locally export GITHUB_TOKEN=$(gh auth token) before npm install. In CI the workflow-level env is already set. |
mergeStateStatus: BLOCKED | Likely missing approval, missing required check, or unresolved review thread. gh pr view <num> --json reviewDecision,statusCheckRollup to inspect. |
| Required check shows skipped on PR | The skipped variant is the queue-only path; the pass-through summary still reports green. |
Push rejected with branch is in merge queue | Wait for the queue to finish. If the PR is ejected, push the fix to the now-reopened branch. |
| Changelog Assembly failed | Check that the PR’s ## CHANGELOG has at least one valid category; verify CLQ accepts the resulting version chain. |
Deploy Frontend failed at quality-gate-build | Likely an npm ci failure (cold cache, missing token) or a workflow-level issue — see Phase 2 design — npm ci auth. |
Appendix — agent companions
Section titled “Appendix — agent companions”| Agent skill | Source | What it automates |
|---|---|---|
pr-steward | workspace/instructions/claude/skills/pr-steward/SKILL.md | Steps 4–9 above. Watches checks, triages reviewer comments, replies and resolves threads, offers queue entry on explicit confirmation, monitors merge_group runs through to merge or ejection. |
pr-body-changelog (knowledge base) | arda-frontend-app/knowledge-base/pr-body-changelog.md | Conventions for ## CHANGELOG sections in the frontend repo. |
The skill never enters the merge queue or merges autonomously — both require an explicit affirmative response in the same session as the request.
Copyright: © Arda Systems 2025-2026, All rights reserved