Why this is written down#
Gillish is a one-person studio that builds WordPress plugins with an AI coding agent. The risk of that setup is not speed; it is drift. An agent that improvises a different process every session produces inconsistent work, and a solo maintainer cannot catch every inconsistency by hand. The defence is a written process that every session loads and follows, so the work stays coherent across sessions and across tools.
This page describes that process so a collaborator, a reviewer, a future maintainer, or the agent itself, opening a fresh session on a future plugin, can see exactly how a feature moves from idea to shipped code, and can push back on any step. Nothing here is secret. Credentials, keys, and deploy mechanics that depend on secrets are deliberately excluded; this is about the method, not the machinery.
The method is shared across every Gillish plugin. Per-plugin CLAUDE.md files extend or refine it; this page is the abstract bar that every plugin's instructions inherit. When a plugin file and this page disagree, the plugin file wins for that plugin and a note explains why.
1: The coding doctrine#
Every project inherits four principles. They exist because LLM-driven coding has known failure modes, and each principle names one of them and the discipline that prevents it. The principles are loaded automatically from the agent's user-global CLAUDE.md, and surface as an explicit skill the agent can invoke (andrej-karpathy-skills:karpathy-guidelines) whenever the doctrine itself needs to be re-asserted.
| Principle | What it forces |
|---|---|
| Think before coding | State assumptions and name ambiguity before the first edit. Restate the task in one sentence. Sketch the approach in two or three lines for any non-trivial change. Confusion that gets hidden becomes a bug; confusion that gets named becomes a decision. |
| Simplicity first | Write the minimum code that solves the stated problem. No speculative features, no premature abstraction, no "while I'm here" refactors. No new helper, class, or interface unless the current change uses it at least twice or removes more code than it adds. Security, validation, and capability checks are never speculative and stay on by default, the "no defensive code" rule applies to product behaviour, never to the security boundary. |
| Surgical changes | Every edit traces to the request. Match the file's existing style, naming, error-handling shape, and import order. No reformatting unrelated lines, no opportunistic refactors riding along. When a refactor is needed to land a feature, do the refactor as its own logical step (ideally its own commit) before the feature lands on top. |
| Goal-driven execution | Define what done looks like as something that can be verified, a test that passes, a screen that shows the right state, a log line that appears, a metric that hits a number. Loop until the check passes, then stop. Diagnose root causes; never suppress symptoms. Bound diagnosis to two failed hypotheses before surfacing the puzzle. |
The doctrine is the abstract bar. Each project's own CLAUDE.md defines the concrete checks and the concrete edits not to make, and the project file wins where the two overlap. The doctrine does not get re-litigated per task; it is the floor.
2: The skills layer#
On top of the doctrine sit skills: named, loadable procedures the agent runs explicitly rather than improvising. Each is invoked by name (/<skill> or via the agent's Skill tool); each carries its own loading instructions, refuses to proceed without required context, and has a defined output. The rule is structural: if a task has a skill, the skill runs; the agent does not freestyle the equivalent.
2.1 impeccable: design & UX#
The central skill for production-grade interface work. Every UI task, from a new block to a new inspector panel to a docs page on this site, is invoked as one of impeccable's commands, never as a freeform "go design something". Before any command touches a file, the skill loads the project's product brief and design context and refuses to proceed without it. It then classifies the surface as either a brand register (the design is the product, like this docs site) or a product register (the design serves a task, like a plugin's inspector panel), and applies a different bar to each.
The commands fall into four families:
| Family | Commands | What they do |
|---|---|---|
| Build | shape, craft, teach, document | Plan UX before code (shape), shape then build end-to-end (craft), set up the design context (teach, document). |
| Evaluate | critique, audit | Heuristic UX review (critique), measurable a11y / performance / responsive / anti-pattern checks scored P0–P3 (audit). |
| Refine | polish, harden, distill, bolder, quieter, onboard | Final pass (polish), errors / i18n / edge cases (harden), tighten copy and structure (distill), volume controls (bolder, quieter), first-run states (onboard). |
| Enhance & fix | animate, colorize, typeset, layout, clarify, adapt, optimize | Targeted improvements when a defect maps to a specific dimension. |
The shared design laws apply to both registers: a committed colour strategy; light or dark chosen from a concrete usage scene rather than by reflex; restrained accent; and a list of absolute bans (gradient text, decorative glassmorphism, side-stripe borders, the hero-metric template, identical card grids, modal-as-first-thought). A critique or audit pass fails any surface that breaks a ban.
2.2 mobbin-ui-research#
Any net-new visual surface, a new block, a new inspector panel, an admin page, an empty or error state, a docs page that introduces a new layout, runs a mobbin-ui-research session before the design brief is written. It is a required step, not a suggestion: impeccable shape blocks on the research note's existence for surfaces that need one.
The skill drives the Mobbin MCP server (mcp__mobbin__search_screens) to translate the design goal into concrete screen descriptions, pull real product screenshots, and synthesise what mature tools actually do for the same problem. The output is a research note in the decision vault citing each screen used. Polish passes and copy-only changes skip it.
2.3 The WordPress skill family#
WordPress-specific work routes through a family of skills, each scoped to one part of the platform. The router skill wordpress-router classifies the repository on session entry (plugin, theme, block theme, WP-core checkout, Gutenberg) and routes to the right narrower skill.
| Skill | When it runs |
|---|---|
wp-project-triage | Deterministic inspection of a WP repo, tooling, tests, version hints, into a structured report that guides workflows and guardrails. Runs once when a new session opens on an unfamiliar repo. |
wp-plugin-development | Plugin architecture and hooks, activation/deactivation/uninstall, admin UI and Settings API, data storage, cron/tasks, security (nonces / capabilities / sanitization / escaping), and release packaging. The default skill for plugin-level work. |
wp-block-development | Gutenberg block work: block.json metadata, register_block_type, attributes/serialization, supports, dynamic rendering (render.php / render_callback), deprecations/migrations, viewScript vs viewScriptModule, @wordpress/scripts build and test workflows. |
wp-block-themes | theme.json (global settings/styles), templates and template parts, patterns, style variations, Site Editor troubleshooting. |
wp-rest-api | Building / extending / debugging REST endpoints, register_rest_route, controller classes, schema and argument validation, permission_callback, response shaping, register_rest_field, exposing CPTs via show_in_rest. |
wp-abilities-api | The WordPress Abilities API specifically, wp_register_ability, wp_register_ability_category, /wp-json/wp-abilities/v1/*, @wordpress/abilities. The skill that runs whenever Cairnstone Phase 13's cairnstone/* abilities or MCP transport work is on the table. |
wp-interactivity-api | Interactivity API features, data-wp-* directives, @wordpress/interactivity store/state/actions, viewScriptModule integration, wp_interactivity_*(), hydration debugging. |
wp-performance | Backend performance work: profiling and measurement (WP-CLI profile/doctor, Server-Timing, Query Monitor via REST headers), DB/query optimization, autoloaded options, object caching, cron, HTTP API calls. |
wp-phpstan | PHPStan static analysis in WordPress projects: phpstan.neon setup, baselines, WordPress-specific typing, handling third-party plugin classes. Owns the level-9 / zero-error gate. |
wp-playground | WordPress Playground workflows, fast disposable WP instances in the browser or locally via @wp-playground/cli, blueprints, version switching, Xdebug. Used for verifying floor-version compatibility without a live test site. |
blueprint | Authoring Playground blueprint JSON files specifically; runs when a new disposable WP scenario needs to be reproducible. |
wp-wpcli-and-ops | WP-CLI operations: safe search-replace, db export/import, plugin/theme/user/content management, cron, cache flushing, multisite, scripting with wp-cli.yml. |
wp-plugin-directory-guidelines | Reviewing plugins against the 18 wp.org Plugin Directory guidelines: GPL compliance, licence headers, upsell/freemium/trialware patterns, plugin naming and trademarks, plugin slugs. Runs before any wp.org submission and whenever a Pro-tier surface is shaped. Its live counterpart, Plugin Check (PCP), the official wp.org review-tool plugin, runs inside WordPress itself on every test env; see §6. |
wpds | The WordPress Design System, components, tokens, patterns. Consulted when a new admin surface needs to align with WP's design language rather than the plugin's own. |
wordpress-penetration-testing | Security assessment for WordPress sites, user/theme/plugin enumeration, vulnerability scanning, WPScan workflows. Runs only against the studio's own test sites, never against any third-party site, and only as part of the CRA Phase 1 baseline or a deliberate audit. |
2.4 Verification skills#
Verification is its own family of skills, kept separate from build skills so the "is this actually done?" gate does not get folded into the work that created it.
| Skill | What it forces |
|---|---|
verify | The agent runs the app, exercises the change in a browser, and confirms behaviour. Used to verify a PR, confirm a fix works, test a change manually, or validate local changes before pushing. A passing test is not proof a feature feels right; verify is the proof. |
run | Launches the project's app to see a change working, first looks for a project-specific launch skill, then falls back to built-in patterns per project type (CLI / server / browser-driven / library). |
code-review | Reviews changed code for reuse, quality, and efficiency, then fixes any issues found. Runs before a non-trivial commit lands, and as the standing skill behind any "second opinion" pass. |
security-review | Complete security review of pending changes on the current branch. Runs before any CRA-relevant work lands and on any change that touches authentication, capability checks, sanitisation, or escaping. |
review | Reviews a pull request specifically, structured against the project's review conventions. |
2.5 Obsidian decision-log skills#
The decision vault (see section 8) is operated through three skills:
| Skill | Role |
|---|---|
obsidian-cli | The interactive surface: read / create / search / manage notes, tasks, properties; run JavaScript inside Obsidian for inspection; capture screenshots; reload plugins. The agent uses it to update the front-cortex index notes, follow backlinks, and verify vault structure without an editor in the loop. |
obsidian-markdown | Authoring Obsidian-Flavored Markdown: wikilinks, embeds, callouts, properties, frontmatter, tags. Runs whenever a decision note is written or refactored. |
obsidian-bases | Working with .base files, database-like views over notes, with filters, formulas, and summaries. Used when the index needs a structured rollup (e.g. all "superseded" notes for a tool). |
2.6 Process & harness skills#
A small set of skills configure how the agent operates rather than what it produces:
anthropic-skills:skill-creator: authoring new skills, modifying or improving existing ones, running evals to test a skill, benchmarking with variance analysis, optimising a skill's description for better triggering accuracy. Runs whenever the method itself is changed.anthropic-skills:consolidate-memory: reflective pass over the agent's memory files: merge duplicates, fix stale facts, prune the index. Runs periodically and after major ecosystem shifts (floor-lift batches, new plugin added, new MCP server adopted).find-skills: the meta-skill for discovering and installing additional skills when a task needs functionality that may already exist as a skill.update-config: configures the agent's harness viasettings.json(hooks, permissions, env vars). Used when a recurring behaviour needs to be automated at the harness layer rather than asked-for per session.fewer-permission-prompts: scans session transcripts for common read-only commands and adds them to the project's permission allowlist. Reduces ceremony without lowering the security bar.loop: recurring task on an interval ("check the deploy every 5 minutes", "keep watching this PR"). Used for poll-until-done patterns and ambient watching.schedule: remote scheduled agents on a cron expression. The escalation fromloopwhen the recurring work should outlive the current session.claude-api: building, debugging, and optimising Claude API / Anthropic SDK applications. Runs whenever a Gillish plugin gains an Anthropic-SDK code path (e.g. MCP's eventual server-side ability hooks).defuddle: extract clean markdown from web pages, removing clutter. The agent uses this in place of rawWebFetchfor any non-.mdURL when researching docs, articles, or vendor pages.keybindings-help: a minor harness utility used when the operator's keyboard shortcuts need to be configured.coding-guidelines: the Karpathy-derived behavioural rules (state assumptions, surgical changes, minimum diff, root-cause-not-symptom) that turn the §1 doctrine from a stated bar into an in-line constraint on every edit. Active on every coding turn; shipped upstream asandrej-karpathy-skills:karpathy-guidelines.gh-address-comments: addresses review and issue comments on the current branch's open PR via theghCLI. Runs after acode-reviewpass produces actionable feedback, or when the operator asks for PR comments to be handled.brightdata-plugin:bright-data-mcp: the skill-side driver for the Bright Data MCP server listed in §3. Runs whenever public web data needs to enter the workflow (competitorwp.orglistings, search-result extraction, structured scraping). Manages query shaping, result parsing, and the MCP connection lifecycle so raw server calls don't surface in the agent's working context.
2.7 Docs-site & SEO skills#
The html.gillish.com docs site is its own repo with its own skill family. The studio's posture is that docs pages are working artefacts, not marketing pages, but SEO and content discipline still apply to them.
searchfit-seo:seo-audit: comprehensive audit of the docs site or a single page (titles, meta, headings, structured data, internal linking).searchfit-seo:on-page-seo,technical-seo,schema-markup,internal-linking,broken-links: narrower passes; the agent reaches for the right one based on the audit finding.searchfit-seo:content-strategy,content-brief,keyword-clustering,create-topic,create-content: when a new docs page or section is being planned, not just iterated.searchfit-seo:ai-visibility: AI-Overview / AI-answer optimisation: how a page is read by search-grade LLMs (Google AI Overviews, Perplexity, ChatGPT browsing), what gets quoted, what gets attributed. Runs alongside the SEO audit when a page's audience includes "an AI agent summarising the studio for someone else", increasingly the path users find docs pages by.marketing:brand-review: brand-voice / style-guide review of a draft. Used as the final pass on any new top-level docs page (this one included).marketing:draft-content,content-creation: when an SEO-shaped draft is the desired output rather than a single edit.
Anthropic's file-format skills, anthropic-skills:pdf, docx, pptx, xlsx, sit alongside but are invoked only when a non-HTML artefact (a CRA-compliance brief in .docx, a SBOM viewer in .xlsx) is the deliverable.
2.8 Design-prototyping skills#
The design loop pulls five skills, split between pre-shape research (finding the right direction before the brief locks) and in-craft iteration (tightening the chosen direction once code is moving). The two pre-shape skills sit alongside impeccable shape:
mobbin-ui-research: covered in §2.2; the "what do mature products do for this problem" surface, mandatory before any net-new visual surface earns its shape brief.anthropic-skills:web-artifacts-builder: rapid in-chat prototyping using React + Tailwind + shadcn/ui. The "what would our concept actually look like" surface. Materialises two or three layout-direction candidates as live HTML artifacts the operator can review before the brief locks. Not a production-code tool, Cairnstone's blocks live in@wordpress/element(WP's React), not shadcn. Artifacts are ephemeral chat scaffolds for direction-finding, never shipped code.
Typical sequence in a heavy-path entry: load context → mobbin-ui-research (understand the convention) → web-artifacts-builder (explore concrete candidates) → impeccable shape (lock the chosen direction in a brief). The middle step is optional but cheap; one artifact session saves a round of shape-brief revision when the chosen direction is contested.
The three in-craft iteration skills come into play after the brief locks, when the question shifts from "what is the right pattern" to "is this rendering the way the brief said it should":
chrome-devtools: DOM inspection, console-log capture, network-request timing, and performance profiling against a running page. Sits alongside Chrome MCP in the iterative craft loop: Chrome MCP drives the surface check,chrome-devtoolsopens the inspector underneath when the check finds something to debug.playwright-skill: scripted browser flows in real Chromium / WebKit / Firefox. Used when a one-shot verification needs to become a repeatable artifact, e.g. when the same regression keeps surfacing across light/dark mode or across the three local Studio sites and the check earns its place as a recorded script. Not the default; reach for it when Chrome MCP one-shots are no longer enough.web-quality-audit: multi-axis audit (accessibility + performance + best-practices) of a live page or component. Sits betweenimpeccable audit(design quality) and §2.10'saccessibility(WCAG methodology): broader than the pure-WCAG manual review, narrower thancomposer verify:deep. Runs as a craft-loop fast-feedback pass before any heavy-path UI surface is declared shippable.
2.9 Performance measurement#
Four skills cover the perf surface, split between live-environment measurement (the "is this slow, and from where" question) and frontend-quality auditing (the "what should we optimise" question). None of them sit on the push-gate critical path, perf work is operator-invoked, not per-push gated.
global-speed-checker: runs HTTP timing checks against any endpoint from multiple regions worldwide. Used to baseline a published frontend before launch, to debug a "Cairnstone feels slow" report by isolating which region degraded, and to capture Phase-N before/after measurements when a heavy-path change affects rendering. Too slow and too sensitive to network flake to sit on the push-gate critical path; reserved for pre-launch baselines, post-major-change audits, and ad-hoc debug. CRA Annex I row (2)(h) "Availability + DoS mitigation" becomes load-bearing the moment Cairnstone hits the wp.org launch; global perf measurement is the evidence trail.perf-lighthouse: full Lighthouse audit (performance + best-practices + SEO + a11y subscore) against a URL. Runs as a one-shot quality bar before a top-level docs page or a Cairnstone admin surface is declared done, and on demand when a regression report needs a structured second opinion. Complementary to §2.10'saccessibilityskill (Lighthouse catches the automatable a11y axis; theaccessibilityskill grounds the manual review).core-web-vitals: the three Google-tracked metrics specifically: Largest Contentful Paint, Interaction to Next Paint, Cumulative Layout Shift. Narrow scope: when a docs page or Cairnstone surface has a known CWV regression and the work is to land the specific fix (image preloading, hydration deferral, layout stabilisation). The skill that runs when the question is "the CWV number is bad, what specifically to change".perf-web-optimization: broader web-perf guidance: bundle size, image strategy, caching headers, render-blocking resources, JS execution cost. Sits one level out fromcore-web-vitals; runs when a surface needs a perf pass that isn't yet narrowed to a single failing metric.
2.10 Accessibility audit#
One skill provides WCAG-grounded patterns and review methodology for accessibility work, invoked alongside impeccable audit when a heavy-path UI surface needs a11y verification, and as a standing pattern reference during craft on any user-facing component.
accessibility(fromaddyosmani/web-quality-skills, installed 2026-05-22), provides the WCAG POUR framework (Perceivable / Operable / Understandable / Robust), conformance levels (A / AA / AAA), and pattern catalogue for text alternatives, ARIA roles, keyboard navigation, focus management, colour contrast, and the screen-reader / assistive-tech expectations every Cairnstone / Node / Core admin surface must meet. What it IS: methodology + pattern reference loaded into agent context during a11y work. What it is NOT: an automated DOM scanner, it does not invoke axe-core / pa11y / lighthouse-a11y; it grounds the manual review the agent performs.
Scope note, WCAG 2.1 vs 2.2. The skill targets WCAG 2.1 AA. The studio's declared bar in §13 + the per-tool security pages is WCAG 2.2 AA. Of the nine criteria 2.2 added on top of 2.1, three are catchable by axe-core's modern ruleset (Target Size 2.5.8, Focus Appearance 2.4.13, Focus Not Obscured Minimum 2.4.11) when an axe-based automation is wired in. The remaining six (Focus Not Obscured Enhanced, Dragging Movements, Consistent Help, Redundant Entry, Accessible Authentication Min/Enh) require manual checklist review during impeccable audit. The accessibility skill grounds that manual review; it does not by itself certify 2.2 AA.
Still an open gap: automated a11y scanning. No skill in the current stack invokes axe-core, pa11y, or lighthouse-a11y against a live URL or DOM snapshot. The accessibility skill closes the methodology gap; the automation gap remains as a future Layer-6 candidate in the verification stack, most likely deferred until Cairnstone has a stable launch-ready admin surface to baseline against.
3: The MCP-server inventory#
The agent's verification and introspection power comes from a fixed inventory of MCP servers (Model Context Protocol). Each server is named, each has a defined role, and the agent picks based on what the task actually needs, not by reflex.
| Server | Layer | What it does | When to reach for it |
|---|---|---|---|
| Chrome MCP | DOM | DOM-aware browser automation in a real Chromium instance (navigate, click, fill, screenshot, read console, read network). | Default for any web-app UI verification, admin pages, the Gutenberg editor, this docs site. Much faster than clicking pixels. |
| Mobbin MCP | Research | Search Mobbin's UI database for screen patterns from mature products. | Required by mobbin-ui-research for any net-new visual surface. |
| Computer-use MCP | Desktop | Screenshot the user's desktop and control it with mouse/keyboard/scroll. Tiered by app category, browsers get "read" tier, IDEs get "click" tier, native apps get "full" tier. | Only when the work is a native desktop app (Obsidian's electron app, Finder, system settings) and no dedicated MCP fits. Never for web UIs, Chrome MCP is faster and more precise. |
| Claude Preview MCP | Local preview | An in-Claude preview panel that renders a local site without leaving the conversation. | Quick visual check of a single edit before committing, especially on this docs site, where Chrome MCP's full DOM round-trip is overkill. |
| Bright Data MCP | Web data | Headless web scraping, search, structured data extraction. | Only when public web data needs to enter the workflow, e.g. researching a competitor plugin's wp.org listing. Driven by the brightdata-plugin:* skill family (13 skills total, bright-data-mcp, scrape, search, scraper-builder, scraper-studio, data-feeds, brd-browser-debug, competitive-intel, brightdata-cli, agent-onboarding, seo-audit, bright-data-best-practices, python-sdk-best-practices); primary driver entry at §2.6. |
wp.org MCP (Automattic's mcp-wordpress-remote) | Directory | WordPress.org Plugin Directory introspection, validate readme.txt formatting, check Stable tag, verify Plugin Directory guideline compliance, monitor the review queue. | Pre-submission and pre-update checks against the wp.org directory. Installed locally; pre-launch today, primary use when Cairnstone / Node near their first submission. |
Picking the right tier matters. Each MCP server trades coverage against speed and precision. The fixed rule: start at the most specific tool that can answer the question. A dedicated app MCP beats Chrome MCP, which beats Computer-use MCP. A wrong-tier choice usually means the agent is about to click pixels at something Chrome MCP could read from the DOM.
The fallback ladder when a server is down. The verify skill primarily drives Chrome MCP for any web-UI surface check. If Chrome MCP is unavailable mid-session, the fallback ladder is:
- For server-side state verification (option values, plugin active state, ability registration, post-meta, transients): use WP-CLI via the
wp-wpcli-and-opsskill, a direct database read, or a focused Chrome MCP admin-page probe against the target Studio site. These give server-side ground truth without a remote adapter. - For desktop / native-app surfaces (Obsidian, Finder, system settings): use Computer-use MCP at the appropriate tier (browsers get the
readtier; IDEs getclick; native apps getfull). Not relevant for plugin verification; only for operator-environment work. - If no MCP path reaches the surface in question: surface the gap explicitly in chat and stop. A failed verify is reportable; it is never optional and never silently skipped. The Karpathy "Goal-Driven Execution" principle in §1 names this, diagnose, do not suppress.
What this is NOT: the fallback ladder is not a degraded-mode default. Chrome MCP is the right tool for web-UI verification; the ladder is for actual outage handling, not for opportunistically skipping browser checks.
3.5: The three speeds: fast / feature / heavy#
Not every task earns the full ceremony. A gearbox at the top of every session selects between three speeds, sized to the scope of what is actually being changed. The gearbox is enforced structurally: before any code or file edit, the agent outputs an initialisation block declaring the mode, the task in one sentence, the target files, the explicit "done means" criterion, and a one-line justification for the chosen speed.
| Speed | For | Verification | Decision log |
|---|---|---|---|
fast-path | Localised bug fixes, settings adjustments, sanitisation/escaping updates, single hook tweaks, capability or nonce checks, typos, one-file refactors touching ≤ 20 lines. | php -l on every edited PHP file + a target quick-check. No full toolchain run. | Skipped. |
feature-path | Normal multi-file feature implementations, custom REST API endpoints, specialised controller classes, cron/data flows, moderate UI additions inside existing plugin patterns, schema additions to existing tables. | composer verify:deep = composer test && composer stan. Lint stays advisory. | Skipped unless the change matches one of the four triggers in §8. |
heavy-path | Net-new Gutenberg block definitions or families, core structural overhauls, floor-lift adjustments, wp.org submission sweeps, new pluggable engines, cross-plugin ecosystem behaviour changes. | composer verify:deep + surface QA on a local Studio site (Chrome MCP for admin UI; WP-CLI or a direct DB read for server-side state). | Required. |
The pipeline described in §4 (the shape → craft → audit → polish sequence) and the phase-based pattern in §5 are heavy-path territory. feature-path uses a 3-line implementation plan and skips Mobbin research and shape briefs. fast-path skips both the plan and the pipeline, execution is the verification.
The Obsidian decision log in §8 inherits the same gating: a note is required only when a change crosses one of four explicit thresholds (schema lock-in, new pluggable engine, cross-plugin behaviour change, platform floor lift). For routine helpers and standard settings fields, the vault stays clean.
Every turn, no exceptions. The initialisation block is not optional, not "for big changes only", not skippable when the next edit feels obvious. Every turn that touches code or files starts with the Mode Selection Grid, if a turn does not need an edit, the grid is skipped; the moment an edit is on the table, the grid precedes it. The discipline exists because the dominant failure mode of agent-driven coding is the agent that "just" makes a small edit and snowballs from there without ever declaring what "done" looks like. The grid is the structural answer.
Session-start acknowledgement. On the first turn of a new session, the agent acknowledges the loaded method by listing the current platform minimums (WordPress and PHP, see §3.6) and standing by for the first task. From that point on, every turn that touches code or files starts with the Mode Selection Grid. This is the one mandated agent output that is not a Mode Grid, everything after it on a coding turn is.
Per-plugin CLAUDE.md loader directives sit at the top of each plugin's manifest file and point at this method page as the read-first source on session entry. Per-plugin manifests carry deviations from this baseline; this page is the abstract bar every plugin's manifest inherits.
3.6: The runtime baseline & security boundary#
Every Gillish plugin codes for a modern runtime baseline: WordPress 6.9+ and PHP 8.3+. Tested up to WordPress 7.0 / PHP 8.5 on the bleeding Studio site. The floor is part of the plugin's declared interface; a floor-lift is treated under the discipline in §9.
- Input sanitisation + validation are mandatory at every entry point. Output escaping (
esc_html,esc_attr,esc_url,wp_json_encode,wp_kses_post) happens at the exact render boundary, not earlier. - Privilege checking. All administrative entry points, AJAX callbacks, and REST routes explicitly enforce capability checks (
current_user_can( 'manage_options' )or the appropriate granular capability) and verify nonces (wp_verify_nonce/check_ajax_referer/permission_callback). Never weaken a security boundary to make a quick test pass. - PHP 8.3 optimisation. Use Typed Class Constants (
public const string SLUG = '...'), explicit type hints on every parameter and return,declare( strict_types=1 );at the top of every PHP file insrc/, strict comparison operators (===/!==), andjson_validate()when validating JSON strings beforejson_decode. - No
.env, no hardcoded secrets. Configuration lives inwp-config.phpconstants, WP options, or each plugin's typedShared\Optionsconstants. No credential, key, or token in any tracked file. - No server-level config from plugin code. Strict CSP, TLS headers, HSTS belong to the host/server layer, not the plugin. A plugin that emits them breaks core and Gutenberg.
- WordPress owns the password store. Never override or mirror
wp_hash_password/ phpass / bcrypt.
Compliance with the broader GDPR / CCPA / CRA / OWASP / WCAG 2.2 AA posture is handled as guardrails, see §13. The rules above are the per-edit security floor; the guardrails are the program-level commitments.
3.7: Session length & context discipline#
The 1M-token context window does not mean unlimited useful context. Retrieval degrades the more unrelated content sits in working memory, "lost in the middle" is a real failure mode even at high token counts. Three rules keep this in check:
- The
Files:list in the init block is normative. Files outside it are not read this turn unless the agent surfaces an explicit need and updates the init block in the next turn. No speculative tree-walking just because the window has room. - Checkpoint at ~250–300k tokens, then
/clear. Long heavy-path sessions that pass that threshold land a checkpoint to.claude/active-state.mdin the working plugin repo before clearing, what's done, what's next, where the reasoning is paused, the exact slash-command to invoke on resume. The cross-session surfaces (vault00 <Tool> Index.mdCurrent state dashboard,Z:\Dev\Obsidian\<Plugin>\Plans\DONE-WORK.md, the agent's auto-memory) already handle long-term continuity; the active-state file handles only in-flight task continuity during a single multi-day work thread. - Delegate deep exploration to read-only subagents. When
heavy-pathneeds to scan multiple plugin repos, audit a 1000+ line module, or do a cross-vault grep before committing to a shape, use theExploreorgeneral-purposeAgent tool. The subagent reads broadly, writes a focused markdown report to disk (Z:\Dev\Obsidian\<Plugin>\Plans\<topic>-research.mdfor plan-adjacent work,Z:\Dev\Obsidian\<Tool>\Research\for strategic reasoning that should land in the Obsidian vault), and the main agent reads back in. Preserves the main agent's context budget for synthesis and edits. Plan-only subagents (thePlanagent type) are the same pattern for design-decision exploration.
4: The pipeline, step by step#
This sequence is the heavy-path expansion (see §3.5 for when each speed applies). feature-path uses a 3-line implementation plan in place of Shape, skips Research, and otherwise follows Craft → Evaluate → Verify → Decision log only if §8 triggers. fast-path skips the pipeline entirely, execution is the verification.
A heavy-path feature moves through the same sequence every time. Each step has an output the next step depends on, and a named skill that owns it.
| Step | Skill / tool | Output |
|---|---|---|
| Context | Per-plugin CLAUDE.md + product brief + foundation plan auto-load on session start; missing context blocks the work. | A shared picture of users, brand, constraints, current state. |
| Triage | wp-project-triage (first session on a repo) or wordpress-router (every session) classifies the repo and routes. | The right WP skill family loaded; tooling state known. |
| Research | mobbin-ui-research for any net-new visual surface; defuddle for reading vendor docs; WebSearch for general questions. | A research note in the decision vault citing screens / sources. |
| Shape | impeccable shape produces a design brief: problem, register, approach, references, acceptance criteria. Work stops here for human review. | A confirmed brief, or a correction. |
| Craft | impeccable craft + the WP skill that fits (wp-block-development, wp-abilities-api, …) builds in deliberate passes: structure, then visual system, then states, then motion, then responsive. Real content, no placeholder scaffold. | Working code, committed in reviewable units. |
| Evaluate | Explicit impeccable audit and impeccable critique passes find defects and score them P0 (blocking) through P3 (polish). | A prioritised defect list. |
| Refine | Each defect is mapped to the right command, harden for a11y and i18n, layout for spacing, polish for the final pass, and fixed in its own commit. | Defects closed, re-verified. |
| Verify | verify exercises the change in a browser via Chrome MCP, against the brief and the bans. Server-side claims are checked via WP-CLI (wp-wpcli-and-ops), a direct DB read, or a Chrome MCP admin-page probe. Static gates run (composer test, composer stan). | Honest proof it works, or a found defect that re-opens Refine. |
| Decision log | obsidian-markdown writes a dated decision note in the right vault when the change crosses the "future session needs to know why" threshold. | A note linked from the vault index. |
| Ship | Version bump in the same commit as the change (header Version:, readme.txt Stable tag, == Changelog ==). Push to main as the canonical backup; the next mirror refresh is what the local Studio sites pick up. | Live on the local matrix; production manual. |
Steps are not compressed. Shape confirmation is not a licence to skip straight to building; it is permission to begin the next gate. The dominant failure mode of this kind of pipeline is collapsing the gates because an earlier one felt complete, so the gates are kept distinct on purpose.
The work is built in passes and committed in small, reviewable units, each with its own focused message and its verification result recorded in the commit. A reviewer can follow the history one decision at a time rather than reading one large diff.
5: The phase-based feature pattern#
Heavy-path only. Large features, a new block family, a new Inspector panel, a new abilities surface, are run as numbered phases. Cairnstone is the most-exercised example: Phase 9 (Block Bindings + library manifests), Phase 10 (Schema panel), Phase 11 (binding shape stabilisation), Phase 13 (MCP cairnstone/* abilities), and so on, each with its own shape brief, its own craft passes, its own audit, and a clear "shipped at N/N" closure.
A phase has three artefacts:
- A shape brief, written first via
impeccable shapeand saved toZ:\Dev\Obsidian\<Plugin>\Plans\(Drive-backed, in the reasoning vault, outside the repo). The brief locks the scope; expanding it mid-phase requires a new shape pass. - A craft sequence, run via
impeccable craft, committed in small units with versioned messages (v2.2.135,v2.2.136, …). Each craft commit records its verification result. - A closure entry in the per-plugin
Z:\Dev\Obsidian\<Plugin>\Plans\DONE-WORK.mdwhen the phase ships at N/N. The shape brief is then deleted; the closure entry is the durable record. The decision vault keeps the strategic record separately (see section 8).
The phase number is part of the commit messages and the changelog entries. A reviewer can ask "what shipped in Phase 9?" and find the answer in Z:\Dev\Obsidian\<Plugin>\Plans\DONE-WORK.md, the corresponding git history, and the per-plugin foundation roadmap published on this docs site.
6: The verification gate#
Nothing is called done on assertion. Done is a check that can be run. For a plugin change the checks are concrete:
| Gate | Command | Bar |
|---|---|---|
| Unit tests | composer test | The unit suite is green. It includes source scanners that fail when a structural-discipline rule is broken (e.g. an add_action outside Plugin::register_hooks()), so a regression is caught by the suite rather than in live review. |
| Static analysis | composer stan | PHPStan at level 9, zero errors. New errors are regressions, not new debt. Compliance is verified surgically, never a tree-wide automated rewrite. |
| Lint | composer lint (advisory) | WordPress-Extra phpcs ruleset. Intentional ecosystem deviations (PSR-4 filenames, signature-match unused params, inline-SVG base64_encode) are documented; new violations on touched files are not. composer fix runs only on files actually edited. |
| Syntax | The agent runs each edited script through PHP's syntax check before committing. | Every edited script parses. |
| Surface check | verify + Chrome MCP (web) or WP-CLI / DB read (server) | The change is exercised on the canonical surface, not a substitute. A screenshot that was not actually looked at does not count. A passing test is not proof a feature feels right. |
| Cross-env | The plugin source is junction-mounted into all three local Studio sites simultaneously; refreshing any of them exercises the floor / stable / bleeding slot. | The declared floor (WordPress 6.9 / PHP 8.3) is continuously available, not just declared. |
| Theme-context render | Any change with a visible result, backend (CPT-editor or post/vanilla editor) or frontend (rendered page), is looked at on a dedicated dark-theme Studio site (csdevdark), not only the default surface or the editor canvas. | The editor canvas and a default light theme hide theme-dependent breakage: a block's own CSS losing to a theme's resets, a colour that only fails on dark, spacing a block theme supplies that a classic theme does not. Rendered or editor-affecting work is not done until it has been read on the dark theme. |
| Dependency CVE scan | composer audit (pre-push gate) | Before every git push origin main on Core / Cairnstone / Node, the agent runs composer audit --format=plain against the resolved lockfile. An open Packagist advisory holds the push until resolved or explicitly waived. Replaces the retired GitHub-Actions audit gate (workflow removed 2026-05-24); same zero-tolerance threshold, in-session instead of on a runner. Feed and Mesh join when their toolchains stand up. |
Plugins are exercised across a small matrix of three local Studio installations on the operator's workstation (see the ecosystem brief): floor (WordPress 6.9.4 / PHP 8.3), stable (WordPress latest stable / PHP 8.4), and bleeding (WordPress 7.1 / PHP 8.5). The plugin source on the workstation is junction-mounted into all three sites' wp-content/plugins/, so a single edit exercises every slot. Production is different: it is never in any automated path. Production sites are updated only by a person uploading a build by hand. The deliberate gap between local matrix and manual production is the single hard rule that protects the live site.
A second matrix, the theme-context matrix, sits alongside the version matrix above, aimed at rendering-across-themes rather than WordPress-version compatibility, and tested in ISOLATION. Where the three sites above run every plugin active together, each of these four activates only the ONE plugin under test, so a cross-plugin interaction can never corrupt a rendering result. The four differ by active theme: a default theme (csdev), a dark theme (csdevdark), a classic no-block theme (devclassic, Twenty Sixteen), and a full-site-editing block theme (devfse, Ollie); today only Cairnstone is set up on them. Any change that produces a visible result is confirmed on the dark site at minimum, because dark is where a block's own CSS most often loses silently to the theme; the classic and FSE sites catch the two other rendering extremes. This is the human complement to the automated hostile-theme run in the shared viewport-check harness (an aggressive unlayered theme reset injected at boot): the harness proves the geometry survives a hostile theme, the dark site is where a person confirms it actually reads right.
Infrastructure-level safety hooks sit one layer below the per-task gates above. The agent's user-global Claude Code harness carries four hooks: three PreToolUse hooks block specific dangerous operations before they execute (raw rm -rf, edits to wp-config.php, creation of any .env file), and one PostToolUse hook auto-runs php -l on every edited PHP file. These fire on the tool call itself, regardless of agent intent, the soft rules in the harness describe the boundary; the hooks enforce it. Workarounds exist for legitimate cases (rm -r without -f for clean temp dirs; git rm -rf for recoverable git operations; manual edits to wp-config.php in the operating system).
A complementary headless smoke-test path ships with Cairnstone / Core / Node via @wp-playground/cli: a Vitest harness that spins up a disposable WordPress 6.9 / PHP 8.3 instance in WebAssembly, mounts the plugin tree, and asserts activation succeeds without fatal. Faster than driving a full Studio site for cheap activation checks; complements the local matrix rather than replacing it.
A live wp.org-compliance check sits on every local Studio site in the form of Plugin Check (PCP), the official Automattic-maintained review-tool plugin. It is reachable at /wp-admin/admin.php?page=plugin-check on each Studio site (8571.wp.local / 8369.wp.local / 84latest.wp.local). The agent invokes it directly, either by driving the admin URL via Chrome MCP (pick plugin, click Run, scrape findings), or by running the equivalent WP-CLI command (wp plugin check <slug>) via the wp-wpcli-and-ops skill. Because Studio's junctions point at the wp.org-clean mirror (not the dev source), the PCP scan sees only production-relevant files, dev-only artefacts (CLAUDE.md, composer.json, phpstan.*, etc.) are filtered out by the mirror before PCP ever sees them, so findings are real findings. PCP runs the same ruleset as the wp.org submission queue (deprecated functions, sanitisation / escaping, file-system writes, enqueue patterns, i18n compliance, late-escaping, header validation), so a clean PCP pass on the floor site is the closest cheap proxy for "would survive submission review". Reach for it pre-submission and after any change that touches a wp.org-relevant surface (a new escape boundary, a new admin enqueue, an i18n string load).
7: The agent's auto-memory layer#
The agent keeps a persistent file-based memory under its own project directory, separate from both the code repository and the Obsidian decision vault. The memory is built up over many sessions so a fresh conversation arrives with a complete picture of the user, the codebase, and the way the work should be approached.
There are four types of memory, each in its own file in the memory directory and indexed from a top-level MEMORY.md:
| Type | What it carries | Example |
|---|---|---|
user | Role, goals, responsibilities, knowledge of the operator. | "Maintainer prefers terse responses; reads diffs directly; commit + push is autonomous." |
feedback | Guidance the user has given on how to approach work, corrections and confirmations. Each carries a Why line (the reason given) and a How to apply line (when the rule kicks in). | "On html.gillish.com, remove resolved/deleted-item narrative entirely, history lives in Obsidian/plans only, public pages are current truth only." |
project | State of ongoing work that is not derivable from code or git: who is doing what, why, by when. Relative dates get converted to absolute dates on save. | "Local Studio site at https://8369.wp.local runs WP 6.9.4 / PHP 8.3 as the floor slot; Cairnstone's Phase 10 (Schema panel) shipped at v2.3.1, Phase 11 (Block Bindings) is the next shape brief." |
reference | Pointers to where information lives in external systems (Linear projects, Grafana dashboards, GitHub repos). | "gh CLI is installed and pre-authed at a known path, call it directly rather than asking the user." |
What the memory does not hold: anything derivable from current repo state (file paths, conventions, architecture), git history facts, debugging fix recipes, or anything documented in CLAUDE.md. Those are read from source on demand. The memory is reserved for what is genuinely cross-session and non-obvious.
The memory is read when the user references prior work, when a request matches a known feedback rule, or when the session is about to take an action that historic feedback addressed. Stale memories are updated or removed rather than acted on, "the memory says X exists" is not the same as "X exists now". The anthropic-skills:consolidate-memory skill runs a reflective pass periodically to merge duplicates, fix drift, and prune the index.
8: The decision log: the Obsidian vault#
Decisions that matter across sessions, an architectural choice, a technical trade-off, a visual direction, a process change, a floor-lift, a distribution call, are written up as dated notes in an Obsidian vault: a linked-markdown knowledge base that lives outside the code repository. The split is deliberate and has a name.
| Layer | Holds | Owned by | Versioned by |
|---|---|---|---|
| Layer 1 | Shippable code + the docs that travel with it, per-project CLAUDE.md, the readme. | Git history | Git |
| Layer 2 | The strategic-thinking record: dated decision notes, the reasoning, the rejected alternatives. Never shipped. | The human (the agent operates here, but cannot overwrite human edits without confirmation) | Dropbox revision history |
The two are kept distinct on purpose so the repository stays focused on what users run and the vault stays free for the why.
There is one vault per tool, Node, Cairnstone, Feed, Mesh, and a Core vault that owns the cross-tool reasoning the per-tool vaults cannot: how the tools compose, this shared docs network, the better-together principle, ecosystem-wide conventions, and the global memory that outlives any single plugin.
Vault shape
Each vault opens with a frontal-cortex index: a 00 <Tool> Index note whose top section is a kept-fresh current-state dashboard, the last shipped commit, the working-tree state, the active threads, the parked items, the next obvious step, and the most recent decisions. It is updated in the same change that triggers it; a stale dashboard is treated as worse than none.
Decision notes follow a fixed shape:
- Frontmatter classifying the area (
architecture,technical,visual,process,distribution) and astatusthat flips tosupersededwith a pointer to the note that replaced it. - Context: what triggered the decision.
- Decision: what was decided, in one paragraph.
- Rationale: the load-bearing reasons.
- Trade-offs: what was given up.
- Implementation: the concrete commits / files / hooks that landed it.
- Implications: what now changes in the working assumption.
- Sources: the cited commits, files, environments, or external links.
Notes link to each other and to the instruction files with explicit-path wikilinks, so Obsidian builds the backlink graph automatically and a reviewer can walk the reasoning, not just read it.
Vault rules
Two rules keep the vault honest:
- Cite the source. Every load-bearing claim in a note traces to a verified commit, file, or live environment before the prose is written, no invented commit hashes, no assumed file paths, no untested "it works".
- The agent does not overwrite the human's thinking. The agent edits its own output freely (the decision notes it wrote, the index it maintains), but user-authored notes and a human's edits to the agent's notes are read first, the diff surfaced, and the change confirmed before anything is overwritten. The vault is the one place the human's reasoning is authoritative over the agent's.
A dated note at Z:\Dev\Obsidian\<Tool>\Decisions\ is required when, and only when, a change crosses one of these four explicit thresholds:
- The architectural approach locks the project into a specific database/schema footprint that is hard to reverse.
- A net-new pluggable engine or extension system is introduced.
- The change directly alters cross-plugin ecosystem behaviours (a structural integration between separate Gillish modules).
- The system platform floor is officially lifted (WP or PHP minimum moves forward).
For routine helpers, standard settings fields, normal controller implementations, and fast-path or feature-path work that does not match the four triggers above, do NOT suggest or write a decision log entry. The vault is the human's strategic record; protect it from clutter.
The summary read: would a future session need to know why this exists and what was rejected? If yes (and a threshold above applies), a note lands. Every new pluggable surface, a new detector, a shared service, a toggleable module, a new library block, earns a note when it lands; a net-new visual surface additionally cites its Mobbin research; a private one-line helper does not. The payoff is that a reviewer can reconstruct not just what was built but why, and can disagree with the why, which is the entire reason it is written down.
9: Version regulation & the floor-lift discipline#
The studio runs continuous local verification: edits in the canonical plugin tree are reflected in all three local Studio sites at once via NTFS junctions. There is no release ceremony to hang a version bump on, so the rule is structural.
Version regulation
- Bump on every meaningful change in the same commit as the change. Feature, behavioural fix, security fix, schema change, floor lift, all bump. Pure docs / comment / test-only edits do not.
- One bump = three places. The plugin header's
Version:line, the constants prefix's version (e.g.GCO_VERSION),readme.txt'sStable tag, and a fresh== Changelog ==entry, all in the same commit. - Major version bumps are reserved. The agent never rolls the major version (the leading number) by itself. Cairnstone's
v3.0.0is held for the wp.org launch; Core's0.x → 1.0is the operator's call alone. An agent that proposes a major bump without explicit instruction has failed the doctrine. - Patch numbers move with floor-lift decisions. When the ecosystem WP or PHP floor lifts, every plugin gets a patch bump even if its own code did not change, the floor is part of the plugin's declared interface.
Floor-lift discipline
The platform floors (WordPress and PHP minimums) only move forward. Each floor lift carries:
- A technical trigger. Either a specific WP or PHP feature unlocks meaningful product work (Cairnstone's binding work needed
block_bindings_supported_attributesfrom WP 6.9), or the current floor blocks a clean implementation (holding PHP 8.2 means hand-rollingjson_validate()), or posture consistency demands it (lifting WP aggressively while holding PHP at an older version is discipline drift). - A dated decision note in the Core vault.
- An ecosystem-wide sweep: every plugin's
Requires at least:/Requires PHP:headers andreadme.txtvalues move together, with a patch bump apiece. - A floor smoke environment at the new minimum, so the declared floor is exercised on every push, not just declared.
- An entry on the public version-support page so site owners can read the policy directly.
10: Distribution mechanics#
The studio retired its remote auto-deploy matrix on 2026-05-23 in favour of a local-first arrangement. The mechanics now live on the operator's workstation; the shape:
- Three local Studio installations cover the floor / stable / bleeding matrix at
https://8571.wp.local(WordPress 7.1 / PHP 8.5; Studio profile8571; bleeding),https://8369.wp.local(WordPress 6.9.4 / PHP 8.3; Studio profile6983; floor), andhttps://84latest.wp.local(WordPress latest stable / PHP 8.4; Studio profile84latest; stable). Studio is Automattic's local-WordPress app; each site runs WordPress in WebAssembly. - Four theme-isolation installs sit alongside those three (
csdev,csdevdark,devclassic,devfse), on the same junction chain but differing by active theme (default / dark / classic / FSE) and run with only the single plugin under test active, for uncontaminated per-theme rendering checks (see §6). - Single canonical plugin tree at
Z:\Dev\Code\<plugin>. Every Studio site'swp-content/plugins/<plugin>entry is an NTFS junction pointing into the production-clean mirror atZ:\Dev\Code backups\<plugin>(not the dev tree directly, see the mirror script below). Editing the source is reflected in all three sites simultaneously after a mirror refresh. - Production-clean view via a mirror script.
Z:\Dev\Code\.tools\mirror.ps1 -Liveruns a robocopy fromCode\<plugin>intoCode backups\<plugin>, stripping two categories: regenerable cache (node_modules,vendor,vendor-runtime,.git,build,dist,logs,.tmp.driveupload) and PCP false-positives (.claude,CLAUDE.md,DESIGN.md,PRODUCT.md,README.md,CHANGELOG.md,phpcs.*,phpstan*,phpunit.xml.dist,.phpunit.result.cache,composer.*,package.*,.gitignore,.gitmodules). The Studio junctions point at this stripped mirror, so PCP and the running WP instance see only production-relevant files. Runs after every substantive code change so Studio's junction sees the new state; also runs as the Google Drive backup refresh. - Production-ship-worthy snapshots.
Z:\Dev\Code\.tools\make-zip.ps1 <plugin>writesZ:\Dev\Code backups\<plugin>.zipwith a 10-file rotation of timestamped historicals. Trigger is ship-worthy changes only, version bumps, behaviour-changing fixes, schema migrations, anything that would be uploaded to a production site. Routine refactors, doc-only edits, and intermediate WIP commits do not trigger a zip; the mirror catches them.Z:\Dev\Code\.tools\audit-gate.ps1runs the combinedcomposer audit+npm run test:a11ygate per plugin (see §6). - Pre-push gates run in-session. Before every
git push origin mainon Core / Cairnstone / Node, the agent runscomposer audit+ the wp-playground accessibility scan. Failures hold the push. Replaces the retired GitHub-Actions audit + a11y workflow. - GitHub repos are backup-only. Pushing to
mainserves only as off-machine code backup; no workflow deploys anywhere from there. - Production is manual zip upload, always. Production sites are never in any automated path. wp.org submission is the same shape: a manual zip uploaded to the Plugin Directory.
The full description and the rationale for each piece live in the ecosystem product brief.
11: How this site is produced#
This documentation network, html.gillish.com, is its own repository, separate from any plugin. Updates are pushed to the live server via a local rsync over SSH, additive-only, invoked by the operator (the previous GitHub-Actions auto-deploy was retired 2026-05-24 alongside the plugin auto-deploy matrix). The plugins do not bundle, deploy, or own the docs site; the docs site does not depend on any plugin.
Per-tool pages are partly hand-authored and partly generated from the plugins' own machine-readable manifests, so a block's description on the site and its behaviour in the code cannot drift apart: change the manifest, regenerate, and both move together. Where pages are hand-authored, the docs-site SEO skill family (searchfit-seo:*, marketing:brand-review) runs as the final pass.
Two rules keep the public docs honest:
- Cite the source. Every load-bearing claim on a public page traces to a verified commit, file, or live environment. Memory-written docs once landed several confident, wrong claims; the rule is now structural.
- Current truth only. Public docs pages carry the current state, never the resolved-internal-history narrative. "Previously had X, now Y, see <internal note>" stays in the Obsidian vault (decision notes and the per-tool
Plans\subfolders), it never appears on a published page. Internal Obsidian filenames are not referenced on public pages.
12: Standing conventions#
A few rules apply to every session regardless of the task.
- One language in the product. Everything shipped, every visible string, label, comment, commit message, is in English. The studio's working conversation can be in Norwegian; the artefact never is. Mixed-language UI signals amateur.
- Build for humans, not developers. Every shipped surface is for site owners and editors, not the developer who built it. Pick a value from a list, do not type a code. Show the human label, store the technical id. Help text answers "what do I type here", with examples.
- Light + dark mode together. Write the light rule first, then the
body.<prefix>-dark-modeoverride immediately below. No one-off shades; reuse the project's palette.html.gillish.comis the named exception, this docs site is light-only by design; Gillish plugins still ship both themes. - Single hook registry per plugin. Every
add_action/add_filterlives in the plugin'sregister_hooks()method, nowhere else. - Sibling detection is one-line. Cross-tool integration uses
class_exists( '\Gillish\<Tool>\Plugin', false ); never a harduse Gillish\…import. - Always offer the next three steps. When a unit of work completes, the session ends with exactly three concrete next options, each with a one-line reason anchored to the state just reached, so the maintainer always has a clean way to redirect.
- Auto-commit, auto-push after meaningful changes. The harness is configured to commit and push without asking; GitHub's revert mechanics make this low-risk and the workflow stays fast. The agent never asks "should I commit?" after a code change, it just commits.
13: Compliance guardrails & the CRA program#
GDPR, CCPA, the EU Cyber Resilience Act, OWASP, and WCAG 2.2 AA are not handled per task; they are permanent guardrails in the doctrine, so the posture cannot drift session to session. The guardrails are deliberately written as what not to do, because in a WordPress plugin the common compliance reflexes are the dangerous ones.
| Guardrail | The rule |
|---|---|
| Compliance layering | Never inject server-level configuration (strict CSP, TLS headers, HSTS) from plugin code, it breaks core and Gutenberg and is the wrong layer. No .env in a WordPress plugin; configuration is wp-config.php, options, or approved constants. WordPress core owns password hashing; a plugin never shadows the password store. |
| Secure by design | Every change keeps PHPStan at level 9 with zero errors and conforms to the WordPress-Extra phpcs ruleset. Sanitisation, nonce checks, and capability checks are mandatory at every entry point. security-review runs on any change that touches the security boundary. No tree-wide automated fixes; compliance is verified surgically, per unit. No hardcoded secrets. |
| Honest documentation | Every GDPR, CCPA, CRA, OWASP, or WCAG claim is defensible, source-cited, and mapped to a real status: met, partial, not assessed, or not applicable. A fabricated or generalised "fully compliant" statement is a legal liability, so it is never written. |
The EU Cyber Resilience Act program
Core owns the ecosystem-wide CRA program for the whole studio. It runs in two operational phases:
- Phase 1, operational baseline. A public coordinated-vulnerability-disclosure (CVD) policy,
security.txtat the well-known location, the public posture pages on this site, the SBOM publication routine, and the internal incident-response runbook. Live across the ecosystem since 2026-05-19. - Phase 2, Annex I gap audit. Fourteen Part-I cited rows + eight Part-II cited rows, mirrored across Core, Cairnstone, and Node security pages. The first CycloneDX 1.5 SBOM ships in parallel; the public mirror at core/security/#annex-i is the canonical visible surface. Landed 2026-05-20.
Operational continuation: the static Phase 2 SBOM baseline is complemented by composer audit as an in-session pre-push gate on every push to main across Core / Cairnstone / Node. Each push runs composer audit --format=plain against the resolved lockfile; an open Packagist advisory holds the push until resolved or explicitly waived. Closes the per-release gap between the static SBOM baseline and the live dependency state. Free, no external SaaS, no new repo secrets. Feed and Mesh are skeleton-state and join when their toolchains stand up.
Why guardrails, not a checklist
A one-pass "make it compliant" rewrite is the exact destructive shortcut the doctrine forbids: high blast radius, mostly category errors on a plugin stack, and a fabricated compliance claim at the end. Guardrails baked into the doctrine are slower to satisfy and far harder to get wrong. Compliance is reached surgically, one verified unit at a time, or it is not claimed.
14: How to give input#
This page exists so the process can be argued with. If a step looks wrong, missing, or over-engineered, that is the useful signal. Concrete places it is worth pushing back:
- The gates. Are the right things gated behind a human, and is anything gated that should not be, or automated that should not be?
- The doctrine. Do the four principles still describe how the work should go, or has a fifth failure mode shown up often enough to earn its own rule?
- The skills layer. Is a skill missing from this manual that the studio actually uses? Is a listed skill no longer load-bearing and should be retired from the description?
- The MCP inventory. Is the right server picked at the right tier, or is the agent reaching for Computer-use MCP when Chrome MCP would do?
- The pipeline order. Is research-then-shape-then-craft the right sequence for the kind of work being done now, or does some class of change deserve a shorter path?
- What is missing. The honest gap in this document is the most valuable thing a reviewer can name.
Input goes back to the maintainer directly. This is a working document; it is expected to change, and the change history is part of the record. The Last revised date in the page header is when it was last touched in a non-trivial way.