v0.2.0
·
28 commits
to refs/heads/v0.2.0
since this release
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)