Summary
The Pulse Assistant dashboard tab is fully built on the frontend but has no backend of any kind in the shipped release. pulse.ts dynamically imports a module that does not exist anywhere in the repo, the import throws, the error is swallowed, and every /assistant/* request the tab makes goes unhandled. The result is a dead tab whenever da.enabled is true.
Investigating the cause surfaced a second, related problem: a naming drift between the design doc and the shipped frontend that should be reconciled before the backend is built.
Root cause
PULSE/pulse.ts wires an assistant module that was never shipped:
pulse.ts:127 — assistantModule = await import("./Assistant/module") (file does not exist; the catch logs "Assistant module not available" and continues)
pulse.ts:356 — assistantModule.assistantHealth()
pulse.ts:476 — assistantModule.startAssistant(config.da, config.jobs)
pulse.ts:548-549 — routes pathname.startsWith("/assistant/") to assistantModule.handleAssistantRequest(...)
Because the import silently fails, assistantModule stays null and none of the routes below are ever registered.
Meanwhile the frontend (PULSE/Observability/src/app/assistant/page.tsx) is complete and actively polls these endpoints:
GET /assistant/identity (page.tsx:218)
GET /assistant/health (page.tsx:219)
GET /assistant/personality (page.tsx:220)
GET /assistant/tasks (page.tsx:221)
GET /assistant/diary (page.tsx:222)
GET /assistant/opinions (page.tsx:223)
GET /assistant/cron, POST /assistant/cron (page.tsx:229, 306)
PATCH/DELETE /assistant/cron/{name} (page.tsx:235, 244, 264)
PATCH /assistant/personality/traits (page.tsx:318)
All of these currently resolve to nothing.
Naming drift: /da/* vs /assistant/*
The DA Subsystem design doc (https://docs.ourlifeos.ai/Pulse__DaSubsystem, "Status: Architecture complete, pending implementation") specifies a different integration surface than the one the frontend was built against:
|
Design doc (DaSubsystem) |
Shipped frontend + pulse.ts |
| Module |
modules/da.ts |
Assistant/module.ts |
| Routes |
/da/health, /da/identity, /da/schedule, /da/diary, /da/opinions |
/assistant/health, /assistant/identity, /assistant/personality, /assistant/tasks, /assistant/diary, /assistant/opinions, /assistant/cron* |
Neither modules/da.ts nor any /da/* route exists in the repo either. It looks like the concept was renamed DA → Assistant and the frontend + pulse.ts wiring were rebuilt under the new name, but (a) the backend was never shipped under either name, and (b) the design doc was never updated to match the rename. Whoever implements the backend should reconcile these two so the doc, the routes, and the module name agree.
Scope the design doc implies
Per DaSubsystem, a real backend covers: Identity Registry, Interview wizard (DAInterview.ts), Heartbeat module (30-min proactive eval), Scheduled Task Manager (scheduled-tasks.jsonl), and Growth Engine (daily diary, opinions.yaml with confidence scoring, bounded identity evolution). That is a substantial feature, not a patch.
Interim mitigation (separate PR)
I have a PR that adds a PULSE/Assistant/module.ts stub so the failure is deliberate rather than an accident of a caught import error: health returns identity_loaded: false (so the frontend's existing EmptyStateGuide/isFreshInstall path is deterministic), read endpoints return correctly-typed empty JSON, and mutating endpoints return 501 with a clear message instead of silently no-op'ing when a user clicks Save/Delete. It does not implement persistence. Happy to link it to this issue.
Suggested resolution
- Decide the canonical name (
Assistant vs DA) and align the doc, routes, and module.
- Implement the backend module against that name, following the DaSubsystem design.
- Land the interim stub first so the tab degrades honestly until then.
Found during a fresh v6.0.0 install.
Summary
The Pulse Assistant dashboard tab is fully built on the frontend but has no backend of any kind in the shipped release.
pulse.tsdynamically imports a module that does not exist anywhere in the repo, the import throws, the error is swallowed, and every/assistant/*request the tab makes goes unhandled. The result is a dead tab wheneverda.enabledis true.Investigating the cause surfaced a second, related problem: a naming drift between the design doc and the shipped frontend that should be reconciled before the backend is built.
Root cause
PULSE/pulse.tswires an assistant module that was never shipped:pulse.ts:127—assistantModule = await import("./Assistant/module")(file does not exist; thecatchlogs"Assistant module not available"and continues)pulse.ts:356—assistantModule.assistantHealth()pulse.ts:476—assistantModule.startAssistant(config.da, config.jobs)pulse.ts:548-549— routespathname.startsWith("/assistant/")toassistantModule.handleAssistantRequest(...)Because the import silently fails,
assistantModulestaysnulland none of the routes below are ever registered.Meanwhile the frontend (
PULSE/Observability/src/app/assistant/page.tsx) is complete and actively polls these endpoints:GET /assistant/identity(page.tsx:218)GET /assistant/health(page.tsx:219)GET /assistant/personality(page.tsx:220)GET /assistant/tasks(page.tsx:221)GET /assistant/diary(page.tsx:222)GET /assistant/opinions(page.tsx:223)GET /assistant/cron,POST /assistant/cron(page.tsx:229, 306)PATCH/DELETE /assistant/cron/{name}(page.tsx:235, 244, 264)PATCH /assistant/personality/traits(page.tsx:318)All of these currently resolve to nothing.
Naming drift:
/da/*vs/assistant/*The DA Subsystem design doc (https://docs.ourlifeos.ai/Pulse__DaSubsystem, "Status: Architecture complete, pending implementation") specifies a different integration surface than the one the frontend was built against:
modules/da.tsAssistant/module.ts/da/health,/da/identity,/da/schedule,/da/diary,/da/opinions/assistant/health,/assistant/identity,/assistant/personality,/assistant/tasks,/assistant/diary,/assistant/opinions,/assistant/cron*Neither
modules/da.tsnor any/da/*route exists in the repo either. It looks like the concept was renamed DA → Assistant and the frontend +pulse.tswiring were rebuilt under the new name, but (a) the backend was never shipped under either name, and (b) the design doc was never updated to match the rename. Whoever implements the backend should reconcile these two so the doc, the routes, and the module name agree.Scope the design doc implies
Per DaSubsystem, a real backend covers: Identity Registry, Interview wizard (
DAInterview.ts), Heartbeat module (30-min proactive eval), Scheduled Task Manager (scheduled-tasks.jsonl), and Growth Engine (daily diary,opinions.yamlwith confidence scoring, bounded identity evolution). That is a substantial feature, not a patch.Interim mitigation (separate PR)
I have a PR that adds a
PULSE/Assistant/module.tsstub so the failure is deliberate rather than an accident of a caught import error: health returnsidentity_loaded: false(so the frontend's existingEmptyStateGuide/isFreshInstallpath is deterministic), read endpoints return correctly-typed empty JSON, and mutating endpoints return501with a clear message instead of silently no-op'ing when a user clicks Save/Delete. It does not implement persistence. Happy to link it to this issue.Suggested resolution
AssistantvsDA) and align the doc, routes, and module.Found during a fresh v6.0.0 install.