The copy was written for someone who had read the spec. It named UTF-8, RFC 3339, canonical form, code points and frontmatter fields, and the one place it gave instructions it gave them as fumi command lines, which say nothing to anyone using carrier or gsmol. Now it uses the words the clients put on screen: "header", with the "+ header" button both of them have, and "Requests folder", which is what both call it. One word per idea throughout — post, feed, header, Requests folder — and reasons are whole sentences that say what happened and what to do, so the reply no longer opens "Reason:" followed by a lowercase fragment. The first-contact mail is the one a stranger reads before anything else, so it now covers accepting this address: a recommendation, not the mechanism behind it. The mechanism would also have aged badly, since a client that delivers its token once makes accepting cost a single refused post rather than all of them. A refused post gets a detail paragraph where one line cannot hold the fix. It tells the author their token arrived and to send again, and what to do if it is refused a second time, which is what happens on a client that attaches the token to everything. A first post on an empty feed says so differently: the author is watching their first attempt fail and needs to hear the feed is fine. Seven admin strings were built with format! and never reached the catalogue, so an ack opened its body in lowercase and could not be translated. They are entries now, and say what blocking does rather than naming the mechanism. The cap warning said "90% of its 1048576 byte limit". It says 1 MB. Four rig assertions matched the old wording and now match the new. They have to read rendered mail, so they stay coupled to it in a way the unit tests, which assert on Reason variants, do not.
201 lines
8.5 KiB
Text
201 lines
8.5 KiB
Text
## Every string the daemon mails to an author. Operator CLI output is not
|
|
## here, deliberately: see the i18n module header.
|
|
##
|
|
## House style, in short. Write to "you" and use contractions. Sentence case.
|
|
## Start with a verb where you can. Say what happened and what to do next,
|
|
## without blaming anyone and without the words invalid, illegal or fatal.
|
|
## Use the words the clients use: "header", not frontmatter field; "Requests
|
|
## folder", not requests tier; "post", not record, twt or entry. No em dashes.
|
|
##
|
|
## These are read in plain-text mail clients and on phones, so keep lines
|
|
## short and leave markup out.
|
|
|
|
## Replies about a message we couldn't publish
|
|
|
|
reply-subject = twtxt: { $reason }
|
|
reply-body =
|
|
{ $reason }
|
|
|
|
Here's the message:
|
|
{ $quoted }
|
|
|
|
## Reasons. Each one is a whole sentence: it becomes the subject line, and
|
|
## the body opens with it.
|
|
##
|
|
## Each MUST be a single line, however long. A reason goes into a mail header,
|
|
## and a line break there breaks the whole header block, so the reply arrives
|
|
## with no subject at all. Fluent keeps the newlines in a wrapped value, so
|
|
## there's no safe way to wrap these. `every_reason_is_a_single_line` checks
|
|
## it. When the fix needs more room, put it in a detail paragraph below.
|
|
|
|
reason-body-not-utf8 = We couldn't read the text in this message. Try sending it again.
|
|
reason-post-not-canonical = We couldn't rebuild this message exactly as you sent it, so we can't prove it's yours. Send the text on its own.
|
|
reason-repost-not-canonical = We couldn't rebuild this repost exactly as you sent it. Send it again with only the Twt-Repost header.
|
|
reason-fields-beyond-reply-to = This post carries extra headers. Send it again with just the text.
|
|
reason-nick-invalid = A nick can use a-z, 0-9 and hyphens, up to 30 characters.
|
|
reason-delete-needs-timestamp = Twt-Delete needs the time of the post to remove, like 2026-10-14T19:39:39Z.
|
|
reason-prune-mode-unknown = Twt-Prune takes fifo or off, not "{ $got }".
|
|
|
|
## Limits on what a post can contain
|
|
|
|
reason-too-many-codepoints = A post can be up to 160 characters. Shorten it and send it again.
|
|
reason-too-many-bytes = A post can be up to 640 bytes, and accents and emoji use several each. Shorten it and send it again.
|
|
reason-forbidden-char = A post has to fit on one line. Take out the line breaks and tabs, then send it again.
|
|
reason-bad-timestamp = That isn't a time we can read. Use the form 2026-10-14T19:39:39Z.
|
|
reason-duplicate-timestamp = Your feed already has a post at that time.
|
|
|
|
## Quota and retention
|
|
|
|
reason-over-quota-post = You've reached today's limit for posts. Try again tomorrow.
|
|
reason-over-quota-repost = You've reached today's limit for reposts. Try again tomorrow.
|
|
reason-collision = Your feed already has a post at { $timestamp }. Wait a second, then send it again.
|
|
reason-feed-full = Your feed is full. Remove a post with Twt-Delete, or send Twt-Prune: fifo to drop the oldest ones from now on.
|
|
reason-reply-to-changed = This feed belongs to { $author }. Send your posts from that address.
|
|
reason-no-record-at = Your feed has no post at { $timestamp }.
|
|
|
|
## Commands
|
|
|
|
reason-one-command-per-mail = Send one command per message. Twt-Register, Twt-Help, Twt-Admit, Twt-Block and Twt-Registration each need their own, and feed commands need another.
|
|
reason-bad-address = "{ $got }" isn't a smolmail address.
|
|
reason-registration-mode-unknown = Twt-Registration takes open, closed or silent, not "{ $got }".
|
|
|
|
## An accept token in a post. The author didn't do anything wrong: their
|
|
## client added the token because they accepted this address. The fix depends
|
|
## on which client they use, so it goes in a detail paragraph.
|
|
|
|
reason-accept-field-on-post = A post can't carry the accept token your client attached.
|
|
reason-accept-field-on-first-post = Your first post carried an accept token, which we can't publish.
|
|
|
|
## Detail paragraphs, added to the end of the reply when one line isn't
|
|
## enough room for the fix. Most reasons don't need one.
|
|
|
|
reason-accept-field-on-post-detail =
|
|
|
|
We publish your post by rebuilding exactly what you signed, so anyone can
|
|
check it was you. A token can't be part of that.
|
|
|
|
We've got your token now, so send the same post again and it should go up.
|
|
|
|
If it's refused again, your client is adding the token to every message
|
|
instead of sending it once. Block this address in your client and send
|
|
the post again. Blocking only moves our replies back to your Requests
|
|
folder.
|
|
|
|
reason-accept-field-on-first-post-detail =
|
|
|
|
Your feed is fine. It's there and it's waiting for its first post.
|
|
|
|
We publish your post by rebuilding exactly what you signed, so anyone can
|
|
check it was you. A token can't be part of that.
|
|
|
|
We've got your token now, so send that post again and it should go up.
|
|
|
|
If it's refused again, your client is adding the token to every message
|
|
instead of sending it once. Block this address in your client and send
|
|
the post again. Blocking only moves our replies back to your Requests
|
|
folder.
|
|
|
|
## Warning as a feed fills up
|
|
|
|
cap-warning-subject = twtxt: your feed is nearly full
|
|
cap-warning-body =
|
|
Your feed has reached 90% of its { $cap } limit.
|
|
|
|
When it's full, new posts are refused. Remove some with Twt-Delete, or
|
|
send Twt-Prune: fifo and we'll drop the oldest ones to make room.
|
|
|
|
## The mail that hands over the accept token
|
|
|
|
welcome-subject = twtxt: your feed is ready
|
|
welcome-body =
|
|
Your feed is live: { $url }
|
|
|
|
Send a message to this address and it becomes a post.
|
|
|
|
To manage your feed, add one of these headers: Twt-Nick, Twt-Delete,
|
|
Twt-Repost or Twt-Prune. Send Twt-Help for what each one does.
|
|
|
|
## First contact from someone who doesn't have a feed
|
|
|
|
info-subject = twtxt: how to get a feed
|
|
info-body =
|
|
You can publish a twtxt feed here by sending mail.
|
|
|
|
To get one, send a message to this address with this header:
|
|
|
|
Twt-Register: yournick
|
|
|
|
Headers sit next to the subject in most clients, often behind a button
|
|
marked "+ header". Leave the value empty and we'll use your username.
|
|
|
|
Our reply arrives in your Requests folder, not your inbox, because you
|
|
haven't accepted this address. We recommend leaving it that way.
|
|
|
|
We publish nothing until you ask, and this is the only mail you'll get
|
|
until you do.
|
|
|
|
## First contact while registration is closed
|
|
|
|
info-closed-subject = twtxt: we're not taking new feeds
|
|
info-closed-body =
|
|
Thanks for writing. We're not taking new feeds right now, so there's
|
|
nothing to do here yet.
|
|
|
|
Nothing was published and nothing was kept.
|
|
|
|
## Twt-Help
|
|
|
|
help-subject = twtxt: your commands
|
|
help-body =
|
|
Your feed: { $url }
|
|
|
|
Send a message to this address and it becomes a post. We publish exactly
|
|
what you write, up to 160 characters, on one line.
|
|
|
|
To manage your feed, add one of these headers. One per message.
|
|
|
|
Twt-Nick: yournick change the name shown on your feed
|
|
Twt-Delete: <time> remove one post or repost
|
|
Twt-Repost: <mention> <#id> share someone else's post
|
|
Twt-Prune: fifo | off what happens when your feed fills up
|
|
Twt-Help: send this list again
|
|
|
|
help-admin-section =
|
|
|
|
You're an admin here, so you can also send:
|
|
|
|
Twt-Admit: user@host give someone a feed
|
|
Twt-Block: user@host stop someone posting
|
|
Twt-Registration: open | closed | silent
|
|
|
|
## Admin notifications
|
|
|
|
admin-notify-subject = twtxt: new feed { $slug }
|
|
admin-notify-body =
|
|
Someone registered a feed.
|
|
|
|
Address: { $address }
|
|
Feed: { $url }
|
|
Fingerprint: { $fingerprint }
|
|
|
|
If you don't know this person, check that fingerprint with them some
|
|
other way. Send Twt-Block to stop them posting.
|
|
|
|
## What an admin command did. These are sentences on their own: they become
|
|
## the subject and open the body.
|
|
|
|
admin-admitted = Gave { $address } a feed at { $url }.
|
|
admin-admit-failed = Couldn't give { $address } a feed. { $detail }
|
|
admin-blocked = Blocked { $address }. Their posts won't go up from now on.
|
|
admin-block-unknown = { $address } wasn't accepted here, so there was nothing to block.
|
|
admin-block-failed = Couldn't block { $address }. { $detail }
|
|
admin-block-half-done = Blocked { $address } here, but the server still has their token, so their posts may still go up. { $detail }
|
|
admin-registration-open = Anyone can register a feed now.
|
|
admin-registration-closed = Registration is closed. People who write in are told so.
|
|
admin-registration-silent = Registration is closed and people who write in get no reply.
|
|
|
|
admin-ack-subject = twtxt: { $what }
|
|
admin-ack-body =
|
|
{ $what }
|
|
|
|
You're getting this because you're an admin here.
|