dashboard-review When to use Use this skill when tasks include: - reviewing a PR that modifies Kibana dashboard JSON files - comparing dashboard changes between branches - summarizing what changed in dashboard exports - checking dashboard changes against the official dashboard guidelines When not to use Do not use this skill as the primary guide for: - creating new dashboards or exporting them from Kibana ( ) - dashboard naming conventions and file layout ( → ) - package-wide command orchestration ( ) - test suite selection ( ) Prerequisites must be installed: Lines prefixed with in the outpu…

\n```\n\n**From a local branch:**\n\n```bash\ngit diff --name-only \u003cbase>...HEAD -- '*/kibana/dashboard/*.json'\n```\n\nClassify each file as **added**, **removed**, or **modified** using\n`git diff --diff-filter=A`, `--diff-filter=D`, `--diff-filter=M`.\n\n## 2. Extract before/after descriptions\n\nFor each **modified** dashboard file, extract the base version with\n`git show` and describe the current state using the package directory.\nRunning kbdash on the package directory (rather than an individual\nfile) resolves saved searches and Kibana asset tags from the package's\n`kibana/search/` and `kibana/tag/` files.\n\n```bash\ngit show \u003cbase>:\u003cpath> > /tmp/kbdash-before.json\nkbdash /tmp/kbdash-before.json > /tmp/kbdash-before.txt\nkbdash \u003cpackage-dir> > /tmp/kbdash-after.txt\n```\n\nThe \"after\" output covers all dashboards in the package; read the\nsection whose `File:` line matches the changed file.\n\nFor **added** files, only run `kbdash \u003cpackage-dir>` on the new state.\nFor **removed** files, only extract the base version.\n\nWhen reviewing a PR by URL and you don't have the repo checked out,\nclone it into a temp directory or use `gh pr checkout`.\n\n## 3. Compare and summarize\n\nRead both text descriptions and compare them. Report changes in\norder of importance:\n\n**Always report (meaningful):**\n\n- Added or removed dashboards (entire files)\n- Added or removed panels\n- Changed panel type or visualization subtype (e.g. `lnsPie` to\n `lnsXY`, or `lens` to `visualization`)\n- Changed data fields — added, removed, or different source fields\n- Changed aggregation operations (e.g. `terms` to `count`,\n `average` to `sum`)\n- Changed or reorganized layer structure in lens panels\n- New, changed, or removed filters (global or per-panel)\n- Changed controls (added, removed, different fields or types)\n- Changed global query\n- New, changed, or removed navigation links\n- Changed dashboard title or description\n\n**Downplay (cosmetic):**\n\n- Grid position shifts (`x`, `y` changes) that don't change the\n relative ordering of panels — group these as \"position adjustments\"\n- Small size changes (`w`, `h`) that don't fundamentally change the\n panel's role — mention only in passing\n- Panel reordering without any other semantic change\n\nUse judgement: a panel moving from row 0 to the bottom of the\ndashboard *is* meaningful (it changes what users see first), but\nshifting 2 grid units to the right is not.\n\n## 4. Verify suspected issues against raw JSON\n\nTrust kbdash output for facts it directly reports — panel count,\ntags, panel types, filter lists, column names, and warnings. Do not\nre-check these in the raw JSON; that is redundant and wastes time.\n\nRaw JSON verification is for suspected issues that kbdash may have\nmissed or only partially extracted: before reporting that something\nis missing (no filters, no fields, empty configuration), check the\nraw JSON to confirm the issue is real.\n\nFor each suspected problem:\n\n1. Find the panel in the raw JSON (match by panel index, title, or\n grid position).\n2. Inspect the relevant section — e.g. for a \"no filter\" finding,\n check `embeddableConfig.attributes.state.datasourceStates`\n column-level `filter` fields, not just panel-level and\n state-level filters.\n3. Note the line number(s) in the JSON file where the issue occurs.\n4. If the raw JSON confirms the issue, report it with line numbers\n so reviewers can locate it directly.\n5. If the raw JSON shows the information *is* present but `kbdash`\n did not surface it, report the review finding as a `kbdash`\n extraction gap instead of a dashboard bug. Note what `kbdash`\n missed so it can be fixed.\n\nThis step prevents false positives from incomplete extraction.\nInclude line numbers in all reported issues — both confirmed\ndashboard problems and `kbdash` gaps.\n\n## 5. Structure the output\n\nWrite one section per dashboard. Include both the dashboard title and\nthe filename (from kbdash's `File:` line) in the heading so reviewers\ncan locate the file. Within each section, list meaningful changes as\nbullet points. If a dashboard has only cosmetic changes, say so in a\nsingle line rather than enumerating every position shift.\n\n**Example output:**\n\n```\n## Dashboard: \"[Logs] Audit Events\" (`audit-events-abc123.json`)\n\n- Added panel \"Error Rate Over Time\" (lens: lnsXY) at row 30\n - Fields: event.outcome (terms), @timestamp (date_histogram)\n- Panel \"Distribution by Result\": changed from lnsPie to lnsXY\n- Panel \"Top Users\": added filter `user.name: exists`\n- Removed panel \"Legacy Status Table\"\n- Global query unchanged\n- Minor position adjustments to 3 panels (no reordering)\n\n### Guideline notes\n- 1 panel uses TSVB (should be Lens)\n- Panel \"Error Rate Over Time\" has no `data_stream.dataset` filter\n```\n\nFor added dashboards, describe the full dashboard briefly — list of\npanel types and what data they show, without exhaustive field lists.\nFor removed dashboards, note the title and what it covered.\n\n## 6. Edge cases\n\n- **New package (no base version):** All dashboards are new. Describe\n each one briefly rather than comparing.\n- **Renamed files:** Check whether a removed + added pair have the\n same dashboard ID or title. If so, treat as a rename and diff the\n content.\n- **Many dashboards:** If the package has more than 5 changed\n dashboards, start with a summary table (dashboard name, change\n type, number of meaningful changes) before the per-dashboard\n detail.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":5791,"content_sha256":"52b82758f1880228fc379d0187eecd7fdaad4013518cf1d191bad7420ffcf4e2"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"dashboard-review","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to use","type":"text"}]},{"type":"paragraph","content":[{"text":"Use this skill when tasks include:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"reviewing a PR that modifies Kibana dashboard JSON files","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"comparing dashboard changes between branches","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"summarizing what changed in dashboard exports","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"checking dashboard changes against the official dashboard guidelines","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When not to use","type":"text"}]},{"type":"paragraph","content":[{"text":"Do not use this skill as the primary guide for:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"creating new dashboards or exporting them from Kibana (","type":"text"},{"text":"dashboard-guidelines","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"dashboard naming conventions and file layout (","type":"text"},{"text":"dashboard-guidelines","type":"text","marks":[{"type":"code_inline"}]},{"text":" → ","type":"text"},{"text":"references/kibana-assets-layout.md","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"package-wide command orchestration (","type":"text"},{"text":"elastic-package-cli","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"test suite selection (","type":"text"},{"text":"integration-testing","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Prerequisites","type":"text"}]},{"type":"paragraph","content":[{"text":"kbdash","type":"text","marks":[{"type":"code_inline"}]},{"text":" must be installed:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"go install github.com/efd6/kbdash@latest","type":"text"}]},{"type":"paragraph","content":[{"text":"Lines prefixed with ","type":"text"},{"text":"[!]","type":"text","marks":[{"type":"code_inline"}]},{"text":" in the output are warnings about potential issues in the dashboard JSON (consistency mismatches, incomplete extraction, parse errors). Run ","type":"text"},{"text":"kbdash -h","type":"text","marks":[{"type":"code_inline"}]},{"text":" for a description of each warning type.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Review procedure","type":"text"}]},{"type":"paragraph","content":[{"text":"Read ","type":"text"},{"text":"references/review-procedure.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for the full step-by-step workflow. The high-level flow is:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identify","type":"text","marks":[{"type":"strong"}]},{"text":" changed dashboard files (added, removed, modified).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Extract","type":"text","marks":[{"type":"strong"}]},{"text":" before/after descriptions with ","type":"text"},{"text":"kbdash","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Compare","type":"text","marks":[{"type":"strong"}]},{"text":" descriptions and classify changes as meaningful or cosmetic.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Verify","type":"text","marks":[{"type":"strong"}]},{"text":" suspected issues against the raw JSON before reporting.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Format","type":"text","marks":[{"type":"strong"}]},{"text":" output as one section per dashboard with bullet-pointed changes.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Check","type":"text","marks":[{"type":"strong"}]},{"text":" guideline compliance on added or modified dashboards.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Guideline compliance checks","type":"text"}]},{"type":"paragraph","content":[{"text":"After summarizing changes, check the final state of every added or modified dashboard against the ","type":"text"},{"text":"official dashboard guidelines","type":"text","marks":[{"type":"link","attrs":{"href":"https://www.elastic.co/docs/extend/integrations/dashboard-guidelines","title":null}}]},{"text":". Report violations in a \"Guideline notes\" subsection after the change summary for each dashboard.","type":"text"}]},{"type":"paragraph","content":[{"text":"Check for these issues:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"TSVB panels:","type":"text","marks":[{"type":"strong"}]},{"text":" Flag any ","type":"text"},{"text":"visualization","type":"text","marks":[{"type":"code_inline"}]},{"text":" panel using TSVB. The guidelines require Lens for all new visualizations. Migrating existing TSVB to Lens is encouraged.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Missing dataset filter:","type":"text","marks":[{"type":"strong"}]},{"text":" Each visualization should filter on ","type":"text"},{"text":"data_stream.dataset","type":"text","marks":[{"type":"code_inline"}]},{"text":" or an equivalently specific scope. Flag panels that query broad index patterns (","type":"text"},{"text":"metrics-*","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"logs-*","type":"text","marks":[{"type":"code_inline"}]},{"text":") without scoping.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"By-reference visualizations:","type":"text","marks":[{"type":"strong"}]},{"text":" Visualization and lens panels should be embedded by value. kbdash flags by-reference ","type":"text"},{"text":"lens","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"visualization","type":"text","marks":[{"type":"code_inline"}]},{"text":", and ","type":"text"},{"text":"map","type":"text","marks":[{"type":"code_inline"}]},{"text":" panels with ","type":"text"},{"text":"[!] \u003ctype> ref: … (definition not inlined)","type":"text","marks":[{"type":"code_inline"}]},{"text":". Flag these. Saved searches are inherently referenced and carry a separate ","type":"text"},{"text":"[!] saved search ref","type":"text","marks":[{"type":"code_inline"}]},{"text":" warning — do not flag those.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Deprecated input controls:","type":"text","marks":[{"type":"strong"}]},{"text":" The ","type":"text"},{"text":"input-control-vis","type":"text","marks":[{"type":"code_inline"}]},{"text":" type is deprecated. Dashboard-native controls should be used instead.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Package-name title prefix:","type":"text","marks":[{"type":"strong"}]},{"text":" Panel titles matching ","type":"text"},{"text":"[\u003cPackage Name> ...]","type":"text","marks":[{"type":"code_inline"}]},{"text":" create unnecessary repetition. Flag these.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Broad wildcard filters:","type":"text","marks":[{"type":"strong"}]},{"text":" Filters using unscoped ","type":"text"},{"text":"-*","type":"text","marks":[{"type":"code_inline"}]},{"text":" patterns without further qualification are a performance concern.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"High panel count:","type":"text","marks":[{"type":"strong"}]},{"text":" kbdash includes the count in the panels section header — ","type":"text"},{"text":"Panels (N total, …)","type":"text","marks":[{"type":"code_inline"}]},{"text":". If N exceeds roughly 20, note it. The guidelines recommend splitting across dashboards and linking with drilldowns.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Queries on ","type":"text","marks":[{"type":"strong"}]},{"text":"event.dataset","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" instead of ","type":"text","marks":[{"type":"strong"}]},{"text":"data_stream.dataset","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":":","type":"text","marks":[{"type":"strong"}]},{"text":" Saved-object queries (dashboards, saved searches, packaged ML job datafeeds) must filter on ","type":"text"},{"text":"data_stream.dataset","type":"text","marks":[{"type":"code_inline"}]},{"text":". Some inputs (e.g. packetbeat) never set ","type":"text"},{"text":"event.dataset","type":"text","marks":[{"type":"code_inline"}]},{"text":", so an ","type":"text"},{"text":"event.dataset","type":"text","marks":[{"type":"code_inline"}]},{"text":" filter silently matches nothing. Flag every saved-object query in a diff that renames or re-maps fields.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"YAML dashboard sources out of sync:","type":"text","marks":[{"type":"strong"}]},{"text":" When a package keeps YAML dashboard sources in ","type":"text"},{"text":"_dev/shared/kibana/*.yaml","type":"text","marks":[{"type":"code_inline"}]},{"text":" (compiled to ","type":"text"},{"text":"kibana/dashboard/*.json","type":"text","marks":[{"type":"code_inline"}]},{"text":" with kb-dashboard), BOTH must be committed and in sync. Flag JSON-only edits when a YAML source exists for that dashboard.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Regeneration diffs:","type":"text","marks":[{"type":"strong"}]},{"text":" A recompile PR is expected to change only ","type":"text"},{"text":"state.adHocDataViews","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"state.internalReferences","type":"text","marks":[{"type":"code_inline"}]},{"text":", and per-layer ","type":"text"},{"text":"index","type":"text","marks":[{"type":"code_inline"}]},{"text":" keys (the ES|QL/Discover fix on Kibana 9.3+). Diffs beyond those keys in a \"regenerate\" PR deserve inspection.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Missing Kibana asset tags:","type":"text","marks":[{"type":"strong"}]},{"text":" kbdash shows a ","type":"text"},{"text":"Tags:","type":"text","marks":[{"type":"code_inline"}]},{"text":" section for each dashboard (resolved from ","type":"text"},{"text":"kibana/tag/","type":"text","marks":[{"type":"code_inline"}]},{"text":" when run on a package directory). New content-pack dashboards are expected to carry Kibana asset tags — note their absence (LOW).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Navigation link completeness:","type":"text","marks":[{"type":"strong"}]},{"text":" If a dashboard has a links panel, verify that every dashboard in the package has a corresponding entry. Run ","type":"text"},{"text":"kbdash \u003cpackage-dir>","type":"text","marks":[{"type":"code_inline"}]},{"text":" to see all dashboard titles (the ","type":"text"},{"text":"=== … ===","type":"text","marks":[{"type":"code_inline"}]},{"text":" headers) alongside each links panel's ","type":"text"},{"text":"Link:","type":"text","marks":[{"type":"code_inline"}]},{"text":" lines. Note any dashboard whose title has no matching link.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Only report issues that actually exist — skip passing checks. For pre-existing violations in unchanged panels, mention them once briefly (\"N existing panels also use TSVB\") rather than listing each one. Focus review attention on newly added or modified panels.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Handoff to other skills","type":"text"}]},{"type":"paragraph","content":[{"text":"After the review is complete:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"dashboard-guidelines","type":"text","marks":[{"type":"code_inline"}]},{"text":" for creation or export guidance if the review surfaces structural issues","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"package-spec","type":"text","marks":[{"type":"code_inline"}]},{"text":" when dashboard changes require a release note entry","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"elastic-package-cli","type":"text","marks":[{"type":"code_inline"}]},{"text":" for validation commands","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"References","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/review-procedure.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" — full extraction, comparison, and output formatting workflow","type":"text"}]}]}]}]},"metadata":{"date":"2026-11-02","name":"dashboard-review","author":"@skillopedia","source":{"stars":16,"repo_name":"integration-skills","origin_url":"https://github.com/elastic/integration-skills/blob/HEAD/skills/dashboard-review/SKILL.md","repo_owner":"elastic","body_sha256":"5043bf1a69c6d8625ab9892fd55bd7787dcba5bc2f812abc81d4d76e4d92d66a","cluster_key":"dcca34f049c124917c41635d7074e398152a4b3071c1893e7e1141eadcf1dff4","clean_bundle":{"format":"clean-skill-bundle-v1","source":"elastic/integration-skills/skills/dashboard-review/SKILL.md","text_bytes":5791,"source_commit":"39792cf81750ee54cba5b653fbfb69706871d42b","skills_sh_rank":19391,"attachment_count":1,"text_attachments":1,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"skills/dashboard-review/SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"v1","category":"data-analytics","category_label":"Data"},"exact_dupes_collapsed_into_this":0},"license":"Apache-2.0","version":"v1","category":"data-analytics","metadata":{"author":"elastic","version":"1.0"},"import_tag":"skills-sh-top20k-2026-11","description":"Use when reviewing dashboard JSON changes in a PR or branch. Extracts structured descriptions with kbdash, compares before/after, and checks guideline compliance."}},"renderedAt":1793671753567}

dashboard-review When to use Use this skill when tasks include: - reviewing a PR that modifies Kibana dashboard JSON files - comparing dashboard changes between branches - summarizing what changed in dashboard exports - checking dashboard changes against the official dashboard guidelines When not to use Do not use this skill as the primary guide for: - creating new dashboards or exporting them from Kibana ( ) - dashboard naming conventions and file layout ( → ) - package-wide command orchestration ( ) - test suite selection ( ) Prerequisites must be installed: Lines prefixed with in the outpu…