diff --git a/scripts/setup.sh b/scripts/setup.sh
index a14828a5..943ed839 100755
--- a/scripts/setup.sh
+++ b/scripts/setup.sh
@@ -230,6 +230,21 @@ case $PM in
;;
esac
+# acl — setfacl/getfacl, needed by per-user Linux accounts.
+#
+# A member's home is 700 and owned by them, which is right for a shell and locks the platform out of the
+# file browser. Named ACL entries are what let both act on the same files without opening the home to every
+# account on the box; mode bits cannot express it in both directions. Core rather than a profile extra
+# because the alternative is an account that provisions and then cannot list its own home.
+case $PM in
+ apt)
+ if dpkg -s acl &>/dev/null 2>&1; then skip "acl"; else CORE_PKGS+=(acl); fi
+ ;;
+ pacman|dnf|yum)
+ if has setfacl; then skip "acl"; else CORE_PKGS+=(acl); fi
+ ;;
+esac
+
if [ ${#CORE_PKGS[@]} -gt 0 ]; then
install_pkg "${CORE_PKGS[@]}"
ok "Installed: ${CORE_PKGS[*]}"
diff --git a/src/apps/officer-web/App.tsx b/src/apps/officer-web/App.tsx
index 5de30db8..4bd300b2 100644
--- a/src/apps/officer-web/App.tsx
+++ b/src/apps/officer-web/App.tsx
@@ -53,8 +53,6 @@ export function App() {
} />
} />
} />
- } />
- } />
} />
} />
} />
diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/Dock.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/Dock.tsx
index 0149be26..14598762 100644
--- a/src/apps/officer-web/Screens/Dashboard/Layout/Dock.tsx
+++ b/src/apps/officer-web/Screens/Dashboard/Layout/Dock.tsx
@@ -169,7 +169,6 @@ export const CORE_DOCK_ITEMS: DockItem[] = [
{ label: 'Chat', to: '/chat', icon: MessageCircle, color: '#60a5fa' },
{ label: 'Gitea', to: '/gitea', icon: GitBranch, color: '#609926' },
{ label: 'Editor', to: '/code-editor', icon: Code, color: '#a78bfa' },
- { label: 'Plans', to: '/plans', icon: FileText, color: '#f472b6' },
{ label: 'Jobs', to: '/jobs', icon: Workflow, color: '#14b8a6' },
{ label: 'Logs', to: '/task-logs', icon: ScrollText, color: '#94a3b8' },
{ label: 'Terminal', to: '/terminal', icon: Monitor, color: '#f97316' },
diff --git a/src/apps/officer-web/Screens/Dashboard/Plans/index.tsx b/src/apps/officer-web/Screens/Dashboard/Plans/index.tsx
deleted file mode 100644
index cf0d2fc2..00000000
--- a/src/apps/officer-web/Screens/Dashboard/Plans/index.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import { useQuery } from '@tanstack/react-query';
-import { useNavigate, useParams } from 'react-router';
-import ReactMarkdown from 'react-markdown';
-import remarkGfm from 'remark-gfm';
-import rehypeRaw from 'rehype-raw';
-import { useClient } from 'hooks/useClient';
-import { Card } from '@/components/Card';
-
-/**
- * A plan is a markdown document on disk, so it gets an address: `/plans/:name`. No redirect guard — the
- * bare route is "no plan open" and a name that no longer exists gets the empty pane, not a rewritten URL.
- *
- * The picker stays a native `