BUG 1: Azure locale derivation produced 'en-EN' (invalid) for 2-letter codes.
→ Added toAzureLocale() with 28-language mapping table (en→en-US, pt→pt-BR, etc.)
→ Exported for testing; falls back to code-CODE for unmapped languages.
BUG 2: model field from request schema was silently dropped after provider refactor.
→ Added optional model field to TranscriptionInput interface.
→ OpenAI provider now uses input.model override (falls back to config.model).
→ Route passes model through to provider.transcribe().
GAP 4: SUPPORTED_AUDIO_TYPES was defined but never validated against.
→ Route now rejects unsupported content-types with a clear error message.
→ Allows application/octet-stream (Azure Blob SAS URLs often return this).
GAP 5: Client JSDoc still said 'via OpenAI Whisper API' — now 'via configured STT provider'.
GAP 8: Azure WAV content-type hardcoded samplerate=16000 — now generic audio/wav.
Tests: 42 transcription tests (was 35), 178 total passing.
→ toAzureLocale: 4 tests (locale mapping, passthrough, fallback, case-insensitive)
→ setSTT: 1 test (singleton override)
→ model passthrough: 2 tests (mock ignores, input accepts)
Marketplace proxy:
- Forward Authorization header to platform-service for consumer/author
routes that call requireAuth() — without this, all authenticated
marketplace endpoints would 401
- Add 2 tests: auth header forwarding + omission when absent
(100 tests, was 98)
IPC intercept_llm handler:
- Replace || with ?? for temperature and max_tokens — temperature:0
is a valid value (deterministic) but || treated it as falsy, passing
undefined to the LLM router instead
Add reverse-IPC protocol support: Rust runtime can send intercept_llm
requests to cowork-service, which routes them through @bytelyst/llm-router.
Changes:
- ipc-bridge.ts: handleLine now detects incoming requests (has 'method' field)
vs normal responses. New handleIncoming() + sendResponse() for reverse IPC.
New onIncomingRequest() to register the handler.
- server.ts: Wires intercept_llm handler — validates messages, calls
getLlmRouter().chat(), records spend for budget tracking, logs provider/model.
- ipc-bridge.test.ts: 5 new tests for reverse IPC (handler registration,
routing, error handling, request vs response disambiguation).
- server.test.ts: Updated IPC bridge mock with onIncomingRequest.
Test count: 85 (was 80)
AuditQuerySchema now accepts taskId and tool optional fields.
Route forwards them as query params to platform-service GET /audit.
Previously these filters sent by the frontend were silently stripped.
Add usage query routes to cowork-service that proxy to platform-service:
- GET /api/usage/summary — user's aggregated usage with days filter
- POST /api/usage/check-limits — check if user is within plan limits
- modules/usage/types.ts — UsageSummaryQuerySchema, CheckLimitsSchema (Zod)
- modules/usage/routes.ts — proxy routes with error handling
- server.ts — register usageRoutes (5 route modules total)
- server.test.ts — add usage routes mock, update register count to 5
57 tests passing, 9 test files, typecheck clean
Bug fixes from systematic review of H.7 LLM router wiring:
- lib/llm-router.ts: remove RUST_RUNTIME_TIMEOUT_MS (300s IPC timeout) override
— let LlmRouter use its built-in 30s default, appropriate for cloud API calls
- server.test.ts: add debug/error to appMock.log — prevents fragile failures
if any startup path hits those log levels
- server.test.ts: add OLLAMA_URL + OLLAMA_MODELS to config mock
New feature:
- config.ts: add OLLAMA_URL + OLLAMA_MODELS env vars for local Ollama support
- server.ts: wire Ollama env vars into initLlmRouter() — set
OLLAMA_MODELS=model1,model2 to auto-add local Ollama as a provider
57 tests passing, 9 test files, typecheck clean
Added LLM routing module to cowork-service:
- lib/llm-router.ts — singleton LlmRouter with cloud + local Ollama support
- modules/llm/types.ts — Zod request schemas
- modules/llm/routes.ts — POST /api/llm/chat, GET /api/llm/providers, GET /api/llm/health
- All endpoints gated by llm_multi_model_enabled feature flag
- Best-effort init: service works without API keys (router stays uninitialized)
- 8 new tests (routes), server test updated for 3 route modules
- 57 total tests passing, typecheck clean
BUG 1: feature-flags.ts had 3 wrong flag names + missing 3 from seed.ts
- Removed: browser_extension_enabled, institutional_knowledge_enabled
- Renamed: connectors_enabled → mcp_connectors_enabled
- Added: llm_multi_model_enabled, telemetry_enabled, platform_auth_required
- Fixed defaults to match seed.ts (marketplace_enabled=true, dispatch_api_enabled=true)
- Now 13 flags exactly matching platform-service/src/modules/flags/seed.ts
BUG 2: ipc-bridge.ts call() had 'initialize' exemption that allowed null deref
- If call('initialize') was invoked externally without start(), the guard
passed but this.child!.stdin!.write() would crash with null dereference
- During normal start(), child.stdin.writable is true so no exemption needed
- Removed the method !== 'initialize' exemption
BUG 3: health routes didn't factor IPC bridge into overall health status
- allOk only checked platform-service reachability
- Now allOk = depsOk && ipcConnected — service reports 503 when bridge is down
- IPC bridge disconnection makes health 'degraded' (correct — fallback mode works)
24 tests passing, typecheck clean.
Extend centralized MCP server with 5 new ChronoMind tools:
- chronomind.timers.reschedule — shift timer by delta or set new target time
- chronomind.timers.availability — find free time slots in a window
- chronomind.routines.start — start a routine from ready/template status
- chronomind.agentActions.list — list agent action audit trail
- chronomind.agentActions.approve — approve a proposed agent action
Client functions added to chronomind-client.ts:
- chronomindTimerReschedule, chronomindTimerAvailability, chronomindRoutineStart
- chronomindAgentActionCreate, chronomindAgentActionsList, chronomindAgentActionApprove
Write tools (reschedule, routines.start) record agent actions for audit trail.
Audit recording is fail-open — failures don't block the actual operation.
MCP server typecheck passes. No breaking changes to existing tools.