summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-05-10ci: AI Validation rewrite — MyST + split-job + branch mapYuriy Andamasov
Rewrites .github/workflows/ai-validation.yml to align with the docs current→rolling rename and the RST→MyST migration. The body is a byte-for-byte copy of the canonical reference at VyOS-Networks/vyos-docs-opus-reviewer/scripts/ai-validation.yml at tag reviewer-v1.0.0 (header stripped on copy). Key changes vs the previously deployed (and currently disabled) workflow: - Trigger pull_request → pull_request_target (required for fork PRs to access secrets) with a split prepare/validate job pattern that preserves the trust boundary. - prepare job: NO secrets referenced; checks out the PR merge ref with persist-credentials:false; emits NUL-delimited diffs + bundles changed .md files into _changed_md/ via xargs cp. - validate job: secrets-availability check; sparse-checkout of branches.json from the reviewer repo (pinned via REVIEWER_REF env var, default reviewer-v1.0.0); fail-fast resolution of docs branch → vyos-1x branch via jq lookup; mapped vyos-1x checkout; reference-DB download (best-effort); fail-closed gate when MyST files are in the diff but the DB is missing; Pass 1 runs from inside _changed_md/ so diff-relative paths resolve; Pass 2 via claude-code-action with hardened prompt (untrusted-content ringfence, narrow tool allowlist). - Concurrency: PR-scoped concurrency cancels superseded runs. - Runners: [self-hosted, web] (org-level VyOS runner pool). - Action versions bumped for Node-24 compat: - actions/create-github-app-token@v2 - actions/setup-python@v6 - robinraju/release-downloader@<v1.13 SHA-pin> Required secrets in vyos/vyos-documentation: ANTHROPIC_API_KEY, VYOS_APP_ID, VYOS_APP_PRIVATE_KEY Implements: - VyOS-Networks/vyos-docs-opus-reviewer docs/superpowers/specs/2026-05-10-myst-parser-and-workflow-fix-design.md Workflow remains disabled_manually while this PR is in review. After merge, re-enable via: gh api repos/vyos/vyos-documentation/actions/workflows/259251949/enable -X PUT 🤖 Generated by [robots](https://vyos.io)
2026-05-10docs: address review on context7 rules — show in both modesYuriy Andamasov
Two more corrections from Copilot review on #1946: Rule 2: `show` exists in both modes. Config-mode `show` displays the working config (verified: `docs/cli.md:389` wraps `show` in `{cfgcmd}`). Op-mode `show` displays running state. Previous wording listed `show` under operational mode only, which contradicted `cli.md`. Reframe to list `show` in both, scoped to "config-state" vs running state. Rule 7: `show <area>` was hand-wavy and arguably invented syntax — conflicts with rule 5 ("do not invent CLI commands"). Replace with documented forms: `show <node>` (config mode, verified at `docs/cli.md:389`) or `show configuration commands` (op mode, verified at `docs/cli.md:224`). Both are direct quotes from the canonical CLI reference. 🤖 Generated by [robots](https://vyos.io)
2026-05-10ci: stack-based fence tracking + file-ext-aware suppression markersYuriy Andamasov
Two issues from PR review: 1. MD/MyST fence tracking treated any longer same-char fence as a closer, which would close `:::{note}` (3 cols) when seeing a nested `::::{code-block}` (4 cols) opener inside it. Real bug in `docs/configuration/interfaces/wireless.md:198–209` (currently unobservable because inner code lines are <80 chars). The "opener has info string / closer has none" heuristic is not sufficient on its own: there are 2,826 bare-fence opens in the tree, so info-string presence cannot distinguish opener from closer. Fix: stack-based tracking. A fence is treated as a closer only when (a) the stack is non-empty, (b) char and length match the top, AND (c) no info string follows. Anything else opens a new (possibly nested) fence. The outermost fence's info string still determines the `md_fence_is_eval_rst` flag. 2. `is_suppression_marker()` accepted `% stop_vyoslinter` in any file outside an MD fence. Per AGENTS.md and the doc-linter instructions, MyST `% ...` markers are only valid in `.md` files; a stray `% stop_vyoslinter` in `.rst`/`.txt` should not silently disable linting. Pass `file_ext` and gate the marker forms accordingly: `% ...` only in `.md` outside fences; `.. ...` in `.rst`/`.txt` outside RST code-blocks, or in `.md` inside an `{eval-rst}` fence. 3. Drop the `not in_rst_codeblock` guard on `.. code-block::` detection. Each occurrence resets the tracked indent (matches `origin/rolling` baseline). Without this, code-block-inside- code-block kept the outer indent and broke dedent detection (verified regression: `_rst_legacy/configuration/system/ rst-syslog.rst:216` long-line warning was lost; restored). Verified: - All 7 original synthetic fixtures pass. - New fixture `nested.md` (3-col outer wraps 4-col inner with long line in between fences) produces exactly one warning at the line outside both fences. - New fixture `wrongmarker.rst` (`%` in `.rst`) — IP error fires (marker correctly ignored). - Full-tree run vs origin/rolling baseline: zero regressions on pre-existing `.rst`/`.txt` warnings; all new output is `.md`. 🤖 Generated by [robots](https://vyos.io)
2026-05-10docs: address review on context7 rules — op-mode set/add, edit-subtreeYuriy Andamasov
Three corrections from Copilot review on #1946: Rule 2: Mode framing was technically wrong. `set ... ` is not unique to config mode — op mode has its own `set`/`add` commands for image management (`add system image`, `set system image default-boot`). Replace the `set/delete/show` listing with mode entry mechanics (`configure` enters config; op mode is the default after login) and acknowledge image-mgmt commands live in op mode. Rule 8: `add system image` and `set system image default-boot` are operational-mode commands (verified: docs/installation/update.md wraps `add system image` in `{opcmd}`; docs/installation/image.md does the same for `set system image default-boot`). The upgrade also is not in effect until reboot. Update to: op mode + reboot to activate. Rule 10: "Configuration is hierarchical — paths extend without re-stating it" was misleading. At the top level (just after `configure`), every `set`/`delete` line must include the full path. Relative paths only work inside an `edit <subtree>` context. The original phrasing would have led an LLM to omit parent nodes and emit invalid CLI examples. All revised rules verified ≤255 chars. 🤖 Generated by [robots](https://vyos.io)
2026-05-10docs: expand context7 rules — VyOS-specific LLM guardrailsYuriy Andamasov
Add 5 rules to `context7.json` targeting recurring LLM mistakes when answering VyOS questions through the context7-served index: 1. `commit` vs `save` semantics + verification step. Most common mistake: forgetting that `set/delete` are staged-only, that `commit` runs validation (failure = no change), and that `save` is a separate persistence step. 2. Image-based, not package-managed. Stops `apt install <pkg>` recommendations. Upgrade is `add system image <url>` then `set system image default-boot <name>`. 3. No raw Linux commands for configuration (`ip`, `iptables`, `systemctl`, NetworkManager). They bypass the CLI and do not persist. 4. CLI quoting with single quotes for whitespace/special chars + hierarchical-path reminder (paths under a parent extend without re-stating it). 5. Routing protocols are FRR-backed but only the VyOS-CLI-exposed subset is valid. Synthesizing from FRR docs produces invalid VyOS commands. Reinforces existing rule 5 with the most common synthesis trap. Each rule fits the 255-char per-rule limit. Total now 11 of 50. Lower-priority candidates intentionally omitted (low LLM-mistake yield): `compare`/`discard`/`rollback` mechanics, interface naming conventions, `commit-confirm`, `load`/`merge`, Equuleus EOL status — already implicit in the version-branches rule. 🤖 Generated by [robots](https://vyos.io)
2026-05-10docs: suppress literal public IP examples in linter guidecopilot-swe-agent[bot]
Agent-Logs-Url: https://github.com/vyos/vyos-documentation/sessions/5d679560-8a77-4735-b585-74c09293eea5 Co-authored-by: andamasov <12631358+andamasov@users.noreply.github.com>
2026-05-10fix: scope vyoslinter markers to real parser contextscopilot-swe-agent[bot]
Agent-Logs-Url: https://github.com/vyos/vyos-documentation/sessions/5d679560-8a77-4735-b585-74c09293eea5 Co-authored-by: andamasov <12631358+andamasov@users.noreply.github.com>
2026-05-10ci: extend doc-linter to MyST MarkdownYuriy Andamasov
Active docs are now MyST `.md`; the linter previously only inspected `.rst` and `.txt`, so ~250 active pages were unchecked for IP usage and line length on every PR. scripts/doc-linter.py: - Add `.md` to the extension filter (use `endswith` for correctness; the prior 4-char slice silently skipped `.md` files). - Track MyST/Markdown fenced code blocks (```` ``` ```` and `:::`) for line-length exemption — same semantics as `.. code-block::` for RST. - Recognize both suppression marker forms: `.. stop_vyoslinter` / `.. start_vyoslinter` (RST and `.txt` includes) and `% stop_vyoslinter` / `% start_vyoslinter` (MyST). Both work in either context; pick the form that matches the surrounding parser. - Replace the brittle `try/finally: fp.close()` with a `with` block — the previous form raised `UnboundLocalError` if `open()` itself failed. - Fix typo `forgett` → `forget`. .github/instructions/rst-linter.instructions.md → doc-linter.instructions.md: - Broaden `applyTo` from `**/*.rst` to `**/*.md,**/*.rst,**/*.txt`. - Document MyST suppression syntax and fenced-code line-length exemption. - Note the parser-form rule for `{eval-rst}` blocks. No regression on `.txt` includes: identical lint output verified against the origin/rolling baseline on a sample of files. Pre-existing IP violations exist in 14 `.md` files (e.g. `configexamples/lac-lns.md` line 95 — a `8.8.8.8` already wrapped in `% stop_vyoslinter`/`% start_vyoslinter`, correctly suppressed). PRs touching unsuppressed violations will start failing CI; this is the intent of enabling the check. 🤖 Generated by [robots](https://vyos.io)
2026-05-10docs: drop stray terraformvyos.rst and remove .rst from source_suffixYuriy Andamasov
The .md equivalent already exists alongside it; with both present and `source_suffix = ['.rst', '.md']`, Sphinx silently preferred the .rst. Deletion removes the shadowing and the only active .rst left in tree (legacy is archived under docs/_rst_legacy/). Restricting source_suffix to ['.md'] prevents future stray .rst files from being picked up, and is what external indexers (e.g. context7) look at when classifying the source format of the docs. 🤖 Generated by [robots](https://vyos.io)
2026-05-10Merge pull request #1943 from vyos/yuriy/fix-prs-conflict-workflow-refYuriy Andamasov
ci+docs: fix open-prs-conflict caller ref + refresh Mergify backport guidance
2026-05-10docs: refresh Mergify backport guidance — single-line syntax + maintainer-onlyYuriy Andamasov
- Update example to the consolidated `@Mergifyio backport circinus sagitta` form (multiple branches in one command, space-separated). The one-branch-per-line form still works but is no longer required. - Document that only Maintainers team members can invoke @Mergifyio commands — Mergify silently drops commands from anyone outside the team, with no error reply. Useful failure mode to know about: if a backport does not trigger, check team membership first. 🤖 Generated by [robots](https://vyos.io)
2026-05-10ci: fix open-prs-conflict caller — point at correct vyos/.github workflow fileYuriy Andamasov
The caller workflow referenced `vyos/.github/.github/workflows/check-open-prs-conflict.yml@current`, but that file does not exist in `vyos/.github`. The workflow was renamed to `check-pr-conflict.yml` (without "open") at some point after the caller was added in 86a282ec (#1638, 2025-05-26). Result: every push to a watched branch since at least 2026-05-07 has produced a "workflow file issue" failure. Verified via `gh api repos/vyos/.github/contents/.github/workflows`. The called workflow is `workflow_call`-callable with no inputs, so this is a one-line ref fix. No behavior change to the caller's trigger list. 🤖 Generated by [robots](https://vyos.io)
2026-05-10Merge pull request #1940 from vyos/yuriy/remove-rst-swap-mechanismYuriy Andamasov
chore: remove RST swap mechanism, archive rst-*.rst under docs/_rst_legacy/
2026-05-10docs: refresh README + sweep stale `current` refs in AGENTS.mdYuriy Andamasov
- Rewrite README.md: drop Python 2 install dance, drop `sphinx-panels` (removed years ago), drop `sudo pip install` antipattern, replace with venv + requirements.txt path. Refresh the branch table to current naming, point contributors at AGENTS.md for the full guide. Refresh the docs status badge to reference `rolling` (was `latest`). - AGENTS.md: replace remaining `current` branch references with `rolling` in the branch table, the "PRs target …" line, and the RTD layout table Branch column. The default branch was renamed `current` → `rolling` on 2026-05-10 (commit 8dbf8b05 only swept CI). 🤖 Generated by [robots](https://vyos.io)
2026-05-10chore: livehtml — drop stale md-* ignore, add _rst_legacy ignoreYuriy Andamasov
The md- prefix on MyST-migrated pages was retired; the ignore was dead config. Replace with _rst_legacy/ so sphinx-autobuild watches don't trigger on archive edits. Addresses Copilot's low-confidence suggestion on PR #1940. 🤖 Generated by [robots](https://vyos.io)
2026-05-10chore: remove RST swap mechanism, archive rst-*.rst under docs/_rst_legacy/Yuriy Andamasov
The swap mechanism (RST-as-fallback for migrated MD pages) is dormant — docs/_rst_overrides.txt has been empty since the MyST flip trio (#1899/#1900/#1901) landed in May 2026. The mechanism's surface area (scripts/swap_sources.py, its 245-line test, RTD pre/post hooks, Makefile glue, conf.py dynamic loader) is dead weight, and the rst-*.rst shadows scattered across the source tree cause Context7's parser to misclassify the project as RST. Changes: - Move 253 rst-*.rst shadow files into docs/_rst_legacy/ preserving subdirectory structure. They remain in the repo for reference; Sphinx excludes the folder via exclude_patterns; Context7 excludes it via excludeFolders. - Strip swap_sources.py invocation from docs/Makefile (swap/restore targets, : swap deps, trap chains). - Strip jobs: pre_build/post_build block from .readthedocs.yml. - Strip rst-*.rst exclude entry and the _md_exclude.txt loader from docs/conf.py; replace with a single _rst_legacy exclude. - Delete scripts/swap_sources.py, tests/test_swap_sources.py, docs/_rst_overrides.txt. - Update context7.json: add docs/_rst_legacy to excludeFolders; fix stale "Branch current tracks…" rule to "Branch rolling tracks…" (default branch was renamed 2026-05-10). - Update AGENTS.md: drop the "RST override mechanism" section and the test-runner snippet for the deleted test; describe _rst_legacy as archive only. Verified: sphinx-build -b html with --keep-going produces identical warning set (68 unique), identical sitemap entry count (257), identical llms.txt entry count (22), zero rst-* URLs in any artifact. 🤖 Generated by [robots](https://vyos.io)
2026-05-10Merge pull request #1939 from vyos/yuriy/github-casing-consistencyYuriy Andamasov
ci: GitHub casing consistency in workflow PR titles
2026-05-10ci: GitHub casing consistency in workflow PR titlesYuriy Andamasov
Cosmetic only — fixes "Github" → "GitHub" in three places that were left behind by the rename cleanup in #1938 (which fixed only the lines it already touched, to keep scope tight). - submodules.yml update_sagitta job: commit-message + title - submodules.yml update_equuleus job: commit-message + title - update-translations.yml: commit-message + title These strings appear in the titles/messages of bot-created PRs only; no functional impact. 🤖 Generated by [robots](https://vyos.io)
2026-05-10Merge pull request #1938 from vyos/yuriy/cleanup-rolling-referencesYuriy Andamasov
ci/docs: drop current branch references after rename to rolling
2026-05-10ci: inline doc lint workflow, drop vyos/.github cross-repo dependencyYuriy Andamasov
The reusable lint-doc workflow at vyos/.github checks out vyos/.github on the consumer's PR base.ref to source doc-linter.py — designed for per-release-train linter rules. With this repo's default renamed current → rolling and vyos/.github still on current, the checkout errors with "fetch +refs/heads/rolling*: exit code 1". Rather than chase branch parity across repos, move the linter where it belongs: doc-linter.py is doc-specific and only consumed here. Inlining removes the cross-repo coupling permanently and unblocks any future branch renames in this repo without touching vyos/.github. - scripts/doc-linter.py: copied byte-for-byte from vyos/.github@current:.github/doc-linter.py (sha 3dc7c2fc16242e62b0ea7107f767577e999ca417 — identical across all four release-train branches in vyos/.github, so no behavioral change). - .github/workflows/lint-doc.yml: replaces `uses: vyos/.github/.github/workflows/lint-doc.yml@current` with the inlined steps. Same actions (bullfrogsec/bullfrog, trilom/file-changes-action, setup-python) and the same final invocation, just sourcing the script from this repo. Adds explicit minimal permissions (contents/pull-requests read) and passes the file list via env var to follow the workflow- injection guidance. Follow-up: vyos/.github still hosts the now-orphaned doc-linter.py and its reusable workflow — separate cleanup PR can delete them once any other consumers migrate (none observed today; this repo was the only caller). 🤖 Generated by [robots](https://vyos.io)
2026-05-10ci: fix Github→GitHub typo in submodules.yml update_rolling jobYuriy Andamasov
In response to Copilot review on #1938 — the commit-message and title strings I touched while renaming current→rolling also had a "Github" typo. Same lines are already in this PR's diff, so corrected here. The same typo exists in update_sagitta and update_equuleus jobs and in update-translations.yml, but those lines are not in this PR's diff; folding them in would expand scope beyond the rename cleanup. They warrant a separate consistency PR. 🤖 Generated by [robots](https://vyos.io)
2026-05-10ci/docs: drop current branch references after rename to rollingYuriy Andamasov
Cleanup PR following the current→rolling default-branch rename. Drops the now-stale current branch from workflow triggers, flips remaining defaults, and updates documentation/templates. Workflows: - pr-mirror-repo-sync.yml: branches narrowed to [rolling]; workflow_dispatch default and choice list now rolling-only; sync_branch fallback flipped from 'current' to 'rolling'. - check-open-prs-conflict.yml: dropped current from push.branches. - update-version-tags.yml: dropped current from push.branches and from the case statement (now bare 'rolling) TAG=rolling'). - submodules.yml: renamed update_current job, branch update-dependencies-current, and the related commit/title strings to rolling. - update-translations.yml: PR branch update-translations-current renamed to update-translations-rolling. - ai-validation.yml: prompt example updated. Docs/templates: - docs/conf.py: READTHEDOCS_GIT_IDENTIFIER fallback flipped to 'rolling'; comment block updated to describe the rolling branch (the user-facing "(current)" suffix is release-channel terminology and remains). - README.md: branching-scheme section now describes rolling as the default branch, with a note about the rename date. - .github/PULL_REQUEST_TEMPLATE.md: CONTRIBUTING link points at blob/rolling. External @current refs to vyos/.github and vyos/vyos-cla-signatures are left untouched — they reference those repos' default branches and are unaffected by this repo's rename. 🤖 Generated by [robots](https://vyos.io)
2026-05-10Merge pull request #1937 from vyos/yuriy/preflight-rename-rollingYuriy Andamasov
ci: defensive triggers ahead of current→rolling default-branch rename
2026-05-10ci: derive sync branch by PR base and add rolling tag triggercopilot-swe-agent[bot]
Agent-Logs-Url: https://github.com/vyos/vyos-documentation/sessions/13538647-bbfb-438c-bec8-30f9ee0aa923 Co-authored-by: andamasov <12631358+andamasov@users.noreply.github.com>
2026-05-10ci: add rolling to workflow branch triggers ahead of current→rolling renameYuriy Andamasov
Defensive pre-flight for the planned rename of the default branch from current to rolling. Adds rolling alongside current to push/pull-request triggers and to the manual dispatch choice list so workflows continue to fire across the rename atomically. Workflow input defaults remain on current — they will be flipped, and current dropped, in the post-rename cleanup PR. Cosmetic naming (submodules.yml job/branch names, conf.py fallback, README, PR template link) is intentionally deferred to that cleanup PR to avoid documenting a branch that does not yet exist. 🤖 Generated by [robots](https://vyos.io)
2026-05-10Merge pull request #1878 from anderbak/t8608-tcp-ping-docsYuriy Andamasov
troubleshooting: T8608: document TCP ping
2026-05-10Merge pull request #1927 from natali-rs1985/T8600Yuriy Andamasov
T8600: Add option to change logging verbosity in Kea
2026-05-10Merge pull request #1934 from vyos/yuriy/version-tags-workflowYuriy Andamasov
ci: floating version tags + context7 switch (rolling/1.5/1.4)
2026-05-10docs(context7): pin previousVersions to release tags, not branchesYuriy Andamasov
context7.json now references the floating release tags (1.5, 1.4) created by .github/workflows/update-version-tags.yml instead of the internal branch names (circinus, sagitta). The tags are kept at the HEAD of their corresponding branches by the workflow, so consumers get the same content under stable, version-shaped names. 🤖 Generated by [robots](https://vyos.io)
2026-05-10ci(version-tags): switch to github.token and singular ref endpointYuriy Andamasov
- Use ${{ github.token }} for GH_TOKEN to match the convention in ai-validation.yml. - Existence check now uses the singular `git/ref/tags/$TAG` endpoint, which 404s when the tag is missing. The plural `git/refs/tags/$TAG` returns 200 with an array even when no exact match exists, which would route every run through the PATCH path and fail with 404 on any tag that has been deleted. 🤖 Generated by [robots](https://vyos.io)
2026-05-10ci: add concurrency group to prevent tag race on rapid pushescopilot-swe-agent[bot]
Agent-Logs-Url: https://github.com/vyos/vyos-documentation/sessions/49d35e98-ac39-4556-824a-e129c23f768e Co-authored-by: andamasov <12631358+andamasov@users.noreply.github.com>
2026-05-10ci: add workflow to keep version tags pointing at branch headsYuriy Andamasov
Maps branches to floating version tags so RTD can build canonical versioned URLs from a single ref name regardless of branch renames: - current -> rolling - circinus -> 1.5 - sagitta -> 1.4 The workflow force-moves the matching tag to the pushed SHA on every push to one of the three branches. Initial seed tags were created manually; subsequent updates are automatic. 🤖 Generated by [robots](https://vyos.io)
2026-05-10Merge pull request #1933 from vyos/yuriy/context7-enrichYuriy Andamasov
Enrich context7.json with project metadata, scope, and rules
2026-05-10Enrich context7.json with project metadata, scope, and rulesYuriy Andamasov
Adds the optional schema fields documented at https://context7.com/docs/adding-libraries to give the Context7 indexer clearer guidance: - projectTitle / description: stable display strings instead of LLM guesses on every refresh. - folders / excludeFolders / excludeFiles: limit indexing to docs/ and skip build artifacts, support scripts, and meta files. - rules: surface the conventions LLMs should respect when answering from VyOS docs — CLI mode separation, cfgcmd/opcmd authority, per-branch version mapping, no-invented-commands, and reserved documentation address space. - previousVersions: map circinus (1.5.x) and sagitta (1.4.x) so Context7 can serve version-appropriate answers. 🤖 Generated by [robots](https://vyos.io)
2026-05-10Merge pull request #1932 from vyos/yuriy/add-context7-configYuriy Andamasov
Add context7.json for repo ownership on context7.com
2026-05-10Add context7.json to claim repo ownership on context7.comYuriy Andamasov
Allows the repo owner to manage Context7 indexing settings (refresh cadence, exclusions, branding) for https://context7.com/vyos/vyos-documentation. 🤖 Generated by [robots](https://vyos.io)
2026-05-09Merge pull request #1931 from kumvijaya/currentYevhen Bondarenko
T8835: added pr mirror workflow
2026-05-10T8835: added pr mirror workflowVijayakumar A
2026-05-08Merge pull request #1877 from LiudmylaNad/remove-deprecated-cloud-init-docsYuriy Andamasov
DOCS: Remove deprecated cloud-init page
2026-05-08T8600: Add option to change logging verbosity in KeaNataliia Solomko
2026-05-08docs: Remove deprecated cloud-init pageMilaNad
2026-05-08troubleshooting: T8608: document TCP pinganderbak
2026-05-07Merge pull request #1871 from vyos/feat/docs-cookiebot-gtm-consentYuriy Andamasov
feat(docs): add Cookiebot CMP and GTM with Consent Mode v2
2026-05-07fix(docs): add missing space after colon in personalization_storageYuriy Andamasov
🤖 Generated by [robots](https://vyos.io)
2026-05-07feat(docs): move Cookiebot CBID to COOKIEBOT_ID env varYuriy Andamasov
Read COOKIEBOT_ID from the environment via conf.py html_context, replacing the hardcoded data-cbid value in layout.html. Guards tightened to {% if gtm_id and cookiebot_id %} so neither GTM nor Cookiebot loads unless both IDs are present. 🤖 Generated by [robots](https://vyos.io)
2026-05-07fix(docs): guard GTM/Cookiebot blocks with {% if gtm_id %}Yuriy Andamasov
Prevents broken googletagmanager.com requests with empty container IDs when GTM_ID is not set (local builds, preview environments). 🤖 Generated by [robots](https://vyos.io)
2026-05-07feat(docs): read GTM_ID from environment instead of hardcodingYuriy Andamasov
Move the Google Tag Manager container ID out of the template and into conf.py via os.environ.get('GTM_ID', ''), exposed to Jinja via html_context. Set GTM_ID in the RTD project environment variables. 🤖 Generated by [robots](https://vyos.io)
2026-05-07fix(docs): remove stray </script> and add title to GTM noscript iframeYuriy Andamasov
🤖 Generated by [robots](https://vyos.io)
2026-05-07fix(docs): deduplicate GTM ID via Jinja var and use window.dataLayer in gtag()copilot-swe-agent[bot]
Agent-Logs-Url: https://github.com/vyos/vyos-documentation/sessions/f6d95cc7-cdbe-4d76-8077-f7fae5e9ddf2 Co-authored-by: andamasov <12631358+andamasov@users.noreply.github.com>
2026-05-07feat(docs): add Cookiebot CMP and GTM with Consent Mode v2Yuriy Andamasov
Inject Cookiebot CMP, Google Consent Mode v2 defaults, and Google Tag Manager into the Sphinx layout. Cookiebot loads first so its auto-blocker can scan and block other tags before they execute; Consent Mode v2 starts denied for all categories except security_storage and updates only after Cookiebot fires the consent update. 🤖 Generated by [robots](https://vyos.io)