diff --git a/.planning/phases/14-pax8-ui-surface/14-CONTEXT.md b/.planning/phases/14-pax8-ui-surface/14-CONTEXT.md
new file mode 100644
index 0000000..1d45f1e
--- /dev/null
+++ b/.planning/phases/14-pax8-ui-surface/14-CONTEXT.md
@@ -0,0 +1,205 @@
+# Phase 14: /pax8 UI Surface - Context
+
+**Gathered:** 2026-07-11
+**Status:** Ready for planning
+
+
+## Phase Boundary
+
+A new `/pax8` page where any authenticated manager can see PAX8 companies with
+their subscriptions and a cost breakdown, and an admin can resolve flagged or
+ambiguous company matches (populated by Phase 12's fuzzy matcher) directly
+from that same page — no `psql` required. No new sync logic (Phases 11-12
+already built and schedule it — Phase 13), no changes to the matching
+algorithm itself, no PAX8 write access (read-only view + resolve-to-Autotask
+metadata only).
+
+
+
+
+## Implementation Decisions
+
+User deferred to Claude's judgment on all four gray areas identified. Decisions below are grounded in existing Pulse conventions and Phase 12/13 schema, documented as concrete direction for research/planning — not open questions.
+
+### Company List & Cost Breakdown Layout
+- **D-01:** Main company list uses `components/admin/DataTable.tsx` (the
+ established `@tanstack/react-table` wrapper used throughout Pulse) rather
+ than a bespoke card grid — consistent with every other tabular list in the
+ app, gives sorting/search/pagination for free.
+- **D-02:** Per-company cost breakdown is a drill-down via
+ `components/admin/DetailModal.tsx` (formatted/raw tab pattern), not inline
+ in the table row — keeps the main list scannable. The formatted tab shows
+ subscriptions (product name, quantity, billing term) and a cost summary;
+ raw tab shows the underlying JSON for support/debugging, matching every
+ other DetailModal usage in the codebase.
+- **D-03:** Cost breakdown is grouped **by subscription/product**, not a
+ single total — matches `pax8_subscriptions`/`pax8_order_items` granularity
+ and gives managers the "what am I paying for" answer, not just "how much."
+ Note the schema quirk from Phase 12 research: `pax8_orders.pax8_company_id`
+ is always NULL (PAX8's `/invoices` API never populates it) — actual
+ per-company cost data must be joined from `pax8_order_items.pax8_company_id`
+ and `start_period`/`end_period`, not from `pax8_orders` directly.
+
+### Review/Resolution Section & Flow
+- **D-04:** The flagged/ambiguous review queue is a **section/tab within
+ `/pax8`** (e.g., "Companies" / "Needs Review" tabs on the same page), not a
+ separate top-level route — matches the roadmap's explicit "directly from
+ that page" wording (SC#4), even though the closest existing precedent
+ (`app/admin/device-link-conflicts/page.tsx`) is a standalone page. Reuse
+ that page's card-list-with-resolve-action UI pattern, just embedded as a
+ tab rather than routed separately.
+- **D-05:** Resolution UI offers **both**: pick from the top-3 stored
+ candidates (`pax8_company_match_review.candidate_company_ids` +
+ `match_confidences`, already computed by Phase 12 — zero extra query cost)
+ as the primary path, with a manual company search/picker as a fallback —
+ required regardless for Phase 12's D-03 zero-candidate case (empty
+ `candidate_company_ids` array), and useful even when candidates exist but
+ none are correct.
+- **D-06:** Resolving writes `resolved_at`, `resolved_by_user_id`,
+ `resolved_to_company_id`, optional `resolution_note` — mirrors
+ `device_link_review`'s resolve shape exactly (same columns exist on
+ `pax8_company_match_review` per Phase 12's schema). This is what makes the
+ resolution "persist and be respected by future syncs" (SC#4) — Phase 12's
+ D-05 already scopes re-matching to `resolved_at IS NULL` rows only.
+
+### Access & Permissions Split
+- **D-07:** Viewing `/pax8` (company list + cost breakdown) requires only
+ `requireAuth()` — any authenticated user, matching the roadmap's "a manager
+ can open /pax8" framing and how other read-heavy pages (dashboard, tickets)
+ work today.
+- **D-08:** The resolve action (mutating a match) requires
+ `requirePermission('admin', 'access')` — matching
+ `/api/admin/device-link-conflicts/[id]/resolve`'s existing pattern exactly.
+ This intentionally differs from that precedent's GET route (which is
+ admin-gated end-to-end) because Phase 14's roadmap explicitly splits
+ "manager views" from "admin resolves" — the read/write permission split is
+ a deliberate phase-14 decision, not an oversight.
+- **Note for the planner:** Phase 13's code review (`13-REVIEW.md`, CR-02)
+ flagged that the adjacent `POST /api/pax8/sync` route has no role check at
+ all — a pre-existing gap, out of Phase 13's scope. Phase 14 should NOT
+ repeat that gap: every new API route this phase adds must have an explicit
+ `requireAuth()`/`requirePermission()` call, not an implicit "whatever
+ middleware allows."
+
+### No-Candidate / Edge-Case Handling
+- **D-09:** A review row with an empty `candidate_company_ids` array shows
+ the same review-section UI with an explicit empty state ("No suggested
+ matches — search manually") rather than a separate flow or page — the
+ manual-search fallback from D-05 handles this case naturally, no special-
+ casing needed beyond the empty-state copy.
+
+### Claude's Discretion
+- Exact tab/section labels, table column set, and DetailModal field layout —
+ left to the planner/researcher; no specific mockup or wording was given.
+- Whether "Needs Review" tab shows a count badge, and sort/filter options on
+ the main company list — standard implementation details, not discussed.
+
+
+
+
+## Canonical References
+
+**Downstream agents MUST read these before planning or implementing.**
+
+### Project scope & requirements
+- `.planning/PROJECT.md` — Current Milestone: v2.0 PAX8 Integration section
+- `.planning/REQUIREMENTS.md` — PAX8-12, PAX8-13, PAX8-14 (this phase's
+ requirement IDs)
+- `.planning/ROADMAP.md` — Phase 14 section (goal, 4 success criteria,
+ depends on Phase 12)
+
+### Prior phase foundation this phase builds on
+- `migrations/091_pax8_tables.sql` — `pax8_companies`, `pax8_products`,
+ `pax8_subscriptions`, `pax8_orders`, `pax8_order_items`,
+ `pax8_company_match_review` — full schema this page reads from
+- `migrations/093_pax8_orders_company_matching.sql` — `pax8_companies`
+ auto-match columns (`autotask_company_id`, `match_confidence`,
+ `match_method`, `matched_at`) and the critical note that
+ `pax8_orders.pax8_company_id` is always NULL — cost-per-company data comes
+ from `pax8_order_items` instead
+- `.planning/phases/12-orders-invoices-company-matching/12-CONTEXT.md` —
+ D-01 through D-05 (match confidence, ambiguous handling, empty-candidate
+ flagging, top-3 candidate cap, re-scoring rules) — the review queue this
+ phase surfaces
+- `.planning/phases/13-scheduler-admin-toggle/13-REVIEW.md` — CR-02 finding
+ (missing permission check on `/api/pax8/sync`) — this phase's new routes
+ must not repeat that gap (see D-08 note above)
+
+### Existing patterns to follow
+- `app/admin/device-link-conflicts/page.tsx` — direct precedent for the
+ review/resolve UI (list + resolve action, card-based); this phase embeds
+ the same pattern as a tab/section rather than a standalone route
+- `app/api/admin/device-link-conflicts/route.ts` and
+ `app/api/admin/device-link-conflicts/[id]/resolve/route.ts` — API shape
+ (list with filters, resolve with `requirePermission('admin', 'access')`)
+ to mirror for `pax8_company_match_review`
+- `components/admin/DataTable.tsx` — table wrapper for the main company list
+- `components/admin/DetailModal.tsx` — formatted/raw tab pattern for the
+ per-company cost breakdown drill-down
+- `lib/auth-utils.ts` — `requireAuth()` / `requirePermission()` helpers this
+ phase's routes must use explicitly (D-07/D-08)
+
+
+
+
+## Existing Code Insights
+
+### Reusable Assets
+- `components/admin/DataTable.tsx` — sortable/searchable/paginated table,
+ used as-is for the company list
+- `components/admin/DetailModal.tsx` — formatted/raw tabs, used as-is for
+ the cost-breakdown drill-down
+- `postgresClient` singleton — parameterized queries, no ORM, joins across
+ `pax8_companies` / `pax8_subscriptions` / `pax8_order_items` /
+ `pax8_company_match_review`
+
+### Established Patterns
+- Admin CRUD pages live at `app/admin//page.tsx` with a matching
+ `app/api/admin//route.ts` — but this page is NOT admin-only
+ (D-07/D-08 split), so its route likely lives at `app/pax8/page.tsx` (top
+ level, alongside `/dashboard`, `/mobile`), not under `/admin`
+- `*_match_review` tables (both `device_link_review` and
+ `pax8_company_match_review`) follow list-with-filter + single-item-resolve
+ API shape: `GET /api/.../conflicts?source=X` + `POST /api/.../[id]/resolve`
+- Toasts via `sonner`, icons via `lucide-react` — standard for the resolve
+ action's success/error feedback
+
+### Integration Points
+- New `app/pax8/page.tsx` — main page with Companies / Needs Review tabs
+- New API routes for: company list + cost data, match-review list, and
+ resolve action (exact paths left to planner — likely
+ `app/api/pax8/companies/route.ts`,
+ `app/api/pax8/company-matches/route.ts` +
+ `app/api/pax8/company-matches/[id]/resolve/route.ts`)
+- `components/navigation/app-navigation.tsx` — needs a new top-level nav
+ entry for `/pax8` (not nested under Admin, given D-07's broader view
+ access)
+
+
+
+
+## Specific Ideas
+
+No UI mockups or specific behavioral scripts were provided — the nine
+numbered decisions above (D-01 through D-09) are the concrete specifics:
+DataTable + DetailModal-drill-down layout, embedded review tab (not a
+separate page) with dual pick-from-candidates/search resolution, an explicit
+manager-view/admin-resolve permission split, and empty-state handling for
+the zero-candidate case.
+
+
+
+
+## Deferred Ideas
+
+None — discussion stayed within Phase 14's scope. (PAX8 write access,
+seat-adjustment actions, and any general natural-language assistant over
+this data are already explicitly out of scope per PROJECT.md, not deferred
+from this discussion.)
+
+
+
+---
+
+*Phase: 14-pax8-ui-surface*
+*Context gathered: 2026-07-11*
diff --git a/.planning/phases/14-pax8-ui-surface/14-DISCUSSION-LOG.md b/.planning/phases/14-pax8-ui-surface/14-DISCUSSION-LOG.md
new file mode 100644
index 0000000..06f47ae
--- /dev/null
+++ b/.planning/phases/14-pax8-ui-surface/14-DISCUSSION-LOG.md
@@ -0,0 +1,59 @@
+# Phase 14: /pax8 UI Surface - Discussion Log
+
+> **Audit trail only.** Do not use as input to planning, research, or execution agents.
+> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.
+
+**Date:** 2026-07-11
+**Phase:** 14-pax8-ui-surface
+**Areas discussed:** Company list & cost breakdown layout, Review/resolution section & flow, Access & permissions split, No-candidate / edge-case handling
+
+---
+
+All four gray areas were presented via a single multiSelect question. The user responded "Use your best judgement" rather than selecting specific areas or answering individually — deferring all four decisions to Claude, grounded in existing codebase precedent.
+
+## Company List & Cost Breakdown Layout
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| DataTable (list) + DetailModal (cost drill-down) | Reuses `components/admin/DataTable.tsx` + `components/admin/DetailModal.tsx`, matches every other tabular list in Pulse | ✓ (Claude's judgment) |
+| Custom card grid | Would be a new visual pattern, not currently used elsewhere | |
+| Inline cost breakdown in table rows | Keeps everything in one view but risks cluttering the row | |
+
+**Notes:** Cost breakdown grouped by subscription/product (D-03), not a single total — matches schema granularity. Flagged the `pax8_orders.pax8_company_id` always-NULL quirk from Phase 12 research; cost data must join through `pax8_order_items` instead.
+
+## Review/Resolution Section & Flow
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Embedded tab/section within `/pax8` | Matches roadmap's "directly from that page" wording | ✓ (Claude's judgment) |
+| Separate standalone page (device-link-conflicts precedent) | Existing precedent's actual shape, but roadmap explicitly wants it on the same page | |
+
+**Notes:** Resolution UI offers both pick-from-top-3-candidates (already computed by Phase 12) and manual search fallback (required anyway for the zero-candidate case).
+
+## Access & Permissions Split
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| View = any authenticated user, Resolve = admin-only | Matches roadmap's explicit "manager views / admin resolves" framing | ✓ (Claude's judgment) |
+| Entire page admin-gated | Matches the closest existing precedent (device-link-conflicts) exactly, but contradicts roadmap wording | |
+
+**Notes:** Explicitly flagged Phase 13's CR-02 code-review finding (missing permission check on `/api/pax8/sync`) as a gap this phase's new routes must not repeat.
+
+## No-Candidate / Edge-Case Handling
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Same review UI with an empty state | No special-casing needed beyond copy — manual search fallback already covers it | ✓ (Claude's judgment) |
+| Separate flow/page for zero-candidate companies | Unnecessary complexity for a copy-level difference | |
+
+---
+
+## Claude's Discretion
+
+- Exact tab/section labels, table column set, DetailModal field layout
+- Whether a count badge appears on the "Needs Review" tab
+- Sort/filter options on the main company list
+
+## Deferred Ideas
+
+None — discussion stayed within Phase 14's scope.