Triage
Claude Code workspace template for running consistent SEO across a portfolio of managed websites.
npx -y skills add mkreindel/seo-toolkit-template --skill triageAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Score every site in `sites/` by SEO opportunity and recommend the top 3 to focus investment on. Considers revenue potential, current authority, technical health, content gap, and conversion potential. Outputs a ranked list with rationale. Use when the user types `/triage` or asks "which sites should I focus on."
SKILL.md
10.3 KB, as published. Nobody here has run it
/triage — Portfolio prioritization
Helps the user pick which sites in their portfolio deserve SEO investment this quarter. With 20+ managed sites and limited time, this is the highest-leverage decision.
Inputs
Optional:
- Time horizon —
quarter(default),month,year. Adjusts how forward-looking opportunities are weighted. - Capacity — number of sites the user can realistically focus on (default: 3).
- Filter — optionally limit to sites matching a tag in
notes.md(e.g., "client-work", "personal", "high-revenue").
Workflow
Step 0 — Cron-mode detection (if invoked with --cron)
If the invocation contains --cron, this skill runs in cron mode (no user available). Required behavior:
-
Idempotency check: see this skill's "Routine versioning + idempotency contract" section. If today's output already exists, exit cleanly with
exit: "idempotent-skip". Write one line to the audit log viascripts/lib/audit-log.mjsappendRun({ exit: "idempotent-skip", ... }). -
Escalation contract: any decision that would normally prompt the user (missing required file, voice anti-AI failure, schema validation failure, keyword cannibalization, etc.) MUST be escalated by writing an item to
sites/{site}/_inbox/viascripts/lib/cron-mode.mjswriteInboxItem(...). After writing, exit cleanly withexit: "escalated". Do NOT useAskUserQuestionin cron mode. -
Defaults: when a choice would normally be asked, default to
site-info.md/goals.mdvalues. If both are silent on the required choice, escalate per (2). -
Audit log: ALWAYS write one line to the audit log on exit — success (
shipped), escalation (escalated), idempotent skip (idempotent-skip), or failure (failed). -
Backoff: at the start of every cron-mode run, call
checkBackoff({ routine })fromscripts/lib/audit-log.mjs. If true, the routine has hit the 3-strike threshold — write_inbox/routine-disabled-{name}.md, runscripts/sync-schedules.mjs --pause-routine={name}, and exit.
Step 1 — Read context (Rule 1)
Load every sites/[name]/site-info.md and notes.md. If any site is missing required files, flag it but don't fail.
Step 2 — Score each site on five dimensions
For each site, compute a score 0–10 on each dimension:
Dimension 1: Revenue potential (weight: 30%)
- 10 = real revenue source, money-keyword rankings would meaningfully grow income
- 7 = active business, ranking gains help but aren't transformative
- 4 = side project, lifestyle business, low monetization
- 1 = vanity site, internal tool, no revenue intent
Read from site-info.md → Business → "What they do" + Conversion → "What counts as a conversion" + recent revenue notes.
Dimension 2: Current authority (weight: 20%)
Score based on site-info.md SEO baseline:
- 10 = > 10K monthly organic visits, DR > 40, indexed > 500 pages
- 7 = 1K–10K visits, DR 20–40, indexed 100–500
- 4 = 100–1K visits, DR < 20, indexed 20–100
- 1 = new site, < 100 visits, < 20 pages indexed
Higher-authority sites compound faster — investment pays off sooner.
Dimension 3: Technical health (weight: 15%)
From most recent /audit results in site-info.md:
- 10 = all 8 non-negotiables pass, Lighthouse mobile ≥ 90, no Tier 1 gaps on top pages
- 7 = minor fixes needed (1–2 non-negotiables fail or floor < score < 90)
- 4 = significant gaps (CSR Lovable site without prerender, missing schema, Lighthouse < 70)
- 1 = fundamentally broken (no sitemap, blocked by robots, manual action, mostly thin content)
Critical filter: a site scoring 1 here gets prioritized for technical fixes regardless of other dimensions, because content investment is wasted on a broken foundation.
Dimension 4: Content gap / opportunity (weight: 20%)
- 10 = strong keyword research done (high-value keywords identified), competitors rank for terms this site doesn't, clear content path forward
- 7 = some opportunity, partial keyword research
- 4 = saturated niche or thin opportunity
- 1 = no opportunity (already #1 for everything relevant, or topic is dead)
Read from keywords.csv row count + competitor analysis in notes.md if present.
Dimension 5: Conversion potential (weight: 15%)
- 10 = clear conversion path documented (CTAs, form, booking system) + tracking working
- 7 = partial setup, conversions counted but not optimized
- 4 = weak CTAs, no tracking, no clear path
- 1 = no conversion infrastructure (rankings would generate traffic but no revenue capture)
Read from site-info.md → Conversion section.
Step 3 — Compute weighted score
Total = (Revenue × 0.30) + (Authority × 0.20) + (Technical × 0.15) + (ContentGap × 0.20) + (Conversion × 0.15)
Score range: 1.0 to 10.0.
Step 4 — Apply filters and special rules
- Critical technical issue (Dimension 3 = 1): site jumps to top of "fix first" list, separate from main ranking.
- Hard pause flag in
site-info.md: site removed from ranking entirely. - Filter argument: restrict ranking to sites matching the tag.
- Architecture gap (
SEO_GUIDE.mdSection 2.6): any site withservice-business: trueAND > 3 rows inservice-keywords.csvAND noarchitecture.mdgets an inline flag in its rationale:⚠️ Missing transactional architecture — required before next /service run.This doesn't change the score but surfaces the planning blocker so it's visible at the recommendation stage.
Step 4.5 — Compute goal-progress per site (T2-J)
For each site in sites/*:
- Read
sites/{site}/goals.md. Parse the## Success metricssection into a list of{metric, target}pairs. - For each metric, attempt to measure the current value:
- "Blog count: N+ new posts" → count entries in
used-keywords.mdshipped since quarter-start (parse the "Shipped — blog posts" section). - "Primary keyword rank: top-N for X" → if SEMrush API configured, query Position Tracking; otherwise mark
cannot-measure-automatically. - "Backlinks: ≥N total in Referring Domains" → if SEMrush API configured, query backlinks endpoint.
- "GSC indexed pages: ≥N" → query GSC API coverage endpoint (uses GSC_OAUTH_REFRESH_TOKEN).
- "Sitemap grows from N → M URLs" → diff live sitemap.xml count against the target.
- Free-text metrics (e.g., "GBP reviews: ≥5 by end of month") → mark
cannot-measure-automatically; user fills in monthly.
- "Blog count: N+ new posts" → count entries in
- Compute "% to target" where possible:
current / target * 100, clamped to 100% for the "exceeded" case. - Assign visual indicator:
- ✅ on track (>= 80%)
- ⚠️ behind (50–79%)
- ⏸️ off-track (< 50%)
- 🔵 exceeded (> 100%)
- ❓ cannot-measure-automatically (free-text or API unavailable)
Step 5 — Generate ranked list + rationale
Output format:
# Portfolio triage — [date]
**Capacity:** [N] sites | **Horizon:** [quarter/month/year]
## Fix-first (technical issues blocking content investment)
| Site | Score | Critical issue |
|------|-------|---------------|
| [name] | 1.0 (Dim 3) | [e.g., CSR Lovable site, no sitemap] |
## Top [N] for SEO investment this [horizon]
### 1. [site-name] — total score: [X.X]
- **Revenue potential:** [score]/10 — [one sentence rationale]
- **Authority:** [score]/10 — [details]
- **Technical:** [score]/10 — [recent audit summary]
- **Content gap:** [score]/10 — [keyword opportunity summary]
- **Conversion:** [score]/10 — [conversion infrastructure status]
- **Recommended next 3 actions:** [bulleted, specific — if `Architecture gap` flag is present, "Create `architecture.md` from `templates/architecture.md`" is action #1]
### 2. [site-name] — total score: [X.X]
[same structure]
### 3. [site-name] — total score: [X.X]
[same structure]
## Park (don't invest this [horizon])
[remaining sites, listed with one-sentence reason]
## Suggested cadence across the top 3
- **Site 1 (highest score):** [N posts/week + service pages + off-page actions]
- **Site 2:** [allocation]
- **Site 3:** [allocation]
Aggregate publishing across the 3 should fit the user's realistic weekly capacity.
## Goal-progress per site (T2-J)
For each site, list each goals.md success metric with current value and indicator:
### [site-name]
- ✅ Blog count: 5 / 8 posts (63%)
- ⚠️ Primary keyword rank: SEMrush API rate-limited this run (recheck next cycle)
- ⏸️ Backlinks: 3 / 7 (43%) — accelerate before quarter-end
- 🔵 GSC indexed pages: 18 / 17 (106% — exceeded)
- ❓ GBP reviews: 2 / 5 (free-text metric; manual verification)
Step 6 — Save results
Write to triage-[YYYY-MM-DD].md at the toolkit root (gitignored if user prefers). Don't overwrite previous triages — keep a history for trend analysis.
Step 7 — Quarterly re-run reminder
If most recent triage was > 90 days ago, flag this. If ≤ 90 days, note "Last triage: [date] — re-run only if portfolio composition changed."
Routine versioning + idempotency contract
This skill participates in cruise-control via --cron mode. When invoked by cron:
-
Stamp
routine_versionin every output (the_triage/YYYY-MM.mdcross-site summary frontmatter, per-sitenotes.mdtriage-rank entry, the audit log line viascripts/lib/audit-log.mjs). Currentroutine_version: 1.0. -
Idempotency: this skill MUST be safe to run twice in the same month without producing duplicate work. Implementation: check whether
_triage/{YYYY-MM}.mdalready exists for the current month; if so, exit cleanly withexit: "idempotent-skip". The monthly summary is meant to be generated once on the 1st of the month. -
Goal-progress computation (T2-J from spec): the cron-mode run reads each site's
goals.mdand computes "% to target" per success metric, integrated into the per-site recommendation in the triage output.
Reference: docs/specs/2026-05-16-agents-cruise-control-design.md § Operational hardening O3 + § T2-J.
Refusal conditions
sites/folder is empty (no managed sites).- All sites have
hard pauseflag (nothing to rank).