Horos

A change of payment address is a succession ceremony, not a field update.

Paste an invoice. Watch it refuse.

The agent reads the document, checks the destination against what has actually been paid before, and reaches a verdict. Every reason is shown, including the ones that did not block. Nothing here needs an account, and nothing here can move money — the page holds no key.

Want this on one of your own invoices? That takes ten minutes.

The counterparty id is derived, not chosen: keccak256(name, firstAccount, registry). The account consents with its own signature, and names the business that may authorise a change — so there is nothing to squat on at all.

fills this in with the counterparty this deployment actually paid — then press Decide
Or start from one of these:

Why this is not a filter

A filter reads the invoice and decides whether the address looks suspicious. That is a losing game: the address is new to every system that ever sees it, because the attacker generates it. Horos does not score the address. It refuses to name one.

CustodyVault.pay(counterpartyId, amount, reference)

There is no parameter for a destination. The vault asks the registry which account this counterparty is currently paid at, and sends there. Paying a new address is not a call this contract can be given, so no prompt, no compromised key and no bug in this page can express it. The refusal is a property of the interface rather than a check that ran.

Changing the address is a ceremony

When a supplier genuinely moves accounts, the move requires two signatures that the recipient cannot produce: the account that was last paid, agreeing to be replaced, and the business, agreeing to the change. Until both exist, the new account is a proposal — visible, pending, and unable to receive anything.

If the old key is genuinely lost, that is not a dead end and it is not a silent override either. The counterparty page shows what happened: the change is recorded permanently and the counterparty is marked broken, in public, where everyone who might pay it can see.

This page holds no key

It reads Arc over public RPC endpoints, which reject every write by design. The ABI it is compiled against contains no write function (worker/src/abi.ts). The decision logic is not reimplemented here — this Worker imports lib/policy.ts from the repository, the same file the unit tests run against, so the deployed site and the test suite cannot disagree.

That is why there is no Connect Wallet button, and the absence is the argument rather than an omission. A wallet on this page could only ever be asked to approve a payment by hand — the exact step this design exists to remove. Every signature a person gives in Horos is a transaction against the contracts: half of a change of account, or an owner's cap, pause or withdrawal. None of them is a destination, and none of them is relayed through a web page.

Source · Arc explorer · built for the Tameion Agents Hackathon