v3.0.0 — Agentic System Enhancement · Settings UX Repairs · System-Employee Top-Up
Major release in two halves: a four-fix sweep across Settings + system bootstrap that
restores user-visible features Rocky filed as broken (copilot.ask error for pre-M33
companies, dead proactive-mode toggle, missing Skill / MCP install entry points,
no way to delete old backups), and a three-track agentic-system enhancement that
replaces three load-bearing stubs with their real implementations (Enhanced AI's
LLM provider, workload-aware delegation signals, the /promote natural-language
command). The composition root for the main process now wires every authored
service that was sitting on the shelf — verified by a comprehensive
authored-vs-wired audit across 119 service files and ~290 IPC channels.
Tests 2051/2053 passing (every targeted suite green; the two pre-existing
failures are a keytar native-ABI mismatch and a release-marker drift now
resolved by this bump). Typecheck clean across all four tsconfig projects.
Added
- Authority Snapshot install entry points
(apps/desktop/src/renderer/src/features/settings/extensions-section.tsx).
Two new buttons —Add SkillandAdd MCP— surface in the card header.
Each opens the existingInstallSkillDialog/ImportMcpDialog, both of
which had shipped fully-working but were not exposed from the new Settings
page (the previous shell had a banner explaining marketplace installs were
removed "until the replacement flow can be engineered without risking the
whole page" — this is that replacement). CLI extensions deferred pending
the agentic system design pass;EXTENSION_KINDSremains['skill', 'mcp'].
Test guard flipped fromnot.toContain('InstallSkillDialog')to
toContainwith the right wiring shape (extensions-section.test.tsx:89-115). - Backup delete IPC + UX
(apps/desktop/src/main/services/backup.ts,
packages/shared-types/src/ipc.ts,
apps/desktop/src/main/ipc/handlers.ts,
apps/desktop/src/main/ipc/register.ts,
apps/desktop/src/preload/api.ts,
apps/desktop/src/renderer/src/hooks/use-backup.ts,
apps/desktop/src/renderer/src/features/settings/backup-section.tsx).
Full-stack add: servicedelete(backupPath)method with a path-traversal
safety guard (path.relativefrombackupsDirrejects..traversal,
absolute paths on different drives, the jail itself, and empty strings),
BackupDeleteRequest/BackupDeleteResponseshared types,backup.delete
channel registered alongsidebackup.create/backup.restore/backup.list,
preload method,useDeleteBackuphook with['backups']cache invalidation,
and aTrash2icon button per row in the BackupSection with a confirm
flow that's mutually exclusive with the existing Restore confirm. Six new
unit tests cover the happy path, idempotent missing-path delete, four
traversal-guard cases (backup.test.ts:188-243). - Boot-time system-employee top-up
(apps/desktop/src/main/index.ts:1437-1470).
The per-company boot loop now idempotently runsensureSystemAgent+
ensureSystemCopilotfor every live company. Pre-M33 companies — created
via M31 paths beforeensureSystemCopilotlanded — now get their missing
system-copilotrow on first boot after the upgrade. Without this top-up,
copilot.askthrew[copilot-service] No system-copilot employee for company "<id>". Did ensureSystemCopilot run on company creation?for any
company that predated M33. Errors per-company are logged + swallowed so a
single broken company can't block boot for the rest. New regression test
system-agent-bootstrap.test.tssimulates the pre-M33 state (agent row
exists, copilot row missing) and asserts the agent row stays untouched
while the copilot row gets created.
Changed
- Enhanced AI now uses the real LLM provider
(apps/desktop/src/main/index.ts:1189-1248).
The M32 placeholderllmCompletethat returned the literal string
(LLM response not configured)regardless of input is gone. Replaced with
an adapter that resolves the first live company'ssystem-agent, threads
it through the sameresolveProviderclosure the agentic loop and copilot
analyzer use (test-mode → canned; production → runtime profile + secrets),
and accumulatesstreamAgentdeltas into a single text blob — same shape
theWriteSideCompleteFnadapter uses at line ~1862. All 7enhancedAi.*
IPC channels (enhancedAi.stats,enhancedAi.query,
enhancedAi.indexWithSemanticChunking,enhancedAi.extractAndStoreFacts,
enhancedAi.queryKnowledge,enhancedAi.createPlan,enhancedAi.getStats)
now return real LLM output when the user has configured a provider. Test-mode
and unconfigured-mode paths unchanged (still gated by
llmEnabled && ragService !== null). - Workload-aware delegation has real signals
(apps/desktop/src/main/index.ts:1810-1859).
WriteSideWorkloadProvider.inMeeting(employeeId)now reads the active
meeting viameetingsRepo.getActive(companyId), parsesattendeesJson,
and tests membership — replacing the() => falsestub that always told
the planner every employee was available.
avgCompletionMs(employeeId, _subtaskType)aggregatesclosedAt - createdAt
across all closed tickets the candidate was the assignee on (clamped against
the 48-hourpastPerformanceCeilingMsdefault). Returnsnullfor new
hires so they're not penalized (preserves the planner's neutral 0.5
default). Subtask-type filtering is forward-compat: parameter accepted,
ignored in V1 — ticket labels do not yet carry a subtask-type taxonomy.
Both implementations wrap intry/catch→ conservative defaults
(false/null) on repo errors. Result:decompose_projectand
delegate_subtasktools score candidates with real load + history instead
of always-available + no-history. /promoteworks in the command palette
(apps/desktop/src/main/index.ts:2329-2342,
apps/desktop/src/main/services/command-service.ts).
The CommandService dispatcher'semployeesPromoteslot was unwired despite
the IPC handler shipping in M-C step d (employees.promoteregistered at
register.ts:687, exercised byemployees-promote-handlers.test.ts).
Result: typingpromote Alice to CTOin the palette returned
handler_error. Now wired with a shape adapter — classifier emits
{employeeId, roleId, newLevel}, IPC takes{employeeId, newRoleId},
newLevelis discarded because the IPC handler derives the level from
the role spec (single source of truth, no divergence risk).- Release-marker freeze pinned to 3.0.0
(apps/desktop/src/renderer/src/app/top-bar.test.tsx:44-47).
APP_RELEASE_VERSION,PACKAGE_RELEASE_VERSION,SHARED_TYPES_RELEASE_VERSION,
INTELLIGENCE_RELEASE_VERSIONall unified at3.0.0. Resolves the v2.0.10-era
drift whereAPP_RELEASE_VERSIONwas still'2.0.9'after the workspace
shipped at2.0.10.
Fixed
- Proactive mode toggle no longer snap-backs
(apps/desktop/src/main/index.ts:1994-2078).
ProactiveTriggerServicewas authored at
apps/desktop/src/main/services/proactive-trigger-service.ts, referenced
by 4 IPC handlers (proactive.setEnabled,proactive.decomposeGoal,
proactive.scanForWork,proactive.getState), and never instantiated
in the composition root. Everyproactive.*IPC fell through to
throw new Error('[ipc] proactive.<method>: proactiveTriggerService dep is required'). The renderer's optimistic Switch caught the throw and
reverted to OFF on every flip. Fix:createProactiveTriggerService(...)
is now instantiated right aftercreateAgenticLoopService, and the IPC
handler deps include a lazy-resolver wrapper (matches the existing
copilotAnalyzerServicepattern at line 1364) so the trigger service
can come online aftercreateIpcHandlersis composed. The wrapper closes
over a module-levelproactiveTriggerServiceInstance: ProactiveTriggerService | null
declared next toagenticLoopServiceInstance.
Audited (no changes)
- Authored-vs-wired audit across 119 service files in
apps/desktop/src/main/services/, ~290 IPC channels in
register.tsREQUEST_CHANNELS /handlers.tsIpcHandlers /shared-types
ChannelMap, and 20+ optional handler deps. Confirmed the
ProactiveTriggerServicegap was the only fully-unwired service.
Other findings (workload-signal stubs, Enhanced AI LLM stub, missing
/promotedispatcher entry) are addressed by this release; remaining
intentional deferments (classifiercompletestub atindex.ts:1467,
thecompanies.archiveclear hookup forcopilotEventWindow.clear—
which IS wired despite a stale comment at line 1227) are documented and
unchanged. No drift in registry consistency: every channel in
REQUEST_CHANNELS has a matchingipcMain.handleregistration; every
IpcHandlersmethod has a matching channel; every ChannelMap entry has
a backing handler.