# UAS Architecture & Roles (with the agent-core Brain) > Companion to agent-core `docs/planning/20260619124751-uas-agentic-overhaul.md`. > This doc is the UAS-side source of truth for: (a) how UAS works internally, > (b) the brain's role vs UAS's role, and (c) the contract between them. > Status: **DESIGN** — describes current state + the agreed target. ## What UAS is UAS (unified-agentic-sourcing) is an **independent sourcing agent**. Given a sourcing request it: generates specs → searches marketplaces (1688/Alibaba via TMAPI) → verifies → cleans up → spec-matches → ranks → shortlists, and serves the result back to agent-core in a PP-API-compatible shape. It has its own LLM stack, run persistence (`uas_runs`), a global product catalog (`uas_products`/`uas_matches`), cost ledger, and dashboard. It reads `sr_contexts` from the shared Firestore directly. ## Roles: Brain vs UAS **The Brain (agent-core) triggers and guides. UAS does the sourcing.** | Concern | Brain | UAS | |---|---|---| | Understand the customer / conversation | ✅ | reads context | | Decide product, quantity, purpose, customization-need, target price | ✅ | consumes | | Multi-item decomposition + merge | ✅ | per-item run | | **Spec generation (veto/rerank + keywords)** | ❌ (was ✅ — moving out) | ✅ | | Search / keyword expansion | — | ✅ (agentic, ≤5 keyword circuit breaker) | | Cleanup (translate, attributes, weight/dims) | — | ✅ | | Spec matching (+ customization gate, product-type validation) | — | ✅ | | Ranking / shortlist / **product bank ≥30** | — | ✅ | | Price (10%) + MOQ (50%) buffers, trader rules | — | ✅ | | When to re-source / relax / expand | ✅ decides → guides | ✅ executes | | Supplier-responsiveness replacement **rounds** | ✅ coordinates | ✅ serves replacements from bank | | Final quotation review + customer delivery | ✅ | — | Principle: **the brain never authors specs or does matching**; it states intent and steers. UAS owns the craft and reasons its way to a good shortlist. ## Internal architecture (current) ### Entry points (`src/http/server.ts`) - `POST /api/sourcing-jobs` — brain trigger (async, 202, idempotent). **Today** runs the 3-tool search-agent + deterministic back-half (see below). - `POST /api/customer-selection-jobs` — pre-picked products: clean + match + force-shortlist. - `POST /source` — full blocking run via the 6-tool agentic `SourcingBrain`. - `GET /job/:id/products` — PP-API-compatible product read for agent-core. - `GET /api/sr/:id/result`, `GET /api/runs`, `GET /api/runs/:id/result` — reads. - `POST /api/runs/:id/{specs,search,verify,cleanup,match,rank,auto-search,finalize}` — playground / streaming. ### Pipeline stages `specs → (search ↔ verify)* → price-gate → cleanup → match → rank` - **specs** `stages/specs/generate.ts` — LLM spec-gen; OR `integration/sr-context.ts srContextToSpecs` translates brain specs. - **search** `stages/search/search.ts` — TMAPI; `item-detail.ts` resolves variants/skuids. - **verify** `stages/verify/verify.ts` — light veto pre-screen (Flash-lite). - **price-gate** `stages/pricing/price-gate.ts` — withhold over-budget (reversible). - **cleanup** `stages/cleanup/cleanup.ts` — translate/attributes/**weight+dims**. - **match** `stages/matching/matcher.ts` — per-spec verdict; `verdict = anyNotMatch?eliminated : anyUnknownVeto?pending : shortlisted`. - **rank** `stages/matching/rank.ts` — non-eliminated by combined score. ### Workflow vs agentic (the key overhaul lever) - The 6-tool agentic `SourcingBrain` (`src/agent/sourcing-brain.ts`) is **built but only used by `/source`**. - The brain's real path (`integration/sourcing-job.ts`) uses **search-agent (3 tools) + deterministic** `phaseCleanup → phaseMatch → phaseRank(12)`. - **Target**: route `/api/sourcing-jobs` through one agentic orchestrator so the back-half + the decisions (re-keyword, relax, validate, bank-fill) are agent-driven, bounded by `config.sourcing.maxToolIterations` + token budget. ### Run model & persistence - runId == jobId (`job___`). `RunContext` blackboard (`agent/run-context.ts`); persisted via `runs/store.ts` (Firestore/memory). - Catalog reuse gated on `config.catalog.version` (`SOURCING_CATALOG_VERSION`). ## Contract with the Brain > Legend: **CURRENT** = implemented today · **PLANNED** = target design, NOT yet > in the codebase. Don't treat PLANNED items as a live contract. ### Inbound — `POST /api/sourcing-jobs` (`integration/brain-contracts.ts`) — CURRENT - Today: `{ sr_id, sourcing_context{ ...specs }, sourcing_request, images }`. - **Planned**: specs become OPTIONAL; brain sends raw intent + `conversation_summary` / `customer_conversation`; UAS generates specs. (Keep accepting brain-authored specs for back-compat / rollback.) ### Inbound — `POST /api/sourcing-jobs/:id/guide` — ⛔ PLANNED, NOT YET IMPLEMENTED > This endpoint does **not** exist in the codebase today — it is a P2 target (see > the migration phases in the agent-core plan), not a current contract. Brain steers a running/finished run: `{ action: "re_source" | "expand_keywords" | "relax_veto" | "validate_product_type" | "request_replacements", payload }`. `request_replacements` serves N products from the **bank** for a supplier round. ### Outbound — `POST {AGENT_CORE_WEBHOOK_URL}` (`integration/agent-core-webhook.ts`) - **CURRENT** (`JobCompletedWebhookBody`): `{ job_id, sr_id, progress, original_sr }`. - **PLANNED (not yet implemented)**: an optional `needs_clarification` signal so UAS can ask the brain a question. ### Read — `GET /job/:id/products` ProcessedProduct (cleanup_data + spec_matching_data). Serves the **bank** (confirm + possible) so the brain can request replacements without a re-run. ## UAS work items (from the pre-launch checklist) 1. **Customisation gate before shortlisting** — for custom SRs, eliminate non-custom products (today customization is only a rerank). Add to match/shortlist. 2. **Price 10% + MOQ 50% buffers** — `config.pricing.tolerancePct` 0→0.10; add MOQ buffer to the gate. 3. **Product bank ≥30 (confirm+possible) + R1=15**; serve round-based replacements via `/guide request_replacements`. 4. **Trader selection** — surface traders only when no factories AND trader price < target (final shape pending Kim, Mon). 5. **Agentic keyword expansion** on 0 confirm/possible, circuit breaker ≤5 keywords. 6. **Product-type validation** — hard sanity check that matched product type == SR product type (fix protein→collagen/milk false positives). 7. **Matcher recall** — let strong-but-unconfirmable (no veto FAIL) shortlist with a confidence tier, instead of capping at `pending`. ## Validation loop (no agent-core deploy needed) - Re-source against UAS dev; read `GET /api/runs/:id/result` → compare `stats.{shortlisted,eliminated,pending}` and the funnel before/after. - Migration shape: agent-core `scripts/replay-migration.ts` (`--job` / `--post`).