[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6GKTYCT6HCB6WK9H3P2YPCM":3,"skill-same:01M6GKTYCT6HCB6WK9H3P2YPCM":77},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":44,"commitSha":45,"skillDirectory":46,"forksCount":47,"repositoryHtmlUrl":48,"repositoryHomepageUrl":49,"ownerHtmlUrl":50,"ownerBlogUrl":51,"ownerDescription":6,"updatedAt":52,"install":53,"resources":66},"01M6GKTYCT6HCB6WK9H3P2YPCM","roots-debugging",null,"Use when something is broken on a Roots\u002FAcorn WordPress project and the cause is unknown - 500 or white screen, Acorn boot failure, \"class not found\", stale Blade, missing ACF blocks, assets 404, Livewire not mounting. Also when it works locally but not on staging or production, or a change is not visible after a deploy - old HTML, Livewire 419 or RangeError right after a deploy, edge\u002FCDN, object cache or OPcache holding old state. Read-only on shared environments. For new features use the building skill; for Lando container problems use lando-wp.","hekivo\u002Fkivo-wise","hekivo","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F278159278?v=4","01M6GKH8S3Z4CAJ9RRR607G1WJ","Hekivo","01M6GKH8XNM7HTVF4DC86MA8RG",14,"MIT","https:\u002F\u002Fgithub.com\u002Fhekivo\u002Fkivo-wise\u002Fblob\u002Fmain\u002Fskills\u002Froots-debugging\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"roots debugging","debugging","read","read-only","missing","screen","project","shared","container","only","use","wordpress","broken","livewire","edge","cdn","cache","state","boot","change","2026-11-10 10:12:30",false,"---\nname: roots-debugging\ndescription: Use when something is broken on a Roots\u002FAcorn WordPress project and the cause is unknown - 500 or white screen, Acorn boot failure, \"class not found\", stale Blade, missing ACF blocks, assets 404, Livewire not mounting. Also when it works locally but not on staging or production, or a change is not visible after a deploy - old HTML, Livewire 419 or RangeError right after a deploy, edge\u002FCDN, object cache or OPcache holding old state. Read-only on shared environments. For new features use the building skill; for Lando container problems use lando-wp.\n---\n\n# Debugging Roots and Acorn projects\n\nFollow the `systematic-debugging` discipline: reproduce, gather evidence, form one hypothesis, test it, then fix. No fix without a root cause you can show (a log line, a header, a command output).\n\nRunner placeholders (`{{runner.wp}}`, `{{runner.acorn}}`, `{{runner.composer}}`, `{{runner.node}}`, `{{runner.cache}}`, `{{runner.logs}}`) come from the session context. On Lando the defaults are `lando wp`, `lando wp acorn`, `lando composer` and so on; the `lando-wp` skill documents the wiring and the container-level symptoms (DNS, certificates, ports, database service). Do not repeat that table here: if the symptom is \"the site does not even resolve\", \"port already allocated\" or \"tooling command unknown\", switch to `lando-wp`.\n\n## When to use\n\n- A request returns 500, a blank page or a Whoops\u002Fignition style error page.\n- `{{runner.acorn}} \u003Ccommand>` fails, prints nothing, or the command is missing.\n- A Blade change, a new class, a new block or a config edit does not show up.\n- Styles or scripts are missing, return 404, or point to a dev server that is not running.\n- Behaviour differs between local and a deployed environment.\n\nNot for building a feature (use the profile's building skill) or for performance tuning (use `wp-performance`).\n\n## Inputs required\n\n1. The profile and its Acorn base path (session context): theme folder, mu-plugin folder, or project root.\n2. Where it fails: local, review, staging or production. Remote environments are read-only for you: observe and report; flushing, purging or restarting needs an explicit request.\n3. What changed: branch switch, `composer.lock` or lockfile change, deploy, database sync, new class, config edit.\n4. Scope: every request, one URL, one block, logged-in only, one language, only cached pages.\n\n### Where things live per profile\n\n| Item | `sage-theme` | `acorn-mu-plugin` | `radicle-app` |\n|---|---|---|---|\n| Acorn base path | the theme folder | the plugin folder (`ACORN_BASEPATH`) | the project root |\n| Application logs | `storage\u002Flogs\u002F` in the theme if `storage\u002F` exists, otherwise `wp-content\u002Fcache\u002Facorn\u002Flogs\u002F` (Bedrock: `web\u002Fapp\u002Fcache\u002Facorn\u002Flogs\u002F`) | `storage\u002Flogs\u002F` in the plugin if present, otherwise the WordPress cache folder as for a theme | `storage\u002Flogs\u002F` at the root |\n| Compiled views | `storage\u002Fframework\u002Fviews\u002F` (same base as the logs) | same | same |\n| Config, route, package caches | `storage\u002Fframework\u002Fcache\u002F` (or `.laravel\u002F` when that folder exists in the base path) | same | same |\n| WordPress `debug.log` | `\u003Ccontent dir>\u002Fdebug.log` when `WP_DEBUG_LOG` is true | same | same (content dir is under the webroot) |\n| Composer autoload | the theme's own `vendor\u002F` | the plugin's own `vendor\u002F` | the root `vendor\u002F` |\n| Provider registration | `withProviders([...])` in the theme's `functions.php` (plus packages auto-discovered from Composer) | provider list in the boot code (`withProviders`) | `composer.json` `extra.acorn.providers` |\n| Livewire, ACF Composer, Poet | present only if installed | usually present | not installed by default |\n\n## Procedure\n\nCommands: write every command with the runner value from the session context filled in (for example `lando wp acorn optimize:clear`), never a bare `wp`\u002F`composer`\u002F`npm`, never the placeholder, never \"prefix with lando if you use it\". Commands that run on a remote host, in CI or in a deploy script go in a separate block labelled with where they run and who runs them.\n\nShared environments (staging, review, production) are read-only for you: diagnose first with requests, headers, page source and logs; any purge, flush, cache clear, restart or redeploy there is proposed with the exact command and the owner of that layer, never run and never presented as the first step.\n\n1. **Locate.** Answer the four inputs before touching code. \"Works locally, broken after a deploy\" goes straight to the deploy-staleness check below before any code reading; that check still includes the log read in step 2 (the Acorn log under the base path's `storage\u002Flogs\u002F`, or the container log on a remote environment).\n2. **Collect evidence.**\n   - Tail the Acorn log and the WordPress `debug.log` (paths above). If neither file exists, logging is not configured or the folder is not writable; that is itself a finding.\n   - Check the web server\u002FPHP log through the runner (`{{runner.logs}}`; see `lando-wp`). On a remote environment read the container or platform log. Logs live under the Acorn base path (the plugin's or app's `storage\u002Flogs\u002F`), not in a theme folder unless the profile is `sage-theme`.\n   - Print the effective debug flags: `{{runner.wp}} eval 'var_dump(WP_DEBUG, WP_DEBUG_LOG, WP_DEBUG_DISPLAY, WP_ENVIRONMENT_TYPE);'`. Acorn's exception page is shown only when `WP_DEBUG` and `WP_DEBUG_DISPLAY` are both true; otherwise errors go only to the log. Ask the user to enable them in the environment file rather than editing it yourself.\n   - Request the URL with `curl -sI` and read status and cache headers.\n   - Does Acorn boot at all? `{{runner.acorn}} list`. If this fails, the problem is boot-level (autoload, provider, storage permissions), not a view.\n3. **Categorize** with the table below, then run the targeted check.\n4. **Form one hypothesis**, change one thing, observe. If two hypotheses fail, stop, summarise the evidence and ask.\n5. **Fix** with the smallest change at the root cause, using the native WordPress\u002FAcorn mechanism first.\n6. **Verify** by repeating the original reproduction, then `{{runner.cache}}`, the project's test runner and linter.\n7. **Report** with four headings in this order: **Evidence** (what you observed or what the user should run to observe it), **Root cause**, **Fix** (local commands through the runner; remote actions as proposals with an owner), **Prevention** (deploy step, cache rule, test).\n\n### Categories and first checks\n\n| Category | Symptoms | First check |\n|---|---|---|\n| Stale caches | Old markup or behaviour after a PHP, Blade or config change | Clear the layers in [references\u002Fcache-layers.md](references\u002Fcache-layers.md), cheapest first |\n| Boot failure | Fatal on every request, every Acorn command fails | Last lines of the log; `vendor\u002F` present for the base path; provider class exists and namespace matches `composer.json` autoload; `storage\u002F` writable |\n| Class or file not found | `Class \"X\" not found`, `View [x] not found` | Namespace-to-folder match, `{{runner.composer}} dump-autoload` in the right working directory, view file name and location |\n| Blade rendering | Raw `{{ }}` shown, double-escaped text, wrong template | Open the compiled file in `storage\u002Fframework\u002Fviews\u002F`: its last line is a `PATH ... ENDPATH` comment that names the source view |\n| Routes | 404 on an Acorn route, route works in CLI but not in browser | `{{runner.acorn}} route:list`; Acorn matches routes during `do_parse_request`; check path, method and trailing slash, cached routes (`route:clear`), and that routing is registered in the boot code. `rewrite flush` is for WordPress rewrites only |\n| ACF | Block missing from the inserter, fields not saving or not showing | Class location and `$name`, location rules, ACF Composer cache (`acf:clear` then `acf:cache`), field group JSON\u002FDB sync state |\n| Livewire | Not mounting, update returns 404\u002F419\u002F500, props mismatch | `{{runner.acorn}} route:list` for the Livewire routes, scripts printed in the layout, stale cached HTML at the edge, then the livewire skill |\n| Assets | Unstyled, JS missing, 404 on `build\u002F` files, requests to a dev-server URL | Manifest exists; `public\u002Fhot` is a leftover from a stopped dev server; URL base. See `tailwind-vite-assets` |\n| Object cache | Options, menus or counts wrong; survives restarts and deploys | `{{runner.wp}} cache type`; flush locally; remote: tell the user |\n| Hooks | Filter or action has no effect | Timing and load order; see `wp-hooks-lifecycle` |\n| Database | Connection refused, migration errors | Environment file host\u002Fcredentials; `{{runner.acorn}} migrate:status` |\n| Deploy staleness | Local works, remote shows old HTML or assets; Livewire 404\u002F419\u002Fchecksum errors right after a deploy | Read-only first: `curl -sI \u003Curl>` for `age`, `cf-cache-status`\u002F`x-cache`\u002F`x-proxy-cache`; compare the asset hashes and the Livewire script\u002Fupdate URL in the served HTML with a cache-busted request and with the new build. Old HTML carries old snapshots, tokens and hashed URLs. Then name each layer that can hold old state and who clears it: edge\u002FCDN\u002Fpage cache (deploy or infra owner), object cache (`{{runner.wp}} cache flush`, environment owner), OPcache (PHP service restart), compiled views and Acorn caches (`{{runner.acorn}} optimize:clear`, deploy script). See [references\u002Fcache-layers.md](references\u002Fcache-layers.md) |\n\nSymptom-by-symptom causes and fixes: [references\u002Fsymptoms.md](references\u002Fsymptoms.md).\n\n## Verification\n\n- The original reproduction now behaves correctly and the log shows no new error for it.\n- You can name the root cause and show the evidence that confirmed it, not only that the symptom vanished.\n- The cache layers you cleared are listed in the report (a fix that only works until the next cache build is not a fix).\n- The project's tests and linter pass through the runner.\n\n## Failure modes\n\n| Symptom | Cause | Fix |\n|---|---|---|\n| Requests fail right after `optimize:clear` (seen on a project using ACF Composer) | A package manifest was deleted and not rebuilt | Run `{{runner.acorn}} optimize` (or the package's own cache command) and retry; prefer `view:clear` and `cache:clear` over `optimize:clear` when you only need views gone |\n| Change visible in CLI but not in the browser | PHP-FPM OPcache differs from CLI OPcache | Restart the PHP service (Lando: `lando restart`) |\n| `{{runner.acorn}}` prints \"command not found\" for a package command | Package discovery cache is stale | `{{runner.acorn}} package:discover`, then retry |\n| Blade error points to a hashed filename | The error is reported in the compiled file | Read the `PATH` comment at the end of that file to find the source view |\n| Fix works locally, not on the remote | A cache layer outside the code (object cache, edge, opcache) holds the old state | Ask the user to flush that layer; do not do it yourself on shared infrastructure |\n| Log file empty while the page fails | `WP_DEBUG_LOG` false or logging channel writes to stdout in that environment | Check `WP_DEBUG_LOG` and the Acorn logging channel; in containers read the container log |\n| Exception page not shown | `WP_DEBUG` or `WP_DEBUG_DISPLAY` false | Enable in the environment file (ask the user), reload |\n\n## Escalation\n\n- Evidence points to infrastructure (container runtime, database server, CDN, orchestration), a third-party plugin's code, or a vendor theme: report the evidence and stop.\n- The fix needs edits to environment files, `wp-config.php`, CI or production data: ask first.\n- Two hypotheses failed: summarise what you ruled out and ask the user.\n- Do not commit, push or run remote cache purges, restarts or database syncs unless the user asked.\n\n\u003C!-- verified: refs\u002Froots-sage\u002Ffunctions.php:35-39 — Application::configure()->withProviders([...])->boot() in functions.php;\nrefs\u002Froots-acorn\u002Fconfig\u002Fapp.php:45 — 'debug' => WP_DEBUG && WP_DEBUG_DISPLAY;\nwp\u002Fwp-includes\u002Fload.php:569-575,622-625 — WP_DEBUG_LOG true writes WP_CONTENT_DIR\u002Fdebug.log, or to a given path;\nrefs\u002Froots-docs\u002Facorn\u002Flogging.md:20 and directory-structure.md:14-27 — logs at [wp-content]\u002Fcache\u002Facorn\u002Flogs zero-config, storage\u002Flogs traditional;\nrefs\u002Froots-acorn\u002Fsrc\u002FRoots\u002FAcorn\u002FApplication.php:184-186,201 — bootstrap path is .laravel when that folder exists, else storage\u002Fframework;\nstorage\u002Fframework\u002Fcache in the reference acorn-mu-plugin project — config.php, routes-v7.php, packages.php, services.php, acf-composer\u002F, blade-icons.php present;\nstorage\u002Fframework\u002Fviews\u002F*.php last line — PATH ... ENDPATH comment with the source view;\nvendor\u002Froots\u002Facorn\u002Fsrc\u002FIlluminate\u002FFoundation\u002FConsole\u002FOptimizeClearCommand.php:59-70 — optimize:clear runs config, cache, compiled, event, route, view clears plus package clears;\nvendor\u002Flog1x\u002Facf-composer\u002Fsrc\u002FProviders\u002FAcfComposerServiceProvider.php:67-72 — optimizes(optimize: acf:cache, clear: acf:clear);\nrefs\u002Froots-acorn\u002Fsrc\u002FRoots\u002FAcorn\u002FApplication\u002FConcerns\u002FBootable.php:230-244 — Acorn routes handled via do_parse_request\u002Fparse_request, unmatched fall through;\nvendor\u002Froots\u002Facorn\u002Fsrc\u002FIlluminate\u002FFoundation\u002FVite.php:1221-1224 — isRunningHot() is is_file(hotFile);\nlando wp acorn list (the reference acorn-mu-plugin project) — view:clear, view:cache, optimize, optimize:clear, clear-compiled, icons:cache exist;\nunverified: that deleting the ACF Composer manifest causes 500s on every request is an observation from one project, not read in package source -->\n","# Debugging Roots and Acorn projects\n\nFollow the `systematic-debugging` discipline: reproduce, gather evidence, form one hypothesis, test it, then fix. No fix without a root cause you can show (a log line, a header, a command output).\n\nRunner placeholders (`{{runner.wp}}`, `{{runner.acorn}}`, `{{runner.composer}}`, `{{runner.node}}`, `{{runner.cache}}`, `{{runner.logs}}`) come from the session context. On Lando the defaults are `lando wp`, `lando wp acorn`, `lando composer` and so on; the `lando-wp` skill documents the wiring and the container-level symptoms (DNS, certificates, ports, database service). Do not repeat that table here: if the symptom is \"the site does not even resolve\", \"port already allocated\" or \"tooling command unknown\", switch to `lando-wp`.\n\n## When to use\n\n- A request returns 500, a blank page or a Whoops\u002Fignition style error page.\n- `{{runner.acorn}} \u003Ccommand>` fails, prints nothing, or the command is missing.\n- A Blade change, a new class, a new block or a config edit does not show up.\n- Styles or scripts are missing, return 404, or point to a dev server that is not running.\n- Behaviour differs between local and a deployed environment.\n\nNot for building a feature (use the profile's building skill) or for performance tuning (use `wp-performance`).\n\n## Inputs required\n\n1. The profile and its Acorn base path (session context): theme folder, mu-plugin folder, or project root.\n2. Where it fails: local, review, staging or production. Remote environments are read-only for you: observe and report; flushing, purging or restarting needs an explicit request.\n3. What changed: branch switch, `composer.lock` or lockfile change, deploy, database sync, new class, config edit.\n4. Scope: every request, one URL, one block, logged-in only, one language, only cached pages.\n\n### Where things live per profile\n\n| Item | `sage-theme` | `acorn-mu-plugin` | `radicle-app` |\n|---|---|---|---|\n| Acorn base path | the theme folder | the plugin folder (`ACORN_BASEPATH`) | the project root |\n| Application logs | `storage\u002Flogs\u002F` in the theme if `storage\u002F` exists, otherwise `wp-content\u002Fcache\u002Facorn\u002Flogs\u002F` (Bedrock: `web\u002Fapp\u002Fcache\u002Facorn\u002Flogs\u002F`) | `storage\u002Flogs\u002F` in the plugin if present, otherwise the WordPress cache folder as for a theme | `storage\u002Flogs\u002F` at the root |\n| Compiled views | `storage\u002Fframework\u002Fviews\u002F` (same base as the logs) | same | same |\n| Config, route, package caches | `storage\u002Fframework\u002Fcache\u002F` (or `.laravel\u002F` when that folder exists in the base path) | same | same |\n| WordPress `debug.log` | `\u003Ccontent dir>\u002Fdebug.log` when `WP_DEBUG_LOG` is true | same | same (content dir is under the webroot) |\n| Composer autoload | the theme's own `vendor\u002F` | the plugin's own `vendor\u002F` | the root `vendor\u002F` |\n| Provider registration | `withProviders([...])` in the theme's `functions.php` (plus packages auto-discovered from Composer) | provider list in the boot code (`withProviders`) | `composer.json` `extra.acorn.providers` |\n| Livewire, ACF Composer, Poet | present only if installed | usually present | not installed by default |\n\n## Procedure\n\nCommands: write every command with the runner value from the session context filled in (for example `lando wp acorn optimize:clear`), never a bare `wp`\u002F`composer`\u002F`npm`, never the placeholder, never \"prefix with lando if you use it\". Commands that run on a remote host, in CI or in a deploy script go in a separate block labelled with where they run and who runs them.\n\nShared environments (staging, review, production) are read-only for you: diagnose first with requests, headers, page source and logs; any purge, flush, cache clear, restart or redeploy there is proposed with the exact command and the owner of that layer, never run and never presented as the first step.\n\n1. **Locate.** Answer the four inputs before touching code. \"Works locally, broken after a deploy\" goes straight to the deploy-staleness check below before any code reading; that check still includes the log read in step 2 (the Acorn log under the base path's `storage\u002Flogs\u002F`, or the container log on a remote environment).\n2. **Collect evidence.**\n   - Tail the Acorn log and the WordPress `debug.log` (paths above). If neither file exists, logging is not configured or the folder is not writable; that is itself a finding.\n   - Check the web server\u002FPHP log through the runner (`{{runner.logs}}`; see `lando-wp`). On a remote environment read the container or platform log. Logs live under the Acorn base path (the plugin's or app's `storage\u002Flogs\u002F`), not in a theme folder unless the profile is `sage-theme`.\n   - Print the effective debug flags: `{{runner.wp}} eval 'var_dump(WP_DEBUG, WP_DEBUG_LOG, WP_DEBUG_DISPLAY, WP_ENVIRONMENT_TYPE);'`. Acorn's exception page is shown only when `WP_DEBUG` and `WP_DEBUG_DISPLAY` are both true; otherwise errors go only to the log. Ask the user to enable them in the environment file rather than editing it yourself.\n   - Request the URL with `curl -sI` and read status and cache headers.\n   - Does Acorn boot at all? `{{runner.acorn}} list`. If this fails, the problem is boot-level (autoload, provider, storage permissions), not a view.\n3. **Categorize** with the table below, then run the targeted check.\n4. **Form one hypothesis**, change one thing, observe. If two hypotheses fail, stop, summarise the evidence and ask.\n5. **Fix** with the smallest change at the root cause, using the native WordPress\u002FAcorn mechanism first.\n6. **Verify** by repeating the original reproduction, then `{{runner.cache}}`, the project's test runner and linter.\n7. **Report** with four headings in this order: **Evidence** (what you observed or what the user should run to observe it), **Root cause**, **Fix** (local commands through the runner; remote actions as proposals with an owner), **Prevention** (deploy step, cache rule, test).\n\n### Categories and first checks\n\n| Category | Symptoms | First check |\n|---|---|---|\n| Stale caches | Old markup or behaviour after a PHP, Blade or config change | Clear the layers in [references\u002Fcache-layers.md](references\u002Fcache-layers.md), cheapest first |\n| Boot failure | Fatal on every request, every Acorn command fails | Last lines of the log; `vendor\u002F` present for the base path; provider class exists and namespace matches `composer.json` autoload; `storage\u002F` writable |\n| Class or file not found | `Class \"X\" not found`, `View [x] not found` | Namespace-to-folder match, `{{runner.composer}} dump-autoload` in the right working directory, view file name and location |\n| Blade rendering | Raw `{{ }}` shown, double-escaped text, wrong template | Open the compiled file in `storage\u002Fframework\u002Fviews\u002F`: its last line is a `PATH ... ENDPATH` comment that names the source view |\n| Routes | 404 on an Acorn route, route works in CLI but not in browser | `{{runner.acorn}} route:list`; Acorn matches routes during `do_parse_request`; check path, method and trailing slash, cached routes (`route:clear`), and that routing is registered in the boot code. `rewrite flush` is for WordPress rewrites only |\n| ACF | Block missing from the inserter, fields not saving or not showing | Class location and `$name`, location rules, ACF Composer cache (`acf:clear` then `acf:cache`), field group JSON\u002FDB sync state |\n| Livewire | Not mounting, update returns 404\u002F419\u002F500, props mismatch | `{{runner.acorn}} route:list` for the Livewire routes, scripts printed in the layout, stale cached HTML at the edge, then the livewire skill |\n| Assets | Unstyled, JS missing, 404 on `build\u002F` files, requests to a dev-server URL | Manifest exists; `public\u002Fhot` is a leftover from a stopped dev server; URL base. See `tailwind-vite-assets` |\n| Object cache | Options, menus or counts wrong; survives restarts and deploys | `{{runner.wp}} cache type`; flush locally; remote: tell the user |\n| Hooks | Filter or action has no effect | Timing and load order; see `wp-hooks-lifecycle` |\n| Database | Connection refused, migration errors | Environment file host\u002Fcredentials; `{{runner.acorn}} migrate:status` |\n| Deploy staleness | Local works, remote shows old HTML or assets; Livewire 404\u002F419\u002Fchecksum errors right after a deploy | Read-only first: `curl -sI \u003Curl>` for `age`, `cf-cache-status`\u002F`x-cache`\u002F`x-proxy-cache`; compare the asset hashes and the Livewire script\u002Fupdate URL in the served HTML with a cache-busted request and with the new build. Old HTML carries old snapshots, tokens and hashed URLs. Then name each layer that can hold old state and who clears it: edge\u002FCDN\u002Fpage cache (deploy or infra owner), object cache (`{{runner.wp}} cache flush`, environment owner), OPcache (PHP service restart), compiled views and Acorn caches (`{{runner.acorn}} optimize:clear`, deploy script). See [references\u002Fcache-layers.md](references\u002Fcache-layers.md) |\n\nSymptom-by-symptom causes and fixes: [references\u002Fsymptoms.md](references\u002Fsymptoms.md).\n\n## Verification\n\n- The original reproduction now behaves correctly and the log shows no new error for it.\n- You can name the root cause and show the evidence that confirmed it, not only that the symptom vanished.\n- The cache layers you cleared are listed in the report (a fix that only works until the next cache build is not a fix).\n- The project's tests and linter pass through the runner.\n\n## Failure modes\n\n| Symptom | Cause | Fix |\n|---|---|---|\n| Requests fail right after `optimize:clear` (seen on a project using ACF Composer) | A package manifest was deleted and not rebuilt | Run `{{runner.acorn}} optimize` (or the package's own cache command) and retry; prefer `view:clear` and `cache:clear` over `optimize:clear` when you only need views gone |\n| Change visible in CLI but not in the browser | PHP-FPM OPcache differs from CLI OPcache | Restart the PHP service (Lando: `lando restart`) |\n| `{{runner.acorn}}` prints \"command not found\" for a package command | Package discovery cache is stale | `{{runner.acorn}} package:discover`, then retry |\n| Blade error points to a hashed filename | The error is reported in the compiled file | Read the `PATH` comment at the end of that file to find the source view |\n| Fix works locally, not on the remote | A cache layer outside the code (object cache, edge, opcache) holds the old state | Ask the user to flush that layer; do not do it yourself on shared infrastructure |\n| Log file empty while the page fails | `WP_DEBUG_LOG` false or logging channel writes to stdout in that environment | Check `WP_DEBUG_LOG` and the Acorn logging channel; in containers read the container log |\n| Exception page not shown | `WP_DEBUG` or `WP_DEBUG_DISPLAY` false | Enable in the environment file (ask the user), reload |\n\n## Escalation\n\n- Evidence points to infrastructure (container runtime, database server, CDN, orchestration), a third-party plugin's code, or a vendor theme: report the evidence and stop.\n- The fix needs edits to environment files, `wp-config.php`, CI or production data: ask first.\n- Two hypotheses failed: summarise what you ruled out and ask the user.\n- Do not commit, push or run remote cache purges, restarts or database syncs unless the user asked.\n\n\u003C!-- verified: refs\u002Froots-sage\u002Ffunctions.php:35-39 — Application::configure()->withProviders([...])->boot() in functions.php;\nrefs\u002Froots-acorn\u002Fconfig\u002Fapp.php:45 — 'debug' => WP_DEBUG && WP_DEBUG_DISPLAY;\nwp\u002Fwp-includes\u002Fload.php:569-575,622-625 — WP_DEBUG_LOG true writes WP_CONTENT_DIR\u002Fdebug.log, or to a given path;\nrefs\u002Froots-docs\u002Facorn\u002Flogging.md:20 and directory-structure.md:14-27 — logs at [wp-content]\u002Fcache\u002Facorn\u002Flogs zero-config, storage\u002Flogs traditional;\nrefs\u002Froots-acorn\u002Fsrc\u002FRoots\u002FAcorn\u002FApplication.php:184-186,201 — bootstrap path is .laravel when that folder exists, else storage\u002Fframework;\nstorage\u002Fframework\u002Fcache in the reference acorn-mu-plugin project — config.php, routes-v7.php, packages.php, services.php, acf-composer\u002F, blade-icons.php present;\nstorage\u002Fframework\u002Fviews\u002F*.php last line — PATH ... ENDPATH comment with the source view;\nvendor\u002Froots\u002Facorn\u002Fsrc\u002FIlluminate\u002FFoundation\u002FConsole\u002FOptimizeClearCommand.php:59-70 — optimize:clear runs config, cache, compiled, event, route, view clears plus package clears;\nvendor\u002Flog1x\u002Facf-composer\u002Fsrc\u002FProviders\u002FAcfComposerServiceProvider.php:67-72 — optimizes(optimize: acf:cache, clear: acf:clear);\nrefs\u002Froots-acorn\u002Fsrc\u002FRoots\u002FAcorn\u002FApplication\u002FConcerns\u002FBootable.php:230-244 — Acorn routes handled via do_parse_request\u002Fparse_request, unmatched fall through;\nvendor\u002Froots\u002Facorn\u002Fsrc\u002FIlluminate\u002FFoundation\u002FVite.php:1221-1224 — isRunningHot() is is_file(hotFile);\nlando wp acorn list (the reference acorn-mu-plugin project) — view:clear, view:cache, optimize, optimize:clear, clear-compiled, icons:cache exist;\nunverified: that deleting the ACF Composer manifest causes 500s on every request is an observation from one project, not read in package source -->\n",{"name":5,"description":7},"main","4045a2f672c1d4c1b4a5a5712b468c5d73ca6724","skills\u002Froots-debugging",0,"https:\u002F\u002Fgithub.com\u002Fhekivo\u002Fkivo-wise","https:\u002F\u002Fhekivo.github.io\u002Fkivo-wise\u002F","https:\u002F\u002Fgithub.com\u002Fhekivo","https:\u002F\u002Fhekivo.dev","2026-11-08 06:10:39",{"source":8,"skillName":5,"commands":54,"prompt":64,"zipAvailable":65},[55,58,61],{"tool":56,"command":57},"npx","npx skills add hekivo\u002Fkivo-wise --skill roots-debugging",{"tool":59,"command":60},"bunx","bunx skills add hekivo\u002Fkivo-wise --skill roots-debugging",{"tool":62,"command":63},"pnpm","pnpm dlx skills add hekivo\u002Fkivo-wise --skill roots-debugging","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fhekivo\u002Fkivo-wise\u002Fblob\u002Fmain\u002Fskills\u002Froots-debugging\u002FSKILL.md",true,[67,73],{"path":68,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":71,"sourceHtmlUrl":72},"references\u002Fcache-layers.md","REFERENCE","参考文档",3997,"https:\u002F\u002Fgithub.com\u002Fhekivo\u002Fkivo-wise\u002Fblob\u002Fmain\u002Fskills\u002Froots-debugging\u002Freferences\u002Fcache-layers.md",{"path":74,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":75,"sourceHtmlUrl":76},"references\u002Fsymptoms.md",5542,"https:\u002F\u002Fgithub.com\u002Fhekivo\u002Fkivo-wise\u002Fblob\u002Fmain\u002Fskills\u002Froots-debugging\u002Freferences\u002Fsymptoms.md",[78,112,130,151,170,193],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":94,"publishedAt":39},"01M6GKWJDFKQM27HTFXX20QVTP","wp-rest-api","Use when building, extending, or debugging WordPress REST API endpoints\u002Froutes: register_rest_route, WP_REST_Controller\u002Fcontroller classes, schema\u002Fargument validation, permission_callback\u002Fauthentication, response shaping, register_rest_field\u002Fregister_meta, or exposing CPTs\u002Ftaxonomies via show_in_rest.","https:\u002F\u002Fgithub.com\u002Fhekivo\u002Fkivo-wise\u002Fblob\u002Fmain\u002Fthird-party\u002Fwp-rest-api\u002FSKILL.md",[84,89],{"categoryNo":85,"categoryName":86,"taxonomyType":87,"taxonomyTypeDesc":88},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":90,"categoryName":91,"taxonomyType":92,"taxonomyTypeDesc":93},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[95,96,97,98,30,99,20,100,101,102,103,104,105,29,106,107,108,109,110,111],"REST","api","wp rest api","rest api","workflows","authentication","Meta","controller","Bash","shaping","filesystem","schema","show","route","register","with","wp-cli",{"skillNo":113,"name":114,"nameZh":6,"description":115,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":116,"categories":117,"keywords":120,"publishedAt":39},"01M6GKWEA5BMJZ2RPPEEJTCC3N","wp-abilities-api","Use when working with the WordPress Abilities API (wp_register_ability, wp_register_ability_category, \u002Fwp-json\u002Fwp-abilities\u002Fv1\u002F*, @wordpress\u002Fabilities) including defining abilities, categories, meta, REST exposure, and permissions checks for clients.","https:\u002F\u002Fgithub.com\u002Fhekivo\u002Fkivo-wise\u002Fblob\u002Fmain\u002Fthird-party\u002Fwp-abilities-api\u002FSKILL.md",[118,119],{"categoryNo":85,"categoryName":86,"taxonomyType":87,"taxonomyTypeDesc":88},{"categoryNo":90,"categoryName":91,"taxonomyType":92,"taxonomyTypeDesc":93},[96,121,122,30,99,123,101,95,103,124,125,105,126,29,109,127,128,110,129,111],"wp abilities api","cli","permissions","php","json","node","targets","clients","categories",{"skillNo":131,"name":132,"nameZh":6,"description":133,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":134,"categories":135,"keywords":136,"publishedAt":39},"01M6GKWA4GG2BZRFXCR9E73VR7","wp-security-escaping","Use when writing or reviewing code that outputs data, handles input or checks permissions in a WordPress + Acorn project - Blade {{ }} vs {!! !!}, esc_html, esc_attr, esc_url, wp_kses_post, \"&#038; in the URL\", double escaping, sanitize_text_field, nonces, current_user_can, map_meta_cap, permission_callback, $wpdb->prepare, whereRaw, file uploads, escaping ACF values, secrets in .env. For route middleware use acorn-routes-api; for ACF validation use acf-native; for Livewire actions use acorn-livewire.","https:\u002F\u002Fgithub.com\u002Fhekivo\u002Fkivo-wise\u002Fblob\u002Fmain\u002Fskills\u002Fwp-security-escaping\u002FSKILL.md",[],[137,138,139,140,141,123,142,101,96,143,32,144,145,108,146,25,147,148,149,150],"security","wp security","wp security escaping","writing","code","actions","secrets","text","cap","map","middleware","native","URL","routes-api",{"skillNo":152,"name":153,"nameZh":6,"description":154,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":155,"categories":156,"keywords":157,"publishedAt":39},"01M6GKW6VVY73BMZ3JNDMR4CWZ","wp-phpstan","Use when configuring, running or fixing PHPStan in a WordPress project that uses Acorn - phpstan.neon, baseline, szepeviktor\u002Fphpstan-wordpress stubs, larastan, level raising, \"Cannot access property on mixed\", get_field() types, paths for app\u002F. For Pint or Mago formatting use testing-wp; for runtime errors use roots-debugging.","https:\u002F\u002Fgithub.com\u002Fhekivo\u002Fkivo-wise\u002Fblob\u002Fmain\u002Fskills\u002Fwp-phpstan\u002FSKILL.md",[],[158,159,30,20,160,161,29,25,162,163,164,165,166,167,168,169],"wp phpstan","testing","baseline","access","get","neon","runtime","formatting","app","paths","types","errors",{"skillNo":171,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":174,"categories":175,"keywords":176,"publishedAt":39},"01M6GKW3JRSRS9N112QFA3SEGT","wp-performance","Use when a WordPress page, query or request is slow or needs profiling - TTFB, slow or N+1 queries, Query Monitor, Server-Timing, wp profile and wp doctor, autoloaded options, Redis object cache hit rate, transients, WP_CACHE_KEY_SALT. Adds the runner and Redis notes on top of the official procedure. For Eloquent query design use acorn-data; for PHP type errors use wp-phpstan.","https:\u002F\u002Fgithub.com\u002Fhekivo\u002Fkivo-wise\u002Fblob\u002Fmain\u002Fskills\u002Fwp-performance\u002FSKILL.md",[],[177,178,179,30,180,181,182,183,184,35,185,186,187,29,188,189,190,191,192,169],"performance","wp performance","design","query design","official","notes","monitor","doctor","server","redis","page","queries","runner","query","type","timing",{"skillNo":194,"name":195,"nameZh":6,"description":196,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":197,"categories":198,"keywords":199,"publishedAt":39},"01M6GKVZN243XQB5QWZ5ZKMG7P","wp-hooks-lifecycle","Use when adding, moving or debugging WordPress actions and filters in an Acorn project - add_action\u002Fadd_filter priority and accepted_args, where a hook belongs (setup or filters files vs a provider boot()), load order (mu-plugins, plugins_loaded, after_setup_theme, init), when Acorn boots per profile, hooks that never fire on Acorn routes, REST or Livewire requests (template_redirect, wp_head), save_post firing twice in the block editor, the_content priorities. For ACF hooks use acf-native; for provider structure use acorn-stack.","https:\u002F\u002Fgithub.com\u002Fhekivo\u002Fkivo-wise\u002Fblob\u002Fmain\u002Fskills\u002Fwp-hooks-lifecycle\u002FSKILL.md",[],[200,201,202,30,203,37,20,142,95,204,32,29,205,206,207,208,209,25,210,211],"lifecycle","hooks","wp hooks lifecycle","init","stack","never","filters","files","provider","structure","filter","theme"]