pipeline: autonomous operation — shortlist stage, auto modes, daily-pipeline orchestrator
- daily-finds: feed-first fetch strategy (fetch: feed + feedUrl), cadence-aware scanning, new score-and-shortlist stage (shortlist: true, up to 12/day, top 1-3 flagged as review candidates), Amazon affiliate lookup for shortlisted physical products, and authority to apply mechanical sources.json maintenance (skip dead sources, demote dormant ones, record working fetch paths) instead of logging recommendations nobody executes. - build-bundle: auto mode (no confirmation gate when unattended) and a 'weekly' date-based catch mode so shortlisted finds never sit invisible for weeks. - cluster-bundles: auto mode. - build-review: hero.ts registration step removed (heroes auto-discovered from hero.<ext>); mandatory fact-check against the product's own site in auto mode; amazonLink carry-through; auto mode publishes and logs instead of pausing twice for approval. - New daily-pipeline skill: capture → bundle → reviews → pick of the day → build → commit → push → digest, with granular per-stage commits. This is the entrypoint for scheduled runs. - Project CLAUDE.md documenting the pipeline and its foot-gun conventions.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
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, expands the body into a full review, writes src/content/reviews/<slug>/index.mdx, and links the two via fromFind / promotedTo. Use when the user runs /build-review <slug>, says "review this find", or "graduate <slug>".
|
||||
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
|
||||
---
|
||||
|
||||
@@ -10,6 +10,11 @@ Convert one captured `find` into a full `review`. Both records persist — the f
|
||||
|
||||
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.
|
||||
@@ -21,31 +26,46 @@ Note on hero assets: the find's hero, when present, sits at `src/content/find/<y
|
||||
|
||||
### 1. Read the find
|
||||
|
||||
Parse frontmatter. Note: `name`, `subtitle`, `link`, `linkText`, `source`, `topics`, `tags`, plus the body.
|
||||
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>."
|
||||
|
||||
### 2. Suggest a hero asset
|
||||
### 2. Pick a hero asset
|
||||
|
||||
Look at the external link and propose a hero asset — a screenshot, demo gif, or product photo from the maker's site.
|
||||
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).
|
||||
|
||||
Tell the user what you'd download and where to place it (`src/content/reviews/<slug>/hero.<ext>` — colocated with the review's `index.mdx`). Pause for approval before downloading.
|
||||
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).
|
||||
|
||||
### 3. Expand the body
|
||||
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.
|
||||
- Reference the hero asset inline if downloaded (``).
|
||||
- 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.
|
||||
- Match the voice of existing reviews under `src/content/reviews/` — informative, concise, no sales tone.
|
||||
|
||||
### 4. Write the review
|
||||
Interactive mode: show the proposed body and wait. Autonomous mode: proceed.
|
||||
|
||||
### 5. Write the review
|
||||
|
||||
File: `src/content/reviews/<slug>/index.mdx`.
|
||||
|
||||
@@ -58,8 +78,9 @@ 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>
|
||||
tags: <merge the find's tags with any review-specific additions>
|
||||
link: "<from the find>"
|
||||
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>"
|
||||
@@ -68,38 +89,19 @@ fromFind: "<find slug>"
|
||||
|
||||
If the find had no `subtitle`, generate one — it's required on reviews.
|
||||
|
||||
### 5. Update the find
|
||||
### 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.)
|
||||
|
||||
### 6. Register the hero in `src/lib/hero.ts` (REQUIRED if a hero asset exists)
|
||||
|
||||
This is the step that has bitten us repeatedly. **The home grid and category cards do NOT auto-discover review hero assets** — they only show a hero if the review's slug is a key in the `heroes` record exported by `src/lib/hero.ts`. Skipping this step ships a review whose grid card is empty.
|
||||
|
||||
For a review with a static image hero (`hero.png`, `hero.jpg`, `hero.webp`):
|
||||
|
||||
1. Add an `import` line near the top, alphabetically grouped with the other image imports. The variable name is the slug in camelCase. Example for slug `tablepro`:
|
||||
```ts
|
||||
import tablepro from '../content/reviews/tablepro/hero.png';
|
||||
```
|
||||
2. Add an entry to the `heroes` record, alphabetically by key:
|
||||
```ts
|
||||
tablepro: { kind: 'image', src: tablepro },
|
||||
```
|
||||
|
||||
For a review with a video hero (`.mp4`), put the import in the second (video) import group and the record entry uses `kind: 'video'`. Match the existing pattern.
|
||||
|
||||
If the review legitimately has no hero asset (rare — e.g. text-only reviews like `snewpapers-newspaper-archive`, `sindre-sorhus-older-mac-apps`), explicitly note it in the log entry from step 8 ("no hero asset — text-only review") so the omission is intentional and traceable.
|
||||
|
||||
### 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.
|
||||
- Visit `/grid/` (or `/`) and confirm the new review's tile renders with its hero — not blank. **If the tile is empty, step 6 was skipped.**
|
||||
- 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
|
||||
|
||||
@@ -109,11 +111,15 @@ 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.
|
||||
- Never auto-write a review without showing the user the proposed body first. This is editorial work; the skill's job is to draft, not to publish unilaterally.
|
||||
- If multiple finds describe the same underlying thing, the user should consolidate them manually before running this skill.
|
||||
- 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).
|
||||
|
||||
Reference in New Issue
Block a user