sangam
README.md
# sangam
**Your coding agent and your teammate's coding agent, on the same page.**
You use Claude Code. Your friend uses Codex. You're building the same thing.
Today that means one of you drives and the rest watch — or you leave notes for
each other's agents and hope.
sangam gives both agents a shared memory of what actually happened, and stops
them editing the same file at the same time.
```bash
npx sangam init --server=https://sangam.you.workers.dev
# → send your teammate one line:
npx sangam join https://sangam.you.workers.dev#prj_a1b2c3#K3y…
```
---
## Why not just have the agents write notes to each other?
Because what crosses is a sentence the *agent* chose to write. Two problems, and
the second is the fatal one:
1. **It's lossy.** 200k tokens of work becomes "refactored auth, see src/auth".
2. **It's voluntary.** It only happens if the model remembers to do it.
Any tool with a `save_context()` in it has the same defect in nicer packaging.
Structure doesn't fix this — *voluntariness is the lossiness*.
**sangam inverts it.** Claude Code and Codex already write a complete, verbatim
record of every session to disk, without being asked:
```
~/.claude/projects/<project>/<session>.jsonl
~/.codex/sessions/YYYY/MM/DD/rollout-<ts>-<uuid>.jsonl
```
sangam tails those files. Nothing is summarised, because nothing needs to be.
**The model is never in the loop on the write side.** Then MCP is used only for
*reading*: your teammate's agent queries the raw stream and gets their exact
words back, with attribution.
Capture is mechanical. Recall is on demand.
---
## What your agent gets
| tool | what it does |
|---|---|
| `ctx_brief` | who's active, what landed since you last worked, what's claimed. ~500 tokens |
| `ctx_search` | your teammates' **verbatim** words and actions, ranked so *human instructions* beat agent chatter |
| `ctx_thread` | expand one moment: what they asked, then what their agent actually did |
| `ctx_claim` / `ctx_release` / `ctx_who_has` | file leases, with a human-readable reason attached |
| `ctx_note` | the one voluntary write, for a decision the transcript can't show |
Plus, without the model having to cooperate at all:
- **SessionStart hook** puts the team's state *into* the context window
- **PreToolUse hook** refuses an edit to a file a teammate holds
- **git pre-push** refuses a push touching someone else's claimed files
---
## Install
```bash
npx sangam init # local only: your own Claude Code + Codex share context
npx sangam install-hooks # enforcement: deny colliding edits, brief every session
npx sangam doctor # check what it can see
```
Zero runtime dependencies. Node ships SQLite with FTS5, so there is nothing to
compile and nothing to install.
To work with other people, deploy the server to **your own** Cloudflare account —
so your transcripts go to infrastructure you control, not to us:
```bash
cd server && npx wrangler deploy
npx sangam init --server=https://sangam.<you>.workers.dev
npx sangam connection # the one line your teammate pastes
```
---
## How it works
```
MACHINE A (you) MACHINE B (teammate)
Claude Code Codex
│ writes ▲ MCP (stdio) │ writes ▲ MCP (stdio)
▼ │ ▼ │
~/.claude/…jsonl │ ~/.codex/…jsonl │
│ │ │ │
└──► sangamd ─────┘ └──► sangamd ───┘
tail → normalise → scrub (full local replica,
→ local SQLite + FTS FTS index, works offline)
│ │
└──── push / pull ────────┬─────────┘
▼
Cloudflare Worker → Durable Object per project
· total order (gseq)
· lease arbitration
· live presence
```
The server is deliberately **not** a search engine — every client keeps a full
local replica, so recall is instant and works on a plane. The server does only
what can't be done locally: ordering, lease arbitration, fanout.
Leases are a single-writer problem, which is exactly what a Durable Object is:
one request at a time, strongly-consistent storage, so "is this claimed?" is an
ordinary branch with no lock protocol. Tested rather than assumed — **50
simultaneous claims on the same pattern yield exactly one winner.**
---
## Honest limitations
These are measured, not guessed. If any of them matters to you, it should matter
before you install rather than after.
- **Enforcement is asymmetric today, and the git gate is the only universal
layer.** Claude Code exposes `PreToolUse`, so an edit can be blocked *before*
it happens. Recent Codex builds *do* ship hooks too — verified in
0.140.0-alpha.19: `PreToolUse`, `PermissionRequest` and `permissionDecision`
are all present — but sangam does not rely on them yet, for three reasons
worth knowing:
- Codex hooks are **trust-gated and fail silently**. An untrusted hook is
skipped with no prompt and no error, and there is no CLI command to trust
one (only a TUI slash command, or `--dangerously-bypass-hook-trust`). A
security control that silently does nothing is worse than none.
- The registration format is **version-skewed** and changing between builds.
- An admin can disable all non-managed hooks outright with
`allow_managed_hooks_only` in `/etc/codex/requirements.toml`.
So on Codex, Cursor, or a human in vim, collisions are caught by **git
pre-push**. Wiring Codex's `PreToolUse` is the next enforcement upgrade, gated
on a post-install check that asserts the hook actually fired.
- **Codex reasoning does not transfer.** Measured across 40 real sessions: 3592
`reasoning` items, all `encrypted_content`, 10 (0.3%) with a readable summary.
Claude Code's `thinking` transfers in full. Human turns, assistant messages,
tool calls and tool output transfer from both.
- **Tool output is not synced by default.** It is 51–88% of transcript bytes and
it is where secrets live. The reasoning trace of an 81 MB session is ~5 MB, so
you lose very little by leaving the bulk at home.
- **These log formats are internal and undocumented.** Anthropic and OpenAI can
change them in any release. Parsing is deliberately fault-tolerant, every event
records the emitting CLI version, and `sangam doctor` reports record shapes it
does not recognise instead of silently dropping them.
- **Hooks fail open, by design and by the host's own rules.** If the server is
unreachable your edit is allowed; a hook that times out is also cancelled and
the tool call proceeds. Wedging someone's work because their wifi dropped is
worse than a missed lease, and the git gate still catches it before anything is
shared. Treat leases as coordination, not as a security boundary.
- **`notify` is a dead end** and sangam does not use it: it is fire-and-forget
with stdin/stdout closed, carries a single event, and is marked for removal in
Codex's own source.
## Privacy
Everything is scoped to one repo and, by default, the last 14 days. Nothing
leaves your machine until you attach a server, and the recommended server is one
you deploy to your own Cloudflare account. Project keys are trust-on-first-use,
stored hashed, compared in constant time; knowing a project id is never enough.
## License
MIT.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues