Crumbs, Deggen, BrandonC
This document specifies a slash-command grammar for conversational Metanet clients, and a global set of command verbs that MUST behave identically in every conforming client regardless of ecosystem.
Commands are the chat-native surface over the addressing, payment, messaging, reachability, and delegation mechanics of BRC-169. /pay @brandon:handcash $2.18 performs a BRC-169 section 6 payment; /trolltoll $0.218 sets a BRC-169 section 8 policy. This document defines the syntax, the parsing and confirmation rules, and the exact behavior of each verb. It defines no new cryptographic or wire mechanics.
It also reserves a set of verbs for commands that are anticipated but not yet specified, so that ecosystems cannot claim them, and defines how an ecosystem advertises its own custom commands without colliding with the global set.
The interface through which people use the Metanet is converging on chat, and two properties make a standardized command grammar worth writing down.
Agents read and write the same grammar. An agent that can parse /pay @brandon:handcash $2.18 can also emit it. A slash command is simultaneously a human-readable interface and a machine-parsable API, which is what an agent-mediated decade requires. That dual role is also a hazard: text that arrives from a counterparty must never be executable, and an agent acting for a user must be bound by verifiable authority rather than by convention. Both are addressed here.
Identical parsing is what makes commands portable. If /pay means one thing in one client and something else in another, the grammar is worthless as an interoperability layer, and worse than worthless as a target for agents. Reserving the global verbs and fixing their meanings in a versioned document is the whole contribution.
A note on scope. Commands requiring a multi-party protocol or an on-chain construct that BRC-169 does not define are reserved in section 6 rather than described loosely. "Every client MUST parse this identically" is not a meaningful requirement for behavior that has not been specified, and a verb sketched in a sentence invites divergent implementations with funds at stake. Reserving the name costs nothing and keeps it available for a specification that does the work.
The key words MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY in this document are to be interpreted as described in RFC 2119.
Throughout, "resolve" means the client resolution algorithm of BRC-169 section 5.7, and "value-moving action" has the meaning given in BRC-169 section 1.
- Command: a line of user input beginning with
/, parsed per section 2. - Global verb: a verb defined in section 5, or reserved in section 6. Global verbs are reserved across all ecosystems.
- Custom verb: a verb defined by a single ecosystem and advertised per section 8.
- Thread: the conversation in which a command is issued. A command issued in reply to a specific message is bound to that message.
command = "/" verb *( 1*SP arg )
verb = alnum [ *30( alnum / "-" ) alnum ] ; 1 to 32 characters
arg = recipient / amount / duration / period / quoted / word
recipient = <the recipient rule of BRC-169 section 2.1>
amount = fiat / sats
fiat = [ iso4217 1*SP ] "$" 1*DIGIT [ "." 1*2DIGIT ]
/ iso4217 1*SP 1*DIGIT [ "." 1*2DIGIT ]
sats = 1*DIGIT 1*SP ( "sat" / "sats" )
duration = 1*DIGIT ( "m" / "h" / "d" ) ; minutes, hours, days
period = "/" ( "day" / "week" / "month" )
quoted = DQUOTE *( %x20-21 / %x23-5B / %x5D-7E / "\" DQUOTE ) DQUOTE
word = 1*64( %x21-7E ) ; no whitespace
iso4217 = 3UPPER
alnum = lower / DIGIT
lower = %x61-7A
UPPER = %x41-5A- A line beginning with
/is a command. A line beginning with//is chat whose first character is a literal/, with the leading//reduced to/before display. Any other line is chat. - Verbs are case-insensitive and MUST be normalized to lowercase before dispatch. Arguments are case-sensitive except where a referenced specification requires normalization.
- Where a command takes free text as its last argument, that argument extends to the end of the line and is not subject to the
wordrule. - A client MUST parse commands only from input composed locally by its own user. Text received from a counterparty, whether in message content, a display name, a memo field, an attachment, or a search result, MUST NOT be parsed or executed as a command under any circumstances, and MUST be rendered as literal text. See Security Considerations.
- A client encountering a verb it does not implement MUST report it as unsupported. It MUST NOT execute a different command, and it MUST NOT reassign the verb's meaning.
- Parsing MUST NOT have side effects. A command takes effect only after the confirmation rules of section 4 are satisfied.
21545 satsdenotes exactly 21,545 satoshis.$2.18denotes 2.18 USD. Other currencies use an ISO-4217 prefix, as inCHF 5.- Fiat amounts MUST be converted at send time through the oracle interface of BRC-169 section 6.2, subject to its staleness bound, disclosure rules, and audit-trail requirements.
- A client MUST display the satoshi amount alongside the fiat amount in the confirmation of section 4 for any fiat-denominated command.
- A client MUST reject a fiat amount it cannot convert. It MUST NOT substitute a stale rate, a cached rate beyond its validity, or a rate from an undisclosed source.
- Before executing any command that moves value, issues or revokes a certificate, or changes a reachability policy, a client MUST present a structured confirmation showing at minimum: the verb, the fully-qualified recipient where one applies, the amount in both satoshis and the typed fiat where applicable, and a plain statement of the effect.
- The confirmation MUST show the recipient as
@handle:domain.tldin fully-qualified form, never as an alias alone, and MUST reflect the display and confusability rules of BRC-169 sections 2.3 and 2.4. - Clients MUST offer autocomplete for verbs and recipients. Autocomplete MUST NOT substitute a recipient the user did not select, and a completed recipient MUST remain visible and editable before confirmation.
- Resolution failures, revoked handles, and key changes MUST be surfaced at confirmation time and MUST block execution of a value-moving command until acknowledged, per BRC-169 sections 4.4 and 5.3.
- Non-interactive execution. An agent or automation executing commands on a user's behalf without per-command human confirmation MUST hold a delegation certificate per BRC-169 section 9 covering each verb it executes, and MUST remain within that certificate's scope, caps, and expiry. A client MUST NOT offer a mode that suppresses confirmation without a corresponding delegation, and MUST NOT treat a suppressed confirmation as raising the limits in the certificate.
- A command bound to a message applies to that message. Where a command requires a binding and none exists, the client MUST report the error rather than apply the command to the thread's most recent message.
The verbs in this section are reserved across all ecosystems and are versioned by this document: additions and changes happen by revision. Every conforming client MUST parse them identically. A client MAY decline to execute a verb it does not support, but MUST NOT reassign its meaning.
/pay <recipient> <amount> [memo]
Resolve the recipient and execute a BRC-169 section 6.1 payment. memo is free text and MUST be carried in the encrypted envelope content, not in envelope metadata.
Where the recipient has a toll in force, the client MUST follow BRC-169 section 8.3, quoting before sending and attaching the toll in addition to the payment amount. The toll and the payment are distinct amounts and MUST be shown separately at confirmation.
/message <recipient> <text>
Send text to the recipient as a BRC-169 section 7.2 envelope. Equivalent to plain chat once a thread exists; the explicit form exists for cross-ecosystem first contact and for agents.
/request <recipient> <amount> [memo]
Send a payment request. The recipient's client MUST render it as an actionable item that, on acceptance, executes /pay back to the requester for the stated amount, and MUST re-derive the amount at acceptance time where it was fiat-denominated, showing both the original and current satoshi values.
A request confers no authority. It MUST NOT cause any transfer without the recipient's explicit confirmation, and a client MUST NOT allow a request to be auto-accepted by any policy short of a delegation certificate scoped to pay.
/tip [amount]
A /pay bound to the message being replied to, addressed to that message's verified sender. The binding MUST be recorded in the envelope content so the recipient can attribute the tip. Where amount is omitted the client SHOULD offer a configured default, and MUST still confirm per section 4.
/split <recipient> 1*( 1*SP <recipient> ) <amount>
Divide amount among the named recipients and send each leg as an independent BRC-169 section 6.1 payment. Recipients MAY be in different ecosystems.
- Division is equal by default. Clients MAY offer custom weights through their own interface, but the grammar above is what MUST be parsed identically.
- Rounding MUST be deterministic: divide into integer satoshis, and allocate any remainder one satoshi at a time to recipients in the order given.
- Legs are independent and failure is partial. A resolution or delivery failure on one leg MUST NOT roll back the others. The client MUST report per-leg outcomes and MUST NOT report the command as succeeded unless every leg succeeded.
- All recipients MUST be resolved and displayed at confirmation before any leg is sent. Clients SHOULD warn when a split exceeds a configured number of legs, since fan-out multiplies both cost and disclosure.
/subscribe <recipient> <amount> <period>
Establish a standing payment executed by the sender's wallet on the stated period.
- This grants the recipient no pull authority. No certificate is issued, nothing is delegated, and the recipient cannot initiate. Each execution is an ordinary
/payperformed by the sender's own wallet. - The subscription is cancellable client-side at any time, and cancellation MUST take effect before the next scheduled execution without requiring the recipient's cooperation.
- Before each execution after the first, the client MUST re-resolve the recipient and apply the key-change rule of BRC-169 section 4.4, suspending the subscription and requiring confirmation if the identity key has changed.
- Where the amount is fiat-denominated it MUST be re-converted at each execution. The client MUST disclose at setup that the satoshi amount will vary, and SHOULD allow a satoshi ceiling above which execution pauses for confirmation.
- A client MUST maintain a visible list of active subscriptions with their next execution time.
/whois <recipient>
Resolve and display the attested identity without transacting: handle, domain, identity key, certificate status including the revocation check and the time it was performed, messagebox, whether the identity is in the user's address book, whether its key has changed since it was added, and any peer attestations per BRC-169 section 10.
/whoison a subhandle MUST return the base handle's identity, noting the queried tag, per BRC-169 section 3.1.- Unverified, host-supplied attributes such as a display name or avatar MUST be labeled as unverified.
/whoisMUST perform a fresh resolution rather than answering from cache, and MUST report the age of the revocation check it relied on.
/attest <recipient>
Publish a peer attestation of the recipient's handle to key binding, per BRC-169 section 10.3. The client MUST require a fresh, successful /whois-equivalent verification immediately before issuing, and MUST make clear at confirmation that the attestation is a public, signed statement that others may rely on.
/scope ( "everyone" / "contacts" / "ecosystem" / "toll" ) [ <recipient> ]
Set the reachability scope defined in BRC-169 section 8.1. The optional recipient argument, which MUST be a subhandle of the user's own handle, scopes the setting to that tag.
The command changes policy at the user's own messagebox. A client MUST confirm that the change was accepted by the messagebox before reporting success, and MUST warn that the messagebox, not the client, is the enforcement point.
/trolltoll [ <recipient> ] ( <amount> / "off" )
Set, change, or lift the per-message toll defined in BRC-169 section 8.2. With a recipient, the toll applies to that sender; without one, to everyone in scope. A recipient that is a subhandle of the user's own handle sets a per-tag toll.
- The toll is paid to the user, is due for every message each time, and is not refunded on reply.
- Setting a toll MUST NOT retroactively apply to quotes already issued and still valid, per BRC-169 section 8.3.
offlifts the toll for the named sender, or for everyone where no sender is named. Lifting a general toll does not lift per-sender tolls, and the client MUST say so.
/delegate <recipient> [scope] [amount] [duration]
Issue a delegation certificate to the recipient per BRC-169 section 9.1, where scope is a BRC-169 section 9.2 scope string, amount sets fields.perActionCap, and duration sets fields.expiry.
The confirmation MUST state, in plain language: which verbs are being granted, the per-action cap, the expiry, whether onward delegation is permitted, and, where a cumulative cap is set, whether it is actually enforced per BRC-169 section 9.3.3. A client MUST NOT describe a cumulative cap as guaranteed unless a principal-funded arrangement is in place.
Issuing * scope MUST require an additional, distinct confirmation.
/revoke <recipient> [serial]
Revoke a delegation certificate the user issued, by spending its revocation outpoint. Where the user has issued more than one certificate to the recipient and no serial is given, the client MUST list them and require a selection rather than guessing.
The client MUST report that revocation is detectable rather than instantaneous, and is subject to the indexing lag described in BRC-169 section 4.2. It MUST NOT report the delegate as unable to act until the spend is confirmed.
/handoff <recipient> [amount] [duration]
Issue a delegation certificate bound to the current thread, per BRC-169 section 9.7, with scope qualified by thread:<id> for the thread in which the command is issued.
The confirmation MUST state the thread being delegated, the per-action cap, and the expiry. Where amount is presented to the user as a spend limit, the client MUST apply BRC-169 section 9.3.3 and state explicitly whether the limit bounds total spend or only each individual action. A client MUST NOT use the words "hard cap", "maximum", or equivalent for a cumulative limit that is not principal-funded.
/sign
Countersign the message being replied to with the user's identity key, producing a BRC-3 signature over the canonical hash of that message's content, delivered into the same thread.
- The signature covers the message content as the signer received and displayed it. A client MUST show the exact content being signed at confirmation.
- Verifiers MUST check the signature against the signer's resolved identity key, per BRC-169 section 5.7.
- Multi-party document signing, counterparty ordering, and on-chain anchoring of a completed document are not specified here. See section 6.
/receipt
Request a signed acknowledgment for the message being replied to, or for the user's most recent message in the thread where the command is unbound. The counterparty's client, if it honours the request, returns a BRC-3 signature over the message hash together with a timestamp.
A receipt is voluntary. No client is obliged to honour a request, absence of a receipt means nothing, and clients MUST NOT present a missing receipt as evidence that a message was not delivered or not read.
The following verbs are reserved and MUST NOT be assigned by any ecosystem, but are not specified by this document. A conforming client MUST report them as unsupported rather than implementing local behavior under these names.
| Verb | Intended purpose | What a specification must settle |
|---|---|---|
/escrow |
Funds held against delivery, released or disputed | The script template, arbiter selection and discovery, the dispute and release protocol, timeout behavior, and what an arbiter attests to |
/bounty |
An open, claimable payment addressed to a room | Claim submission and adjudication, protection against front-running a claim, and release or expiry of unclaimed funds |
/poll |
Payment-gated voting | Vote aggregation, the auditability claim, protection against the poll operator discarding votes, and refund or forfeit of vote payments |
/gate |
An entry fee for a room or channel | A room and membership model, which BRC-169 does not define, plus fee custody and split policy |
/contract |
Multi-party document signing and anchoring | Party enumeration, signing order, partial-signature state, the canonical document hash, and the anchoring transaction format |
Each of these requires either a multi-party protocol or an on-chain construct that BRC-169 does not provide. Each is a candidate for its own BRC, which would extend this document by claiming its reserved verb.
- Global verbs, whether specified in section 5 or reserved in section 6, are reserved across all ecosystems. A custom verb MUST NOT shadow one.
- Where a collision occurs, including where a future revision of this document promotes a verb that an ecosystem had already claimed, clients MUST resolve it in favour of the global meaning and the ecosystem MUST rename its custom command.
- A client MUST NOT allow a user, a configuration file, or a plugin to rebind a global verb to different behavior. Aliases that expand to a global verb are permitted; redefinitions are not.
An ecosystem MAY define additional verbs and advertise them in the metanet.handles.commands array of its manifest (BRC-169 section 5.1), so that foreign clients can surface them contextually or explain why they cannot.
{
"verb": "gift",
"description": "Send a payment wrapped in an animated gift card.",
"args": [
{ "name": "recipient", "type": "recipient", "required": true },
{ "name": "amount", "type": "amount", "required": true },
{ "name": "design", "type": "word", "required": false }
],
"fallback": "payment",
"docs": "https://example.com/docs/gift"
}| Field | Requirement | Meaning |
|---|---|---|
verb |
MUST | The verb, per the verb rule of section 2. MUST NOT be a global verb. |
description |
MUST | One sentence, for display in autocomplete and help. |
args |
MUST | Ordered argument descriptors. May be empty. |
args[].type |
MUST | One of recipient, amount, duration, period, quoted, word, text, enum. |
args[].values |
MUST for enum |
Permitted values. |
fallback |
MUST | What a client that does not implement the verb should do: payment, message, or none. |
docs |
MAY | A URL documenting the command. |
- Custom commands MUST follow the section 2 grammar, the section 4 confirmation rules, and the section 7 precedence rule.
- A client MUST NOT execute a custom verb it does not implement. It MAY offer the declared
fallback:paymentmeans the equivalent plain/pay,messagemeans a plain/message, andnonemeans the command is unavailable outside its ecosystem. A fallback MUST be presented as a substitution and separately confirmed. - Descriptors are host-supplied and unattested. A client MUST render
descriptionanddocsas untrusted text, MUST NOT followdocsautomatically, and MUST NOT allow a descriptor to alter the confirmation requirements of section 4. - Commands advertised by one ecosystem apply to recipients of that ecosystem. A client MUST NOT offer a custom verb for a recipient whose domain does not advertise it.
Two illustrations. A wallet ecosystem might define /gift @r $x [design], wrapping a payment in an animated presentation for its own users while foreign clients fall back to a plain payment carrying the design as an attachment. A machine-to-machine ecosystem might define /charge 15kWh for device handles such as @charger-0042:voltnet, where a vehicle's agent pays a charging post through streamed payments under a thread-scoped delegation, with no account and no roaming contract.
Received text must never be executable. A chat client that parses commands out of incoming message content, memos, display names, or search results hands every counterparty the ability to spend the recipient's money. Section 2.4 forbids it absolutely. This extends to agents: an agent that reads a thread and acts on instructions found in it is executing counterparty-supplied commands, and MUST treat message content as data. Where an agent is intended to act on a counterparty's request, the action must still pass its delegation's scope and caps, and the request must be treated as a proposal rather than an instruction.
Agents are bounded by delegation, not by the client. Section 4.5 requires a delegation certificate for non-interactive execution because a client-side "auto-approve" toggle is unverifiable by anyone else and unenforceable once the agent holds keys. The exposure is what BRC-169 section 9.3 says it is: bounded per action, and bounded in total only where the principal funds each action. An agent granted /pay with a per-action cap and no principal funding can spend without limit until its certificate expires.
Confirmation is the last line of defence, and it is a human factors problem. Homoglyph handles, an alias that resolves somewhere unexpected, an autocomplete that fills a similar recipient, or a fiat amount whose satoshi value has moved are all things a user confirms without noticing. Sections 4.2 and 4.3 exist for this reason, along with the confusability rules of BRC-169 section 2.3. Clients should resist the temptation to make confirmation frictionless for value-moving commands.
Fan-out amplifies mistakes and disclosure. A /split across many recipients in several ecosystems performs many resolutions and many payments, discloses the sender's intent to every domain involved, and fails partially by design (section 5.5.3). A mistyped recipient in a long split is not recoverable.
Standing authority accumulates quietly. /subscribe grants no pull authority, which makes it safer than a card mandate, but it does create a recurring outflow that a user may forget. Section 5.6.5 requires a visible list. Fiat-denominated subscriptions vary in satoshi terms and can grow without any further user action, which is why 5.6.4 requires disclosure and recommends a ceiling.
Revocation is not immediate. /revoke spends an outpoint. Until that spend is confirmed and indexed by whatever source a counterparty consults, the delegate may still transact successfully. Section 5.12 requires the client to say so rather than implying the delegate has been cut off.
Custom command descriptors are attacker-influenced input. A hostile or compromised host can publish a descriptor whose description misrepresents what the command does. Section 8.3 requires descriptors to be treated as untrusted and forbids them from weakening confirmation. A client that renders a description as instructions to an agent has reintroduced the injection problem from a different direction.
Reserved verbs are reserved for a reason. A client that implements /escrow with locally invented semantics creates the exact interoperability failure this document exists to prevent, with funds at stake. Section 6 requires such verbs to be reported as unsupported.
- Every command in section 5 is implementable today against the BRC-169 stack and the reference
@bsv/sdkand@bsv/wallet-toolboxcomponents. No command in section 5 requires a mechanism that BRC-169 does not define, which was the criterion for including it here rather than reserving it in section 6. - A minimal conforming client implements the section 2 grammar, the section 4 confirmation rules, and
/pay,/message, and/whois. Everything else is independently optional, provided unimplemented verbs are reported as unsupported rather than repurposed. - Ecosystems adopting custom commands are encouraged to publish descriptors from launch, so that foreign clients can explain an unavailable command rather than failing silently.