diff --git a/.planning/phases/10-pax8-client-auth-foundation/10-CONTEXT.md b/.planning/phases/10-pax8-client-auth-foundation/10-CONTEXT.md
new file mode 100644
index 0000000..050c468
--- /dev/null
+++ b/.planning/phases/10-pax8-client-auth-foundation/10-CONTEXT.md
@@ -0,0 +1,163 @@
+# Phase 10: PAX8 Client & Auth Foundation - Context
+
+**Gathered:** 2026-07-10
+**Status:** Ready for planning
+
+
+## Phase Boundary
+
+Pulse can authenticate to the PAX8 REST API (`api.pax8.com/v1`) via OAuth2
+client-credentials, and the Postgres schema for all PAX8 entities exists —
+companies, subscriptions, product catalog, orders/order-line-items, and a
+company-match review queue. No sync logic, no company-matching logic, no
+`/pax8` UI, and no scheduler wiring in this phase — those are Phase 11-14.
+This phase proves the auth + schema foundation only.
+
+
+
+
+## Implementation Decisions
+
+### Orders / Invoices Schema
+- **D-01:** Two-table design — `pax8_orders` (header: order id, company,
+ order date, total, status) + `pax8_order_items` (line-item detail:
+ `order_id` FK, product/SKU, quantity, unit price, line total). Matches
+ PAX8's own order shape (an order has N line items) and avoids repeating
+ order-level fields on every line.
+- **D-02:** No lookback-window bound. Sync (built in a later phase) pulls
+ full order history PAX8's API returns on first sync — no "earliest
+ synced" or window-config column needed in this phase's migration.
+- **D-03:** Both `pax8_orders` and `pax8_order_items` carry a `raw_payload
+ JSONB` column alongside typed columns, as a safety net for PAX8 fields
+ not yet modeled. Mirrors the `itglue-search.ts` precedent of not
+ discarding API data even when only a subset is used today.
+- **D-04:** Monetary amounts use `NUMERIC(12,2)` + a `currency CHAR(3)
+ DEFAULT 'USD'` column on both orders and line items — cheap insurance
+ against a future non-USD client without requiring a schema migration
+ later.
+
+### Claude's Discretion
+The user chose to discuss only Orders/Invoices granularity. The following
+gray areas were surfaced but explicitly left to the planner/executor,
+default to the closest existing codebase pattern:
+
+- **Company match/review table shape** — model on `device_link_review`
+ (migration `080_device_xref_company_id.sql`): a conflicts/review queue
+ with candidate match(es), confidence, `resolved_at`/`resolved_by_user_id`/
+ `resolution_note`. Adapt field names for PAX8 companies →
+ Autotask companies instead of device → CI matching. This table is
+ created in this phase's migration but populated by Phase 12's matching
+ logic — schema should anticipate that consumer without over-designing it.
+- **Product catalog scope** — no explicit decision; planner may choose
+ full-catalog sync or lazy/referenced-only population. This is a Phase
+ 11 sync-service decision more than a Phase 10 schema decision — the
+ `pax8_products` table shape should accommodate either without requiring
+ a redesign (e.g., don't add a "referenced only" constraint at the schema
+ level).
+- **Raw payload retention on other tables** — whether `pax8_companies`,
+ `pax8_subscriptions`, and `pax8_products` also get a `raw_payload`
+ JSONB column. Given D-03 established this pattern for orders, applying
+ it consistently across all four PAX8 tables is a reasonable default
+ unless the planner has a specific reason not to (e.g., a table is fully
+ and confidently typed).
+
+
+
+
+## Canonical References
+
+**Downstream agents MUST read these before planning or implementing.**
+
+### Project scope & requirements
+- `.planning/PROJECT.md` — Current Milestone: v2.0 PAX8 Integration section;
+ states read-only scope, out-of-scope write access, and the SEED-003
+ future-consumer design note ("build the Postgres schema with that eventual
+ consumer in mind - clean, well-typed tables, avoid PAX8-API-shaped blobs")
+- `.planning/REQUIREMENTS.md` — PAX8-01, PAX8-02 (this phase's requirement
+ IDs); also PAX8-03..14 for downstream-phase awareness of what this schema
+ must support later
+- `.planning/seeds/SEED-002-pax8-integration.md` — original exploration:
+ auth breadcrumbs (client ID/secret already provisioned), pattern
+ breadcrumbs (`lib/services/-client.ts` + `-factory.ts`), entity
+ list (companies/subscriptions/catalog/orders), and the "fuzzy name match
+ at sync time, flag ambiguous for manual review" design fork
+- `.planning/research/questions.md` — `RESEARCH-pax8-company-identifiers`:
+ open question on whether PAX8 exposes a stable identifier (domain,
+ external ID) beyond company name — worth checking PAX8's `companies`
+ endpoint response shape before Phase 12 commits fully to fuzzy name
+ matching. Not blocking for this phase (schema should keep the door open:
+ don't build the match table assuming name is the only comparable field).
+
+### Existing patterns to follow
+- `lib/services/msgraph-client.ts` + `lib/services/msgraph-factory.ts` —
+ closest existing OAuth2 client-credentials pattern (token endpoint POST,
+ in-memory token + expiry cache, `isConfigured()` + throw-if-missing).
+ PAX8's auth client should follow this shape, not the Veeam API-key shape.
+- `lib/services/veeam-factory.ts` — canonical `isConfigured()` +
+ singleton + throw-with-clear-message-if-missing-creds pattern (same shape
+ msgraph-factory.ts follows; both are valid reference points).
+- `migrations/080_device_xref_company_id.sql` (`device_link_review` table) —
+ reference shape for the PAX8 company-match/review table (see Claude's
+ Discretion above).
+- `migrations/081_integration_settings.sql` — integration toggle table;
+ PAX8's toggle row is added in Phase 13, not this phase — do not seed it
+ here.
+- `CLAUDE.md` "External integrations" table — env var prefix convention
+ (`PAX8_*`); add PAX8 to this table and to `INTEGRATIONS.md` once the
+ client exists.
+
+
+
+
+## Existing Code Insights
+
+### Reusable Assets
+- `lib/services/msgraph-client.ts` — direct template for OAuth2
+ client-credentials token exchange (`getToken()` with expiry-aware
+ in-memory caching), including the exact `fetch` + `URLSearchParams` shape
+ to adapt for PAX8's token endpoint.
+- `lib/services/msgraph-factory.ts` — direct template for
+ `isPax8Configured()` / `getPax8Client()` / `resetPax8Client()`.
+
+### Established Patterns
+- Factory + `isConfigured()` + throw-if-missing-creds is used
+ uniformly across all ~15 existing integrations — no deviation expected
+ here.
+- Migration numbering is sequential regardless of gaps; next number after
+ `090_ticket_reconcile_schedule.sql` is `091`.
+- Match/review queues for ambiguous cross-system links use a dedicated
+ table (`device_link_review`) rather than a status column on the primary
+ entity table, keeping the "needs human review" concern separate from
+ the synced data itself.
+
+### Integration Points
+- New files: `lib/services/pax8-client.ts`, `lib/services/pax8-factory.ts`,
+ `lib/types/pax8.ts` (types barrel, per `lib/types/.ts` convention),
+ new migration `091_pax8_tables.sql` (or similar name).
+- No route/nav/UI integration in this phase (`UI hint: no` per ROADMAP.md).
+
+
+
+
+## Specific Ideas
+
+No specific UI or behavioral references were given — this phase is schema
+and client plumbing only. The concrete decisions are the four Orders/
+Invoices schema points (D-01 through D-04) above.
+
+
+
+
+## Deferred Ideas
+
+None — discussion stayed within phase scope. (Company matching logic,
+product catalog population strategy, the `/pax8` UI, and scheduler wiring
+are already sequenced into Phases 11-14 per ROADMAP.md and REQUIREMENTS.md
+— not deferred from this discussion, just out of this phase's boundary.)
+
+
+
+---
+
+*Phase: 10-pax8-client-auth-foundation*
+*Context gathered: 2026-07-10*
diff --git a/.planning/phases/10-pax8-client-auth-foundation/10-DISCUSSION-LOG.md b/.planning/phases/10-pax8-client-auth-foundation/10-DISCUSSION-LOG.md
new file mode 100644
index 0000000..0e8f185
--- /dev/null
+++ b/.planning/phases/10-pax8-client-auth-foundation/10-DISCUSSION-LOG.md
@@ -0,0 +1,75 @@
+# Phase 10: PAX8 Client & Auth Foundation - 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-10
+**Phase:** 10-pax8-client-auth-foundation
+**Areas discussed:** Orders/invoices granularity
+
+---
+
+## Gray areas presented (multiSelect)
+
+| Area | Description | Selected |
+|------|-------------|----------|
+| Match/review table shape | Model on `device_link_review` (candidate array + confidences) vs. simpler single-best-guess + status enum | |
+| Product catalog scope | Full PAX8 catalog vs. lazily populated from referenced subscriptions only | |
+| Orders/invoices granularity | Line-item grain with header+items tables vs. flat single table | ✓ |
+| Raw payload retention | JSONB safety-net column per row vs. fully typed columns only | |
+
+**User selected:** Orders/invoices granularity only. The other three were left to the planner's discretion (see CONTEXT.md "Claude's Discretion").
+
+---
+
+## Orders/Invoices Granularity
+
+### Q1 — Grain
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Two tables (header + line items) | `pax8_orders` (order id, company, order date, total, status) + `pax8_order_items` (order_id FK, product/SKU, quantity, unit price, line total). Matches PAX8's own order shape. | ✓ |
+| One flat table | `pax8_order_items` only, order-level fields repeated per line. Simpler queries, no natural home for order status/totals. | |
+
+**User's choice:** Two tables (header + line items)
+
+### Q2 — Backfill window
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Full history, no bound | Pull everything on first sync, no lookback-window column needed. | ✓ |
+| Bounded lookback window | e.g. last 24 months; requires a config value and sync logic to respect it. | |
+
+**User's choice:** Full history, no bound
+
+### Q3 — Raw JSON safety net
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Yes, keep raw_payload JSONB | Typed columns for used fields + raw_payload JSONB per row for anything not yet modeled. | ✓ |
+| No, typed columns only | Fully committed to normalized columns per PROJECT.md's "avoid PAX8-API-shaped blobs" guidance. | |
+
+**User's choice:** Yes, keep raw_payload JSONB
+
+### Q4 — Currency handling
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| NUMERIC amount + currency code column | `NUMERIC(12,2)` + `CHAR(3) DEFAULT 'USD'` on orders and line items. | ✓ |
+| USD-only, no currency column | `NUMERIC(12,2)` only, assume USD everywhere. | |
+
+**User's choice:** NUMERIC amount + currency code column
+
+**Notes:** No additional follow-up questions requested — user moved straight to wrap-up after the 4 questions.
+
+---
+
+## Claude's Discretion
+
+- Company match/review table shape — follow `device_link_review` (migration 080) as the closest precedent, adapted for PAX8 company → Autotask company matching.
+- Product catalog scope (full vs. lazy/referenced-only) — deferred to Phase 11's sync-service design; schema should not preclude either approach.
+- Raw payload retention on `pax8_companies` / `pax8_subscriptions` / `pax8_products` — reasonable to apply the same JSONB safety-net pattern established for orders (D-03), for consistency, unless the planner has a specific reason not to.
+
+## Deferred Ideas
+
+None — discussion stayed within Phase 10's boundary. Company matching logic (Phase 12), product catalog population (Phase 11), the `/pax8` UI (Phase 14), and scheduler wiring (Phase 13) are already sequenced elsewhere in ROADMAP.md/REQUIREMENTS.md.