[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CS3SRT5Y62DVWWRVVRHNEE":3,"skill-same:01M6CS3SRT5Y62DVWWRVVRHNEE":55},{"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":27,"linkOnly":28,"markdownContent":29,"markdownBody":30,"frontMatter":31,"refName":32,"commitSha":33,"skillDirectory":34,"forksCount":35,"repositoryHtmlUrl":36,"repositoryHomepageUrl":6,"ownerHtmlUrl":37,"ownerBlogUrl":38,"ownerDescription":39,"updatedAt":40,"install":41,"resources":54},"01M6CS3SRT5Y62DVWWRVVRHNEE","tracing",null,"Tracing, observability, and instrumentation conventions for the Ghost codebase. MUST READ before adding or modifying: tracing spans, #[tracing::instrument] attributes, tracing::info_span!() calls, OTel semantic convention fields (gen_ai.*), span hierarchy, or any observability-related code. Failure to follow these conventions produces inconsistent telemetry.","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\u002Ftracing\u002FSKILL.md",[],[5,19,20,21,22,23,24,25,26],"otel","telemetry","code","observability","ghost","read","instrumentation","info","2026-11-10 10:12:30",false,"---\nname: tracing\ndescription: >-\n  Tracing, observability, and instrumentation conventions for the Ghost codebase. MUST\n  READ before adding or modifying: tracing spans, #[tracing::instrument] attributes,\n  tracing::info_span!() calls, OTel semantic convention fields (gen_ai.*), span\n  hierarchy, or any observability-related code. Failure to follow these conventions\n  produces inconsistent telemetry.\n---\n\n# Observability Conventions (NON-NEGOTIABLE)\n\nInstrument meaningful execution boundaries, not every function. Prioritize: provider API\ncalls, tool executions, agent\u002Fjob entry points, DB mutations, and embedding ops. Keep\nsmall helpers and pure functions uninstrumented.\n\n## Span Naming — `{verb} {object}`, Low Cardinality\n\nSource: https:\u002F\u002Fopentelemetry.io\u002Fblog\u002F2025\u002Fhow-to-name-your-spans\u002F\n\nFollow the OTel-recommended **`{verb} {object}`** pattern for all span names. The verb\ndescribes the action; the object describes what is acted upon. This keeps span names\n**low-cardinality** (aggregatable for P95 latency, dashboards, alerts).\n\n### Rules\n\n1. **Never embed run-dependent values in span names.** IDs, file paths, query strings,\n   user names, and tool names belong in **attributes**, not the span name.\n2. **Name the operation, not the outcome.** Use `validate input` — not\n   `validation_failed`. Record the outcome in span status or an attribute.\n3. **Keep names short and stable.** Two words is ideal. Three is the max.\n\n### Current span names\n\n| Span Name                    | Attributes (run-dependent)                                   |\n| ---------------------------- | ------------------------------------------------------------ |\n| `boot ghost`                 | —                                                            |\n| `create provider`            | `provider`, `endpoint`                                       |\n| `create session_chat`        | —                                                            |\n| `embed batch`                | `model`, `batch_size`                                        |\n| `embed source`               | `source_table`, `source_id`                                  |\n| `embed sources`              | `sources`, `embedded`, `skipped` + info event with file list |\n| `execute agent`              | `gen_ai.agent.name`, `gen_ai.agent.id`                       |\n| `execute resume`             | —                                                            |\n| `fetch url crawl4ai`         | `url`                                                        |\n| `fetch url reqwest`          | `url`                                                        |\n| `import crawl`               | `topic`                                                      |\n| `import git`                 | `topic`                                                      |\n| `import page`                | `topic`                                                      |\n| `import references`          | `source`, `topic`, `url`                                     |\n| `orchestrate response`       | `session_id`                                                 |\n| `process file_changes`       | `count`                                                      |\n| `process file_change`        | `kind`, `path`                                               |\n| `reboot session`             | `old_session_id`                                             |\n| `receive discord message`    | —                                                            |\n| `reconcile embeddings`       | —                                                            |\n| `request completion`         | `gen_ai.system`, `gen_ai.request.model`, etc.                |\n| `resume agent bg`            | `agent_id`                                                   |\n| `run lua agent`              | —                                                            |\n| `run lua agent with history` | —                                                            |\n| `run tool`                   | `gen_ai.tool.name`, `params_preview`                         |\n| `run tools`                  | —                                                            |\n| `search web`                 | `query`                                                      |\n| `send message`               | `channel_id`, `content_len`                                  |\n| `start agent`                | `gen_ai.agent.name`                                          |\n| `start scheduler`            | —                                                            |\n| `start watcher`              | —                                                            |\n\n### Bad vs Good\n\n| Bad (high cardinality)      | Good                  |\n| --------------------------- | --------------------- |\n| `tool: note_write`          | `run tool`            |\n| `watcher: note`             | `process file_change` |\n| `agent: research-agent`     | `execute agent`       |\n| `openai_compatible.request` | `request completion`  |\n| `ghost.startup`             | `boot ghost`          |\n\n## OTel GenAI Semantic Conventions (Mandatory for Provider Calls)\n\nSource: https:\u002F\u002Fopentelemetry.io\u002Fdocs\u002Fspecs\u002Fsemconv\u002Fregistry\u002Fattributes\u002Fgen-ai\u002F\n\nAll LLM provider calls must record these fields on the `request completion` span:\n\n- `gen_ai.system` — provider name (e.g. `openrouter`)\n- `gen_ai.operation.name` — always `\"chat\"`\n- `gen_ai.request.model` — model ID sent in the request\n- `gen_ai.response.model` — model ID returned by the provider\n- `gen_ai.response.id` — response identifier\n- `gen_ai.response.finish_reasons` — stop reason\n- `gen_ai.usage.input_tokens` \u002F `gen_ai.usage.output_tokens`\n- `gen_ai.usage.cache_read_input_tokens` \u002F `gen_ai.usage.cache_creation_input_tokens`\n\n## Span Hierarchy — Keep It Shallow (2-3 Levels Max)\n\n- `receive discord message` -> `orchestrate response` -> `request completion` \u002F\n  `run tool`\n- `execute agent` \u002F `run lua agent` -> `request completion` \u002F `run tool`\n- `boot ghost` -> `start scheduler` \u002F `start watcher` \u002F `create provider`\n- Never wrap a single delegation call in a span\n\n## Implementation Rules\n\n- Use `#[tracing::instrument(name = \"verb object\", skip_all, fields(key = %val))]` —\n  always set an explicit `name` on info-level spans at execution boundaries\n- Use `tracing::info_span!(\"verb object\", key = val)` for programmatic spans — **never\n  interpolate dynamic values into the span name string**\n- Use `tracing::Span::current().record()` to fill response fields at span completion\n- Use `tracing::info!()` \u002F `warn!()` \u002F `error!()` for discrete events within spans\n- Do not duplicate information between a span and a child log event\n- Log all errors with full context before propagating\n- Provider request\u002Fresponse bodies: logged as `gen_ai.input.messages` \u002F\n  `gen_ai.output.messages` at info level inside `request completion` spans\n- Debug-level DB\u002Finternal spans may omit `name =` (function name default is fine)\n- OTLP export is conditional on the `OTEL_EXPORTER_OTLP_ENDPOINT` env var — when unset,\n  tracing emits to stderr only (no spans are exported)\n- Default RUST_LOG:\n  `warn,ghost=info,chromiumoxide=error,usvg=off,resvg=off,fontdb=off,html5ever=off`\n","# Observability Conventions (NON-NEGOTIABLE)\n\nInstrument meaningful execution boundaries, not every function. Prioritize: provider API\ncalls, tool executions, agent\u002Fjob entry points, DB mutations, and embedding ops. Keep\nsmall helpers and pure functions uninstrumented.\n\n## Span Naming — `{verb} {object}`, Low Cardinality\n\nSource: https:\u002F\u002Fopentelemetry.io\u002Fblog\u002F2025\u002Fhow-to-name-your-spans\u002F\n\nFollow the OTel-recommended **`{verb} {object}`** pattern for all span names. The verb\ndescribes the action; the object describes what is acted upon. This keeps span names\n**low-cardinality** (aggregatable for P95 latency, dashboards, alerts).\n\n### Rules\n\n1. **Never embed run-dependent values in span names.** IDs, file paths, query strings,\n   user names, and tool names belong in **attributes**, not the span name.\n2. **Name the operation, not the outcome.** Use `validate input` — not\n   `validation_failed`. Record the outcome in span status or an attribute.\n3. **Keep names short and stable.** Two words is ideal. Three is the max.\n\n### Current span names\n\n| Span Name                    | Attributes (run-dependent)                                   |\n| ---------------------------- | ------------------------------------------------------------ |\n| `boot ghost`                 | —                                                            |\n| `create provider`            | `provider`, `endpoint`                                       |\n| `create session_chat`        | —                                                            |\n| `embed batch`                | `model`, `batch_size`                                        |\n| `embed source`               | `source_table`, `source_id`                                  |\n| `embed sources`              | `sources`, `embedded`, `skipped` + info event with file list |\n| `execute agent`              | `gen_ai.agent.name`, `gen_ai.agent.id`                       |\n| `execute resume`             | —                                                            |\n| `fetch url crawl4ai`         | `url`                                                        |\n| `fetch url reqwest`          | `url`                                                        |\n| `import crawl`               | `topic`                                                      |\n| `import git`                 | `topic`                                                      |\n| `import page`                | `topic`                                                      |\n| `import references`          | `source`, `topic`, `url`                                     |\n| `orchestrate response`       | `session_id`                                                 |\n| `process file_changes`       | `count`                                                      |\n| `process file_change`        | `kind`, `path`                                               |\n| `reboot session`             | `old_session_id`                                             |\n| `receive discord message`    | —                                                            |\n| `reconcile embeddings`       | —                                                            |\n| `request completion`         | `gen_ai.system`, `gen_ai.request.model`, etc.                |\n| `resume agent bg`            | `agent_id`                                                   |\n| `run lua agent`              | —                                                            |\n| `run lua agent with history` | —                                                            |\n| `run tool`                   | `gen_ai.tool.name`, `params_preview`                         |\n| `run tools`                  | —                                                            |\n| `search web`                 | `query`                                                      |\n| `send message`               | `channel_id`, `content_len`                                  |\n| `start agent`                | `gen_ai.agent.name`                                          |\n| `start scheduler`            | —                                                            |\n| `start watcher`              | —                                                            |\n\n### Bad vs Good\n\n| Bad (high cardinality)      | Good                  |\n| --------------------------- | --------------------- |\n| `tool: note_write`          | `run tool`            |\n| `watcher: note`             | `process file_change` |\n| `agent: research-agent`     | `execute agent`       |\n| `openai_compatible.request` | `request completion`  |\n| `ghost.startup`             | `boot ghost`          |\n\n## OTel GenAI Semantic Conventions (Mandatory for Provider Calls)\n\nSource: https:\u002F\u002Fopentelemetry.io\u002Fdocs\u002Fspecs\u002Fsemconv\u002Fregistry\u002Fattributes\u002Fgen-ai\u002F\n\nAll LLM provider calls must record these fields on the `request completion` span:\n\n- `gen_ai.system` — provider name (e.g. `openrouter`)\n- `gen_ai.operation.name` — always `\"chat\"`\n- `gen_ai.request.model` — model ID sent in the request\n- `gen_ai.response.model` — model ID returned by the provider\n- `gen_ai.response.id` — response identifier\n- `gen_ai.response.finish_reasons` — stop reason\n- `gen_ai.usage.input_tokens` \u002F `gen_ai.usage.output_tokens`\n- `gen_ai.usage.cache_read_input_tokens` \u002F `gen_ai.usage.cache_creation_input_tokens`\n\n## Span Hierarchy — Keep It Shallow (2-3 Levels Max)\n\n- `receive discord message` -> `orchestrate response` -> `request completion` \u002F\n  `run tool`\n- `execute agent` \u002F `run lua agent` -> `request completion` \u002F `run tool`\n- `boot ghost` -> `start scheduler` \u002F `start watcher` \u002F `create provider`\n- Never wrap a single delegation call in a span\n\n## Implementation Rules\n\n- Use `#[tracing::instrument(name = \"verb object\", skip_all, fields(key = %val))]` —\n  always set an explicit `name` on info-level spans at execution boundaries\n- Use `tracing::info_span!(\"verb object\", key = val)` for programmatic spans — **never\n  interpolate dynamic values into the span name string**\n- Use `tracing::Span::current().record()` to fill response fields at span completion\n- Use `tracing::info!()` \u002F `warn!()` \u002F `error!()` for discrete events within spans\n- Do not duplicate information between a span and a child log event\n- Log all errors with full context before propagating\n- Provider request\u002Fresponse bodies: logged as `gen_ai.input.messages` \u002F\n  `gen_ai.output.messages` at info level inside `request completion` spans\n- Debug-level DB\u002Finternal spans may omit `name =` (function name default is fine)\n- OTLP export is conditional on the `OTEL_EXPORTER_OTLP_ENDPOINT` env var — when unset,\n  tracing emits to stderr only (no spans are exported)\n- Default RUST_LOG:\n  `warn,ghost=info,chromiumoxide=error,usvg=off,resvg=off,fontdb=off,html5ever=off`\n",{"name":5,"description":7},"main","083d96429a2d05526f8a294b83c74f0336670def",".agents\u002Fskills\u002Ftracing",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":42,"prompt":52,"zipAvailable":53},[43,46,49],{"tool":44,"command":45},"npx","npx skills add mrtolkien\u002FGHOST --skill tracing",{"tool":47,"command":48},"bunx","bunx skills add mrtolkien\u002FGHOST --skill tracing",{"tool":50,"command":51},"pnpm","pnpm dlx skills add mrtolkien\u002FGHOST --skill tracing","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmrtolkien\u002FGHOST\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Ftracing\u002FSKILL.md",true,[],[56,82,108,125,134,145],{"skillNo":57,"name":58,"nameZh":6,"description":59,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":60,"categories":61,"keywords":62,"publishedAt":27},"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",[],[63,64,65,66,67,68,69,70,71,72,73,74,23,75,76,77,78,79,80,81],"system management","management","system","shell","cli","nix","config","setup","debugging","capabilities","services","Providers","tool","troubleshooting","environment","use","version","models","configuration",{"skillNo":83,"name":84,"nameZh":6,"description":85,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":86,"categories":87,"keywords":101,"publishedAt":27},"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",[88,93,96],{"categoryNo":89,"categoryName":90,"taxonomyType":91,"taxonomyTypeDesc":92},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":94,"categoryName":95,"taxonomyType":91,"taxonomyTypeDesc":92},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":97,"categoryName":98,"taxonomyType":99,"taxonomyTypeDesc":100},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[102,103,104,105,106,78,107],"writing skills","writing","coding","work","editing","deployment",{"skillNo":109,"name":110,"nameZh":6,"description":111,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":112,"categories":113,"keywords":116,"publishedAt":27},"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",[114,115],{"categoryNo":94,"categoryName":95,"taxonomyType":91,"taxonomyTypeDesc":92},{"categoryNo":97,"categoryName":98,"taxonomyType":99,"taxonomyTypeDesc":100},[117,103,118,21,119,104,120,121,78,122,123,124],"writing plans","spec","ZeRO","write","context","engineer","implementation","task",{"skillNo":126,"name":127,"nameZh":6,"description":128,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":129,"categories":130,"keywords":131,"publishedAt":27},"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",[],[127,104,105,78,132,133],"evidence","claim",{"skillNo":135,"name":136,"nameZh":6,"description":137,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":138,"categories":139,"keywords":141,"publishedAt":27},"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",[140],{"categoryNo":89,"categoryName":90,"taxonomyType":91,"taxonomyTypeDesc":92},[136,103,21,142,104,120,78,143,123,144],"first","minimal","test",{"skillNo":146,"name":147,"nameZh":6,"description":148,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":149,"categories":150,"keywords":152,"publishedAt":27},"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",[151],{"categoryNo":89,"categoryName":90,"taxonomyType":91,"taxonomyTypeDesc":92},[153,71,154,78,104,144,155],"systematic debugging","behavior","bug"]