Questions about Countersign

What the agent does, how to run a pack, how to read and verify the signed memo, and what a run costs.

About Countersign

What is Countersign?

An autonomous agent for counterparty due diligence. You give it a token, a cargo seller and vessel, or a legal entity. It plans the checks a desk would order and buys each answer from a Telegraph miner. It then decides with a fixed rule and signs a memo that anyone can re-verify.

It is an entry in Telegraph Hackathon Season II, track Apps & Agents.

Who is it for?

Three desks, one pack each, matching three Telegraph commercial missions:

PackDeskQuestion it answers
ExchangeToken listing deskShould we list this token?
CommoditiesPhysical commodity traderIs the seller real, the ship clean, the port open?
LegalLaw firm, compliance teamIs this entity in good standing everywhere it operates?

What does each pack check?

  • Exchange: sanctions on the issuing entity, smart-contract audit, adverse media. Optional: bot detection on the X account, on-chain treasury balance, source code review.
  • Commodities: seller registry and sanctions, vessel sanctions and telemetry, port congestion at discharge. Optional: bill of lading authenticity.
  • Legal: registry standing in up to three jurisdictions, sanctions on the entity and up to three officers, regulatory filings, adverse media, B2B identity.

A finding can trigger more checks. A sanctions hit, a dead registry record or a bot-run audience makes the agent buy a targeted news search.

Why buy checks from Telegraph instead of calling a data API?

Telegraph routes each request to the miner ranked best for that kind of check, so the agent never hardcodes a vendor. Every answer arrives with a signed signal hash and a payment receipt that prove who answered and that the agent paid. Most checks cost $0.01, with no subscriptions and no per-vendor API keys.

Does an AI model decide the outcome?

No. Miners supply the answers; a fixed rule in the code decides. The same answers always give the same decision.

  • STOP a blocking finding that a second miner confirmed.
  • REVIEW any flag, an unconfirmed or disputed block, a critical check without a usable answer, miners that disagree, or fewer than two thirds of checks answered.
  • GO everything else: every answered check came back clean.

Why do the decision labels differ between packs?

Each desk has its own words for the same three outcomes. The memo shows both, for example PROCEED (GO).

RuleExchangeCommoditiesLegal
GOLISTPROCEEDCLEAR
REVIEWREVIEWHOLDREVIEW
STOPREJECTBLOCKESCALATE

What is a cross-check?

When a critical check comes back with anything but a clean answer, the agent pays a second, independent miner for the same question. The finding is then marked confirmed or disputed. A block the second miner does not confirm leads to REVIEW, never STOP.

Is the memo legal or investment advice?

No. Countersign reports what the miners answered and applies its own rule on top. It supports a human decision and does not replace it.

Getting started

What do I need to run it?

Node.js 20.12 or newer and a little Sepolia ETH (0.01 to 0.05) from any Sepolia faucet, which pays gas for minting test USDC. No account and no API key.

How do I set it up?

npm install
npm run wallet:new        # throwaway key in .env, prints the address
# send Sepolia ETH to that address, then:
npm run cs -- mint        # 10 test USDC to the agent wallet
npm run cs -- wallet      # balances and today's spend

Can I try it without paying?

Yes. The node prices every request before payment, so a quote is free. It lists each planned check, its price and the worst case with cross-checks.

npm run cs -- plan exchange --example

How do I run a real check?

npm run cs -- run exchange --example
npm run cs -- run commodities --example
npm run cs -- run legal --example

--example uses a built-in subject: Uniswap, Trafigura with the vessel EVER GIVEN, or Revolut Ltd. The terminal streams each purchase, each finding and the decision.

How do I check my own subject?

Pass the fields as flags. npm run cs -- packs lists every field.

npm run cs -- run commodities --seller "Trafigura Pte Ltd" \
  --jurisdiction Singapore --vessel "EVER GIVEN" --imo 9811000 --port Rotterdam
PackRequiredOptional
exchange--project --token--chain --entity --x --treasury --source
commodities--seller --jurisdiction --vessel --port--imo --document
legal--entity --jurisdictions--people --period

Add --no-crosscheck to skip second-miner checks and spend less.

Is there a web interface?

Run npm run serve and open the agent at 127.0.0.1:4402/app.html. Pick a pack, fill the form or load the example, get a free quote, then run. Purchases stream in live, the memo opens with its evidence ledger, and Verify re-checks every signal on the node.

Which commands does the CLI have?

walletAddress, Sepolia ETH, test USDC, escrow credit, today's spend
mint --amount 10Mint test USDC
packsPacks and their fields
plan <pack>Free quote
run <pack>Paid run, writes a signed memo
verify <memo>Re-check signature, digest, signals
show <memo>Print a memo as Markdown

Every command starts with npm run cs --.

The memo

What is in a memo?

  • Decision with its desk label, the share of checks answered and the total cost.
  • Why: the reasons behind the decision.
  • Findings: one row per check with its verdict, summary, corroboration and signal hash.
  • Evidence ledger: intent, miner, full signal hash, payment receipt, cost.
  • Integrity: agent wallet, keccak256 digest of the memo, EIP-191 signature.

Each run writes the memo as JSON and Markdown to data/memos/.

What do CLEAR, FLAG, BLOCK and UNKNOWN mean?

CLEAR: the miner's answer shows no risk. FLAG: something a person should read. BLOCK: a hard stop such as a sanctions match. UNKNOWN: the miner returned no usable value or the request failed.

An unknown answer is never treated as clean. An unknown critical check turns the memo to REVIEW.

How do I verify a memo, mine or someone else's?

npm run cs -- verify exchange-2026-11-09-58b7f27b
npm run cs -- verify path/to/memo.json

Verify recomputes the memo digest and recovers the signer. It fetches every signal from the Telegraph node, recomputes its keccak256 hash and confirms the agent wallet paid for it. Changing one field in the memo breaks the digest. Any signal can also be opened in a browser at devnode.telegraphprotocol.com/engine/v1/signal/<hash>.

Cost and safety

What does a run cost?

Most checks cost $0.01 in test USDC. The three example runs cost $0.05, $0.05 and $0.08. Cross-checks and follow-up checks add a few cents, and the free quote shows the worst case before you pay.

What stops the agent from overspending?

Three caps in .env. The agent refuses to sign any payment that would cross one.

VariableDefaultLimit
MAX_USD_PER_RUN$0.25One run
MAX_USD_PER_DAY$2.00All runs in a day
MAX_ATOMIC_PER_PAYMENT$0.10One payment

Budget is reserved before signing and charged only on success. Engine errors come back before payment and cost nothing.

Are my queries private?

No. Every Telegraph request is public, and the network feed shows the query with the paying wallet.

Use only public company, vessel and token names and a throwaway testnet key. Never put client names or confidential deal terms into a run.

Where is the private key kept?

In .env, which git ignores. npm run wallet:new creates a fresh throwaway key. Never commit .env and never reuse a key that holds real funds.

Is this real money?

No. Countersign runs on Ethereum Sepolia with Telegraph test USDC. Telegraph plans to move to mainnet on the same contracts and payment path.

Troubleshooting

“AGENT_PRIVATE_KEY is missing or malformed”

There is no key in .env. Run npm run wallet:new.

Minting test USDC fails

The wallet has no Sepolia ETH for gas. Fund the address from a Sepolia faucet and mint again.

A finding says “Not bought: run budget reached”

The run or daily cap was hit. Raise MAX_USD_PER_RUN or MAX_USD_PER_DAY in .env, or run again tomorrow.

Every paid check fails

The wallet is likely out of test USDC. Check with npm run cs -- wallet and mint more.

Errors 429 or 503

429 means more than 60 new questions in a minute; wait a minute. 503 no_compatible_miner means no miner serves that check right now; it shows as UNKNOWN, so retry later. Neither costs anything.

Verify shows BAD for a signal

Either the node was unreachable or the memo was edited. Retry; if it still fails, do not trust the memo.

For developers

Is there an HTTP API?

The local server binds to 127.0.0.1 and runs one agent at a time.

GET /api/statusNode, wallet, budget, current run
GET /api/packsPacks and fields
POST /api/planFree quote: {"pack", "subject"}
POST /api/runsStart a run, returns its id
GET /api/runs/<id>/eventsLive events (Server-Sent Events)
GET /api/memosList memos
GET /api/memos/<id>One memo as JSON
GET /api/memos/<id>/verifyVerify a memo

How do I add a pack?

Copy a file in src/packs/, define its fields, example subject, labels and the checks it plans from the shared builders in src/packs/checks.ts, then register it in src/packs/index.ts. The agent, budget, decision rule, memo and web UI pick it up unchanged.

How do I run the tests?

npm test
npm run typecheck

They cover the decision rule, the answer evaluators, signal hashing against a real Telegraph signal, memo signing and the spend caps.