Inventory Health Report
Unified per-SKU replenishment analysis. Computes safety stock, reorder point, EOQ, turnover, sell-through, days of stock, and demand variability (XYZ) — then classifies each SKU with an actionable status flag. Three outputs every run (CSV, PNG, PDF).
When to use this skill
Activate when the user:
- Wants to know what to order, when, and how much
- Asks about safety stock, reorder points, or economic order quantity
- Has Shopify exports and wants replenishment recommendations
- Mentions stockout risk, overstock, or inventory planning
- Wants to assess inventory health across their catalog
Prerequisites
Before running, ensure Python 3.9+ is available and install dependencies:
pip install -r "$SKILL_DIR/scripts/requirements.txt"
Resolve SKILL_DIR to the installed skill root first. If pip install fails due to permissions, try pip install --user -r "$SKILL_DIR/scripts/requirements.txt" or use a virtual environment.
Input
- Orders CSV (required): Shopify Admin → Orders → Export, or any CSV with SKU, quantity, date, and price columns
- Products CSV (optional but recommended): Shopify Admin → Products → Export. Provides stock levels, cost data, and titles. Without it, only demand-side metrics are available.
- Lead time (recommended): Either a global value via
--lead-time or a per-SKU column in the products CSV via --lead-time-col. Without lead time, Stockout Risk and Reorder Now flags are unavailable.
Running the report
Resolve the installed skill root first. The exact path depends on where the skill was installed in the current environment.
SKILL_DIR="<resolved-installed-skill-dir>"
python "$SKILL_DIR/scripts/inventory_health.py" \
--orders orders_export.csv \
--products products_export.csv \
--lead-time 14 \
--output-dir ./health-output
All flags
| Flag |
Default |
Description |
--orders |
(required) |
Orders/sales CSV |
--products |
— |
Products CSV for stock, cost, titles |
--output-dir |
./health-output |
Output directory |
--window |
90 |
Analysis window in days |
--lead-time |
— |
Global lead time in days |
--lead-time-col |
— |
Per-SKU lead time column in products CSV |
--service-level |
0.95 |
Target service level (0.50–0.9999) |
--ordering-cost |
— |
Fixed cost per order in $ (for EOQ) |
--holding-cost |
0.25 |
Annual holding cost as fraction of product cost |
--overstock-days |
180 |
Days-of-stock threshold for overstock flag |
--sku-col |
auto |
SKU column (generic CSVs) |
--date-col |
auto |
Date column (generic CSVs) |
--quantity-col |
auto |
Quantity column (generic CSVs) |
--revenue-col |
auto |
Revenue column (generic CSVs) |
--cost-col |
auto |
Cost column (generic CSVs) |
--stock-col |
auto |
Stock column (generic CSVs) |
--products-sku-col |
auto |
SKU column in products CSV when it differs from the orders file |
--csv-only |
false |
Skip PNG and PDF generation (faster, CSV only) |
Lead time resolution: When both --lead-time and --lead-time-col are provided, per-SKU values take priority. The global --lead-time fills in SKUs that don't have a per-SKU value.
Examples
Shopify exports with 14-day lead time:
python "$SKILL_DIR/scripts/inventory_health.py" \
--orders orders_export.csv \
--products products_export.csv \
--lead-time 14
90-day window with EOQ:
python "$SKILL_DIR/scripts/inventory_health.py" \
--orders orders_export.csv \
--products products_export.csv \
--lead-time 14 \
--ordering-cost 25 \
--window 90
Higher service level for critical inventory:
python "$SKILL_DIR/scripts/inventory_health.py" \
--orders orders_export.csv \
--products products_export.csv \
--lead-time 14 \
--service-level 0.99
Output
Three files every run:
inventory_health_report.csv — Per-SKU metrics: SKU, Title, Status, Demand Variability (X/Y/Z), Avg Daily Demand, Demand Std Dev, CV, Demand Trend %, Current Stock, Days of Stock, Sell-Through %, Turnover Ratio, Lead Time, Safety Stock, Safety Stock Reliability, Reorder Point, EOQ, Revenue, Units Sold, Cost per Unit.
Sorted by status priority (Stockout Risk first), then days of stock ascending within each status. This sort is intentional — the most urgent items appear at the top.
inventory_health_chart.png — Two panels: stock position scatter (days of stock vs sell-through, colored by status, sized by revenue) and status distribution bars (% SKUs vs % revenue).
inventory_health_report.pdf — Multi-page report: summary with status counts and key findings, analysis and recommendations per status flag, demand variability summary, service level guidance, caveats, numbered next steps, embedded chart, a "SKUs Requiring Action" table, and a "Full Catalog Reference" appendix.
Status flags
Each SKU gets exactly one flag (priority cascade):
| Priority |
Flag |
Condition |
Action |
| 1 |
Stockout Risk |
Days of stock < lead time |
Emergency order |
| 2 |
Reorder Now |
Stock ≤ reorder point |
Standard reorder |
| 3 |
Overstock |
Days of stock > 180 (configurable) |
Reduce quantities |
| 4 |
No Stock |
Stock = 0 with active demand |
Replenish immediately |
| 5 |
No Demand |
Zero sales in window |
Review / discontinue |
| 6 |
Healthy |
None of above |
Maintain cadence |
Demand variability (XYZ)
Each SKU with active demand gets a demand predictability classification:
| Class |
CV Range |
Meaning |
Safety stock reliability |
| X |
< 0.5 |
Stable, predictable |
High — formula accurate |
| Y |
0.5 – 1.0 |
Variable, possibly seasonal |
Moderate — review seasonality |
| Z |
≥ 1.0 |
Erratic, sporadic |
Low — manual review recommended |
Presenting results
After the script runs:
- Check degraded mode first — if any data was missing (no lead time, no stock, no cost), tell the user upfront what's unavailable and why. "Without lead time, I can't flag stockout risk or calculate reorder points."
- Lead with status flag counts — how many items need action, highlighting urgency
- For Stockout Risk and Reorder Now items, quote the reorder point and EOQ (if available) as specific quantities: "SKU-123 has 15 units left with a reorder point of 40 — order at least 25 units"
- Name the top stockout-risk SKUs by revenue — these are urgent
- Highlight erratic-demand items (Z-class) where safety stock may be unreliable — note that the computed safety stock for these items is a rough guide, not a precise number
- Present overstock value if cost data was available
- Note the service level used (default 95%) and mention the A/B/C differentiation recommendation: "For your highest-revenue items, consider re-running at 99%"
- For Z-class items in Stockout Risk, note that the safety stock number is less reliable — manual judgment needed
- Show the PNG chart inline if the environment supports images
- Point to the PDF for full analysis, caveats, and per-SKU detail
- Reference the bundled
reference.md for formula explanations
Degraded modes
The skill works with progressively less data:
- No lead time: Stockout Risk and Reorder Now unavailable. Only Overstock, No Stock, No Demand, and Healthy flags.
- No products CSV: Only demand-side metrics (avg daily demand, demand variability). No stock, sell-through, turnover, or reorder metrics.
- No cost data: EOQ unavailable. All other metrics work.
When presenting orders-only results, acknowledge the limitation upfront: "Without product data, I can show demand metrics (velocity, variability, XYZ classification) but not stock adequacy, sell-through, or reorder calculations. Providing a products CSV would unlock the full analysis."
Edge cases
- Single SKU: Classified normally
- All healthy: Reports zero action items
- Zero demand across all SKUs: Script exits with error (no orders in window)
- Short window (< 180 days): Caveat about seasonal misclassification
- All Z-class (erratic demand): Explicit caveat that safety stock estimates are unreliable across the board
1---2name: inventory-health-report3description: Generate a per-SKU inventory health report from Shopify exports or generic sales and product CSVs, including safety stock, reorder points, EOQ, stockout risk, overstock signals, and replenishment guidance. Use when an agent needs inventory planning, replenishment analysis, stockout prevention, overstock review, or SKU-level order recommendations from CSV data.4---56# Inventory Health Report78Unified per-SKU replenishment analysis. Computes safety stock, reorder point, EOQ, turnover, sell-through, days of stock, and demand variability (XYZ) — then classifies each SKU with an actionable status flag. Three outputs every run (CSV, PNG, PDF).910## When to use this skill1112Activate when the user:13- Wants to know what to order, when, and how much14- Asks about safety stock, reorder points, or economic order quantity15- Has Shopify exports and wants replenishment recommendations16- Mentions stockout risk, overstock, or inventory planning17- Wants to assess inventory health across their catalog1819## Prerequisites2021Before running, ensure Python 3.9+ is available and install dependencies:2223```bash24pip install -r "$SKILL_DIR/scripts/requirements.txt"25```2627Resolve `SKILL_DIR` to the installed skill root first. If `pip install` fails due to permissions, try `pip install --user -r "$SKILL_DIR/scripts/requirements.txt"` or use a virtual environment.2829## Input3031- **Orders CSV** (required): Shopify Admin → Orders → Export, or any CSV with SKU, quantity, date, and price columns32- **Products CSV** (optional but recommended): Shopify Admin → Products → Export. Provides stock levels, cost data, and titles. Without it, only demand-side metrics are available.33- **Lead time** (recommended): Either a global value via `--lead-time` or a per-SKU column in the products CSV via `--lead-time-col`. Without lead time, Stockout Risk and Reorder Now flags are unavailable.3435## Running the report3637Resolve the installed skill root first. The exact path depends on where the skill was installed in the current environment.3839```bash40SKILL_DIR="<resolved-installed-skill-dir>"4142python "$SKILL_DIR/scripts/inventory_health.py" \43 --orders orders_export.csv \44 --products products_export.csv \45 --lead-time 14 \46 --output-dir ./health-output47```4849### All flags5051| Flag | Default | Description |52|------|---------|-------------|53| `--orders` | *(required)* | Orders/sales CSV |54| `--products` | — | Products CSV for stock, cost, titles |55| `--output-dir` | `./health-output` | Output directory |56| `--window` | `90` | Analysis window in days |57| `--lead-time` | — | Global lead time in days |58| `--lead-time-col` | — | Per-SKU lead time column in products CSV |59| `--service-level` | `0.95` | Target service level (0.50–0.9999) |60| `--ordering-cost` | — | Fixed cost per order in $ (for EOQ) |61| `--holding-cost` | `0.25` | Annual holding cost as fraction of product cost |62| `--overstock-days` | `180` | Days-of-stock threshold for overstock flag |63| `--sku-col` | auto | SKU column (generic CSVs) |64| `--date-col` | auto | Date column (generic CSVs) |65| `--quantity-col` | auto | Quantity column (generic CSVs) |66| `--revenue-col` | auto | Revenue column (generic CSVs) |67| `--cost-col` | auto | Cost column (generic CSVs) |68| `--stock-col` | auto | Stock column (generic CSVs) |69| `--products-sku-col` | auto | SKU column in products CSV when it differs from the orders file |70| `--csv-only` | `false` | Skip PNG and PDF generation (faster, CSV only) |7172> **Lead time resolution:** When both `--lead-time` and `--lead-time-col` are provided, per-SKU values take priority. The global `--lead-time` fills in SKUs that don't have a per-SKU value.7374### Examples7576Shopify exports with 14-day lead time:77```bash78python "$SKILL_DIR/scripts/inventory_health.py" \79 --orders orders_export.csv \80 --products products_export.csv \81 --lead-time 1482```838490-day window with EOQ:85```bash86python "$SKILL_DIR/scripts/inventory_health.py" \87 --orders orders_export.csv \88 --products products_export.csv \89 --lead-time 14 \90 --ordering-cost 25 \91 --window 9092```9394Higher service level for critical inventory:95```bash96python "$SKILL_DIR/scripts/inventory_health.py" \97 --orders orders_export.csv \98 --products products_export.csv \99 --lead-time 14 \100 --service-level 0.99101```102103## Output104105Three files every run:1061071. **`inventory_health_report.csv`** — Per-SKU metrics: SKU, Title, Status, Demand Variability (X/Y/Z), Avg Daily Demand, Demand Std Dev, CV, Demand Trend %, Current Stock, Days of Stock, Sell-Through %, Turnover Ratio, Lead Time, Safety Stock, Safety Stock Reliability, Reorder Point, EOQ, Revenue, Units Sold, Cost per Unit.108109Sorted by status priority (Stockout Risk first), then days of stock ascending within each status. This sort is intentional — the most urgent items appear at the top.1101112. **`inventory_health_chart.png`** — Two panels: stock position scatter (days of stock vs sell-through, colored by status, sized by revenue) and status distribution bars (% SKUs vs % revenue).1121133. **`inventory_health_report.pdf`** — Multi-page report: summary with status counts and key findings, analysis and recommendations per status flag, demand variability summary, service level guidance, caveats, numbered next steps, embedded chart, a "SKUs Requiring Action" table, and a "Full Catalog Reference" appendix.114115## Status flags116117Each SKU gets exactly one flag (priority cascade):118119| Priority | Flag | Condition | Action |120|----------|------|-----------|--------|121| 1 | **Stockout Risk** | Days of stock < lead time | Emergency order |122| 2 | **Reorder Now** | Stock ≤ reorder point | Standard reorder |123| 3 | **Overstock** | Days of stock > 180 (configurable) | Reduce quantities |124| 4 | **No Stock** | Stock = 0 with active demand | Replenish immediately |125| 5 | **No Demand** | Zero sales in window | Review / discontinue |126| 6 | **Healthy** | None of above | Maintain cadence |127128## Demand variability (XYZ)129130Each SKU with active demand gets a demand predictability classification:131132| Class | CV Range | Meaning | Safety stock reliability |133|-------|----------|---------|------------------------|134| **X** | < 0.5 | Stable, predictable | High — formula accurate |135| **Y** | 0.5 – 1.0 | Variable, possibly seasonal | Moderate — review seasonality |136| **Z** | ≥ 1.0 | Erratic, sporadic | Low — manual review recommended |137138## Presenting results139140After the script runs:1411. **Check degraded mode first** — if any data was missing (no lead time, no stock, no cost), tell the user upfront what's unavailable and why. "Without lead time, I can't flag stockout risk or calculate reorder points."1422. Lead with **status flag counts** — how many items need action, highlighting urgency1433. For **Stockout Risk and Reorder Now items**, quote the reorder point and EOQ (if available) as specific quantities: "SKU-123 has 15 units left with a reorder point of 40 — order at least 25 units"1444. Name the **top stockout-risk SKUs** by revenue — these are urgent1455. Highlight **erratic-demand items** (Z-class) where safety stock may be unreliable — note that the computed safety stock for these items is a rough guide, not a precise number1466. Present **overstock value** if cost data was available1477. Note the **service level used** (default 95%) and mention the A/B/C differentiation recommendation: "For your highest-revenue items, consider re-running at 99%"1488. For **Z-class items in Stockout Risk**, note that the safety stock number is less reliable — manual judgment needed1499. Show the PNG chart inline if the environment supports images15010. Point to the PDF for full analysis, caveats, and per-SKU detail15111. Reference the bundled `reference.md` for formula explanations152153## Degraded modes154155The skill works with progressively less data:156- **No lead time**: Stockout Risk and Reorder Now unavailable. Only Overstock, No Stock, No Demand, and Healthy flags.157- **No products CSV**: Only demand-side metrics (avg daily demand, demand variability). No stock, sell-through, turnover, or reorder metrics.158- **No cost data**: EOQ unavailable. All other metrics work.159160When presenting orders-only results, acknowledge the limitation upfront: "Without product data, I can show demand metrics (velocity, variability, XYZ classification) but not stock adequacy, sell-through, or reorder calculations. Providing a products CSV would unlock the full analysis."161162## Edge cases163164- **Single SKU**: Classified normally165- **All healthy**: Reports zero action items166- **Zero demand across all SKUs**: Script exits with error (no orders in window)167- **Short window** (< 180 days): Caveat about seasonal misclassification168- **All Z-class (erratic demand)**: Explicit caveat that safety stock estimates are unreliable across the board