[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CS3PPX808R7P6GG7XPA0ZP":3,"skill-same:01M6CS3PPX808R7P6GG7XPA0ZP":80},{"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":34,"publishedAt":52,"linkOnly":53,"markdownContent":54,"markdownBody":55,"frontMatter":56,"refName":57,"commitSha":58,"skillDirectory":59,"forksCount":60,"repositoryHtmlUrl":61,"repositoryHomepageUrl":6,"ownerHtmlUrl":62,"ownerBlogUrl":63,"ownerDescription":64,"updatedAt":65,"install":66,"resources":79},"01M6CS3PPX808R7P6GG7XPA0ZP","testing",null,"Test conventions, harness API, and readability rules for the Ghost codebase. MUST READ before writing or modifying any test — unit tests, integration tests, or live tests. Covers: test helper functions (test_config, test_workspace, test_database), MockProvider, LiveTestEnv, live test isolation rules, and the non-negotiable readability requirements. For step-based end-to-end tests, also read the `e2e-testing` skill. Failure to read this will produce duplicated boilerplate and broken test isolation.","mrtolkien\u002FGHOST","mrtolkien","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F8489650?v=4","01M6CS32Q934XBQQE8BDV5Z6W2","Tolki","01M6CS32VBCD47F5E27WF9W6FC",5,"MIT","https:\u002F\u002Fgithub.com\u002Fmrtolkien\u002FGHOST\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Ftesting\u002FSKILL.md",[18,23,26,29],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[5,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],"integration","functions","read","broken","Rules","workspace","ghost","api","e2e","produce","database","harness","config","unit tests","integration tests","test","writing","2026-11-10 10:12:30",false,"---\nname: testing\ndescription: >-\n  Test conventions, harness API, and readability rules for the Ghost codebase. MUST READ\n  before writing or modifying any test — unit tests, integration tests, or live tests.\n  Covers: test helper functions (test_config, test_workspace, test_database),\n  MockProvider, LiveTestEnv, live test isolation rules, and the non-negotiable\n  readability requirements. For step-based end-to-end tests, also read the `e2e-testing`\n  skill. Failure to read this will produce duplicated boilerplate and broken test\n  isolation.\n---\n\n# Testing Conventions\n\n## Strategy\n\n- **Integration tests** with a `live-tests` feature flag for all major features.\n- Maintain robust, reusable test fixtures shared across tests.\n- **Unit tests** only for genuinely complex behaviors or external crate behaviors.\n- Live tests (`--features live-tests`) are human-run only. Ask the user before running\n  them.\n\n## Live Test Assertions (NON-NEGOTIABLE)\n\nLive test assertions encode real quality requirements. **NEVER weaken, remove, or relax\nassertions to make a flaky test pass.** If the test fails, fix the agent behavior\n(prompt, nudges, tool loop, context management) — not the test.\n\nSee `memory\u002Fdeep-research-agent.md` for the full iteration history, known failure modes,\nand nudge architecture for the deep research agent specifically.\n\nFor step-based e2e fixture\u002Flog tooling, use `uv run scripts\u002Fe2e` and select the\noperation (`refresh`, `render-log`, `diff`, `analyze-request`).\n\n## Live Test Isolation (NON-NEGOTIABLE)\n\nLive tests must **never** load data from the user's real workspace (`~\u002FGHOST\u002F`). Always\nuse `LiveTestEnv` which provides a fresh temp workspace with repo-current agent\ndefinitions (via `include_str!` + `install_default_agents()`). The real workspace may\ncontain stale agent prompts referencing deleted tools.\n\n## Test Readability (NON-NEGOTIABLE)\n\nTests must be **readable first**. A reader should understand what a test does in\nseconds, not minutes.\n\n- Extract ALL setup boilerplate into helper functions. A test body should be setup +\n  action + assert, each in 1–3 lines.\n- Prefer `let workspace = test_workspace()` over 15 lines of `TempDir` + `fs::write` +\n  `env::set_var` inline.\n- Name helpers after what they produce, not what they do: `test_config()` not\n  `setup_config_dir_and_write_toml_and_set_env()`.\n- Never duplicate setup across tests — if two tests need similar state, extract a\n  helper.\n- Extend existing helpers with parameters rather than creating new ones. If\n  `test_config()` works for most tests but one needs a custom model, add an optional\n  parameter — don't write `test_config_with_custom_model()`.\n- Every test should read like a specification.\n\n## Test Harness API\n\nAll reusable infrastructure lives in `tests\u002Fcommon.rs`.\n\n### Non-Live Helpers (always available)\n\n| Helper                                                      | Purpose                                                            |\n| ----------------------------------------------------------- | ------------------------------------------------------------------ |\n| `test_config()`                                             | Temp config + workspace dirs, returns `(Config, TempDir, TempDir)` |\n| `test_workspace()`                                          | `test_config()` + bootstrapped workspace                           |\n| `test_database()`                                           | `test_workspace()` + connected SQLite                              |\n| `write_test_note(workspace, title, body)`                   | Write a note file with frontmatter                                 |\n| `write_test_reference(workspace, topic, filename, content)` | Write a reference file                                             |\n\n### Mock Types (always available)\n\n| Type\u002FFunction                          | Purpose                                                    |\n| -------------------------------------- | ---------------------------------------------------------- |\n| `MockProvider`                         | Queued `ChatResponse` provider; records all `ChatRequest`s |\n| `MockProvider::requests()`             | Access recorded requests for assertion                     |\n| `EchoTool`                             | Simple tool that returns `echo:{text}`                     |\n| `response(content, stop_reason)`       | Build a `ChatResponse`                                     |\n| `respond_response(message, citations)` | Build a response that calls the `respond` tool             |\n\n### Live Test Helpers (`#[cfg(feature = \"live-tests\")]`)\n\nCreated via `let env = live_test_database(\"test_name\").await;`\n\n`LiveTestEnv` uses the real `~\u002F.config\u002Fghost\u002Fconfig.toml` (with real API keys) but\ncreates a fresh temp workspace and database.\n\n#### Session Helpers\n\n| Method                                              | Purpose                                |\n| --------------------------------------------------- | -------------------------------------- |\n| `env.create_session()`                              | Create a bare session, returns `Thing` |\n| `env.session_with_messages(&[(\"role\", \"content\")])` | Session with pre-filled messages       |\n\n#### Chat Helpers\n\n| Method       | Purpose                                       |\n| ------------ | --------------------------------------------- |\n| `env.chat()` | `SessionChat` with real provider + chat tools |\n\n#### Job Runners\n\n| Method                                    | Purpose                                                      |\n| ----------------------------------------- | ------------------------------------------------------------ |\n| `env.run_reflection(&session_id, &agent)` | Load + run reflection agent, returns `(String, RunMetadata)` |\n\n#### Completion \u002F Background Helpers\n\n| Method                                                               | Purpose                                        |\n| -------------------------------------------------------------------- | ---------------------------------------------- |\n| `env.chat_with_completion_watcher()`                                 | `SessionChat` with completion watcher enabled  |\n| `env.wait_for_continuation_response(&session_id, since_count, secs)` | Wait for background task continuation response |\n| `env.wait_for_agents(&session_id, timeout_secs)`                     | Wait for agent tasks to complete               |\n| `env.wait_for_system_message(&session_id, pattern, timeout_secs)`    | Wait for system message matching pattern       |\n| `env.stop_all_agents()`                                              | Stop all running agents, returns count         |\n| `env.stop_and_reset_agent(&agent_id)`                                | Stop and reset a specific agent                |\n\n#### Agent Helpers\n\n| Method                   | Purpose                                                       |\n| ------------------------ | ------------------------------------------------------------- |\n| `env.load_agent(\"name\")` | Load agent definition from temp workspace (repo-current copy) |\n\n#### Assertion Helpers\n\n| Method                                                              | Purpose                                                 |\n| ------------------------------------------------------------------- | ------------------------------------------------------- |\n| `env.workspace_file_exists(\"relative\u002Fpath\")`                        | Check file exists in temp workspace                     |\n| `env.read_workspace_file(\"relative\u002Fpath\")`                          | Read file content from temp workspace                   |\n| `env.list_notes()`                                                  | List all files under `knowledge\u002Fnotes\u002F`                 |\n| `env.list_references()`                                             | List all files under `knowledge\u002Freferences\u002F`            |\n| `env.find_file_containing(\"subdir\", \"needle\")`                      | Recursive content search under a workspace subdir       |\n| `env.collect_tool_calls(&session_id)`                               | Collect all tool calls from session                     |\n| `env.collect_web_fetch_metrics(&session_id)`                        | Gather web fetch statistics                             |\n| `env.assert_research_quality(findings, metrics, domains, keywords)` | Assert research quality markers                         |\n| `env.assert_notes_contain_any(&[needles], description)`             | Assert workspace notes contain any of specified strings |\n| `env.assert_diary_exists()`                                         | Returns diary content if it exists                      |\n| `env.workspace_path()`                                              | Returns workspace directory path                        |\n\n#### Diagnostic Logging\n\n| Method                                             | Purpose                                                       |\n| -------------------------------------------------- | ------------------------------------------------------------- |\n| `env.log_session_json(\"label\", &session_id)`       | Dump all messages from a session into the diagnostic log      |\n| `env.log_session_json_since(\"label\", &session_id)` | Logs messages added since last `log_session_json` for session |\n| `env.collect_session_json(&session_id)`            | Get all session messages as JSON                              |\n| `env.log(\"custom message\")`                        | Add a note to the diagnostic log                              |\n\nOn drop, the diagnostic log is written to\n`e2e-output\u002F\u003Ctimestamp>_\u003Ctest_name>\u002Fdiagnostic.log` and printed to stderr with\n`--nocapture`.\n\n#### Transcript \u002F Snapshot Helpers\n\n| Method                                                     | Purpose                                   |\n| ---------------------------------------------------------- | ----------------------------------------- |\n| `env.session_from_transcript(&[json_values])`              | Create session from transcript JSON array |\n| `env.write_workspace_archive(path)`                        | Write workspace to tar.zst                |\n| `env.install_web_cache_fixture(&session_id, &fixture_dir)` | Install web cache fixture for a session   |\n\n### Writing a New Live Test\n\n```rust\n#[tokio::test]\nasync fn my_live_test() {\n    let env = common::live_test_database(\"my_test\").await;\n    let session = env.session_with_messages(&[\n        (\"user\", \"Hello\"),\n        (\"assistant\", \"Hi!\"),\n    ]).await;\n\n    let chat = env.chat();\n    let (result, _metadata) = chat.chat(&session, \"What is 2+2?\", None).await.unwrap();\n    env.log_session_json(\"chat\", &session).await;\n\n    assert!(!result.message.trim().is_empty());\n}\n```\n","# Testing Conventions\n\n## Strategy\n\n- **Integration tests** with a `live-tests` feature flag for all major features.\n- Maintain robust, reusable test fixtures shared across tests.\n- **Unit tests** only for genuinely complex behaviors or external crate behaviors.\n- Live tests (`--features live-tests`) are human-run only. Ask the user before running\n  them.\n\n## Live Test Assertions (NON-NEGOTIABLE)\n\nLive test assertions encode real quality requirements. **NEVER weaken, remove, or relax\nassertions to make a flaky test pass.** If the test fails, fix the agent behavior\n(prompt, nudges, tool loop, context management) — not the test.\n\nSee `memory\u002Fdeep-research-agent.md` for the full iteration history, known failure modes,\nand nudge architecture for the deep research agent specifically.\n\nFor step-based e2e fixture\u002Flog tooling, use `uv run scripts\u002Fe2e` and select the\noperation (`refresh`, `render-log`, `diff`, `analyze-request`).\n\n## Live Test Isolation (NON-NEGOTIABLE)\n\nLive tests must **never** load data from the user's real workspace (`~\u002FGHOST\u002F`). Always\nuse `LiveTestEnv` which provides a fresh temp workspace with repo-current agent\ndefinitions (via `include_str!` + `install_default_agents()`). The real workspace may\ncontain stale agent prompts referencing deleted tools.\n\n## Test Readability (NON-NEGOTIABLE)\n\nTests must be **readable first**. A reader should understand what a test does in\nseconds, not minutes.\n\n- Extract ALL setup boilerplate into helper functions. A test body should be setup +\n  action + assert, each in 1–3 lines.\n- Prefer `let workspace = test_workspace()` over 15 lines of `TempDir` + `fs::write` +\n  `env::set_var` inline.\n- Name helpers after what they produce, not what they do: `test_config()` not\n  `setup_config_dir_and_write_toml_and_set_env()`.\n- Never duplicate setup across tests — if two tests need similar state, extract a\n  helper.\n- Extend existing helpers with parameters rather than creating new ones. If\n  `test_config()` works for most tests but one needs a custom model, add an optional\n  parameter — don't write `test_config_with_custom_model()`.\n- Every test should read like a specification.\n\n## Test Harness API\n\nAll reusable infrastructure lives in `tests\u002Fcommon.rs`.\n\n### Non-Live Helpers (always available)\n\n| Helper                                                      | Purpose                                                            |\n| ----------------------------------------------------------- | ------------------------------------------------------------------ |\n| `test_config()`                                             | Temp config + workspace dirs, returns `(Config, TempDir, TempDir)` |\n| `test_workspace()`                                          | `test_config()` + bootstrapped workspace                           |\n| `test_database()`                                           | `test_workspace()` + connected SQLite                              |\n| `write_test_note(workspace, title, body)`                   | Write a note file with frontmatter                                 |\n| `write_test_reference(workspace, topic, filename, content)` | Write a reference file                                             |\n\n### Mock Types (always available)\n\n| Type\u002FFunction                          | Purpose                                                    |\n| -------------------------------------- | ---------------------------------------------------------- |\n| `MockProvider`                         | Queued `ChatResponse` provider; records all `ChatRequest`s |\n| `MockProvider::requests()`             | Access recorded requests for assertion                     |\n| `EchoTool`                             | Simple tool that returns `echo:{text}`                     |\n| `response(content, stop_reason)`       | Build a `ChatResponse`                                     |\n| `respond_response(message, citations)` | Build a response that calls the `respond` tool             |\n\n### Live Test Helpers (`#[cfg(feature = \"live-tests\")]`)\n\nCreated via `let env = live_test_database(\"test_name\").await;`\n\n`LiveTestEnv` uses the real `~\u002F.config\u002Fghost\u002Fconfig.toml` (with real API keys) but\ncreates a fresh temp workspace and database.\n\n#### Session Helpers\n\n| Method                                              | Purpose                                |\n| --------------------------------------------------- | -------------------------------------- |\n| `env.create_session()`                              | Create a bare session, returns `Thing` |\n| `env.session_with_messages(&[(\"role\", \"content\")])` | Session with pre-filled messages       |\n\n#### Chat Helpers\n\n| Method       | Purpose                                       |\n| ------------ | --------------------------------------------- |\n| `env.chat()` | `SessionChat` with real provider + chat tools |\n\n#### Job Runners\n\n| Method                                    | Purpose                                                      |\n| ----------------------------------------- | ------------------------------------------------------------ |\n| `env.run_reflection(&session_id, &agent)` | Load + run reflection agent, returns `(String, RunMetadata)` |\n\n#### Completion \u002F Background Helpers\n\n| Method                                                               | Purpose                                        |\n| -------------------------------------------------------------------- | ---------------------------------------------- |\n| `env.chat_with_completion_watcher()`                                 | `SessionChat` with completion watcher enabled  |\n| `env.wait_for_continuation_response(&session_id, since_count, secs)` | Wait for background task continuation response |\n| `env.wait_for_agents(&session_id, timeout_secs)`                     | Wait for agent tasks to complete               |\n| `env.wait_for_system_message(&session_id, pattern, timeout_secs)`    | Wait for system message matching pattern       |\n| `env.stop_all_agents()`                                              | Stop all running agents, returns count         |\n| `env.stop_and_reset_agent(&agent_id)`                                | Stop and reset a specific agent                |\n\n#### Agent Helpers\n\n| Method                   | Purpose                                                       |\n| ------------------------ | ------------------------------------------------------------- |\n| `env.load_agent(\"name\")` | Load agent definition from temp workspace (repo-current copy) |\n\n#### Assertion Helpers\n\n| Method                                                              | Purpose                                                 |\n| ------------------------------------------------------------------- | ------------------------------------------------------- |\n| `env.workspace_file_exists(\"relative\u002Fpath\")`                        | Check file exists in temp workspace                     |\n| `env.read_workspace_file(\"relative\u002Fpath\")`                          | Read file content from temp workspace                   |\n| `env.list_notes()`                                                  | List all files under `knowledge\u002Fnotes\u002F`                 |\n| `env.list_references()`                                             | List all files under `knowledge\u002Freferences\u002F`            |\n| `env.find_file_containing(\"subdir\", \"needle\")`                      | Recursive content search under a workspace subdir       |\n| `env.collect_tool_calls(&session_id)`                               | Collect all tool calls from session                     |\n| `env.collect_web_fetch_metrics(&session_id)`                        | Gather web fetch statistics                             |\n| `env.assert_research_quality(findings, metrics, domains, keywords)` | Assert research quality markers                         |\n| `env.assert_notes_contain_any(&[needles], description)`             | Assert workspace notes contain any of specified strings |\n| `env.assert_diary_exists()`                                         | Returns diary content if it exists                      |\n| `env.workspace_path()`                                              | Returns workspace directory path                        |\n\n#### Diagnostic Logging\n\n| Method                                             | Purpose                                                       |\n| -------------------------------------------------- | ------------------------------------------------------------- |\n| `env.log_session_json(\"label\", &session_id)`       | Dump all messages from a session into the diagnostic log      |\n| `env.log_session_json_since(\"label\", &session_id)` | Logs messages added since last `log_session_json` for session |\n| `env.collect_session_json(&session_id)`            | Get all session messages as JSON                              |\n| `env.log(\"custom message\")`                        | Add a note to the diagnostic log                              |\n\nOn drop, the diagnostic log is written to\n`e2e-output\u002F\u003Ctimestamp>_\u003Ctest_name>\u002Fdiagnostic.log` and printed to stderr with\n`--nocapture`.\n\n#### Transcript \u002F Snapshot Helpers\n\n| Method                                                     | Purpose                                   |\n| ---------------------------------------------------------- | ----------------------------------------- |\n| `env.session_from_transcript(&[json_values])`              | Create session from transcript JSON array |\n| `env.write_workspace_archive(path)`                        | Write workspace to tar.zst                |\n| `env.install_web_cache_fixture(&session_id, &fixture_dir)` | Install web cache fixture for a session   |\n\n### Writing a New Live Test\n\n```rust\n#[tokio::test]\nasync fn my_live_test() {\n    let env = common::live_test_database(\"my_test\").await;\n    let session = env.session_with_messages(&[\n        (\"user\", \"Hello\"),\n        (\"assistant\", \"Hi!\"),\n    ]).await;\n\n    let chat = env.chat();\n    let (result, _metadata) = chat.chat(&session, \"What is 2+2?\", None).await.unwrap();\n    env.log_session_json(\"chat\", &session).await;\n\n    assert!(!result.message.trim().is_empty());\n}\n```\n",{"name":5,"description":7},"main","083d96429a2d05526f8a294b83c74f0336670def",".agents\u002Fskills\u002Ftesting",0,"https:\u002F\u002Fgithub.com\u002Fmrtolkien\u002FGHOST","https:\u002F\u002Fgithub.com\u002Fmrtolkien","https:\u002F\u002Fblog.tolki.dev","Data Engineer \u002F Esports \u002F Keyboards","2026-04-24 15:41:08",{"source":8,"skillName":5,"commands":67,"prompt":77,"zipAvailable":78},[68,71,74],{"tool":69,"command":70},"npx","npx skills add mrtolkien\u002FGHOST --skill testing",{"tool":72,"command":73},"bunx","bunx skills add mrtolkien\u002FGHOST --skill testing",{"tool":75,"command":76},"pnpm","pnpm dlx skills add mrtolkien\u002FGHOST --skill testing","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmrtolkien\u002FGHOST\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Ftesting\u002FSKILL.md",true,[],[81,106,121,139,148,158],{"skillNo":82,"name":83,"nameZh":6,"description":84,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":87,"publishedAt":52},"01M6CS613RWD9CFJ3KFX47V1DS","system-management","Use when reading or changing GHOST configuration (providers, models, timing, compaction, services, any config.toml key), adding or switching LLM providers, answering questions about GHOST's own features or capabilities, a CLI tool is missing or \"not found\", services need starting\u002Fstopping\u002Fdebugging, updating GHOST to a newer version, managing the Nix shell environment, or troubleshooting GHOST setup.","https:\u002F\u002Fgithub.com\u002Fmrtolkien\u002FGHOST\u002Fblob\u002Fmain\u002Fassets\u002Fskills\u002Fsystem-management\u002Fskill.md",[],[88,89,90,91,92,93,47,94,95,96,97,98,41,99,100,101,102,103,104,105],"system management","management","system","shell","cli","nix","setup","debugging","capabilities","services","Providers","tool","troubleshooting","environment","use","version","models","configuration",{"skillNo":107,"name":108,"nameZh":6,"description":109,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":110,"categories":111,"keywords":115,"publishedAt":52},"01M6CS5XTK2884R9HE15YR8YZM","writing-skills","Use when creating new skills, editing existing skills, or verifying skills work before deployment","https:\u002F\u002Fgithub.com\u002Fmrtolkien\u002FGHOST\u002Fblob\u002Fmain\u002Fassets\u002Fskills\u002Fsuperpowers\u002Fwriting-skills\u002Fskill.md",[112,113,114],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},[116,51,117,118,119,102,120],"writing skills","coding","work","editing","deployment",{"skillNo":122,"name":123,"nameZh":6,"description":124,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":129,"publishedAt":52},"01M6CS5V737R1DVB3TZEK0C6WT","writing-plans","Use when you have a spec or requirements for a multi-step task, before touching code. Write comprehensive implementation plans assuming the engineer has zero context for our codebase and questionable taste.","https:\u002F\u002Fgithub.com\u002Fmrtolkien\u002FGHOST\u002Fblob\u002Fmain\u002Fassets\u002Fskills\u002Fsuperpowers\u002Fwriting-plans\u002Fskill.md",[127,128],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},[130,51,131,132,133,117,134,135,102,136,137,138],"writing plans","spec","code","ZeRO","write","context","engineer","implementation","task",{"skillNo":140,"name":141,"nameZh":6,"description":142,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":143,"categories":144,"keywords":145,"publishedAt":52},"01M6CS5S5S0YY56686G5CQ0WMP","verification","Use when about to claim work is complete, fixed, or passing, before committing or creating PRs. Requires running verification commands and confirming output before making any success claims. Evidence before assertions, always.","https:\u002F\u002Fgithub.com\u002Fmrtolkien\u002FGHOST\u002Fblob\u002Fmain\u002Fassets\u002Fskills\u002Fsuperpowers\u002Fverification\u002Fskill.md",[],[141,117,118,102,146,147],"evidence","claim",{"skillNo":149,"name":150,"nameZh":6,"description":151,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":152,"categories":153,"keywords":155,"publishedAt":52},"01M6CS5PD2ZSFWYRDZSACNTAJY","tdd","Use when implementing any feature or bugfix, before writing implementation code. Write the test first. Watch it fail. Write minimal code to pass.","https:\u002F\u002Fgithub.com\u002Fmrtolkien\u002FGHOST\u002Fblob\u002Fmain\u002Fassets\u002Fskills\u002Fsuperpowers\u002Ftdd\u002Fskill.md",[154],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[150,51,132,156,117,134,102,157,137,50],"first","minimal",{"skillNo":159,"name":160,"nameZh":6,"description":161,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":162,"categories":163,"keywords":165,"publishedAt":52},"01M6CS5K5WE2SHF1YV8D9C4C77","systematic-debugging","Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes","https:\u002F\u002Fgithub.com\u002Fmrtolkien\u002FGHOST\u002Fblob\u002Fmain\u002Fassets\u002Fskills\u002Fsuperpowers\u002Fsystematic-debugging\u002Fskill.md",[164],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[166,95,167,102,117,50,168],"systematic debugging","behavior","bug"]