# Release v0.11.17 - Changelog

Released: 2026-02-07

## Overview

This release focuses on security improvements, bug fixes for the AI runner system, and enhanced AI provider model management.

## 🎉 Features

### Universal Model Refresh for AI Providers
- **Model Refresh Button**: Added "Refresh Models" button to AI providers on the `/devtools/providers` page
- **Multi-Provider Support**: Refresh now works for both API and CLI providers including:
  - API providers: OpenAI, LM Studio, Ollama (with provider-specific endpoint detection)
  - CLI providers: Claude/Anthropic (returns latest model list)
- **Smart UI**: Button is hidden for providers that don't require model specification (e.g., Gemini CLI)
- **User Feedback**: Toast notifications show success/failure messages with descriptive error handling
- **Loading States**: Button shows "Refreshing..." state during model fetch operations
- **Graceful Degradation**: Providers without refresh support show appropriate error messages

**Implementation Details**:
- Updated `portos-ai-toolkit` to support provider-specific refresh strategies
- Added `_refreshAPIProviderModels()` for API-based providers with multi-format support
- Added `_refreshCLIProviderModels()` with provider detection and API integration
- Client shows refresh button for all providers (previously API-only)
- Enhanced error handling with user-friendly toast notifications

**Files Modified**:
- `portos-ai-toolkit/src/server/providers.js` - Universal refresh implementation
- `client/src/pages/AIProviders.jsx` - UI updates with toast notifications

### Digital Twin Interview & Enrichment Guide
- Redesigned "Interview" tab as a single-page assessment analyzer + enrichment guide
- Paste AI personality assessments for automated analysis and twin profile updates
- Enrichment gap dashboard shows which areas need the most attention
- Direct navigation from gaps to specific enrichment categories
- Automatically maps traits to Big Five, values, and communication dimensions
- Creates new documents for personality dimensions not yet captured
- Removed session-based chat interface in favor of simpler paste-and-analyze flow

### Digital Twin Enrichment UX Improvements
- **Deep-link Enrich buttons**: All "Enrich" buttons on gap cards and completeness missing sections now navigate directly to the specific enrichment category (e.g., `/digital-twin/enrich?category=values`) instead of the generic landing page
- **"Start Enrichment Session" targets top gap**: The main CTA button uses the most critical gap's category for immediate action
- **"Enrich Soul" quick action uses top gap**: The overview quick action card navigates to the highest-priority gap's category when available
- **Next Action Banner on Overview**: New contextual banner at the top of the overview tab with three modes:
  - **No profile yet**: Suggests pasting a personality assessment via the Interview tab
  - **Gaps exist (Q&A)**: Shows an inline question from the top gap's category with submit/skip, Ctrl+Enter shortcut, and link to full enrichment
  - **Gaps exist (list-based)**: Shows a navigate prompt for list categories (books, movies, music)
  - **All caught up**: Confirms the twin is well-defined and links to behavioral tests

### Likert-Scale Trait Scoring for Digital Twin Enrichment
- **Immediate Trait Feedback**: Enrichment now includes 1-5 Likert-scale questions that directly update trait scores and confidence when answered, closing the loop between enrichment answers and personality modeling
- **18 Scale Questions**: Covers Big Five (10 items), communication style (2), daily routines (2), values (2), and decision heuristics (2) — each mapped to a specific trait dimension
- **Weighted Moving Average**: Scale answers blend with existing scores using a 0.3 weight factor, preventing any single answer from dominating while still moving the needle
- **Confidence Boost**: Each scale answer adds +0.15 to the relevant dimension's confidence score, so 3-4 answers can cross the 0.6 gap threshold and remove that dimension from recommendations
- **Inline Scale UI**: New `ScaleInput` component renders 5 touch-friendly buttons with labels, working in both the full EnrichTab and the NextActionBanner's quick-enrich mode
- **Backward Compatible**: `questionType` defaults to `text`, existing text question flow is completely unchanged, old client submissions still work

## 🐛 Bug Fixes

### CLI Runner Security & Reliability
- **Security Warning Fix**: Resolved Node.js DEP0190 deprecation warning in CLI runner by removing unsafe `shell: true` option from child process spawning
- **Improved Argument Handling**: CLI commands now use direct argument passing instead of shell interpretation, preventing potential security vulnerabilities from unescaped arguments
- **Enhanced Logging**: Added detailed logging for CLI execution showing full command and prompt preview to aid debugging
- **Context**: The `/devtools/runner` page was generating security warnings when executing Claude CLI commands. The fix removes shell interpretation which was unnecessary and insecure, while maintaining full functionality

**Technical Details**:
- Created override in `server/services/runner.js` for `executeCliRun()` function
- Removed `shell: true` option from `spawn()` call (recommended by Node.js security guidelines)
- Arguments are now properly passed as array without shell metacharacter interpretation
- Added runtime patching in `server/index.js` to inject fixed implementation into AI toolkit

**Files Modified**:
- `server/services/runner.js` - New secure CLI execution implementation
- `server/index.js` - Runtime patching to override toolkit's runner

### Brain Inbox Classification Hang on Capture
- **Background Classification**: Brain inbox thought capture now returns immediately instead of blocking the UI while waiting for AI classification
- **Real-time Updates**: Classification results are pushed to the client via Socket.IO events (`brain:classified`), with toast notifications showing the result
- **New "Classifying" Status**: Added `classifying` status with animated UI indicator so users can see thoughts being processed in real time
- **No More Hangs**: Previously, submitting a thought would hang the UI spinner indefinitely if the AI provider was slow or unresponsive. Now the thought is saved instantly and classified in the background

**Files Modified**:
- `server/services/brain.js` - Split `captureThought` into immediate return + background `classifyInBackground`
- `server/services/socket.js` - Added brain event forwarding via `setupBrainEventForwarding`
- `server/lib/brainValidation.js` - Added `classifying` to inbox status enum
- `server/services/brainStorage.js` - Added `classifying` to inbox log counts
- `client/src/components/brain/tabs/InboxTab.jsx` - Socket.IO listener for classification results, classifying section UI
- `client/src/components/brain/constants.js` - Added `classifying` status color

### Killed Tasks No Longer Requeue
- **DevTools Kill Integration**: Killing a CoS agent via the DevTools process manager (`DELETE /api/agents/:pid`) now delegates to the CoS `killAgent()` function, which properly blocks the task instead of letting the close handler treat it as a retryable failure
- **Immediate Task Blocking**: Both `terminateAgent()` and `killAgent()` in direct mode now immediately update the task to `blocked` with `user-terminated` category, matching the runner mode behavior. Previously, task blocking was deferred to the close handler, creating a window where server restarts could cause requeue
- **Orphan Handler Guard**: `handleOrphanedTask()` now skips tasks already marked as `user-terminated`, preventing any residual requeue path

### Task Enhancement Empty Result No Longer Throws Error
- **Graceful fallback**: When an AI provider returns an empty response during task prompt enhancement, the server now returns the original description instead of throwing a 500 error
- **Reduced log noise**: Empty enhancement results log a warning instead of surfacing as route errors
- **Client unchanged**: The client already handled enhancement failures gracefully; this fix prevents unnecessary error noise server-side

### AI Providers Status Unreachable on Health Page
- **Route shadowing fix**: The `/api/providers/status` endpoint was being intercepted by the AI toolkit's `GET /:id` route (treating "status" as a provider ID), returning "Provider not found" instead of the actual status data
- **Root cause**: PortOS mounted the toolkit's parameterized routes before its own `/status` route, so Express matched the toolkit's `/:id` first
- **Fix**: Reordered route registration so PortOS-specific routes (including `/status`) are defined before mounting the toolkit's catch-all routes

### Quick Enrich Repeats Already-Answered Questions
- **AI fallback no longer recycles answered questions**: When all predefined and scale questions for a category are exhausted and AI question generation fails, the system now serves a generic follow-up ("What else should your digital twin know about your [category]?") instead of repeating the first predefined question
- **Fallback only asked once**: The generic fallback question is now only served once per category; after being answered, the category signals completion instead of repeating
- **Category exhaustion UI**: EnrichTab now shows a "all questions answered" completion view when a category has no more questions, instead of silently falling back to category selection
- **Deduplicated near-identical questions**: `values` and `non_negotiables` categories previously had nearly identical first questions; `values` now asks a distinct question about top three guiding values

### Quick Enrich Shows "Unable to Load Question" for Exhausted Categories
- **Auto-advance to next gap**: When a category's questions are exhausted (all predefined, scale, and fallback answered) and AI generation isn't available, the NextActionBanner now automatically advances to the next gap category instead of showing "Unable to load question"
- **Graceful exhaustion UI**: If all gap categories are exhausted, the banner shows an "Enrichment questions complete" view with links to run an interview or behavioral tests
- **Stable gap tracking**: Uses category-based dependency tracking instead of array references to prevent unnecessary resets during parent re-renders

### Quick Enrich Skip Returns Same Question
- **Skip now advances to a different question**: Clicking "Skip" on Quick Enrich prompts (both in the overview banner and the full EnrichTab) previously returned the exact same question, because question selection was deterministic based on `questionsAnswered` count which skip didn't increment
- **Client tracks skipped indices**: Both NextActionBanner and EnrichTab now maintain a `skippedIndices` list for the current session, passing it to the server so it can serve the next non-skipped question
- **Works for all question types**: Predefined questions skip by index, scale questions skip by negative-offset convention, and AI-generated questions already vary via temperature

### Digital Twin Personality Trait Confidence Display & Recalculation
- **Low confidence bars now grey instead of red**: Personality trait bars with low confidence (<60%) now display as grey rather than red, avoiding the false impression of errors when data is simply unverified or sparse
- **Confidence recalculates after trait analysis**: Running "Analyze Traits" or processing an AI interview assessment now automatically recalculates confidence scores, so the displayed confidence reflects the latest data instead of remaining stale from a previous manual calculation

### Autofixer App Replaced with PortOS Default
- Replaced the standalone Autofixer app with PortOS default app in sample data to avoid confusion

### Immediate Task Execution for User Tasks
- **Instant Spawn**: User-submitted tasks now start immediately when agent slots are available, instead of waiting up to 60 seconds for the next evaluation interval
- **Slot-Free Dequeue**: When an agent completes and frees a slot, the next pending task is immediately dequeued and spawned without waiting for the evaluation cycle
- **Priority Preserved**: Dequeue on slot free checks user tasks first, then auto-approved system tasks, maintaining the existing priority order
- **Evaluation Interval Preserved**: The periodic evaluation interval continues to handle system task generation, idle reviews, and mission tasks — immediate execution is specifically for dequeuing pending work

### Autonomous Jobs (M37)
- **Recurring Proactive Jobs**: The CoS can now run scheduled recurring jobs on your behalf — maintaining repositories, processing brain ideas, generating daily briefings, and reviewing projects
- **Digital Twin Integration**: Jobs execute using your digital twin identity, so the CoS acts with your preferences and values in mind
- **4 Built-in Jobs**: Ships with Git Repo Maintenance (weekly), Brain Inbox Processing (daily), Daily Briefing (daily), and Brain Project Review (weekly) — all disabled by default for opt-in
- **Jobs Tab UI**: New "Jobs" tab on the `/cos/jobs` page with toggle controls, interval configuration, manual trigger, inline editing, and prompt template visibility
- **Custom Jobs**: Create your own recurring jobs with custom prompt templates, intervals (hourly to monthly), priority levels, and autonomy levels (standby/assistant/manager/yolo)
- **Evaluation Integration**: Due jobs are checked during each CoS evaluation cycle at Priority 3.5 (between missions and idle review), only when no user tasks are pending
- **Full CRUD API**: REST endpoints at `/api/cos/jobs` for listing, creating, updating, toggling, triggering, and deleting jobs

**Files Added**:
- `server/services/autonomousJobs.js` — Job management service with scheduling, execution tracking, and task generation
- `client/src/components/cos/tabs/JobsTab.jsx` — Jobs tab UI component

**Files Modified**:
- `server/services/cos.js` — Added autonomous jobs to evaluation loop (Priority 3.5), added `autonomousJobsEnabled` config
- `server/routes/cos.js` — Added `/api/cos/jobs` REST endpoints
- `client/src/services/api.js` — Added autonomous jobs API functions
- `client/src/components/cos/constants.js` — Added Jobs tab to navigation
- `client/src/components/cos/index.js` — Export JobsTab component
- `client/src/pages/ChiefOfStaff.jsx` — Render Jobs tab

### Completed Agents Search
- **Search bar**: Added a search input to the Completed Agents section on the Agents tab, allowing quick filtering by task description, model, agent ID, or error message
- **Full results when searching**: When a search query is active, all matching agents are shown (bypasses the default 15-item limit) so you can find any completed agent
- **Match count**: Displays "X of Y agents match" when filtering is active

**Files Modified**:
- `client/src/components/cos/tabs/AgentsTab.jsx` — Added search state, filtered list with `useMemo`, search input UI

### Quick Task Templates
- **One-click task creation**: Added a collapsible "Quick Templates" section above the task form with 8 built-in templates for common task patterns (fix mobile, add feature, fix bug, refactor, add tests, improve UX, add API, security fix)
- **Save as template**: New "Save Template" button lets you save the current form as a reusable template for future tasks
- **Usage tracking**: Templates show usage counts and are sorted by popularity so your most-used templates appear first
- **Custom templates**: Create and delete your own templates; built-in templates cannot be deleted
- **Template presets**: Each template populates description, context, and optionally provider/model/app settings

**Files Added**:
- `server/services/taskTemplates.js` — Template management with built-in templates, usage tracking, CRUD operations

**Files Modified**:
- `server/routes/cos.js` — Added `/api/cos/templates` REST endpoints
- `client/src/services/api.js` — Added template API functions
- `client/src/components/cos/tabs/TasksTab.jsx` — Template UI with apply/save/delete functionality

## 🔧 Improvements

### Live Output Streaming for Claude CLI Agents
- **Real-time Feedback**: Claude CLI agents now stream output in real-time as they work, matching the live output experience previously only available with Codex
- **Stream-JSON Parsing**: Uses Claude CLI's `--output-format stream-json --verbose --include-partial-messages` flags to receive incremental text deltas as they're generated
- **Tool Use Visibility**: Shows tool invocations (e.g., "🔧 Using Edit...") in the live output so users can see what the agent is doing
- **Both Spawn Modes**: Works in both direct spawn mode and via the standalone CoS Runner (PM2 process)
- **Clean Output Files**: The final output file contains the clean result text, while the raw JSON stream is preserved for error analysis

### Detailed Agent Tool Activity Display
- **Tool Input Details**: Agent output now shows what each tool is operating on — file paths for Read/Edit/Write, search patterns for Grep/Glob, commands for Bash, queries for WebSearch, and descriptions for Task spawns
- **Input JSON Delta Parsing**: Stream parser now accumulates `input_json_delta` events and emits detailed summaries when `content_block_stop` fires, providing context like `🔧 Using Grep... → "pattern" in …/services/api.js`
- **Rich Live Activity Feed**: Running agent cards show the last few tool actions with details instead of just the tool name, giving immediate insight into what the agent is doing
- **Color-Coded Expanded View**: Expanded agent output now color-codes tool invocations (accent blue), input details (gray), and tool results (dim gray) for easy scanning
- **Scrollable Output**: Expanded output view is now height-limited and scrollable to prevent page layout issues with verbose agents
- **Tool Counter**: Shows total tool invocation count when agents use more than 3 tools

### Memory System Overhaul — User-Centric Knowledge
- **Focus on the user, not the code**: Memory extraction now prioritizes user values, preferences, work patterns, and aesthetic taste — not implementation details an agent can discover by reading files
- **Higher quality bar**: Minimum confidence raised from 0.6 to 0.7; auto-save threshold raised from 0.8 to 0.85. Most task outputs now correctly produce zero memories instead of noisy low-value ones
- **Implementation detail filter**: Both LLM classifier and pattern-based fallback now reject file paths, CSS values, port numbers, architecture descriptions, status assessments, and other trivially-discoverable code facts
- **Removed noise patterns**: Eliminated pattern extractors for "no issues found", "already well-optimized", conclusion sections, and positive assessments — these were generating the bulk of low-value 0% confidence approval requests
- **Key test**: Every candidate memory now passes the question "Would a brand-new agent benefit from knowing this even with full code access?" — if it's about code, reject; if it's about the user, keep

### Orphaned Agent Completion Warnings on Restart
- **Eliminated false "unknown agent" warnings**: On app restart, the runner's orphan cleanup would emit completion events for dead agents, but the server's in-memory tracking map was already cleared — causing noisy `⚠️ Received completion for unknown agent` warnings for every finished agent
- **Graceful state reconciliation**: `handleAgentCompletion()` now checks cos persistent state when an agent isn't in the in-memory map. If already completed by the server's own cleanup, it logs a quiet confirmation instead of a warning. If still marked as running, it properly completes the agent and updates its task.
- **No more duplicate work**: The two parallel orphan cleanup paths (server at 2s, runner at 3s) now cooperate — whichever runs first handles the agent, and the second silently skips it

### Task Progress Bars Use P80 Estimates Instead of Average
- **More accurate progress**: Task progress bars now use a P80 (80th percentile approximation) estimate instead of the simple average duration, preventing progress bars from hitting 100% when only ~50% through a task
- **Variance tracking**: The learning system now tracks `maxDurationMs` per task type and computes `p80DurationMs` (avg + 60% of the gap to max) for more realistic progress estimates
- **ETAs reflect variance**: Running agent ETAs and pending task time estimates are based on the P80 value, giving users a more honest picture of when tasks will complete
- **Learning tab shows both**: The Duration Estimates table now displays both average and estimated (P80) columns so users can see the range
- **Backward compatible**: Existing learning data without max/P80 fields gracefully falls back to using the average

### Browser URL Navigation & Headed Mode
- **Open URL in CDP browser**: Added a URL input bar to the Browser page that opens any URL in a new tab of the managed CDP browser
- **Auto-prefix**: URLs without a protocol are automatically prefixed with `https://`
- **Server endpoint**: New `POST /api/browser/navigate` route with Zod URL validation, using CDP's `/json/new` endpoint to open tabs
- **Conditional visibility**: The URL bar only appears when the browser is connected, keeping the UI clean when the browser is stopped
- **Headed mode support**: Browser now reads the `headless` config setting from `data/browser-config.json` — disable headless to see the browser window and manually authenticate to sites like GitHub
- **Persistent browser profile**: Auth cookies, localStorage, and sessions now persist across restarts via `--user-data-dir` pointing to `data/browser-profile`
- **Config-driven launch**: The browser process reads its configuration from the shared config file on startup instead of hardcoding `headless: true`
- **Live mode display**: Sidebar shows whether the running browser is in headed or headless mode, with a restart hint after config changes
- **Real Chrome instead of Playwright Chromium**: Browser process now spawns system Chrome directly (`/Applications/Google Chrome.app`) instead of Playwright's bundled Chromium, enabling Google sign-in and other auth flows that reject automation browsers
- **Removed Playwright dependency**: Browser process uses `child_process.spawn()` and CDP HTTP endpoints, no longer depends on the playwright npm package

### Architecture Documentation Update
- **Updated system diagram**: Expanded the architecture diagram to include portos-browser and portos-autofixer as PM2-managed satellite services alongside Chief of Staff
- **New data flow sections**: Added Browser Automation Flow and Autofixer Flow documenting how each service communicates with the rest of PortOS
- **Directory structure**: Added `browser/`, `autofixer/`, `data/autofixer/`, and `data/browser-config.json` entries
- **Key services**: Added Browser Service and Autofixer service descriptions
- **PM2 process map**: Expanded with script paths and more descriptive purposes
