Skip to content
Worix
BrowsePublish
Log inSign Up

operation-report-writing

How an unattended operation report turn is written — the wording of each section and of each "Oscar recommends" line, given figures that are already calculated. Covers both the weekly report and the three rolling windows (Last 7 / 14 / 30 days). Read this ONLY when a schedule or a page warm-up has started a report-writing turn. It has no entry of its own, no merchant is waiting on it, and it must never be entered from a chat message.

0 downloads
Free
Reviewed
internal
ops
requires-yepai-tools

name: operation-report-writing description: >- How an unattended operation report turn is written — the wording of each section and of each "Oscar recommends" line, given figures that are already calculated. Covers both the weekly report and the three rolling windows (Last 7 / 14 / 30 days). Read this ONLY when a schedule or a page warm-up has started a report-writing turn. It has no entry of its own, no merchant is waiting on it, and it must never be entered from a chat message. tags: [internal, ops, requires-yepai-tools] license: MIT-0

Writing the scheduled operation report

A schedule or a page warm-up started this turn, not a merchant — nobody is waiting on it. The figures are already worked out; your whole job is the words around them.

One call, then write

OPERATION_REPORT_SNAPSHOT with the id you were given returns everything that report needs — the metrics, the period-over-period changes, the baselines, the top products, the alerts that fired, and the candidate drivers the backend matched. That one call is your entire input (one call per id, when the prompt hands you more than one — see "Two kinds of turn" below). Do not fetch anything else, do not go looking for a number that is missing, and do not open the store's data yourself to check one.

What is yours and what is not

SectionDecided byYour part
The three headline metrics, their change and their arrowsThe snapshotNothing — quote them
The line reading those three togetherFixed logic: growth that comes from order count versus from basket size; a basket drop past a tenth is worth flagging for discounting or a shift to cheaper linesWording only
Highlights, one line eachFixed viewpoints: sales, orders, productsThe content
Top products, both tablesThe snapshotNothing
Oscar recommends, per section—All of it — in three parts, see below
The alerts that fired this periodThe alert logNothing

The sections you write are the keys the turn's prompt hands you, and only those. The Highlights row above lists three merchant-facing VIEWPOINTS, which is not the same list: the card's Orders line is filled from the fulfilment recommendation, because "3 orders past your usual pace · fulfilment running 27% slower" is fulfilment content. Writing an extra key for it produces a paragraph with no section to sit above — measured on dev (2026-08-24): a report whose stored recommends were sales / alerts / orders / fulfillment had orders rendered nowhere at all, one whole turn spent on text no merchant ever saw. The page now floats an unrecognised key to the top rather than dropping it, so the cost has gone from invisible to merely misplaced — still not where you meant it.

followups is the one exception, and it is not a section. It is the four buttons under the report card in the merchant's chat — their only way into this report from there. The turn's prompt asks for it by name, in the same JSON object, and nothing above applies to it: it has somewhere to go, it is never rendered as a banner, and leaving it out costs the merchant those four buttons. Measured on dev (2026-09-14): the rule above is worded strongly enough that two runs in a row wrote the sections and silently dropped followups, which is why it is called out here rather than left for the prompt to win on its own.

Two kinds of turn: the report week, and the three rolling windows

Almost everything in this file is about the WEEKLY report — one frozen Monday-to-Sunday week, one snapshot, one set of sections. There is a second turn that reads this same file, and the prompt tells you which one you are in by handing you three snapshot ids at once:

7d  -> "7d-<date>"
14d -> "14d-<date>"
30d -> "30d-<date>"

Call OPERATION_REPORT_SNAPSHOT once per id and write about each window from its own snapshot. Everything under "Every Oscar recommends has three parts" and every one of the Hard rules applies unchanged — a window is explained under exactly the rules a week is. What differs is four things, and all four are ways of getting the window wrong:

These windows ROLL. They end YESTERDAY, in the shop's timezone. Each snapshot's period names its own first and last day; read it. Never write "this week", never write "the report" or "the report week" — that is a different thing with different days, and a merchant reading a chip is not looking at it.

Never carry a figure from one window into another. They overlap: the same order is inside all three, and the seven days are inside the fourteen. A sentence about the month that quotes the week's total is wrong twice over.

dailySeries in these snapshots IS the window's own days — unlike the weekly report's, which runs four weeks back so the "usual day" band has something to average against.

No followups here. The exception above is about the weekly report card in chat. A rolling window has no card and no buttons, so a followups key written in this turn is discarded — the four buttons it would have made have nowhere to appear.

Reply with one JSON object keyed by window, each window mapping section to its recommendation:

{"7d": {"sales": {...}, "fulfillment": {...}, "products": {...}},
 "14d": {...}, "30d": {...}}

An answer that does not name its windows is thrown away in full. Not filed under a guess: an unlabelled paragraph could be about seven days or thirty, and putting a month's reasoning over a week's figures is the exact defect this shape exists to prevent (it was filed once already, as QA 序7). If you can only write about one window, send that one window under its own key and leave the others out.

Every "Oscar recommends" has three parts

Not one sentence. In this order, and the third is the one that gets skipped:

  1. Overall — what happened to this block, and which way it moved.
  2. Why — the driver, from drivers and usualDay, under the rules below.
  3. Outstanding — what is still not done. Read outstandingAlerts: things flagged BEFORE this period that are still open, so the line reads "flagged last week and still not done". Also look at alertsInPeriod for anything raised inside the week whose status is not done.

Leave part three out when there is nothing outstanding — do not write "nothing outstanding". An empty Outstanding line trains the merchant to stop reading the one part of the report that asks them to act.

A section with nothing to say in part one is dropped whole, as below.

Send the three parts separately, not joined into one paragraph

The turn's prompt asks for each section as an object with overall, why and outstanding keys. Fill those keys; do not glue the three parts together and put the result in one of them.

Because two different surfaces read this, and they need different amounts of it. The report page shows the whole argument — that is where a merchant goes to find out why. The summary cards (the Monday push, and the "compare to last week" card) have room for one line, and they take overall on its own. A single glued paragraph forces those cards to show three paragraphs under a row of KPIs, or to cut one mid-sentence — and half a sentence on the card with the whole one on the page is one week saying two different things.

So overall has to stand alone. Write it as a sentence that is complete without the other two: what happened to this block and which way it moved. Do not open it with a connective that depends on text the card will not show ("Because of that, …"), and do not end it dangling into the why.

overall is required. why and outstanding are left out entirely when you have nothing for them — an empty string is not the same as omitting the key, and it renders as a blank line rather than as nothing.

Hard rules

requiredClauses first, before you write anything. Each entry is a finished sentence and the section it belongs in. Put every one of them into that section's paragraph — you may adjust the join so it reads naturally, but the figures, the direction and the wording of the claim are already decided and must survive intact. There is no entry you can leave out.

This list exists because asking did not work. The refund rate was in the snapshot and the rule was in this file, and across two real reports one stated it and one wrote three fulfilment sentences without mentioning refunds at all. So it now arrives written, at the top, and placing it is the whole job.

Quote every number, calculate none of them. Changes, shares, averages, days of cover are all in the snapshot; if one you want is not there, say it is not available rather than deriving it from the ones that are.

caveats is the same kind of list, and the same rule applies — it is at the top, it is short, and everything in it belongs in the paragraph it constrains.

Explain a movement from two places, in this order. First what the store did, which is in drivers: price and listing changes and stock-outs (drivers.productHistory), how many orders carried a discount code and which codes (drivers.discounting), where the orders were placed (drivers.channelMix), and new versus returning buyers (drivers.customerMix) — then the store's own day-of-week baseline in usualDay. Then the retail calendar entries the snapshot matched for this period, as a supplement where the store's own behaviour already explains it. When neither place explains the movement, write no clear driver found and move on — do not reach for a third explanation.

Price changes, listing changes and stock-outs are in drivers.productHistory — and they are the strongest explanations you have, because they are things the merchant did. Shopify keeps no history of any of the three, so this is our own daily record, and that is why the next rule matters more than any other in this file.

When drivers.productHistory.coverageNote is present, its content goes into the sales paragraph — every time, not when it seems worth mentioning. Never write that nothing changed. The note tells you how many of the period's days were actually recorded. Where it is short, an empty priceChanges / listingChanges / stockouts list means we were not watching, not that nothing happened, and those two look identical on the page.

This one is not hypothetical. With one of seven days recorded, the sentence that came out was "no price, listing or stockout changes were observed in the period" — technically true, and a merchant reads it as "nothing changed". If the note is there, say the record does not reach back that far. A new merchant's first report will have almost no history, and that is normal.

Never name a price change, a listing change or a stock-out that is not in that block. They read like the most natural explanations in the world, and that is exactly the danger: "the price rise explains it" is a guess wearing the clothes of a finding. If the movement looks like one of these and the block does not have it, write no clear driver found.

channelMix is where the order was PLACED — Online Store, Point of Sale, an app's own name. It is not the referring site and cannot tell you which ad or post someone came from. Say where the orders were placed, never where the shopper came from.

Traffic source is not missing from your input by accident, and it is not something you can work around: Shopify keeps referrer and landing page behind a protected-customer-data approval this app does not hold, so nobody has that data — not the report, not the page, not another tool you could call. A merchant who asks where their customers came from should be told plainly that the store's channel breakdown covers where orders were placed and that traffic source is not something we can see, rather than being handed channelMix as if it answered the question.

A key of an app means Shopify gave no name for it. Say "an app" and move on — there is nothing more to know, and the producer no longer carries the internal id, so there is nothing to accidentally read out.

Never search the web for a driver. No holiday lookup, no weather, no industry news; if it is not in the snapshot's own drivers or the calendar it carries, it is not a driver you can name.

The fulfilment recommendation carries the refund rate against last period. It is the one place in the report where refunds are read, and a fulfilment section that talks only about shipping speed leaves the merchant to guess whether the delays cost them anything. The rate is in fulfillment.refundRate (value, previous, deltaPct, deltaPoints, direction, and a basis saying what it divides by) and the money is in kpis.refunds — quote the rate as a percentage, say whether the move is inside this store's normal range, and do not compute a rate the snapshot has not given you.

The clause is already written for you: fulfillment.refundRate.sentence, which is also the fulfillment entry in requiredClauses. Use it. Do not restate the rate in your own words next to it, and do not recompute anything in it — the percentage, the direction and the "no prior period" wording are all decided.

The figures behind it are there if you need to reason about them: value is a FRACTION (0.032 is 3.2%), deltaPoints is the move in percentage POINTS, and deltaPct is absent whenever last period was 0% because there is no base to divide by.

When value is null there is no sentence and no required clause: the store had no gross sales in the window or could not be read. Say the rate is not available, and do NOT call it 0%.

Refund reasons: check drivers.refundReasons.worthReporting before you name one. Only a refund raised through Shopify's returns flow carries a reason; a merchant who refunds directly leaves none, and for small stores that is most of them. When the flag is false, do NOT list the breakdown — say how many of the period's refunds came through returns and stop there. A list reading "Damaged 1 · Wrong size 1" out of sixteen refunds looks like an analysis of why customers sent things back, and is actually a count of who used the returns flow.

Recommend only what the platform can do: restock, look at the pricing, delist, chase an unshipped order. Never name a price change or a percentage. Never suggest ads, new photography, a site change or anything else nobody can act on from here.

A section that cannot be written is dropped, the report still goes out. Leave that section out silently rather than failing the whole report or filling it with a note about what went wrong.

No data means no section. Where the snapshot has nothing for a period, say there is nothing to report for it — do not display an empty shell and do not generate something to fill it.

Download

ZIP package — ready to use

Skill Info

Creator
Yepai
License
MIT-0
Downloads
0
Published
Oct 26, 2026
Updated
Oct 29, 2026