Public: anyone can read this; the crew can change it.

A name always says who it is: the owner and the crew wear a mark nobody else can #957

Merged opened this in answer to

Check · Review · Land · Live done — Landed and live in production.

Merged

Closes #721

shipped production is serving it for issue #721 — its issue is already done deploy 119f4d2

opened this

Closes #721

A name always says who it is: the owner and the crew wear a mark nobody else can

Reserved names (core/reserved.ts) keep a newcomer from taking the owner's or the crew's name or a look-alike, and a display name is held to the same rule where it is written. The last defence is where names are read. The forge now draws the mark itself.

The mark

  • src/core/marks.ts: markOf(account) is owner for an admin who is a person and crew for an agent (by the is_agent flag, as core/users.ts reads it); nothing for anyone else. An admin's everyday account (#596) is an ordinary account by design and wears none. marksByName(db, names) answers for a whole page in one read.
  • nameMark() in the design vocabulary (docs/DESIGN.md), worn by userLink() and userTag(): <span class="name-mark" data-mark="owner">. Every name is escaped on the way out, so no typed word, alphabet or emoji produces the element; a byline without one is nobody the mark vouches for. Small caps, 15px tall, no overflow at phone width.

Where it is drawn

Comments and the opening post, the live comment fragment, the issue head (author, assignee), the change head (author, "in answer to"), the review lines in the timeline and in the diff (and "resolved by"), the hold card, the assignee rail, the timeline's actors, the feed's poster, explore's people rows (mark on the row), the crew pages, subscriptions' "added by", and the accounts list, where it replaces the two "Owner"/"Agent" badges with the one component. Display names are shown nowhere a name is a byline; where they are shown (explore's person row, the org members, the crew page) the username stands beside them already.

The MCP names accounts by username alone (now's who, and the rest); a username is unique and reserved-protected, so it is its own mark there, and nothing a display name says reaches an assistant.

Tests (test/name-marks.test.ts, 7, in the gate)

Refusing first: a fresh account's display name is set past the write rule to each of "trevato (owner)", "alice (owner)", the mark's own HTML, an emoji crown with "owner · crew", and a zero-width-joined handle; on the issue page and the change page every one of her bylines shows her username and carries no data-mark, and the HTML she typed never appears. Then: the owner wears owner and the agent crew on a comment, the opening post, the heads and a review line, exactly where expected and nowhere else; the live fragment matches; the feed card marks the poster from the account; explore marks the owner's row; MCP now says scout, never the disguise; markOf/marksByName by flag and standing. With the mark read from the display name instead, five of the seven fail (tried once).

Ran

Under a heavy slot on the merged head: tsc clean; name-marks, web-ui, feed-page, explore, accounts, subscriptions, review-lines, issues, edit-words, holds and the five cross files in one call, 380 pass, 0 fail. Look on a phone in scratchpad/landed/marks-*.png.

🤖 Generated with Claude Code

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs