Skip to content

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 18 Jul 21:07
· 28 commits to refs/heads/v0.2.0 since this release
e129f01

Changes

  • #1013 | perf(cargo): tune release profile (lto=fat, codegen-units=2) for lancache-ui and nats-subscriber
  • #982 | security: eliminate remaining argv secret exposure found during #955 review
  • #981 | refactor(tests): dedupe cmd_secondary heredoc-extraction logic in bats tests
  • #943 | test(setup): cover the reset-to-last-known-good-config Kea recovery family
  • #795 | fix: prove SSL-mode DNS routes to a distinct MITM endpoint (#668)
  • #744 | fix: close arm64 rollout gaps in backfill guard, docs, and setup.sh platform check
  • #746 | fix: harden ssl-mitm-cache-simulation.sh against 5 robustness gaps
  • #747 | docs: explain shared validation-network proxy address for SSL/standard DNS (#668)
  • #713 | docs: batch-fix 7 documentation accuracy issues
  • #708 | fix: prefix build-tools branch tags to avoid release-tag collision
  • #690 | ci: derive Compose project name and Admin UI port per validation run
  • #691 | ci: attest the merged multi-platform manifest digest in merge-manifests
  • #689 | test: repeat-run idempotence proof for Kea DHCP config snapshot adapter (#640)
  • #693 | fix(dhcp): stop writing host-reservation-identifiers at Kea subnet scope
  • #687 | ci: complete cheap-lint GitHub-hosted fallback, document Rust/image fallback decision
  • #688 | test: repeat-cycle convergence tests for watchdog restart/status writer
  • #684 | fix: close build-tools manifest merge permission and tag races
  • #643 | feat(dhcp-proxy): expose configurable dnsmasq relay/proxy DHCP options
  • #678 | fix(ci): publish_coverage_badge skipped on push due to implicit success() trap
  • #589 | ci(_Issue510): publish dynamic Rust coverage badge
  • #631 | feat: persisted known-good Kea DHCP config snapshots (#614)
  • #638 | feat(logging): syslog-ng central receiver + fluent-bit forwarder (dev/prod/quickstart)
  • #637 | dhcp: safe Kea activation preflight before serving LAN clients
  • #641 | test: repeat-run idempotence proof for setup.sh update .env migration (#456)
  • #649 | docs: reword CHANGELOG "Unreleased" heading to reflect the dev channel
  • #642 | dhcp: real Kea lease-flow behavior test, distinct from #377 discovery
  • #635 | docs: define project-wide runtime naming convention
  • #636 | fix: remove last CACHE_DIR_STANDARD/CACHE_DIR_SSL residue after single-CACHE_DIR migration
  • #629 | fix: publish OCI index-level description annotations on manifest lists
  • #627 | ci: push PR-scoped staging tags so full-setup-validate tests the PR's own commits
  • #616 | feat: known-good configuration snapshots for nginx and dnsmasq (#415)
  • #600 | ci: default full-setup-validate to edge, not stale latest
  • #624 | ci: derive full-setup-validate subnet per-run instead of hardcoded 172.30.99.0/24
  • #618 | fix: restore executable bit on ui-nats-dns-integration-simulation.sh
  • #613 | fix: feed distcc-pump bare hostnames and stop treating --randomize as a host list
  • #609 | fix: distinguish git dubious-ownership rejection from no-.git in setup.sh
  • #602 | ci: add a check that git-tracked files use Unix (LF) line endings
  • #594 | ci: execute setup.sh end-to-end instead of only bash -n (#403)
  • #612 | docs: move Watchtower entry from Deprecated to Changed in CHANGELOG.md
  • #608 | feat: real UI -> NATS -> DNS integration test, fix LAN record flow being completely non-functional
  • #606 | fix: build docker CLI and docker-compose from source to fix CVE-2026-39822
  • #598 | ci: real DNS/HTTP/HTTPS caching test against a Debian mirror
  • #604 | fix: register template functions before parsing templates in load_templates
  • #592 | ci: native arm64 image builds on GitHub-hosted runners
  • #593 | docs(agents): AG-CI-008 -- Dockerfile ARG defaults are not a CI bug
  • #582 | ci(_Issue557): add full-setup client simulation
  • #588 | ci(_Issue528): verify build-tools arm64 scan image
  • #591 | ci: _Issue509 github-hosted fallback for shellcheck and policy
  • #584 | feat(_Issue556): add DHCP lease release and custom options
  • #587 | feat(_Issue544): show running image version in Admin UI
  • #585 | docs(_Issue549): document single cache migration touchpoints
  • #576 | ci(_Issue569): attest stack pointer provenance
  • #580 | ci(_Issue565): allow host network scan builds
  • #572 | fix(_Issue563): migrate legacy strict proxy defaults
  • #575 | ci(_Issue570): avoid build-tools fallback on light runner
  • #579 | ci(_Issue566): run coverage merge in build-tools
  • #581 | feat(_Issue560): run dashboard collectors concurrently
  • #578 | ci(_Issue567): refresh build-tools multiarch bases
  • #564 | docs: align action pinning guidance
  • #577 | fix(_Issue568): carry pinned release tag resolution
  • #574 | fix(_Issue561): preserve UI auth secret generation failures
  • #573 | docs(_Issue562): document mirror.gcr.io base image policy
  • #586 | docs(governance): merge triplicate no-new-language rules into AG-REL-001
  • #531 | chore(governance): Track B hardening — rule IDs, enforcement matrix, conflict resolution, closing-report contract
  • #554 | Update CONTRIBUTING.md for AI assistance notice
  • #551 | docs: expand NGINX_UPSTREAM_RESOLVER note in README into a clear explanation
  • #553 | feat: add project logo, favicon, and Admin UI branding
  • #548 | feat: derive SSL cert root domains from cdn-domains.txt via real PSL
  • #530 | docs: Fix three documentation-drift issues (DNS, auth, console behavior)
  • #546 | fix(proxy): correct X-Served-By response header to lancache-ng
  • #542 | Promote v0.2.0 to master (publishes as edge channel)
  • #543 | docs: reconstruct full v0.2.0 changelog, bump crate versions to 0.2.0
  • #541 | ci: re-authenticate to GHCR and back off before the in-job build retry
  • #539 | fix(quickstart): copy dhcp-probe.sh into install dir, not just docker-socket-proxy.sh
  • #527 | fix: improve error message when latest channel is unavailable
  • #518 | feat(dhcp): complete dnsmasq-proxy mode with docs, tests, and compose coverage
  • #517 | ci(codeql): surface Rust extraction-quality signal instead of silent green
  • #535 | fix(ui): missing curl for full-setup healthcheck + drop unauthorized Go toolchain from build-tools
  • #522 | docs: require issue depth and explicit successor-coverage statements
  • #534 | fix(ci): make validate-full-setup-image wait for promote on push events
  • #533 | fix(ci): stop promote/release from being silently skipped on push events
  • #521 | fix(build): add sccache-failure fallback to Dockerfile run_cargo_build
  • #520 | docs: document dev-stack .env resolution and Admin-UI auth-gate behavior
  • #515 | test(nats-subscriber): add unit tests for real subscribe/forward logic (Closes #504)
  • #512 | docs: document build-tools container as the only valid verification path
  • #513 | docs: create CHANGELOG.md with v0.1.0 release notes
  • #511 | docs: fix outdated two-proxy architecture description
  • #516 | fix(ci): resolve full-setup-validate image channel from the target branch
  • #514 | fix(tests): use single-quoted trap in setup-migration-semantics.sh
  • #507 | feat(ci): wire up the documented but never-implemented dev channel
  • #503 | ci: trigger build-push/codeql/build-tools workflows on v0.2.0 too
  • #482 | ci: refresh build-tools libc headers

🐛 Fixed

  • #1022 | ci: verify bats/shellspec/docker buildx in build-tools smoke test + add drift guard (#822 Pattern G)
  • #984 | fix: collect all missing cmd_secondary arguments and report together
  • #976 | fix: sync cmd_secondary() heredoc healthcheck with dig-based probe (#946)
  • #978 | fix: close DHCP domain/hostname/MAC validation gaps and CSRF-exempt GET /api/dhcp/check
  • #960 | security: validate cdn-domains.txt entries before generating RPZ rules
  • #933 | fix(ci): persist validation teardown env before non-retryable failures (#932)
  • #953 | test: explain what each UI test actually checks (config.rs, main.rs, dhcp.rs)
  • #956 | fix: stop exposing PAT/token as plain argv secrets
  • #951 | test: basic_auth middleware full-chain integration tests
  • #958 | docs: translate remaining German comments in deploy configs
  • #931 | ci: retry Buildx bootstrap on GitHub-hosted arm64 runners
  • #941 | fix(setup): declare leaked locals in migrate_env_for_update and cmd_secondary
  • #939 | fix(setup): fail closed on cmd_restore's install-path sed rewrite
  • #936 | fix(ci): verify base-channel image freshness before untouched-service backfill
  • #934 | fix(ci): governance-guard check live-fetches PR title/body instead of stale event snapshot
  • #929 | ci: generation-age retention for persistent Trivy cache dirs
  • #927 | ci(build-tools.yml): scope Trivy cache dirs per ref and self-clean ephemeral ones
  • #911 | fix(ci): stop racing Docker's growing restart backoff in crash-loop sim final check
  • #881 | fix(ui): refuse remote-secondary registration without a reachable NATS URL
  • #924 | fix(ci): ci_scope_policy Buildx guard could never fail (self-matching grep pattern)
  • #922 | fix(ci): remove per-row fork storm in check-logging-matrix.sh's doc parser (Refs #633)
  • #918 | fix(ci): serialize promote/backfill tag moves with a git-ref lock, not GH concurrency
  • #916 | fix(nats): grant dns-ssl replica publish on lancache.dns.record (#906)
  • #909 | fix(ci): strip CRLF from gh-fetched PR bodies before awk parsing
  • #882 | fix(dns): grant rollback flush publish permission + surface flush failure (#867)
  • #907 | ci: wrap two unwrapped stack-starting validation jobs in run-in-validation-subnet.sh
  • #878 | fix(ui): report error instead of success on failed CDN domain write
  • #905 | fix(ci): widen workflow-level permissions, fetch PR labels/milestone live too (#903 follow-up)
  • #877 | fix: standardize SYSLOG_ENABLED/SYSLOG_MAX_GB parsing between Admin UI and watchdog
  • #903 | fix(ci): checkout in ci_scope_policy (#901), fetch PR body live not from stale event payload
  • #892 | fix(ci): scope build-push.yml cancellation to build/container-scan, not the whole run
  • #880 | fix(ci): expand build-tools.yml path filter to real bats dependencies
  • #890 | docs: stop CHANGELOG.md merge-conflict cascade at its source (Fixes #889)
  • #885 | fix: watchdog.sh hardening bundle (disk_info JSON, curl timeout/healthcheck, CONTAINER_* allowlist, maybe_purge)
  • #883 | fix: make setup.sh's functional health gate fail closed on a missing probe tool
  • #884 | ci: redesign validation-subnet address pool to /27 slots within 172.30.0.0/16 (#832)
  • #876 | fix: real dig-based DNS healthcheck across all deploy profiles (#869)
  • #865 | fix(ui): wire /logs syslog-mode host filter through to parse_syslog_tail
  • #863 | docs: add CHANGELOG entry for #834 validation-network teardown race fix
  • #861 | fix(ui): stop noisy hosts from starving quiet hosts in /logs merge
  • #855 | fix(ui): auto-generate secondary registration token when missing
  • #835 | fix: wait for real endpoint detach before removing validation networks
  • #817 | fix(nats): stop entrypoint clobbering the UI's auth_callout config (#811)
  • #821 | ci: reserve a locked validation subnet in deep-validate stack jobs (Refs #820)
  • #813 | fix(setup): escape unescaped backticks in the .env heredoc's comment
  • #810 | fix(ci): pull fresh images before dns-zone-rollback-simulation's stack
  • #807 | fix(ci): wait for rollback listener readiness before baseline read (#806)
  • #792 | fix: recognize sccache-dist server-side failures in fallback regex (#783)
  • #784 | fix(dhcp,dns): reverse (PTR) DDNS updates always fail against a non-existent zone
  • #786 | ci: pin setup.sh CLI simulation to the PR's own immutable image
  • #789 | ci: build docker buildx from source into build-tools image
  • #769 | fix(dhcp,dns): DDNS updates never reach PowerDNS (loopback bind, wrong port, empty allow-list)
  • #750 | fix: pre-check DHCP settings writability and roll back on persist failure
  • #776 | fix: select-build-tools-image.sh trusted a stale, incomplete published image
  • #774 | fix: point Kea file-log output at /var/log/kea, not /var/log/lancache-dhcp
  • #742 | fix: skip unreadable lines in get_log_stats instead of truncating scan
  • #741 | perf: make parse_log_tail O(tail window) instead of O(file size)
  • #740 | fix: preserve each retained line's own terminator in remove_domain
  • #749 | fix: resolve NTP hostnames before writing Kea ntp-servers option in Admin UI
  • #748 | fix: close backup/restore safety gaps in setup.sh
  • #745 | fix: cmd_update_ip operates on the real install directory, not repo checkout
  • #738 | fix: nak-and-stop batch on retryable PDNS update failure (#653)
  • #734 | docs: document kea-ctrl-agent.conf must not be hand-edited
  • #743 | fix: require a real SECONDARY_REGISTRATION_TOKEN, not just non-empty
  • #737 | fix: widen PowerDNS authoritative webserver-allow-from to full RFC1918
  • #760 | ci: close full-setup-validate subnet reservation race with host-local locking
  • #739 | fix: anchor SAN IP match and clean up cert artifacts on sign failure
  • #736 | fix: add missing healthcheck to secondary DNS docker-compose
  • #731 | fix: converge .env and validate compose config during setup.sh restore
  • #726 | ci: harden watchtower-update-simulation against 5 real Codex findings
  • #720 | fix: detect stale PDNS_API_KEY after pdns.conf rollback (mirrors recursor-side check)
  • #714 | ci: fix nats-secondary-auth-callout-simulation.sh exec bit and Kea lease-flow success-check
  • #721 | fix: remove reviewer/PR references from dhcp.rs code comments
  • #537 | fix(ci): detect-changes diffs against the real merge-base, not base's moving tip
  • #485 | fix(dhcp-proxy): disable DNS port explicitly with additional config o…

🚀 Added

  • #900 | feat(ci): automated changelog pipeline (release-drafter + changelog-updater-action)
  • #886 | feat(secrets): generalize shared-secret bootstrap (PDNS_API_KEY, KEA_CTRL_TOKEN, DDNS_TSIG_KEY, NATS_*_PASSWORD)
  • #794 | feat: Admin UI reachability test + setup.sh reset-to-last-known-good-config CLI (#763)
  • #831 | feat(ui): add Admin UI release-channel and scheduled-update control (#819)
  • #830 | feat(setup): add the ordered, health-gated update orchestrator (#819)
  • #827 | feat(setup): add an interactive stable/edge release channel picker
  • #782 | setup.sh: add create-logs-for-issue diagnostic bundle command
  • #788 | feat: add PowerDNS zone/record known-good snapshot rollback (#628)
  • #764 | ci: add an automatic per-PR deep full-setup validation gate
  • #758 | feat(ui): Admin UI reader for the central syslog-ng log store (#633 PR4)
  • #767 | docs(governance): require labels/milestone/project on PRs, not just issues
  • #753 | ci: logging-matrix drift guard + fluent-bit healthcheck (issue #633)
  • #756 | feat: wire remaining services into central logging pipeline (issue #633)
  • #759 | fix: preserve NATS-secondary override and restore .env.local convergence in setup.sh
  • #757 | feat(watchdog): add storage-budget retention engine for syslog-ng logs
  • #733 | feat(ui): surface discovered DHCP server details in Admin UI
  • #732 | test: add repeat-run idempotence coverage for NATS config writer + CI guard (#640)
  • #735 | docs: scope DNS/PowerDNS Admin UI feature surface (#645)
  • #730 | docs: scope the PDNS zone/record/TSIG/DDNS rollback design (#628)
  • #731 | fix: converge .env and validate compose config during setup.sh restore
  • #694 | ci: add a real Kea Control Agent mutation round-trip test to full-setup-validate
  • #625 | feat: known-good configuration snapshots for PowerDNS static config (#615)
  • #621 | feat: per-secondary NATS identity via auth callout (#583)
  • #622 | ci: verify Watchtower's real update behavior end-to-end (#611)
  • #446 | feat: migrate to single CACHE_DIR, remove split cache keys
  • #525 | test: add DNS zone generation tests (bats-core)
  • #524 | test: add comprehensive bats suite for proxy cert generation (Closes #401)
  • #461 | Add ShellSpec setup host simulation fixtures
  • #499 | ci: add GitHub-hosted fallback for file-headers check
  • #460 | Add bats-core setup migration fixtures
  • #498 | ci: add full-setup GHCR image for offline deterministic validation
  • #500 | docs: publish build-status badge and document coverage measurement
  • #497 | ci: pin CI/runtime images by immutable SHA (policy + detection script)
  • #501 | ci: add PR template validator check for required metadata
  • #496 | ci: fail CI on actionable warnings with explicit exception policy
  • #494 | test: add Rust and setup validation test suite coverage
  • #495 | ci: add Rust coverage reporting and gating (tarpaulin + threshold)

📚 Documentation

  • #1026 | docs: fix stale serial-file path and add concurrency-guard doc (#921 partial)
  • #1006 | docs: re-verify SoT-ui-routes.md against current v0.2.0
  • #1003 | docs: services/dns bug-hunt findings, finding #1 marked FIXED (issue #849)
  • #1010 | docs: watchdog bug-hunt findings, mark 11 fixed by PRs #880/#885 (issue #849)
  • #1009 | docs: re-verify bughunt-ui-routes findings against current v0.2.0
  • #1008 | docs: observability bug-hunt findings, mark #4/#5/#9/#10 fixed (issue #849)
  • #1001 | docs(setup): currency-check bug-hunt setupsh.md against v0.2.0 (#1 fixed, #8 partly stale)
  • #1007 | docs: observability capability inventory, update PR #828/#865 status (issue #843)
  • #1005 | docs: bug-hunt findings for services/ui core (re-verified, 2 findings corrected)
  • #1004 | docs: services/proxy capability inventory, clarify CIDR-allowlist scope (issue #843)
  • #1002 | docs: re-verify SoT-ui-core.md against current v0.2.0
  • #1000 | docs(setup): currency-check SoT-setupsh.md against v0.2.0 @ dc8d79c
  • #1011 | docs: watchdog capability inventory, update test-coverage status (issue #843)
  • #1012 | docs(governance): add AG-GH-17 (branch traceability) and AG-WF-024 (sub-agent worktree/force-push safety)
  • #997 | fix(nats): grant replica STREAM.CREATE permission + currency-check nats.md (Finding D FIXED)
  • #996 | docs: services/dns capability inventory (issue #843)
  • #995 | docs: services/proxy bug-hunt findings (issue #849)
  • #994 | docs(nats): currency-check SoT-nats.md against v0.2.0 @ dc8d79c
  • #993 | docs: dnsmasq-proxy bug-hunt findings (issue #849)
  • #992 | docs: dnsmasq-proxy capability inventory (issue #843)
  • #991 | docs: DHCP bug-hunt findings for services/dhcp (issue #849)
  • #980 | docs: restore two WHY-comments dropped when duplicate PR #948 was closed
  • #969 | docs(agents): reconcile AGENTS.md across master/v0.2.0, tag 28 missing rule IDs
  • #971 | docs(claude): reconcile CLAUDE.md across master/v0.2.0, tag 12 missing rule IDs
  • #954 | docs(agents): add AG-VAL-024 for the exec-bit/Windows authoring blind spot
  • #920 | docs: clarify AG-WF-017's marker belongs in the body, never the title
  • #902 | docs: add AG-WF-018 (duplicate-issue check) and AG-WF-019 (bash cd/pwd chaining) to AG-WF-017/AG-VAL-023
  • #890 | docs: stop CHANGELOG.md merge-conflict cascade at its source (Fixes #889)
  • #779 | docs: reconcile AG-VAL-021/AG-VAL-022 CodeQL carve-out wording
  • #758 | feat(ui): Admin UI reader for the central syslog-ng log store (#633 PR4)
  • #767 | docs(governance): require labels/milestone/project on PRs, not just issues
  • #753 | ci: logging-matrix drift guard + fluent-bit healthcheck (issue #633)
  • #756 | feat: wire remaining services into central logging pipeline (issue #633)
  • #757 | feat(watchdog): add storage-budget retention engine for syslog-ng logs
  • #729 | docs+config: fix NGINX_UPSTREAM_RESOLVER override docs, add IPv6 default
  • #728 | docs: stop Option B one-liner from exposing ca.key on the LAN
  • #725 | docs(governance): reconcile AGENTS.md precedence list and CodeQL carve-out self-contradictions (#701, #702)
  • #721 | fix: remove reviewer/PR references from dhcp.rs code comments
  • #500 | docs: publish build-status badge and document coverage measurement

🧰 Chore / CI

  • #1025 | ci: add orphaned-branch guard (script + scheduled workflow)
  • #1015 | fix(ci): wrap unguarded command-substitution assignments in scripts/*-simulation.sh
  • #1024 | fix(ci): replace prose incomplete-scope scan with Partial-Fix: #NNNN trailer (#1023)
  • #1017 | fix(ci): governance-guard fetches PR base SHA directly so long-lived PRs don't crash (#1016)
  • #1022 | ci: verify bats/shellspec/docker buildx in build-tools smoke test + add drift guard (#822 Pattern G)
  • #1021 | ci: add check-executable-bits.sh guard against bare-path script invocation with lost exec bit (#822 Pattern B)
  • #1020 | docs: document mutable-tag/cached-image distrust convention in AGENTS.md (#822 Pattern A)
  • #999 | ci: guard build-tools.yml's bats path filter against dependency drift
  • #998 | ci: shared quickstart-compose-lock.sh, dedupe 3 inline flock copies
  • #997 | fix(nats): grant replica STREAM.CREATE permission + currency-check nats.md (Finding D FIXED)
  • #985 | fix: sync CA subject string between generate-ca.sh and proxy entrypoint.sh (#968)
  • #988 | security: case-insensitive placeholder detection + cross-implementation parity fixture
  • #987 | ci: stop dev-channel starvation from cancel-in-progress on push (build-push.yml)
  • #983 | fix(ci): scan tests/bats/*.bats with shellcheck, fix real+false-positive findings (CLD-1784358369)
  • #962 | ci: derive-validation-network calls the shared subnet-slot script directly (#822 pattern)
  • #977 | fix(ci): ensure-pr-staging-images congestion probe queries build-push runs by the wrong SHA
  • #964 | ci: guard services_with_healthcheck against silent divergence (#822 pattern)
  • #966 | ci: build-push.yml calls validation-image-tag.sh's functions directly (#822 pattern)
  • #933 | fix(ci): persist validation teardown env before non-retryable failures (#932)
  • #937 | ci: guard build-push.yml service lists against silent divergence
  • #931 | ci: retry Buildx bootstrap on GitHub-hosted arm64 runners
  • #936 | fix(ci): verify base-channel image freshness before untouched-service backfill
  • #934 | fix(ci): governance-guard check live-fetches PR title/body instead of stale event snapshot
  • #929 | ci: generation-age retention for persistent Trivy cache dirs
  • #927 | ci(build-tools.yml): scope Trivy cache dirs per ref and self-clean ephemeral ones
  • #911 | fix(ci): stop racing Docker's growing restart backoff in crash-loop sim final check
  • #914 | fix(ci): make ensure-pr-staging-images.sh's poll congestion-aware
  • #926 | ci: teach ci_scope_policy to tolerate legitimate supersession, extend cancel-in-progress to remaining #891 candidates
  • #925 | ci: self-clean ephemeral (dispatch/rerun/tag) Trivy cache dirs at job end
  • #924 | fix(ci): ci_scope_policy Buildx guard could never fail (self-matching grep pattern)
  • #922 | fix(ci): remove per-row fork storm in check-logging-matrix.sh's doc parser (Refs #633)
  • #917 | ci: add standing guard against unwrapped validation-subnet jobs (#896)
  • #915 | ci: extend job-level cancel-in-progress to rust_coverage, shellcheck, file-headers, line-endings, ci_scope_policy
  • #913 | fix(ci): scope container-scan's Trivy cache dirs per ref to close a #892-enabled race
  • #918 | fix(ci): serialize promote/backfill tag moves with a git-ref lock, not GH concurrency
  • #909 | fix(ci): strip CRLF from gh-fetched PR bodies before awk parsing
  • #905 | fix(ci): widen workflow-level permissions, fetch PR labels/milestone live too (#903 follow-up)
  • #900 | feat(ci): automated changelog pipeline (release-drafter + changelog-updater-action)
  • #903 | fix(ci): checkout in ci_scope_policy (#901), fetch PR body live not from stale event payload
  • #892 | fix(ci): scope build-push.yml cancellation to build/container-scan, not the whole run
  • #880 | fix(ci): expand build-tools.yml path filter to real bats dependencies
  • #884 | ci: redesign validation-subnet address pool to /27 slots within 172.30.0.0/16 (#832)
  • #863 | docs: add CHANGELOG entry for #834 validation-network teardown race fix
  • #857 | chore: backport 5 master-only commits into v0.2.0
  • #852 | fix(ci): make Dependabot also scan v0.2.0, not just master
  • #828 | test(ci): real syslog-ng -> Admin UI visibility E2E simulation (Refs #453)
  • #835 | fix: wait for real endpoint detach before removing validation networks
  • #794 | feat: Admin UI reachability test + setup.sh reset-to-last-known-good-config CLI (#763)
  • #833 | ci: extend GHCR 401-retry policy (#541) to every registry-writing call site (#822)
  • #829 | feat(setup): remove Watchtower, add scheduled-update opt-in in its place
  • #826 | ci: add automated SemVer patch-tag engine to the promote job
  • #824 | ci: extract detect-changes classifier into scripts/classify-image-impact.sh
  • #821 | ci: reserve a locked validation subnet in deep-validate stack jobs (Refs #820)
  • #804 | ci: guard against pinned GitHub Actions declaring a deprecated Node runtime
  • #810 | fix(ci): pull fresh images before dns-zone-rollback-simulation's stack
  • #793 | fix(ci): give promote its own concurrency group + debounce stale tag moves
  • #807 | fix(ci): wait for rollback listener readiness before baseline read (#806)
  • #792 | fix: recognize sccache-dist server-side failures in fallback regex (#783)
  • #800 | ci: bump actions/upload-artifact v4.3.6 -> v7.0.1 (deprecated Node 20)
  • #780 | fix: rebuild proxy image when cdn-domains.txt changes
  • #786 | ci: pin setup.sh CLI simulation to the PR's own immutable image
  • #789 | ci: build docker buildx from source into build-tools image
  • #779 | docs: reconcile AG-VAL-021/AG-VAL-022 CodeQL carve-out wording
  • #776 | fix: select-build-tools-image.sh trusted a stale, incomplete published image
  • #764 | ci: add an automatic per-PR deep full-setup validation gate
  • #767 | docs(governance): require labels/milestone/project on PRs, not just issues
  • #765 | fix(dhcp-proxy): opt-in PXE boot-pointer support + real PXE simulation
  • #751 | CI audit: workflow logic verified free of the implicit-success() silent-skip trap
  • #759 | fix: preserve NATS-secondary override and restore .env.local convergence in setup.sh
  • #761 | test(dhcp): verify Kea static host reservations are honored end-to-end
  • #732 | test: add repeat-run idempotence coverage for NATS config writer + CI guard (#640)
  • #752 | fix(ui): resolve clippy lints in is_valid_dns_label
  • #760 | ci: close full-setup-validate subnet reservation race with host-local locking
  • #726 | ci: harden watchtower-update-simulation against 5 real Codex findings
  • #694 | ci: add a real Kea Control Agent mutation round-trip test to full-setup-validate
  • #725 | docs(governance): reconcile AGENTS.md precedence list and CodeQL carve-out self-contradictions (#701, #702)
  • #714 | ci: fix nats-secondary-auth-callout-simulation.sh exec bit and Kea lease-flow success-check
  • #721 | fix: remove reviewer/PR references from dhcp.rs code comments
  • #723 | test: correct DHCP/DDNS bats test overclaims (is_ipv4 scope, reverse-DDNS TSIG assertion)
  • #622 | ci: verify Watchtower's real update behavior end-to-end (#611)
  • #676 | test: add WHY-comments to dhcp_kea_config_generation.bats
  • #523 | docs: clarify build-tools :latest policy boundaries
  • #526 | test: implement Kea/DHCP config generation tests (issue #404)
  • #525 | test: add DNS zone generation tests (bats-core)
  • #524 | test: add comprehensive bats suite for proxy cert generation (Closes #401)
  • #537 | fix(ci): detect-changes diffs against the real merge-base, not base's moving tip
  • #461 | Add ShellSpec setup host simulation fixtures
  • #499 | ci: add GitHub-hosted fallback for file-headers check
  • #460 | Add bats-core setup migration fixtures
  • #498 | ci: add full-setup GHCR image for offline deterministic validation
  • #500 | docs: publish build-status badge and document coverage measurement
  • #497 | ci: pin CI/runtime images by immutable SHA (policy + detection script)
  • #501 | ci: add PR template validator check for required metadata
  • #496 | ci: fail CI on actionable warnings with explicit exception policy
  • #494 | test: add Rust and setup validation test suite coverage
  • #495 | ci: add Rust coverage reporting and gating (tarpaulin + threshold)