diff --git a/docs/design-decisions.md b/docs/design-decisions.md
index cd0d91f..364a03e 100644
--- a/docs/design-decisions.md
+++ b/docs/design-decisions.md
@@ -1883,3 +1883,58 @@
Proof resources torn down (cluster, template, router-if, subnet, net --
residual check clean); post-teardown cloud-assert PASS. Phase 0 gates are
fully discharged; the D-074 implementation (DOCFIX-106/107) ships.
+
+## D-075: Dashboard VIP root -- redirect to /horizon + no autoindex (ADOPTED+EXECUTED 2026-07-07)
+
+**Status: ADOPTED (operator ruling 2026-07-07, option c) + EXECUTED live same day.**
+
+**Context.** During the devteam handover browser check the operator hit Apache
+"Index of /" at https://10.12.4.58/ (provider-public dashboard VIP). Measured:
+Horizon mounts at webroot /horizon (WSGIScriptAlias in conf-enabled/
+openstack-dashboard.conf); the charm-rendered vhosts define no root handler;
+Ubuntu stock apache2.conf grants `Options Indexes` on /var/www/. A directory
+listing on a tenant-facing commercial surface is an information-disclosure /
+posture defect, and a bare 200 at the root previously masqueraded as a healthy
+dashboard (the D-072 as-executed "https 200" at the VIP root was THIS autoindex
+page, not Horizon).
+
+**Options presented:** (a) redirect / -> /horizon; (b) disable autoindex at the
+root; (c) both. **Operator ruled (c).**
+
+**Decision / mechanism.** Local override /etc/apache2/conf-available/
+99-omega-root.conf on the dashboard unit (the charm exposes no config option
+for either behavior; charm manages sites-enabled/ but never conf-enabled/, so
+the snippet survives config-changed re-renders and in-channel charm refreshes):
+
+
+ Options -Indexes
+ RewriteEngine On
+ RewriteRule ^$ %{REQUEST_SCHEME}://%{HTTP_HOST}/horizon [R=302,L]
+
+
+**Why per-directory mod_rewrite and NOT RedirectMatch:** first attempt used
+`RedirectMatch 302 ^/$ /horizon`; mod_alias absolutizes the Location from the
+BACKEND connection port when the client Host header carries none, emitting
+http://:70/horizon (and :433 on the TLS leg) -- ports haproxy does not
+expose. Caught in this window's verify step. The rewrite echoes the client's
+own Host header and request scheme, so both haproxy legs redirect correctly.
+302 (not 301) so browsers do not cache permanently against a future webroot
+change. `Options -Indexes` subtracts from the inherited option list and covers
+/var/www/html by inheritance.
+
+**Verification (as-executed):** on-unit root -> 302 + zero "Index of" match;
+via VIP http leg: / -> 302 http://10.12.4.58/horizon -> follows to 200 at
+/horizon/auth/login/. TLS-leg browser confirmation by operator.
+
+**Durability:** PER-REBUILD -- teardown wipes the unit; reapply each rebuild
+via the phase-03 step 3.3 block (DOCFIX-118), same lifecycle as the D-044
+cookie override. **Roosevelt:** edge TLS/DNS (D-044 trajectory) supersedes
+this plumbing; carry the invariant "tenant-facing roots never serve directory
+listings" into the Roosevelt bundle review.
+
+**Revert:** `sudo a2disconf 99-omega-root && sudo systemctl reload apache2`
+on the dashboard unit; git-revert the DOCFIX-118 runbook/appendix additions.
+
+**Related:** D-072 (VIP TLS repair; its root-200 evidence reinterpreted),
+D-044 (cookie override precedent + Roosevelt edge trajectory), DOCFIX-089
+(fail-closed dashboard checks), DOCFIX-118 (runbook + appendix-A delivery).
diff --git a/docs/session-ledger.md b/docs/session-ledger.md
index 06a4a74..4ed7664 100644
--- a/docs/session-ledger.md
+++ b/docs/session-ledger.md
@@ -296,21 +296,18 @@
~/devteam-package + the ~/tenant-devteam credential files in-person
to the two named custodians.
2. **Operator manual item:** foil1 Horizon checks (contract 5.1/5.3) --
- domain-admin login + GUI probe-user create/delete; non-blocking. Same
- checks now also apply to devteam. IN PROGRESS 2026-07-07: operator
- browsed the dashboard VIP root and got Apache "Index of /" -- see the
- two entries below (URL corrected to /horizon in the devteam package;
- root-autoindex finding OPEN, options presented). Login check at
- /horizon pending operator confirm.
-2b. **FINDING (2026-07-07, UNRULED -- present options, do not implement):
- Apache autoindex at the public dashboard VIP root.** Browsing
- https://10.12.4.58/ (provider-public, tenant-facing) serves "Index of /"
- instead of Horizon (webroot /horizon, measured). Tenant-visible surface
- on a commercial cloud => security-relevant posture item. Options for
- operator ruling: (a) redirect / -> /horizon (upstream-common), (b)
- disable autoindex on the vhost root, (c) both [recommended]. Charm-vs-
- local-override mechanism TBD at ruling time; D-072/D-044 adjacent; would
- consume the next-free D number as a PROPOSED entry when drafted.
+ domain-admin login + GUI probe-user create/delete; non-blocking.
+ devteam 5.1 reachability CONFIRMED 2026-07-07 (operator browser,
+ /horizon login page); devteam/foil1 5.3 GUI probe still open, plus one
+ operator re-browse of the httpS VIP ROOT to confirm the D-075 redirect
+ on the TLS leg (http leg verified from jumphost).
+2b. **D-075 RULED (option c) + EXECUTED 2026-07-07** (was: root-autoindex
+ finding): redirect / -> /horizon + Options -Indexes via
+ conf-enabled/99-omega-root.conf on the dashboard unit. First attempt
+ (RedirectMatch) caught leaking the backend port in verify and replaced
+ with per-dir mod_rewrite. Delivered as D-075 entry + DOCFIX-118
+ (phase-03 PER-REBUILD block + appendix-A symptom entry). PER-REBUILD
+ like the D-044 override.
3. **capi-test-1 CREATE_FAILED record delete: RULED YES (2026-07-07),
execution handed to operator** -- the Claude Code permission classifier
(correctly) refuses agent-side deletes of resources it did not create;
diff --git a/docs/v1-redeploy-changelog.md b/docs/v1-redeploy-changelog.md
index a52916b..c7e4329 100644
--- a/docs/v1-redeploy-changelog.md
+++ b/docs/v1-redeploy-changelog.md
@@ -2779,3 +2779,36 @@
REVERT (package correction only): sed 's|/horizon||' on the 4 corrected lines in ~/devteam-package; git checkout HEAD~ -- docs/session-ledger.md docs/v1-redeploy-changelog.md
Next-free after this push (per scan, keep this line unwrapped): D-075, DOCFIX-118, BUNDLEFIX-012.
+
+### 2026-07-07 (addendum 37, jumphost stream) -- D-075 ADOPTED+EXECUTED: dashboard VIP root redirect + no-autoindex; DOCFIX-118 runbook/appendix delivery
+
+Operator confirmed /horizon works (devteam contract 5.1 reachability) and RULED
+option (c) on the root-autoindex finding (addendum 36). Same gated window
+(ops-devteam-onboard log).
+
+- **Measured before mutating:** charm exposes NO config option for root
+ behavior (full option list read); vhost map + docroots read on-unit;
+ "Index of /" REPRODUCED from the unit's own http backend (:70).
+- **D-075 EXECUTED (2 gated mutations + verify):**
+ /etc/apache2/conf-available/99-omega-root.conf (charm never manages
+ conf-enabled/), a2enconf, configtest, reload. FIRST ATTEMPT (RedirectMatch)
+ caught by the verify step emitting Location http://10.12.4.58:70/horizon --
+ mod_alias absolutizes from the backend port, which haproxy does not expose;
+ REPLACED with per-dir mod_rewrite echoing the client Host header + scheme.
+ Final verify: VIP http root -> 302 http://10.12.4.58/horizon -> 200 at
+ /horizon/auth/login/; on-unit listing grep zero. TLS-leg browser confirm
+ pending operator (http leg proven; rule is scheme-agnostic).
+- **DOCFIX-118:** phase-03 step 3.3 gains the D-075 PER-REBUILD block (RUN +
+ fail-closed CHECK that specifically FAILs on a backend-port-leaking
+ redirect); appendix-A gains the "Index of /" symptom entry incl. the two
+ traps (root-200 masquerades as healthy dashboard -- the D-072 root-200 was
+ this listing; RedirectMatch port leak). D-075 entry appended to
+ design-decisions (ADOPTED+EXECUTED, mechanism, revert, Roosevelt sunset
+ under the D-044 edge trajectory).
+- **Hygiene note:** a scratchpad dump of the full dashboard charm config
+ (secret-bearing values, taken for option-list reading) was deleted
+ immediately after key-name extraction; values never entered context.
+- Numbers consumed: D-075, DOCFIX-118.
+REVERT: on-unit `sudo a2disconf 99-omega-root && sudo systemctl reload apache2`; git checkout HEAD~ -- docs/design-decisions.md runbooks/phase-03-core-verify.md runbooks/appendix-A-troubleshooting.md docs/session-ledger.md docs/v1-redeploy-changelog.md
+
+Next-free after this push (per scan, keep this line unwrapped): D-076, DOCFIX-119, BUNDLEFIX-012.
diff --git a/runbooks/appendix-A-troubleshooting.md b/runbooks/appendix-A-troubleshooting.md
index 9a73bdb..1465459 100644
--- a/runbooks/appendix-A-troubleshooting.md
+++ b/runbooks/appendix-A-troubleshooting.md
@@ -598,6 +598,27 @@
GATE: 3x "Cluster is ONLINE", exactly one "Mode: R/W".
--------------------------------------------------------------------------------
+## Dashboard VIP root shows "Index of /" (Apache directory listing) [added DOCFIX-118]
+--------------------------------------------------------------------------------
+SYMPTOM: browser (or curl) at the dashboard VIP root (`/`, not `/horizon`)
+ renders an Apache autoindex page "Index of /"; Horizon itself is
+ healthy at `/horizon`.
+CAUSE: Horizon mounts at webroot `/horizon`; the charm vhosts define no root
+ handler; Ubuntu stock apache2.conf grants `Options Indexes` on
+ /var/www/. Nothing redirects `/`. (First seen 2026-07-07, devteam
+ handover browser check.)
+TRAP: a 200 at the VIP root is NOT proof the dashboard works -- the D-072
+ as-executed record's root-200 was this listing. Health-check /horizon,
+ never /. Second trap: fixing with `RedirectMatch` emits a Location
+ carrying the BACKEND port (:70/:433) that haproxy does not expose --
+ mod_alias absolutizes from the physical connection; use the per-dir
+ mod_rewrite form.
+FIX: apply the D-075 override block -- phase-03 step 3.3, "DOCFIX-118 --
+ Dashboard VIP root" (PER-REBUILD, like the D-044 cookie override).
+GATE: `curl -s -o /dev/null -w '%{http_code} %{redirect_url}' http://10.12.4.58/`
+ -> exactly `302 http://10.12.4.58/horizon` (no port suffix).
+
+--------------------------------------------------------------------------------
## Point-of-use identifier index [added DOCFIX-077]
--------------------------------------------------------------------------------
These identifiers are DEFINED where they are used (runbook/bundle comments), not
diff --git a/runbooks/phase-03-core-verify.md b/runbooks/phase-03-core-verify.md
index f4c0a5c..ace5fae 100644
--- a/runbooks/phase-03-core-verify.md
+++ b/runbooks/phase-03-core-verify.md
@@ -272,6 +272,35 @@
of v1 (D-044 rationale). Diagnostic lessons (reload race, proxy_ssl_name DNS-SAN, sed no-op,
scheme-mismatch redirect loop) are in appendix-A.
+### DOCFIX-118 -- Dashboard VIP root: redirect + no autoindex (D-075; PER-REBUILD)
+Without this, the tenant-facing VIP root serves Apache "Index of /" (no root handler in
+the charm vhosts + Ubuntu-default `Options Indexes` on /var/www/), and a bare 200 at the
+root can masquerade as a healthy dashboard. Per-directory mod_rewrite, NOT RedirectMatch:
+mod_alias absolutizes Location from the BACKEND port (:70/:433), which haproxy does not
+expose (D-075 rationale).
+
+**RUN -- jumphost**
+```bash
+# RUN: jumphost -- D-075 root redirect + no-autoindex on the dashboard unit (PER-REBUILD)
+juju ssh -m openstack openstack-dashboard/leader -- "printf '# Omega Cloud local override (D-075): tenant-facing VIP root must not serve\n# a directory listing; humans land on Horizon. Rewrite, NOT RedirectMatch:\n# mod_alias self-referential Location appends the backend port (70/433),\n# which haproxy does not expose; the rewrite echoes the client Host header.\n\n Options -Indexes\n RewriteEngine On\n RewriteRule ^\$ %%{REQUEST_SCHEME}://%%{HTTP_HOST}/horizon [R=302,L]\n\n' | sudo tee /etc/apache2/conf-available/99-omega-root.conf >/dev/null && sudo a2enconf 99-omega-root && sudo apache2ctl -t && sudo systemctl reload apache2"