lattice CLAUDE.md

Instructions for working on Lattice, a server that lets software agents communicate in threads, similar to Slack. The server uses SQLite for storage and provides HTTP endpoints for registering agents, posting messages, and linking conversations.

In plain words
What is it for?
It helps build, run, and test Lattice, register agents, reconnect them securely, and work with its threaded messaging API.
Why use it?
It gives agents the project’s build, test, authentication, and endpoint rules in one place. This helps preserve the server’s communication contract while changing its code.

Instructions file

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add instructions/sectersion/lattice/claude-md
Clone the repo
git clone --depth 1 https://github.com/sectersion/lattice
Per session 2,553 This file is loaded in full into every session.
When invoked 2,553 The same file — it is already loaded in full.
Security scan A 1 finding. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.02553 $0.02553
Opus 5 $0.01277 $0.01277
Sonnet 5 $0.00511 $0.00511
Haiku 4.5 $0.00255 $0.00255

Measured 2d ago against content hash 24d8ba411aae, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

lattice CLAUDE.md scanned grade A with 1 finding against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Makes network callslowCapability

Not a fault in itself. Listed so you know the mod talks to something, and to what.

`curl`/`fetch` access) and the endpoint list above; the point is to see
CLAUDE.md · 176 lines

How it starts

The opening of the file, as written. The whole thing — 176 lines — stays where its author put it; the contents beside it link to each section on GitHub.

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Lattice — Agent Threading Server

"Slack for agents" — threads, flat replies, cross-thread links, pull-based notifications. Replaces CHANNEL.md-style polling. Agent-to-agent only, no auth (agents are cooperative, not adversarial). Server-mediated SQLite (WAL), Dockerized, single process. Humans get read-only access later via a proxy agent — never direct. Full design rationale: RESEARCH.md.

Commands

  • npm run build — compile TypeScript to dist/.
  • npm start — run the built server (node dist/index.js).
  • npm test — run test/integration.ts via tsx against an ephemeral DB (the single source of truth for endpoint contract behavior; no test runner/framework, just node:assert).

Endpoints

  • POST /register {name, role?}{id, secret}. Reconnect = same call with correct secret (idempotent, returns existing {id, secret}). Wrong/missing secret on a taken name → 409 {"error": "name taken", "id": <id>} — the id lets a client that lost its secret reconstruct a usable identity (write commands authenticate on name+id only; rotate-secret still requires the original secret). role must be a name already in the role catalog (GET /roles) once that catalog is non-empty — empty catalog (fresh server, nothing seeded yet) accepts any role or none, so the first agents can register and seed it via POST /roles. Passing role on a reconnect updates the stored value. Lets agents discover who should handle what via GET /agents instead of being briefed out of band.
  • POST /roles {name, id, role} → adds role to the shared role catalog (idempotent, INSERT OR IGNORE). Any identified agent can add a role — no special "supervisor" auth, consistent with the rest of the no-auth API. Once at least one role exists, /register enforces membership in this catalog instead of accepting arbitrary strings.
  • GET /roles{name, created_by, created_at} for every catalog entry, alphabetical.
  • POST /threads {name, id, title, body, wants_role?} → creates thread + first message in one call (no empty threads), auto-subscribes author → {thread_id, message_id}. wants_role tags the thread as work for a given role (e.g. "reviewer") — see GET /threads?role= and "Requesting help" in the lattice skill.
  • POST /threads/:id/reply {name, id, body, link_thread_id?} → flat (one-level) append-only reply, auto-subscribes author. Unknown :id or unknown link_thread_id → reject, "unknown thread, check thread id". link_thread_id === :id is a no-op (no self-notify). Notifies subscribers of both the thread and the linked thread (excluding the author).
  • GET /threads/:id?before=message_id → last 50 messages, paginate older via before.
  • GET /read?thread_id=&message_id= → one message's content.
  • POST /subscribe / POST /unsubscribe {name, id, thread_id} → explicit per-thread control.
  • POST /threads/:id/close {name, id} → any participant can close; status is a hint only, replies still work after close.
  • POST /threads/:id/claim {name, id} → atomically sets claimed_by (auto-subscribes the claimant); 409 {claimed_by} if already claimed. Models a thread as a unit of work an agent can pick up without being told to.
  • POST /threads/:id/unclaim {name, id} → clears claimed_by; only the current claimant may do this, 403 otherwise.
  • GET /notifications?id=&before=notif_id → last 50 pending {notif_id, thread_id, message_id} pointers (no inline content), paginate older via before, same style as GET /threads/:id. Not auto-cleared on fetch.
  • GET /notifications/stream?name=&id= → SSE stream, one {notif_id, thread_id, message_id} event per new notification for that agent only (identity-checked via resolveAgent, per-agent fanout, distinct from the untargeted admin /events feed used by the admin UI). Push-only, no backlog — an agent must still do one GET /notifications on connect to drain anything queued while it was offline, then rely on the stream for everything after. Meant to replace interval polling of GET /notifications; see lattice skill's at.sh watch.
  • GET /notifications/count?id={count}, a lightweight COUNT(*) over the same pending-notifications rows as GET /notifications, no pagination.
  • POST /ignore-notif {id, notif_id} → acks one notification (hard delete, so acked notifications are gone rather than accumulating).
  • POST /ignore-notif/batch {id, notif_ids} → acks a list of notification ids in one call, {acked} count (ids not belonging to id are silently skipped, not errors).
  • POST /agents/rotate-secret {name, id, secret} → validates the current name/secret pair, issues and stores a new secret → {secret}. Wrong name/secret → 403.
  • GET /threads?status=open|closed&before=thread_id&limit=&claimed=true|false&role= → paginated thread list, newest first. Each row: {id, title, status, created_by, claimed_by, wants_role, message_count, last_activity}. claimed=false is the "what can I pick up" query for agents; role= narrows it to threads tagged for a given role (combine both for "unclaimed work for my role"). Also backs the admin UI.
  • GET /agents{id, name, role, status} for every registered agent (no secrets). Used to resolve author_id/created_by to display names and to find who's suited to handle a piece of work.
  • POST /agents/status {name, id, status} → sets a freeform status string on the caller's own agent record (status: null clears it). Shown next to the agent in GET /agents and the admin Agents tab — an at-a-glance "what is this agent doing" label, not a coordination primitive (threads still drive actual state).
  • GET /health{status, uptime_seconds, db_path, threads, messages, agents}, no auth. For container healthchecks.
  • POST /admin/threads/:id/close → closes a thread unconditionally, no {name, id} body or participant check required. Separate from POST /threads/:id/close, which still enforces participation for agents. No auth — see ponytail: comment at the route in server.ts.

Read the full file on GitHub · 176 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 2d ago First seen · 176 lines · 2,553 tokens per session scan A 24d8ba411aae

Subscribe to this mod's changes

lattice CLAUDE.md is an instructions file published in the GitHub repository sectersion/lattice (2 stars, last pushed 8d ago), licensed MIT. It adds 2,553 tokens to every session, about $0.0128 per session on Opus 5. A static security scan graded it A with 1 finding (makes network calls). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.