# CI guardrails for blog content (evaluation)

**Last Updated:** 2026-04-04

## Current state

- **PR workflow:** [.github/workflows/code-quality.yml](../../.github/workflows/code-quality.yml) runs PHPStan (with `continue-on-error: true`) on pull requests; it does **not** run per-post blog validators.
- **Rationale:** Full `make blog-post-validate` is **slow** and **noisy** if run on every PR (many posts, WARN-level competitor ratios, environment assumptions). Failing CI on optional WARN would block unrelated PRs.

## Recommended approach (layered)

1. **Human / agent (mandatory):** After changing `v2/data/blog/posts/**/*.json` body or FAQs, run `make blog-post-validate POST=… CAT=…` locally; before publish run `make blog-post-validate-strict POST=… CAT=…`.
2. **Optional future CI (path-filtered):** Add a job triggered only when `v2/data/blog/posts/` changes, running a **fast subset**, for example:
  - `php v2/scripts/blog/validate-internal-links-exist.php --post=SLUG --category=CAT` for detected slugs (requires a small script to list changed JSON files), or
  - `validate-content-flow.php` only (catches FAQ-in-body false positives).
3. **False positives:** Document in post `CREATION_NOTES.md` when a validator WARN is accepted; use `--strict` on compare only at publish time.

## Skyscraper checks: no separate `make` target

`make blog-post-validate` already runs `**compare-content-to-competitors.php`** and `**validate-content-completeness.php`** (plus section-depth, geo, AEO, FAQ, new-post). A dedicated `blog-skyscraper-sanity` target would largely duplicate that chain. For **stricter** skyscraper ratio enforcement before publish, use `**make blog-post-validate-strict`** (includes `compare-content-to-competitors --strict`). See [CONTENT_PIPELINE_AUDIT_2026-03-23.md](CONTENT_PIPELINE_AUDIT_2026-03-23.md) and [SKYSCRAPER_CONTENT_QUALITY_ENFORCEMENT.md](SKYSCRAPER_CONTENT_QUALITY_ENFORCEMENT.md).

## Manual regression slugs (after validator / pipeline changes)

CI does not run full per-post strict checks. After changing blog validators, `Makefile` targets, or pipeline scripts, spot-check known-good posts:

```bash
make blog-post-validate-strict POST=urlaubskonto CAT=lexikon
make blog-post-validate-strict POST=personaldisposition CAT=lexikon
```

Adjust slugs over time; pick posts that historically pass strict and represent typical lexikon depth.

## Related

- [BLOG_CONTENT_EDIT_WORKFLOW.md](BLOG_CONTENT_EDIT_WORKFLOW.md)
- [CONTENT_SYSTEM_INDEX.md](CONTENT_SYSTEM_INDEX.md)

