Files
unique/.claude/skills/cluster-bundles/SKILL.md
T
rzen 06f8a9dc22 pipeline: hard editorial exclusion of tobacco and alcohol content
New rule at every selection stage: daily-finds drops such items at
capture (categorical, overrides design/gift appeal; borderline cases
skip too), build-bundle and cluster-bundles treat legacy alcohol
finds as ineligible for new bundles, and build-review refuses to
graduate them even on explicit slug. Existing finds stay published
per forward-only decision; CLAUDE.md records the policy centrally.

Claude-Session: https://claude.ai/code/session_01WZaczDJjL3xZ3u5spsN5AL
2026-07-14 09:03:05 -04:00

7.4 KiB
Raw Blame History

name, description, disable-model-invocation
name description disable-model-invocation
cluster-bundles Batch-cluster every existing find item in src/content/find/ into 4-7 thematic bundles. Use when the user wants to bring the find pool up to date all at once — ("re-cluster the finds", "build bundles for everything", "spread the new finds across themed bundles"). For drafting one bundle from a single theme, use build-bundle instead. true

cluster-bundles

Bulk version of build-bundle. Reads the entire src/content/find/ pool, partitions it into themed clusters, and writes one src/content/bundles/<date>-<slug>/index.mdx bundle per cluster. The audience-facing site treats bundles as the primary discovery vehicle for individual find items, so the goal is coverage: by the end of the run, almost every find that deserves a home should have one.

Invoke from inside the unique.rzen.dev repo.

Inputs

  • src/content/find/<year>/<month>/<slug>/index.mdx — the full pool to cluster (folders are nested by date but slugs are globally unique; iterate with find src/content/find -name index.mdx).
  • src/content/bundles/*.mdx — already-written bundles. Their items[] lists are the prior clustering — read these to know which finds already have a home and what themes have been used.
  • Optional argument: a number of clusters to target (default: model's call, usually 4-7).
  • Optional argument: a list of theme phrases to seed clustering around.

Procedure

1. Read the pool

Read the frontmatter and body of every find. Note the name, subtitle, topics, tags, and the body's stated virtue (the specific thing that makes the item delightful). Tags and topics are hints, not the answer — the body usually tells you what cluster a find actually belongs to.

Also read every existing bundle's items[] array — these are pre-clustered and should not be re-clustered into a new redundant theme. They can still be re-used in a new cluster if the new theme genuinely calls for them (see overlap rules).

2. Partition into clusters

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, of which at least 2 have a hero image (hero.<ext> next to the find's index.mdx) — with 01 images the grid reads as a wall of text. Hero-less finds ride along freely; beyond the floor, aim for ~4 heroes, and give bigger clusters (78 items) proportionally more. Above 8 the grid stops being scannable.
  • Be distinct from existing bundles in angle, even if a couple of items repeat.

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 enough hero-bearing finds emerge.

Ineligible: tobacco- and alcohol-related finds. Legacy finds of this kind (wine, whisky, cocktail, bar items) stay published but must never be clustered into a new bundle. Exclude them from the pool up front and list them as "ineligible (alcohol/tobacco)" rather than uncovered.

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

Re-use is allowed but rationed. Set a soft budget: at most ~20% of items across all new bundles may be repeats from existing bundles or from other new bundles in this same run. Concretely, for a 25-item pool, that's ~5 reuses total. Track repeats as you draft.

When choosing which items to repeat: only repeat a find when the second theme genuinely illuminates a different facet of it. "It also kind of fits over here" is not enough.

4. Confirm with the user

Autonomous mode (auto argument, or running unattended — e.g. via /daily-pipeline or a scheduled/headless session): skip the confirmation; hold yourself to the same bar, write the bundles, and record the full plan (clusters, overlaps, uncovered finds) in the log entry so the user can review and veto afterwards. When torn between a bold theme and a safe one, take the safe one.

Otherwise, before writing any files, show a compact plan:

Cluster A — "<theme>" (N items)
  - <slug>: <name>
  - ...
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

Same file format as build-bundle. For each cluster, write src/content/bundles/<YYYY-MM-DD>-<theme-slug>/index.mdx:

---
title: "<Theme phrased as a noun phrase, max ~60 chars>"
date: YYYY-MM-DD
tags: [daily-finds, <topic-tag-1>, <topic-tag-2>]
description: "<One-line meta description.>"
blurb: "<One short editorial sentence; appears in the home feed.>"
items:
  - <slug>
  - <slug>
  - ...
---

> <One audience-facing sentence or two that names what links these finds. Vary the opening — don't reuse 'Today's catch' for every bundle in the run. Read like a magazine standfirst, not a checklist.>

Body rules (same as build-bundle):

  • 1-2 sentence intro paragraph in a blockquote. No headings, no list items, no numbered candidates — the grid handles the items.
  • Audience-facing language. Never write "today's pick", "candidates", "winners".
  • Vary the opening across the batch. With 4-7 bundles going out the same day, repeating "Today's catch" five times feels mechanical.

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 2 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

Append to daily-finds.log.md:

## YYYY-MM-DD — cluster run

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:
- <date>-<slug-A>: <title> (N items)
- <date>-<slug-B>: <title> (N items)
- ...

Notes

  • This skill complements, doesn't replace, build-bundle. After a cluster run, build-bundle is still the right tool for ad-hoc, single-theme bundles on top of new captures.
  • If two themes you're considering have heavy overlap (≥50% same items), they're really one theme — merge them and pick the stronger framing.
  • Date all bundles with the run date, not staggered — these are siblings written together, and the home feed will sort them naturally by title.
  • Don't edit existing bundles when running this. If an existing bundle overlaps with a new cluster you're proposing, either keep the new cluster (overlap-tolerated) or drop it from the plan; do not retroactively rewrite history.