Part of the Simple Agility stack. Canonical copy:
~/source/stockroom/docs/superpowers/plans/2026-10-03-stockroom-phase-2-pricing-triage.md. It has 17 test-first tasks with complete code for every step. This page mirrors the decisions and structure for retrieval. It implements rollout phase 2 of StockroomIntakeInventoryPricingDesign and follows StockroomPhase1FoundationPlan. Status: written 2026-10-03; execution started the same day.
Price every identified item for each sales route (Amazon FBA, eBay, local, buyback, lot). Then triage it to the best route and explain why. The pieces:
triage_rules;The Amazon SP-API price source is not in this plan. It waits for SP-API approval and gets its own small plan.
New core packages:
core.triage: the rules, the pure Triage.decide, and TriageService.core.pricing: the PriceSource port, quotes, net maths, and the price_item job.core.weight: binding and the weight estimate.core.lot: grouping and suggestions.A new adapter module, stockroom-pricing, holds the eBay Browse adapter.
An item that becomes identified enqueues a price_item job. The job:
Manual quotes and overrides apply at once, with no job and no network.
| Topic | Decision |
|---|---|
| eBay access | The Browse adapter is built but disabled until EBAY_CLIENT_ID/EBAY_CLIENT_SECRET are set. eBay documents Buy-API production access as partner-only, so manual quotes are first-class for every route |
| FBA without SP-API | A manual FBA quote takes the list price, sales rank and a restricted flag from the Amazon Seller app; the fees are worked out from the rules |
| eBay comparables | Active fixed-price listings by GTIN, in the item's condition and its neighbours. List price = median of price + fixed shipping; USD only. Confidence comes from the comparables count |
| eBay net | We offer free shipping: list − 15.3% final value fee − $0.30/$0.40 per-order fee − our Media Mail (books) or Ground Advantage postage by weight |
| FBA net | list − 15% referral − $1.80 closing fee − fulfillment by shipping weight (+3.5% surcharge) − inbound per unit |
| Weight | Books: base + per-page × pages, by binding; a plausible Open Library weight wins. It is stored as catalog_estimate unless the operator entered a weight |
| Effective quote | Per route, among usable quotes (not older than quote_max_age_days): the newest manual, else the newest automatic, else the newest derived |
| Triage order | 1. Look-closer or high value → needs a decision (high value also flags look-closer). 2. No usable quotes → needs price. 3. A lot item takes the best of eBay/local. 4. FBA if net ≥ min, rank ≤ cap and not restricted. 5. The best of eBay/local if net ≥ the individual minimum (ties go to local). 6. Buyback ≥ min. 7. Otherwise lot |
| Decision record | Rule fired, reason, expected net (the prediction), quotes used, suppressed routes with measured and required values, rules version, and the item's cost at decision time. An override keeps the recommendation |
| Idempotent jobs | Pricing de-duplicates on item_id + requested_at; an identical decision is not re-inserted. A source cache per (identifier, condition, day) means copies cost one call |
| Lots | A lot is an item of kind lot with no acquisition. Its cost is the sum of its members' costs. Members move to ready. Dissolving returns them to needs_prep. Value = Σ member local value × lot_factor |
| Rules | Versioned in triage_rules; version 1 is seeded at start-up from bundled defaults marked uncalibrated (2026-10 research). Edited on the Rules page |
Five failure modes, each pinned by named tests:
identified, and a manual quote re-triages
immediately.| # | Task |
|---|---|
| 1 | Non-blocking source rate limits and job deferral |
| 2 | Catalog record kind and lock-before-load |
| 3 | Versioned triage rules |
| 4 | Binding, the book weight estimate, and Open Library binding and weight |
| 5 | Pricing schema, routes, statuses and net maths |
| 6 | The pure triage function |
| 7 | TriageService and PricingService |
| 8 | Pricing HTTP and the read side |
| 9 | The automatic pricing job |
| 10 | The eBay Browse adapter (new module) |
| 11 | Lots (backend) |
| 12 | Frontend: wire types, API modules, labels, queues and the item list |
| 13 | Frontend: the item page pricing card |
| 14 | Frontend: the Decide page |
| 15 | Frontend: the Lots page |
| 16 | Frontend: the Rules page |
| 17 | Hand-over: configuration, docs, coverage floors and verification |