docs(skill): add pipeline-for-MR recipe with source filter

Problem

The Orbit skill had no recipe for "pipelines for an MR" and the query language reference didn't document the parent/child pipeline duplication. Asked "how many pipelines have run for gitlab-org/gitlab!235291", Claude Code + skill v0.6.0 followed MergeRequest --TRIGGERED--> Pipeline (or filtered Pipeline.merge_request_id) without a source filter and returned 98 — the graph links every CI pipeline spawned in the context of an MR to that MR, including downstream child pipelines (source = "parent_pipeline"). REST /merge_requests/235291/pipelines, the MR Pipelines tab, and the DAP Orbit panel all return 16.

Solution

Teach the skill the canonical pattern: filter Pipeline.source = "merge_request_event" on every MR-pipeline query. Concretely — a "Common pitfalls" callout in SKILL.md, a leading imperative gotcha in recipes.md ahead of three paste-ready shapes (count by status, list failed, two-node TRIGGERED form), and a matching section in query_language.md. Version bump 0.6.0 → 0.7.0. The deeper fix would be ontology-level (e.g. a dedicated HAS_MR_PIPELINE edge); happy to file a follow-up.

Closes https://gitlab.com/dgruzd/tasks/-/work_items/2659

Validation — opencode-refine smoke tests against the installed branch skill

Each prompt was run twice: once against an interim revision (recipe only, gotcha in a blockquote inside the recipe), once against the final revision (with the SKILL.md callout and the imperative leading line in the recipe). Numbers confirmed by REST API ground truth.

Prompt 1 — "How many pipelines have run for MR !235291 in gitlab-org/gitlab? Break down by status."

Query shape source filter? Result
Interim Multi-node aggregation (Project + MR + Pipeline, TRIGGERED), no filter 686 (343 / 329 / 14)
Interim + filter applied Same multi-node aggregation, with source = merge_request_event wrong shape 112 (98 / 7 / 7) — see Notes
Final Canonical single-node aggregation on Pipeline, merge_request_id + source 16 (14 / 1 / 1)
REST ground truth 16 (14 failed / 1 success / 1 canceled)

Final-revision agent explicitly quoted the warning back: "Without it, the count would also include downstream child pipelines (source = "parent_pipeline") and over-count by 5-10× compared to what the MR's Pipelines tab and the REST endpoint show."

Prompt 2 — "Show me the failed pipelines for MR !235291 in gitlab-org/gitlab"

Query shape source filter? Result
Interim Multi-node traversal over TRIGGERED, status = failed, no source filter 8 results, mix of merge_request_event and parent_pipeline (e.g. 2520134257, 2520134222 were children)
Final Canonical single-node traversal, merge_request_id + source + status filters Only top-level failed pipelines, matching the MR Pipelines tab

Prompt 3 — "What pipelines ran for MR !1216 (merged) in gitlab-org/orbit/knowledge-graph?"

Query shape source filter? Result
Interim Multi-node traversal over TRIGGERED, no source filter 3 pipelines — coincidentally correct (no children on this MR)
Final Canonical single-node traversal, merge_request_id + source filter 3 pipelines, all merge_request_event, all success — correct by construction

Notes

  • A recipe alone wasn't enough — agents tend to read SKILL.md and only optionally pull in references, and they default to multi-node forms even when single-node is canonical. Promoting the gotcha into SKILL.md + the leading imperative in the recipe is what got the agent to use the canonical form on the first try.
  • The 686 → 112 gap on Prompt 1 interim is a separate multi-node aggregation cross-join behaviour: the same multi-node traversal returns 16 distinct pipeline nodes, but aggregation with the same nodes/relationships counts joined rows instead. My recipes steer users to the single-node form which avoids it; happy to file the engine quirk as a separate issue.
  • Linting clean (markdownlint-cli2, vale --minAlertLevel error, lychee --offline); lefthook orbit-skill-docs-sync passes. The sync rolls forward four disclaimer lines that previous syncs had left out (pre-existing drift since commit 00f5adaa).
Edited by Dmitry Gruzd

Merge request reports

Loading