From 15ffc91ec20aeb8ee8effcd2b3f870cac8750b3b Mon Sep 17 00:00:00 2001 From: Nubenetes Bot Date: Sat, 20 Jun 2026 12:14:49 +0200 Subject: [PATCH] fix(ci): PR Guardian must not auto-format the generated v2-docs/ tree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Guardian's auto_format_file ("&"->"and" in headings, URL trailing-slash normalization) ran on every changed .md including the generated v2-docs/, then committed the result back to the PR branch. Because PRs land on develop while release branches merge to master via plain git merge (no Guardian run), develop ended up with the normalized form and master with the generator's raw form — a perpetual cosmetic develop<->master drift that spawned recurring no-op 'Release: Agentic V2 Portal Update' PRs (e.g. #399). v2_optimizer.py is the single source of truth for v2-docs/ formatting, so the Guardian now skips that tree in the auto-format loop and drops it from the auto-commit 'git add'. Hand-authored docs/ and README/inventory are unaffected. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/07.1.pr_guardian.yml | 5 ++++- src/pr_guardian.py | 8 +++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/07.1.pr_guardian.yml b/.github/workflows/07.1.pr_guardian.yml index f1f1f5bf..5d2624af 100644 --- a/.github/workflows/07.1.pr_guardian.yml +++ b/.github/workflows/07.1.pr_guardian.yml @@ -59,7 +59,10 @@ jobs: run: | git config --global user.name "nubenetes-bot" git config --global user.email "bot@nubenetes.com" - git add docs/ v2-docs/ README.md data/inventory.yaml data/inventory.sql src/memory/ + # NOTE: v2-docs/ is deliberately excluded. It is generated by + # src/v2_optimizer.py (single source of truth); re-formatting it here + # caused a perpetual cosmetic develop<->master drift (see pr_guardian.py). + git add docs/ README.md data/inventory.yaml data/inventory.sql src/memory/ if ! git diff --cached --quiet; then git commit -m "style(cleaner): auto-correcting formatting & URL normalization" git push origin HEAD:${{ github.event.pull_request.head.ref }} || echo "⚠️ Push failed (likely fork permission limit)." diff --git a/src/pr_guardian.py b/src/pr_guardian.py index 473b3a55..b630bf94 100644 --- a/src/pr_guardian.py +++ b/src/pr_guardian.py @@ -95,7 +95,13 @@ def main(): files = pr.get_files() modified_files = [f.filename for f in files if f.status in ["modified", "added"]] for filepath in modified_files: - if filepath.endswith(".md"): + # The v2-docs/ tree is generated by src/v2_optimizer.py, which is its + # single source of truth for formatting. Auto-formatting it here + # ("&"->"and" in headings, URL trailing-slash stripping) only fights + # the generator: the rewrite lands on develop via the PR while master + # gets the generator's raw form via release merges, producing a + # perpetual cosmetic develop<->master drift. Skip the generated tree. + if filepath.endswith(".md") and not filepath.startswith("v2-docs/"): auto_format_file(filepath) except Exception as e: print(f"Warning: Failed to fetch files for auto-formatting: {e}")