Commit Graph

64 Commits

Author SHA1 Message Date
sb-iam 412d3f7df6 tune(graph): de-noise the live materializer
Verified materializePodGraph against real demo-pod data (joins all connect:
21/21 interventions->collisions, learned_from produced). Tuning:
- engineer nodes are case-insensitive (merges Shakthi/shakthi)
- git (engineer_states) now only CONFIRMS editing on files vision/collisions
  already surfaced, instead of adding the whole repo diff (killed a 29-file
  node explosion from a watcher running against the full podman repo)

Cut demo-pod from 110 -> 77 nodes; git file-edges 39 -> 6.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 21:03:57 -07:00
sb-iam 85ab8da598 feat(graph): live materializer + light shadcn theme (real-data glue)
- backend/src/graph/live.ts: materializePodGraph builds the graph from the real
  collections (pods, engineer_states, observations, collisions, interventions,
  outcomes) instead of the demo seed. Parses git-status paths, fuses git+vision,
  draws collides/warns/learned_from, computes live metrics + a column layout.
- store.ts: loadPodGraph now prefers live → seeded team_model.graph → demo.
- GraphView.tsx: light/shadcn theme (from the team-memory-theme work), composed
  from the ruixen primitives; node-shape encoding unchanged.
- docs/graph.md: live data→graph mapping + fallback order.

Typechecks clean. Not yet runtime-verified end-to-end (Atlas creds rotated again).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 20:44:50 -07:00
Ramis 745f0032f7 fix: make MongoDB mandatory, fail loud instead of degrading
Reverse the best-effort error swallowing. MongoDB is core to PodMan's
continual-learning story and must always be used, so a broken memory
layer must surface immediately rather than silently masquerade as
working (which is how observations stayed at 0 unnoticed).

- agent verifies Mongo via initMemory() at boot; bad creds / unreachable
  Atlas now fail loudly before joining the room, not mid-demo
- server exits on Mongo init failure instead of warning and limping on
- getGitStates and onScreenFrame no longer swallow Mongo errors
- memory persist() logs the failure and rethrows instead of warning

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AaCFWMkYQmTcuPsxaaACft
2026-06-27 20:34:27 -07:00
Ramis 6a6fbca9e0 fix: stop agent crashing on Mongo errors during live loop
A Mongo auth/connection failure in getGitStates escaped uncaught and
killed the agent process on the first screen frame, so collision
detection never ran. Make git-state fusion best-effort (degrade to
vision-only) and wrap the whole onScreenFrame loop so no per-frame
Gemini/GitHub/Mongo error can crash the long-running agent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AaCFWMkYQmTcuPsxaaACft
2026-06-27 20:31:38 -07:00
Kartikeya fe37f35522 feat: podman.live Caddy + social link previews
infra/Caddyfile: add podman.live + www.podman.live (serve app + proxy /api),
so the domain is durable in the canonical config (not just a manual edit).
index.html: Open Graph + Twitter Card meta (title, description, og:image) so
sharing www.podman.live renders a rich preview. Adds a 1200x630 og.png card
(generated from og.svg) under public/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 20:22:08 -07:00
Yahya Alhinai 924552a025 chore: remove unused screen publish hook 2026-06-28 03:00:12 +00:00
Yahya Alhinai 7497318cde test: strengthen deployment verification 2026-06-28 02:54:29 +00:00
Kartikeya 702026fbd4 feat(frontend): add PodMan favicon
SVG favicon (dark #0b0f17 tile, emerald "P" + live dot) wired via
<link rel="icon"> in index.html. Fixes the favicon.ico 404.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 19:51:21 -07:00
Yahya Alhinai 4639db11b1 fix: verify atlas vector index without voyage 2026-06-28 02:38:54 +00:00
Yahya Alhinai 39a06499af feat: add local vector recall fallback 2026-06-28 02:27:45 +00:00
Yahya Alhinai 146d7e4bd2 test: verify frontend screen sharing 2026-06-28 02:20:58 +00:00
Yahya Alhinai 4253921532 Add Hermes operations management layer 2026-06-28 02:17:23 +00:00
Yahya Alhinai 89893110f1 feat: activate gemini voice tts path 2026-06-28 02:11:02 +00:00
Yahya Alhinai 4726e8ce80 test: make frontend verifier target frontend pod 2026-06-28 02:02:06 +00:00
Yahya Alhinai 1088196ba6 test: verify graph surfaces end to end 2026-06-28 01:59:58 +00:00
sb-iam b092a24941 Merge pull request #2 from karti-ai/feat/graph-data-viz
feat(graph): continual-learning graph data model + dark-Bauhaus viz
2026-06-27 18:56:00 -07:00
sb-iam 4ff17415b6 Merge origin/main into feat/graph-data-viz
Resolve App.tsx header conflict: keep main's "Privacy-limited" badge AND the
"Team memory" graph button (both in the header action group). server.ts and
backend/package.json auto-merged cleanly — main's closeMemory/shutdown and the
graph:seed script are both preserved.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 18:54:10 -07:00
Yahya Alhinai 3d99dd2449 fix: proxy LiveKit subdomain to cloud service 2026-06-28 01:53:20 +00:00
Yahya Alhinai 205939616b chore: add public healthcheck watchdog 2026-06-28 01:53:03 +00:00
Yahya Alhinai 9ac7bc5e8f test: stabilize frontend live join verifier 2026-06-28 01:46:57 +00:00
Yahya Alhinai c818d5081e feat: harden podman deployment orchestration 2026-06-28 01:44:26 +00:00
sb-iam eedfa935b1 Merge origin/main into feat/graph-data-viz
Resolve conflicts:
- backend/src/server.ts: keep main's getPresence + closeRoom (room auto-cleanup)
  and add the graph imports/routes (additive).
- frontend/src/App.tsx: take main's shadcn command-center UI and re-integrate
  GraphView — import, graphPodId state, an early-return render branch, and a
  shadcn "Team memory" button next to Refresh.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 18:41:56 -07:00
sb-iam 32bff6a3ab fix(graph): address review — reachFrom direct edges + node a11y
- reachFrom now returns the direct outbound edges PLUS the recursive
  $graphLookup reaches, de-duped by edge id, with maxDepth to bound cycles.
  It was dropping edges straight off the start node. [review P2]
- GraphView SVG nodes are keyboard-accessible: role/tabIndex/aria-label +
  Enter/Space handler alongside onClick. [review P3]

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 18:14:48 -07:00
sb-iam 546aeeed70 feat(graph): continual-learning graph data model + dark-Bauhaus viz
Adds the team_model graph layer (the "it learned" view) and its visualization,
per docs/graph.md. Demo-backed first; built on origin/main conventions.

- shared: PodGraph / node / edge / metric types + GraphNodeDoc / GraphEdgeDoc
- backend/src/graph: demo graph data; Mongo store (loadPodGraph w/ demo
  fallback, seedGraph, reachFrom via $graphLookup); graph:seed script
- backend/src/server.ts: additive GET /api/pods/:id/graph + /graph/reach/:node
- frontend: dark-Bauhaus GraphView + fetch helper, reachable from a
  "Team memory" toggle in App.tsx
- docs/graph.md: spec (data model, $graphLookup, API, demo-first plan)

Demo-backed: the route serves a grounded demo graph when team_model has no
graph yet; graph:seed writes team_model + graph_nodes/graph_edges so the
$graphLookup traversal is real. Swap loadPodGraph to live team_model later.

Known follow-ups before merge: branch is based on 65a0791; origin/main is now
at 1294b84, so this needs a rebase + App.tsx conflict resolution (teammate
rewrote App.tsx with live room view / one-click join).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 18:14:48 -07:00
Yahya Alhinai 5185845090 Overhaul PodMan UI with shadcn 2026-06-28 01:04:25 +00:00
Yahya Alhinai 80cc89072f feat: modernize PodMan frontend command center 2026-06-28 00:35:46 +00:00
Ramis 549895292c fix(frontend): stop screen MediaStreamTrack on PodView unmount
room.disconnect() removes the participant from LiveKit but doesn't stop
the underlying OS capture. Without track.stop() the screen share indicator
keeps running after Leave. beatRef already had cleanup; add the same for
screenTrackRef.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AaCFWMkYQmTcuPsxaaACft
2026-06-27 17:34:37 -07:00
Kartikeya 59e201fe93 fix(frontend): refresh pod list on leave so a deleted pod doesn't linger
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 17:23:47 -07:00
Kartikeya 891d4b12bd feat(livekit): close the room when a pod is deleted
DELETE /api/pods/:id now also calls closeRoom (RoomServiceClient.deleteRoom)
to end the live LiveKit room and disconnect anyone connected. PodView listens
for RoomEvent.Disconnected and returns the user to the pod list, so a deleted
pod cleanly kicks everyone out instead of stranding them in a dead room.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 17:22:07 -07:00
Kartikeya e29fabc3f1 fix(livekit): stable identity + room auto-cleanup
Use the member name as the LiveKit identity (was random per join) so a
refresh/rejoin replaces the existing session instead of leaving a ghost
participant in the room. Set roomConfig on the token (emptyTimeout 60s,
departureTimeout 20s) so empty rooms and departed participants clean up
promptly. Pods map 1:1 to a deterministic room name, so joins reuse the
same room rather than spawning new ones.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 17:13:32 -07:00
Yahya Alhinai b1b0761973 chore: format repo and fix lint config 2026-06-28 00:09:48 +00:00
Yahya Alhinai 1294b8428d docs: add README architecture section 2026-06-27 23:54:25 +00:00
Ramis a853ef7709 feat: fuse engineer_states git truth into collision detector
Add getGitStates(podId) to db.ts — queries the engineer_states collection
written by scripts/podman-agent.mjs and returns a map keyed by engineer name.

In PodMan.onScreenFrame(), fuse before detectCollisions(): if an engineer has
changedFiles in engineer_states, force hasUnpushedChanges=true on their context.
This overrides Gemini vision's unreliable pixel-based guess with deterministic
local git state — preventing the money-moment collision from silently not firing.

Key assumption: LiveKit participant identity matches the --name arg used when
running the git watcher (e.g. identity "alice" → --name alice).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AaCFWMkYQmTcuPsxaaACft
2026-06-27 16:53:13 -07:00
Yahya Alhinai 3598dce89e Merge pull request #1 from karti-ai/codex/podman-master-plan 2026-06-27 23:51:18 +00:00
Yahya Alhinai 8695c1bb53 docs: rewrite PodMan master plan 2026-06-27 23:49:04 +00:00
Ramis 27bf3d5855 feat(task-2b): git watcher script + docs update
- Add scripts/podman-agent.mjs — polls git every 15s, upserts changedFiles/
  diffStat/recentCommit/branch into MongoDB engineer_states collection
- README: add "Git watcher" section with per-laptop demo commands for each
  team member (alice/bob/carol --pod demo-pod)
- PLAN.md: mark scheduled git truth  partial, update acceptance checklist,
  clarify remaining fusion step (GIT_REPORT data channel wire-up still needed)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AaCFWMkYQmTcuPsxaaACft
2026-06-27 16:48:22 -07:00
Kartikeya 0f3b55a4f9 feat: one-click join + live pod presence
Join UX: click a member's name to join directly, or type a name and "Join"
(adds to roster + joins) — removes the redundant dropdown step. "Add" still
adds to the roster without joining.

Presence: new GET /api/presence (LiveKit RoomServiceClient) reports who's
connected per pod. The pod list polls it and shows a "N in room" badge plus a
green dot on members currently connected, so people can see active pods and jump in.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 16:46:47 -07:00
Kartikeya 8271188cf1 feat(frontend): live room view, beat connectivity test, session resume
- PodView now shows LIVE LiveKit participants (updates as people join/leave,
  active-speaker highlight) instead of the static roster — no refresh needed.
- "Play beat" button publishes a generated 4/4 beat into the room so every
  participant hears the same audio (speaker lights up) — a real connectivity test.
- "Share my screen" is now a deliberate button; joining only connects to the
  room (fast/reliable), so a denied/slow screen prompt no longer fails the join.
- Session persisted in sessionStorage with auto-reconnect, so a refresh keeps
  you in the room instead of dropping back to the pod list.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 16:37:32 -07:00
Ramis 65a0791022 docs(plan): audit server state + mark tasks 1-5 done, reflect actual arch
Server synced to HEAD (7ff750a). Actual arch differs from original spec:
- Frame capture: LiveKit track subscription (not HTTP /ingest)
- State layer: observations/collisions/interventions/outcomes collections
- Event detection: collision-based detector (not Gemini event prompt)
- Voice: stub only — logs but no audio yet

Tasks done: 1, 2, 3, 4, 5, 10
Tasks partial: 6 (voice stub), 8 (memory persists, no warm-start log)
Tasks missing: 2b (git watcher), 7 (SessionView.tsx)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8xxvqZtPhzkigb8Z7U4KV
2026-06-27 16:08:30 -07:00
Kartikeya 7ff750ad5e harden: address adversarial review of Pods CRUD
Backend: atomic create with insert-retry-on-duplicate-key (removes slug
TOCTOU race + wrong 400s), resilient per-index creation so a unique-index
failure can't silently drop the constraint or block seeding, idempotent
race-safe seeding via $setOnInsert, type validation + size caps on all pod
fields/members, removeMember no-ops without a write, /api/outcome guarded.
Frontend: per-pod busy state (one mutation no longer disables every card),
joined pod derived from the list (can't go stale), create keeps inputs on error.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 16:02:40 -07:00
Kartikeya 4ddc59be08 fix(frontend): self-destroying service worker to avoid stale UI during dev
The precaching PWA SW was serving an old bundle after deploys (stale UI).
Switch to selfDestroying so it unregisters + clears caches on all clients;
deploys are now always fresh. Re-add a tuned PWA before the demo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 15:52:24 -07:00
Kartikeya 5a03ad4d6b feat: Mongo-backed Pods with full CRUD + member management
Pods are persisted in MongoDB and CRUD'd via /api/pods (list/create/get/
update/delete + add/remove member). Shared Pod reshaped to a persisted entity
(members: string[], description, timestamps) + PodInput. Backend seeds Demo/
Frontend/Backend Pods on first run (Squad -> Pod rename). Frontend replaces
hardcoded teams with live data: PodCard (member chips add/remove, inline edit,
delete, join) + CreatePodForm; App fetches+mutates via API. Removes teams.ts/
TeamCard; gitignores test artifacts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 15:49:05 -07:00
Ramis 789f0da61b docs: remove per-person ownership assignments from PLAN.md and CLAUDE.md
No fixed ownership — any teammate can pick up any task.
PLAN.md: drop Owner field from all tasks, remove team assignments table.
CLAUDE.md: remove ownership map table and person-specific lane rules.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFbfi4Cmb7BY75Wtne7bZn
2026-06-27 15:46:40 -07:00
Ramis b4c0107e82 chore(frontend): update demo teams — Zander out, Shakthi in
Demo Pod: remove Zander, keep Karti/Yahya/Ramis/Shakthi
Frontend Squad: replace Zander with Ramis

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFbfi4Cmb7BY75Wtne7bZn
2026-06-27 15:43:33 -07:00
Ramis e16eff83ed docs(claude): add documentation-first enforcement rule
Hard gate: all code must trace to docs/PLAN.md task or a spec.
Claude must stop, consult, and update docs before writing unplanned code.
Includes off-plan signals checklist and rationale for 4-person concurrent team.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFbfi4Cmb7BY75Wtne7bZn
2026-06-27 15:41:49 -07:00
Ramis 9ad65331c3 docs: add git watcher script task + update engineer_states schema
- PLAN.md: add task 2b — scripts/podman-agent.mjs writes git signals
  directly to MongoDB (changedFiles, diffStat, branch, recentCommit)
  every 15s; Hermes reads merged vision+git state for event detection
- mongodb.md: extend engineer_states with git fields, document two-writer
  upsert pattern (vision fields vs git fields, no conflict)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFbfi4Cmb7BY75Wtne7bZn
2026-06-27 15:39:18 -07:00
Kartikeya 3fc19194f2 feat(backend): persist memory to MongoDB
Replace the in-memory store with a real MongoDB-backed store. Adds memory/db.ts
(client singleton, typed collections, startup ping + indexes) and rewrites
record{Observation,Collision,Intervention,Outcome} to insert into Mongo
(best-effort — failures log, don't crash). Server connects on startup and
exposes GET /api/memory/stats for verification.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 15:34:59 -07:00
Ramis e8fb91232f docs(claude): add 4-person concurrent team context to CLAUDE.md
Tell Claude this repo has 4 simultaneous owners with distinct lanes.
Adds ownership map, rules for staying in lane, merge conflict guidance,
and integration point contract rules.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFbfi4Cmb7BY75Wtne7bZn
2026-06-27 15:29:20 -07:00
Ramis 34d923374a chore: remove docs/generated, expand PLAN.md into full implementation plan
- Remove all docs/generated/* (stale research output from prior workflow)
- Rewrite PLAN.md as ordered implementation plan: 10 tasks by dependency + demo criticality
- Each task has owner, estimate, dependencies, specific files to create/modify
- Cut line separates must-ship from nice-to-have

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFbfi4Cmb7BY75Wtne7bZn
2026-06-27 15:27:23 -07:00
Ramis 923ab1cf58 docs: finalize PodMan architecture and write full integration specs
Replaces v1 plan with locked architecture:
- Hermes orchestrator: POST /ingest → Gemini Vision → MongoDB → event detection → Gemini Live 2.5 voice via LiveKit Agents
- Four MongoDB collections: engineer_states, ownership_map, events, nudges
- Continual learning via ownership_map persisting across sessions

New files: docs/idea.md, docs/gemini.md, docs/livekit.md, docs/mongodb.md, docs/digitalocean.md, docs/demo-setup.md
Updated: README.md, docs/PLAN.md (12-hour build plan), database/README.md, infra/README.md, .env.example

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFbfi4Cmb7BY75Wtne7bZn
2026-06-27 15:27:23 -07:00