Files
unique/.claude/skills/build-review/SKILL.md
T

129 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: build-review
description: Graduate a find item to a full review for unique.rzen.dev. Reads src/content/find/<year>/<month>/<slug>/index.mdx, fact-checks against the product's own site, expands the body into a full review, writes src/content/reviews/<slug>/index.mdx, and links the two via fromFind / promotedTo. Supports an 'auto' unattended mode. Use when the user runs /build-review <slug>, says "review this find", or "graduate <slug>".
disable-model-invocation: true
---
# build-review
Convert one captured `find` into a full `review`. Both records persist — the find stays put as the historical capture, the review becomes the canonical long-form treatment, and the two link to each other.
Invoke from inside the `unique.rzen.dev` repo with a find slug as the argument.
## Modes
- **Interactive (default when a user is present)**: propose the hero asset and show the drafted body before writing (steps 3 and 4 pause for approval).
- **Autonomous (`auto` argument, or when running unattended — invoked by `/daily-pipeline`, a scheduled run, or any headless session)**: no pauses. Download the hero, verify, write, publish. The fact-check step (step 3) is **mandatory** in this mode — it is the substitute for the human eye. Record the editorial decisions (hero choice, category, corrections made) in the log entry so the user can review after the fact.
## Inputs
- `src/content/find/<year>/<month>/<slug>/index.mdx` — the source find (must exist; abort otherwise). The slug is unique across the whole `find/` tree, so locate it via `find src/content/find -type d -name "<slug>"` if you don't already know the year/month.
- `src/content/reviews/<slug>/index.mdx` — must NOT exist (abort if a review with the same slug is already there; ask the user to disambiguate).
Note on hero assets: the find's hero, when present, sits at `src/content/find/<year>/<month>/<slug>/hero.<ext>` next to its `index.mdx`. The review's hero goes at `src/content/reviews/<slug>/hero.<ext>` (flat — reviews are not date-bucketed).
## Procedure
### 1. Read the find
Parse frontmatter. Note: `name`, `subtitle`, `link`, `linkText`, `amazonLink`, `source`, `topics`, `tags`, plus the body.
If `promotedTo` is already set, abort: "This find has already been promoted to <slug>."
If the find is tobacco- or alcohol-related (wine, whisky, cocktail, bar, smoking items — a few legacy finds predate the exclusion), abort: the site no longer promotes either, so these never graduate to reviews, even on explicit slug argument — explain why instead. (Restates `EDITORIAL.md` "Content rules" — the charter is the source of truth.)
### 2. Pick a hero asset
Look at the external link and pick a hero — a screenshot, demo gif, or product photo from the maker's site. The find's own `hero.<ext>` is a valid fallback, but prefer a richer asset from the source when one exists (finds often carry low-res OG cards).
- Mac apps: an App Store screenshot or hero image from the developer's site.
- Physical products: the maker's product photo.
- Travel destinations: a Wikipedia or Wikimedia Commons photo (free-to-use only).
Save it at `src/content/reviews/<slug>/hero.<ext>`. **Name it exactly `hero.<ext>`** — review heroes are auto-discovered by `src/lib/hero.ts` from that filename (images and `hero.mp4` both); no registration step exists anymore. Heavy originals go in `src/content/reviews/<slug>/source/` (never bundled).
Interactive mode: state what you'd download and pause for approval first. Autonomous mode: download it.
If the review legitimately has no usable hero (rare — text-only subjects), note it explicitly in the log entry ("no hero asset — text-only review") so the omission is intentional. The grid tile will render without media.
### 3. Fact-check the find (mandatory in autonomous mode)
Finds are 2-3 sentences written from a source's secondhand description — they routinely undersell or misdescribe (a "terminal with a sidebar" turned out to be a full Git-tooling workspace; an "AI agent" was specifically Claude Code). Before expanding:
- Fetch the product's **own** site / App Store page / repo README — not just the source that surfaced it.
- Verify: what it actually is and does, current availability and price model, platform requirements, licensing, and whether the find's claimed virtue is real.
- If the find got something wrong or undersold it, the review states the corrected picture (calling out the correction when it's interesting, as the Muxy review did). If the product turns out to fail the site's bar entirely (vaporware, abandoned, misrepresented), **abort and report** instead of publishing — in autonomous mode, log it as a rejected graduation.
- If the find has no `amazonLink` and the item is a physical product, check Amazon for an exact match while you're at it (same maker + model only; canonical `/dp/<ASIN>` form). Carry any confident result into the review frontmatter.
### 4. Expand the body
Take the find's 2-3 sentence body and expand it to a full review:
- Lead with a `>` blockquote summary (1-2 sentences) — this renders as the accent-bordered lead per the existing review style.
- 3-5 paragraphs covering: what it is, the specific problem it solves, the concrete details that make it earn its place, and any honest limitations (surfaced by step 3).
- Reference the hero asset inline where it helps (relative `./hero.<ext>`; use `astro:assets` `<Image>` for JPG sources — plain Markdown images have rendered small on JPGs).
- Don't pad. If the find body is already complete, the review is just it + a blockquote summary + maybe one paragraph on context.
- Write to `EDITORIAL.md` (the voice charter): concise, to the point, delight through specificity. Budget: **250450 words, hard ceiling 600** — narrative subjects (travel, history, story-led pieces) may earn up to ~800 when the story itself is the delight. Budgets are ceilings, not targets.
Interactive mode: show the proposed body and wait. Autonomous mode: proceed.
### 5. Write the review
File: `src/content/reviews/<slug>/index.mdx`.
Frontmatter:
```yaml
---
name: "<from the find>"
subtitle: "<from the find — required for reviews>"
date: YYYY-MM-DD # today (the review date), not the find's date
category: <pick from existing categories or propose a new one>
topics: <1-3 from the controlled vocabulary in src/lib/topics.ts (TOPIC_META keys) — usually the find's topics, adjusted if the review's angle differs; build fails on values outside the vocabulary>
tags: <merge the find's tags with any review-specific additions>
link: "<from the find — or a better canonical URL surfaced by step 3>"
linkText: "<from the find, if set>"
amazonLink: "<from the find or step 3, physical products only — omit otherwise>"
description: "<short meta description>"
source: "<from the find>"
fromFind: "<find slug>"
---
```
If the find had no `subtitle`, generate one — it's required on reviews.
### 6. Update the find
Edit `src/content/find/<year>/<month>/<slug>/index.mdx` frontmatter: add `promotedTo: <review-slug>`.
(Slug usually matches the find's slug, so `promotedTo` and the find's filename match.)
### 7. Verify
- Run `npm run build`. Confirm:
- `/reviews/<slug>/` exists, shows the source badge and "← First surfaced…" backlink to the find page.
- `/find/<slug>/` shows the "→ Read the full review" callout pointing to the review.
- Any bundle that references the find still renders fine; the find card on the grid remains.
- The new review's tile on `/grid/` renders with its hero — if it's blank, the hero file isn't named `hero.<ext>` (or is missing).
### 8. Update the log
Append to `daily-finds.log.md`:
```
## YYYY-MM-DD — review: <slug>
Graduated from find captured on <find-date>, source: <source>.
Hero: <what was used and where it came from>.
Category: <category> (<new or existing>).
Fact-check: <corrections made, or "find held up">.
Amazon: <amazonLink added / carried / n-a>.
```
## Notes
- The find's slug and the review's slug should match. Same slug = same item across the pipeline; cross-references stay simple.
- Don't move or delete the find. Both records persist. The find is the historical capture; the review is the long-form treatment.
- Making the new review the homepage pick is a separate one-line edit to `src/data/pick.json` (`{"hero": "<slug>"}`) — the pipeline or user decides that after graduation; it is not part of this skill.
- If multiple finds describe the same underlying thing, consolidate them before running this skill (autonomous mode: pick the better capture, note the duplicate in the log).