feat(housekeeping): unify complete rebuild in gated preview
This commit is contained in:
1 parent
4ad007d241
commit
43470ebf82
402 files changed
+78313
-1663
No files matched your search
@@ -0,0 +1,148 @@
|
||||
# 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`
|
||||
@@ -0,0 +1,349 @@
|
||||
# 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.
|
||||
@@ -0,0 +1,404 @@
|
||||
# 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.
|
||||
@@ -0,0 +1,234 @@
|
||||
# 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
|
||||
```
|
||||
Reference in new issue
Block a user