Files
EpicNext-Cms/docs/superpowers/specs/2026-08-26-housekeeping-completion-design.md
T

17 KiB

Housekeeping Completion and Atomic Cutover Design

Status: Approved in conversation on 2026-08-26 Delivery branch: codex/housekeeping-complete Delivery shape: one final pull request Cutover: atomic, with no compatibility redirects

Relationship to the existing design

This specification completes the program described by 2026-08-24-housekeeping-modernization-design.md after the merged Inventory & Foundation subproject. The existing foundation is not the finished product: it provides the 137-route migration matrix, capability-aware contracts, validated domain manifests, shell primitives, and a non-production preview.

This document defines the remaining implementation and the final cutover. Where delivery details differ, this document is authoritative for phases 02 onward. The master architecture remains authoritative for domain ownership and product behavior.

This completion specification supersedes the earlier documents only for the route namespace: the new surface uses /ase, never /admin, as its canonical production root.

Approved decisions

  • Build complete verticals behind the existing non-production gate.
  • Keep all remaining work on one branch and deliver it through one final pull request.
  • Implement in vertical slices rather than UI-first placeholders.
  • Keep current /admin and /mod behavior unchanged until the final cutover commit.
  • At cutover, make the new Command Deck live at /ase, remove the legacy /admin, /admin-next, and /mod trees, and remove obsolete legacy routes without redirects.
  • Use hybrid personalization: mandatory content is capability-derived; operators may pin and reorder allowed shortcuts and optional widgets.
  • Add only backward-compatible database migrations before cutover.

Outcomes

The completed program must:

  1. Give every one of the 137 legacy routes a verified canonical destination or an explicit removal decision.
  2. Replace the fragmented admin and moderator surfaces with one capability-aware Command Deck.
  3. Deliver real workflows for all retained administration responsibilities, not wrappers around legacy pages.
  4. Provide global search, safe commands, derived operational inboxes, recent work, favorites, and optional widgets.
  5. Enforce the existing ACL model on navigation, reads, mutations, commands, search results, inbox items, and widgets.
  6. Produce durable and sanitized audit evidence for sensitive operations.
  7. Preserve a release-level rollback path without destructive database rollback.

Delivery model

All work is committed to codex/housekeeping-complete, based on the latest origin/main. No pull request is opened until every vertical and the cutover are implemented, reviewed, and verified.

The foundation currently exposes /admin-next. The first completion change renames that preview tree and its links to /ase-next; the preview remains unavailable when NODE_ENV=production. Development and test environments use /ase-next to exercise the new shell before cutover. The final cutover publishes the canonical /ase tree and removes the preview entry; it does not weaken the production preview gate before that point.

The branch is built in this order:

  1. access, audit, error, and preference core;
  2. People, moderation, and support;
  3. Content and engagement;
  4. Economy and catalog;
  5. Hotel, world, and operational systems;
  6. Command Deck operations and cross-domain composition;
  7. atomic route cutover and legacy removal.

Canonical route structure

After cutover the public administration route tree is:

/ase                           Operations workspace
/ase/people/*                  users, tickets, CFH, bans, moderation, teams
/ase/content/*                 articles, events, polls, media, engagement
/ase/economy/*                 catalog, shop, transactions, vouchers, values
/ase/hotel/*                   rooms, furni, badges, radio, emulator, Studio
/ase/system/*                  settings, ACL, logs, DevOps, maintenance

/ase is the operational home, not a duplicate menu page. /admin, /admin-next, and /mod have no route after cutover. A workflow has one canonical owner and one canonical destination; the new tree must not retain duplicate hubs or aliases.

Module ownership

src/features/housekeeping/foundation owns only cross-cutting composition:

  • request-scoped actor and capability context;
  • registry and navigation projection;
  • Command Deck chrome and page-state primitives;
  • command dispatch contracts;
  • search and inbox orchestration;
  • preference reconciliation;
  • shared error and audit envelopes.

Each domain owns its routes, pages, query services, commands, search providers, inbox sources, widgets, and domain-specific validation. Domains communicate with the foundation through the published contracts. They do not import another domain's internal modules.

The foundation must not import database clients, server actions, or domain page modules. Server-only domain adapters may import data and action services.

Domain manifests

Every manifest registers real, non-placeholder definitions for:

  • canonical routes and contextual navigation;
  • safe and sensitive commands;
  • entity-search providers;
  • derived-inbox sources;
  • mandatory and optional widgets;
  • localization keys and capability requirements.

Registry validation rejects duplicate IDs across all provider categories, duplicate routes, invalid ownership, missing localization, unknown capability slugs, invalid widget kinds, and commands without an owning domain.

The migration matrix and manifests are linked by contract tests. Every retained matrix row must resolve to one registered route or workflow. Every manifest capability set must cover the capabilities attributed to its matrix rows.

Authorization flow

Each request creates one capability context from getAdminContext(). The context contains the authenticated actor and immutable effective permission slugs. Rank is informational and may influence presentation defaults only; it is never used as a new authorization threshold.

Authorization is applied at every layer:

  1. registry projection removes inaccessible domains and routes;
  2. provider orchestration calls only permitted providers;
  3. providers filter inaccessible results and items;
  4. page loaders revalidate their required capability;
  5. command execution revalidates capability and input on the server;
  6. the underlying mutation service retains its own permission guard.

Client state, hidden navigation, preferences, or a previously loaded page never authorize an operation.

Commands and audit

Commands use typed input schemas and typed success/error results. Safe commands may execute directly from the palette. Sensitive commands open a dedicated contextual confirmation flow and require a reason when the command contract says so.

The existing admin_audit_log remains the canonical audit store. An additive migration adds nullable correlation_id varchar(64), outcome varchar(32), reason text, and domain varchar(32) columns plus an index on correlation_id. Existing action, target, target_id, before, after, diff, ip_address, and actor fields remain in use.

  • Database mutations write mutation and audit evidence in the same transaction whenever the affected service uses the same database connection.
  • Sensitive external or file operations persist an audit intent before execution and a final outcome afterward. Failure to persist the intent blocks execution.
  • Audit payloads pass through the existing recursive secret redaction.
  • Every command result and audit record carries the same correlation ID.
  • Failed, denied, and partially completed sensitive operations are audited.

Preferences

No suitable user-scoped HK preference store currently exists. Add housekeeping_user_preferences with:

  • user_id int as the primary key and unique owner;
  • schema_version int not null default 1;
  • payload longtext not null, containing validated JSON presentation state;
  • created_at datetime and updated_at datetime timestamps.

The payload stores pinned route/command IDs, shortcut order, widget order, and enabled optional widget IDs. It never stores permissions, authorization decisions, workflow state, or inbox status.

Every read reconciles stored IDs against the current registry and effective capabilities. Unknown, removed, or unauthorized entries are dropped before the payload reaches the UI. Mandatory widgets cannot be disabled.

Command Deck experience

The shell has four stable regions:

  1. a compact six-domain rail;
  2. domain-owned contextual navigation;
  3. a global search and command field with keyboard access;
  4. an operational workspace for pages, inboxes, recent work, and widgets.

Desktop and mobile share the same semantic hierarchy. Mobile collapses the rail and contextual navigation without changing route ownership or available actions. Focus order, landmarks, headings, active-state uniqueness, keyboard navigation, reduced motion, and semantic theme tokens are tested contracts.

Loading, empty, partial, error, forbidden, and ready states use the shared page state primitives. Partial provider failure is visible without replacing valid results from other providers.

Search supports navigation, entity results, and commands. It is not a raw database search endpoint.

  • A term shorter than two trimmed characters performs navigation/command matching only.
  • Entity providers have a two-second timeout and a maximum of 25 results each.
  • The combined entity response is capped at 50 results before client rendering.
  • Providers run only when their declared capability is satisfied.
  • Results include stable ID, owner, type, title, optional description, canonical href, and capability metadata.
  • Provider errors produce a typed partial result and do not fail unrelated providers.
  • Search terms and result payloads are not written to audit logs by default.

Derived operational inbox

The inbox is a read model over domain-owned work: tickets, CFH reports, alerts, emulator errors, operational anomalies, and other existing live states. It does not introduce a second assignment or task-status system.

Each inbox item exposes stable source/item IDs, domain, type, title, priority, age, state, canonical href, available actions, and required capability. Source items are deduplicated by the pair (sourceId, itemId).

Sources run independently with a two-second timeout. The composed response contains successful items plus per-source errors. The server caps the result at 200 items after capability filtering and deterministic priority/age ordering.

Recent work, favorites, and widgets

Recent work is derived from the operator's existing audit events and canonical route visits; it does not create workflow state. Favorites and ordering come from the reconciled preference payload.

Mandatory widgets are supplied by the system according to capability and cannot be removed. Optional widgets can be enabled and reordered. Widget loaders are server-side, capability-checked, independently timed out, and represented as partial failures rather than shell failures.

Vertical scope

Access, audit, and system core

  • command dispatcher and confirmation model;
  • audit extension and correlation IDs;
  • typed error taxonomy and boundary mapping;
  • preference repository and reconciliation;
  • shared provider orchestration and timeout behavior;
  • System routes for ACL, settings, logs, DevOps, and maintenance.

People, moderation, and support

  • user discovery, details, editing, password/reset controls, account relations, bans, and permitted staff actions;
  • help tickets and moderator tickets;
  • CFH queues and details;
  • moderation actions, team views, and ban workflows;
  • People search providers, inbox sources, commands, and widgets.

This vertical proves that all retained /mod responsibilities work inside the new capability model before /mod is removed.

Content and engagement

  • articles, events, polls, media, navigation content, tags, banners, and related editorial tools;
  • Content search, commands, inbox sources, and widgets;
  • consolidation of duplicate editorial hubs into canonical workflows.

Economy and catalog

  • catalog and item management, Builder Club catalog, maintenance, shop, transactions, vouchers, subscriptions, marketplace, and value tools;
  • Economy search, commands, anomaly sources, and widgets;
  • existing specialized editors remain components of canonical workflows rather than parallel navigation roots.

Hotel, world, and operational systems

  • rooms and room furni, badges, sounds, radio, emulator controls, imports, and Studio tools;
  • Hotel search, commands, operational sources, and widgets;
  • long-running operations retain progress/error behavior and gain consistent capability and audit envelopes.

Operations composition

  • global search and command palette;
  • derived inbox and partial-source reporting;
  • recent work and favorites;
  • mandatory operational summaries and optional widgets;
  • no duplicate mutation logic: actions route to the owning domain command.

Error model

All HK services return typed errors from this stable set:

  • UNAUTHENTICATED;
  • FORBIDDEN;
  • VALIDATION;
  • NOT_FOUND;
  • CONFLICT;
  • RATE_LIMITED;
  • DEPENDENCY_UNAVAILABLE;
  • TIMEOUT;
  • INTERNAL.

User messages are localized and do not expose internal details. Server logs and audit evidence include correlation IDs. Expected domain errors do not rely on framework exception text. Unknown errors are sanitized at the boundary and logged once.

Database changes

Allowed pre-cutover migrations are additive only:

  1. nullable HK audit metadata columns on admin_audit_log;
  2. the housekeeping_user_preferences table and its unique user index.

No legacy table or column is dropped or repurposed in this program. Removal of legacy UI routes is an application cutover, not a destructive data migration.

Atomic cutover

The final cutover commit is created only after all vertical gates pass. It:

  1. moves the completed shell and Operations workspace from /ase-next to /ase;
  2. changes domain preview hrefs to canonical /ase/<domain> hrefs;
  3. updates internal links, navigation configuration, and authorization fallback destinations;
  4. removes the legacy /admin, /admin-next, and /mod route trees plus every legacy route marked REMOVE;
  5. removes legacy pages whose behavior moved or merged into canonical routes;
  6. removes the temporary preview entry and flag if no longer used by tests;
  7. adds no compatibility redirects.

The cutover must leave no links, imports, route discovery entries, or tests that depend on removed UI modules.

Verification strategy

Each vertical uses TDD and has four gates:

  1. contract and authorization tests;
  2. domain query/command behavior tests, including denied and failure paths;
  3. page and accessibility behavior tests;
  4. cumulative Housekeeping and repository verification.

The final branch requires:

  • the migration matrix reporting 137/137 valid with every retained row linked to a canonical implementation;
  • mutation-sensitive authorization, provider, command, audit, and preference tests;
  • full project tests, Housekeeping tests, typecheck, semantic Biome, targeted formatting checks, and git diff --check;
  • production build with temporary environment restoration;
  • visual verification at desktop and mobile widths for every domain and shared state;
  • route-level smoke checks for canonical /ase pages, denied access, and removal of /admin, /admin-next, /mod, and obsolete routes;
  • a broad whole-branch code review followed by one reviewed fix wave if needed.

Repository-wide pre-existing formatter debt is reported separately and must not be hidden by mass-formatting unrelated files.

Merge, deployment, and rollback

The single pull request targets main only after all final gates pass. Merging is the atomic release boundary; no partial vertical is intentionally exposed to production operators.

After merge, the deployment pipeline must complete and /api/health must be verified live. A push or successful build alone is not deployment evidence.

Rollback deploys the prior application release. Because database changes are additive and ignored by the prior release, rollback does not require manual data reversal. If audit or preference migrations themselves fail, deployment stops before serving the cutover release.

Explicit non-goals

  • A new task-assignment system for inbox items.
  • A replacement authentication or ACL model.
  • Rank-based authorization thresholds.
  • Compatibility redirects for removed /admin, /admin-next, or /mod routes.
  • Destructive cleanup of legacy database data.
  • Rewriting specialized domain engines that already work; they are integrated behind consistent domain contracts instead.
  • Unrelated CMS redesign or repository-wide formatting cleanup.

Completion criteria

The program is complete only when:

  • all retained legacy capabilities are available through canonical new routes;
  • all six manifests contain real routes/providers/widgets rather than empty placeholders;
  • the Command Deck search, commands, inbox, preferences, recent work, and widgets operate against real domain services;
  • capability enforcement and audit evidence cover every exposed read and mutation path;
  • /ase serves the new HK; /admin, /admin-next, /mod, and removed legacy routes are unreachable; and no compatibility redirects exist;
  • final local, CI, deployment, health, and visual evidence are all recorded.