All checks were successful
ci/woodpecker/push/ci Pipeline was successful
Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
5.0 KiB
5.0 KiB
P8-019 Verification — Phase 8 Platform Architecture
Date: 2026-03-15 Status: complete Branch: feat/p8-019-verify PR: #185 Issue: #172
Test Results
- Unit tests (baseline, pre-P8-019): 101 passing across 9 gateway test files + 1 CLI file
- Integration tests added: 2 new spec files (68 new tests)
apps/gateway/src/commands/commands.integration.spec.ts— 42 testspackages/cli/src/tui/commands/commands.integration.spec.ts— 26 tests
- Total after P8-019: 160 passing tests across 12 test files
- Quality gates: typecheck ✓ lint ✓ format:check ✓ test ✓
Components Verified
Command System
CommandRegistryService.getManifest()returns 19 core commands (>= 12 requirement met)- All commands have correct
executiontype:socket: model, thinking, new, clear, compact, retry, system, gc, agent, mission, prdy, tools, reloadrest: rename, history, export, preferenceshybrid: provider, status (gateway), (status overridden to local in TUI)local: help (gateway); help, stop, cost, status, clear (TUI local)
- All aliases verified: m→model, t→thinking, n→new, a→agent, s→status, h→help, pref→preferences
parseSlashCommand()correctly extracts command + args for all forms- Unknown commands return
success: falsewith descriptive message
Preferences + System Override
PreferencesService.getEffective()applies platform defaults when no user overrides- Immutable keys (
limits.maxThinkingLevel,limits.rateLimit) cannot be overridden — enforcement always wins set()returns error for immutable keys with "platform enforcement" messageSystemOverrideService.set()stores to Valkey with 5-minute TTL; verified via mock/systemcommand callsSystemOverrideService.set()with exact text arg/systemwith no args callsSystemOverrideService.clear()
Session GC
collect(sessionId)deletes allmosaic:session:<id>:*Valkey keysfullCollect()clears allmosaic:session:*keys on cold startsweepOrphans()extracts unique session IDs from keys and collects each- GC result includes
durationandorphanedSessionscount /gccommand invokessweepOrphans(userId)and returns count in response
Tool Security (path-guard)
guardPathrejects../traversal → throwsSandboxEscapeErrorguardPathrejects absolute paths outside sandbox → throwsSandboxEscapeErrorguardPathUnsaferejects sibling-named directories (e.g./tmp/test-sandbox-evil/)- All 12 path-guard tests pass;
SandboxEscapeErrormessage includes path and sandbox in text
Workspace
WorkspaceService.resolvePath()returns user path for solo projects:$MOSAIC_ROOT/.workspaces/users/<userId>/<projectId>WorkspaceService.resolvePath()returns team path for team projects:$MOSAIC_ROOT/.workspaces/teams/<teamId>/<projectId>- Path resolution is deterministic (same inputs → same output)
exists(),createUserRoot(),createTeamRoot()all tested
TUI Autocomplete
filterCommands(commands, query)filters by name, aliases, and description- Empty query returns all commands
- Prefix matching works: "mo" → model, "mi" → mission
- Alias matching: "h" matches help (alias)
- Description keyword matching: "switch" → model
- Unknown query returns empty array
useInputHistoryring buffer caps at 50 entries- Up-arrow recall returns most recent entry
- Down-arrow after up restores saved input
- Duplicate consecutive entries are deduplicated
- Reset navigation works correctly
Hot Reload
ReloadServiceregisters plugins viaregisterPlugin()reload()iterates plugins, calls theirreload()method- Plugin errors are counted but don't prevent other plugins from reloading
- Non-MosaicPlugin objects are skipped gracefully
- SIGHUP trigger verified via reload trigger = 'sighup'
Gaps / Known Limitations
SystemOverrideServicecreates its own Valkey connection in constructor (not injected) — functional but harder to test in isolation without mockingcreateQueue. Current tests mock it at the executor level./statuscommand hasexecution: 'hybrid'in the gateway registry butexecution: 'local'in the TUI local registry — TUI local takes precedence, which is the intended behavior.SessionGCService.fullCollect()runs ononModuleInit(cold start) — this is intentional but means tests must mock redis.keys to avoid real Valkey calls.ProjectBootstrapServiceandTeamsServicein workspace module have no dedicated tests — they are thin wrappers over Drizzle that delegate to WorkspaceService (which is tested).- GC cron schedule (
SESSION_GC_CRONenv var) is configured at module level — not unit tested here; covered by NestJS cron integration. filterCommandsinCommandAutocompleteis not exported — replicated in integration test to verify behavior.
CI Evidence
Pipeline: TBD after push — all 4 local quality gates green:
- pnpm typecheck: 32 tasks, all cached/green
- pnpm lint: 18 tasks, all green
- pnpm format:check: all files match Prettier style
- pnpm test: 32 tasks, 160 tests passing