The daily portfolio triage
Needs Work
LiveRuns every morning
Every morning the whole portfolio is ranked by which website most needs its owner's attention, with the reasons and a ready-to-run job for each. A morning email of the top sites goes out each morning.
A morning triage desk for 150+ websites. Live since 27 Oct 2026: the ranking is recomputed every morning, and the morning email is sent each morning; the first went out on 28 Oct 2026.
It is new. This page describes what it does and what it counts; it claims no results, and any will be reported once they are measured.
Live since 27 Oct 2026
These are totals read from the private control panel. They show how large the ranking and the weekly scan are, not what the owner has done with them: no site is named, and a count of zero is printed as zero.
- sites in the ranking
- 154
- measured 28 Oct 2026
- in the red tier
- 6
- measured 28 Oct 2026
- in the amber tier
- 36
- measured 28 Oct 2026
- pinned at the top
- 6
- a noindex homepage or a sitewide robots block
- measured 28 Oct 2026
- sites in the latest weekly scan
- 154
- 140 ok, 9 partial, 5 inconclusive
- measured 28 Oct 2026
- sites with half or more of their measured pages thin
- 36
- at least five pages measured
- measured 28 Oct 2026
Measured weekly. Counts taken on 28 Oct 2026. Scores from the run of 28 Oct 2026. A scan that could not be read is marked inconclusive and set aside; it is never counted as thin.
Busy-looking is not the same as worked-on
The portfolio is large (150+ live websites ranked across Hetzner Cloud servers and other hosting; Cloudflare Workers/Pages sites are out of scope) and run by one person with AI agents.
Routine automation (SEO fixes, error-tracker fixes, dependency bumps, data refreshes) touches nearly every site within a month. To a normal "last updated" check, every site looks busy.
Some sites quietly drift: thin pages, outdated years in titles, broken links, pages Google will not index, falling traffic. Nobody notices until the traffic has gone.
The owner wants to choose what to work on, and needs an honest, ranked reminder rather than an automated fixer.
Counted from deploy history, 90 days to 28 Oct 2026
- successful deploys (finished or ready) in the last 90 days across 150 sites
- 7,556
- measured 28 Oct 2026
How it works, in five steps
Detect, rank, act. It recommends; the owner decides.
Work log
Every day the system reads each site's Git commit history and sorts every commit into real work or routine (SEO, error-tracker, dependency, automated data refresh, fleet-wide sweep, bot and deploy plumbing).
Weekly site scan
A polite crawler visits every website: homepage, robots.txt, sitemap, 20 evenly sampled pages, a fake URL to catch "soft 404s", internal links, and the homepages of competitors that outrank it.
Signals
Search performance (Google Search Console daily data, traffic-cliff detection), AI-search citations, engagement, backlinks and open issues are joined to the scan. Indexing coverage is built but not yet active (see the signals below).
Scoring
Each site gets a transparent score built from named terms. Every point carries its evidence, such as days since real work or the share of measured pages that are thin. Critical problems are pinned to the top.
Delivery
A ranked page in the private control panel, and a daily email with the top 15, today's suggested plan and a copy-paste job prompt for each site, written to be handed straight to an AI coding agent. The email is switched on and is sent each morning.
What gets measured
The weekly site scan
Page checks
Per page: word count, noindex (meta tag and HTTP header, including bot-specific directives), headings, structured data, images, internal links, search box and navigation links. Also the sitemap, including sitemap indexes, and whether the site has an llms.txt.
Thin content
Pages under 300 words. Counting is language-aware: Thai, Chinese, Japanese, Lao, Khmer and Burmese pages are segmented with the Unicode word segmenter instead of being misread as thin.
Template duplication
8-word shingle similarity flags pages that are near-copies of each other.
Outdated content
Stale years in titles and headings, "last updated" dates more than 12 months old, and old copyright years. Historic context such as a founding year is deliberately ignored.
Broken links
Up to 60 internal links checked per site. Only a definitive 404 or 410 counts as broken; blocked or rate-limited checks count as unknown.
Competitor homepages
Up to 5 real competitors per site, taken from search results where they outrank it, with platforms such as video and encyclopedia sites filtered out, cached for 30 days.
Polite by design
Rate-limited, small fixed concurrency, an honest self-identifying user agent, 12-second timeouts and capped page sizes.
Search, AI and audience signals
Traffic trend
The last 28 days of clicks against the 28 days before, from Search Console. Sites with zero clicks and real content are flagged.
Traffic-cliff dating
The control panel's existing cliff detector runs over the daily series, so a collapse older than a month is still detected and dated, and matched to the nearest Google algorithm update where one is close.
Indexing gap
Pages in the sitemap against pages Google actually indexes. Built but not yet active: the panel does not yet hold a trustworthy indexed-page count, so this term does not fire.
AI-citation gap
Sites that get search impressions but are never cited in AI answers, using the Google AI Overviews and Perplexity checks the panel already runs.
Engagement
Content that ranks but makes visitors leave quickly, from GA4. Built but not yet calibrated on live data.
Backlink loss
Referring domains falling month over month.
Open problems
The count of serious open issues. Dependency-bot noise is deliberately excluded.
Coverage
Every website on the Hetzner Cloud fleet and on other hosting is in scope; infrastructure tools (monitoring, mail, admin panels), parked sites and sites still being set up are excluded by tag. Static Cloudflare Workers/Pages sites are also kept out of the triage ranking and uptime monitoring, by the owner's decision.
How a site is scored
Each site gets a 0 to 100 score built from named terms, each with its points and its evidence. The weights are not published here: they will be tuned as the system runs.
example-site.com
- 64 days since real work
- 58% (11/19) of measured pages are thin
- no search box
Suggested: Content sprintbig project
designedAn illustration with a fictional site, not a measurement.
15+ named terms
- Neglect (in steps of days)
- Noindex
- Thin content
- Missing features
- Traffic drop
- Dated cliff
- Stale sitemap
- Outdated pages
- Broken links
- Indexing gap
- AI-citation gap
- Engagement
- Backlink loss
- Competitor feature gaps
- Site-type checklist
- Open problems
- Page speed
- On-page gaps
- Console errors
Neglect is judged in steps of 30 / 60 / 90 days since real work.
- Pinned rows
- A site that is noindex is always shown at the top. The owner keeps several unfinished sites deliberately noindex, and they stay pinned as a reminder that they need work. Thin pages do not pin a site: they are a large score term, and the email lists thin sites in a compact section of their own.
- Priority tiers A, B and C
- The owner sets each site's priority tier. The score is weighted x1.3 / x1.0 / x0.6 for tiers A, B and C, so a lower-priority site still surfaces when badly neglected but rarely crowds out a higher one. A pinned site is not weighted.
- Colour tiers
- Red (60+), amber (35 to 59) and green.
- Effort tag
- Every suggested job is labelled a quick win (add an about page, schema, a search box, llms.txt, fix a few broken links or old titles) or a big project (a content sprint, a relaunch, an indexing gap).
- Site-type checklist
- An AI model labels each site (directory, news, guide, register, tool, portfolio or other), and the owner can set the label by hand. For a directory, a register, a news site or a guide the score then checks a few things that type should have, such as a search box, enough listing pages, article schema or links between pages. The labels are still being filled in, so the checklist applies only to the sites that have one.
- Hygiene terms
- Three small terms, capped together, from checks the panel already runs: a poor mobile page-speed score on the last two captures, a fifth or more of the crawled pages missing a title or meta description or repeating a title, and console errors on the homepage in each of the last three runs. A capture that failed or is missing adds nothing and removes nothing.
- Site down
- A site with an open outage alert is flagged "DOWN, fix uptime first", is left out of today's plan, and has its scan-derived terms set aside when the scan was taken during the outage.
- Competitor feature gaps
- Features present on 60% or more of a site's real competitors but missing on the site, judged only once at least 2 competitors have been scanned.
The control panel page
A page called "Needs work" in the private control panel holds the full ranked list of every site: pinned first, then by score.
Columns
- Score
- Colour tier
- Priority tier (A, B or C)
- Days since real work
- Pages and thin share
- Noindex
- Top reasons
- Suggested job and effort
- Search impressions and clicks, last 28 days
Filters by server, tag, colour tier, priority tier and effort, a switch to show dismissed sites, and a CSV export.
Row actions
- Next up: queue the site for the plan.
- Dismiss 30 days: hide a site for a month; it returns on its own.
- Mark by design: say the state is intended. In a site's score breakdown the same can be said of a single term, which is then dropped from that site's score; each mark can be undone.
- I worked on this today: record real work the commit log cannot see; it also queues a fresh scan of the site.
- Copy prompt: take the ready-to-run job.
- Rescan now: refresh one site on demand.
Per-site card
The full score breakdown (every term, its points and its evidence), a score history sparkline, the last 10 commits with their class badges and a Reclassify control, the search queries to target, before and after work-impact results, and a short log of when the site was proposed, through which channel, at what rank and with what outcome.
The morning email
A daily email, separate from the existing health digest, with the top 15 sites.
The email is switched on and is sent each morning. The first one went out on 28 Oct 2026.
Needs work — top 15 of 150 (5 pinned) — a sample day
SampleToday's plan
- projectexample-site.comContent sprint on the thin pages
- quick winsample-guide.netAdd a search box
- quick windemo-register.exampleFix the broken links
Next updemo-tools.example
Ranked by need
| # | Site | Score | Suggested job |
|---|---|---|---|
| 1 | example-site.com | 71 | Content sprintproject |
| 2 | sample-guide.net | 66 | Add a search boxquick win |
| 3 | demo-register.example | 62 | Fix the broken linksquick win |
| 4 | demo-tools.example | 58 | Indexing reviewproject |
| 5 | sample-news.example | 55 | Add author pagesquick win |
| 6 | mock-directory.example | 52 | Rewrite the templatesproject |
| 7 | sample-wiki.example | 49 | Refresh the titlesquick win |
| 8 | demo-portfolio.example | 47 | Add an about pagequick win |
| 9 | mock-guide.example | 44 | Answer-first rewriteproject |
| 10 | example-register.example | 41 | Regenerate the sitemapquick win |
| 11 | sample-tools.example | 39 | Outreach planproject |
| 12 | demo-news.example | 37 | Improve the introsproject |
| 13 | mock-wiki.example | 33 | Add llms.txtquick win |
| 14 | sample-portfolio.example | 29 | Update the footerquick win |
| 15 | example-guide.example | 26 | Link the guides togetherproject |
- Today's plan
- One big project plus two quick wins, taken from the owner's Next-up queue first and skipping sites worked on in the last 3 days and sites that are down.
- Next-up queue
- Up to 5 owner-chosen sites shown first. They clear themselves once real work is detected.
- Top 15 ranking
- One line per site: rank, score, days since real work, the main problems, traffic at stake, the suggested job and a quick-win or project badge.
- Fleet sweeps
- Quick wins that the same job fits on 3 or more sites are grouped into one block with a single prompt to run across them.
- Movers
- The biggest risers and fallers since last week, with the score terms that changed.
- Monday scorecard
- Sites really worked on last week, and whether the neglect backlog is shrinking, plus a "what worked" look at traffic before and after recent work.
- One-click actions
- Next up, Dismiss and Worked today from the phone. Links are single-use, expire after 7 days and are stored only as hashes. Each opens a confirm screen, because email security scanners automatically click links.
- Copy-paste job prompts
- A ready-to-run brief per site (the repository, which project notes to read, the top reasons, sample URLs of thin, outdated or broken pages, the search queries to target, the suggested job, the site's own notes, its latest real commits and a "Done when" line), so a fresh AI coding session starts with full context.
- Stale-ranking flag
- If the overnight scoring did not complete, the email is still sent, but its subject starts with "[STALE]" and a banner says when the ranking was last scored.
The old "sites needing revisit" section of the health digest is retired.
Honesty and engineering
A ranking is only worth reading if it can be trusted, so the system is built around not fooling itself.
- of routine commits mislabelled as real work (4 of 382), in a set of 1,186 hand-labelled commits (a set also used while tuning)
- 1.05%
- measured 28 Oct 2026
- of routine commits mislabelled as real work (3 of 212), in a second set of 615 hand-labelled commits from 16 repositories, measured after the rule changes (a set that also informed them)
- 1.42%
- measured 28 Oct 2026
- one 1.5 MB adversarial page stalled the first version of the HTML parser, found by the first verifier round
- 26 min
- measured 26 Oct 2026
A zero is data; a failure is not
If a page cannot be fetched, parsed or measured, the result is unknown, never zero. A site is never called thin because a scan failed. JavaScript-only shells, pages behind a login and off-site redirects are recognised and set aside.
Honest days since real work
A daily commit sync (roughly 150 API calls a run, far inside GitHub's limits) feeds a classifier with 7 classes: real work, SEO, error-tracker, dependencies, automated data, fleet-wide sweep, and bot and deploy plumbing. The rule that fired is stored, so the panel can show why a commit got its label. Skip-deploy markers never decide the class, and a commit message that lands on 3 or more sites in a week is treated as a sweep rather than real work on any one of them. Genuinely ambiguous commits get a second opinion from a self-hosted open-weight model, with validated output and a daily cap. Manual decisions always win: a Reclassify control on any commit, and an "I worked on this today" button.
Checked against hand labels
The classifier was tuned on 620 commit subjects taken from real deploys, then checked against two sets of hand-labelled commits. Neither is a clean test: the first set was also used while tuning, and the second, measured after the rule changes, had itself been used to find where the rules were too broad. The shares above are routine commits wrongly called real work; on both sets no real work was called routine.
Parsers rebuilt for linear time
The HTML and sitemap parsers were rebuilt to run in linear time with capped input after the first verifier found an adversarial page that stalled the first version for the time shown above.
Adversarial verification
Every build wave is attacked by an independent verifier agent whose job is to refute it. The first round rejected two of the three components (a classifier blind spot and the parser stall) and sent them back for rework.
No paid AI per run
Classification and site-type labelling run on the fleet's own self-hosted open-weight models. The marginal AI cost per run is designed to be $0.
Also built, and what is switched off
Three more parts. The first two appear on each site's card in the control panel and in the email; neither has produced a result that this page claims. The third is switched off.
- Queries to target
- For each site, up to 5 real search queries it already gets impressions for but ranks poorly on (below position ten), each with its impressions, its position and the page Google actually ranks for it. "Improve these queries" replaces a vague "add content".
- Work-impact report
- 30+ days after a burst of real work, Search Console clicks and impressions for the 28 days before are compared with the same length of time afterwards, beside the score change. The aim is to learn which kinds of work actually move traffic.
- Weekly AI memo
- A short note of up to 120 words per red or amber site on what it is missing. The code is built and the owner chose to launch without it, so it is switched off.
Questions
Does it fix sites automatically?
No. It ranks and explains, and the owner chooses. It does not edit or deploy sites; it recommends.
Does it count SEO bot fixes as work?
No. SEO, error-tracker, dependency, automated data and fleet-wide sweep commits are sorted as routine, so they do not reset a site's days since real work.
What if a site blocks the scanner?
It is marked unknown and never penalised.
Is the morning email on?
Yes. It is sent each morning, and the first one went out on 28 Oct 2026. It has its own switch, apart from the ranking.
Is it live?
Yes. The ranking went live on 27 Oct 2026 and is recomputed every morning. The morning email is switched on; the first one went out on 28 Oct 2026. Results will be reported once they are measured; none are claimed yet.