# Dead Stock Identifier

> Identify dead stock, slow-moving inventory, declining SKU velocity, and carrying-cost waste from Shopify exports or generic sales and inventory CSVs. Use when an agent needs dead inventory analysis, slow-mover detection, catalog rationalization, warehouse waste review, or sales-velocity diagnostics for SKU-level inventory decisions.

- Skill: `useretrace/dead-stock-identifier` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add useretrace/dead-stock-identifier`
- Raw SKILL.md: https://api.skillmd.com/api/skills/useretrace/dead-stock-identifier/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: useretrace (https://skillmd.com/u/useretrace)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/useretrace/dead-stock-identifier

---


# Dead Stock Identifier

Flag dead, slow-moving, and declining SKUs based on sales velocity analysis. Produces a flagged inventory CSV, velocity distribution chart (PNG), and a formatted PDF report with operational guidance — all three, every run.

## When to use this skill

Activate when the user:
- Wants to find dead stock, slow-moving inventory, or items losing momentum
- Asks about inventory carrying costs, warehouse space waste, or capital tied up in unsold goods
- Has Shopify product/order CSVs and wants to know what to discontinue, discount, or investigate
- Mentions declining sales velocity, items that stopped selling, or catalog rationalization

## Prerequisites

Before running the analysis, ensure Python 3.9+ is available and install dependencies:

```bash
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

The skill needs **sales data** with dates (to measure velocity) and optionally **product data** (for stock on hand and cost).

### Shopify exports (auto-detected)

- **Orders CSV** (required): Shopify Admin → Orders → Export. Detected via `Lineitem sku`, `Lineitem quantity`, `Lineitem price`, `Created at`.
- **Products CSV** (recommended): Shopify Admin → Products → Export. Provides stock on hand (`Variant Inventory Qty`), cost (`Variant Cost per item`), and product titles. Without this, dead stock detection is limited to SKUs that appear in orders.

### Generic CSVs

Any CSV with SKU, date, and quantity columns works. Use `--sku-col`, `--date-col`, `--quantity-col` to specify column names if auto-detection fails. Use `--cost-col` and `--stock-col` for product data in generic formats.

## Running the analysis

Resolve the installed skill root first. The exact path depends on where the skill was installed in the current environment.

```bash
SKILL_DIR="<resolved-installed-skill-dir>"

python "$SKILL_DIR/scripts/dead_stock.py" \
  --orders <path-to-orders-csv> \
  --products <path-to-products-csv> \
  --output-dir ./dead-stock-output
```

### All flags

| Flag | Default | Description |
|------|---------|-------------|
| `--orders` | *(required)* | Path to orders/sales CSV |
| `--products` | — | Path to products CSV (stock, cost, titles) |
| `--output-dir` | `./dead-stock-output` | Directory for output files |
| `--window` | `90` | Analysis window in days |
| `--slow-percentile` | `10` | Velocity percentile for "at risk" tier |
| `--decline-threshold` | `50` | Velocity decline % for "watch" tier |
| `--carrying-cost` | — | Annual carrying cost as fraction of product cost (e.g., 0.25) |
| `--csv-only` | `false` | Skip PNG and PDF generation (faster, CSV only) |
| `--sku-col` | auto-detect | SKU column name for generic CSVs |
| `--products-sku-col` | auto-detect | SKU column name in products CSV (when different from orders) |
| `--date-col` | auto-detect | Date column name for generic CSVs |
| `--quantity-col` | auto-detect | Quantity column name for generic CSVs |
| `--revenue-col` | auto-detect | Revenue/price column name for generic CSVs |
| `--cost-col` | auto-detect | Product cost column name for generic CSVs |
| `--stock-col` | auto-detect | Stock-on-hand column name for generic CSVs |

### Examples

Shopify exports with carrying cost analysis:
```bash
python "$SKILL_DIR/scripts/dead_stock.py" \
  --orders orders_export.csv \
  --products products_export.csv \
  --output-dir ./dead-stock-output \
  --carrying-cost 0.25
```

Wider analysis window (180 days):
```bash
python "$SKILL_DIR/scripts/dead_stock.py" \
  --orders orders_export.csv \
  --products products_export.csv \
  --window 180
```

## Output

The script always produces all three outputs:

1. **`dead_stock_report.csv`** — Flagged SKU list: SKU, Product Title, Risk Tier, Units Sold, Revenue, Days Since Last Sale, Avg Daily Velocity, Current Stock, Days of Stock Remaining, Est. Carrying Cost, Velocity Change %
2. **`dead_stock_chart.png`** — Two-panel chart: velocity distribution with risk tier coloring (left), risk tier breakdown bars (right)
3. **`dead_stock_report.pdf`** — Multi-page report: summary, analysis & recommendations with per-tier operational guidance, charts, tier summary table, full flagged inventory table

The CSV is sorted by risk tier (Dead first, then At Risk, Watch, Healthy) and within each tier
by days since last sale (longest first). This means the most urgent items appear at the top of
the file.

## Risk tiers

| Tier | Definition | Color |
|------|------------|-------|
| **Dead** | Zero units sold in the analysis window | Red |
| **At Risk** | Velocity in the bottom Nth percentile of active SKUs | Amber |
| **Watch** | Velocity declined >X% vs prior equivalent period | Yellow |
| **Healthy** | Not flagged | Green |

## Presenting results

After the script runs:
1. **Lead with the dead stock % KPI** if cost data was provided — this is the single most scannable health metric (e.g., "Dead inventory represents 23% of carrying cost — critical threshold")
2. Name the **top dead stock items** by inventory value (or units if no cost data) — merchants want to know which items to act on first
3. Present the **aging breakdown for dead items** — this communicates urgency: items 180+ days need immediate disposal action, 91-180 need escalation, 61-90 need intervention
4. Highlight any **capital opportunity** if carrying cost data is available
5. Present the **escalating disposal actions** from the PDF — these urgency-graded recommendations are the key differentiator of this tool over flat "you have dead stock" lists
6. Show the PNG chart inline if the environment supports images
7. Point the user to the **PDF report** for the full "Analysis & Recommendations" page with per-tier guidance, escalating disposal actions, caveats, and next steps
8. Point to the CSV for raw data — note it's sorted by risk tier (Dead first) then days since last sale (descending), so the most urgent items appear first
9. Suggest cross-referencing with ABC Analysis: items flagged here that are Tier A or B in ABC need immediate attention — they were revenue drivers and are now losing momentum
10. Reference the bundled `reference.md` for follow-up questions about dead stock methodology, SLOB terminology, aging framework, or carrying cost calculation

**If no products file was provided:** Acknowledge upfront that stock-on-hand, carrying cost,
sell-through rate, and days-of-stock are unavailable. Explain what additional insights would be
available with product data: "With a products export, I could also show you how much capital is
tied up in dead stock, how many days of inventory you're carrying, and sell-through rates."

## Edge cases

- **No products file**: Analysis limited to SKUs in orders; stock on hand and carrying cost unavailable. Noted in caveats.
- **Insufficient history for Watch tier**: Need 2× the window in order data to detect velocity decline. If unavailable, Watch tier is omitted and noted in caveats.
- **All items dead**: Script handles gracefully — all SKUs classified as Dead.
- **No cost data**: Carrying cost columns show as empty; capital opportunity section omitted.
- **Single SKU**: Classified based on whether it had sales in the window.
- **Cancelled/refunded orders**: Shopify exports with `Financial Status` column are automatically filtered to paid/authorized orders. If this column is absent, cancelled orders may inflate velocity — noted in caveats.

## Optional follow-up analysis

If the user also wants revenue-priority context, pair this analysis with a separate ABC analysis. Treat that as an optional follow-up rather than a dependency: this skill stands on its own for dead-stock and slow-mover decisions.

