Skip to content

[CI] Docs tier-drift's path filter watches the templates but not docs/guide, so a change to the generated output alone skips the only gate that checks it #1059

Description

Summary

docs/guide/*.md is generated from docs/_pipeline/templates/*.md.dt. The only gate that detects drift between them is the Docs tier-drift CI job — and its path filter watches the templates, not the generated output.

A change that touches only docs/guide/*.md and leaves the template untouched sets docs-templates=false, skips the job, and ships with no gate at all.

OBSERVED_AT 2026-08-01T13:45:35Z    main = 1ed2644e

.github/workflows/ci.yml:71
  if echo "$files" | grep -qE '^(docs/_pipeline/templates/|docs/_pipeline/apps/|src/Reactor\.Cli/Docs/)'; then
    docs-templates=true

  'docs/_pipeline' in the filter block : True
  'docs/guide'     in the filter block : FALSE     <- the artifact it protects

No unit-test gate compensates

The other two generated artifacts in this repo are gated by tests that run in the Unit Tests leg, which executes on every non-Markdown change:

artifact gate runs when
samples/ReactorGallery/reactor-search-index.json SearchIndexGeneratorTests.Index_IsUpToDate every non-md change
skills/reactor.api.txt (+ plugins copy) ApiIndexGeneratorTests every non-md change
docs/guide/*.md Docs tier-drift CI job only only when a template/app/CLI path changes

Searched every test referencing md.dtCrossLinkLintTests, DiagramTests, TierLintTests, TierLintOrchestratorTests, FlexPanelCssBehaviorFixtures, VersionSingleSourceTests. The only one touching both docs/guide and a compile step is VersionSingleSourceTests, and it is version-only — seven tests about version literals/tokens, Assert.Equal occurrences: 0.

Why this is reachable, not theoretical

Found while verifying a merge. git merge-tree on two open PRs reports:

CONFLICT (content): ... 5 files ...
Auto-merging docs/_pipeline/templates/data-system.md.dt
Auto-merging docs/guide/data-system.md                    <- generated output, SILENT
Auto-merging tests/.../DataGridEditFixtures.cs

Git merges the template and its generated output as two unrelated text files. It can interleave two generated outputs into a file the generator would never emit, and no conflict marker appears on either.

In that particular merge the template also changes, so the gate would fire. That is incidental. Any of these skips it:

  • a merge where only one side changed the template, so only the output auto-merges
  • a hand-edit of docs/guide/*.md (forbidden by AGENTS.md — and this gate is what enforces it)
  • a revert or cherry-pick touching only the output

The absence of a conflict marker is not evidence that regeneration can be skipped — and here nothing downstream will catch it either.

Suggested fix

Add docs/guide/ to the docs-templates filter at ci.yml:71:

if echo "$files" | grep -qE '^(docs/_pipeline/templates/|docs/_pipeline/apps/|src/Reactor\.Cli/Docs/|docs/guide/)'; then

The job already does the right comparison (docs compile --no-screenshots --ci then fails with "docs/guide is out of date with the doc templates" at :670) — it simply is not invited to run when only its subject changes.

Non-vacuity check for the fix: modify one byte of a committed docs/guide/*.md without touching any template, and confirm Docs tier-drift runs and fails. Under the current filter it does not run at all.


Surfaced by the #1010 session's observation that merge-tree's auto-merge lines matter more than its conflict list; filter and gate coverage verified independently here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions