release: publish v0.1.0-alpha.5 - #70
Merged
Merged
Conversation
foxly-it
added a commit
that referenced
this pull request
Aug 5, 2026
…earlier) (#86) rootguard-webapp#68 and #70 were already merged but this repo's submodule pointer and roadmap checkboxes were never updated - an oversight caught by an explicit audit request rather than during the normal per-PR workflow. Bumps the submodule, checks both items, and records both in project-state.md. Also removes a stale "not yet built" note about global search that was left behind after #64 shipped.
foxly-it
added a commit
that referenced
this pull request
Aug 5, 2026
* Initial rootguard-unbound engine (Debian based) + GH Actions * Fix Dockerfile: remove entrypoint and stabilize build * Fix: use system user instead of fixed UID * Fix: use packaged unbound system user * Add MIT license and README * Enterprise versioning: automatic Debian Unbound tagging * Fix Docker tag: sanitize Debian version (+ → -) * update README.md * Finalize recursive DNSSEC configuration with persistent trust anchor * Finalize Debian-based recursive DNSSEC configuration (enterprise commented) * Run container as root (Debian compliant), let unbound drop privileges internally * Install dns-root-data package to provide Debian root.key * Container-optimized recursive DNSSEC configuration with documentation * Finalize enterprise container-optimized Unbound configuration * Finalize container-optimized Unbound configuration (no pidfile, no syslog) * Move DNSSEC trust anchor to /var/lib/unbound (writable runtime path) * Add runtime entrypoint to fix volume ownership and drop privileges correctly * Finalize runtime bootstrap: proper trust anchor handling without su * Enterprise runtime model: root PID1 + internal privilege drop * Enterprise entrypoint: state init + ownership fix + DNSSEC bootstrap * Replace unbound-anchor bootstrap with Debian trust anchor copy * Remove unbound-anchor, use Debian dns-root-data trust anchor * Finalize immutable runtime model with documented unbound.conf * Finalize immutable runtime model with documented unbound.conf * cleanup: remove legacy entrypoint.sh, keep docker-entrypoint.sh * feat: stable rootguard unbound base image with dnssec, internal bind and production defaults * fix: install unbound-anchor for automatic dnssec trust anchor generation * fix: bind unbound to 0.0.0.0 for docker port mapping compatibility * stable: production-ready rootguard unbound base image * stable: production-ready rootguard unbound image without anchor hard-fail * stable: Debian 13 compliant rootguard unbound image using dns-root-data trust anchor * fix: use writable trust anchor in /var/lib/unbound (Debian 13 compliant) * final: Debian 13 compliant writable trust anchor under /var/lib/unbound * fix: explicit IPv4 + IPv6 binding for Docker compatibility * final: docker-compatible access-control with bridge network support * phase2: rootguard-ready modular unbound base (unbound.d includes) * update README.md * Initial commit * Add initial backend implementation (health + version endpoints) * Initial project structure * Add Apache 2.0 license * Add NOTICE * Add professional project README * ci: add GHCR multi-arch pipeline + improved Dockerfile * feat: full-stack container integration with stable SPA routing * feat(ui): professional dashboard layout with status indicator * feat: stabilize router + SPA fallback, add dashboard API + service endpoint, UI glass layout baseline * backend: add docker stats engine, system API and dashboard metrics * feat(service-engine): implement service detection engine - add /api/services endpoint - implement binary detection (AdGuard, Unbound) - implement docker container detection - filter infrastructure containers - improve process detection using pgrep exit codes - integrate detection into router RootGuard milestone: Service Discovery Engine * feat(service-control): implement docker container lifecycle control * feat: introduce rootguard service model * feat: introduce service registry * fix: regenerate package-lock for CI build * fix: extend service model to support detection layer fields * refactor: remove duplicate service model file * Build secure RootGuard control plane (#1) * Connect WebApp to Core and add Unbound settings (#12) * Connect WebApp to Core and add Unbound settings * Run WebApp validation on pull requests * Harden Unbound for RootGuard runtime (#1) * Harden Unbound for RootGuard runtime * Validate Unbound changes on pull requests * Validate Unbound after trust anchor initialization * Add secure AdGuard bootstrap control (#2) * Add AdGuard bootstrap interface (#13) * Add AdGuard bootstrap interface * Update vulnerable frontend dependencies * Add versioned Unbound configuration lifecycle (#4) * Add versioned Unbound configuration lifecycle * Update Core CI action runtimes * Add Unbound preview rollback and diagnostics UI (#14) * Add Unbound preview rollback and diagnostics UI * Update WebApp CI action runtimes * Add Unbound presets and advisor (#5) * Add Unbound advisor and preset interface (#15) * Add safe Unbound custom configuration (#6) * Add Unbound expert configuration editor (#16) * Build AIO control plane and safe updates (#7) Build the RootGuard AIO control plane, container lifecycle management, live diagnostics, and guarded component updates. * Adopt AGPL-3.0-or-later (#2) License the RootGuard Unbound component under AGPL-3.0-or-later and document the licensing terms. * Add secure AIO management interface (#17) Add the responsive bilingual RootGuard management interface with login, guided DNS setup, live configuration, diagnostics, and component update controls. * Prepare RootGuard alpha foundation and documentation (#5) Establish the RootGuard AIO alpha foundation with secure component updates, guided DNS management, current project documentation, AGPL licensing, and the public Wiki and roadmap. * Enforce frontend dependency security audit (#18) Fail WebApp CI when npm reports a high or critical frontend dependency vulnerability. * Add guided conditional forwarding (#8) Add typed conditional forwarding, loop-safe validation, expert conflict detection, versioned rendering, and bounded DNS target reachability checks. * Add guided conditional forwarding interface (#19) Add the bilingual responsive forwarding wizard, ordered IPv4 and IPv6 targets, reachability checks, fallback guidance, and safe activation through the existing Unbound lifecycle. * Support unsigned private forward zones (#9) * Guide unsigned private forward zones (#20) * Allow private answers per forward zone (#10) * Guide private answers for forward zones (#21) * Require authoritative forwarding probes (#11) Accept conditional-forwarding targets only when the configured zone returns NOERROR with an SOA record. * Clarify forwarding authority checks (#22) Describe the SOA-based activation requirement precisely in the German and English conditional-forwarding feedback. * Stabilize forwarding probe errors (#12) Return stable, redacted semantic errors for forwarding targets that do not provide a valid zone SOA, and cover NXDOMAIN and malformed responses with regression tests. * Allow versioned RootGuard image tags (#3) Let the Unbound component publish its own optional RootGuard release tag while retaining its existing version tags. * Fix alpha dependency security audit (#23) * Add secure local password recovery (#24) * Improve GitHub project discoverability (#13) * Improve GitHub project discoverability (#25) * Improve GitHub project discoverability (#4) * Expose trustworthy service runtime metadata (#15) * Explain service runtime state in Stack Center (#27) * Add bounded redacted service diagnostics (#16) * Add on-demand service diagnostics (#28) * Add safe update cleanup history (#17) * Show update and cleanup history (#29) * Add safe update lifecycle history (#34) * Prepare standalone updater component (#1) * Test real paired update and rollback (#3) * Add typed installation diagnostics (#18) * Show actionable installation diagnostics (#30) * Add guided private DNS settings (#19) * Add guided private DNS controls (#31) * Add capability-checked resolver modes (#20) * Add guided resolver protocol modes (#32) * Distinguish missing container healthchecks (#21) Report containers without a configured Docker healthcheck separately from genuinely unknown inspection states. * Explain containers without healthchecks (#33) Present running containers without a Docker healthcheck as a distinct non-error state with bilingual operator guidance. * Polish Unbound fields and runtime badge (#34) Align guided Unbound controls with Setup fields and center the pulsing runtime indicator independently of Safari font baselines. * Polish management UI (#35) * Add live dashboard metrics (#22) * Add bounded Unbound resource profiles (#23) * Add Unbound resource profile controls (#36) * Preserve Unbound resource profiles in proxy (#37) * Upgrade Unbound security baseline to 1.25.2 (#6) * Upgrade Unbound security baseline to 1.25.2 * Read Unbound version without entrypoint output * Add guided serve-expired controls (#24) * Add serve-expired controls to Webapp (#38) * Add DNSSEC cache controls (#39) * Add DNSSEC cache controls (#25) * Add EDNS buffer size control (#26) * Expose EDNS buffer size control (#40) * Expose temporary diagnostic logging (#41) * Add privacy-safe diagnostic logging (#27) * Enable loopback-only runtime control (#7) * Bump the actions group across 1 directory with 6 updates (#2) Bumps the actions group with 6 updates in the / directory: | Package | From | To | | --- | --- | --- | | [actions/checkout](https://github.com/actions/checkout) | `5` | `7` | | [docker/metadata-action](https://github.com/docker/metadata-action) | `5` | `6` | | [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) | `3` | `4` | | [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `3` | `4` | | [docker/login-action](https://github.com/docker/login-action) | `3` | `4` | | [docker/build-push-action](https://github.com/docker/build-push-action) | `6` | `7` | Updates `actions/checkout` from 5 to 7 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@v5...v7) Updates `docker/metadata-action` from 5 to 6 - [Release notes](https://github.com/docker/metadata-action/releases) - [Commits](docker/metadata-action@v5...v6) Updates `docker/setup-qemu-action` from 3 to 4 - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](docker/setup-qemu-action@v3...v4) Updates `docker/setup-buildx-action` from 3 to 4 - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](docker/setup-buildx-action@v3...v4) Updates `docker/login-action` from 3 to 4 - [Release notes](https://github.com/docker/login-action/releases) - [Commits](docker/login-action@v3...v4) Updates `docker/build-push-action` from 6 to 7 - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](docker/build-push-action@v6...v7) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: docker/build-push-action dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: docker/login-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: docker/metadata-action dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: docker/setup-buildx-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: docker/setup-qemu-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add collapsible navigation sidebar (#42) * Keep Unbound volume identity stable (#8) * Migrate service volume ownership during updates (#28) * Show AdGuard filter diagnostics (#43) * Add AdGuard filter diagnostics and DNS defaults (#29) * Fix AdGuard DNS baseline status (#30) * Unify actions and focus AdGuard diagnostics * Build Unbound reproducibly from verified source (#9) * Expose stack release metadata (#31) * Show trusted stack release metadata (#45) * feat(installer): add AdGuard release channels (#32) * feat(setup): select AdGuard release channel (#46) * feat(stack): verify release attestations (#33) * feat: show cryptographic release provenance (#47) * feat(stack): show release attestation status * ci: attest published WebApp images * fix(stack): explain attestation states consistently * fix(stack): verify exact SLSA v1 predicate (#34) * fix(api): preserve service provenance fields (#48) * fix(deps): bump brace-expansion and postcss to clear high-severity audit gate (#52) npm audit --audit-level=high fails on main and therefore on every PR: brace-expansion 5.0.8 (High, GHSA-rgw5-rvv9-x895, DoS via unbounded intermediate arrays) and postcss <=8.5.22 (Moderate, GHSA-6g55-p6wh-862q, sourceMappingURL .map read). Both resolve with a patch-level `npm audit fix`, no breaking changes. Fixes #51 * fix(overview): derive service KPI total from allowlist instead of hardcoded 2 (#50) The Services KPI card compared against a hardcoded 2 (from an earlier version with fewer managed services), so a fully healthy 5-service stack rendered "5 / 2" instead of "5 / 5". Derive both numerator and denominator from the actual /api/services allowlist response and update the EN/DE note copy to name all five services. Fixes #49 * feat(theme): introduce semantic design tokens with System/Light/Dark support (#54) Completes the semantic token layer that was already half-referenced across 7 component files (--text, --text-muted, --border, --border-subtle, --accent, --success, --warning, --surface-soft were used but never defined at :root), adds a contrast-verified light palette, and wires up a ThemeProvider (System/Light/Dark, localStorage-persisted, zero-FOUC) mirroring the existing i18n provider pattern. Fixes a dead-code bug along the way: a duplicate .sidebar rule in index.css silently overrode --rg-bg-sidebar with a hardcoded value. Migrates hardcoded color literals to tokens in the app shell and first screen (index.css, header, buttons, card, status, layout, motion, glass, content-modal, login). Page-specific stylesheets (setup/stack/dashboard/ adguard/unbound*) are explicit follow-up work and intentionally keep their current dark appearance under both themes for now - see the issue for the full scope boundary and screenshot evidence. Also removes 4 verified-unused legacy button classes in buttons.css. Fixes #53 * feat(theme): migrate Dashboard to design tokens (#56) Replaces the 70 hardcoded hex/rgba literals in dashboard.css with the semantic tokens introduced in #54, so the Overview/Dashboard page (hero, KPI tiles, resource tiles, DNS data-flow diagram, service list) now follows the System/Light/Dark theme toggle. No new tokens needed - all values mapped onto the existing set. Fixes #55 * feat(theme): migrate remaining pages to design tokens (#58) Replaces the ~470 remaining hardcoded hex/rgba literals in Setup, Stack Center, AdGuard, and the Unbound settings pages (12 files) with the token set introduced in #54, so the whole app now follows the System/Light/Dark theme toggle. Adds a --category-violet token pair for the forwarding/private-DNS panels' distinct accent, previously unnamed purple literals used consistently across those two files. Code/config viewers (Unbound expert editor, live-config viewer, log and diagnostic <pre> panels) intentionally stay dark regardless of theme, consistent with the existing content-modal.css precedent. Fixes #57 * feat(header): rework as a coherent utility bar (#60) Gives every header control (language, theme, sign-out, GitHub, Docs) the same height, border, radius, background, icon size, hover, and focus-visible treatment, per the ROADMAP.md "accessible WebGUI navigation and appearance" slice. Fixes an actual bug along the way: GithubIcon/DocsIcon both render at a raw inline 22x22 SVG size and reference a shared .rg-icon class that had no CSS rule anywhere, so they were never constrained to the 15-16px used by the other controls' icons. The language <select> keeps full native functionality (keyboard, screen readers) via a transparent-overlay technique rather than a custom-built dropdown. Fixes #59 * feat(header): consolidate language, appearance, and sign-out into a user menu (#62) New UserMenu component: a trigger button (username + chevron, same chip style as the rest of the utility bar) opens a panel with three explicit System/Light/Dark options, the language select, and sign-out. GitHub/Docs stay direct on desktop; on narrow viewports they additionally appear inside the same menu while the standalone chips hide, so mobile header clutter consolidates into one trigger, per the ROADMAP.md "accessible WebGUI navigation and appearance" slice. Click-outside and Escape close the panel (Escape returns focus to the trigger), opening auto-focuses the first control. Fixes #61 * feat(search): add global, local-only search with S / Ctrl+Cmd+K (#64) New src/search/ module: a hand-curated local index (~45 entries) covering all pages, the 4 Unbound tabs, and the meaningfully distinct guided settings/actions across Unbound, Setup, Stack Center, and AdGuard, each reusing the app's existing bilingual i18n label plus optional technical-directive keywords (qname-minimisation, prefetch-key, serve-expired-ttl, local-zone, forward-zone, 90-rootguard-custom.conf, ...). SearchModal is a self-contained trigger + portal panel (same pattern as ContentModal/UserMenu): opens from the new header search chip, the "S" key (ignored while typing in a real field), or Ctrl/Cmd+K (always). Arrow keys move the highlighted result, Enter selects it, Escape closes and restores focus to the trigger. Selecting a result navigates to the matching page; landing on the exact originating tab/section is the next roadmap item, since Unbound's tab state isn't currently URL-addressable. Fixes #63 * fix(theme,header): remove distracting hero circles, fix search placement (#66) Removes the four decorative bordered-circle pseudo-elements on the Dashboard/Setup/Unbound/Stack hero cards (purely cosmetic, no content) - reported as too prominent in light mode and distracting in dark mode. Also removes the now-unused rg-soft-glow keyframe. Reorders the header utility bar so vdev precedes the Search/GitHub/Docs/ account button group instead of splitting it, and adds a visible <kbd>S</kbd> badge to the search trigger so the shortcut is discoverable without hovering. Fixes #65 * feat(sidebar): move collapse control to bottom edge, default desktop to collapsed (#68) Moves the sidebar-toggle button after the nav items (pinned to the bottom edge via margin-top: auto instead of sitting above the nav list). New sessions with no stored rootguard.sidebar.collapsed preference now default to collapsed on desktop widths (>=760px); an existing explicit preference, in either direction, still always wins. Mobile is unaffected - the toggle is hidden there and labels always show regardless of the value. Fixes #67 * Keep sidebar navigation and collapse control visible while long pages scroll (#70) * feat(layout): keep sidebar and collapse control visible while pages scroll Replaces the page-level scroll with a fixed app-shell layout: html/body/ #root at height:100%, a new .app-shell wrapping Header + .layout at 100dvh, .layout as flex:1/min-height:0, and .main scrolling internally (overflow-y:auto) instead of the whole document. Nav items move into a new .sidebar-nav wrapper with its own overflow-y:auto so the nav list can scroll independently if it ever outgrows the viewport, while the collapse button outside that wrapper always stays at the sidebar's bottom edge - reachable without scrolling, per the user's explicit concern before this was implemented. Mobile's horizontal-scrolling nav row moves from .sidebar to .sidebar-nav; labels remain unchanged. Fixes #69 * fix(sidebar): restore collapsed nav tooltips, remove stray scrollbar The new .sidebar-nav scroll wrapper from the previous commit inadvertently broke two things, both caused by giving it overflow-y:auto without an explicit overflow-x: per the CSS overflow spec, one axis set to a non-visible value while the other stays "visible" forces both to "auto" - so the collapsed-state tooltip (positioned via `left: calc(100% + 12px)`, intentionally escaping the sidebar's bounds) got clipped, and the forced overflow-x:auto rendered a stray horizontal scrollbar above the collapse button. Sets overflow-x: hidden explicitly (no more ambiguous coupling), and replaces the CSS ::after tooltip with a small JS-positioned one rendered via a document.body portal, so it's never subject to .sidebar-nav's clipping in the first place regardless of overflow settings. * Make box-shadow color/intensity theme-aware to fix washed-out light mode (#72) Every box-shadow was a literal near-black rgba() hand-tuned for the dark theme; reused unchanged in light mode it reads as a muddy grey halo instead of a crisp lift, especially combined with light mode's already low-contrast card borders. Adds --shadow-ink/--shadow-scale tokens (dark: unchanged; light: cooler ink at ~40% intensity) and rewrites the 15 existing shadow declarations to reference them, preserving each component's hand-tuned offset/blur/spread exactly. Fixes #71 Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * Add fullscreen mode and inline base-config reference to expert editor (#74) Fullscreen renders via a document.body portal: .unbound-page carries a permanent `animation: ... both` that leaves a non-none transform applied after the entrance animation ends, which makes it a containing block for position:fixed descendants - a plain CSS toggle would size the "fullscreen" panel against that page div instead of the viewport. The base config was previously only reachable through a separate ContentModal popup; it's now an inline, collapsed-by-default disclosure next to the editor. Fixes #73 Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * Remove git submodules ahead of monorepo migration Part of #92. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * Rebuild CI, docs, and workflow tooling for the monorepo - Replace each component's own nested CI (now inert - GitHub only reads the top-level .github/workflows/) with path-filtered workflows here: ci-core.yml, ci-webapp.yml, ci-unbound.yml, ci-updater.yml. Each keeps its component's test/build/publish behavior, scoped to trigger only on changes under its own directory. Dropped the type=semver release-tag publish path from webapp/updater (redundant with the unified release workflow below); kept :latest/:sha-* dev tags. - release-alpha.yml: drop submodules: recursive (plain directories now); expand the publish matrix from core-only to all four components, so one release build produces all four images under one version instead of requiring matching version tags pushed to three separate repos first. Removed the now-redundant "verify independently published" step in smoke-test, since publish covers all four directly. - ci.yml: drop submodules: recursive from the integration test checkout. - Consolidate dependabot config (github-actions repo-wide, gomod scoped to rootguard-updater/, matching what existed before). - Remove the now-inert nested .github/ (workflows, issue templates, PR template) from each component directory. - Update AGENTS.md, README.md, CONTRIBUTING.md, docs/project-state.md, ROADMAP.md's blockpage entry, and rootguard-core/README.md to describe the monorepo layout instead of submodules. Fixes #92 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
foxly-it
added a commit
that referenced
this pull request
Aug 6, 2026
… scroll (#70) * feat(layout): keep sidebar and collapse control visible while pages scroll Replaces the page-level scroll with a fixed app-shell layout: html/body/ #root at height:100%, a new .app-shell wrapping Header + .layout at 100dvh, .layout as flex:1/min-height:0, and .main scrolling internally (overflow-y:auto) instead of the whole document. Nav items move into a new .sidebar-nav wrapper with its own overflow-y:auto so the nav list can scroll independently if it ever outgrows the viewport, while the collapse button outside that wrapper always stays at the sidebar's bottom edge - reachable without scrolling, per the user's explicit concern before this was implemented. Mobile's horizontal-scrolling nav row moves from .sidebar to .sidebar-nav; labels remain unchanged. Fixes #69 * fix(sidebar): restore collapsed nav tooltips, remove stray scrollbar The new .sidebar-nav scroll wrapper from the previous commit inadvertently broke two things, both caused by giving it overflow-y:auto without an explicit overflow-x: per the CSS overflow spec, one axis set to a non-visible value while the other stays "visible" forces both to "auto" - so the collapsed-state tooltip (positioned via `left: calc(100% + 12px)`, intentionally escaping the sidebar's bounds) got clipped, and the forced overflow-x:auto rendered a stray horizontal scrollbar above the collapse button. Sets overflow-x: hidden explicitly (no more ambiguous coupling), and replaces the CSS ::after tooltip with a small JS-positioned one rendered via a document.body portal, so it's never subject to .sidebar-nav's clipping in the first place regardless of overflow settings.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Verification