Revert "Merge pull request 'Complete Housekeeping migration and /ase cutover' (#52) from codex/housekeeping-complete into main"
CI / check (push) Successful in 27s
CI / release (push) Skipped
CI / deploy (push) Successful in 43s

This reverts commit 488b6e57c4, reversing
changes made to b506b4499a.
This commit is contained in:
Simo committed 2026-08-30 21:31:34 +02:00
1 parent 488b6e57c4
commit b1ddda66ff
802 files changed
+61370 -76659

No files matched your search

@@ -1,148 +0,0 @@
# Task 10 report: System vertical
## Outcome
Delivered the real System access, configuration, observability, and operations vertical from base `0117b45d74450510187f8f860ee927a193c45a3c` on `codex/housekeeping-complete`.
- Registered the exact 17 System route IDs, canonical `/ase/system/*` hrefs, labels, and read capabilities from `migration/system.ts`.
- Added injected access, configuration, observability, and operations queries with forbidden, partial, and dependency-unavailable results.
- Extracted redirect-free, server-only, capability-guarded mutation services from the six legacy action modules while retaining their existing permission checks and `/admin` revalidation behavior.
- Registered 29 sensitive System commands through deterministic bootstrap, dispatcher authorization, confirmation, rate limiting, and audit. Reasons are mandatory for ACL/permission changes, global settings, alert broadcast, every RCON operation, and maintenance/global availability.
- Added four query-backed server workflow page modules with loading, empty, partial, error, forbidden, and ready states.
- Added the exact 17 System handlers to the global aggregate. The manifest contains real routes and deliberately keeps providers, search, inbox, and widgets empty for Task 19.
No database operation, deployment, push, pull request update, Task 11 work, `/admin` or `/mod` cutover, rank-threshold authorization, or placeholder workflow was performed. `.remember/remember.md` remained untracked and untouched.
## TDD evidence
All Vitest commands used `--coverage.enabled=false` so each RED/GREEN cycle exercised only the named boundary.
| Phase | Exact command | RED | GREEN |
| --- | --- | --- | --- |
| Routes | `pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/system/routes.test.ts` | 1 file failed before tests: missing `./routes`. | 1 file, 3 tests passed. |
| Injected queries | `pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/system/queries/system-queries.test.ts` | 1 file failed before tests: missing `./access`. | 1 file, 6 tests passed. |
| Commands and guarded service | `pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/system/commands/system-commands.test.ts` | 1 file failed before tests: missing `../services/mutations`. | 1 file, 6 tests passed at the first command boundary. |
| Legacy alert and maintenance wrappers | `pnpm exec vitest run --coverage.enabled=false src/actions/admin-alerts.test.ts src/actions/admin-maintenance.test.ts` | 1 of 7 tests failed because the existing alert mock granted `notifications.edit` instead of the canonical `admin.notifications.edit`. | 2 files, 7 tests passed after correcting only the stale mock permission. |
| ACL wrapper extraction | `pnpm exec vitest run --coverage.enabled=false src/lib/admin/acl-management-contract.test.ts` | 1 of 2 tests failed before `access.permissions.update` was present. | 1 file, 2 tests passed after the wrapper delegated to the guarded service. |
| Workflow pages | `pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/system/pages/system-pages.test.tsx` | 1 file failed before tests: missing `./access`. | 1 file, 8 tests passed. |
| Handler/bootstrap integration | `pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/route-handlers.test.ts src/features/housekeeping/foundation/commands/bootstrap.test.ts` | 2 tests failed: System had 0 handlers instead of 17 and no 29-command bootstrap registration. | 2 files, 3 tests passed. |
| Review regressions | `pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/system/commands/system-commands.test.ts src/features/housekeeping/domains/system/services/mutations-production.test.ts src/lib/admin/acl-management-contract.test.ts` | 3 files failed; 11 tests failed and 6 passed. Failures proved missing alert reason, six whitespace-only inputs accepted, three alert dependency failures swallowed, and the public/non-strict production boundary. | 3 files, 17 tests passed after the minimal corrections. |
The first integrated target run passed 17 files and 179 tests. `pnpm typecheck` then exposed four integration-only type errors (a heterogeneous test tuple, a bigint alert identifier, and result-union narrowing); the corrected run passed. The first `pnpm test:housekeeping` exposed exactly three obsolete foundation assertions (40 files/372 tests otherwise passed). The three directly obsolete contracts were updated with strict positive System assertions without relaxing another domain; the focused rerun passed 2 files/38 tests and the then-current full suite passed 42 files/376 tests.
## Final verification
- `pnpm exec vitest run --coverage.enabled=false src/actions/admin-alerts.test.ts src/actions/admin-maintenance.test.ts src/lib/admin/acl-management-contract.test.ts src/features/housekeeping/domains/system/routes.test.ts src/features/housekeeping/domains/system/queries/system-queries.test.ts src/features/housekeeping/domains/system/commands/system-commands.test.ts src/features/housekeeping/domains/system/services/mutations-production.test.ts src/features/housekeeping/domains/system/pages/system-pages.test.tsx src/features/housekeeping/migration/system.test.ts src/features/housekeeping/route-handlers.test.ts src/features/housekeeping/foundation/commands/bootstrap.test.ts src/features/housekeeping/foundation/commands/registry.test.ts src/features/housekeeping/foundation/commands/dispatcher.test.ts src/features/housekeeping/foundation/commands/confirmation.test.ts src/features/housekeeping/foundation/commands/audit-envelope.test.ts src/features/housekeeping/foundation/foundation-source-contract.test.ts src/features/housekeeping/foundation/registry.test.ts`  17 files, 185 tests passed.
- `pnpm exec vitest run --coverage.enabled=false src/lib/admin-operations-contract.test.ts src/lib/staff-smoke-contract.test.ts src/lib/admin/authorization-contract.test.ts`  3 files, 97 tests passed.
- `pnpm test:housekeeping`  43 files, 385 tests passed.
- `pnpm typecheck`  passed (`tsc --noEmit`).
- `pnpm exec biome check --formatter-enabled=false src/actions/admin-alerts.test.ts src/actions/admin-alerts.ts src/actions/admin-emulator.ts src/actions/admin-maintenance.ts src/actions/admin-settings.ts src/actions/commandocentrum.ts src/actions/permissions.ts src/features/housekeeping/domains/system src/features/housekeeping/foundation/commands/bootstrap.test.ts src/features/housekeeping/foundation/commands/bootstrap.ts src/features/housekeeping/foundation/foundation-source-contract.test.ts src/features/housekeeping/foundation/registry.test.ts src/features/housekeeping/route-handlers.test.ts src/features/housekeeping/route-handlers.ts src/lib/admin/acl-management-contract.test.ts`  checked 32 files; no fixes applied.
- `git diff --check`  exit 0; only expected Git autocrlf warnings.
- `git diff --cached --check`  exit 0 before staging and rerun after exact staging.
- Independent read-only re-review  0 Critical, 0 Important, 0 Minor; ready verdict.
Node/pnpm emitted this non-blocking warning during pnpm gates:
```text
[WARN] Unsupported engine: wanted: {"node":">=26.8.1 <27"} (current: {"node":"v26.7.0","pnpm":"11.24.0"})
```
## Architectural decisions
- The migration matrix remains the single source of route truth. The System route array is materialized from its exact identifiers and values, and tests assert ordered route/handler equality rather than set-only coverage.
- Query factories accept narrow adapters; production adapters reuse existing ACL, settings, emulator, health, online-user, analytics, log, alert, and maintenance services. The fix round added only a strict online-roster helper beside the unchanged tolerant legacy API in `ops-online-users.ts`, so System can report a database outage truthfully.
- `systemMutationService` is the only public production mutation boundary. It is server-only and repeats capability enforcement even when called by an already-guarded legacy action or an authorized dispatcher. The unguarded production adapter is module-private.
- Adapter exceptions and unsuccessful RCON sends become typed `DEPENDENCY_UNAVAILABLE` failures. Rank-delete conflict metadata travels in the standard `fieldErrors` shape; the legacy wrapper reconstructs the prior human-readable `ActionError`, keeping the dispatcher result schema strict.
- Command string schemas use a non-transforming `\S` check to reject whitespace-only values; normalization and trimming remain at the guarded service boundary. This preserves the foundation registry rule that command schemas contain no executable transforms.
- System navigation labels use stable `pages.housekeeping.routes.system.*` keys. Complete source strings are present in the tested English and Italian catalogs; repository fallback remains responsible for other locales.
- Foundation source-boundary changes are a narrow source-to-import allowlist for the new System integration edges. Existing forbidden directions for every other domain remain asserted.
## Changed files
- `.superpowers/sdd/2026-08-26-housekeeping-completion/task-10-report.md`
- `src/actions/admin-alerts.test.ts`
- `src/actions/admin-alerts.ts`
- `src/actions/admin-emulator.ts`
- `src/actions/admin-maintenance.ts`
- `src/actions/admin-settings.ts`
- `src/actions/commandocentrum.ts`
- `src/actions/permissions.ts`
- `src/features/housekeeping/domains/system/commands/system-commands.test.ts`
- `src/features/housekeeping/domains/system/commands/system-commands.ts`
- `src/features/housekeeping/domains/system/manifest.ts`
- `src/features/housekeeping/domains/system/pages/access.tsx`
- `src/features/housekeeping/domains/system/pages/configuration.tsx`
- `src/features/housekeeping/domains/system/pages/observability.tsx`
- `src/features/housekeeping/domains/system/pages/operations.tsx`
- `src/features/housekeeping/domains/system/pages/system-pages.test.tsx`
- `src/features/housekeeping/domains/system/queries/access.ts`
- `src/features/housekeeping/domains/system/queries/configuration.ts`
- `src/features/housekeeping/domains/system/queries/observability.ts`
- `src/features/housekeeping/domains/system/queries/operations.ts`
- `src/features/housekeeping/domains/system/queries/system-queries.test.ts`
- `src/features/housekeeping/domains/system/route-handlers.ts`
- `src/features/housekeeping/domains/system/routes.test.ts`
- `src/features/housekeeping/domains/system/routes.ts`
- `src/features/housekeeping/domains/system/services/mutations-production.test.ts`
- `src/features/housekeeping/domains/system/services/mutations.ts`
- `src/features/housekeeping/foundation/commands/bootstrap.test.ts`
- `src/features/housekeeping/foundation/commands/bootstrap.ts`
- `src/features/housekeeping/foundation/foundation-source-contract.test.ts`
- `src/features/housekeeping/foundation/registry.test.ts`
- `src/features/housekeeping/route-handlers.test.ts`
- `src/features/housekeeping/route-handlers.ts`
- `src/lib/admin/acl-management-contract.test.ts`
## Official review fix round 1
The official review was addressed on exact base `3788ecd9f1a4e32e68abac5ee2dae3418cdebfb2`. The three parked Minor findings were deliberately left unchanged.
### Findings resolved
1. **Housekeeping label namespace:** all 17 System routes used legacy `pages.admin.*` keys, which the Task 9 preview layout correctly rejected. Routes now use 17 stable `pages.housekeeping.routes.system.*` keys, EN/IT provide non-empty source strings, and a preview-contract test builds and translates the real System navigation without broadening layout validation.
2. **Truthful partial/outage states:** access, configuration, and observability previously rendered empty before considering failed dependencies. Partial now takes precedence whenever any dependency failed. System online-user queries use a strict helper that exposes database failure; the existing tolerant `fetchOpsOnlineUsers` API and legacy behavior remain intact.
3. **Rank synchronization failures:** create, delete, and update no longer report success when `updatepermissions` returns false, and set-rank no longer reports success when RCON committed but database persistence failed. Both paths return the existing strict `DEPENDENCY_UNAVAILABLE` envelope with stable message keys and explicit `fieldErrors` describing `operation`, `completed`, and `pending` effects. Dispatcher audit records `intent` then `failure`, never `success`.
4. **Legacy permission error parity:** known rank-in-use and role-not-found conflicts retain their established `ActionError` text. Unknown infrastructure failures now cross the real `adminAction` boundary as ordinary errors and are sanitized to `Internal server error`; internal Housekeeping message keys are not exposed to the legacy UI.
### Fix-round TDD evidence
| Cycle | Exact command | RED | GREEN |
| --- | --- | --- | --- |
| Labels and runtime navigation | `pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/system/routes.test.ts src/features/housekeeping/foundation/localization-contract.test.ts src/features/housekeeping/foundation/preview-route-contract.test.ts` | 3 files failed; 4 tests failed and 66 passed. The route labels mismatched, EN/IT lacked the routes subtree, and preview layout rejected `pages.admin.hubs.tabs.permissions`. | 3 files, 70 tests passed. |
| Partial precedence and online-user outage | `pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/system/pages/system-pages.test.tsx src/features/housekeeping/domains/system/queries/operations-production.test.ts` | 2 files failed; 4 tests failed and 9 passed. Three pages rendered empty, and the production adapter resolved a false ready zero-user state on database failure. | 2 files, 13 tests passed. |
| Rank synchronization | `pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/system/services/rank-mutations-production.test.ts` | 1 file failed; 4 tests failed. Create/delete/update returned success after failed permission synchronization, and set-rank lacked explicit partial-completion metadata. | 1 file, 4 tests passed. The first post-production run had 3 passed and 1 test-only audit expectation failure; aligning it with the established `intent` then `failure` envelope produced the final GREEN without a further production change. |
| Legacy permission parity | `pnpm exec vitest run --coverage.enabled=false src/actions/permissions.test.ts` | 1 file failed; 1 test failed and 2 passed. The generic infrastructure case leaked `errors.housekeeping.dependencyUnavailable`; both known business conflicts already retained their prior text. | 1 file, 3 tests passed. |
The combined focused rerun passed 7 files and 90 tests. The first fix-round `pnpm typecheck` found two test-only narrowing errors in the new rank test; after the minimal annotations, its focused test remained green and `tsc --noEmit` passed.
### Fix-round verification
- Full affected Task 10 System, action, audit, authorization, bootstrap, localization, and preview suite: 22 files, 264 tests passed.
- Legacy operations, staff smoke, and authorization suite: 3 files, 97 tests passed.
- `pnpm test:housekeeping`: 45 files, 395 tests passed.
- `pnpm typecheck`: passed (`tsc --noEmit`).
- Exact changed-file `pnpm exec biome check --formatter-enabled=false ...`: checked 17 code, test, and locale files; no fixes applied after the one mechanical import-order correction.
- UTF-8 source verification confirmed the Italian `Analisi attività` label contains U+00E0, followed by a 3-file/70-test route-localization-preview GREEN rerun.
- `git diff --check` and the pre-stage `git diff --cached --check`: exit 0; only expected Git autocrlf warnings.
- Independent read-only re-review: 0 Critical, 0 Important, 0 new Minor; all four official Important findings resolved, all three parked Minors unchanged, ready-to-merge verdict.
### Fix-round changed files
- `.superpowers/sdd/2026-08-26-housekeeping-completion/task-10-report.md`
- `src/actions/permissions.test.ts`
- `src/actions/permissions.ts`
- `src/features/housekeeping/domains/system/pages/access.tsx`
- `src/features/housekeeping/domains/system/pages/configuration.tsx`
- `src/features/housekeeping/domains/system/pages/observability.tsx`
- `src/features/housekeeping/domains/system/pages/system-pages.test.tsx`
- `src/features/housekeeping/domains/system/queries/operations-production.test.ts`
- `src/features/housekeeping/domains/system/queries/operations.ts`
- `src/features/housekeeping/domains/system/routes.test.ts`
- `src/features/housekeeping/domains/system/routes.ts`
- `src/features/housekeeping/domains/system/services/mutations.ts`
- `src/features/housekeeping/domains/system/services/rank-mutations-production.test.ts`
- `src/features/housekeeping/foundation/localization-contract.test.ts`
- `src/features/housekeeping/foundation/preview-route-contract.test.ts`
- `src/lib/admin/ops-online-users.ts`
- `src/messages/en.json`
- `src/messages/it.json`
@@ -1,349 +0,0 @@
# Task 11 — People workflow read models
Status: DONE — fix round 2
## Delivered scope
- Added the exact 24-route People catalog covering the 39 migration-matrix entries across users, multi-account review, online/community, guilds, staff applications/teams, support tickets/help tickets, CFH, moderation overview, bans, IP rules, VPN settings, and word filter workflows.
- Added canonical, JSON-serializable People DTOs, `/ase/people` link builders, bounded list normalization, and stable sorting with numeric-ID tie breaking.
- Added injected query factories and narrow server-only production adapters for user/detail, community/guild, staff/applications/teams, support queues/tickets/help/CFH, and moderation/bans/sanctions sources.
- Reused foundation `HousekeepingResult`, error codes, capability context, authorization, and canonical href contracts. People-local `ListInput` and `Page` were added because no shared foundation equivalents exist in this checkout.
- Kept the People manifest, global handlers, pages, mutations, providers, widgets, search, and inbox unchanged for Task 12.
## Security and behavior decisions
- User mail and current IP remain independently nullable fields. Each is projected only when the capability context contains the existing `PERMS.USERS_VIEW`; `PERMS.MOD_USERS_VIEW` alone receives the safe base projection with both values set to `null`, and a context with neither permission is forbidden.
- No new ACL slug or rank threshold was introduced. Staff filtering reuses the existing `getMinStaffRank()` source.
- The production user selection is explicit and excludes passwords, authentication tickets, secrets, and two-factor material. VPN settings intentionally exclude `vpn_api_key`.
- Adapters fail closed. Malformed driver envelopes, invalid identifiers, corrupt links, non-serializable DTO values, and count failures map to `DEPENDENCY_UNAVAILABLE`. Primary/entity identifiers remain positive safe integers; zero is accepted only for the schema-declared guild `userId`/`roomId` and CFH `senderId`/`reportedId`/`roomId`/`moderatorId` sentinels. Missing valid detail entities map to `NOT_FOUND`; invalid request identifiers map to `VALIDATION`.
- Pagination clamps page size to 100 and offset to 10,000. Deterministic primary sorting, numeric-ID tie breaking, and `LIMIT`/`OFFSET` now execute in the database; no list query fetches a prefix for locale re-sorting or second slicing.
- Raw production adapters and `buildPeopleUserSelection` are module-private. Runtime exports expose only context-authorized query factories and singleton query surfaces.
- Multi-account clusters use one bounded CTE/window page query plus one independent matching-cluster count query, cap accounts per cluster at 100, and never issue one query per IP cluster.
- User detail/edit now includes the operator's watched state and canonical permission-rank data. Support ticket reads use the existing unified inbox through a strict, fail-closed, database-paged mode that includes CMS and help-center rows while leaving the legacy tolerant mode unchanged.
- The unified `/support/tickets` inbox still merges CMS and help-center rows. The ticket desk now has its own strict CMS-only page loader preserving priority, category, assignee, and message count; help summaries include reply count. Support desk/detail DTOs explicitly include queue counts, bounded staff, and the relevant active ban.
- Active bans are filtered before sorting. Expiry `0` remains the permanent-active sentinel; expired rows cannot hide permanent or future-active bans in lists or details.
## Official fix round 1 findings
1. **Authorization boundary:** fixed by making all raw production adapters and the user selection builder module-private and testing only guarded public query surfaces plus source/runtime export contracts.
2. **Pagination and sorting:** fixed by moving declared sort fields, deterministic tie ordering, and bounded `LIMIT`/`OFFSET` to production adapters. The exact `user10`/`user2` and support `status`/`updatedAt` page regressions are covered.
3. **Resource bounds:** fixed by replacing multi-account prefix loading plus per-row `Promise.all` with one bounded batched CTE/window query. No million-row prefix and no N+1 cluster query remain.
4. **Fail-closed database validation:** fixed across People models and community/support/moderation query boundaries. Invalid driver shapes and invalid identifiers cannot become empty lists, `NOT_FOUND`, ID `0`, or corrupt canonical links.
5. **Canonical dependencies:** fixed watched and permission-rank data for user detail/edit; `/support/tickets` now calls strict `fetchUnifiedTicketInbox`; support queue/staff/active-ban data is explicit in canonical query DTOs.
6. **Moderation capability equality:** fixed after direct user authorization. `moderationQuery.capability` now exactly equals the existing eleven-slug overview union already used by the route and `run`; no route, mutation, rank threshold, or new slug changed.
7. **Active bans:** fixed list/detail selection so permanent `ban_expire = 0` and future-active bans are deterministic and expired rows cannot hide them.
The two official Minor findings remain parked and unchanged as instructed.
## Official fix round 2 findings
1. **Entity-aware sentinels:** canonical guild DTOs now use the real schema names `userId` and `roomId`. Serialization permits zero only on those two guild fields and the four named CFH fields when the containing DTO has the matching canonical entity href. Generic `*Id` zero values, negatives, unsafe integers, and primary ID zero remain unavailable failures.
2. **Support source fidelity:** `people.support.tickets` remains on strict `fetchUnifiedTicketInbox`. `people.support.ticket-desk` now dispatches to a distinct strict `website_tickets` loader with message aggregation and no help-center source. Real priority/category/assignee/message count and help reply count are present in canonical DTOs; malformed driver rows fail closed.
3. **Multi-account total:** the page CTE and matching-cluster count run as two bounded parallel queries. Empty pages retain the correct total without prefix loading or N+1 queries.
## Strict TDD evidence
### Cycle 1 — exact route catalog
RED:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/routes.test.ts
Test Files 1 failed
Error: Cannot find module './routes'
```
GREEN:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/routes.test.ts
Test Files 1 passed (1)
Tests 3 passed (3)
```
### Cycle 2 — canonical models and normalizers
RED:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/models.test.ts
Test Files 1 failed
Error: Cannot find module './models'
```
GREEN:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/models.test.ts
Test Files 1 passed (1)
Tests 5 passed (5)
```
### Cycle 3 — injected-adapter read queries
RED:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/queries/people-queries.test.ts
Test Files 1 failed
Error: Cannot find module './community'
```
GREEN:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/queries/people-queries.test.ts
Test Files 1 passed (1)
Tests 10 passed (10)
```
Production-source contract RED:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/queries/people-adapters-production.test.ts
Test Files 1 failed (1)
Tests 2 failed (2)
Reason: raw production adapters and buildPeopleUserSelection were exported as bypassable runtime internals.
```
Pagination regression RED after adding the production contract fixture:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/queries/people-adapters-production.test.ts
Test Files 1 failed (1)
Tests 1 failed | 2 passed (3)
Expected ["203.0.113.1", "203.0.113.2"], received ["203.0.113.2"].
```
GREEN for the original baseline implementation:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/queries/people-adapters-production.test.ts
Test Files 1 passed (1)
Tests 3 passed (3)
```
The query tests cover adversarial page size/offset/search, stable tie sorting, empty/missing entities, adapter and count failures, PII capability combinations, serializable DTOs, explicit source projection, and production pagination.
## Fix round 1 strict behavioral TDD evidence
### Authorization boundary
RED:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/queries/people-adapters-production.test.ts
Test Files 1 failed (1)
Tests 2 failed (2)
Observed runtime exports: buildPeopleUserSelection and peopleUsersAdapters.
```
GREEN:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/queries/people-adapters-production.test.ts
Test Files 1 passed (1)
Tests 3 passed (3)
```
### Database pagination and declared sorting
RED:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/models.test.ts src/features/housekeeping/domains/people/queries/people-queries.test.ts
Test Files 2 failed (2)
Tests 4 failed | 14 passed (18)
Failures: offset 999999 was not capped; DB pages were sliced a second time for user10/user2 and support status/updatedAt.
```
GREEN:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/models.test.ts src/features/housekeeping/domains/people/queries/people-queries.test.ts
Test Files 2 passed (2)
Tests 18 passed (18)
```
### Multi-account resource bounds
RED:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/queries/people-adapters-production.test.ts
Test Files 1 failed (1)
Tests 1 failed | 2 passed (3)
Observed prefix result plus one query per IP cluster.
```
GREEN:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/queries/people-adapters-production.test.ts
Test Files 1 passed (1)
Tests 3 passed (3)
```
### Fail-closed validation
RED:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/models.test.ts src/features/housekeeping/domains/people/queries/people-queries.test.ts src/features/housekeeping/domains/people/queries/people-adapters-production.test.ts
Test Files 3 failed (3)
Tests 5 failed | 21 passed (26)
Failures covered ID 0, corrupt links/dates, corrupt detail shapes, and malformed driver envelopes.
```
GREEN:
```text
same command
Test Files 3 passed (3)
Tests 26 passed (26)
```
### Canonical dependencies and unified support inbox
RED:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/queries/people-queries.test.ts src/features/housekeeping/domains/people/queries/people-adapters-production.test.ts -t "watched state|hydrates desk|strict unified"
Test Files 2 failed (2)
Tests 3 failed | 22 skipped (25)
```
GREEN:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/models.test.ts src/features/housekeeping/domains/people/queries/people-queries.test.ts src/features/housekeeping/domains/people/queries/people-adapters-production.test.ts -t "watched state|hydrates desk|strict unified|normalizes BigInt"
Test Files 3 passed (3)
Tests 4 passed | 27 skipped (31)
```
### Moderation capability equality
RED captured before direct authorization:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/queries/people-queries.test.ts -t "eleven-permission"
Test Files 1 failed (1)
Tests 1 failed | 18 skipped (19)
Expected the route/run eleven-slug union; query metadata still contains six slugs.
```
GREEN after the user directly authorized only this isolated metadata hunk:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/queries/people-queries.test.ts -t "eleven-permission"
Test Files 1 passed (1)
Tests 1 passed | 18 skipped (19)
```
### Active-ban semantics
RED:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/queries/people-adapters-production.test.ts -t "permanent"
Test Files 1 failed (1)
Tests 1 failed | 4 skipped (5)
Expected permanent expiresAt 0; received null.
```
GREEN:
```text
same command
Test Files 1 passed (1)
Tests 1 passed | 4 skipped (5)
```
## Fix round 2 strict behavioral TDD evidence
### Entity-aware schema sentinels
RED:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/queries/people-queries.test.ts -t "zero sentinels"
Test Files 1 failed (1)
Tests 2 failed | 19 skipped (21)
Valid guild userId/roomId zero and CFH senderId/reportedId/moderatorId/roomId zero were rejected by generic identifier validation.
```
GREEN:
```text
same command
Test Files 1 passed (1)
Tests 2 passed | 19 skipped (21)
```
### CMS-only ticket desk and help reply counts
RED:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/queries/people-queries.test.ts src/features/housekeeping/domains/people/queries/people-adapters-production.test.ts -t "CMS-only context loader|reply counts"
Test Files 2 failed (2)
Tests 2 failed | 28 skipped (30)
The desk received a help row with synthetic normal priority; help summary omitted replyCount.
```
GREEN:
```text
same command
Test Files 2 passed (2)
Tests 2 passed | 28 skipped (30)
```
### Independent multi-account total
RED:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/queries/people-adapters-production.test.ts -t "beyond the last page"
Test Files 1 failed (1)
Tests 1 failed | 8 skipped (9)
Expected total 4 on the empty page; received 0.
```
GREEN:
```text
same command
Test Files 1 passed (1)
Tests 1 passed | 8 skipped (9)
```
## Verification
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/routes.test.ts src/features/housekeeping/domains/people/models.test.ts src/features/housekeeping/domains/people/queries/people-queries.test.ts src/features/housekeeping/domains/people/queries/people-adapters-production.test.ts
Test Files 4 passed (4)
Tests 40 passed (40)
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people src/features/housekeeping/foundation/foundation-source-contract.test.ts src/features/housekeeping/foundation/authorization.test.ts src/features/housekeeping/foundation/capability-context.test.ts src/features/housekeeping/foundation/server-capability-context.test.ts src/features/housekeeping/foundation/contracts/contracts.test.ts
Test Files 9 passed (9)
Tests 86 passed (86)
pnpm test:housekeeping
Test Files 49 passed (49)
Tests 435 passed (435)
pnpm typecheck
tsc --noEmit
Exit 0
pnpm exec biome check --formatter-enabled=false <7 exact changed Task 11 TypeScript files>
Checked 7 files. No fixes applied.
git diff --check
Exit 0
```
Both `pnpm test:housekeeping` and `pnpm typecheck` emitted the environment warning: the repository requires Node `>=26.8.1 <27`, while this host runs Node `v26.7.0` with pnpm `11.24.0`. Tests and typecheck still exited successfully.
No database operation, deployment, push, or pull-request update was performed.
@@ -1,404 +0,0 @@
# Task 12 — People users, community, and staff workflows
Status: DONE
## Delivered scope
- Registered exactly the nine approved real People routes: users list/edit/multi-account/detail, community online/guilds/guild detail, and staff applications/teams. The remaining support and moderation routes stay catalogued in `routes.ts` but unregistered for Task 13.
- Added query-backed People pages with explicit loading, empty, partial, dependency-error, forbidden, and ready states. Links are canonical `/ase/people/*` links; optional mail/IP fields and mutation affordances remain absent unless their exact capability is present.
- Added the exact fourteen user command IDs plus the six stable People-owned IDs `people.guild.disband`, `people.application.decide`, `people.team.change`, `people.ip.action`, `people.vpn.configure`, and `people.word-filter.update`.
- Added bounded Zod command schemas, stable rate limits, dispatcher capability rechecks, confirmation metadata, a redirect-free server-only mutation service, and deterministic bootstrap registration.
- Extracted shared mutation behavior behind the existing actions while preserving the legacy action exports, exact ACLs, `/admin` revalidation, VPN redirect/fail-soft behavior, word-filter `ActionResult` shapes, already-gone delete semantics, and failure propagation where legacy persistence errors previously propagated.
- Added neutral EN/IT labels only for the nine runtime routes.
## Security and behavior decisions
- No ACL slug or route authorization rank threshold was added. Exact legacy capabilities remain authoritative: single ban/unban use `USERS_BAN`, reset-password uses `USERS_RESET_PASSWORD`, bulk/user/community/team/application operations use `USERS_EDIT`, IP/VPN use `SETTINGS_EDIT`, and word filter uses `WORDFILTER_EDIT`.
- The existing target hierarchy safeguard remains for legacy user mutations that previously used `guardRank`; alert remains capability-authorized without a new target-rank rule.
- Ordinary user edit and alert remain reason-free because their existing semantics are non-destructive. Sanctions, destructive operations, global/security changes, currency delivery, and bulk mutations require a nonblank dispatcher reason. Ban and bulk-ban operational reasons are also persisted with the mutation audit evidence.
- Every public service call rechecks the exact capability before production work. The production adapter is module-private; server-only placement is not treated as authorization.
- Successful mutations emit before/after audit evidence and a stable correlation ID. Audit persistence failure is fail-closed and maps to `DEPENDENCY_UNAVAILABLE`. User mutation audit snapshots omit mail because it is unnecessary PII; page projection continues to follow Task 11 exactly.
- User pages consume only Task 11 guarded read models, preserving bounded pagination, deterministic sorting, fail-closed DTO validation, serialization, zero-sentinel rules, watched state, permission context, and PII projection.
- Legacy wrappers remain on `/admin` behavior until Task 25. No `/admin`, `/mod`, API, redirect, database schema, deployment, or cutover behavior was changed.
## Strict TDD evidence
### Initial command/page/route RED
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/commands/user-commands.test.ts src/features/housekeeping/domains/people/commands/community-commands.test.ts src/features/housekeeping/domains/people/pages/people-primary-pages.test.tsx
Test Files 3 failed (3)
Tests 0
Missing modules: community-commands, ../services/mutations, ../route-handlers
```
Initial focused GREEN:
```text
Command tests: 2 files passed, 22 tests passed
Primary page/route tests: 3 files passed, 12 tests passed
Bootstrap tests: 1 file passed, 2 tests passed
```
### Foundation integration RED/GREEN
RED after enabling People:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people src/features/housekeeping/foundation
Test Files 3 failed | 31 passed
Tests 4 failed | 376 passed
Failures: stale System-only registry assertions, stale preview expectation, and an unapproved People vertical runtime edge.
```
GREEN after updating the explicit runtime-edge and registry contracts:
```text
Focused foundation contracts: 3 files passed, 40 tests passed
People + foundation: 34 files passed, 380 tests passed
```
### Audited sanction reason
RED:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/services/mutations-reason-production.test.ts
Test Files 1 failed (1)
Tests 1 failed (1)
The ban audit after-snapshot did not contain the nonblank sanction reason.
```
GREEN:
```text
Production mutation contracts: 2 files passed, 4 tests passed
The audited snapshot includes the reason and excludes mail.
```
### Legacy wrapper failure parity
RED:
```text
pnpm exec vitest run --coverage.enabled=false src/actions/people-wrapper-errors.test.ts
Test Files 1 failed (1)
Tests 3 failed (3)
Persistence failures were swallowed and already-gone word-filter deletion was not idempotent.
```
GREEN:
```text
Test Files 1 passed (1)
Tests 3 passed (3)
```
### Single authorization check for positive bulk adjustment
RED:
```text
pnpm exec vitest run --coverage.enabled=false src/actions/bulk-adjust-wrapper.test.ts
Test Files 1 failed (1)
Tests 1 failed (1)
Expected one requirePermission call; received two.
```
GREEN:
```text
Test Files 1 passed (1)
Tests 1 passed (1)
```
### Static gates during implementation
```text
pnpm typecheck
RED: one unused `describe` import in admin-ip.test.ts
GREEN: tsc --noEmit, exit 0
pnpm exec biome check --formatter-enabled=false <exact Task 12 src files>
RED: 14 import-order assists
GREEN: checked 44 files, no fixes applied
```
## Final verification
```text
Focused wrapper/command/page/service/route/authorization/audit matrix
Test Files 22 passed (22)
Tests 129 passed (129)
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people src/features/housekeeping/foundation
Test Files 35 passed (35)
Tests 381 passed (381)
pnpm test:housekeeping
Test Files 54 passed (54)
Tests 469 passed (469)
pnpm typecheck
tsc --noEmit
Exit 0
pnpm exec biome check --formatter-enabled=false <44 exact changed Task 12 src files>
Checked 44 files. No fixes applied.
git diff --check
Exit 0
```
The Node engine warning remains the approved non-blocker: the repository requests Node `>=26.8.1 <27`, while this host runs Node `v26.7.0` with pnpm `11.24.0`. All test and type gates exited successfully.
No database operation, deployment, push, or pull-request update was performed.
## Official review fix round 1
The official review reported 0 Critical and 5 Important findings. This round addresses the five findings without widening the Task 12 route catalog or changing legacy redirects, safe-action response shapes, or cutover behavior.
### RED evidence
```text
Production server authority: auth resolver was called 0 times at the public service boundary (1 failing regression).
Canonical external audit: 3 failing regressions for missing durable intent/outcome behavior.
Transactional audit: expected one transaction and observed zero (1 failing regression).
Legacy/production workflows: new production matrix initially exposed bulk truncation/deduplication, trade-lock hierarchy/state, missing StaffActivities, and missing word-filter refresh behavior.
Primary workflows: page suite started at 7 passed / 2 failed (no executable command form and no bounded URL parser); preview contract started at 61 passed / 3 failed (searchParams/loading propagation).
Import boundary after real forms: test:housekeeping reached 481 passed / 1 failed, then the focused boundary exposed one exact page-state -> People models edge (22 passed / 1 failed).
```
### GREEN implementation
- Production People services now rehydrate `getHousekeepingCapabilityContext()` on every public mutation. Invocation data can carry correlation and an expected actor only; it cannot synthesize permissions. The production adapter stays private, while test factories inject an authority resolver.
- Pure database mutations write their canonical before/after audit evidence in the same transaction. Mixed database/RCON/cache work writes sanitized intent first and a correlated success, failure, or partial outcome afterward. Audit-outcome persistence errors retain truthful completed/partial state, and legacy wrappers preserve their observable behavior.
- Ban/unban use observed active-ban state; trade-lock uses observed sanction/settings state. Passwords, hashes, API keys, and secrets are excluded from canonical evidence.
- Shared legacy bulk paths preserve original order, duplicates, totals, and iteration with no service-side 100-item cap. The <=100 bound remains in command schemas. Trade lock has no invented hierarchy gate and its missing-user wrapper message remains exactly `User not found`.
- Original `StaffActivities` side effects are retained for bulk ban/unban/currency/badge, guild disband, VPN, and trade lock. Missing word-filter deletion still reloads local cache, sends RCON refresh, and returns legacy success.
- The nine registered pages now expose capability-gated, accessible command forms backed by `executeHousekeepingCommand`; no inert command spans remain. Edit submits a mutation, list inputs come from bounded URL search parameters, and the dynamic preview route passes them through. Atomic Task 11 queries keep their fail-closed contracts; the impossible synthetic partial state was removed. A real Next loading route was added.
- The foundation contract allows only the exact same-domain edges required here: each People page to the shared People command form, the form to the single housekeeping command action, and page-state to the People `ListInput` model. No wildcard or prefix relaxation was introduced.
### Final verification after review fixes
```text
Focused wrapper/command/page/service/route/auth/audit/staff-smoke matrix
Test Files 24 passed (24)
Tests 187 passed (187)
pnpm test:housekeeping
Test Files 58 passed (58)
Tests 482 passed (482)
pnpm test
Test Files 206 passed | 3 skipped (209)
Tests 1321 passed | 5 skipped (1326)
pnpm typecheck
tsc --noEmit
Exit 0
pnpm exec biome check --formatter-enabled=false <40 exact changed Task 12 source files>
Checked 40 files. No fixes applied.
git diff --check e1b31ff7738eb5cc59e7765c8ed7290d62130972 --
Exit 0
```
The approved Node engine warning remains: the repository requests Node `>=26.8.1 <27`, while the host runs Node `v26.7.0` with pnpm `11.24.0`. No database operation, deployment, push, or pull-request update was performed.
## Official review fix round 2
The round-1 re-review reported 0 Critical, 7 Important, and no Minor findings. This round addresses all seven findings without changing the nine-route Task 12 manifest or exposing any raw production adapter.
### RED evidence
```text
Typed partial/result contract: 5 failed / 8 passed before completion metadata and audit-outcome handling were added.
Observed active-ban and absent-settings snapshots: 2 focused failures before deterministic active reads and null-preserving trade snapshots.
BIGINT preservation: 8 focused failures across application, team, IP, and wordfilter before decimal string/BigInt boundaries.
Real form/reset workflow: 2 primary-page failures before the actual action adapter and one-time credential result were added.
Production operation closure: 2 failed / 10 passed before unban observed-after and bulk false-RCON partial truth.
Post-commit notification/legacy parity: 2 failed / 12 passed before update/reset transactional intent and legacy throw/false mapping.
Cumulative gate exposed one unsupported custom Zod schema, one stale direct-alert expectation, and one stale numeric audit-ID expectation; each received a minimal regression-preserving fix.
```
### GREEN implementation
- Mixed database/external operations now commit sanitized intent with the mutation and return correlated typed `partial` completion when RCON, cache, notification, or final audit persistence fails afterward. Pre-mutation external failure and intent persistence failure remain blocking. The dispatcher and public server action preserve one serializable partial result and emit no contradictory generic failure evidence.
- Ban and unban reuse the permanent-or-unexpired Task 11 filter, deterministic timestamp/ID ordering, and observed before/after reads. An absent `UsersSettings` row remains null before and after a no-op trade settings update.
- Legacy alert calls RCON without a target query or hierarchy guard. Legacy wrappers retain their prior false/throw behavior while new Housekeeping commands report synchronization false as partial truth.
- Application, team, IP, and wordfilter identifiers remain canonical decimal strings/`BigInt` through wrappers and Drizzle, including values above `Number.MAX_SAFE_INTEGER`. The cloneable command regex accepts the full unsigned BIGINT range and rejects overflow without a Zod custom refinement.
- Reset-password returns the generated credential once in the current authorized form result. It is rendered through an accessible `output`, excluded from durable service evidence, and recursively redacted by the canonical audit sanitizer.
- Production tests execute all twenty Task 12 operation IDs with meaningful database/RCON/audit assertions. The primary-page test invokes the actual form action adapter, and the unused multi-accounts-to-command-form boundary exception was removed.
### Final verification after review fix round 2
```text
Focused People + foundation + wrappers + audit + action + staff-smoke matrix
Test Files 45 passed (45)
Tests 459 passed (459)
pnpm test:housekeeping
Test Files 58 passed (58)
Tests 502 passed (502)
pnpm test
Test Files 206 passed | 3 skipped (209)
Tests 1345 passed | 5 skipped (1350)
pnpm typecheck
tsc --noEmit
Exit 0
pnpm exec biome check --formatter-enabled=false <28 exact changed TypeScript/TSX files>
Checked 28 files. No fixes applied.
```
The approved Node engine warning remains: the repository requests Node `>=26.8.1 <27`, while the host runs Node `v26.7.0` with pnpm `11.24.0`. No database operation, deployment, push, or pull-request update was performed.
## Official review fix round 3
The round-2 re-review reported 0 Critical, 2 Important, and 2 adjacent Minor findings. This round addresses all four findings without changing the nine-route manifest, the public command IDs, or legacy external call ordering and permissions.
### RED evidence
```text
Focused external-audit, bulk-production, and dispatcher matrix
Test Files 2 failed (2)
Tests 15 failed | 54 passed (69)
The ten external-only false/throw cases persisted optimistic desired after-state instead of confirmed unchanged or unknown delivery evidence. Four bulk currency/badge false/throw cases reported completed=0 and Database error after a committed database write. The dispatcher accepted one ok:false result carrying impossible completion metadata.
```
### GREEN implementation
- External-only alert, disconnect, mute, unmute, and send-currency keep desired state in intent/success evidence. Confirmed RCON `false` now writes a dedicated unchanged/no-delivery failure snapshot; an exception writes unknown delivery with a null after-state. Correlation and failure outcome stay identical across intent/outcome records.
- Bulk currency and badge count a successful database write before RCON. RCON false/throw is additive `externalSyncFailures` sync debt, never a database failure; `failedIds` remains reserved for database/business failures and the result is typed partial with an explicit no-automatic-retry warning.
- Webhook notification remains explicit fire-and-forget best effort (`void notify(...)`) and no longer participates in mutation completion. The impossible promise-rejection test was replaced with the real void contract.
- The dispatcher runtime schema now accepts `completion` only for `ok: true`, matching the TypeScript `HousekeepingResult` contract; failure envelopes containing it are rejected as malformed.
### Final verification after review fix round 3
```text
Focused external audit + production bulk + dispatcher
Test Files 3 passed (3)
Tests 73 passed (73)
People + foundation + legacy wrappers + staff-smoke matrix
Test Files 48 passed (48)
Tests 470 passed (470)
pnpm test:housekeeping
Test Files 58 passed (58)
Tests 516 passed (516)
pnpm test
Test Files 206 passed | 3 skipped (209)
Tests 1359 passed | 5 skipped (1364)
pnpm typecheck
tsc --noEmit
Exit 0
pnpm exec biome check --formatter-enabled=false <4 exact changed source/test files>
Checked 4 files. No fixes applied.
git diff --check
Exit 0
```
The approved Node engine warning remains: the repository requests Node `>=26.8.1 <27`, while the host runs Node `v26.7.0` with pnpm `11.24.0`. No database operation, deployment, push, or pull-request update was performed.
## Official review fix round 4
The round-3 re-review reported 0 Critical, 2 Important, and 0 Minor findings. This round restores the pre-cutover legacy bulk result contract at the wrapper boundary and makes committed-database/emulator-sync debt explicit in the successful partial operator result. Canonical Housekeeping accounting, audit evidence, routes, commands, and ACLs remain unchanged.
### Pre-Task12 parity evidence
`git show e1b31ff7^:src/actions/bulk-users.ts` confirms that currency and badge wrappers awaited RCON inside the same `try`: an RCON exception entered the catch, did not increment `given`, and appended `{ userId, reason: "Database error" }`; an RCON `false` return did not throw and therefore remained a legacy success. Positive bulk adjustment delegated to the same currency wrapper and had the same result semantics.
### RED evidence
```text
pnpm exec vitest run --coverage.enabled=false src/actions/bulk-users.test.ts src/actions/bulk-adjust-wrapper.test.ts
Test Files 2 failed (2)
Tests 3 failed | 3 passed (6)
Currency, badge, and positive-adjust wrappers returned given/adjusted=1 with no failedIds for the canonical external-sync debt produced by a thrown RCON call; historical results require 0 plus Database error.
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/pages/people-primary-pages.test.tsx
Test Files 1 failed (1)
Tests 2 failed | 12 passed (14)
The operator result rendered only Partially completed and exposed neither an alert/do-not-retry instruction nor the typed user sync debt returned by the real form adapter.
```
### GREEN implementation
- `src/actions/bulk-users.ts` translates only `externalSyncFailures` at the legacy wrapper boundary into historical `Database error` failures and subtracts those entries from `given`/positive `adjusted`. Canonical completed counts and sync-debt evidence are untouched; the existing legacy `false` path still produces no external-sync entry and remains successful. Failure entries are restored in input order, including duplicate IDs.
- `src/features/housekeeping/domains/people/pages/people-command-form.tsx` reads only a successful typed partial result with failed external completion and a bounded `after.externalSyncFailures` array. It renders an alert, explicit do-not-retry instruction, and safe user/reason debt entries. Unknown payload fields and malformed entries are never rendered, and the generated reset password path remains one-time and unchanged.
Focused GREEN:
```text
pnpm exec vitest run --coverage.enabled=false src/actions/bulk-users.test.ts src/actions/bulk-adjust-wrapper.test.ts
Test Files 2 passed (2)
Tests 6 passed (6)
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/domains/people/pages/people-primary-pages.test.tsx
Test Files 1 passed (1)
Tests 14 passed (14)
pnpm exec vitest run --coverage.enabled=false src/actions/bulk-users.test.ts src/actions/bulk-adjust-wrapper.test.ts src/features/housekeeping/domains/people/pages/people-primary-pages.test.tsx src/features/housekeeping/domains/people/services/mutations-production-workflows.test.ts
Test Files 4 passed (4)
Tests 48 passed (48)
```
### Cumulative verification
```text
People + foundation + Task12 legacy wrappers + route/audit/staff-smoke matrix
Test Files 52 passed (52)
Tests 491 passed (491)
pnpm test:housekeeping
Test Files 58 passed (58)
Tests 518 passed (518)
pnpm test
Test Files 206 passed | 3 skipped (209)
Tests 1364 passed | 5 skipped (1369)
pnpm typecheck
tsc --noEmit
Exit 0
pnpm exec biome check --formatter-enabled=false src/actions/bulk-users.ts src/actions/bulk-users.test.ts src/actions/bulk-adjust-wrapper.test.ts src/features/housekeeping/domains/people/pages/people-command-form.tsx src/features/housekeeping/domains/people/pages/people-primary-pages.test.tsx
Checked 5 files. No fixes applied.
git diff --check
Exit 0
```
The only warning is the approved Node engine mismatch: the repository requests Node `>=26.8.1 <27`, while the host runs Node `v26.7.0` with pnpm `11.24.0`.
### Exact tracked paths
- `.superpowers/sdd/2026-08-26-housekeeping-completion/task-12-report.md`
- `src/actions/bulk-adjust-wrapper.test.ts`
- `src/actions/bulk-users.test.ts`
- `src/actions/bulk-users.ts`
- `src/features/housekeeping/domains/people/pages/people-command-form.tsx`
- `src/features/housekeeping/domains/people/pages/people-primary-pages.test.tsx`
The required controller lines were appended to the git-ignored `.superpowers/sdd/2026-08-26-housekeeping-completion/progress.md`; it is excluded from the commit. `.remember/` remains untouched.
### Self-review
- Scope and compatibility: the production mutation service, canonical audit/accounting, manifest, route, command, ACL, database, redirect, and cutover behavior are unchanged. The adapter applies only to legacy currency/badge results and their historical positive-adjust delegate.
- Security: the operator surface requires an `ok: true` partial/external-failed envelope, accepts at most 100 positive safe-integer user IDs, renders only the canonical safe reason, and does not inspect or serialize arbitrary result payloads. Reset-password display and audit redaction tests remain green.
- Test quality: legacy tests exercise the real exported wrappers against a complete canonical partial response and fail on either wrong count or missing historical failure; UI tests render the real component, invoke the real form adapter, and prove malformed/extra payload is not displayed.
### Commit
Single local commit message: `fix(housekeeping): restore people partial compatibility`. The final SHA of the commit containing this report is returned to the controller after creation.
No database operation, deployment, push, pull, or pull-request update was performed.
@@ -1,234 +0,0 @@
# Task 9 report — canonical route dispatch
## Status
- DONE: matcher, registry collision guard, empty handler aggregate, preview root routing, and catch-all dispatch are implemented.
- Base verified before edits: `2970dff56378cf5259fd125794bf0d89bec25b25` on `codex/housekeeping-complete`.
- Commit message: `feat(housekeeping): dispatch canonical domain routes`.
- `.remember/` remained untouched and untracked.
- No pull, push, PR/MR update, deployment, database operation, Task 10 work, or worktree was performed.
## TDD evidence
### RED — tests written before production
Exact command:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/foundation/routing/match-route.test.ts src/features/housekeeping/foundation/registry.test.ts src/features/housekeeping/route-handlers.test.ts src/features/housekeeping/foundation/preview-route-contract.test.ts
```
Observed exit 1:
```text
Test Files 4 failed (4)
Tests 1 failed | 14 passed (15)
Cannot find module './match-route'
Cannot find module './route-handlers'
Cannot find package '@/app/ase-next/[domain]/[[...segments]]/page'
registry > rejects duplicate dynamic route shapes regardless of parameter name
AssertionError: expected [Function] to throw an error
```
This proved the three missing production boundaries and the existing registry's acceptance of equivalent `:id` / `:username` route shapes.
### First targeted GREEN
The same exact command after the minimum implementation exited 0:
```text
Test Files 4 passed (4)
Tests 94 passed (94)
```
An intermediate run had 92/94 passing because two import-boundary fixtures still used the old route file's relative depth. The fixture imports were moved one directory higher for the new catch-all location; the forbidden-module assertions were unchanged.
### Full-suite contract correction
The first full housekeeping run correctly exposed one obsolete Task 1 expectation:
```text
Test Files 1 failed | 37 passed (38)
Tests 1 failed | 348 passed (349)
Expected NEXT_REDIRECT:/ase-next/operations
Received NEXT_NOT_FOUND
```
`server-capability-context.test.ts` was updated to the Task 9 ruling: with the real registered route set still empty, `/ase-next` calls `notFound()` and must not redirect to an empty Operations placeholder. Its request-scoped context isolation assertions remain intact.
## Implemented behavior
- `matchHousekeepingRoute` compares decoded path segments without constructing a regular expression from route text.
- Static routes win over same-depth dynamic routes; dynamic and nested parameters are returned in a frozen readonly record.
- Unknown, cross-domain, malformed, repeated-separator, trailing-separator, query/fragment, invalid-percent, encoded-separator, dot-segment, and backslash paths fail closed.
- Registry construction rejects duplicate dynamic shapes even when parameter names differ.
- `HousekeepingPageInput` is exactly the readonly `{ context, match }` pair.
- The global route-handler aggregate is empty and its test proves one-to-one equality with the currently empty manifest route set; no placeholder handlers were added.
- `/ase-next` searches registered routes in manifest order, requires both domain and route capability, redirects to the first permitted route, and calls `notFound()` when none exists.
- `/ase-next/<domain>/<segments>` derives the domain's canonical `/ase` path, matches it, finds the exact handler, reacquires the cached request-scoped context, rechecks domain and route capability, and invokes the handler with that same context and match.
- Unknown routes fail before context loading; inaccessible matched routes load one context and never invoke a handler.
## Verification evidence
Targeted routing/registry/handler/preview tests:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/foundation/routing/match-route.test.ts src/features/housekeeping/foundation/registry.test.ts src/features/housekeeping/route-handlers.test.ts src/features/housekeeping/foundation/preview-route-contract.test.ts
Test Files 4 passed (4)
Tests 94 passed (94)
```
Directly affected context contract:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/foundation/server-capability-context.test.ts
Test Files 1 passed (1)
Tests 2 passed (2)
```
Full housekeeping suite:
```text
pnpm test:housekeeping
Test Files 38 passed (38)
Tests 349 passed (349)
```
TypeScript:
```text
pnpm typecheck
$ tsc --noEmit
exit 0
```
The only output note was the existing engine warning: local Node `26.7.0` is below the package request `>=26.8.1 <27`.
Targeted Biome with formatting disabled:
```text
pnpm exec biome check --formatter-enabled=false <11 changed Task 9 source/test files>
Checked 11 files in 47ms. No fixes applied.
```
`git diff --check` exited 0 before staging. Cached-diff and committed-tree checks are run as the final staging/commit gates.
## Exact Task 9 files
```text
src/app/ase-next/[domain]/[[...segments]]/page.tsx
src/app/ase-next/[domain]/layout.tsx
src/app/ase-next/[domain]/page.tsx (deleted)
src/app/ase-next/page.tsx
src/features/housekeeping/foundation/preview-route-contract.test.ts
src/features/housekeeping/foundation/registry.test.ts
src/features/housekeeping/foundation/registry.ts
src/features/housekeeping/foundation/routing/match-route.test.ts
src/features/housekeeping/foundation/routing/match-route.ts
src/features/housekeeping/foundation/server-capability-context.test.ts
src/features/housekeeping/route-handlers.test.ts
src/features/housekeeping/route-handlers.ts
.superpowers/sdd/2026-08-26-housekeeping-completion/task-9-report.md
```
## Self-review and tooling
- Mutation check: dynamic-name normalization removal, regex-style static matching, static-priority removal, decoded-separator acceptance, domain mismatch acceptance, skipped route ACL, context reload inside the handler, missing handler lookup, placeholder handler addition, and empty-domain redirect each break a focused test.
- The catch-all route imports only housekeeping foundation/manifests/handlers and retains the existing forbidden database/auth/permissions/actions/legacy-page boundary audit.
- `apply_patch` created all new files, but the Windows sandbox helper repeatedly failed to read existing files with `apply deny-read ACLs`. Existing-file edits therefore used controller-approved exact-anchor/full-file fallbacks only after resolving absolute paths and validating every target under `E:\Users\simol\Desktop\EpicNext-cms`.
## Fix Round 1 — deterministic encoded route matching
### Status and scope
- Fix base: `e5c230ba35aec2b4c471608d32b8a16ecc1ee382`.
- Only the two Important matcher blockers were addressed.
- The three parked Minor findings remain unchanged; no changed line required an adjustment to them.
- Commit message: `fix(housekeeping): make route matching deterministic`.
- `.remember/` remained untouched. No worktree, push, PR/MR, database operation, deployment, or Task 10 work was performed.
### Root-cause evidence
1. The catch-all receives decoded Next segments and re-encodes them with `encodeURIComponent`. The matcher decoded the request path into `decodedSegments` but compared static route text against `rawSegments`. Therefore literal `a+b[1]` did not equal `a%2Bb%5B1%5D`; the competing `:id` route captured the request and could change the selected capability/handler.
2. Candidate sorting used only total dynamic-segment count. Intersecting patterns `/:kind/settings` and `/users/:id` have the same count, so stable sort preserved manifest order and allowed registration order to decide dispatch.
### RED
Exact command after test setup was validated:
```text
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/foundation/routing/match-route.test.ts src/features/housekeeping/foundation/registry.test.ts src/features/housekeeping/route-handlers.test.ts src/features/housekeeping/foundation/preview-route-contract.test.ts
```
Observed exit 1:
```text
Test Files 2 failed | 2 passed (4)
Tests 2 failed | 95 passed (97)
catch-all encoded literal:
Expected routeId people.literal-tool with params {}
Received routeId people.tool-detail with params { id: "a+b[1]" }
equal-count specificity:
Expected routeId people.user-detail with params { id: "settings" }
Received routeId people.kind-settings with params { kind: "users" }
```
The registration-order table exercises both orders. Before production changes the general-first order failed while the reverse order passed, proving that order was the deciding variable.
An earlier RED attempt exposed a test-table setup error (`manifest.routes is not iterable`); the table was changed from spread array rows to named `{ routes }` rows, then rerun to obtain the behavioral RED above before any production edit.
### Fix
- A single `decodeCanonicalSegment` boundary now normalizes request segments and static route-pattern segments exactly once.
- Invalid percent encoding, empty values, decoded `/` or `\`, and decoded `.` / `..` remain fail closed.
- Dynamic markers retain their parameter names and receive the already-decoded request segment.
- Candidate specificity is compared left-to-right. At the earliest static/dynamic difference, the static segment wins; manifest order no longer selects among intersecting patterns.
- Existing static-over-dynamic behavior and registry duplicate-shape rejection remain unchanged.
### GREEN and pre-commit verification
Targeted command above, exit 0:
```text
Test Files 4 passed (4)
Tests 97 passed (97)
```
Full housekeeping suite, exit 0:
```text
pnpm test:housekeeping
Test Files 38 passed (38)
Tests 352 passed (352)
```
TypeScript, exit 0:
```text
pnpm typecheck
$ tsc --noEmit
```
The only output note remained the existing Node warning: local `26.7.0`, package request `>=26.8.1 <27`.
Exact changed-file Biome, exit 0:
```text
pnpm exec biome check --formatter-enabled=false src/features/housekeeping/foundation/routing/match-route.ts src/features/housekeeping/foundation/routing/match-route.test.ts src/features/housekeeping/foundation/preview-route-contract.test.ts
Checked 3 files in 25ms. No fixes applied.
```
`git diff --check` exited 0 before the report update. Cached and committed-tree checks are final staging/commit gates.
### Exact fix files
```text
src/features/housekeeping/foundation/routing/match-route.ts
src/features/housekeeping/foundation/routing/match-route.test.ts
src/features/housekeeping/foundation/preview-route-contract.test.ts
.superpowers/sdd/2026-08-26-housekeeping-completion/task-9-report.md
```