Claude-specific guidance. For automation/agent rules see AGENTS.md. For public docs see docs/README.md.
This repo (the Observability Migration Platform, CLI obs-migrate) is the
canonical source for the migration engine — grafana-migrate,
datadog-migrate, PromQL/Datadog translation, and the shared Kibana
native-payload/upload path. Treat this repository as the single source of truth.
(See the Naming note in AGENTS.md.)
- Engine fixes and features belong in Issues/PRs on this repo, not in downstream forks.
- Downstream vendored snapshots should be refreshed from this repo rather than maintained as long-lived forks.
- Operator-first feature design. Design and document for the operator who
only runs the installable CLI and follows public docs — not for agents or
engineers who can run helper scripts, dated harness folders, env-gated
rewrites, or sample-data generators. Lab tooling is fine for CI and
investigation; it must not be the user journey or a required step for the
feature to work. Full rule:
AGENTS.md(Repo-Specific Working Rules). - Architecture overview:
docs/architecture.md - Canonical CLI commands:
docs/command-contract.md - Build / test / lint: see
AGENTS.md(usemake test,make lint,make typecheck). - Keep docs in the same PR as operator-visible behavior changes. Update
docs/command-contract.mdfor CLI/env/upload/smoke changes,docs/architecture/asset-model.mdfor shared IR/result contracts,docs/architecture.mdanddocs/pipeline-trace.tpl.mdfor package maps or cross-source pipeline structure,docs/targets/kibana.mdfor Kibana target/native API/review-artifact behavior,docs/sources/grafana.mdordocs/sources/datadog.mdfor source-specific behavior,docs/contributing/import-paths.mdfor public helper/module moves,docs/testing.mdfor verifier/gate changes, anddocs/contributing/dev-commands.mdfor repo-checkout-only commands (scripts/*, verifier gates, pytest). If public install/scope changes, also updateREADME.mdanddocs/README.md. Generated trace docs must be updated through their templates/generators. - Preserve "degrade gracefully" behavior for unsupported translations — do not silently hide semantic gaps.
- Do not commit secrets or generated local artifacts.
- Dashboard migration fixes must be checked against the schema, the uploaded
saved object, and uploaded Kibana behavior. Do not infer schema support from
Kibana UI controls alone: a Lens XY panel supports one
breakdown, while multi-breakdown arrays are for schemas such as datatable/pie/treemap unlessdocs/dashboards/schema.jsonand the mapper prove otherwise. - Before claiming migrated dashboards render correctly, validate real artifacts:
native/*.native.jsonandir/*.ir.json, the uploaded saved object, scoped smoke or direct_query, and a clean view-mode browser session. Clear stale dashboard edit state before trusting browser observations. - For dashboard-regression work, use the layered verifier gates documented in
docs/contributing/dev-commands.md:verifier.live_validatefor runtime ES|QL errors,verifier.dashboards_apifor typed Kibana UI-contract validation,obs-migrate compareplusverifier.corpus_gatefor semantic parity,verifier.benchmark_gatefor PM benchmark-history regressions,verifier.scorecardfor the Layer-9 fidelity ratchet, andrender_audit_driverfor whether panels actually render in Kibana, and the interaction audit (scripts/run_interaction_audit_local.sh) for whether control selection rewrites affected panel queries. Do not rely on a single migrated/clean percentage; also watch denominator drops (panels_total,dashboards,verification_total) and filtered datasource slices. - The render audit is the only gate that catches Lens accessor / "invalid
column" / empty-state failures (which ES|QL execution and the schema gate
miss). It is per-panel and classifies
render_error(real bug, fail) vsfield_gap/data_gap/unexpected_empty(data-readiness, warn). A breakdown panel that errors because its label is absent from target data is a field/data gap, NOT a translator bug — confirm via seeded data before filing a bug. Interaction correctness additionally requires control-selection evidence plus affected-query correlation; do not infer filter behavior from a green default- state render alone. - Coverage of supported panel/widget types is machine-enforced
(
tests/core/coverage/, the panel matrices, and the kitchen-sink canary). Add a type → updatecore/coverage/supported_types.py+ a matrix cell, or CI fails. Refreshparity-rig/benchmark/fidelity_baseline_*.jsononly for intentional changes, never to mask a regression. - When growing benchmark coverage, prefer pinned stratified manifests from
verifier.corpus_manifest(top dashboards + long-tail + datasource quotas + bug seeds) over an unpinned "top N today" sample. Use small deterministic PR gates and larger/nightly corpus gates. - Curated Grafana packs MUST author canonical field/label names and never
hardcode
labels.*/metrics.*/prometheus.*target spellings; the resolver namespaces per--field-profile. New packs are verified by the cross-profile leakage gate (scripts/run_cross_profile_corpus.py). - Skills live in both
.claude/skills/and.cursor/skills/— edit both copies in lockstep (see the mirroring rule inAGENTS.mdfor the.claude↔.cursorpath-prefix caveat).
Follow AGENTS.md commit rules. Key points:
- Commit only when the user explicitly asks.
- Conventional-Commits subject (
feat:,fix:,docs:) + blank line + why-focused rationale. - Never
--no-verify. Never force-pushmain.