Where Mesh stands#
Mesh is at Phase 0: scaffolded skeleton. The
scaffold shipped 2026-05-02: the full Gillish house architecture
on disk, a PSR-4 src/ tree with
Autoloader.php, a single Plugin.php
hook registry, Core/{Installer,DbMigrator,HeaderCipher},
Shared/{Options,Hooks} constant facades, empty
Crawl/ Graph/ Admin/ Privacy/ Integrations/
directories held by .gitkeep, plus
templates/, assets/,
uninstall.php, readme.txt and
CHANGELOG.md. The directory layout, file naming,
namespace (Gillish\Mesh\*), slug
(gillish-mesh) and plugin identity are
locked (plan §5); functional features are not.
The project is deliberately parked until Gillish Cairnstone and
Gillish Node ship, the skeleton plus the two specs
exist so the design doesn’t drift and the re-entry cost
stays near zero.
Why standalone, not a Node module#
A first draft scoped this work as a module inside Gillish Node. A peer review raised that crawling-other-sites is materially more controversial than the rest of Node, link management, content graphs, GSC integration are all “operate on your own site” use cases nobody flags ethically; a crawler is different. Three options were weighed: a standalone plugin, a Pro-gated Node module, or dropping the feature. The author chose standalone, for five reasons: reputational isolation (Node’s wp.org listing stays focused on the “snill” feature set), compliance posture (corporate / agency code scans of Node find no crawler regardless of toggle state), independent update cadence (Cloudflare-evasion fixes don’t force Node releases), pricing flexibility, and ethical positioning (“a specialist tool you opt into buying” reads differently from “a feature in your link manager”).
The accepted trade-off: shared services (PageRank, levels, graph build, the D3 canvas, dark-mode CSS, branded UI) cannot be imported from Node, they are re-implemented fresh (~1–2 weeks of one-time foundation work). No Composer package, no shared filesystem: wp.org plugins can’t rely on Composer at runtime, a shared package would couple two independent release schedules, and the shared surface (~430 lines of PageRank + Levels + GraphBuilder) is small enough that duplication is cheaper than the abstraction. The Better Together detection layer closes the gap for installs that have both.
The phased rollout#
Each phase ends with a manual verification pass on a real target (the author’s staging site or a friendly blogger who has given permission). When something works end-to-end, the version ships and a DONE-WORK entry is written. The calendar is “weeks of focused work”, while the project is parked, that calendar doesn’t tick.
Phase 0: skeleton (done, 2026-05-02)#
Directory layout, file naming, namespace, and plugin identity
committed to disk and version-tracked; the plan and brief
preserved alongside the empty shell. 0.1.0-skeleton.
Phase 1: Foundation → v0.9.0#
Plugin scaffold, autoloader, the real DbMigrator
(dbDelta against the two-table §7 schema, DB_VERSION
starting at 1), settings-page skeleton, uninstall. Empty admin
pages. Verifies the activation / deactivation / uninstall
round-trip on a real WP install.
Phase 2: Crawler MVP → v1.0.0#
SitemapFetcher, PageFetcher (realistic
Chrome UA + headers, Cloudflare-challenge detect-and-explain),
LinkExtractor (hardened DOMDocument,
main / article / body scoping),
CrawlJob, the WP-Cron-backed CrawlQueue,
HeaderCipher (AES-256-CBC, keyed off
wp_salt('auth')). A WP_List_Table of
past crawls + a new-crawl form. No graph view yet.
Phase 3: Single-graph view → v1.1.0#
PageRankService (~80 lines, pure, no WP coupling),
LevelsService (~150 lines, LCC discovery + L1..Ln
BFS), GraphBuilder (~200 lines, reads the
plugin’s own pages table, anchor text a
first-class output), and the self-contained D3 v7 canvas
(mesh-graph.js, ~400 lines). The
Their site tab only.
Phase 4: Comparison + Better Together → v1.2.0#
The Your site tab (both the
standalone-self-crawl path and the Gillish Node bridge), the
Compare tab with the metrics table and clickable
⚠ insight chips, and GillishNodeBridge. v1
feature-complete. (Pricing model is decided at this phase entry.)
Phase 5: Polish → v1.2.x + launch#
Dark mode (mesh-dark.css + a color-scheme JS, own
implementation, mirroring Node’s body-class pattern), CSV
export, the re-crawl button, the retention sweep, the
configurable param-blocklist UI. Then the wp.org listing + the
Pro-tier sale page go live.
Phase 6: Deferred (demand-driven)#
Topical-NLP overlap, scheduled recurring crawls, multi-competitor overlay, true synchronised side-by-side D3, a REST API, SERP-API integration, CSV import (a strong v2 candidate, sidesteps Cloudflare entirely). Each becomes its own plan if and when prioritised, after Phase 5 ships and gets used.
When picking this up#
The plan’s §21 re-entry checklist, verbatim in intent:
- The name is locked: Gillish Mesh, slug
gillish-mesh, namespaceGillish\Mesh\*. Don’t second-guess it, renaming a WP slug after release is painful, and the Node + Mesh pairing is the right brand call. - Set up a Git repo (Mesh is currently Dropbox-durable, not version-controlled). The plan is the seed; on resume it moves into the new repo’s plans and out of any holding location.
- Start with Phase 1 scaffolding, the §6.1 directory layout is ready to instantiate.
- Don’t share code with Gillish Node directly. The Better Together bridge (plan §14) is the only contact surface: a one-way read of one transient + a
class_existscheck. That is the whole API contract. - The algorithm services (
PageRankService,LevelsService,GraphBuilder) can be lifted as starting points from Node’ssrc/Graph/Services/, but they need de-WP-coupling; write fresh implementations against Mesh’s own data sources. - Set up the build / zip pipeline early, mirror Node’s
make-ziphygiene (exclude markdown, dotfiles,plans/,CHANGELOG.mdper Plugin Check).
Risks & open questions#
- WP-Cron reliability: the same problem Node has; low-traffic sites stall crawls. Mitigation: a detect-and-warn admin notice with a “Force tick” button; Action Scheduler is a Phase 6 candidate.
- Performance at 1,000 pages: ~17 min per crawl at 1 req / sec; acceptable as background work, the UI must communicate it.
- Sitemap quality: some sites have broken or no sitemaps; v1 fails gracefully with a paste-the-URL message; v2 is an HTML-crawl fallback.
- Cloudflare success rate: the realistic-UA path slips through ~70–80% of free-tier configs; paid WAF / Turnstile / “I’m Under Attack” is not solvable from PHP, the clear-error path is honest graceful degradation, not a pretended bypass.
- GDPR / data-controller exposure: specified in plan §16; the tool-provider model (the WP site owner is the controller) is the framing;
custom_headersis encrypted at rest, an exporter / eraser is wired, retention defaults to 90 days, and a first-use disclaimer names the controller role before any crawl can start. - No shared services: ~430 lines of fresh PageRank / Levels / GraphBuilder that must be correct first time; mitigation: lift the proven Node algorithms as a starting point and de-WP-couple.
- Keeping the plugin focused: the non-goals are load-bearing; a single-purpose tool that does structural comparison well beats a half-baked SEO suite. The biggest standing risk is simply that the project stays parked, the skeleton + plan + brief keep the re-entry cost low precisely for that reason.
The plans corpus#
The plans/ folder is excluded from the build zip
, these documents never reach end users, but it is
the strategic working surface. This page mirrors its shape; the
folder itself is not relocated. At Phase 0 the corpus is
deliberately small, two canonical specs:
GILLISH-MESH-PLAN.md: how to build it: 21 sections covering the why-standalone reasoning, the architecture and the fresh-write services, the two-table schema, the crawl-pipeline state machine, the Cloudflare strategy, link extraction, the Better Together bridge, privacy / GDPR, the phased rollout, and the re-entry checklist.PRODUCT-BRIEF.md: what / who / why / pricing / distribution / metrics: the strategic counterpart, with the OPEN questions consolidated in §16. Surfaced on the Product brief page.
When Phase 1 starts, the corpus grows the Node way, active
plans in plans/, a DONE-WORK.md the
finished plans summarise into, holding tanks for deferred /
polish ideas, but that structure is intentionally not
pre-built while parked.
Ecosystem position#
Mesh is one tool in the Gillish network (Core · Node
· Cairnstone · Feed · Mesh). It stands fully on
its own and gets better together with Gillish
Node: when both are installed, the
Your site tab auto-loads from Node’s
gn_graph_data_cache transient instead of requiring a
redundant self-crawl, saving the user ~15 minutes and
making the comparison internally consistent with the graph they
already see in Node. Cross-navigation buttons and a shared
dark-mode default round it out. The boundary is deliberate and
one-way: no data-write into Node, no shared option keys, no
Node-side hooks invoked, a small Node-side change (a
Content-Graph card, a bento card) is its own Node-roadmap item
for when Mesh actually ships. Ecosystem-spanning infrastructure
(this docs network, global memory) is owned by
Gillish Core, not lodged in whichever plugin created it
first.