pipeline: hero floor — bundles require at least 4 items with hero images

Bundles now ship only when at least four of their items have a hero.*
image, purely so the grid never renders image-thin. Clusters that miss
the floor are held back and logged rather than padded or written thin;
the weekly catch widens its window to older unbundled hero-bearing
finds instead of holding. Capture gets a nudge to try a second image
source before giving up on a hero.

Claude-Session: https://claude.ai/code/session_01WZaczDJjL3xZ3u5spsN5AL
This commit is contained in:
2026-07-14 08:08:57 -04:00
parent 7e7b5afa1f
commit f0f1d8fb61
4 changed files with 23 additions and 8 deletions
+9 -2
View File
@@ -30,10 +30,12 @@ Also read every existing bundle's `items[]` array — these are pre-clustered an
Aim for 4-7 clusters. Each cluster should:
- Hang off **one specific editorial angle**, phrasable in 4-8 words ("Pocket carry", "The morning kitchen ritual", "Travel as a kind of attention"). Avoid generic buckets ("Tools", "Apps") — those are tag pages.
- Hold **3-8 items**. Below 3 the grid feels thin; above 8 it stops being scannable.
- Hold **4-8 items**, of which **at least 4 have a hero image** (`hero.<ext>` next to the find's `index.mdx`) — the grid looks broken with fewer than four image cards. Hero-less finds may ride along beyond the four. Above 8 the grid stops being scannable.
- Be **distinct from existing bundles** in angle, even if a couple of items repeat.
Coverage check: after partitioning, every find should appear in at least one cluster (existing or new). If a find genuinely fits no theme, leave it uncovered and report it — don't pad a cluster with a misfit.
If a cluster can't meet the hero floor, **hold it back** rather than pad it with misfits or write it thin — record it as deferred (theme + items + which lack heroes) and revisit when a fourth hero-bearing find emerges.
Coverage check: after partitioning, every find should appear in at least one cluster (existing or new). If a find genuinely fits no theme, leave it uncovered and report it — don't pad a cluster with a misfit. Finds left homeless only because their cluster was deferred for the hero floor count as covered-pending — list them under the deferred cluster, not as uncovered.
### 3. Overlap rules
@@ -55,9 +57,12 @@ Cluster B — "<theme>" (N items)
...
Overlap with existing bundles: <slug> appears in <existing-bundle> + <new cluster>; ...
Deferred clusters (hero floor not met): "<theme>" — <items, annotating (no hero)>; or "none"
Uncovered finds: <list, or "none">
```
Annotate items that lack a hero with `(no hero)` in the cluster listings so the floor is visible at a glance.
Wait for the user to confirm, refine, swap, or merge clusters. Do not write files until they sign off.
### 5. Write each bundle
@@ -89,6 +94,7 @@ Body rules (same as `build-bundle`):
### 6. Verify
- Every slug in every `items[]` must exist at `src/content/find/<year>/<month>/<slug>/index.mdx` (locate with `find src/content/find -type d -name "<slug>"`). Confirm before declaring done.
- Every bundle meets the hero floor: at least 4 of its `items[]` folders contain a `hero.*` file.
- Run `npm run build`. If any bundle fails to compile, fix and re-run.
### 7. Update the log
@@ -100,6 +106,7 @@ Append to `daily-finds.log.md`:
Wrote <N> bundles from a pool of <M> finds.
Reuses across bundles: <count> (budget: ~20%).
Deferred clusters (hero floor): <list with items, or "none">.
Uncovered finds: <list, or "none">.
Bundles created: