Skip to content

[codex] add AI Team OS cockpit panel#665

Open
smithpeter wants to merge 1 commit into
builderz-labs:mainfrom
smithpeter:codex/ai-team-os-panel
Open

[codex] add AI Team OS cockpit panel#665
smithpeter wants to merge 1 commit into
builderz-labs:mainfrom
smithpeter:codex/ai-team-os-panel

Conversation

@smithpeter
Copy link
Copy Markdown

Summary

Adds a Mission Control AI Team OS cockpit surface backed by the VoxSign AI Team OS state and reports.

What Changed

  • Added viewer-protected /api/ai-team-os endpoint.
  • Added AiTeamOsPanel with health, excellence, budget, CI/PR backlog, and eval coverage cards.
  • Added AI Team OS to the Observe navigation group.
  • Routed the ai-team-os panel in the main content router.

Validation

  • pnpm typecheck
  • pnpm exec eslint src/app/api/ai-team-os/route.ts src/components/panels/ai-team-os-panel.tsx src/app/[[...panel]]/page.tsx src/components/layout/nav-rail.tsx
  • pnpm build
  • systemctl --user restart mission-control.service
  • curl http://127.0.0.1:3000/api/status?action=health returned healthy
  • unauthenticated /api/ai-team-os returned 401 as expected

Notes

This PR is opened from the smithpeter fork because the current token has pull-only access to builderz-labs/mission-control. It intentionally excludes unrelated local changes in src/app/api/status/route.ts and src/app/login/page.tsx.

@smithpeter smithpeter marked this pull request as ready for review May 8, 2026 14:11
@smithpeter smithpeter requested a review from 0xNyk as a code owner May 8, 2026 14:11
@liberathio
Copy link
Copy Markdown

Review (community / read-only) — Verdict: NEEDS-CHANGES ⚠️

Nice additive panel — clean structure, correct auth via requireRole(request, 'viewer'), no DB writes, no new dependencies. Three HIGH findings before merge:

HIGH

1. Path traversal risk: readJson / readText use bare path.join without an escape guard

File: src/app/api/ai-team-os/route.ts:9-23

Both helpers do path.join(VOXSIGN_ROOT, relativePath). All current callers pass hardcoded literals (no immediate exploit), but the pattern is unsafe: any future caller wiring user input into relativePath enables traversal outside VOXSIGN_ROOT. The repo already has src/lib/paths.ts::resolveWithin() for exactly this case (see how agents/[id]/files/route.ts uses it with an explicit allowlist).

Fix:

// BAD
const content = await readFile(path.join(VOXSIGN_ROOT, relativePath), 'utf8')

// GOOD
import { resolveWithin } from '@/lib/paths'
const content = await readFile(resolveWithin(VOXSIGN_ROOT, relativePath), 'utf8')

2. VOXSIGN_ROOT leaks into the API response

File: src/app/api/ai-team-os/route.ts:62

The response includes root: VOXSIGN_ROOT, exposing the server-side absolute path (default /home/ubuntu/projects/voxsign) to every authenticated browser. The panel's AiTeamOsPayload type doesn't even declare root — the frontend ignores it. This is server internals disclosure for zero gain.

Fix: remove root from the NextResponse.json({...}) payload.

3. Hardcoded VoxSign project identity in a generic open-source dashboard

File: src/components/panels/ai-team-os-panel.tsx:208, src/app/api/ai-team-os/route.ts (default VOXSIGN_ROOT)

The description says "Customer-oriented operating scorecard for the VoxSign AI team." and the route's VOXSIGN_ROOT defaults to /home/ubuntu/projects/voxsign. Both bake one external project's identity into what's being merged to the general-purpose Mission Control dashboard.

Fix: make the title/description configurable (env or panel prop), and default VOXSIGN_ROOT to '' (forcing explicit env var) instead of a path that only exists on the contributor's machine.

MEDIUM

  • catch (err: any) in ai-team-os-panel.tsx:176 — replace with catch (err) + err instanceof Error ? err.message : '...'.
  • No stale-data-with-error state: when polling fails after a successful first load, the error is set but data stays rendered with no visual indication. Compare to system-monitor-panel.

LOW

  • Nav rail entry reuses <MonitorIcon /> from the existing monitor entry directly above — visually identical, likely an oversight. Use a distinct emoji/text per the project convention.

Summary

Severity Count
HIGH 3
MEDIUM 2
LOW 1

Auth, DB safety, and dependency surface are all clean. The two non-negotiable fixes are #1 (resolveWithin) and #2 (drop root from response). #3 is about whether this is the right level of generalization for merging into the OSS dashboard.

(Reviewer is read-only on this repo — flagging for a maintainer.)

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.

2 participants