[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-93273":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":16,"stars30d":16,"stars90d":15,"forks30d":15,"starsTrendScore":15,"compositeScore":17,"rankGlobal":10,"rankLanguage":10,"license":18,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":21,"hasPages":21,"topics":22,"createdAt":10,"pushedAt":10,"updatedAt":27,"readmeContent":28,"aiSummary":29,"trendingCount":15,"starSnapshotCount":15,"syncStatus":14,"lastSyncTime":30,"discoverSource":31},93273,"waggle","modiqo\u002Fwaggle","modiqo","Attributed, resolvable artifact references for agent handoffs — a ~30-byte token instead of pasted context. MCP-native; the reference layer for the agent-harness world.","https:\u002F\u002Fwaggle.sh",null,"Rust",550,137,2,0,281,80.42,"Apache License 2.0",false,"main",true,[23,24,25,26],"ai-agents","harness-engineering","llm-tools","loop-engineering","2026-07-22 04:02:08","\u003Ch1 align=\"center\">\n  \u003Cimg src=\"docs\u002Fassets\u002Flogo.svg\" width=\"52\" alt=\"the waggle mark: a figure-eight dance with the waggle run as an arrow\" align=\"center\"> waggle\n\u003C\u002Fh1>\n\n\u003Cp align=\"center\">\n  \u003Cstrong>Not a path. Not a URL. A handoff that answers back.\u003C\u002Fstrong>\n\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  Locations are dumb — no per-agent shaping, no receipts, no way to fix them\n  once sent. waggle's 30-byte \u003Cstrong>token\u003C\u002Fstrong> resolves into each\n  agent's own view, \u003Cstrong>counts every read\u003C\u002Fstrong>, and propagates a\n  correction to every holder. A path can't do that; a URL needs a server;\n  this needs neither.\n\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  \u003Ca href=\"#the-problem\">The problem\u003C\u002Fa> ·\n  \u003Ca href=\"#how-it-works\">How it works\u003C\u002Fa> ·\n  \u003Ca href=\"#install\">Install\u003C\u002Fa> ·\n  \u003Ca href=\"#wire-it-into-your-harness\">Harness setup\u003C\u002Fa> ·\n  \u003Ca href=\"#by-file-type\">By file type\u003C\u002Fa> ·\n  \u003Ca href=\"#reach-local--machines--the-edge\">Reach\u003C\u002Fa> ·\n  \u003Ca href=\"#the-tmux-switchboard\">Switchboard\u003C\u002Fa> ·\n  \u003Ca href=\"docs\u002Fdesign\u002Fessay.md\">The essay\u003C\u002Fa> ·\n  \u003Ca href=\"paper\u002F\">The paper\u003C\u002Fa>\n\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"docs\u002Fassets\u002Fhero.svg\" alt=\"The handoff, before and after: pasting the whole artifact to every subagent, versus handing off a 30-byte token that each consumer resolves into its own projection\" width=\"940\">\n\u003C\u002Fp>\n\n## The problem\n\nWe are entering the world of agent harnesses: Claude Code orchestrators\nfanning out subagents, Codex sessions delegating in parallel, cross-vendor\nagents discovering each other over open protocols. And every one of these\nhandoffs, today, works the same way: **forward the context and hope.**\n\nThe costs are measured, not hypothetical. Multi-agent systems consume ~15×\nthe tokens of a chat session — the overhead attributed by the vendor itself\nto *\"duplicating context across agents… and summarizing results for\nhandoffs,\"* whose one-line summary is **\"each handoff loses context.\"**\nRoughly 37% of multi-agent failures trace to exactly this seam.\n\nWaggle's competitor is not another protocol. It is\n`\"Here's \u002Ftmp\u002Fanalysis.md. Use it.\"` — and that instinct is *correct*: a\npath is a 30-byte reference, which is exactly the right size for a handoff.\nBut a raw path has **no attribution** (who made this, from what), **no\nadaptation** (the small-context model gets the same 9,000 tokens as the\nfrontier model), **no lifecycle** (a stale path silently serves wrong data\nforever), **no telemetry** (which subagent actually read its input? which\nstalled?), and **no reach** (it dies at the machine boundary).\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"docs\u002Fassets\u002Fcontext.svg\" alt=\"Three context windows compared: a full handoff fills the window with the artifact again; a raw path is cheap but blind; a waggle token stays small and pulls back only budgeted slices through resolve, search, and read\" width=\"940\">\n\u003C\u002Fp>\n\nOnly the *string* enters the consumer's context — the artifact behind it\nnever travels unless something fetches it. Waggle standardizes that third\npattern and enforces its one hard rule **by type**: the token travels; the\nartifact never auto-expands; `resolve`, `read`, and `search` return only the\nprojection or slice the consumer asked for, under byte budgets. Cheap like a\npath — but the reference answers back.\n\n## \"But my subagents share a filesystem — that's already share-by-reference\"\n\nIt is, and that's the smartest thing you can do without waggle. A path isn't a\ncopy; both agents point at the same bytes. Our benchmark's `reference` arm is\n*exactly* this — a local path plus `ls`, `grep`, `open`, `pdftotext` — and with a\nfair toolset it scores **90%**, competitive with waggle's 96%. If your agents are\nlocal, the task is short, and you never need to audit anything, **use the path** —\nwaggle is overhead.\n\nThe distinction isn't copy-vs-reference. It's that a path is a *location*, and a\nlocation can't answer three questions a handoff eventually has to:\n\n- **Was it read — and which parts?** `cat` and `grep` leave no trace you can query.\n  The entire \"did your subagent actually read it?\" check is *impossible* with a bare\n  path, not just inconvenient — reading a file records nothing. Our sharpest result\n  (regions read → 99% correct; skipped → 20%) exists only because reads go through\n  the token.\n- **Which version?** A path names *mutable* bytes. Correct the file mid-task and\n  agent A read the old copy, B the new, with nothing to tell them apart — the\n  divergent-copy failure, happening *with* a shared filesystem. Waggle snapshots at\n  mint (content-addressed, immutable) and gives `supersede`\u002F`revoke` with lineage.\n- **Reachable from where?** `file:\u002F\u002F\u002F…` means nothing to an agent in another\n  container or at the edge. The same token resolves unchanged across all three radii.\n\nThe case for waggle is **accountability, versioning, and reach** — never that the\nfilesystem duplicates bytes. The moment you need to *prove* what an agent read,\nsurvive the file changing, or hand off to something not on this box, a path runs out\nand a name doesn't.\n\n## How it works\n\nA **token** is a ~30-byte attributed name for an artifact, minted in one\ncall. Behind it stands an **attribution manifest**: who minted it\n(Ed25519-signed when the host holds an identity), for which channel, from\nwhich parent (delegation forms a lineage tree), with **variants** —\ndifferent projections for different consumers. When an agent resolves the\ntoken it presents its context, and a **sealed, deterministic matcher**\nreturns *its* projection. Everything afterward is an event in an\nappend-only log — payload-free by construction, so funnels count without\never seeing your data.\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"docs\u002Fassets\u002Floop.svg\" alt=\"The author's loop: mint, hand off one 30-byte line, consumers resolve their own projections, work is recorded as payload-free counts, the funnel reports, and a revocation travels to every replica\" width=\"940\">\n\u003C\u002Fp>\n\n**Consumption is protocol-shaped**: waggle is an MCP server. One config line\nin Claude Code, Codex, Cursor, or anything MCP-speaking — no SDK, no language\nbindings, no accounts. Locally it is one binary and a SQLite file.\n\n## Walk the handoff, in first person\n\nThe value isn't abstract. Stand in each role and it's obvious.\n\n**You are the orchestrator.** You just wrote a plan and spawned three\nsubagents. Today you paste the plan into each prompt — three copies,\nre-billed every turn, and afterward you have no idea which one actually\nread it. With waggle you hand each the same 30-byte line. When they\nreturn, the funnel shows two resolved and read it, one never opened it —\nand you catch the bluff *before* you trust its answer. Found a bug in the\nplan? One revoke, and the correction reaches all three.\n\n**You are the subagent.** You wake up with one line: `resolve b2uQyZUC`.\nYou resolve it into a digest shaped for *your* model, an outline so you\nknow what's inside before you read, and `next` steps pointing you where to\nlook. You grep for the one fact you need and pull 200 bytes — not the\n9,000-token plan. You never ingest what you didn't need.\n\n**Now the subagent moves to another machine.** Nothing changes. The same\nline, the same resolve, the same grep — the bytes stay on the\norchestrator's laptop, only the matches travel back. The loop you learned\nin one process is byte-for-byte the loop across the network.\n\n**And this can't live inside a harness.** Claude Code could build clever\nhandoffs — but that cleverness would die at its boundary; a Codex subagent\ncouldn't see it, and the orchestrator's memory of who made what, and who\nread it, would be prose in one harness's context, gone at the next\ncompaction. The reference layer has to sit *outside* any single harness — a\nneutral substrate every harness speaks in one line — so what Claude Code\nmints, Codex resolves, and the receipt survives them both. Handoffs are a\ndistributed-systems problem; solving them inside one vendor's harness logic\nis solving them in the one place they can't be solved.\n\n## Install\n\nPick one — all install the same `waggle` binary:\n\n```bash\ncargo install waggle-cli                          # from crates.io\n\n# ...or a prebuilt binary, no Rust toolchain needed:\ncurl --proto '=https' --tlsv1.2 -LsSf \\\n  https:\u002F\u002Fgithub.com\u002Fmodiqo\u002Fwaggle\u002Freleases\u002Flatest\u002Fdownload\u002Fwaggle-cli-installer.sh | sh\n\n# ...or Homebrew:\nbrew install modiqo\u002Fhomebrew-tap\u002Fwaggle-cli\n```\n\nThe store lives at `~\u002F.waggle\u002Fwaggle.db` (SQLite, WAL); blobs sit beside it.\n`waggle daemon status` shows uptime, connections, and disk weight.\n\n## Wire it into your harness\n\nTwo things make a harness waggle-fluent: the **MCP server** (the tools) and\nthe **convention-file stub** (the one standing instruction). Each is one\ncommand. All three land on the **same daemon and the same tokens** — what a\nClaude Code session mints, a Codex session resolves.\n\n**Claude Code**\n\n```bash\nclaude mcp add waggle -- waggle serve --stdio\nwaggle init        # in each repo where agents work\n```\n\n**Codex** — add to `~\u002F.codex\u002Fconfig.toml`:\n\n```toml\n[mcp_servers.waggle]\ncommand = \"waggle\"\nargs = [\"serve\", \"--stdio\"]\n```\n\n**Cursor** — add to `.cursor\u002Fmcp.json`:\n\n```json\n{ \"mcpServers\": { \"waggle\": { \"command\": \"waggle\", \"args\": [\"serve\", \"--stdio\"] } } }\n```\n\n**You don't start a server.** `waggle serve --stdio` *is* the MCP server — your\nharness launches it on demand, and its shim **auto-starts a shared background\ndaemon** the first time any harness connects (`connect_or_start`). There is no\nmanual daemon step: nothing to run, nothing to keep alive. Restart your harness so\nit picks up the new tools, then confirm:\n\n```bash\nwaggle daemon status     # → running · uptime · connections · db size\n```\n\nPrefer to run it in the foreground (for logs \u002F debugging) instead of letting it\nauto-start? `waggle serve --daemon`. Stop or restart the background one with\n`waggle daemon stop` \u002F `waggle daemon restart`.\n\n`waggle init` writes a short stub into `CLAUDE.md`, `AGENTS.md`, and\n`.cursorrules` (idempotent — it manages its own marked block). That stub is\nthe **entire** standing instruction; everything else is taught in-band —\nevery tool response carries up to three executable `next` steps, and `map`\nanswers *\"where am I, what are my paths?\"* computed live from state.\nInstructions in convention files rot; envelopes can't.\n\n**The orchestrator pattern**, in practice: when you delegate, the subagent's\nprompt contains the handoff line and nothing else about the artifact —\n\n> Your working context: **resolve `b2uQyZUC` via waggle**. Use `search`\u002F`read`\n> to pull only the slices you need; call `record --stage run` when you've\n> used it.\n\nThe subagent finds the tools already mounted, pulls its own projection, and\nthe funnel shows you it happened.\n\n## By file type\n\nThe lens engine is text-first, not markdown-first — structure is discovered\nfrom the content type, so the loop you learn on a report works on a lockfile.\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"docs\u002Fassets\u002Flenses.svg\" alt=\"One token, the right lens for each artifact: prose affords outline\u002Fsection\u002Flines\u002Fsearch; source code affords symbol\u002Flines\u002Fsearch plus symbol contracts, its outline extracted at mint; binaries are made text by extraction or ride as media variants\" width=\"940\">\n\u003C\u002Fp>\n\n**Prose** — mint with `--snapshot` to pin the bytes; consumers get the\noutline, sections, line windows, and grep:\n\n```bash\nwaggle mint --target \"file:\u002F\u002F$PWD\u002Fq3-report.md\" --snapshot\nwaggle read   --token b2uQyZUC --section \"Competitor Pricing\"\nwaggle search --token b2uQyZUC --pattern \"pricing\"     # matches travel, the file stays\n```\n\n**Source code** — `--snapshot` also runs tree-sitter at mint and stores a\n**symbol outline** beside the bytes. The consumer orients before it greps,\nreads a definition by name, and you can declare — and *prove* — what a\nreviewer had to reach:\n\n```bash\nwaggle mint --target \"file:\u002F\u002F$PWD\u002Fsrc\u002Fcontract.rs\" --snapshot \\\n    --require symbol:evaluate                 # a consumption contract, signed at mint\nwaggle read     --token 9u6KEr6F              # overview: the symbol table of contents\nwaggle read     --token 9u6KEr6F --symbol evaluate   # the exact definition, no window guessing\nwaggle coverage --token 9u6KEr6F              # { met: true }  ← the required region was reached\n```\n\nSymbols work for Rust, Python, TypeScript\u002FJavaScript, and Go; other text\nkeeps the full line\u002Fsearch loop. Extraction happens only at mint — no parser\never runs on a serving path, including the edge.\n\n**Binaries (PDF, image, voice)** — extract the text with your own abilities\nand pass it via `--content`, or attach the media so vision\u002Fvoice consumers\nreceive it while everyone else falls through to the catch-all:\n\n```bash\nwaggle mint --target \"file:\u002F\u002F$PWD\u002Fdeck.pdf\"   --content .\u002Fdeck.txt      # searchable text\nwaggle mint --target \"file:\u002F\u002F$PWD\u002Fmemo.m4a\"   --attach  .\u002Fmemo.m4a      # audio → listeners\n```\n\n## Reach: local → machines → the edge\n\nThe reference doesn't stop at the process boundary. Every harness on a\nmachine shares one daemon; daemons federate across machines; and the same\ntokens graduate to Cloudflare's edge by **replaying the log** — migration is\na stream, because the log is the truth. Pinned snapshots replicate with the\nrecords, so `search` greps *at the edge* against content whose source file\nnever left your laptop.\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"docs\u002Fassets\u002Freach.svg\" alt=\"One token at three radii: every harness on one machine through waggled; across machines through federation; and on Cloudflare's edge where grep runs remotely while the source files never leave\" width=\"940\">\n\u003C\u002Fp>\n\nWhen the handoff must outlive your laptop, deploy once\n([guide 09](docs\u002Fguide\u002F09-the-edge.md)) and push:\n\n```bash\nnpx wrangler deploy               # a Durable Object per tenant, same certified engine\nwaggle edge push                  # records + snapshots replicate; the FILES never leave\nwaggle edge status                # { \"health\": \"ok\", \"tools\": 9 }\nwaggle edge smoke                 # proof loop: mint → resolve → funnel, at the edge\n```\n\nThe CLI is transparent through all three tiers — an agent's loop (mint, hand\noff, resolve, interrogate, report) is byte-for-byte the same whether the\nother end is in this process, on another machine, or on another continent.\n\n## The tmux switchboard\n\nFor the full multi-harness experience, `waggle-tmux` turns handoffs into the\ninterface itself ([guide 11](docs\u002Fguide\u002F11-tmux-switchboard.md)):\n\n```bash\ncargo install --path crates\u002Fwaggle-tmux         # ships with the repo\nwaggle-tmux up claude-code codex                # choose once — everything wires itself\n```\n\nOne window per harness (the tmux bar is your harness switcher), a live\nlineage board under each, and when an agent finishes it mints its outcome to\n`tmux\u002F\u003Cdestination>` — your screen **swaps** to that harness with the resolve\ninstruction typing itself. Receipts on the board, `\u002Fexit` handled gracefully,\n`--seal` when the review must be provable.\n\n## What makes it credible\n\nThis repository is design-first and unusually explicit about its own\ndiscipline — the [design docs](docs\u002Fdesign\u002F) are the contract, and the\n[**specification**](spec\u002Fwaggle-spec.md) with its\n[conformance vectors](spec\u002Fvectors\u002F) is the portable half (generated FROM the\nimplementation and drift-checked in CI — an independent implementation that\nmatches them is a waggle implementation):\n\n- **Sans-I\u002FO core** — no clock, no entropy, no storage in the domain crates;\n  every effect is a parameter. The same code runs in the native daemon and in\n  Workers wasm, deterministic under test.\n- **Deterministic adaptivity** — same context, same projection, always; the\n  variant matcher is sealed so the trust claim survives.\n- **Event-sourced with a reconstruct guarantee** — counters are cache; the log\n  is truth; replay-equivalence is a CI property, not a slogan.\n- **One operations catalog** — the MCP tools, the clap CLI, the `map`\n  navigation, and `COMMANDS.md` are four projections of one table, with parity\n  tests that fail the build on drift.\n- **Verified against real infrastructure** — a differential oracle holds the\n  edge byte-identical to SQLite over the same operations, on a real Cloudflare\n  account.\n\n## Status\n\n**v0.4.0 on [crates.io](https:\u002F\u002Fcrates.io\u002Fcrates\u002Fwaggle)** — the full feature\nset, every claim a passing test in CI (three-OS matrix + wasm + the live\nMiniflare edge matrix):\n\n- **the full loop** — mint \u002F resolve \u002F record \u002F mutate \u002F funnel \u002F read \u002F\n  search \u002F query \u002F map over MCP and CLI, one shared daemon per machine;\n- **surgical content** — snapshots pinned content-addressed at mint; grep and\n  windowed reads through the token under byte budgets;\n- **receipts** — consumption contracts (`--require`), coverage with misses\n  named, `accepted`\u002F`rejected` outcomes, and an escalation choreography;\n- **the symbol lens** — mint-time tree-sitter outlines; `read --symbol`,\n  `--require symbol:`, zero parsing on any serving path;\n- **the resource projection** — MCP `resources\u002Flist`+`read`, and subscriptions\n  that push lifecycle corrections to holders;\n- **federation & the edge** — daemon-to-daemon; a Durable Object per tenant;\n  resolve p50 1.2 ms through the full HTTP-worker-DO path;\n- **trust** — Ed25519 over the immutable core; capability-URL private tokens;\n- **measured, not promised** ([benches\u002FPERF.md](benches\u002FPERF.md)) — 39 ns\n  cache-hit resolves, 39 µs durable appends, a million-event funnel fold in\n  334 µs.\n\nThe **[documentation map](docs\u002FREADME.md)** holds the guides in reading order;\nthe **[essay](docs\u002Fdesign\u002Fessay.md)** is why it's shaped this way, and the\n**[paper](paper\u002F)** is the systems treatment.\n\n## License\n\nMIT OR Apache-2.0, at your option.\n\n---\n\n\u003Cp align=\"center\">\n  \u003Cem>She never carries the field home. She dances, and the hive knows.\u003C\u002Fem>\n\u003C\u002Fp>\n","Waggle 是一个为 AI 代理协作设计的轻量级可解析工件引用协议，用约 30 字节的 token 替代传统上下文粘贴或路径传递。其核心功能包括：支持属性化（如来源、版本、权限）、按需动态解析（适配不同模型上下文窗口）、读取计数、错误传播与跨设备可达性，无需中心化服务。基于 MCP（Model Communication Protocol）原生集成，适用于多代理系统中的任务交接、上下文分发与资源协同场景，尤其适合 LLM 编排框架、Agent Harness 工程及分布式推理链路。","2026-07-15 02:30:06","CREATED_QUERY"]