You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Four medium-priority gaps remain in the engine layer. Individually small, they collectively affect daily usability and code quality. Bundled here because each is 2-4 hours and they share no dependencies.
Claude Code estimate: ~1-2h
Current State (verified 2026-04-04)
Quiet hours
`User` type has `quietHoursStart?: string` and `quietHoursEnd?: string`
Settings API accepts and persists these fields
Not enforced: `PolicyEvaluator` never checks quiet hours before auto-execution
Policy CRUD
`action_policies` table exists in schema
`PolicyEvaluator` reads via `getAllPolicies()`
No API endpoints for CRUD
Users manage behavior through domain autonomy + escalation triggers, but cannot create custom action-level policies
Type safety
`apps/api/src/routes/ask.ts` line 102: `policyRepositoryAdapter as never`
Lines 105-106: `twinService as never` and `policyEvaluator as never`
Root cause: port interface method names don't match DB repository method names
Structured logging
All logging via `console.log/warn/error`
No JSON output, log levels, request IDs, or correlation
Proposed Change
1. Quiet hours enforcement
Add check in `PolicyEvaluator.evaluate()`: if current time is within quiet hours and outcome is auto-execute, escalate to approval with reason "Quiet hours active." Handle midnight wrap-around (22:00 → 07:00). Urgent escalations (safety, spend limit) still fire.
2. Policy CRUD API
GET/POST/PUT/DELETE at `/api/policies/:userId`. Settings page: "Advanced → Custom Policies" section. Not the primary flow.
3. Type safety cleanup
Create proper adapters in `ask.ts`, remove all `as never` casts. Grep entire codebase to verify zero remain.
4. Structured logging
Add `pino` to `@skytwin/core`. `createLogger(name)` factory. JSON output with timestamp, level, service, request ID. Replace all console calls. Human-readable in dev via `pino-pretty`. Desktop app logs to `~/Library/Logs/SkyTwin/`.
Acceptance Criteria
User sets quiet hours 22:00–07:00 → action at 23:00 with `outcome: 'auto-execute'` → policy evaluator changes outcome to `'request-approval'` with reason containing "Quiet hours"
User sets quiet hours 22:00–07:00 → action at 06:59 → escalated to approval (midnight wrap-around works)
User sets quiet hours 22:00–07:00 → action at 07:01 → auto-executes normally (boundary correct)
User sets quiet hours 22:00–07:00 → spend limit breach at 23:00 → notification still fires (urgent escalations bypass quiet hours)
User with no quiet hours configured → no change in behavior (null-safe)
`POST /api/policies/:userId` with valid policy → returns 201 → `GET /api/policies/:userId` includes new policy
`PUT /api/policies/:userId/:policyId` with updated conditions → returns 200 → policy enforced on next decision
`DELETE /api/policies/:userId/:policyId` → returns 204 → policy no longer returned by GET → no longer enforced
`POST /api/policies/:userId` with missing required field `name` → returns 400 with field-level error
Created policy with `actionType: 'email-send'` and `conditions: { requireApproval: true }` → next email-send action requires approval regardless of trust tier
During implementation, maintain two sources of truth to survive context compaction:
Local context file: Write progress, decisions, and blockers to .context/issue-14-engine-gaps.md (gitignored). Update this file after each meaningful step. On compaction, re-read this file to restore state.
Context
Four medium-priority gaps remain in the engine layer. Individually small, they collectively affect daily usability and code quality. Bundled here because each is 2-4 hours and they share no dependencies.
Claude Code estimate: ~1-2h
Current State (verified 2026-04-04)
Quiet hours
Policy CRUD
Type safety
Structured logging
Proposed Change
1. Quiet hours enforcement
Add check in `PolicyEvaluator.evaluate()`: if current time is within quiet hours and outcome is auto-execute, escalate to approval with reason "Quiet hours active." Handle midnight wrap-around (22:00 → 07:00). Urgent escalations (safety, spend limit) still fire.
2. Policy CRUD API
GET/POST/PUT/DELETE at `/api/policies/:userId`. Settings page: "Advanced → Custom Policies" section. Not the primary flow.
3. Type safety cleanup
Create proper adapters in `ask.ts`, remove all `as never` casts. Grep entire codebase to verify zero remain.
4. Structured logging
Add `pino` to `@skytwin/core`. `createLogger(name)` factory. JSON output with timestamp, level, service, request ID. Replace all console calls. Human-readable in dev via `pino-pretty`. Desktop app logs to `~/Library/Logs/SkyTwin/`.
Acceptance Criteria
Testing Plan
Effort Estimate
Total: ~1-2h Claude Code time
Files Reference
Out of Scope
Related
Working Context Protocol
During implementation, maintain two sources of truth to survive context compaction:
.context/issue-14-engine-gaps.md(gitignored). Update this file after each meaningful step. On compaction, re-read this file to restore state.This ensures no quality loss across compaction events — the local file has granular state, the GitHub issue has durable history.