18 KiB
Codex Handoff: MongoDB Cleanup, Team Memory Graph, and RSI Learning Docs
Date: 2026-06-28
Repo state checked: main at 1d097b1
Database checked: MongoDB Atlas database named podman
Scope: docs/spec handoff, live Team memory graph verification, and safe DB cleanup path
Current Repo State
The local checkout was moved to main and fast-forwarded to origin/main.
Working tree was clean after inspection.
The learning and graph specification docs are present on main:
docs/agent-learning/README.mddocs/agent-learning/spec.mddocs/agent-learning/policy.mddocs/agent-learning/plan.mddocs/agent-learning/prompt.mddocs/continual-learning/README.mddocs/continual-learning/spec.mddocs/continual-learning/policy.mddocs/continual-learning/plan.mddocs/continual-learning/prompt.mddocs/graph-discovery/README.mddocs/graph-discovery/spec.mddocs/graph-discovery/policy.mddocs/graph-discovery/plan.mddocs/graph-discovery/prompt.md
These docs describe the intended architecture, but only some pieces are backed by live Atlas collections today.
Verification Summary
Atlas connection is valid through local .env MONGODB_URI. No secrets were
printed during verification.
Public API checks:
https://165-22-129-249.sslip.io/healthreturned200with{ "ok": true }.GET /api/podsreturned one real pod:demo-pod.GET /api/pods/demo-pod/graphreturned a live materialized Team memory graph.
Live graph response for demo-pod:
- Nodes:
31 - Edges:
59 - Learned owners metric:
2 - Open risk paths metric:
2 - Accept rate metric:
39% - Learning loop active step:
adapt - Learned edges:
2learned_fromedges - Activity stream populated from real records
Important conclusion:
The main Team memory graph endpoint is real and backed by Atlas live materialization. It is not merely returning the demo fallback.
Atlas Collection Snapshot
Approximate counts observed:
| Collection | Count / status |
|---|---|
pods |
1 |
engineer_states |
9 |
observations |
2318 |
collisions |
451 |
interventions |
362 |
outcomes |
107 |
team_model |
65 |
graph_nodes |
715 |
graph_edges |
845 |
hermes_jobs |
29 |
hermes_job_events |
337 |
memory_vectors |
missing |
agent_runs |
missing |
agent_trace_events |
missing |
strategy_versions |
missing |
learning_proposals |
missing |
Real pod:
demo-pod
name: demo pod
members: ram, Karti, yahya, shakthi
Noise observed:
- Many
verify-pod-*records. - Many
verify-graph-*records. Verify ...observations insidedemo-pod.- Orphaned verify outcomes in
demo-pod. - Some stale or duplicate engineer state casing, e.g.
Shakthiandshakthi. frontend-podoutcomes with no corresponding active pod.
What Is Real Today
The following are real and active:
- Atlas connectivity.
demo-podpod record.- Real
engineer_statesfor demo members. - Real observation/collision/intervention/outcome collections.
- Live graph materialization from source collections.
- Graph response
loopandactivityfields. - Real
learned_fromedges produced by accepted real outcomes that still join back to surviving intervention/collision records.
The following are not yet real:
memory_vectorscollection.agent_runscollection.agent_trace_eventscollection.strategy_versionscollection.learning_proposalscollection.
That means the continual-learning story is currently supported by exact MongoDB records and graph edges. The richer agent-learning spec is documented but not implemented in Atlas yet.
Claude Code Review Addendum
Source: pasted Claude Code review text approved for Codex to read. The review
was treated as input, then reconciled against current main and the Atlas check
above. Do not copy the review blindly; a few findings were from an older repo
state or have since been superseded.
Still Material Findings
The review correctly identifies the main mismatch:
The docs describe a broader self-improving platform, while the shipped product
currently has a narrower but real recall-and-policy loop.
The shipped loop lives in code, not in the aspirational agent-learning docs:
backend/src/agent/podman.ts- Calls
recallSimilar(collision). - If prior memory exists, bumps severity to
critical. - Calls
shouldIntervene(collision, prior). - Calls
preferredAction(collision, prior). - Adds the visible message suffix
Seen before.when prior memory exists.
- Calls
backend/src/memory/policy.ts- Suppresses known false-positive prior outcomes.
- Enforces pod cooldown.
- Reuses a prior accepted intervention action when available.
backend/src/memory/vectors.ts- Stores
memorySignature,memoryText, and optionalembeddingoncollisions. recallSimilartries vector recall first, then signature/file fallback.
- Stores
This is the real recursive/self-improving asset today:
new collision -> recall prior collision -> adjust severity/action/message ->
record outcome -> future collision changes behavior
The current docs should eventually be reconciled around this loop instead of implying the full agent-learning platform already exists.
Confirmed Aspirational Areas
The following are documented but not live in Atlas/code yet:
agent_runsagent_trace_eventsstrategy_versionslearning_proposalsmemory_vectors
The agent-learning docs should be treated as future architecture unless a
small, explicit slice is implemented. For demo purposes, do not build a broad
strategy-versioning platform. If time allows, the smallest credible slice is one
stored policy/strategy row that explains a concrete behavior change.
Outcome Write Caveat
backend/src/memory/store.ts recordOutcome currently:
- inserts the outcome into
outcomes; - updates the intervention status to
acceptedordismissed.
It does not currently persist team_model.ownership. The live graph can still
derive owns and learned_from from accepted real outcomes at read time, but a
literal "before/after MongoDB ownership write" does not exist yet.
If the demo needs a concrete durable ownership diff, add a small explicit write on accepted real outcomes:
accepted && wasRealCollision -> team_model.ownership[normalizedFile] = learnedOwner
That should be a separate code task, not part of the DB cleanup unless the user explicitly asks.
Vector Recall Caveat
The docs often say "exact recall first." Current code does the reverse:
recallSimilar = vector recall first, then signature/file fallback
Also:
- Embeddings live on
collisions, notmemory_vectors. - Atlas vector index name in code is
collision_embedding. - Gemini embedding calls request
outputDimensionality: 768. - Voyage embeddings may have a different dimensionality depending on model.
For the hackathon demo, exact/signature/file fallback is the reliable story. Vector recall should remain nice-to-have unless Atlas index configuration is verified.
Demo Script Caveat
docs/demo-setup.md is stale relative to the Team memory observatory demo. It
still describes an older Hermes/voice/blocker flow and does not script:
- graph observatory;
- collision -> intervention -> outcome;
learned_from;- run 1 vs run 2 changed behavior.
Before stage rehearsal, rewrite docs/demo-setup.md around the actual
observatory path.
Superseded Review Findings
The pasted review included two findings that must be treated carefully:
- It claimed the current
shared/src/graph.tshad an olderLearningStage/ActivityEvent.textcontract. CurrentmainusesPodLearningLoopwithactiveStep, stepstatus, andPodGraphActivitywithtitle/detail. Always checkshared/src/graph.tsbefore editing specs. - It claimed the hero
learned_fromedge did not render ondemo-pod. The current Atlas/public API check returned two livelearned_fromedges. The risk is still real if cleanup deletes accepted real outcomes or their joined collision/intervention records. Preserve the intact accepted chains.
Priority Reconciliation Tasks
After the DB cleanup script, the next documentation/code priorities should be:
- Rewrite
docs/demo-setup.mdas the canonical graph observatory demo script. - Add a short
docs/recursive-loop.mdor equivalent section that names the real shipped loop inpodman.ts,policy.ts, andvectors.ts. - Mark agent-learning collections and strategy versioning as not-yet-built unless implemented.
- Reconcile vector-recall language in docs with current
vectors.ts. - Optionally add the
recordOutcomeownership write if a durable ownership diff is needed for judging.
Main Data Issue
The live graph and the normalized graph mirror are out of sync.
Live materializer for demo-pod:
31 nodes
59 edges
2 learned_from edges
Normalized mirror in graph_nodes / graph_edges for demo-pod:
11 seeded/demo-style nodes
13 seeded/demo-style edges
Impact:
GET /api/pods/demo-pod/graphis good and real.GET /api/pods/demo-pod/graph/reach/:nodeIdusesgraph_edges, so it can return stale seeded paths.- Example observed:
/graph/reach/engineer:kartireturned a seeded path./graph/reach/engineer:ramreturned0, even though Ram is present in the live graph.
The cleanup should therefore include a mirror rebuild after deleting test data.
Relevant Code Paths
Graph and MongoDB:
backend/src/graph/live.ts- Live materializer.
- Reads
pods,engineer_states,observations,collisions,interventions,outcomes, andteam_model. - Produces
nodes,edges,metrics,loop, andactivity.
backend/src/graph/store.tsloadPodGraph: live materializer first, then seededteam_model.graph, then demo fallback.seedGraph: writes seeded graph intoteam_model,graph_nodes,graph_edges.reachFrom: uses$graphLookupovergraph_edges.
backend/src/memory/db.ts- MongoDB connection and core collection helpers.
shared/src/graph.ts- Public graph contract including optional
loopandactivity.
- Public graph contract including optional
Docs:
docs/mongodb.mddocs/graph.mddocs/graph-discovery/docs/continual-learning/docs/agent-learning/
DB Cleanup Goal
Get Atlas into a demo-stable state:
- Preserve real
demo-podlearning history. - Remove verification/orphan/test records.
- Rebuild
graph_nodesandgraph_edgesfrom the live materialized graph. - Keep cleanup repeatable and reversible.
- Avoid ad hoc shell deletes.
Required Safety Rule
Take a backup before deleting anything.
mongodump "$MONGODB_URI" --archive=podman-before-cleanup.archive --gzip
Do not commit the archive.
Cleanup Keep Set
Start with this conservative keep set:
const keepPods = ["demo-pod"];
Records with podId outside this set are cleanup candidates unless there is a
specific reason to preserve them.
Phase 1: Dry-Run Counts
Write a script that defaults to dry-run. It should print counts only.
Candidate file:
scripts/db-cleanup.mjs
Default behavior:
node scripts/db-cleanup.mjs --dry-run
Apply behavior:
node scripts/db-cleanup.mjs --apply
The script must not delete anything unless --apply is present.
Phase 2: Remove Orphan/Test Pod Data
Delete records whose podId is not in keepPods.
Collections:
engineer_statesobservationscollisionsinterventionsoutcomesteam_modelgraph_nodesgraph_edgeshermes_jobshermes_job_events
Filter:
{ podId: { $nin: ["demo-pod"] } }
Note:
Some pods documents may use id instead of podId. For pods, do not use
the filter above. Keep the document with id: "demo-pod" and delete obvious
test pods only if they exist.
Phase 3: Clean Demo-Pod Verification Artifacts
Within demo-pod, delete only obvious verification records.
Observations
{
podId: "demo-pod",
$or: [
{ engineerId: /^Verify\b/ },
{ currentFile: /^PodMan verification screen$/ },
{ currentFile: /^frame \d+$/ }
]
}
Outcomes
{
podId: "demo-pod",
$or: [
{ interventionId: /^int-verify-/ },
{ collisionId: /^col-verify-/ }
]
}
Collisions and Interventions
Be more conservative. Delete only records that clearly have verify IDs or no matching counterpart.
Safe candidate filters:
// collisions
{
podId: "demo-pod",
id: /^col-verify-/
}
// interventions
{
podId: "demo-pod",
id: /^int-verify-/
}
Optional orphan cleanup:
- Delete interventions whose
collisionIddoes not exist incollisions. - Delete outcomes whose
interventionIddoes not exist ininterventionsand whosecollisionIddoes not exist incollisions.
Run orphan cleanup only after dry-run prints exact IDs and counts.
Phase 4: Normalize Demo-Pod Engineer State
Keep canonical active engineers:
ram
Karti
yahya
shakthi
Cleanup candidates:
{
podId: "demo-pod",
$or: [
{ name: /^Verify\b/ },
{ name: /^codex-check$/i },
{ name: /^testrepo/i },
{ name: "Shakthi" }
]
}
Only delete Shakthi if shakthi is confirmed as the canonical current record.
Phase 5: Rebuild Graph Mirror
This is the most important post-cleanup step.
The live graph endpoint is real, but reachability uses stale mirrored records. After cleanup:
- Materialize the live graph for
demo-pod. - Delete mirrored rows for
demo-pod. - Insert live graph nodes into
graph_nodes. - Insert live graph edges into
graph_edges. - Update
team_model.graphandteam_model.updatedAt.
Pseudocode:
const graph = await materializePodGraph("demo-pod");
await db.collection("graph_nodes").deleteMany({ podId: "demo-pod" });
await db.collection("graph_edges").deleteMany({ podId: "demo-pod" });
await db.collection("graph_nodes").insertMany(
graph.nodes.map((node) => ({ ...node, podId: "demo-pod" }))
);
await db.collection("graph_edges").insertMany(
graph.edges.map((edge) => ({ ...edge, podId: "demo-pod" }))
);
await db.collection("team_model").updateOne(
{ podId: "demo-pod" },
{ $set: { podId: "demo-pod", graph, updatedAt: new Date().toISOString() } },
{ upsert: true }
);
Important:
Use materializePodGraph, not createDemoPodGraph, for this rebuild.
seedGraph currently writes a demo graph and would recreate the stale mismatch.
Phase 6: Add Helpful Indexes
Current initMemory creates the core indexes, but cleanup/reachability benefits
from these as well:
db.graph_nodes.createIndex({ podId: 1, id: 1 }, { unique: true });
db.graph_edges.createIndex({ podId: 1, id: 1 }, { unique: true });
db.graph_edges.createIndex({ podId: 1, source: 1 });
db.graph_edges.createIndex({ podId: 1, target: 1 });
db.graph_edges.createIndex({ podId: 1, kind: 1 });
db.team_model.createIndex({ podId: 1 }, { unique: true });
db.collisions.createIndex({ podId: 1, memorySignature: 1 });
db.outcomes.createIndex({ podId: 1, interventionId: 1 });
db.interventions.createIndex({ podId: 1, collisionId: 1 });
Make index creation idempotent.
Validation After Cleanup
Run these checks after --apply.
Atlas counts
Confirm:
- No
verify-pod-*pod data remains. - No
verify-graph-*team models or graph rows remain. demo-podstill has meaningful observations, collisions, interventions, and outcomes.
Public API
curl https://165-22-129-249.sslip.io/health
curl https://165-22-129-249.sslip.io/api/pods
curl https://165-22-129-249.sslip.io/api/pods/demo-pod/graph
Expected:
- Health is
ok. demo-podstill exists.- Graph has nodes, edges, metrics, loop, activity.
- Graph includes
learned_fromif accepted real outcomes remain.
Reachability
After mirror rebuild, these should reflect the live graph, not old seed data:
curl "https://165-22-129-249.sslip.io/api/pods/demo-pod/graph/reach/engineer%3Aram"
curl "https://165-22-129-249.sslip.io/api/pods/demo-pod/graph/reach/engineer%3Ayahya"
curl "https://165-22-129-249.sslip.io/api/pods/demo-pod/graph/reach/engineer%3Akarti"
Expected:
- At least engineers present in the live graph should have reachable edges when they have outbound graph edges.
Known Tooling Caveat
One pnpm exec verification attempt was blocked by supply-chain policy:
prettier@3.9.0 was within the minimumReleaseAge cutoff
This did not indicate a MongoDB or graph failure. Direct MongoDB reads and the
existing local backend/node_modules/.bin/tsx binary were used instead.
Do not run broad dependency cleanup during DB cleanup unless explicitly asked.
Recommended Cleanup Script Shape
The script should:
- Load
.envwithdotenv. - Require
MONGODB_URI. - Print the database name.
- Refuse to run against a DB whose name is not
podmanunless--force-dbis passed. - Default to
--dry-run. - Require
--applyfor deletes. - Print every collection and matched count before deleting.
- Never print
MONGODB_URI. - Rebuild graph mirror only after delete phase succeeds.
- Print before/after counts.
Suggested flags:
--dry-run
--apply
--skip-mirror-rebuild
--keep-pod demo-pod
--force-db
Do Not Do
- Do not run
seedGraph("demo-pod")as the fix; that writes the demo graph. - Do not delete all
outcomes; accepted and dismissed outcomes are learning signals. - Do not delete all
team_model; preserve or rebuild thedemo-poddocument. - Do not print secrets or raw terminal/screenshot content.
- Do not rely on vector collections for the current demo; they are absent.
- Do not treat seeded graph mirror data as proof of current live learning.
Suggested Next Codex Prompt
Use this prompt for the implementation pass:
Create a safe MongoDB cleanup script for PodMan.
Read docs/handoff/README.md, docs/mongodb.md, docs/graph.md,
docs/continual-learning/spec.md, backend/src/graph/live.ts,
backend/src/graph/store.ts, backend/src/memory/store.ts,
backend/src/memory/policy.ts, backend/src/memory/vectors.ts, and
backend/src/agent/podman.ts before coding.
Implement scripts/db-cleanup.mjs with --dry-run default and --apply required for
deletes. Keep demo-pod, remove verify/orphan pod data, remove obvious demo-pod
verification artifacts, and rebuild graph_nodes/graph_edges/team_model.graph for
demo-pod from materializePodGraph, not createDemoPodGraph. Do not print secrets.
Run dry-run first and show counts before applying.
Do not implement broad agent-learning infrastructure in this task. The real
shipped RSI loop today is recallSimilar -> shouldIntervene/preferredAction ->
outcome -> future recall. Preserve accepted real outcome chains so learned_from
continues to render.