Skip to content

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.

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.

  1. Branch from latest main as <github-username>/<topic>.
  2. Make your change. Run make ci (or lint + tsc + jest + build) before pushing.
  3. Open a PR. Fill out the ## CHANGELOG section in the description (the template scaffolds it).
  4. The Fast Gate runs (~5 min). Address any review comments and re-push.
  5. Get at least one approving review.
  6. Click “Merge when ready” → PR enters the merge queue.
  7. Queue Gate runs (~10–15 min). On success the PR merges automatically.
  8. Post-merge automation handles the rest (CHANGELOG assembly, version bump, GitHub Release, deploy).

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.

Terminal window
git -C <workspace>/arda-frontend-app fetch origin main
git -C <workspace>/arda-frontend-app checkout -b <username>/<topic> origin/main

For project work, prefer a worktree under projects/<project-name>-worktrees/ rather than touching the main clone.

Follow the repo conventions in arda-frontend-app/CLAUDE.md. Notable rules:

  • Path alias@/ maps to src/.
  • AuthenticationuseAuth() from src/store/hooks/useAuth.ts is the authoritative auth hook. Legacy AuthContext is being phased out.
  • API client — never call the ARDA backend directly from the browser. Use src/lib/ardaClient.ts, which routes through src/app/api/arda/....
  • Mock modenpm run dev:mock (or make dev-mock) runs the app with MSW handlers. E2E tests always run in mock mode.

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:

Terminal window
cd <workspace>/arda-frontend-app
make check

Equivalent manual sequence:

Terminal window
npm run lint
npx tsc --noEmit
npx jest --no-coverage --watchAll=false --forceExit
npm run build

If you changed E2E specs, also run a relevant subset locally:

Terminal window
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.

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.
  • ClosesCloses #<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>
Required checkTypical timeWhat it does
lint~30sESLint
build~3 minNext.js production build (includes typecheck)
unit-tests-coverage~3 minJest + coverage threshold enforcement
changelog-check~10sValidates the ## CHANGELOG section in the PR body
e2e~5sPass-through summary on PR — shards skip on pull_request
quarantine-check~5sValidates @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.

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 (or gh issue create) and reply with Tracked in <ticket-url>.
  • Ignore — reply with the rationale.

Resolve every review thread once it has been addressed. The pr-steward skill automates this.

The repository requires at least one approving review and no pending “request changes” review. Once approved:

mergeStateStatus: BLOCKED → CLEAN

Click “Merge when ready” in the GitHub UI (or run gh pr merge <num> --auto --squash). The PR enters the merge queue.

The Queue Gate runs against the rebased merge commit (gh-readonly-queue/main/pr-<num>-<sha>):

Required checkTypical timeWhat it does
lint, build, unit-tests-coverage~5 minRe-run on the rebased code (zero added wall time — finishes before E2E)
changelog-checkpass-throughAlready validated on PR; passes through in queue
e2e-sanity-{alpha,bravo}~5–8 minSanity E2E shards
e2e-acceptance-{alpha,bravo,charlie}~10–15 minAcceptance E2E shards
quarantine-check~5sQuarantine tag + budget validation on the rebased commit
  • 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.

Three workflows run automatically on main after the merge commit lands:

  1. Changelog Assembly (changelog-assembly.yaml)
    • Extracts the ## CHANGELOG entries from your PR description (or the last ## CHANGELOG comment).
    • Computes the SemVer bump from .github/clq/changemap.json.
    • Updates CHANGELOG.md, package.json, package-lock.json.
    • Pushes a [changelog-assembly] commit using CHANGELOG_ASSEMBLY_TOKEN (a PAT, so the push triggers downstream workflows).
    • Runs CLQ validation.
    • Creates the GitHub Release.
  2. Deploy Frontend (deploy.yaml) — triggered by the assembly’s success via workflow_run.
    • Runs source-infodeploy-devdeploy-stage in series.
    • In parallel, runs quality-gate-buildquality-gate-{alpha,bravo} (Extended E2E) → quality-gate-evaluate.
    • Also runs the non-blocking quality-gate-quarantine job.
    • deploy-demo and deploy-prod run after stage and a successful evaluate. Prod requires environment-protection approval in the GitHub UI before it actually deploys.
  3. 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).

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.
CategorySemVer bumpUse for
AddedminorNew features
ChangedmajorIntentional breaking changes to existing functionality
DeprecatedminorFeatures marked for future removal
FixedpatchBugfixes (most common)
RemovedmajorRemoved functionality
SecuritypatchVulnerability 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.

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.

CI rejects PRs that modify CHANGELOG.md directly (the file is the assembly’s output, not its input). The changelog-check job enforces this.

If a test fails intermittently and you need to ship the change anyway:

  1. Open an issue describing the flake. Note the test path and a sample failure.
  2. Tag the test title with @quarantine(YYYY-MM-DD, #<issue>):
    test('TC-NAV-004 sidebar toggle @acceptance @quarantine(2026-05-04, #795)', ...);
  3. The expiry date must be ≤ the budget’s maxExpiryDays from today (default: 7).
  4. The total quarantined count must be ≤ the budget’s maxQuarantined (default: 5). If you would exceed it, fix or unquarantine an existing test first.
  5. The quarantine-check action 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.

SymptomWhat 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: BLOCKEDLikely missing approval, missing required check, or unresolved review thread. gh pr view <num> --json reviewDecision,statusCheckRollup to inspect.
Required check shows skipped on PRThe skipped variant is the queue-only path; the pass-through summary still reports green.
Push rejected with branch is in merge queueWait for the queue to finish. If the PR is ejected, push the fix to the now-reopened branch.
Changelog Assembly failedCheck that the PR’s ## CHANGELOG has at least one valid category; verify CLQ accepts the resulting version chain.
Deploy Frontend failed at quality-gate-buildLikely an npm ci failure (cold cache, missing token) or a workflow-level issue — see Phase 2 design — npm ci auth.
Agent skillSourceWhat it automates
pr-stewardworkspace/instructions/claude/skills/pr-steward/SKILL.mdSteps 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.mdConventions 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.