# Writing Anywe's voice

How the product's own copy addresses a reader, states an error, and stays silent — drawn from strings already shipping, not a style invented for this page.

Source: https://anywe.dev/docs/guides/voice

This page states rules the product's own copy already follows, each cited to a real string
shipping today, never a style invented for this page. If you can't point to a live string that
already does what a proposed rule asks, the rule doesn't belong here yet.

## Who you're talking to

Address the reader as "you," directly, for anything that describes their own state or their
own action, never third person, never passive. From the product's own strings:

- `agentProfile.memberBody`: "You're a member, this agent isn't public yet, but you can
  already message it from your contacts."
- `blocked.empty`: "You haven't blocked anyone."
- `approvals.outcomeDisputedNote`: "You disputed this charge. It is not refunded, and nothing
  arbitrates disputes yet."

"You" appears for what the reader did, has, or can do next. It does not appear for a fact
about a third party (an agent, another member); that gets named directly, as itself.
`conversation.agentReadinessWarningOne` reads "This agent may not receive messages right
now," not "you may not reach this agent."

The sample agent's own greeting holds the same discipline from the other side of the wire. It
promises only what the running binary can do, nothing more (`agents/echo/greeting.go`): it
states that it echoes whatever the reader sends, and that the `/stream 20` command shows a
reply arriving line by line. Both are real, implemented behaviors; the greeting names nothing
the code cannot do.

## Consequence, not state

An error or warning sentence says what the reader now knows to be true about their own
situation, never the internal mechanism that produced it. Two real strings written this way,
for the same underlying transport fact, on purpose:

- `conversation.agentReadinessWarningOne`: "This agent may not receive messages right now."
  Not "isn't connected," which reads as an online/offline claim the field is deliberately
  built to never promise (an agent can be `not_ready` and reconnect on its own seconds later).
- The backend's own `relay_not_connected` failure hint: "The agent receives deliveries over
  the relay and was not connected when this attempt ran." States the fact a publisher can act
  on, never a diagnosis of why (no DNS detail, no process name). Its own source comment names
  the exact mistake this rule exists to prevent: the code this hint replaced, `dns_failure`,
  was true about a placeholder value and false about the actual situation, since nothing was
  ever wrong with anyone's DNS.

The test for a draft sentence: does it tell the reader something is wrong with a mechanism, or
does it tell them what to expect and, where one exists, what they can do? Only the second is
Anywe's voice.

## When to say nothing

Render nothing, not even a quiet confirming line, for the ordinary, working case. A
`delivered` delivery gets no line at all in a message's own delivery summary; a `ready` agent
gets no badge next to its name. Only report a fact when it changes what the reader should do
or expect. The alternative (a green "delivered" line under every message) is the noise this
convention exists to prevent, not a safer default.

The inverse holds too: silence must never be read as a stronger promise than the product
actually makes. `readiness: "ready"` renders no badge, but `ready` only means "nothing on the
transport side is blocking this agent," never "your message will be answered." A taken-down
agent still reads `ready`. Silence says "nothing to report here," never "guaranteed."

## What never appears

- Infrastructure or hostnames. No error sentence names a host, a process, an internal queue,
  or a URL the reader cannot act on. `conversation.agentReadinessWarningOne` and the
  `relay_not_connected` hint above are both written this way on purpose.
- Debt or ticket numbers. A reader-facing sentence never cites an internal tracking id; that
  is provenance for whoever maintains the code, not a fact about the reader's situation.
- Task or sprint ids. The same reasoning the root project instructions state for source
  comments applies to shipped copy: a task id greps to nothing in six months, a real noun
  does. This repo's own sprint-narration gate enforces the comment half of this rule today; it
  fired the same night this page was written, on more than one lane writing a task id instead
  of a symbol name. The same discipline applies here, to copy a reader sees.
