Files
EpicNext-Cms/docs/superpowers/plans/2026-08-26-housekeeping-completion.md
T
Simo 43470ebf82
CI / check (pull_request) Failing after 10s
CI / deploy (pull_request) Skipped
CI / release (pull_request) Skipped
feat(housekeeping): unify complete rebuild in gated preview
2026-08-31 20:37:51 +02:00

65 KiB

Housekeeping Completion Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (current session) or superpowers:executing-plans (separate session) to execute this plan task-by-task.

Goal: Complete all 137 Housekeeping migrations behind /ase-next, then atomically publish the capability-aware Command Deck at /ase and remove the legacy /admin, /admin-next, and /mod UI trees without redirects.

Architecture: Keep src/features/housekeeping/foundation limited to cross-domain contracts, registry projection, provider orchestration, shell composition, preferences, commands, and audit envelopes. Each of the six domains owns its route catalog, server adapters, commands, search, inbox, widgets, and workflow components. App Router entrypoints dispatch canonical route IDs to domain-owned renderers; the preview maps canonical /ase/* destinations to /ase-next/* without changing domain manifests.

Tech Stack: Node.js 26, Next.js 16 App Router, React 19, TypeScript 7, Drizzle ORM/MySQL, next-intl, Zod 4, Vitest 4, Biome 2, Tailwind CSS 4, cmdk, dnd-kit.

Spec: docs/superpowers/specs/2026-08-26-housekeeping-completion-design.md

Global Constraints: Work only on codex/housekeeping-complete; do not use worktrees; preserve .remember/ and unrelated changes; keep /admin and /mod behavior unchanged until Task 25; keep /ase-next unavailable in production; retain /api/admin/* as internal transport contracts unless a task explicitly changes one; add only backward-compatible database changes; use the current ACL permission slugs and never introduce rank thresholds; stage exact files; run git diff --check before every commit; do not push or open a pull request until the entire plan and final review pass.

File structure and ownership

src/app/ase-next/                         gated preview App Router surface
  layout.tsx                              production-denying preview gate
  page.tsx                                first visible domain redirect
  [domain]/layout.tsx                     capability-projected Command Deck shell
  [domain]/[[...segments]]/page.tsx       route ID resolution and domain dispatch
src/app/ase/                              created only by atomic cutover

src/features/housekeeping/foundation/
  contracts/                              stable capability, result, route, command,
                                          search, inbox, widget, and preference types
  routing/                                canonical/preview href mapping and matcher
  providers/                              timeout, cap, partial-result orchestration
  commands/                               dispatcher, confirmation, audit envelope
  preferences/                            schema validation and reconciliation
  recent/                                 audit-derived recent work
  shell/                                  rail, contextual nav, command deck, inbox,
                                          widgets, favorites, and responsive chrome
  page/                                   shared page states and workflow primitives

src/features/housekeeping/domains/<id>/
  manifest.ts                             declarative registry entry
  routes.ts                               canonical `/ase` routes and handler IDs
  route-handlers.ts                       domain-owned renderer dispatch
  queries/                                server-only read adapters
  commands/                               typed mutations around existing services
  search.ts                               entity-search providers
  inbox.ts                                derived work sources
  widgets.ts                              mandatory and optional loaders
  pages/                                  workflow-focused React server/client views

src/actions/housekeeping-*.ts             narrow server-action boundaries
drizzle/migrations/0023_housekeeping.sql  additive audit and preference migration
src/features/housekeeping/cutover/        137-row parity and legacy-removal contracts

The migration files remain the authoritative inventory of legacy source pages and dependencies. Domain route catalogs are authoritative for canonical /ase destinations. A contract joins the two by canonical route ID; no legacy page component is imported into the new route tree.

Task 1: Lock the /ase namespace and preview mapping

Files:

  • Modify: src/features/housekeeping/foundation/contracts/domain.ts
  • Create: src/features/housekeeping/foundation/routing/href.ts
  • Create: src/features/housekeeping/foundation/routing/href.test.ts
  • Modify: src/features/housekeeping/foundation/registry.ts
  • Modify: src/features/housekeeping/foundation/registry.test.ts
  • Modify: src/features/housekeeping/foundation/navigation.ts
  • Modify: src/features/housekeeping/foundation/navigation.test.ts
  • Modify: src/features/housekeeping/domains/*/manifest.ts
  • Modify: src/features/housekeeping/migration/operations.ts
  • Modify: src/features/housekeeping/migration/people.ts
  • Modify: src/features/housekeeping/migration/content.ts
  • Modify: src/features/housekeeping/migration/economy.ts
  • Modify: src/features/housekeeping/migration/hotel.ts
  • Modify: src/features/housekeeping/migration/system.ts
  • Modify: src/features/housekeeping/migration/validate-matrix.ts
  • Modify: src/features/housekeeping/migration/validate-matrix.test.ts
  • Move: src/app/admin-next to src/app/ase-next
  • Modify: src/features/housekeeping/foundation/preview-route-contract.test.ts
  • Modify: src/features/housekeeping/foundation/foundation-source-contract.test.ts
  • Modify: src/lib/admin-theme-source-audit.test.ts

Interfaces:

  • Consumes: canonical route strings beginning with /ase.
  • Produces:
export type HousekeepingSurface = "preview" | "canonical";
export type CanonicalHousekeepingHref = `/ase${string}`;
export function toHousekeepingHref(
  href: CanonicalHousekeepingHref,
  surface: HousekeepingSurface,
): CanonicalHousekeepingHref | `/ase-next${string}`;
  • HousekeepingDomainManifest.canonicalHref is a CanonicalHousekeepingHref; Operations uses /ase, while the other domains use /ase/<domain>. Route definitions store canonical /ase hrefs only.

  • Write failing href tests proving /ase stays /ase, /ase/people/users maps to /ase-next/people/users in preview, and /admin input is rejected by the type/runtime guard.

  • Run pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/foundation/routing/href.test.ts and confirm RED.

  • Implement toHousekeepingHref, replace previewHref with canonicalHref, and pass surface into buildHousekeepingNavigation.

  • Change every non-null migration targetPath prefix from /admin to /ase; change validation to require targetPath === "/ase" || targetPath.startsWith("/ase/").

  • Move the preview route tree to src/app/ase-next, update source contracts/localized test fixtures, and prove production still calls notFound().

  • Run pnpm hk:matrix:check and the routing, registry, navigation, preview, matrix, and theme-source tests; confirm 137 discovered rows and zero issues.

  • Run targeted Biome, git diff --check, stage only listed paths, and commit refactor(housekeeping): adopt ase route namespace.

Task 2: Stabilize result, error, correlation, and route contracts

Files:

  • Modify: src/features/housekeeping/foundation/contracts/result.ts
  • Modify: src/features/housekeeping/foundation/contracts/query.ts
  • Modify: src/features/housekeeping/foundation/contracts/command.ts
  • Modify: src/features/housekeeping/foundation/contracts/search.ts
  • Modify: src/features/housekeeping/foundation/contracts/inbox.ts
  • Modify: src/features/housekeeping/foundation/contracts/widget.ts
  • Modify: src/features/housekeeping/foundation/contracts/domain.ts
  • Modify: src/features/housekeeping/foundation/contracts/index.ts
  • Modify: src/features/housekeeping/foundation/contracts/contracts.test.ts
  • Create: src/features/housekeeping/foundation/correlation.ts
  • Create: src/features/housekeeping/foundation/correlation.test.ts

Interfaces:

export type HousekeepingErrorCode =
  | "UNAUTHENTICATED" | "FORBIDDEN" | "VALIDATION" | "NOT_FOUND"
  | "CONFLICT" | "RATE_LIMITED" | "DEPENDENCY_UNAVAILABLE"
  | "TIMEOUT" | "INTERNAL";
export interface HousekeepingError {
  code: HousekeepingErrorCode;
  messageKey: string;
  fieldErrors?: Readonly<Record<string, readonly string[]>>;
}
export type HousekeepingResult<T> =
  | { ok: true; data: T; correlationId: string }
  | { ok: false; error: HousekeepingError; correlationId: string };
export function createCorrelationId(): string;
  • Replace the obsolete error-code expectations with table-driven tests for all nine approved codes, field errors, success, and correlation preservation.
  • Run the contracts and correlation tests and confirm RED on the renamed taxonomy.
  • Implement the types, ok, fail, mapUnknownError, and a 64-character-safe correlation generator using crypto.randomUUID().
  • Extend search results with type, description, canonical href, and capability metadata; extend inbox items with priority, age/state, actions; allow widget loaders to accept an abort signal.
  • Run the two tests plus pnpm typecheck; fix all foundation callers without weakening types.
  • Run targeted Biome, git diff --check, stage exact contract files, and commit refactor(housekeeping): stabilize service contracts.

Task 3: Make capability context request-scoped and reusable

Files:

  • Modify: src/features/housekeeping/foundation/server-capability-context.ts
  • Modify: src/features/housekeeping/foundation/server-capability-context.test.ts
  • Modify: src/features/housekeeping/foundation/capability-context.ts
  • Modify: src/features/housekeeping/foundation/capability-context.test.ts
  • Modify: src/lib/admin/guard.ts
  • Modify: src/lib/admin/guard.test.ts
  • Create: src/features/housekeeping/foundation/authorization.ts
  • Create: src/features/housekeeping/foundation/authorization.test.ts

Interfaces:

export const getHousekeepingCapabilityContext: () =>
  Promise<HousekeepingCapabilityContext>;
export function authorizeHousekeeping(
  context: HousekeepingCapabilityContext,
  requirement: CapabilityRequirement,
): HousekeepingResult<HousekeepingCapabilityContext>;
export function requireHousekeepingCapability(
  requirement: CapabilityRequirement,
  context?: HousekeepingCapabilityContext,
): Promise<HousekeepingCapabilityContext>;
  • Write tests proving one request calls getAdminContext() once across shell, page, and command preflight; denied checks return FORBIDDEN without rank thresholds.
  • Run the capability, authorization, and guard tests and confirm RED.
  • Keep React cache() as the request boundary, add reusable authorization functions, and let HK guards accept an already-created context.
  • Retain legacy requireStaff, requirePermission, and /admin fallbacks unchanged until cutover; remove only duplicate HK lookups.
  • Run targeted tests and pnpm typecheck.
  • Run Biome, git diff --check, stage exact files, and commit refactor(housekeeping): reuse request capability context.

Task 4: Add the audit and preferences schema additively

Files:

  • Create: drizzle/migrations/0023_housekeeping.sql
  • Modify: src/db/schema.ts
  • Create: src/features/housekeeping/foundation/persistence-contract.test.ts

Interfaces:

export type HousekeepingUserPreferenceRow =
  typeof HousekeepingUserPreferences.$inferSelect;
// admin_audit_log adds correlationId, outcome, reason, and domain.

Migration shape:

ALTER TABLE `admin_audit_log`
  ADD COLUMN `correlation_id` VARCHAR(64) NULL,
  ADD COLUMN `outcome` VARCHAR(32) NULL,
  ADD COLUMN `reason` TEXT NULL,
  ADD COLUMN `domain` VARCHAR(32) NULL,
  ADD INDEX `admin_audit_log_correlation_id_idx` (`correlation_id`);
CREATE TABLE `housekeeping_user_preferences` (
  `user_id` INT NOT NULL,
  `schema_version` INT NOT NULL DEFAULT 1,
  `payload` LONGTEXT NOT NULL,
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`user_id`)
);
  • Write a source-contract test asserting exact nullable audit columns/index, exact preference columns, one primary key, and no DROP, RENAME, or legacy-column mutation.
  • Run the persistence contract and confirm RED.
  • Add migration 0023 and matching Drizzle declarations using existing schema naming conventions.
  • Run the contract, pnpm typecheck, and pnpm db:migrate:status against the configured non-production environment only when available; record an unavailable DB as unexecuted, not passed.
  • Run targeted Biome, git diff --check, stage the migration/schema/test, and commit feat(housekeeping): add audit and preference storage.

Task 5: Extend audit writing and correlation evidence

Files:

  • Modify: src/lib/services/audit.ts
  • Modify: src/lib/services/audit.test.ts
  • Create: src/features/housekeeping/foundation/commands/audit-envelope.ts
  • Create: src/features/housekeeping/foundation/commands/audit-envelope.test.ts

Interfaces:

export interface AuditEntry {
  userId: number;
  action: string;
  target: string;
  targetId?: number;
  before?: Record<string, unknown>;
  after?: Record<string, unknown>;
  correlationId?: string;
  outcome?: "intent" | "success" | "failure" | "partial" | "denied";
  reason?: string;
  domain?: HousekeepingDomainId;
  ipAddress?: string;
}
export interface HousekeepingAuditWriter {
  write(entry: AuditEntry, transaction?: HousekeepingAuditTransaction): Promise<void>;
}
  • Add tests for recursive secret redaction, correlation/domain/outcome persistence, denied/failure evidence, and transaction-injected writes.
  • Run audit tests and confirm RED.
  • Export the audit payload type, preserve existing call compatibility, and add a writer adapter that can use either db or the supplied transaction.
  • Implement writeIntent and writeOutcome; block external/file execution if intent persistence fails.
  • Run audit and envelope tests plus pnpm typecheck.
  • Run Biome, git diff --check, stage exact files, and commit feat(housekeeping): correlate command audit evidence.

Task 6: Implement preferences validation, repository, and reconciliation

Files:

  • Create: src/features/housekeeping/foundation/preferences/schema.ts
  • Create: src/features/housekeeping/foundation/preferences/schema.test.ts
  • Create: src/features/housekeeping/foundation/preferences/repository.ts
  • Create: src/features/housekeeping/foundation/preferences/repository.test.ts
  • Create: src/features/housekeeping/foundation/preferences/reconcile.ts
  • Create: src/features/housekeeping/foundation/preferences/reconcile.test.ts
  • Create: src/actions/housekeeping-preferences.ts
  • Create: src/actions/housekeeping-preferences.test.ts

Interfaces:

export const housekeepingPreferencesSchema: z.ZodType<{
  schemaVersion: 1;
  pinnedRouteIds: string[];
  pinnedCommandIds: string[];
  shortcutOrder: string[];
  widgetOrder: string[];
  enabledOptionalWidgetIds: string[];
}>;
export interface HousekeepingPreferencesRepository {
  read(userId: number): Promise<HousekeepingPreferences>;
  upsert(userId: number, value: HousekeepingPreferences): Promise<void>;
}
export function reconcilePreferences(
  stored: HousekeepingPreferences,
  registry: HousekeepingRegistry,
  context: HousekeepingCapabilityContext,
): HousekeepingPreferences;
  • Write failing schema tests for malformed JSON, unknown keys, duplicate IDs, and schema version; write repository tests for absent/default and upsert behavior.
  • Write reconciliation tests proving unauthorized/removed IDs are dropped, mandatory widgets remain, and relative order of valid IDs is stable.
  • Run all four preference test files and confirm RED.
  • Implement Zod validation, injected repository DB adapter, deterministic reconciliation, and capability-checked load/save server actions.
  • Run preference tests, pnpm typecheck, and the Housekeeping suite.
  • Run Biome, git diff --check, stage exact files, and commit feat(housekeeping): persist operator preferences.

Task 7: Build bounded provider orchestration

Files:

  • Create: src/features/housekeeping/foundation/providers/run-provider.ts
  • Create: src/features/housekeeping/foundation/providers/run-provider.test.ts
  • Create: src/features/housekeeping/foundation/providers/orchestrate.ts
  • Create: src/features/housekeeping/foundation/providers/orchestrate.test.ts

Interfaces:

export interface ProviderPolicy<T> {
  timeoutMs: number;
  perProviderLimit: number;
  combinedLimit: number;
  sort(items: readonly T[]): readonly T[];
  dedupeKey(item: T): string;
}
export interface ProviderBatchResult<T> {
  items: readonly T[];
  errors: readonly { providerId: string; code: HousekeepingErrorCode }[];
  correlationId: string;
}
  • Use fake timers to test a 2,000 ms abort, capability-skipped providers, thrown errors mapped once, stable dedupe, per-provider cap, combined cap, and deterministic ordering.
  • Run both provider tests and confirm RED.
  • Implement orchestration without importing domain modules or database clients; accept providers and policy through arguments.
  • Prove one timeout returns successful sibling results with a typed partial error.
  • Run provider tests and pnpm typecheck.
  • Run Biome, git diff --check, stage exact files, and commit feat(housekeeping): orchestrate partial providers.

Task 8: Implement the typed command dispatcher

Files:

  • Create: src/features/housekeeping/foundation/commands/registry.ts
  • Create: src/features/housekeeping/foundation/commands/registry.test.ts
  • Create: src/features/housekeeping/foundation/commands/dispatcher.ts
  • Create: src/features/housekeeping/foundation/commands/dispatcher.test.ts
  • Create: src/features/housekeeping/foundation/commands/confirmation.ts
  • Create: src/features/housekeeping/foundation/commands/confirmation.test.ts
  • Create: src/actions/housekeeping-command.ts
  • Create: src/actions/housekeeping-command.test.ts

Interfaces:

export interface HousekeepingCommand<I, O> {
  id: string;
  owner: HousekeepingDomainId;
  risk: "safe" | "sensitive";
  capability: CapabilityRequirement;
  input: z.ZodType<I>;
  requiresReason: boolean;
  rateLimit: { attempts: number; windowMs: number };
  execute(ctx: HousekeepingCommandContext, input: I): Promise<HousekeepingResult<O>>;
}
export interface HousekeepingCommandContext {
  capability: HousekeepingCapabilityContext;
  correlationId: string;
  ipAddress: string;
}
export interface HousekeepingCommandDependencies {
  context: HousekeepingCapabilityContext;
  audit: HousekeepingAuditWriter;
  rateLimit(key: string, attempts: number, windowMs: number): Promise<boolean>;
}
export async function dispatchHousekeepingCommand(
  request: { commandId: string; input: unknown; reason?: string },
  dependencies: HousekeepingCommandDependencies,
): Promise<HousekeepingResult<unknown>>;
  • Write tests for unknown command, denied capability, invalid input, missing reason, rate limit, safe success, sensitive intent/success, sensitive intent/failure, and sanitized unknown exception.
  • Run dispatcher/action tests and confirm RED.
  • Implement global ID/owner validation, server-side capability recheck, Zod parsing, per-actor/IP limit, confirmation metadata, and audit envelope usage.
  • Ensure server actions accept plain serializable values and never trust client risk/capability metadata.
  • Run all command tests, audit tests, and pnpm typecheck.
  • Run Biome, git diff --check, stage exact files, and commit feat(housekeeping): dispatch audited commands.

Task 9: Resolve canonical routes and dispatch domain pages

Files:

  • Create: src/features/housekeeping/foundation/routing/match-route.ts
  • Create: src/features/housekeeping/foundation/routing/match-route.test.ts
  • Create: src/features/housekeeping/route-handlers.ts
  • Create: src/features/housekeeping/route-handlers.test.ts
  • Modify: src/app/ase-next/page.tsx
  • Modify: src/app/ase-next/[domain]/layout.tsx
  • Create: src/app/ase-next/[domain]/[[...segments]]/page.tsx
  • Delete: src/app/ase-next/[domain]/page.tsx

Interfaces:

export interface HousekeepingRouteMatch {
  routeId: string;
  domain: HousekeepingDomainId;
  params: Readonly<Record<string, string>>;
  canonicalHref: CanonicalHousekeepingHref;
}
export interface HousekeepingRouteHandler {
  routeId: string;
  render(input: HousekeepingPageInput): Promise<ReactNode>;
}
export function matchHousekeepingRoute(
  registry: HousekeepingRegistry,
  canonicalPath: string,
): HousekeepingRouteMatch | null;
  • Write matcher tests for static, :id, nested, unknown, malformed, and cross-domain paths; test one-to-one equality between registered route IDs and handler IDs.
  • Run matcher/handler tests and confirm RED.
  • Implement segment-safe matching without regular-expression injection; reject duplicate dynamic shapes during registry creation.
  • Update preview pages to map /ase-next/<domain>/<segments> to canonical /ase/<domain>/<segments>, reauthorize the matched route, and call its handler.
  • Test inaccessible routes as notFound() and permitted routes with one request-scoped context.
  • Run routing, registry, preview-route tests and pnpm typecheck.
  • Run Biome, git diff --check, stage exact paths, and commit feat(housekeeping): dispatch canonical domain routes.

Task 10: Deliver System access, configuration, observability, and operations

Files:

  • Create: src/features/housekeeping/domains/system/routes.ts
  • Create: src/features/housekeeping/domains/system/routes.test.ts
  • Create: src/features/housekeeping/domains/system/queries/access.ts
  • Create: src/features/housekeeping/domains/system/queries/configuration.ts
  • Create: src/features/housekeeping/domains/system/queries/observability.ts
  • Create: src/features/housekeeping/domains/system/queries/operations.ts
  • Create: src/features/housekeeping/domains/system/queries/system-queries.test.ts
  • Create: src/features/housekeeping/domains/system/commands/system-commands.ts
  • Create: src/features/housekeeping/domains/system/commands/system-commands.test.ts
  • Create: src/features/housekeeping/domains/system/pages/access.tsx
  • Create: src/features/housekeeping/domains/system/pages/configuration.tsx
  • Create: src/features/housekeeping/domains/system/pages/observability.tsx
  • Create: src/features/housekeeping/domains/system/pages/operations.tsx
  • Create: src/features/housekeeping/domains/system/pages/system-pages.test.tsx
  • Create: src/features/housekeeping/domains/system/route-handlers.ts
  • Modify: src/features/housekeeping/domains/system/manifest.ts
  • Modify: src/actions/admin-alerts.ts
  • Modify: src/actions/admin-emulator.ts
  • Modify: src/actions/admin-maintenance.ts
  • Modify: src/actions/admin-settings.ts
  • Modify: src/actions/commandocentrum.ts
  • Modify: src/actions/permissions.ts
  • Modify: src/lib/admin/ops-health.ts
  • Modify: src/lib/admin/ops-online-users.ts

Interfaces:

export const SYSTEM_ROUTE_IDS = [
  "system.access.permissions", "system.access.permission-detail",
  "system.configuration.settings", "system.configuration.emulator",
  "system.observability.analytics", "system.observability.analytics-activity",
  "system.observability.analytics-economy", "system.observability.devops",
  "system.observability.devops-errors", "system.observability.logs-staff",
  "system.observability.logs-audit", "system.observability.logs-chat",
  "system.observability.logs-commands", "system.observability.logs-trades",
  "system.operations.alerts", "system.operations.command-center",
  "system.operations.maintenance",
] as const;
  • Write route tests asserting the exact route IDs above, canonical /ase/system/* destinations, matrix coverage, labels, and read capabilities.
  • Write query tests using injected adapters for ACL/ranks, settings, emulator data, analytics/logs, health, errors, alerts, and maintenance; include dependency-unavailable mapping.
  • Write command tests for rank/ACL writes, settings/emulator updates, alerts, RCON commands, and maintenance; require reasons for permission, RCON, and global-availability mutations.
  • Run System tests and confirm RED before each production module is added.
  • Extract redirect-free mutation functions from the listed legacy actions; keep legacy action wrappers and /admin redirects working until cutover.
  • Build the four workflow pages with loading/empty/partial/error/forbidden states, then register real System routes and commands; Task 19 registers the System search, inbox, and widget providers.
  • Run System, legacy action, audit, authorization, full HK tests, and pnpm typecheck.
  • Run Biome, git diff --check, stage exact System/action files, and commit feat(housekeeping): deliver system vertical.

Task 11: Build People read adapters and canonical data models

Files:

  • Create: src/features/housekeeping/domains/people/routes.ts
  • Create: src/features/housekeeping/domains/people/routes.test.ts
  • Create: src/features/housekeeping/domains/people/queries/users.ts
  • Create: src/features/housekeeping/domains/people/queries/community.ts
  • Create: src/features/housekeeping/domains/people/queries/staff.ts
  • Create: src/features/housekeeping/domains/people/queries/support.ts
  • Create: src/features/housekeeping/domains/people/queries/moderation.ts
  • Create: src/features/housekeeping/domains/people/queries/people-queries.test.ts
  • Create: src/features/housekeeping/domains/people/models.ts
  • Create: src/features/housekeeping/domains/people/models.test.ts

Interfaces:

export interface PeopleUserSummary {
  id: number; username: string; rank: number; online: boolean;
  mail: string | null; ipCurrent: string | null; bannedUntil: number | null;
}
export interface PeopleQueueSnapshot {
  tickets: number; helpTickets: number; cfh: number; activeBans: number;
}
export interface PeopleQueries {
  users(input: ListInput): Promise<HousekeepingResult<Page<PeopleUserSummary>>>;
  user(id: number): Promise<HousekeepingResult<PeopleUserDetail>>;
  queue(): Promise<HousekeepingResult<PeopleQueueSnapshot>>;
}
  • Write exact route-catalog tests for users, multi-accounts, online, guilds, applications, teams, bans, IP/VPN/wordfilter, tickets, help tickets, CFH, moderation actions, and mod-team workflows.
  • Write query tests for pagination, stable sorting, missing users, capability-safe projections, ticket/CFH counts, guild detail, staff applications, sanctions, and dependency failures.
  • Run People model/query/route tests and confirm RED.
  • Implement server-only adapters around the matrix-listed Drizzle/RCON/service dependencies; never expose password hashes, auth tickets, secrets, or unredacted IPs without their explicit capability.
  • Map all returned failures to the stable HK error set and canonical /ase/people/* links.
  • Run People tests and pnpm typecheck.
  • Run Biome, git diff --check, stage exact People query files, and commit feat(housekeeping): model people workflows.

Task 12: Deliver People users, community, and staff workflows

Files:

  • Create: src/features/housekeeping/domains/people/commands/user-commands.ts
  • Create: src/features/housekeeping/domains/people/commands/user-commands.test.ts
  • Create: src/features/housekeeping/domains/people/commands/community-commands.ts
  • Create: src/features/housekeeping/domains/people/commands/community-commands.test.ts
  • Create: src/features/housekeeping/domains/people/pages/users.tsx
  • Create: src/features/housekeeping/domains/people/pages/user-detail.tsx
  • Create: src/features/housekeeping/domains/people/pages/user-edit.tsx
  • Create: src/features/housekeeping/domains/people/pages/multi-accounts.tsx
  • Create: src/features/housekeeping/domains/people/pages/community.tsx
  • Create: src/features/housekeeping/domains/people/pages/staff.tsx
  • Create: src/features/housekeeping/domains/people/pages/people-primary-pages.test.tsx
  • Modify: src/actions/bulk-users.ts
  • Modify: src/actions/users.ts
  • Modify: src/actions/admin-guilds.ts
  • Modify: src/actions/admin-applications.ts
  • Modify: src/actions/admin-teams.ts
  • Modify: src/actions/admin-ip.ts
  • Modify: src/actions/admin-vpn.ts
  • Modify: src/actions/admin-wordfilter.ts

Interfaces:

export type UserCommandId =
  | "people.user.update" | "people.user.ban" | "people.user.unban"
  | "people.user.alert" | "people.user.disconnect" | "people.user.mute"
  | "people.user.unmute" | "people.user.reset-password"
  | "people.user.send-currency" | "people.user.trade-lock"
  | "people.users.bulk-ban" | "people.users.bulk-unban"
  | "people.users.bulk-currency" | "people.users.bulk-badge";
  • Write command tests for the exact IDs above plus guild disband, application decision, team change, IP action, VPN configuration, and wordfilter update; assert server capability rechecks and audit before/after.
  • Run command tests and confirm RED.
  • Extract redirect-free service functions from listed actions while preserving legacy server-action wrappers.
  • Implement user list/detail/edit and multi-account pages; preserve existing fields/actions only when the matrix capability permits them.
  • Implement community and staff workflows with canonical links and no duplicate show/edit aliases.
  • Run People primary page/command tests, affected legacy tests, HK suite, and pnpm typecheck.
  • Run Biome, git diff --check, stage exact files, and commit feat(housekeeping): deliver people account workflows.

Task 13: Deliver People support and moderation parity

Files:

  • Create: src/features/housekeeping/domains/people/commands/support-commands.ts
  • Create: src/features/housekeeping/domains/people/commands/moderation-commands.ts
  • Create: src/features/housekeeping/domains/people/commands/support-commands.test.ts
  • Create: src/features/housekeeping/domains/people/commands/moderation-commands.test.ts
  • Create: src/features/housekeeping/domains/people/pages/support.tsx
  • Create: src/features/housekeeping/domains/people/pages/moderation.tsx
  • Create: src/features/housekeeping/domains/people/pages/cfh-detail.tsx
  • Create: src/features/housekeeping/domains/people/pages/ticket-detail.tsx
  • Create: src/features/housekeeping/domains/people/pages/help-ticket-detail.tsx
  • Create: src/features/housekeeping/domains/people/pages/people-support-pages.test.tsx
  • Create: src/features/housekeeping/domains/people/search.ts
  • Create: src/features/housekeeping/domains/people/inbox.ts
  • Create: src/features/housekeeping/domains/people/widgets.ts
  • Create: src/features/housekeeping/domains/people/people-providers.test.ts
  • Create: src/features/housekeeping/domains/people/route-handlers.ts
  • Modify: src/features/housekeeping/domains/people/manifest.ts
  • Modify: src/actions/admin-bans.ts
  • Modify: src/actions/admin-help-tickets.ts
  • Modify: src/actions/help-tickets.ts
  • Modify: src/actions/moderation.ts
  • Modify: src/actions/tickets.ts
  • Modify: src/actions/ticket-templates.ts
  • Modify: src/lib/services/moderation.ts
  • Modify: src/lib/services/ticket-replies.ts

Interfaces:

export const PEOPLE_INBOX_SOURCE_IDS = [
  "people.tickets", "people.help-tickets", "people.cfh", "people.active-bans",
] as const;
export const PEOPLE_SEARCH_PROVIDER_IDS = [
  "people.users", "people.guilds", "people.tickets",
] as const;
  • Write failing parity tests joining all People matrix rows, including every /mod row, to one route or removed decision.
  • Write support/moderation command tests for assign/reply/close/reopen/template, CFH resolve/sanction, ban/unban, and moderation action; require reasons for sanctions and bans.
  • Implement support and moderation pages with queue/detail flows, safe links, preserved mid-rank mod.* access, and no admin.dashboard dependency when the original route did not require it.
  • Implement the exact People search/inbox providers and mandatory queue widget; enforce 25-result and item capability filtering at provider level.
  • Register handlers/providers/widgets and prove no People manifest collection is empty.
  • Run People, legacy moderation/ticket tests, HK suite, and pnpm typecheck.
  • Run Biome, git diff --check, stage exact files, and commit feat(housekeeping): complete people moderation parity.

Task 14: Deliver Content and engagement

Files:

  • Create: src/features/housekeeping/domains/content/routes.ts
  • Create: src/features/housekeeping/domains/content/routes.test.ts
  • Create: src/features/housekeeping/domains/content/queries/content-queries.ts
  • Create: src/features/housekeeping/domains/content/queries/content-queries.test.ts
  • Create: src/features/housekeeping/domains/content/commands/content-commands.ts
  • Create: src/features/housekeeping/domains/content/commands/content-commands.test.ts
  • Create: src/features/housekeeping/domains/content/pages/editorial.tsx
  • Create: src/features/housekeeping/domains/content/pages/media.tsx
  • Create: src/features/housekeeping/domains/content/pages/engagement.tsx
  • Create: src/features/housekeeping/domains/content/pages/help.tsx
  • Create: src/features/housekeeping/domains/content/pages/brand.tsx
  • Create: src/features/housekeeping/domains/content/pages/localization.tsx
  • Create: src/features/housekeeping/domains/content/pages/content-pages.test.tsx
  • Create: src/features/housekeeping/domains/content/search.ts
  • Create: src/features/housekeeping/domains/content/inbox.ts
  • Create: src/features/housekeeping/domains/content/widgets.ts
  • Create: src/features/housekeeping/domains/content/route-handlers.ts
  • Create: src/features/housekeeping/domains/content/content-providers.test.ts
  • Modify: src/features/housekeeping/domains/content/manifest.ts
  • Modify: src/actions/admin-ads.ts
  • Modify: src/actions/admin-articles.ts
  • Modify: src/actions/admin-banners.ts
  • Modify: src/actions/admin-email-templates.ts
  • Modify: src/actions/admin-help.ts
  • Modify: src/actions/admin-media.ts
  • Modify: src/actions/admin-nav-menu.ts
  • Modify: src/actions/admin-photos.ts
  • Modify: src/actions/admin-tags.ts
  • Modify: src/actions/admin-theme.ts
  • Modify: src/actions/admin-writeable-boxes.ts
  • Modify: src/actions/banners.ts
  • Modify: src/actions/events.ts
  • Modify: src/actions/polls.ts
  • Modify: src/actions/prefixes.ts
  • Modify: src/actions/save-favicon.ts
  • Modify: src/actions/save-logo.ts
  • Modify: src/actions/translations.ts

Interfaces:

export const CONTENT_ROUTE_GROUPS = [
  "editorial", "media", "engagement", "help", "brand", "localization",
] as const;
export const CONTENT_SEARCH_PROVIDER_IDS = [
  "content.articles", "content.events", "content.media", "content.help",
] as const;
  • Write route tests mapping every Content matrix row to one of the six exact route groups and canonical /ase/content/* destinations.
  • Write query/command tests for articles, ads, banners, events/types, polls, photos/media, navigation, tags/prefixes, help questions, writable boxes, email templates, theme/favicon, and three translation stores.
  • Run Content tests and confirm RED before production implementations.
  • Extract redirect-free domain operations from the listed actions, retain legacy wrappers, and ensure global brand/localization mutations are sensitive and audited.
  • Implement the six workflow pages, content search providers, publication/attention inbox source, mandatory editorial summary, and optional media/localization widgets.
  • Register real routes/commands/providers/widgets and prove Content matrix closure.
  • Run Content, affected legacy tests, HK suite, and pnpm typecheck.
  • Run Biome, git diff --check, stage exact files, and commit feat(housekeeping): deliver content vertical.

Task 15: Deliver Economy and catalog

Files:

  • Create: src/features/housekeeping/domains/economy/routes.ts
  • Create: src/features/housekeeping/domains/economy/routes.test.ts
  • Create: src/features/housekeeping/domains/economy/queries/catalog.ts
  • Create: src/features/housekeeping/domains/economy/queries/commerce.ts
  • Create: src/features/housekeeping/domains/economy/queries/value.ts
  • Create: src/features/housekeeping/domains/economy/queries/economy-queries.test.ts
  • Create: src/features/housekeeping/domains/economy/commands/economy-commands.ts
  • Create: src/features/housekeeping/domains/economy/commands/economy-commands.test.ts
  • Create: src/features/housekeeping/domains/economy/pages/catalog.tsx
  • Create: src/features/housekeeping/domains/economy/pages/items.tsx
  • Create: src/features/housekeeping/domains/economy/pages/commerce.tsx
  • Create: src/features/housekeeping/domains/economy/pages/history.tsx
  • Create: src/features/housekeeping/domains/economy/pages/value.tsx
  • Create: src/features/housekeeping/domains/economy/pages/rewards.tsx
  • Create: src/features/housekeeping/domains/economy/pages/economy-pages.test.tsx
  • Create: src/features/housekeeping/domains/economy/search.ts
  • Create: src/features/housekeeping/domains/economy/inbox.ts
  • Create: src/features/housekeeping/domains/economy/widgets.ts
  • Create: src/features/housekeeping/domains/economy/route-handlers.ts
  • Create: src/features/housekeeping/domains/economy/economy-providers.test.ts
  • Modify: src/features/housekeeping/domains/economy/manifest.ts
  • Modify: src/actions/catalog.ts
  • Modify: src/actions/catalog-bc.ts
  • Modify: src/actions/catalog-items.ts
  • Modify: src/actions/items-base.ts
  • Modify: src/actions/admin-marketplace.ts
  • Modify: src/actions/admin-rare-values.ts
  • Modify: src/actions/admin-shop.ts
  • Modify: src/actions/admin-vouchers.ts
  • Modify: src/actions/shop.ts
  • Modify: src/actions/soundtracks.ts
  • Modify: src/actions/voucher.ts
  • Modify: src/lib/services/catalog-audit.ts
  • Modify: src/lib/services/catalog-items-loader.ts
  • Modify: src/lib/services/catalog-tree.ts
  • Modify: src/lib/services/paypal.ts
  • Modify: src/lib/services/paypal-topup.ts
  • Modify: src/lib/services/send-currency.ts

Interfaces:

export const ECONOMY_ROUTE_GROUPS = [
  "catalog", "items", "commerce", "history", "value", "rewards",
] as const;
export const ECONOMY_SEARCH_PROVIDER_IDS = [
  "economy.catalog-pages", "economy.items", "economy.transactions",
] as const;
  • Write route tests covering catalog/detail/Builder Club/maintenance, items/detail, shop, marketplace, transactions, vouchers, subscriptions, rare values, badges, achievements, sounds, and calendar matrix rows.
  • Write adapter tests for catalog trees/items, commerce history, transactions, vouchers/subscriptions, marketplace, rare values, rewards, sounds, and calendar; verify stable pagination and money/value serialization.
  • Write sensitive command tests for catalog/item edits, maintenance, vouchers, shop changes, rare values, badge/reward changes, and destructive catalog operations with reason/audit requirements.
  • Run Economy tests and confirm RED before implementation.
  • Extract redirect-free domain services, implement six pages plus exact providers/widgets, and retain specialized catalog editors as components inside canonical workflows.
  • Register the Economy manifest and prove matrix closure and non-empty route/search/inbox/widget collections.
  • Run Economy, catalog/service, HK tests, and pnpm typecheck.
  • Run Biome, git diff --check, stage exact files, and commit feat(housekeeping): deliver economy vertical.

Task 16: Deliver Hotel rooms, radio, badges, and runtime tools

Files:

  • Create: src/features/housekeeping/domains/hotel/routes.ts
  • Create: src/features/housekeeping/domains/hotel/routes.test.ts
  • Create: src/features/housekeeping/domains/hotel/queries/rooms.ts
  • Create: src/features/housekeeping/domains/hotel/queries/radio.ts
  • Create: src/features/housekeeping/domains/hotel/queries/assets.ts
  • Create: src/features/housekeeping/domains/hotel/queries/hotel-queries.test.ts
  • Create: src/features/housekeeping/domains/hotel/commands/room-commands.ts
  • Create: src/features/housekeeping/domains/hotel/commands/radio-commands.ts
  • Create: src/features/housekeeping/domains/hotel/commands/asset-commands.ts
  • Create: src/features/housekeeping/domains/hotel/commands/hotel-commands.test.ts
  • Create: src/features/housekeeping/domains/hotel/pages/rooms.tsx
  • Create: src/features/housekeeping/domains/hotel/pages/room-detail.tsx
  • Create: src/features/housekeeping/domains/hotel/pages/room-furni.tsx
  • Create: src/features/housekeeping/domains/hotel/pages/radio.tsx
  • Create: src/features/housekeeping/domains/hotel/pages/badges.tsx
  • Create: src/features/housekeeping/domains/hotel/pages/sounds.tsx
  • Create: src/features/housekeeping/domains/hotel/pages/hotel-pages.test.tsx
  • Modify: src/actions/rooms.ts
  • Modify: src/actions/admin-radio-api-keys.ts
  • Modify: src/actions/admin-radio-autodj.ts
  • Modify: src/actions/admin-radio-extra.ts
  • Modify: src/actions/admin-radio-moderation.ts
  • Modify: src/actions/admin-radio-points.ts
  • Modify: src/actions/admin-badges.ts
  • Modify: src/actions/admin-badge-upload.ts
  • Modify: src/lib/services/radio.ts
  • Modify: src/lib/services/import-badge.ts
  • Modify: src/lib/services/rcon.ts
  • Modify: src/lib/services/soundtracks.ts

Interfaces:

export const HOTEL_PRIMARY_ROUTE_IDS = [
  "hotel.rooms", "hotel.room-detail", "hotel.room-furni",
  "hotel.radio.overview", "hotel.radio.settings", "hotel.radio.monitoring",
  "hotel.radio.moderation", "hotel.radio.autodj", "hotel.radio.history",
  "hotel.radio.points", "hotel.radio.ranks", "hotel.radio.api-keys",
  "hotel.radio.banners", "hotel.radio.embed", "hotel.badges", "hotel.sounds",
] as const;
  • Write route tests proving room show/edit aliases merge into one detail and one furni route; assert every radio/badge/sound matrix row has a canonical destination.
  • Write query tests for room/owner/furni, radio configuration/monitoring/history/ranks, badges, and soundtracks; include unavailable RCON/radio dependencies.
  • Write command tests for room changes, furni movement/removal, radio configuration/moderation/API keys/points, badge upload, and sounds; require reasons for destructive or external operations.
  • Run Hotel tests and confirm RED.
  • Extract redirect-free services, implement the six workflow page modules, and keep legacy wrappers live until cutover.
  • Run Hotel primary, RCON/radio/sound, HK tests, and pnpm typecheck.
  • Run Biome, git diff --check, stage exact files, and commit feat(housekeeping): deliver hotel operations.

Task 17: Integrate Studio and long-running asset operations

Files:

  • Create: src/features/housekeeping/domains/hotel/queries/studio.ts
  • Create: src/features/housekeeping/domains/hotel/queries/studio.test.ts
  • Create: src/features/housekeeping/domains/hotel/commands/studio-commands.ts
  • Create: src/features/housekeeping/domains/hotel/commands/studio-commands.test.ts
  • Create: src/features/housekeeping/domains/hotel/pages/studio.tsx
  • Create: src/features/housekeeping/domains/hotel/pages/studio.test.tsx
  • Create: src/features/housekeeping/domains/hotel/components/operation-progress.tsx
  • Create: src/features/housekeeping/domains/hotel/components/operation-result.tsx
  • Create: src/features/housekeeping/domains/hotel/components/operation-progress.test.tsx
  • Create: src/features/housekeeping/domains/hotel/search.ts
  • Create: src/features/housekeeping/domains/hotel/inbox.ts
  • Create: src/features/housekeeping/domains/hotel/widgets.ts
  • Create: src/features/housekeeping/domains/hotel/route-handlers.ts
  • Create: src/features/housekeeping/domains/hotel/hotel-providers.test.ts
  • Modify: src/features/housekeeping/domains/hotel/manifest.ts
  • Modify: src/actions/import-furni.ts
  • Modify: src/actions/furni-maintenance.ts
  • Modify: src/lib/services/clone-import.ts
  • Modify: src/lib/services/clothing-set-import.ts
  • Modify: src/lib/services/effect-import.ts
  • Modify: src/lib/services/figure-import.ts
  • Modify: src/lib/services/furni-import.ts
  • Modify: src/lib/services/furni-maintenance.ts
  • Modify: src/lib/services/pet-import.ts
  • Modify: src/lib/services/repair-icons.ts
  • Modify: src/lib/services/repair-nitros.ts
  • Modify: src/lib/services/upload-import.ts

Interfaces:

export type StudioOperationKind =
  | "badge" | "clone" | "clothing" | "effect" | "furni"
  | "maintenance" | "pet" | "repair-icons" | "sync" | "upload";
export interface StudioOperationEvent {
  operationId: string;
  kind: StudioOperationKind;
  phase: "queued" | "running" | "completed" | "failed" | "partial";
  completed: number;
  total: number | null;
  messageKey: string;
  correlationId: string;
}
  • Write tests for all ten Studio kinds, progress ordering, partial batch results, cancellation/abort propagation, unavailable external sources, and persisted intent before filesystem/RCON work.
  • Run Studio tests and confirm RED.
  • Wrap existing services with typed operations while preserving their current progress/error semantics and stable internal /api/admin/import/* transport paths.
  • Implement the canonical /ase/hotel/studio/* workflow, operation progress/result components, Studio search, operational inbox source, and mandatory active-operation widget.
  • Register every Hotel matrix route and prove no duplicate Studio root or orphan handler.
  • Run Studio/import/service tests, Hotel tests, HK suite, and pnpm typecheck.
  • Run Biome, git diff --check, stage exact files, and commit feat(housekeeping): integrate studio operations.

Task 18: Implement global navigation, entity search, and command discovery

Files:

  • Create: src/features/housekeeping/foundation/search/search-service.ts
  • Create: src/features/housekeeping/foundation/search/search-service.test.ts
  • Create: src/features/housekeeping/foundation/search/navigation-search.ts
  • Create: src/features/housekeeping/foundation/search/navigation-search.test.ts
  • Create: src/actions/housekeeping-search.ts
  • Create: src/actions/housekeeping-search.test.ts
  • Create: src/features/housekeeping/foundation/shell/command-deck.tsx
  • Create: src/features/housekeeping/foundation/shell/command-deck.test.tsx
  • Modify: src/features/housekeeping/foundation/shell/command-trigger.tsx
  • Modify: src/features/housekeeping/foundation/shell/housekeeping-shell.tsx
  • Modify: src/features/housekeeping/foundation/shell/housekeeping-shell.test.tsx

Interfaces:

export interface HousekeepingSearchResponse {
  navigation: readonly HousekeepingNavigationHit[];
  commands: readonly HousekeepingCommandHit[];
  entities: readonly HousekeepingSearchResult[];
  errors: readonly { providerId: string; code: HousekeepingErrorCode }[];
  correlationId: string;
}
export function searchHousekeeping(
  term: string,
  context: HousekeepingCapabilityContext,
): Promise<HousekeepingSearchResponse>;
  • Write tests proving trimmed terms shorter than two characters search navigation/commands only; two-character terms invoke permitted entity providers.
  • Add orchestration tests for 2,000 ms/provider, 25/provider, 50 combined, stable dedupe/order, forbidden provider omission, and partial errors.
  • Run search/action/deck tests and confirm RED.
  • Implement registry navigation/command matching, domain entity orchestration, and a cmdk-based keyboard dialog with grouped results and canonical-to-preview href projection.
  • Test open/close shortcut, focus restoration, arrow navigation, Enter activation, Escape, loading, no-results, and partial-provider UI.
  • Run search, shell, provider, HK tests, and pnpm typecheck.
  • Run Biome, git diff --check, stage exact files, and commit feat(housekeeping): add global command deck search.

Task 19: Implement the derived operational inbox

Files:

  • Create: src/features/housekeeping/foundation/inbox/inbox-service.ts
  • Create: src/features/housekeeping/foundation/inbox/inbox-service.test.ts
  • Create: src/actions/housekeeping-inbox.ts
  • Create: src/actions/housekeeping-inbox.test.ts
  • Create: src/features/housekeeping/foundation/shell/operational-inbox.tsx
  • Create: src/features/housekeeping/foundation/shell/operational-inbox.test.tsx
  • Create: src/features/housekeeping/domains/system/search.ts
  • Create: src/features/housekeeping/domains/system/inbox.ts
  • Create: src/features/housekeeping/domains/system/widgets.ts
  • Create: src/features/housekeeping/domains/system/system-providers.test.ts
  • Modify: src/features/housekeeping/domains/system/manifest.ts

Interfaces:

export interface HousekeepingInboxResponse {
  items: readonly HousekeepingWorkItem[];
  errors: readonly { sourceId: string; code: HousekeepingErrorCode }[];
  correlationId: string;
}
export const INBOX_POLICY = {
  timeoutMs: 2_000,
  combinedLimit: 200,
  dedupe: "sourceId:itemId",
} as const;
  • Write tests for (sourceId,itemId) dedupe, capability filtering before count, priority then age ordering, 2,000 ms/source, 200-item cap, and partial-source failures.
  • Run inbox action/service/component tests and confirm RED.
  • Implement composition over registered People, Content, Economy, Hotel, and System sources without adding assignment/read-status persistence.
  • Add System alert, emulator-error, and operational-anomaly sources plus System search/widgets that Task 10 registered conceptually.
  • Implement accessible filters by domain/state/priority, canonical links, source error summaries, and empty/loading/partial states.
  • Run inbox, all domain-provider, HK tests, and pnpm typecheck.
  • Run Biome, git diff --check, stage exact files, and commit feat(housekeeping): compose operational inbox.

Task 20: Add recent work, favorites, and widget personalization

Files:

  • Create: src/features/housekeeping/foundation/recent/recent-work.ts
  • Create: src/features/housekeeping/foundation/recent/recent-work.test.ts
  • Create: src/actions/housekeeping-recent.ts
  • Create: src/actions/housekeeping-recent.test.ts
  • Create: src/features/housekeeping/foundation/shell/recent-work.tsx
  • Create: src/features/housekeeping/foundation/shell/favorites.tsx
  • Create: src/features/housekeeping/foundation/shell/widget-grid.tsx
  • Create: src/features/housekeeping/foundation/shell/widget-settings.tsx
  • Create: src/features/housekeeping/foundation/shell/personalization.test.tsx
  • Modify: src/features/housekeeping/foundation/registry.ts
  • Modify: src/features/housekeeping/foundation/registry.test.ts

Interfaces:

export interface HousekeepingRecentItem {
  routeId: string;
  canonicalHref: CanonicalHousekeepingHref;
  labelKey: string;
  occurredAt: string;
  source: "route-visit" | "audit";
}
export interface HousekeepingWidgetLoadResult {
  widgets: readonly { id: string; data: unknown }[];
  errors: readonly { widgetId: string; code: HousekeepingErrorCode }[];
}
  • Write tests deriving recent work from housekeeping.route.visit and mutation audit rows, deduping by route ID, capability-filtering, and limiting to 12.
  • Write component tests for pin/unpin, drag/keyboard ordering, mandatory widget lock, optional widget enable/disable, reconciled stale IDs, and partial widget failure.
  • Run recent/personalization/action tests and confirm RED.
  • Implement route-visit recording in admin_audit_log, recent-work queries, reconciled preference actions, dnd-kit ordering, and provider-orchestrated widget loading.
  • Ensure preferences never authorize content and failed preference saves retain the previous UI state with an error announcement.
  • Run preference, recent, widget, HK tests, and pnpm typecheck.
  • Run Biome, git diff --check, stage exact files, and commit feat(housekeeping): personalize command deck.

Task 21: Build the Operations workspace and complete shell composition

Files:

  • Create: src/features/housekeeping/domains/operations/routes.ts
  • Create: src/features/housekeeping/domains/operations/routes.test.ts
  • Create: src/features/housekeeping/domains/operations/queries.ts
  • Create: src/features/housekeeping/domains/operations/queries.test.ts
  • Create: src/features/housekeeping/domains/operations/pages/workspace.tsx
  • Create: src/features/housekeeping/domains/operations/pages/workspace.test.tsx
  • Create: src/features/housekeeping/domains/operations/search.ts
  • Create: src/features/housekeeping/domains/operations/inbox.ts
  • Create: src/features/housekeeping/domains/operations/widgets.ts
  • Create: src/features/housekeeping/domains/operations/route-handlers.ts
  • Modify: src/features/housekeeping/domains/operations/manifest.ts
  • Modify: src/features/housekeeping/foundation/shell/housekeeping-shell.tsx
  • Modify: src/features/housekeeping/foundation/shell/housekeeping-shell.test.tsx
  • Modify: src/app/ase-next/page.tsx

Interfaces:

export const OPERATIONS_ROUTES = [{
  id: "operations.workspace",
  href: "/ase",
  capability: anyCapability(PERMS.ADMIN_DASHBOARD),
}] as const;
export interface OperationsWorkspaceModel {
  inbox: HousekeepingInboxResponse;
  recent: readonly HousekeepingRecentItem[];
  favorites: HousekeepingPreferences;
  widgets: HousekeepingWidgetLoadResult;
}
  • Write route/matrix tests mapping the legacy /admin row to operations.workspace at canonical /ase.
  • Write workspace tests for capability-specific sections, independent partial failures, no accessible domain, and preview links.
  • Run Operations tests and confirm RED.
  • Implement parallel inbox/recent/preferences/widget loading and render the operational home directly at /ase-next; the canonical cutover renders the same handler directly at /ase.
  • Populate the Operations manifest with real route, safe navigation command, operational inbox summary, and mandatory workspace widget.
  • Run Operations, shell, registry, HK tests, and pnpm typecheck.
  • Run Biome, git diff --check, stage exact files, and commit feat(housekeeping): compose operations workspace.

Task 22: Finish responsive behavior, accessibility, and localization

Files:

  • Modify: src/features/housekeeping/foundation/shell/housekeeping-shell.tsx
  • Modify: src/features/housekeeping/foundation/shell/domain-rail.tsx
  • Modify: src/features/housekeeping/foundation/shell/context-nav.tsx
  • Modify: src/features/housekeeping/foundation/shell/operator-summary.tsx
  • Modify: src/features/housekeeping/foundation/shell/command-deck.tsx
  • Modify: src/features/housekeeping/foundation/shell/operational-inbox.tsx
  • Modify: src/features/housekeeping/foundation/shell/recent-work.tsx
  • Modify: src/features/housekeeping/foundation/shell/favorites.tsx
  • Modify: src/features/housekeeping/foundation/shell/widget-grid.tsx
  • Modify: src/features/housekeeping/foundation/shell/widget-settings.tsx
  • Create: src/features/housekeeping/foundation/shell/accessibility.test.tsx
  • Create: src/features/housekeeping/foundation/shell/responsive-contract.test.tsx
  • Modify: src/features/housekeeping/foundation/page/housekeeping-page-shell.tsx
  • Modify: src/features/housekeeping/foundation/page/housekeeping-page-state.tsx
  • Modify: src/features/housekeeping/foundation/page/housekeeping-page-state.test.tsx
  • Modify: src/features/housekeeping/foundation/localization-contract.test.ts
  • Modify: src/messages/ar.json
  • Modify: src/messages/bg.json
  • Modify: src/messages/cs.json
  • Modify: src/messages/da.json
  • Modify: src/messages/de.json
  • Modify: src/messages/el.json
  • Modify: src/messages/en.json
  • Modify: src/messages/es.json
  • Modify: src/messages/fi.json
  • Modify: src/messages/fr.json
  • Modify: src/messages/hr.json
  • Modify: src/messages/hu.json
  • Modify: src/messages/it.json
  • Modify: src/messages/ja.json
  • Modify: src/messages/nl.json
  • Modify: src/messages/no.json
  • Modify: src/messages/pl.json
  • Modify: src/messages/pt.json
  • Modify: src/messages/ro.json
  • Modify: src/messages/ru.json
  • Modify: src/messages/sk.json
  • Modify: src/messages/sr.json
  • Modify: src/messages/sv.json
  • Modify: src/messages/tr.json
  • Modify: src/messages/uk.json
  • Modify: src/app/globals.css

Interfaces:

export const HOUSEKEEPING_LANDMARKS = [
  "banner", "primary-navigation", "context-navigation", "main",
] as const;
export type HousekeepingPageState =
  | "loading" | "empty" | "partial" | "error" | "forbidden" | "ready";
  • Write failing tests for one active nav item, landmark labels, heading hierarchy, skip link, focus-visible behavior, keyboard-reorder instructions, live error announcements, reduced-motion classes, and page-state semantics.
  • Write responsive contracts for rail/context navigation collapse below lg, usable command deck at 320 px, non-overflowing tables/cards, and unchanged capabilities between mobile/desktop.
  • Extend localization contract to collect every manifest/route/command/widget/state key and assert a non-empty value in all 25 locale files.
  • Run accessibility/responsive/localization tests and confirm RED.
  • Implement semantic shell behavior and complete every locale subtree with native-language operator copy; do not expose untranslated keys or preview wording after cutover.
  • Run shell/page/localization tests, HK suite, and pnpm typecheck.
  • Run targeted Biome, git diff --check, stage exact UI/locale files, and commit feat(housekeeping): finish accessible command deck.

Task 23: Close the 137-row matrix against the runtime registry

Files:

  • Create: src/features/housekeeping/cutover/parity.ts
  • Create: src/features/housekeeping/cutover/parity.test.ts
  • Create: src/features/housekeeping/cutover/source-boundaries.test.ts
  • Modify: src/features/housekeeping/migration/operations.ts
  • Modify: src/features/housekeeping/migration/people.ts
  • Modify: src/features/housekeeping/migration/content.ts
  • Modify: src/features/housekeeping/migration/economy.ts
  • Modify: src/features/housekeeping/migration/hotel.ts
  • Modify: src/features/housekeeping/migration/system.ts
  • Modify: scripts/verify-housekeeping-matrix.ts
  • Modify: package.json

Interfaces:

export interface HousekeepingParityReport {
  discovered: 137;
  mapped: 137;
  verified: 137;
  removed: number;
  unresolved: readonly string[];
  capabilityGaps: readonly string[];
  handlerGaps: readonly string[];
}
export function verifyHousekeepingRuntimeParity(
  matrix: readonly MigrationEntry[],
  registry: HousekeepingRegistry,
  handlers: readonly HousekeepingRouteHandler[],
): HousekeepingParityReport;
  • Write a failing aggregate test requiring exactly 137 discovered/mapped/verified rows, zero unresolved/capability/handler gaps, every retained target under /ase, and every removed row with no handler.
  • Write source-boundary tests forbidding foundation imports from domain internals/database/actions and forbidding one domain from another domain's internals.
  • Run parity/boundary tests and confirm RED.
  • Add concrete parityEvidence test IDs to each matrix row and change retained rows to VERIFIED, removed rows to REMOVED only after their evidence passes.
  • Extend hk:matrix:check output with the runtime parity counts and make non-137 or any gap exit non-zero.
  • Run pnpm hk:matrix:check, pnpm test:housekeeping, and pnpm typecheck.
  • Run Biome, git diff --check, stage exact files, and commit test(housekeeping): prove 137 route parity.

Task 24: Pass cumulative pre-cutover verification

Files:

  • Create: docs/superpowers/evidence/2026-08-26-housekeeping-pre-cutover.md
  • Inspect: every file changed by Tasks 1-23; source failures return to their owning task and commit before this evidence-only task continues

Interfaces:

The evidence document records command, exit code, test count, date/time, environment limitations, visual viewport, route, actor capability fixture, and observed result. It never reports unavailable live services as passing.

  • Run pnpm toolchain:check, pnpm hk:matrix:check, pnpm test:housekeeping, pnpm test, and pnpm typecheck; record fresh output and fix only Housekeeping-caused failures with a RED/GREEN test.
  • Run semantic Biome on all changed JS/TS/JSON with formatter disabled, run targeted formatter only on changed files, then run git diff --check.
  • Run pnpm build with the repository's required temporary environment values; restore every environment file/value afterward and record restoration.
  • Start the preview in non-production mode and verify /ase-next at 1440x900, 1024x768, 390x844, and 320x568 for all six domains plus loading, empty, partial, error, and forbidden states.
  • Smoke permitted/denied access, safe/sensitive commands, provider timeout isolation, preference persistence/reconciliation, and all long-running Studio states.
  • Record evidence, run git diff --check, stage only the evidence and verified fixes, and commit test(housekeeping): record pre-cutover verification.

Task 25: Perform the atomic /ase cutover

Files:

  • Move: src/app/ase-next to src/app/ase
  • Delete: src/app/admin
  • Delete: src/app/mod
  • Modify: src/features/housekeeping/foundation/routing/href.ts
  • Modify: src/features/housekeeping/foundation/preview-gate.ts
  • Modify: src/features/housekeeping/foundation/preview-gate.test.ts
  • Modify: src/features/housekeeping/foundation/preview-route-contract.test.ts
  • Create: src/features/housekeeping/cutover/route-cutover.test.ts
  • Modify: src/lib/admin/guard.ts
  • Modify: src/lib/admin/guard.test.ts
  • Modify: src/proxy.ts
  • Modify: src/components/navigation.tsx
  • Modify: src/components/top-header.tsx
  • Modify: src/components/admin/admin-breadcrumb.tsx
  • Modify: src/lib/admin-theme-source-audit.test.ts
  • Modify: src/features/housekeeping/foundation/foundation-source-contract.test.ts
  • Modify: src/env.ts
  • Modify: .env.example

Interfaces:

export const HOUSEKEEPING_ROOT = "/ase" as const;
// No runtime preview surface remains after cutover.
  • Write the route-cutover test first: src/app/ase/layout.tsx and canonical dispatcher must exist; src/app/admin, src/app/admin-next, src/app/ase-next, and src/app/mod must not exist; proxy/global navigation/fallbacks must target /ase; no redirect maps removed UI paths.
  • Run the cutover test and confirm RED before moving/removing route trees.
  • Move the completed preview tree to /ase, remove preview-only badge/gate/flag behavior, and make all navigation/search/inbox/widget links canonical without preview projection.
  • Remove legacy UI trees, rewrite global navigation and authorization fallbacks, and keep /api/admin/* internal endpoints unchanged because they are not UI compatibility routes.
  • Remove imports/tests tied to deleted page modules; retain shared services/components only when the new domains import them without legacy route coupling.
  • Run cutover, proxy/auth, source-boundary, theme, matrix, HK, full tests, and pnpm typecheck.
  • Run Biome on changed files, git diff --check, stage the entire exact cutover set, and commit feat(housekeeping): cut over administration to ase.

Task 26: Run final review and release-quality verification

Files:

  • Create: docs/superpowers/evidence/2026-08-26-housekeeping-final.md
  • Inspect: every file changed on origin/main...HEAD; confirmed findings return to their owning task and commit before this evidence-only task continues

Interfaces:

Final acceptance requires a clean git diff --check, 137/137 runtime parity, production build success, no legacy UI route tree, no compatibility redirect, and recorded desktop/mobile evidence for /ase.

  • Review git diff --stat origin/main...HEAD, every commit, and the complete diff for authorization bypass, client-trusted capability, missing audit, leaked secret, unsafe external/file mutation, cross-domain import, dead legacy route, and unrelated churn.
  • Invoke superpowers:requesting-code-review; classify each finding by evidence and fix confirmed findings in one reviewed wave using a failing regression test first.
  • Re-run pnpm toolchain:check, pnpm hk:matrix:check, pnpm test:housekeeping, pnpm test, pnpm typecheck, semantic Biome, targeted formatting, and git diff --check from a clean process.
  • Re-run pnpm build with temporary environment restoration and repeat canonical /ase route/access/command visual smoke at 1440x900 and 390x844.
  • Verify direct requests to /admin, /admin-next, /ase-next, /mod, and removed routes are unreachable and not redirected; verify /api/health locally only if its dependencies are available.
  • Record exact final evidence and residual pre-existing repository debt, stage only the evidence/fix wave, and commit test(housekeeping): finalize release evidence.
  • Stop before network mutation. Present branch status, commits, checks, and evidence to the user; push and open the one final PR only after an explicit instruction.

Post-merge release gate

After the final PR is explicitly authorized, pushed, reviewed, and merged, wait for the deployment pipeline to finish and verify the live /api/health response plus authenticated /ase access. A failed migration or health check blocks the release. Rollback deploys the prior application release; the additive 0023 schema remains compatible and is not destructively reversed.