Files
podman/codex_team_memory_redisgn.md
2026-06-27 22:39:07 -07:00

14 KiB

Team Memory Graph - Codex Redesign Brief

Read this whole file before touching code. This is a fresh-session handoff for rebuilding PodMan's live Team memory graph UI. The goal is not to tweak labels or add another filter. The goal is to make the real-data light UI as polished, legible, and functional as the original dark Bauhaus mock, while keeping the graph backed by live MongoDB data.

0. Mission

PodMan's Team memory view should make the recursive self-improvement loop visible: who is working, which files overlap, where collisions happen, which intervention was sent, and what PodMan learned from accepted outcomes.

The current light real-data implementation proves the backend can materialize a graph, but the UI does not yet tell the story. It still reads as a static node-link diagram: edges dominate, labels collide, the layout feels fixed, and the important loop observe -> store -> predict -> outcome -> adapt is not visible.

Rebuild the Team memory experience so it has the narrative clarity of the dark Bauhaus mock, in the app's light shadcn/ruixen visual system, with a dynamic graph that animates and responds to live data changes.

1. Current State

Branch context:

  • Work is on feat/live-graph-glue.
  • The live graph backend exists and should be reused.
  • A PR for the live graph glue already exists, and later commits have continued refining readability.
  • The current file requested by the user is this document: codex_team_memory_redisgn.md.

Important existing files:

  • backend/src/graph/live.ts Builds PodGraph from real Mongo collections: pods, engineer_states, observations, collisions, interventions, and outcomes.
  • backend/src/graph/store.ts Loads live graph first, then seeded team_model.graph, then demo fallback.
  • shared/src/graph.ts Defines the graph contract.
  • frontend/src/components/GraphView.tsx Current frontend graph rendering. This is the main file to redesign.
  • frontend/src/lib/graph.ts Fetches the graph.
  • frontend/src/App.tsx and frontend/src/components/PodCard.tsx Open Team memory per pod.

Do not start by rewriting the backend materializer. It already does the most important real-data work: filtering noisy files, collapsing repeated collisions, capping graph size, shortening labels, and pruning test engineers. The redesign is primarily a frontend information-architecture and interaction problem.

2. Reference Screens

Current Light Real-Data UI

The light UI is technically real and connected to live data, but it fails visually.

Observed problems:

  • The graph is too static and column-like.
  • Red collision edges dominate the canvas.
  • Labels overlap and fight for attention.
  • Interventions repeat as a row of identical diamonds.
  • The right panel says "It learned" but does not explain the actual workflow state.
  • The screen lacks an activity stream.
  • The screen lacks the explicit learning-loop rail from the dark mock.
  • The viewer cannot quickly answer:
    • What happened?
    • Who collided?
    • What did PodMan do?
    • Did the team accept it?
    • What changed in memory?

The current light version proves data plumbing. It does not yet work as a demo surface.

Dark Bauhaus Mock

The dark mock is the quality target. Do not copy the dark palette wholesale, but copy the structure, density, and storytelling.

The mock has:

  • A strong title bar: PODMAN / CONTINUAL-LEARNING OBSERVATORY
  • A live status indicator: LIVE - POD demo-pod
  • A left metrics rail: workflow metrics as compact, high-contrast cards.
  • A center graph: sparse, geometric, readable, with one primary path emphasized.
  • A right learning-loop rail: Observe -> Store -> Predict -> Outcome -> Adapt
  • A bottom activity stream: timestamped events with type badges.
  • A selected-node detail panel: kind, relationships, severity, explanation.
  • A legend: node shapes and edge colors.

The mock works because it is not just a graph. It is an observatory. It tells the loop story.

3. Product Goal

Team memory should be the "it learned" surface.

In a 10-second demo, a viewer should understand:

  1. Two engineers are converging on the same file.
  2. PodMan detected the risk before a push.
  3. PodMan suggested an intervention.
  4. The team accepted or dismissed the intervention.
  5. PodMan retained that outcome as memory.
  6. Future collisions become more informed.

The graph should support that story, not overwhelm it.

4. Target Layout

Build a light shadcn page with the same conceptual structure as the dark mock.

+--------------------------------------------------------------------------+
| Header: Team memory - What PodMan learned - <pod>              [<- Pods] |
+--------------------------------------------------------------------------+
| Mode controls: Risk path | Learning edges | Whole graph                  |
+---------------+--------------------------------------+-------------------+
| Workflow      |                                      | Learning loop     |
| metrics       |          Dynamic graph canvas         | Observe           |
| cards         |                                      | Store             |
|               |                                      | Predict           |
|               |                                      | Outcome           |
|               |                                      | Adapt             |
+---------------+--------------------------------------+-------------------+
| Activity stream                                | Selected node details   |
+--------------------------------------------------------------------------+

Required panels:

  • Header
    • Pod name / id.
    • Live/generated timestamp.
    • Back to pods action.
  • Mode controls
    • Risk path.
    • Learning edges.
    • Whole graph.
  • Workflow metrics rail
    • Learned owners.
    • Open risk paths.
    • Accept rate.
    • Optional: observations, interventions, memory vectors if available.
  • Dynamic graph canvas
    • Force-directed or animated layered graph.
    • Geometric node shapes.
    • Curved or bundled edges.
    • Labels should not overlap by default.
    • Hover/select reveals full details.
  • Learning loop rail
    • Observe.
    • Store.
    • Predict.
    • Outcome.
    • Adapt.
    • Active/current step should pulse or be highlighted.
  • Activity stream
    • Recent editing, collision, warning, outcome, learned events.
    • Compact rows with timestamp + colored type badge.
  • Selected node
    • Default state explains the loop.
    • Selected state shows node kind, name, relationships, severity/status, and why this node matters.

5. Visual Direction

Use the app's light shadcn/ruixen design system for chrome.

Hard rules:

  • Use @/components/ui/* primitives where possible.
  • If a primitive is missing, add it through: npx shadcn@latest add "https://ruixen.com/r/[component]"
  • Do not make the entire UI a bespoke CSS island.
  • The graph canvas itself may be bespoke SVG/canvas.
  • The rest should be composed from cards, badges, buttons, tabs/toggles, and utility classes consistent with App.tsx.

Keep semantic graph colors:

  • Engineer: blue.
  • File: slate outline.
  • Feature: amber circle.
  • Collision: red triangle.
  • Intervention: violet diamond.
  • collides: red edge.
  • warns: amber/orange edge.
  • learned_from: dashed violet edge.
  • owns: blue edge.
  • editing / touches: muted slate.

Use light surfaces:

  • Background: app background token.
  • Panels: card.
  • Borders: border.
  • Text: foreground.
  • Supporting copy: muted-foreground.

The result should feel like the dark mock translated into the app's light command center, not a random analytics dashboard.

6. Dynamic Graph Requirement

The current graph is too static. Replace or augment the static column layout.

Preferred implementation:

  • Use d3-force in the frontend.
  • Initialize nodes from server x/y when useful, but let the simulation settle.
  • Use:
    • link force by edge strength.
    • charge force for separation.
    • center force.
    • collision force based on node radius.
    • optional x/y bias by kind to preserve rough story flow.
  • Make nodes draggable.
  • Preserve node shape encoding.
  • Animate:
    • new nodes fading/scaling in.
    • new edges drawing/fading in.
    • learned_from dashed edge flowing or pulsing.
    • active collision/intervention pulse.

If d3-force is too much for the current branch, use an animated layered layout:

  • Engineers left.
  • Files mid-left.
  • Collisions center/right.
  • Interventions right.
  • Curved edges.
  • Smooth transitions between graph snapshots.
  • Gentle idle motion only if it helps.

Do not leave the final version as static fixed columns.

7. De-Hairball Rules

Default screen should show the risk path, not every possible relationship.

Rules:

  • Default mode: Risk path.
  • Whole graph can exist, but it is not the demo default.
  • Dim non-selected/non-risk edges aggressively.
  • Use curved edges or edge bundling.
  • Hide low-priority labels until hover/select.
  • Prefer file basename/short path on canvas.
  • Put full path in selected-node panel.
  • Group repeated collisions by signature.
  • Cap visible collisions/interventions for demo readability.
  • Preserve all data in the payload; choose a readable default projection.

The graph is not an exhaustive database browser. It is a story-first visualization.

8. Data Model To Use

Current PodGraph contract:

interface PodGraph {
  podId: string;
  generatedAt: string;
  nodes: PodGraphNode[];
  edges: PodGraphEdge[];
  metrics: PodGraphMetric[];
}

Node kinds:

  • engineer
  • file
  • feature
  • collision
  • intervention

Edge kinds:

  • owns
  • editing
  • touches
  • collides
  • warns
  • learned_from

Statuses:

  • stable
  • active
  • risk
  • learned

Existing collections behind the materializer:

  • pods
  • engineer_states
  • observations
  • collisions
  • interventions
  • outcomes

Important caveat:

The current demo-pod accepted outcome chain may be orphaned from test churn. If learned_from does not show, confirm whether there is an intact:

collision -> intervention -> accepted outcome

Do not assume the UI is broken until this data chain is verified.

9. Extend Data For Missing Panels

The current graph contract does not fully support the dark mock's learning-loop rail or activity stream.

Recommended additive extension:

interface PodGraphLoopStep {
  id: 'observe' | 'store' | 'predict' | 'outcome' | 'adapt';
  label: string;
  value: string;
  detail: string;
  status: 'idle' | 'active' | 'complete';
}

interface PodGraphActivity {
  id: string;
  at: string;
  kind: 'editing' | 'collision' | 'warns' | 'outcome' | 'learned_from';
  label: string;
  detail: string;
  nodeId?: string;
  edgeId?: string;
}

interface PodGraph {
  ...
  loop?: PodGraphLoopStep[];
  activity?: PodGraphActivity[];
}

Possible data mappings:

  • Observe: recent observations.
  • Store: stored observations / vectorized collisions / memory documents.
  • Predict: distinct live collisions.
  • Outcome: accepted vs dismissed outcomes.
  • Adapt: learned owners / learned_from edges / team_model.ownership.

Activity stream source:

  • engineer_states.gitUpdatedAt -> editing/git state.
  • collisions.detectedAt -> collision.
  • interventions.createdAt -> warns/intervention.
  • outcomes.recordedAt -> outcome.
  • accepted real outcome -> learned_from/adapt event.

Cap activity rows to 8-10.

10. Suggested Implementation Plan

  1. Create a new branch from the current graph branch or latest main.
  2. Read:
    • this file.
    • claude_team_memory_redesign.md.
    • docs/graph.md.
    • docs/live-ui-spec.md if present.
    • frontend/src/components/GraphView.tsx.
    • backend/src/graph/live.ts.
  3. Add graph UI subcomponents:
    • MetricsRail.
    • GraphCanvas.
    • LearningLoopRail.
    • ActivityStream.
    • SelectedNodePanel.
  4. Implement the dynamic graph canvas first.
  5. Add the learning-loop rail and activity stream.
  6. Polish interaction states:
    • hover.
    • selected node.
    • selected edge/path.
    • empty/live-loading/offline.
  7. Verify with local live data.
  8. Capture screenshots at desktop and narrow widths.
  9. Run:
    • pnpm build or local vite build.
    • tsc for shared/backend/frontend.
  10. Open a PR. Do not push directly to main.

11. Acceptance Criteria

The redesign is acceptable only when:

  • The default view is readable in 10 seconds.
  • The graph is dynamic, not static columns.
  • It includes metrics, graph, learning-loop rail, activity stream, selected-node panel, and legend.
  • The primary risk path is obvious.
  • Labels do not overlap in the default view.
  • Whole graph mode exists but can be visually denser.
  • It uses real data from the materializer.
  • It remains composed from light shadcn/ruixen primitives where possible.
  • It builds successfully.
  • It is verified after a hard refresh because the PWA can cache stale bundles.

12. What Not To Do

  • Do not make a marketing page.
  • Do not make a generic dashboard.
  • Do not rewrite the backend materializer unless the UI needs a small additive field.
  • Do not return to the dark UI wholesale.
  • Do not keep the static column layout as the final answer.
  • Do not show raw full paths as always-on canvas labels.
  • Do not show every edge at equal opacity.
  • Do not hide the learning loop in copy only; it needs a visible rail or panel.

13. Demo Script The UI Should Support

The final UI should support this story:

  1. Engineer A and Engineer B work in the same repo.
  2. One has unpushed changes.
  3. PodMan observes the overlap.
  4. A collision node appears and pulses.
  5. PodMan sends a sync PR / warning intervention.
  6. The intervention diamond appears.
  7. The team accepts.
  8. The outcome appears in the activity stream.
  9. A learned_from edge appears or pulses.
  10. The learning-loop rail advances to Adapt.

That is the recursive self-improvement moment. Everything else is supporting evidence.

14. Open Questions For The Implementer

  • Should dynamic layout be d3-force or animated layered SVG?
  • Should loop/activity be added to PodGraph or exposed as separate endpoints?
  • Should the demo seed one intact accepted outcome chain?
  • Should Whole graph be hidden behind an explicit "inspect full graph" affordance?
  • Should mobile show a simplified activity-first version instead of the full graph?

Answer these in code comments or PR notes when implementing.

15. Final Reminder

The backend now has real graph glue. The UI needs to become a live learning observatory, not a static graph dump.

Make the light version earn the same reaction as the dark Bauhaus mock:

I can see what happened.
I can see what PodMan did.
I can see what it learned.