goes to another screengoes to another state of this screenfaded = not mocked yetEverything else — filters, sorts, tabs, modals — works, it just stays on this screen. The URL always names the state you are on, so any view can be copied and shared.
Runs / Batches/Listing builder/J-0112eBay · Response Commerce (US) — channel account CA-01, no store contextCreated 2026-08-29 09:41 · resumable. Account defaults were copied onto the job at creation.
The account decides the marketplace, and it brings its operating defaults and price ladder onto the job. Defaults are copied at job creation — later edits on the account don't change a job already in flight.
Copied from CA-01 operating defaults
ConditionNewQuantity10 units (start, adjust later)ShippingeBay Free, 30-dayHandlingNext business dayShip-fromMiami, FLReturnsStandard policy (reused, never new)
Price ladder2-pack −5%/unit3-pack −10%5-pack −15%sale single −20%Edit on account →
Completed 09:41. Changing the account now would restart the job — SKUs, defaults and collision checks are account-bound.
Products on this job
Pick the catalog products the packages will be built from. Each pick shows what this account has already listed for it — start from a prior listing with Sell similar instead of from scratch.
Add another product
2 products picked. Combos become available in the package builder whenever a job holds more than one product.
Copied from CA-01 at job creationLadder —Final value fee 13%Promoted ad rate 2%Margin floor 35%set on the sales channel — not mocked yetPostage USPS Ground Advantage
Packages are locked while drafts hold an approval.Changing a rule now invalidates the draft approval for every listing it moves (r2) and re-runs their collision checks.
1
Product Pool
2
Shape
A pack size and its discount are added together — the ladder has no row without one.
3
Gift Pool
4
Base Prices
One-bottle item
Price
5
Price Ladder
Tier
Off per unit
Price
Per unit
G-margin
6
Promotions
Listings
Creative brief optional
Nothing here is required. What you set feeds title, description and image prompts across the whole job.
Sale type
Attach a campaign — its SKU token is stamped into every slot (OB-MEMO-3P-SUM-EBY) and its image set pre-fills shared slots — or type a one-off theme that only guides prompts.
Benefits angle
One angle for the whole job. It's injected into every content and image prompt (per-listing overrides are out of scope this round — see Design notes).
Completing this step created job J-0112 at 09:47 — it's resumable from the Listing builder list from here on.
Drafts approved — revision r2 · Paul · 10:18.The approved revision is immutable. Editing any field below reopens that listing's draft (r3) and invalidates its downstream image approvals.
View
Compare pivots the four listings side by side — a wrong price or count breaks the row.
From CA-01 account defaults — not asked per listing
ConditionNewQuantity10ShippingeBay Free, 30-dayHandlingNext business dayShip-fromMiami, FLReturnsStandard policy
Title
77/80 — over eBay's 80-char limit; approval is blocked until it fits · Brand + Name + Type + Key feature + Count
Category
eBay-suggested · verified by drafter — regulated category, never re-pick for exposure
Item specifics
Brand
VitaLifes
Type
Memory support supplement
Formulation
Capsule
Count
60 capsules (1 bottle)
Main purpose
Memory & focus
Department
Unisex adults
Country of manufacture
United States
UPC
83169900279-8
Drafted from catalog facts — "never guess": blank beats invented. Count is per-package (L2 says 120, L3 says 180). Bundles and combos send no UPC.
Description
Drafted per package from the job prompt (campaign + angle injected)
Compliance
Claim gate — clear. 3 claims matched the approved claim library; no BLOCK or REVIEW findings on this listing's content.
1 resolved finding
REVIEW (resolved 10:14): draft said "clinically proven recall" — not in the claim library. Reworded to "formulated for memory & focus"; approved in r2.
Priceladder · sale single −20%est. margin 63% · shipped total $31.99
pre-fills L4 only — a combo is its own product set, it never inherits a single product's set
No supplemental set yet. Generate one from both products' base images, or pick existing combo imagery from the library. L4 can't reach final review without it.
Hero — one per listing
depicts the actual package, carries the campaign text, owns the -D<n> design revision
L1 · Memopryl × 1-D1Hero status: approved v1
"END OF SUMMER" flash + single bottle · claim check clear · filed to library 10:31
Hero overlay "boosts memory in weeks" isn't in the claim library — reword or approve an exception. Lifestyle slot detached & customized for this listing.
6 slots pre-filled from the Memopryl shared set; hero v1 in flight (attempt 1, est. $0.09).
L4 · Memopryl + CogniHoneyCOMBOListing images: blocked — no combo supplemental set
A combo is its own product set — build or pick its supplemental set (see the combo card in By asset). Hero can start independently.
ShipStation sync
Builds the ShipStation product behind every listing on this job — the record that connects an eBay SKU to the actual bottle the warehouse picks off a shelf. Two jobs run per listing: the API build, then the two settings that only exist inside ShipStation's own website. Nothing on this job goes live on eBay until every listing here is done.
Building these records early is safe — a ShipStation product is internal, no customer ever sees it. All four listings are built here, whether or not they are ready to push, so pushing never waits on this step.
writes to ShipStation on CA-01 · nothing is sent to eBay from this stepShipStation sign-in status: sign-in healthy · 6 days ago
The actual bottles inside the bundles, shared by every listing on the job. Both records — the QuickBooks item and the ShipStation product — were created when the catalog product was set up, so this is a check, not work. On a bundle, ShipStation ignores the weight we send and adds up these weights instead — so these are the numbers that rate a real shipping label. A missing weight, or one that no longer agrees with the catalog, stops this step.
FP-COGH-30 has no weight. ShipStation would rate every order of the listing that contains it as though the box were empty, and we would pay the difference. This is a catalog problem, not a job problem — fix it on the catalog product, then start the sync.
Physical SKU
Product
Set up in catalog
ShipStation ID
Weight
FP-MEMO-60
Memopryl · 60 capsules
QuickBooks + ShipStation ✓
31710996
2.00 oz
FP-COGH-30
CogniHoney · 30 servings
QuickBooks + ShipStation ✓
31711044
3.40 oz
ListingsStatus: not started
Channel SKUAPI buildWebsite settings
Not started. The step finishes when every listing's product is built, read back and matching, and both website-only settings are confirmed with a screenshot.
L1 · OB-MEMO-1-SUM-EBYSINGLEListing status: ready to push
mirror SKU not built yet — the ShipStation step has not run
Push to eBay · CA-01
Pushing creates run B-0114 and hands off to the run cockpit — APPLYING → RECONCILING, then the live-listing spot-check. Partial push is normal: ready listings go now, the rest follow when their blocks clear.
Mode
dry run is the default for a new batch — logs "would do X", writes nothing
Blocked: L2OB-MEMO-2P-SUM-EBYhero overlay claim REVIEW — reword or approve exception
Blocked: L3OB-MEMO-3P-SUM-EBYhero still generating
Blocked: L4OB-MEMO-COGH-BNDL-1-SUM-EBYcombo supplemental set not built
Design notes — MR-045 Listing Builder
Design: references/ebay-planning/LISTING-BUILDER-DESIGN.md (approved 2026-08-29). Dedicated screen, superseding the new-listing slice of MR-031; the other five presets stay on scr-newjob.
What the fixture demonstrates
Count and type are derived, never asked — 4 slots → 4 listings; SINGLE/BUNDLE/COMBO computed from slot contents.
Collision check as the error-killer — L2 carries the resolved history of an operator SKU edit colliding with a live listing (the spreadsheet's swapped-fan-out bug class).
Gate invalidation — packages are locked while drafts hold approval r2; editing reopens r3 and voids downstream image approvals.
Prefill, not lock — the Memopryl shared set pre-fills L1–L3; L2 shows a detached custom lifestyle slot (ink underline = this listing only).
Two claim gates — content gate cleared in drafts; the image claim check catches L2's "boosts memory in weeks" overlay.
Partial push is normal — 1 of 4 ready; dry run is the default mode for a new batch.
ShipStation sync is its own stage (MR-053) — stage 7, between Images and Final review. Two jobs per listing, stated separately: the API build (read-back proof, never a bare 200) and the two website-only settings the robot sets. Failure recovery lives on the failed row, not in Attention; Attention only links back.
Cost telemetry — every generation logged with cost in the activity rail (REQ §13.1).
MR‑077 — stage 3 is the package rule stack, and package-builder.html is gone
Stage 3 was a fixed grid of four slots with hard-coded SKUs and prices. It is now the rule stack that makes the slots — Product Pool → Shape → Gift Pool → Base Prices → Price Ladder, and the listings they produce. The stack was built as its own screen (MR‑064 explored three designs, MR‑075 picked this one, MR‑076 added job pack sizes); that file is deleted rather than kept, because two screens that can each define a job's packages is precisely how they drift.
What the fold changed, and nothing else did. The standalone page's own header, breadcrumb and listing chip go — the stage already has a stepper and a job header. Its count now lands on the stepper's sub-label, which used to read a hard-coded 4 slots, and on the step footer. The lock gate survives: it is the listing builder's own rule, not the packages screen's, and the stack never had it.
Two counts that disagree, on purpose. The job header says 4 listings and the footer says the rules make more. Both are true: the job holds four approved listings — drafts, images, ShipStation and final review are all built on them — while the stack describes what a re-run would produce. That gap is exactly what the lock gate is about, so the footer names both rather than letting the header look stale. Open: the downstream stages' fixtures are still a four-listing job; rebuilding them against a 26-listing one is a separate round.
The sidebar collapses here now too, to the 58px icon rail, taken verbatim from catalog-product-setup.html rather than re-derived — the label survives as a native title while collapsed, because a CSS tooltip is clipped by .sb's own overflow.
Pack sizes are the open variant, on the harness bar: Account set only against + job sizes. Both branches share every node; only Add pack size and the per-row remove appear or do not.
MR‑078 — stage 2 searches the catalog, and the picked cards come off the same list
The Add another product field was a dead input under a dead heading. It now filters the account’s catalog as you type — name, brand, SKU and UPC, the four things its placeholder already promised — and a row adds that product to the panel as a card. Arrow keys move, Enter adds, Escape clears; the query and the focus survive an add, because picking three products out of one search should be three clicks and not three searches.
Every row carries its thumbnail. A supplement is recognised by its bottle long before its SKU, and two of these products are collagen. Only two have a catalog photo, so the rest fall back to the same four-letter initials block the cards already use — the fallback is the common case here, not the exception.
One list, both halves. The two cards the job started with are no longer hand-written markup: they render from the same fixture the search reads, marked picked. That is what makes removal honest — a product taken off the job goes back to being searchable, and every card’s × works, not just the ones added this session. Two lists would have meant a product could be in neither.
Gift‑eligible is a tick on the card. Rung 3 of the package stack has always said the flag is set “in the Products step” — the step had no such control, so the sentence described a screen that did not exist. It does now: one checkbox per card, and a product the catalog calls a giveaway (the Riot gift bag) arrives ticked, disabled and tagged catalog, because unflagging it is the catalog's decision and not this job's. Everything else about the gift — whether variants are built at all, and what they cost — stays in rung 3, where the maths is.
What it does not do. The search is fixture-local: adding a product here does not carry into stage 3’s Product Pool, which holds its own four-product fixture. Nothing is scoped by channel account either — a real catalog search would be, and would page. Sell similar is still a dead button.
MR‑084 / 085 — a per-unit price on every row, a ladder that shows margin, and a workspace that fits it
The Listings table carries Per unit beside Price — the price over the Units column next to it. It is the number a buyer compares across pack sizes, and until now the only place to see it was the ladder’s example column, which prices one product.
Rung 5 loses its net multiplier and gains a gross margin.2.85× was the discount restated in a second notation: it said nothing the −5% beside it did not. Gross margin — (per unit − cost) / per unit — is the question the tier is actually being set against. Price and Per unit are two columns rather than a price with a subscript — the per-bottle figure is what the tiers are compared on, so it reads down its own column instead of trailing the pack price. The header carries no tooltip: the picker directly above it already reads Memopryl — $39.99 a bottle, $7.40 cost, and a tooltip that restates its own control is one more thing to keep true.
The example product is picked, not assumed. It was pool[0], so the margin the ladder implied moved when somebody toggled an unrelated product in rung 1, with nothing on screen to say why. A dropdown beside Model names it, and the choice supplies both numbers: the one-bottle price saved in rung 4, and the cost from the catalog — the same figure the Listings table’s Cost column already spends. No new fields and nothing typed. A product switched off in the Product Pool hands the example back to the first one still in it, and picking one prices nothing: it redraws two columns and writes to no record.
Gross margin is not the 35% floor sitting inches above it. That one is net — it also takes off shipping, the 13% fee and the ad rate (D21). The hint under the table says which is which, and the column takes no colour for being low; only a negative reads red, because that is unambiguous under either measure. This is MR‑083’s rule, kept deliberately identical on the screen where the two numbers can be seen at once.
Promoted listings becomes rung 6, Promotions. It was a stray checkbox under the ladder’s table, which read as a property of the ladder; it is a job-level fee decision that moves every margin in the table beside it. Its own rung says so, carries the state in the header count (off · 13% fee only), and leaves somewhere for the rest of the promotion levers to land.
The Packages table is deleted. Tare, material and postage are inputs to a number the Listings table already shows — Ship — and the Package column already names which box each row lands in. What only that card said now lives in the listings tooltip: package is picked by weight, Ship is postage + material at the static v1 USPS rate (MR‑047), and an over capacity row is priced at a box that cannot hold it, so its cost is understated. The data is unchanged — PKGS still drives every row’s package and postage; only the read-only display of it is gone.
The listings card is as tall as the rule stack, and only then scrolls. It was a fixed 640px window regardless of how much was in it. Now it grows with its rows up to the height of rungs 1–6 and scrolls past that, with the totals bar pinned under it. The cap has to come from the other column, which is why the two columns are a grid: the listings column is kept out of the row’s sizing (height:0) so the row is as tall as the rules, then fills it (min-height:100%). A short job still draws a short card — nothing is stretched to fill.
Every listings column sorts, and the two columns scroll independently (MR‑086). Each header is a real <button>, so the keyboard gets sorting for free; a second click reverses, build order breaks every tie, and # keeps the number the row was built with rather than renumbering — a listing is the same listing after a sort. Sorting reorders what is shown and touches no price, no rule and no record.
Stage 3 is a two-pane workspace, not a long page (MR‑087). The stage is exactly as tall as what is left of the viewport; each column scrolls itself, and the listings table scrolls inside its card under headers that never move. Rung 6 and row 52 are both reachable, and neither costs you the other.
Sticky was tried first and it failed in the one place that matters. MR‑086 pinned the listings card under the sticky header, which worked until the page scrolled past the rule stack’s own height: a sticky box can never leave its containing block, so the card was pushed up from below and took the column headers with it. Runway you cannot extend is not a fix, and the right answer was to stop scrolling the page at all here.
Two numbers are measured in script rather than hard-coded — the header’s height, because it wraps at narrow widths and a fixed offset would be wrong exactly when it matters, and the scroller’s free height, because 100vh overshoots by the harness bar and by the 60px of bottom padding the long stages need. Under 560px of workspace the stage gives up and scrolls the page instead: two slivers are worse than one page.
Open questions
Q0 · Which pack-size branch, and do the downstream fixtures follow?Account set only is what MR‑075 shipped; + job sizes lets a job add sizes up to a dozen with the ladder tier required alongside. Either way, drafts / images / ShipStation / review are still fixtured on four listings while stage 3 now describes twenty-six.
Q1 · Combo supplemental default. When a combo product set has no imagery, should "Generate set" or "Pick from library" be the primary action? The fixture shows both, unranked.
Q2 · Campaign image set precedence. An attached campaign carries its own image set. Does it pre-fill shared slots ahead of the product-set library, behind it, or as a third labeled source the operator picks from?
Q3 · -D<n> numbering inside one job. If a hero regenerates before push (v1 → v2), is that still -D1 until pushed, with -D2 reserved for post-push design revisions? Fixture assumes yes (L1 offers "Regenerate as -D2" only because v1 is approved).
Q4 · Does one job-level product list feed both stages? Stage 2's picks and stage 3's Product Pool are still separate fixtures, so a product added here does not appear there and the gift tick does not reach the Gift Pool. Settling it is a fixture rebuild, not a screen change.
Q6 · Does per unit mean per bottle in the box, or per bottle sold? A gift row’s Per unit divides by a bottle nobody paid for, because the free bottle counts in Units. Dividing by the paid bottles instead would make a gift variant read identically to the bundle it came from — which is arguably the truer number, and arguably hides the giveaway. It is a pricing decision, not a layout one.
Q5 · Is the catalog search account-scoped, and does it page? Drawn against nine products with neither. A real catalog is thousands and a channel account cannot list all of them — but what narrows the list (account eligibility, brand, both) is a domain question this screen cannot answer alone.
Refinement round (MR-046)
Live push gate — Live is styled destructive, the button label is mode-aware, and a confirm dialog restates account + manifest before any live write. Dry run stays one-click.
Watch panel — after a live push the push card opens a read-only window into run B-0114 (APPLYING → RECONCILING → live + spot-checks); the cockpit still owns the run.
View toggles — Drafts adds Compare (fields × listings); Images adds By listing (readiness-first). Same segmented-control idiom.
eBay preview — per-listing buyer's-eye preview on Final review; deliberately approximate, marketplace chrome omitted.