Skip to content

fix(task-board): fix orphan detection and add session linking#419

Open
dimakis wants to merge 5 commits into
mainfrom
session/2026-06-27-87cad9e05f06
Open

fix(task-board): fix orphan detection and add session linking#419
dimakis wants to merge 5 commits into
mainfrom
session/2026-06-27-87cad9e05f06

Conversation

@dimakis

@dimakis dimakis commented Jun 28, 2026

Copy link
Copy Markdown
Owner

Summary

  • Fix orphan detection: getActiveSessionIds() was returning SDK session IDs but task sessionId stores client IDs — comparison never matched, so dead tasks stayed "running" forever. Now returns client IDs.
  • Clickable session hash: Running tasks show a tappable session hash that navigates to the session's chat view. Uses the resolved SDK session ID (enriched on broadcast).
  • Source link in session banner: Sessions spawned from Telos items or Task Board goals show a tappable link ("Task Board" / "Telos") in the session banner header.

Test plan

  • Task orchestrator orphan detection tests pass (46/46)
  • SessionBanner tests pass with router context (9/9)
  • TypeScript type check clean on all changed files
  • Manual: start a Task Board goal, verify running tasks show clickable session hash
  • Manual: verify dead tasks get reclaimed (kill a headless session, wait for tick)
  • Manual: verify Telos-spawned session shows "Telos" link in banner

🤖 Generated with Claude Code

dimakis and others added 4 commits June 28, 2026 00:40
Read the existing token from ~/.mitzo/internal-token on startup instead
of generating a new one every time. Only generates a fresh token when
the file is missing or corrupt. Fixes 401 errors for agents and hooks
after every Mitzo restart.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Address Centaur review: 7 tests covering read existing, reject
corrupt, regenerate on missing, trim whitespace, consistency.
Also accept uppercase hex tokens in validation regex.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Address second Centaur review: extract function with configurable
path, test the real implementation instead of a copy, add write
failure test, use path.dirname instead of string splitting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Orphan detection compared task clientIds against SDK sessionIds, so dead
tasks were never reclaimed. Now getActiveSessionIds() returns clientIds
to match. Running tasks show a clickable session hash that navigates to
the chat. Sessions spawned from Telos items or Task Board goals display
a tappable source link in the session banner.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@dimakis

dimakis commented Jun 28, 2026

Copy link
Copy Markdown
Owner Author

Centaur Review

Found 6 issue(s) (1 critical) (3 warning).

frontend/src/components/__tests__/TaskNode.test.tsx

The orphan detection fix is correct — aligns getActiveSessionIds with the clientId keys stored in tasks. However, TaskNode tests are broken (missing Router wrapper + missing sdkSessionId in mock), and the enrichment logic is duplicated between app.ts and index.ts.

  • 🔴 regressions: TaskNode now calls useNavigate() (line 4 of TaskNode.tsx), but the existing tests render <TaskNode> without a Router context. Every test in this file will crash with "useNavigate() may be used only in the context of a component." Needs a MemoryRouter wrapper like SessionBanner tests got. [fixable]
  • 🟡 regressions (L11): makeTask() helper is missing the new required sdkSessionId: string | null field added to the Task type (frontend/src/types/task.ts:30). This will cause a TypeScript compile error in the test file. Add sdkSessionId: null to the default object. [fixable]

server/index.ts

The orphan detection fix is correct — aligns getActiveSessionIds with the clientId keys stored in tasks. However, TaskNode tests are broken (missing Router wrapper + missing sdkSessionId in mock), and the enrichment logic is duplicated between app.ts and index.ts.

  • 🟡 style (L226): The enrichWithSdkSessionId lambda duplicates the enrichTasksWithSdkSessionId function already defined in server/app.ts:628. Both do the same recursive tree walk with registry.get(t.sessionId)?.sessionId. Extract to a shared helper to avoid the logic drifting apart. [fixable]

frontend/src/components/__tests__/SessionBanner.test.tsx

The orphan detection fix is correct — aligns getActiveSessionIds with the clientId keys stored in tasks. However, TaskNode tests are broken (missing Router wrapper + missing sdkSessionId in mock), and the enrichment logic is duplicated between app.ts and index.ts.

  • 🟡 missing_tests: SessionBanner tests were updated with MemoryRouter wrapping but no test exercises the new sourceLink prop — rendering the link label, click navigation to /tasks or /todos, the hasTelos vs hasGoal priority logic, or the edge case where telosTaskId === goalId (which suppresses the Telos link). [fixable]

frontend/src/components/TaskNode.tsx

The orphan detection fix is correct — aligns getActiveSessionIds with the clientId keys stored in tasks. However, TaskNode tests are broken (missing Router wrapper + missing sdkSessionId in mock), and the enrichment logic is duplicated between app.ts and index.ts.

  • 🔵 missing_tests (L72): The new ActiveContextLine component with clickable session navigation has no test coverage — the click handler, the fallback to plain text when sdkSessionId is missing, and keyboard navigation are all untested. [fixable]

server/app.ts

The orphan detection fix is correct — aligns getActiveSessionIds with the clientId keys stored in tasks. However, TaskNode tests are broken (missing Router wrapper + missing sdkSessionId in mock), and the enrichment logic is duplicated between app.ts and index.ts.

  • 🔵 missing_tests (L628): The enrichTasksWithSdkSessionId helper has no unit test. A test verifying the recursive enrichment (nested children) and the null-session fallback would protect against future regressions in the tree walk. [fixable]

TaskNode now uses useNavigate(), requiring Router context in tests.
Client Task type also needed sdkSessionId field to match server.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@dimakis

dimakis commented Jun 28, 2026

Copy link
Copy Markdown
Owner Author

Centaur Review

Found 6 issue(s) (2 warning).

server/app.ts

The orphan detection fix (clientId vs SDK sessionId) is correct and important. The internal-token refactoring is solid. Main concern: task broadcasts from REST mutations aren't enriched with sdkSessionId, causing inconsistent frontend data. Enrichment logic is also duplicated across app.ts and index.ts. New reducer action and UI components lack test coverage.

  • 🟡 bugs (L649): onTaskBroadcast calls throughout app.ts (lines 649, 964, 1001, 1068, 1953) pass raw taskStore.getTree() without enriching with sdkSessionId. Only GET /api/tasks and the orchestrator's broadcastTasks enrich. REST-mutation-triggered broadcasts will send tasks without sdkSessionId, causing the frontend to intermittently lose session links depending on how the data arrived (poll vs. push). [fixable]
  • 🔵 missing_tests (L632): No test coverage for enrichTasksWithSdkSessionId — specifically that it recursively enriches children and correctly maps registry.get(t.sessionId)?.sessionId to sdkSessionId. [fixable]

server/index.ts

The orphan detection fix (clientId vs SDK sessionId) is correct and important. The internal-token refactoring is solid. Main concern: task broadcasts from REST mutations aren't enriched with sdkSessionId, causing inconsistent frontend data. Enrichment logic is also duplicated across app.ts and index.ts. New reducer action and UI components lack test coverage.

  • 🔵 style (L226): The enrichWithSdkSessionId inline arrow function duplicates the named enrichTasksWithSdkSessionId in app.ts. Extract to a shared function (e.g. in app.ts, already exported) to avoid drift between the two implementations. [fixable]

packages/client/src/slices/messages.ts

The orphan detection fix (clientId vs SDK sessionId) is correct and important. The internal-token refactoring is solid. Main concern: task broadcasts from REST mutations aren't enriched with sdkSessionId, causing inconsistent frontend data. Enrichment logic is also duplicated across app.ts and index.ts. New reducer action and UI components lack test coverage.

  • 🟡 missing_tests (L465): The new SET_SOURCE_LINK reducer action has no test coverage. The existing messages-slice.test.ts comprehensively tests all other actions — this new one should have tests for: setting sourceLink when both telosTaskId and goalId are present, setting when only one is present, and clearing when neither is present. [fixable]

frontend/src/components/__tests__/SessionBanner.test.tsx

The orphan detection fix (clientId vs SDK sessionId) is correct and important. The internal-token refactoring is solid. Main concern: task broadcasts from REST mutations aren't enriched with sdkSessionId, causing inconsistent frontend data. Enrichment logic is also duplicated across app.ts and index.ts. New reducer action and UI components lack test coverage.

  • 🔵 missing_tests: SessionBanner tests were updated to add MemoryRouter but no test verifies the new sourceLink prop: that the link renders with the correct label ('Task Board' vs 'Telos'), that clicking it navigates to the expected route, and that it doesn't render when sourceLink is null. [fixable]

frontend/src/components/__tests__/TaskNode.test.tsx

The orphan detection fix (clientId vs SDK sessionId) is correct and important. The internal-token refactoring is solid. Main concern: task broadcasts from REST mutations aren't enriched with sdkSessionId, causing inconsistent frontend data. Enrichment logic is also duplicated across app.ts and index.ts. New reducer action and UI components lack test coverage.

  • 🔵 missing_tests: TaskNode tests were updated for MemoryRouter but no test covers the new ActiveContextLine component: that the session hash renders as a clickable link when sdkSessionId is present, that clicking navigates to /chat/<sdkSessionId>, and that it falls back to plain text when sdkSessionId is absent. [fixable]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant