[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M698S8HHXTJYJRY11PS2DF71":3,"skill-same:01M698S8HHXTJYJRY11PS2DF71":76},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":42,"linkOnly":43,"markdownContent":44,"markdownBody":45,"frontMatter":46,"refName":47,"commitSha":48,"skillDirectory":49,"forksCount":50,"repositoryHtmlUrl":51,"repositoryHomepageUrl":52,"ownerHtmlUrl":53,"ownerBlogUrl":52,"ownerDescription":54,"updatedAt":55,"install":56,"resources":69},"01M698S8HHXTJYJRY11PS2DF71","release-openclaw-plugin-testing",null,"Plan and run pre-release OpenClaw plugin validation across bundled plugins, package artifacts, lifecycle commands, doctor\u002Ffix, config round-trip, gateway startup, SDK compatibility, Docker E2E, Package Acceptance, and Testbox proof.","openclaw\u002Fopenclaw","openclaw","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F252820863?v=4","01M698P3FSAZ6B4R928ZF19KPT","01M698PDMDRVH56MV30D253NFP",394302,"MIT","https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Frelease-openclaw-plugin-testing\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[9,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41],"plugin testing","openclaw plugin","release","plugin","release openclaw plugin testing","testing","config","run","docker","doctor","acceptance","gateway","e2e","lifecycle","plan","fix","compatibility","across","commands","2026-11-10 10:12:30",false,"---\nname: release-openclaw-plugin-testing\ndescription: Plan and run pre-release OpenClaw plugin validation across bundled plugins, package artifacts, lifecycle commands, doctor\u002Ffix, config round-trip, gateway startup, SDK compatibility, Docker E2E, Package Acceptance, and Testbox proof.\n---\n\n# OpenClaw Pre-Release Plugin Testing\n\nUse this skill when the user asks for plugin release confidence, plugin lifecycle\nsweeps, package-artifact plugin proof, or \"what else should we test before\nrelease?\" It complements `openclaw-testing`; use that skill too when choosing\nthe cheapest safe runner or debugging a failing lane.\n\n## Goal\n\nProve the plugin system as a product surface, not just as source tests:\n\n- bundled plugin lifecycle: install, inspect, enable, disable, uninstall\n- package artifact behavior from a clean `HOME`\n- doctor\u002Ffix\u002Fconfig validation and idempotence\n- config discovery and config round-trip\n- status\u002Flog visibility and diagnostics\n- gateway startup\u002Fbootstrap with plugin metadata snapshots\n- public SDK compatibility for real external plugins\n- live-ish provider\u002Fchannel probes only when safe credentials exist\n\n## First Checks\n\nFrom the OpenClaw repo root:\n\n```bash\npnpm docs:list\ngit status --short --branch\npnpm changed:lanes --json\n```\n\nFollow [`openclaw-testing`](..\u002Fopenclaw-testing\u002FSKILL.md) for dependency\nownership and the choice of local or remote proof.\n\n## Runner Choice\n\nPrefer this order:\n\n1. **GitHub Package Acceptance** for installable-package product proof.\n2. **Current dedicated Linux worker** for trusted source\u002Fpackage\u002FDocker proof\n   when it has the required dependencies and capabilities.\n3. **`ci-build-artifacts-testbox.yml` Testbox** when Docker\u002Fpackage lanes need\n   seeded `dist`, `dist-runtime`, and package caches.\n4. **`ci-check-testbox.yml` Testbox** for source checks, targeted Vitest,\n   package-boundary checks, or focused Docker lanes.\n5. **Workstation targeted commands only** for small format\u002Fstatic\u002Funit probes.\n\nAvoid long package Docker runs from a stale sparse worktree. If Testbox sync\nreports hundreds of changed files or starts deleting package inputs, stop and\nwarm a fresh box from current `main`, or switch to Package Acceptance.\n\n## Existing Baseline\n\nRun or verify these before inventing new coverage:\n\n```bash\nOPENCLAW_TESTBOX=1 pnpm check:changed\npnpm run test:extensions:package-boundary:canary\npnpm run test:extensions:package-boundary:compile\npnpm test:docker:plugins\nOPENCLAW_PLUGINS_E2E_CLAWHUB=0 pnpm test:docker:plugins\npnpm test:docker:plugin-update\n```\n\nFor full bundled install\u002Funinstall proof, shard the packaged sweep:\n\n```bash\nOPENCLAW_BUNDLED_PLUGIN_SWEEP_TOTAL=8 \\\nOPENCLAW_BUNDLED_PLUGIN_SWEEP_INDEX=\u003C0-7> \\\npnpm test:docker:bundled-plugin-install-uninstall\n```\n\nThis example partitions the selected package's plugin inventory over shards `0-7`.\nPrivate QA plugins are source-mode only unless a package explicitly includes\nthem.\n\n## Confidence Matrix\n\nUse this matrix for pre-release signoff. Record pass\u002Ffail, run URL\u002FTestbox ID,\npackage SHA\u002Fversion, and skipped-live reason.\n\n| Surface           | Proof                                                           | Preferred runner                     |\n| ----------------- | --------------------------------------------------------------- | ------------------------------------ |\n| Package artifact  | Package Acceptance `suite_profile=package` or custom lanes      | GitHub Actions                       |\n| Bundled lifecycle | Sharded `test:docker:bundled-plugin-install-uninstall`          | Testbox or release Docker            |\n| External plugins  | `test:docker:plugins` and `plugins-offline`                     | Testbox\u002Fpackage acceptance           |\n| Update no-op      | `test:docker:plugin-update`                                     | Testbox\u002Fpackage acceptance           |\n| Doctor\u002Ffix        | seeded bad configs + `doctor --fix --non-interactive`           | new Docker\u002FTestbox harness           |\n| Config round-trip | `config set\u002Fget`, inspect, doctor, reload, diff hash            | new Docker\u002FTestbox harness           |\n| Gateway bootstrap | clean `HOME`, plugin groups enabled\u002Fdisabled, status JSON       | new Docker\u002FTestbox harness           |\n| SDK compatibility | directory, tgz, and `file:` external plugins using SDK subpaths | `test:docker:plugins` plus new smoke |\n| Live-ish          | redacted provider\u002Fchannel probes only for present env           | Testbox live lanes                   |\n\n## Package Acceptance Plan\n\nFull Release Validation owns final candidate qualification with Q=C and the\nexact publication tarballs. Use standalone Package Acceptance for diagnostics\nor postpublish confidence, not as a replacement candidate qualification:\n\n```bash\ngh workflow run package-acceptance.yml \\\n  --repo openclaw\u002Fopenclaw \\\n  --ref main \\\n  -f workflow_ref=main \\\n  -f source=ref \\\n  -f package_ref=\u003Cbranch-or-sha> \\\n  -f suite_profile=custom \\\n  -f docker_lanes='plugins-offline plugin-update doctor-switch update-channel-switch config-reload mcp-channels npm-onboard-channel-agent' \\\n  -f telegram_mode=mock-openai\n```\n\nUse `source=npm -f package_spec=openclaw@beta` for published beta proof. These\nstandalone diagnostic\u002Fconfidence runs may use trusted current harness code;\ncandidate qualification must retain the frozen candidate's harness instead.\n\nFor extended-stable shared publication, require complete exact-target Full\nRelease Validation from the admitted candidate-owned `release-ci\u002F*` harness at Q=C,\nwith trusted P admission and publication tooling separate. Direct\ncanonical-branch or `main` producers do not satisfy the protected publisher.\nPackage Acceptance is a post-publish selector smoke:\n\n```bash\ngh workflow run package-acceptance.yml \\\n  --repo openclaw\u002Fopenclaw \\\n  --ref main \\\n  -f workflow_ref=main \\\n  -f source=npm \\\n  -f package_spec=openclaw@extended-stable \\\n  -f suite_profile=package \\\n  -f telegram_mode=mock-openai\n```\n\nRecord the resolved version. Still verify every package and selector in the\ntag's `all-publishable` inventory; one smoke is not registry readback.\n\n## Plugin npm Artifact Qualification\n\nFor a publication candidate, Full Release Validation owns plugin npm artifact\nqualification. Supply its publication selection at dispatch; the all-group\nparent invokes `plugin-npm-release.yml` in artifact-only mode against the exact\nRelease SHA, requires successful tarball readback, and records the immutable\naggregate descriptor in `publicationArtifacts.pluginNpm`. Release Prepare and\npublication must adopt that exact descriptor rather than repacking plugins.\n\nUse a standalone trusted-workflow preflight only for a focused diagnostic or a\nselected-plugin repair that is outside a regular publication candidate:\n\n```bash\nrelease_sha=\"$(git rev-parse origin\u002Frelease\u002F2026.7.1)\"\ngh workflow run plugin-npm-release.yml \\\n  --repo openclaw\u002Fopenclaw \\\n  --ref main \\\n  -f preflight_only=true \\\n  -f publish_scope=selected \\\n  -f plugins=@openclaw\u002Fmeta-provider \\\n  -f ref=\"${release_sha}\" \\\n  -f npm_dist_tag=default\n```\n\nDo not pass `release_publish_run_id`. Require the workflow to finish\n`verify_plugin_npm_preflight` successfully. Record the run URL, workflow SHA,\nand source SHA. The workflow first creates the staging\u002Freadback artifact\n`plugin-npm-package-source-\u003Csource-sha>-\u003Cextension-id>` containing\n`npm-pack.json`, `preflight-manifest.json`, and the tarball. It then uploads the\nfinal consumer artifact\n`plugin-npm-package-\u003Cextension-id>-\u003Cversion>-\u003Croute>-\u003Crun-id>-\u003Cattempt>` containing\nthe tarball and `plugin-publication-manifest.json`.\n\nRecord the final artifact name and digest separately. The manifest uses\n`openclaw.plugin-publication-artifact\u002Fv1` and records the target SHA, package\nmanifest hashes, publication route and policy, and tarball hashes and inventory.\nThis standalone proof is validation-only; it does not authorize or stage\npublication and cannot replace Full Release Validation's manifest-bound\ndescriptor. The artifact inventory, rather than the unpacked source tree, is\nthe security and package-content boundary: source-only fixtures are irrelevant.\nPackage-owned test and fixture paths outside shipped runtime and skill assets\nfail qualification; shipped runtime remains security-scanned. Bundled\n`node_modules` stays with dependency evidence rather than plugin-source policy.\nThe separate `trusted_publisher_preflight=true` OIDC check requires a protected\n`release-publish\u002F\u003Ctooling-sha12>-\u003Cepoch>` dispatch tag and runs in `npm-publish`.\nReal publication also requires that tooling tag; a direct human dispatch waits\nfor its `npm-release` approval job before publishing.\nFor an already-published version,\nrequire npm `dist.integrity` and `dist.shasum` to match the verified tarball.\nTreat only missing or provably older dist-tags as repairable; newer or\nincomparable selectors are a blocker.\n\n## New Testbox Harness Plan\n\nIf more certainty is needed, add or run a `plugin-lifecycle-matrix` Docker lane\nthat uses one package tarball and sharded plugin lists. Per plugin:\n\n1. Start with a clean `HOME`.\n2. Capture `plugins list --json`.\n3. `plugins install \u003Cid>`.\n4. `plugins inspect \u003Cid> --json`.\n5. `plugins disable \u003Cid>`, then assert disabled visibility.\n6. `plugins enable \u003Cid>`, except config-required plugins without config.\n7. `plugins registry --refresh`.\n8. `doctor --non-interactive`.\n9. `plugins uninstall \u003Cid> --force`.\n10. Assert the plugin's `plugins.entries` value is exactly `{ enabled: false }`,\n    while its allow\u002Fdeny entries, install record, managed directory, and bundled\n    runtime load paths are gone. Use the existing harness's source-qualified\n    uninstall expectations for historical targets.\n11. Assert diagnostics contain no `level: \"error\"` and output redacts\n    secret-looking values.\n\nKeep `memory-lancedb` special: it is config-required. First assert install does\nnot enable it without embedding config, then run a second configured case.\n\n## Doctor\u002FFix Matrix\n\nSeed bad states and require `doctor --fix --non-interactive` to repair them,\nthen run doctor again and require idempotence:\n\n- stale `plugins.allow`\n- stale `plugins.entries`\n- stale channel config for missing channel plugin\n- invalid `plugins.entries.\u003Cid>.config`\n- packaged bundled path in `plugins.load.paths`\n- legacy `plugins.installs`\n- disabled channel\u002Fplugin config that must not stage runtime deps\n- root-owned global package tree that must remain unmodified\n\n## Gateway Bootstrap Matrix\n\nStart packaged OpenClaw in Docker with clean state:\n\n- provider plugins enabled, no credentials: ready with warnings, no crash\n- channel plugins configured disabled: no runtime deps staged\n- startup-activation plugins enabled: ready and reflected in status\n- invalid single plugin config: bad plugin skipped\u002Fquarantined, others remain\n\nAssert:\n\n- gateway reaches ready\n- `openclaw status --json` includes plugin diagnostics\n- `openclaw plugins inspect --all --json` is parseable\n- package tree is not mutated\n- logs contain no raw tokens\n\n## Config Round-Trip Representatives\n\nUse representative plugin families instead of every plugin for deep config\nround-trip:\n\n- providers: `openai`, `anthropic`, `mistral`, `openrouter`\n- channels: `telegram`, `discord`, `slack`, `whatsapp`\n- memory: `memory-lancedb`\n- feature\u002Fruntime: `browser`, `acpx`, `tokenjuice`\n\nFor each representative:\n\n1. Write config through CLI when possible.\n2. Read it back through `config get` or JSON.\n3. Run `plugins inspect`.\n4. Run `doctor --non-interactive`.\n5. Trigger gateway config reload if applicable.\n6. Compare config hash before\u002Fafter no-op commands.\n\n## External SDK Smoke\n\nIn a package Docker lane, create tiny external plugins and install them from:\n\n- local directory\n- `.tgz`\n- `file:` npm spec\n\nCover CJS and ESM shapes, plus at least one plugin importing focused\n`openclaw\u002Fplugin-sdk\u002F*` subpaths. Assert `plugins inspect` sees its tool,\ngateway method, CLI command, or service.\n\n## Live-Ish Probe Rules\n\nBefore live-ish work, source allowed env in Testbox and generate a redacted\navailability matrix: present\u002Fmissing only, never values.\n\nOnly run probes for credentials that exist. Prefer auth\u002Fcatalog\u002Fstatus probes\nover sending user-visible messages. If a probe might contact an external user,\nchannel, or workspace, stop and ask the user.\n\n## Reporting\n\nReport in this shape:\n\n```text\npackage\u002Fref:\ntbx ids \u002F run urls:\nmatrix:\n  bundled lifecycle:\n  package acceptance:\n  doctor\u002Ffix:\n  gateway bootstrap:\n  config round-trip:\n  sdk external:\n  live-ish:\nfailures:\nskips:\nnext highest-value gap:\n```\n\nSay clearly when a failure is Testbox sync\u002Fenv damage rather than product\nbehavior, and prove that with a clean rerun or current-main comparison.\n","# OpenClaw Pre-Release Plugin Testing\n\nUse this skill when the user asks for plugin release confidence, plugin lifecycle\nsweeps, package-artifact plugin proof, or \"what else should we test before\nrelease?\" It complements `openclaw-testing`; use that skill too when choosing\nthe cheapest safe runner or debugging a failing lane.\n\n## Goal\n\nProve the plugin system as a product surface, not just as source tests:\n\n- bundled plugin lifecycle: install, inspect, enable, disable, uninstall\n- package artifact behavior from a clean `HOME`\n- doctor\u002Ffix\u002Fconfig validation and idempotence\n- config discovery and config round-trip\n- status\u002Flog visibility and diagnostics\n- gateway startup\u002Fbootstrap with plugin metadata snapshots\n- public SDK compatibility for real external plugins\n- live-ish provider\u002Fchannel probes only when safe credentials exist\n\n## First Checks\n\nFrom the OpenClaw repo root:\n\n```bash\npnpm docs:list\ngit status --short --branch\npnpm changed:lanes --json\n```\n\nFollow [`openclaw-testing`](..\u002Fopenclaw-testing\u002FSKILL.md) for dependency\nownership and the choice of local or remote proof.\n\n## Runner Choice\n\nPrefer this order:\n\n1. **GitHub Package Acceptance** for installable-package product proof.\n2. **Current dedicated Linux worker** for trusted source\u002Fpackage\u002FDocker proof\n   when it has the required dependencies and capabilities.\n3. **`ci-build-artifacts-testbox.yml` Testbox** when Docker\u002Fpackage lanes need\n   seeded `dist`, `dist-runtime`, and package caches.\n4. **`ci-check-testbox.yml` Testbox** for source checks, targeted Vitest,\n   package-boundary checks, or focused Docker lanes.\n5. **Workstation targeted commands only** for small format\u002Fstatic\u002Funit probes.\n\nAvoid long package Docker runs from a stale sparse worktree. If Testbox sync\nreports hundreds of changed files or starts deleting package inputs, stop and\nwarm a fresh box from current `main`, or switch to Package Acceptance.\n\n## Existing Baseline\n\nRun or verify these before inventing new coverage:\n\n```bash\nOPENCLAW_TESTBOX=1 pnpm check:changed\npnpm run test:extensions:package-boundary:canary\npnpm run test:extensions:package-boundary:compile\npnpm test:docker:plugins\nOPENCLAW_PLUGINS_E2E_CLAWHUB=0 pnpm test:docker:plugins\npnpm test:docker:plugin-update\n```\n\nFor full bundled install\u002Funinstall proof, shard the packaged sweep:\n\n```bash\nOPENCLAW_BUNDLED_PLUGIN_SWEEP_TOTAL=8 \\\nOPENCLAW_BUNDLED_PLUGIN_SWEEP_INDEX=\u003C0-7> \\\npnpm test:docker:bundled-plugin-install-uninstall\n```\n\nThis example partitions the selected package's plugin inventory over shards `0-7`.\nPrivate QA plugins are source-mode only unless a package explicitly includes\nthem.\n\n## Confidence Matrix\n\nUse this matrix for pre-release signoff. Record pass\u002Ffail, run URL\u002FTestbox ID,\npackage SHA\u002Fversion, and skipped-live reason.\n\n| Surface           | Proof                                                           | Preferred runner                     |\n| ----------------- | --------------------------------------------------------------- | ------------------------------------ |\n| Package artifact  | Package Acceptance `suite_profile=package` or custom lanes      | GitHub Actions                       |\n| Bundled lifecycle | Sharded `test:docker:bundled-plugin-install-uninstall`          | Testbox or release Docker            |\n| External plugins  | `test:docker:plugins` and `plugins-offline`                     | Testbox\u002Fpackage acceptance           |\n| Update no-op      | `test:docker:plugin-update`                                     | Testbox\u002Fpackage acceptance           |\n| Doctor\u002Ffix        | seeded bad configs + `doctor --fix --non-interactive`           | new Docker\u002FTestbox harness           |\n| Config round-trip | `config set\u002Fget`, inspect, doctor, reload, diff hash            | new Docker\u002FTestbox harness           |\n| Gateway bootstrap | clean `HOME`, plugin groups enabled\u002Fdisabled, status JSON       | new Docker\u002FTestbox harness           |\n| SDK compatibility | directory, tgz, and `file:` external plugins using SDK subpaths | `test:docker:plugins` plus new smoke |\n| Live-ish          | redacted provider\u002Fchannel probes only for present env           | Testbox live lanes                   |\n\n## Package Acceptance Plan\n\nFull Release Validation owns final candidate qualification with Q=C and the\nexact publication tarballs. Use standalone Package Acceptance for diagnostics\nor postpublish confidence, not as a replacement candidate qualification:\n\n```bash\ngh workflow run package-acceptance.yml \\\n  --repo openclaw\u002Fopenclaw \\\n  --ref main \\\n  -f workflow_ref=main \\\n  -f source=ref \\\n  -f package_ref=\u003Cbranch-or-sha> \\\n  -f suite_profile=custom \\\n  -f docker_lanes='plugins-offline plugin-update doctor-switch update-channel-switch config-reload mcp-channels npm-onboard-channel-agent' \\\n  -f telegram_mode=mock-openai\n```\n\nUse `source=npm -f package_spec=openclaw@beta` for published beta proof. These\nstandalone diagnostic\u002Fconfidence runs may use trusted current harness code;\ncandidate qualification must retain the frozen candidate's harness instead.\n\nFor extended-stable shared publication, require complete exact-target Full\nRelease Validation from the admitted candidate-owned `release-ci\u002F*` harness at Q=C,\nwith trusted P admission and publication tooling separate. Direct\ncanonical-branch or `main` producers do not satisfy the protected publisher.\nPackage Acceptance is a post-publish selector smoke:\n\n```bash\ngh workflow run package-acceptance.yml \\\n  --repo openclaw\u002Fopenclaw \\\n  --ref main \\\n  -f workflow_ref=main \\\n  -f source=npm \\\n  -f package_spec=openclaw@extended-stable \\\n  -f suite_profile=package \\\n  -f telegram_mode=mock-openai\n```\n\nRecord the resolved version. Still verify every package and selector in the\ntag's `all-publishable` inventory; one smoke is not registry readback.\n\n## Plugin npm Artifact Qualification\n\nFor a publication candidate, Full Release Validation owns plugin npm artifact\nqualification. Supply its publication selection at dispatch; the all-group\nparent invokes `plugin-npm-release.yml` in artifact-only mode against the exact\nRelease SHA, requires successful tarball readback, and records the immutable\naggregate descriptor in `publicationArtifacts.pluginNpm`. Release Prepare and\npublication must adopt that exact descriptor rather than repacking plugins.\n\nUse a standalone trusted-workflow preflight only for a focused diagnostic or a\nselected-plugin repair that is outside a regular publication candidate:\n\n```bash\nrelease_sha=\"$(git rev-parse origin\u002Frelease\u002F2026.7.1)\"\ngh workflow run plugin-npm-release.yml \\\n  --repo openclaw\u002Fopenclaw \\\n  --ref main \\\n  -f preflight_only=true \\\n  -f publish_scope=selected \\\n  -f plugins=@openclaw\u002Fmeta-provider \\\n  -f ref=\"${release_sha}\" \\\n  -f npm_dist_tag=default\n```\n\nDo not pass `release_publish_run_id`. Require the workflow to finish\n`verify_plugin_npm_preflight` successfully. Record the run URL, workflow SHA,\nand source SHA. The workflow first creates the staging\u002Freadback artifact\n`plugin-npm-package-source-\u003Csource-sha>-\u003Cextension-id>` containing\n`npm-pack.json`, `preflight-manifest.json`, and the tarball. It then uploads the\nfinal consumer artifact\n`plugin-npm-package-\u003Cextension-id>-\u003Cversion>-\u003Croute>-\u003Crun-id>-\u003Cattempt>` containing\nthe tarball and `plugin-publication-manifest.json`.\n\nRecord the final artifact name and digest separately. The manifest uses\n`openclaw.plugin-publication-artifact\u002Fv1` and records the target SHA, package\nmanifest hashes, publication route and policy, and tarball hashes and inventory.\nThis standalone proof is validation-only; it does not authorize or stage\npublication and cannot replace Full Release Validation's manifest-bound\ndescriptor. The artifact inventory, rather than the unpacked source tree, is\nthe security and package-content boundary: source-only fixtures are irrelevant.\nPackage-owned test and fixture paths outside shipped runtime and skill assets\nfail qualification; shipped runtime remains security-scanned. Bundled\n`node_modules` stays with dependency evidence rather than plugin-source policy.\nThe separate `trusted_publisher_preflight=true` OIDC check requires a protected\n`release-publish\u002F\u003Ctooling-sha12>-\u003Cepoch>` dispatch tag and runs in `npm-publish`.\nReal publication also requires that tooling tag; a direct human dispatch waits\nfor its `npm-release` approval job before publishing.\nFor an already-published version,\nrequire npm `dist.integrity` and `dist.shasum` to match the verified tarball.\nTreat only missing or provably older dist-tags as repairable; newer or\nincomparable selectors are a blocker.\n\n## New Testbox Harness Plan\n\nIf more certainty is needed, add or run a `plugin-lifecycle-matrix` Docker lane\nthat uses one package tarball and sharded plugin lists. Per plugin:\n\n1. Start with a clean `HOME`.\n2. Capture `plugins list --json`.\n3. `plugins install \u003Cid>`.\n4. `plugins inspect \u003Cid> --json`.\n5. `plugins disable \u003Cid>`, then assert disabled visibility.\n6. `plugins enable \u003Cid>`, except config-required plugins without config.\n7. `plugins registry --refresh`.\n8. `doctor --non-interactive`.\n9. `plugins uninstall \u003Cid> --force`.\n10. Assert the plugin's `plugins.entries` value is exactly `{ enabled: false }`,\n    while its allow\u002Fdeny entries, install record, managed directory, and bundled\n    runtime load paths are gone. Use the existing harness's source-qualified\n    uninstall expectations for historical targets.\n11. Assert diagnostics contain no `level: \"error\"` and output redacts\n    secret-looking values.\n\nKeep `memory-lancedb` special: it is config-required. First assert install does\nnot enable it without embedding config, then run a second configured case.\n\n## Doctor\u002FFix Matrix\n\nSeed bad states and require `doctor --fix --non-interactive` to repair them,\nthen run doctor again and require idempotence:\n\n- stale `plugins.allow`\n- stale `plugins.entries`\n- stale channel config for missing channel plugin\n- invalid `plugins.entries.\u003Cid>.config`\n- packaged bundled path in `plugins.load.paths`\n- legacy `plugins.installs`\n- disabled channel\u002Fplugin config that must not stage runtime deps\n- root-owned global package tree that must remain unmodified\n\n## Gateway Bootstrap Matrix\n\nStart packaged OpenClaw in Docker with clean state:\n\n- provider plugins enabled, no credentials: ready with warnings, no crash\n- channel plugins configured disabled: no runtime deps staged\n- startup-activation plugins enabled: ready and reflected in status\n- invalid single plugin config: bad plugin skipped\u002Fquarantined, others remain\n\nAssert:\n\n- gateway reaches ready\n- `openclaw status --json` includes plugin diagnostics\n- `openclaw plugins inspect --all --json` is parseable\n- package tree is not mutated\n- logs contain no raw tokens\n\n## Config Round-Trip Representatives\n\nUse representative plugin families instead of every plugin for deep config\nround-trip:\n\n- providers: `openai`, `anthropic`, `mistral`, `openrouter`\n- channels: `telegram`, `discord`, `slack`, `whatsapp`\n- memory: `memory-lancedb`\n- feature\u002Fruntime: `browser`, `acpx`, `tokenjuice`\n\nFor each representative:\n\n1. Write config through CLI when possible.\n2. Read it back through `config get` or JSON.\n3. Run `plugins inspect`.\n4. Run `doctor --non-interactive`.\n5. Trigger gateway config reload if applicable.\n6. Compare config hash before\u002Fafter no-op commands.\n\n## External SDK Smoke\n\nIn a package Docker lane, create tiny external plugins and install them from:\n\n- local directory\n- `.tgz`\n- `file:` npm spec\n\nCover CJS and ESM shapes, plus at least one plugin importing focused\n`openclaw\u002Fplugin-sdk\u002F*` subpaths. Assert `plugins inspect` sees its tool,\ngateway method, CLI command, or service.\n\n## Live-Ish Probe Rules\n\nBefore live-ish work, source allowed env in Testbox and generate a redacted\navailability matrix: present\u002Fmissing only, never values.\n\nOnly run probes for credentials that exist. Prefer auth\u002Fcatalog\u002Fstatus probes\nover sending user-visible messages. If a probe might contact an external user,\nchannel, or workspace, stop and ask the user.\n\n## Reporting\n\nReport in this shape:\n\n```text\npackage\u002Fref:\ntbx ids \u002F run urls:\nmatrix:\n  bundled lifecycle:\n  package acceptance:\n  doctor\u002Ffix:\n  gateway bootstrap:\n  config round-trip:\n  sdk external:\n  live-ish:\nfailures:\nskips:\nnext highest-value gap:\n```\n\nSay clearly when a failure is Testbox sync\u002Fenv damage rather than product\nbehavior, and prove that with a clean rerun or current-main comparison.\n",{"name":5,"description":7},"main","f1c93577085244aa96aa87b53a2df9b59d293bd7",".agents\u002Fskills\u002Frelease-openclaw-plugin-testing",82862,"https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw","https:\u002F\u002Fopenclaw.ai","https:\u002F\u002Fgithub.com\u002Fopenclaw","Your personal, open source AI assistant.","2026-11-11 08:46:30",{"source":8,"skillName":5,"commands":57,"prompt":67,"zipAvailable":68},[58,61,64],{"tool":59,"command":60},"npx","npx skills add openclaw\u002Fopenclaw --skill release-openclaw-plugin-testing",{"tool":62,"command":63},"bunx","bunx skills add openclaw\u002Fopenclaw --skill release-openclaw-plugin-testing",{"tool":65,"command":66},"pnpm","pnpm dlx skills add openclaw\u002Fopenclaw --skill release-openclaw-plugin-testing","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Frelease-openclaw-plugin-testing\u002FSKILL.md",true,[70],{"path":71,"resourceType":72,"resourceTypeDesc":73,"sizeBytes":74,"sourceHtmlUrl":75},"agents\u002Fopenai.yaml","REFERENCE","参考文档",299,"https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Frelease-openclaw-plugin-testing\u002Fagents\u002Fopenai.yaml",[77,83,106,124,146,168],{"skillNo":78,"name":79,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":80,"categories":81,"keywords":82,"publishedAt":42},"01M698VP84FNM6G9MR1HPX7MF7","lobster","https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002Fextensions\u002Flobster\u002FSKILL.md",[],[79],{"skillNo":84,"name":85,"nameZh":6,"description":86,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":87,"categories":88,"keywords":89,"publishedAt":42},"01M698YY8QGQ7S8TJNKJG6VTPH","xurl","xurl CLI for authenticated X posts, replies, reads\u002Fsearch, DMs, media upload, followers, auth status, or raw v2 API calls.","https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002Fskills\u002Fxurl\u002FSKILL.md",[],[85,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105],"for","api","calls","replies","posts","upload","tap","install","brew","node","Media","search","npm","status","auth","cli",{"skillNo":107,"name":108,"nameZh":6,"description":109,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":110,"categories":111,"keywords":112,"publishedAt":42},"01M698YWT1CJ0WK88WB909R9RT","weather","Current weather and forecasts with web_fetch, falling back to wttr.in curl for locations, rain, temperature, travel planning.","https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002Fskills\u002Fweather\u002FSKILL.md",[],[108,113,114,97,115,98,116,117,118,119,120,121,90,122,123],"travel planning","travel","fetch","curl","https","help","planning","web","back","temperature","with",{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":135,"publishedAt":42},"01M698YV2Q0R0JJKAWGFS21K0N","visualize","Create inline visuals for code and explanations, or author persistent OpenClaw dashboard widgets with show_widget.","https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002Fskills\u002Fvisualize\u002FSKILL.md",[130],{"categoryNo":131,"categoryName":132,"taxonomyType":133,"taxonomyTypeDesc":134},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[126,136,137,138,139,90,123,140,141,142,143,144,9,145],"widgets","openclaw dashboard","author","inline","show","code","create","visuals","dashboard","widget",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":150,"categories":151,"keywords":158,"publishedAt":42},"01M698YS2TRJH9ENG28HD9CD87","trello","Manage Trello boards, lists, and cards via the Trello REST API.","https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002Fskills\u002Ftrello\u002FSKILL.md",[152,155],{"categoryNo":153,"categoryName":154,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":156,"categoryName":157,"taxonomyType":133,"taxonomyTypeDesc":134},"01JBSEEDCAT000000000000030","开发工程师",[148,117,159,160,161,162,163,164,97,98,165,116,91,166,167],"cloud","manage","via","rest api","token","atlassian","jq","REST","developer",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":172,"categories":173,"keywords":174,"publishedAt":42},"01M698YQ9Q3M4W78EWV2KSCSVW","tmux","Control tmux sessions\u002Fpanes for interactive CLIs: list, capture output, send keys, paste text, monitor prompts.","https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002Fskills\u002Ftmux\u002FSKILL.md",[],[170,97,175,176,90,177,178,179,180,181,182,183,98,184,185,186,187,188,189],"send","darwin","keys","paste","output","control","prompts","interactive","list","capture","panes","text","monitor","sessions","linux"]