DEV Community

holistis
holistis

Posted on

Two Strangers, Zero Stars, Two Boundaries Still Open

capacity-attest is a small npm package for signed, content-addressed delivery claims between two parties in an x402 agent-to-agent payment. As of today the GitHub repo behind it has 0 stargazers, 0 forks, and 1 open issue, and two outside developers built on it anyway.

This is what happened, told in the order it happened, using only what we can point at directly: pull requests, commit hashes, an npm registry, an on-chain transaction, an issue thread, and our own decision log. One real gap got closed and shipped on 2026-09-06. Two others are written down in DECISIONS.md as still open, on purpose, because no one has hit them hard enough yet to justify a fix.

The format

A capacity-attest claim comes down to two things: a claimId and a signature.

The claimId is a sha256 hash of the canonical content of the claim: who delivered what, to whom, and whether it was delivered. The signature is an EIP-191 signature over that content, and it recovers to a buyer address.

That is the whole trust model. No central ledger to believe, no reputation score, just a hash anyone can recompute and a signature anyone can verify themselves. We did not design this to be portable across chains. We designed it to be simple. Whether that simplicity would also travel across chains was tested by what happened between 2026-09-05 and 2026-09-07, not decided by us in advance.

The question that came before either builder

On 2026-09-05, goun7 opened x402-foundation/x402#3379, a feature request about binding x402 settlement to an externally verifiable agent work-receipt ledger, under the short name proof-of-done. The thread reached 14 comments from 5 people: 0xultravioleta, goun7, holistis (us), safal207, and wildcherrycasa.

Inside that thread was a specific technical question about our own ledger: is the append-only claims file hash-chained, or does its integrity rest entirely on whoever hosts it. goun7's own team had found the same class of problem in their own system, that a hostile writer can fabricate a consistent fake history against a fresh node.

We checked. It was not hash-chained. A host could show a buyer a subset of real, validly-signed claims, all positive, none negative, and the buyer would have no way to detect what was left out. Every individual claim would still verify as authentic. The set as a whole would still be misleading.

Boundary 1: completeness got a partial fix, not a full one

We built a priorClaimId field that lets a buyer chain their own successive claims about the same seller together, plus an analyzeCompleteness check that flags any returned claim whose predecessor is missing from the result. It shipped with 494 tests and a public fixture, merged and published as capacity-attest@0.4.0, and we answered publicly in the same issue thread (comment 5560977571) instead of asking anyone to take our word for it.

Read analyzeCompleteness for what it actually checks, not what its name implies. It detects a broken chain: if claim 5 points to claim 4 as its prior and claim 4 is missing, that gap is visible. It cannot prove there was never a claim 6. A host that simply never issues an attestation for a delivery leaves no gap to find, because no link in the chain was ever broken. Detecting an incomplete chain and proving a complete one are different guarantees, and only the first one shipped.

Existence anchoring, the piece that would let a third party confirm a claim exists independent of the host's own record, stays unbuilt for the same reason it started unbuilt: no real counterparty has ever named its absence as a blocker. It stays on the list, not in the code, until that changes.

The same discipline caught an overclaim before it went further than it should have. Working against the package, one contributor, YE-YI7, surfaced enough real friction that our decision log's first pass called it proof of a real need for a formal conformance-vectors suite, based on that single interaction. We walked that back once it became clear one data point does not prove a need for permanent infrastructure. What we shipped instead was cheaper: a section in the README for verifying a claim independently. The vectors suite stays unbuilt until a second, independent party hits the same friction after reading that section. So far, nobody has.

2026-09-06, 13:59 UTC: YE-YI7 merges PR #18

The same day, YE-YI7 merged a PR into their own asm-spec repository, 1568 additions across 6 files, that does not just copy our claim shape. It imports capacity-attest@0.2.0 as an actual dependency and calls into it directly, verifying the claim byte digest, the claimId, and the EIP-191 signer through our code, not a reimplementation of it. That is the first time anyone outside this project used the package itself, not just the idea behind it.

Nobody had asked us to build a reputation score or ranking on top of delivery claims, not YE-YI7, not goun7, and we deliberately do not. We corrected our own decision log on this point while writing this article: an earlier version credited YE-YI7 with a quote endorsing that choice, and we could not find that quote anywhere in YE-YI7's actual public work when we checked it against the source. It is gone from the log now. What survives, checked directly rather than assumed, is plainer and weaker: neither real contact has ever asked for a score, so the decision not to build one stands on our own reasoning, not on someone else's words.

Boundary 2: two ways to fake scale, neither closed

Not building a reputation score closes off one way to fake standing. Two separate, unrelated ways remain open, and we found both ourselves in an abuse scan on 2026-09-06 rather than fixed either.

The first is identity: nothing in capacity-attest stops one operator from registering many addresses and looking like many different buyers or sellers. A 14-agent research pass the same day checked whether this is already covered elsewhere, ERC-8004, Google's AP2, Microsoft's Entra Agent ID, the x402 Foundation's own work, the Legal Context Protocol, and concluded that it is. What we shipped from that pass was small: externalRefs citation fields and a resolve_agent_identity tool, verified live against ERC-8004 on Base mainnet. Citing an ERC-8004 identity is not the same as stopping one operator from registering many of them, and we left this deliberately thin.

The second is volume, a plainer problem with no identity layer involved. Nothing charges an actor for producing a claim, so an attacker can fabricate an unlimited stream of validly-signed, false claims against a real seller for free. get_delivery_history also returns results unbounded and synchronously, with no pagination and no rate limit on the read side. Both are marked in the decision log as found and not fixed, on purpose: rate-limiting one side while leaving the other free would look like a fix without being one. Both wait for an actual trigger, a real abuse case or a partner who needs the guarantee, before we commit to a specific mitigation.

2026-09-06, 19:33 UTC: 0.5.0 ships, and gets proven on-chain

Between the two pull requests, we published capacity-attest 0.5.0: cross-installation discovery plus an EAS source, commit c8fa192 ("chore(capacity-attest): 0.5.0 (cross-installation discovery + EAS source)").

The problem it addresses is separate from either boundary above: get_delivery_history is local by default. If buyer A and buyer B each run their own installation, B does not automatically see the claim A recorded about the same seller. discoverDeliveryHistory pulls claims from multiple independent sources and re-verifies every one of them regardless of where it came from, trusting no source by default.

We then proved this against a real public chain, not just a fixture. On Base mainnet, a schema was registered on EAS, UID 0x1dd19408345dee43b432b89ccb68760265ecff506098b6efe8ba82ad0d52b195, and two claims were published as attestations: one delivered yes, UID 0x81a55d54452b2cf8bdda7918f63a27bf9ff79e5025b485f7316aae6259288ccc, and one delivered no, UID 0xe736b005cbcb54f8f196ac64ef09d75d939c8a18c0d5d9670b5c5025c07398c4. Total cost for the three transactions was about 0.0000096 ETH, roughly 2.5 dollar cents. A separate read-only script, standing in for a fresh installation, then found both attestations on-chain and verified each one locally, including the negative one.

This solves discoverability, not completeness. Finding a claim across installations and proving you found every claim that exists are different problems, and only the first one has a shipped fix. One honest caveat on the numbers above: those three UIDs are quoted directly from our decision log. We have not independently re-checked them against base.easscan.org as part of writing this article.

2026-09-07, 04:54 UTC: EmbryoSpace merges PR #19

The second builder took a different path, into the same asm-spec repository. EmbryoSpace's PR, 543 additions across 9 files, reuses only the claim format, claimId as a sha256 hash of canonical content. Nothing else.

It could not reuse more, because our verifyClaim function is typed around ETH-style EIP-191 signatures. EmbryoSpace's claims are signed and encoded for BSV, base58, a different signature scheme entirely. Our verification code cannot check a BSV signature, so there was no version of this PR where it could call into our package the way YE-YI7's did.

That is the actual answer to whether the format is rail-neutral. It is, in the one part that matters most: content-addressing. The claimId only depends on hashing canonical content, so any chain can produce and consume the identifier. The signature and its verification are not neutral at all, and pretending otherwise would have been the wrong thing to write in a decision log meant to be checked, not trusted.

One more line item stayed unbuilt for a plainer reason: an in-transit status for multi-day deliveries. Neither external contact asked for it, and the closest real-world comparisons, AWS, Vast.ai, RunPod, also bill after the fact.

The numbers, plainly

capacity-attest is at 0.5.0 on npm, with 646 downloads over the period 2026-08-08 through 2026-09-06. The repository has 0 stargazers, 0 forks, 1 open issue. The most recent commit, c8fa192, landed 2026-09-06T19:33:36Z, and the four commits before it, all from the same author, landed on the same calendar day. This is one person moving fast on one day, not a project carrying years of review.

Exactly two people outside this project, YE-YI7 and EmbryoSpace, have built something that uses the claim format or the package itself, confirmed through their own merged pull requests, and they did it in two different ways worth telling apart. One calls into capacity-attest's own verification code. The other reuses only the hash-based identifier because its signature scheme cannot be checked by this code at all.

One boundary, completeness of visibility across a claim history, got a real but partial fix on 2026-09-06: it catches a broken chain, not a fabricated silence. A second boundary, faking scale, splits into an identity gap that was named and researched but left deliberately thin, and a plainer volume gap, free claim fabrication and an unbounded read endpoint, found and documented instead of patched over. Two strangers proved the format holds across two different rails. The decision log is where the next person finds out what it still does not hold against, corrections included.

Top comments (0)