Skip to main content

User profile

Your fingerprint claims your aim.

Your profile is the record of everything you've contributed to the tree. It shows your lore rank, your earned specializations (divs), your activity history, and every topic and branch you've published. It is the structured fingerprint on the web that an agent reads before your work.

A profile reads in four layers. Identity says who you are. Standing says what the community recognizes in you. Activity shows the work behind it. Your library is the private side, visible only to you. An agent reads the same layers from Public files, without a session.

flowchart TD
ID["1. Identity<br/>header, bio, linked accounts"] --> ST["2. Standing<br/>Lore, Voting Power,<br/>tiles and divs"]
ST --> AC["3. Activity<br/>matrix and log"]
AC --> LB["4. Library<br/>bookmarks, notifications<br/>private to you"]
ST --> PF["Public files<br/>what an agent reads"]
AC --> PF

The lore rank on a profile is {tier} {score}, at /u/{handle}. Formula and tiers stay in Rank. The relevance vote is in Relevance vote. Energy is in Energy. Downloads, field names, and the noname examples are in Public files.

SurfacePathWho
Profile/u/{handle}Anyone
Bookmarks/bookmarksThe signed-in user
Notifications/notificationsThe signed-in user. The list is not built yet.

1. Identity​

Identity is the part of the profile that exists before any work: a name, a handle, a short bio, and the accounts behind them.

The public handle is x_handle, then google_handle, then github_handle. The profile URL and the @handle in the header use that same value.

Own profile adds the options menu. A visitor sees the same identity row without it.

PieceOn screenRule
AvatarLeft of the nameImage, or a generated mark from the handle
NamePage titleusers.name, then the handle. The hover card uses display_name, then name, then the handle
X PremiumBeside the nameShown when x_premium is true
HandleUnder the name@{handle}
XIconShown when x_handle is set. Opens https://x.com/{x_handle}
GitHubIconShown when github_handle is set. Opens https://github.com/{github_handle}
LoredivIconLinks to /
OptionsOwn profileEdit bio, Settings, Delete account, Log out

Settings opens account linking. Edit bio turns on the bio fields. Log out asks for confirmation. Delete account is in the menu; the profile header does not pass it a handler. Google can be the public handle and has no icon in this row.

Bio​

FieldEditLimit
BioOwn profile200 characters. Placeholder: BIO. Share a bit about yourself.
LocationOwn profileFree text
SiteOwn profileFree text
JoinedRead only{Month Year} in UTC

Save calls auth.updateProfile with bio, location, and site. Cancel restores the saved values. A visitor sees the same fields read only. The character count is on your own profile.

Linked accounts​

Settings is the linking modal. A link runs in an OAuth popup. X, Google, and GitHub are the three providers.

ProviderPublic iconCan connectCan disconnectPrimary
X (Twitter)Yes, when linkedWhen x_handle is emptyNoWhen X is linked
GoogleNoWhen Google is not linkedYesWhen X is absent and GitHub is absent
GitHubYes, when linkedWhen GitHub is not linkedYesWhen X is absent

A vote still requires one of these sign-ins. That rule is in Rank.

Hover card​

An avatar opens a card. It shows name, handle, X and GitHub when those handles exist, bio, joined date, Voting Power, Lore, divs, topic count, and branch count. Open profile goes to /u/{handle}.


2. Standing​

Standing is what the community has recognized in you. Two plates sit side by side and measure different things. Lore is recognition you earned. Voting Power is energy you can spend. Casting a vote spends energy and does not raise your rank. Votes you receive add to both. Six tiles beside the plates count the work and name your divs.

Lore​

Label Lore. The number is formatReputationRank of Received, for example Wizard 6.1. The bar fills the current tenth. At 9.9 the bar is full.

SideText
LeftCurrent tier range, such as 3.2 – 5.4
Right{n} to next, or Max at 9.9

n is the Received points still required for the next tenth.

Title tooltip: Public rank from Received. Score 1.0–9.9 across four tiers. The link explore more... goes to /community. The tooltip table is Range and Tier for Newbie, Geek, Wizard, and GOAT. Those ranges are the tier table in Rank.

Voting Power​

Label Voting Power. The number is the current balance. The bar splits the month into the remaining monthly grant, energy earned above that grant, and the empty remainder. Footer: {used} used / {votes} votes and Reset in {n}d.

Title tooltip: Energy to vote. Resets on the 1st of each UTC month. The link explore more... goes to /community.

EventEnergy
1st of month+31
Vote received+1
100 votes in 48h+130
Idle day−1%

The bar tooltip lists remaining, earned, used this month, idle decay, the monthly grant, and the max for this month. The pool resets on the 1st UTC. A high rank does not add energy. The full pool rules are in Energy.

Tiles​

Six tiles sit beside the two plates. Counts use grouped digits. Topic, branch, Received, and active-day figures are lifetime totals. The matrix below them is one UTC year.

TileNumberHint
TopicsAuthored topicsCount of authored topics.
BranchesProposed branchesCount of branches.
VotesBranch and relevance votes castCount of branch and relevance votes cast. Owner-only.
ReceivedNet of community votes on shared workNet points from community votes on shared content.
Active daysDays with a topic, a branch, or (on your own profile) a voteTotal active days since joining.
Last activetoday, 3d through six days, otherwise Sep 8Latest UTC day with a topic or a branch. On your own profile a vote counts too.

The Votes tile is on every profile. A visitor sees 0. On your own profile the count includes your cast votes, and active days include days you voted.

Last active shows — when there is no topic or branch. The hover shows the full date. On your own profile the day can be a vote.

The share on one row of work splits across its tags in order. One tag takes the whole count. Two tags split 6:3. Three tags split 6:3:1. The first tag is primary, the second secondary, the third tertiary. Authored topics contribute their relevance score. Proposed branches on someone else's topic contribute the vote count on that branch. The profile keeps the top ten tags.


3. Activity​

Activity is the evidence for standing. The matrix shows when you contributed. The log lists the work itself, with filters.

Activity matrix​

Title Activity. The year control runs from the join year through the current UTC year, and only appears when that span is longer than one year. The current year leaves ?year= off the URL. The count reads {n} contributions in {year}: topics, branches, and, on your own profile, votes in that year.

The grid is the UTC year. Columns are weeks. The first column is the Sunday on or before 1 January. Cells outside the year are empty. Month labels are Jan through Dec, and a label is skipped when it would sit on the column next to the previous one.

Day totalLevel
1–21
3–52
6 or more3

The join day is marked Joined. A cell tooltip lists Joined, votes, topics, branches, and the UTC date. Vote counts appear on your own profile. A visitor's year has topics and branches.

Under the grid, a curve traces a 7-day mean of those same day totals. The plot sits on the activity plate. The area under the line fades from the accent color to clear. A vertical line marks the first day of each month. The month names stay on the grid.

Log​

Three tabs. Page size is 10. The tab count is the grouped list: distinct topics, not raw branch or vote rows. Until that tab has loaded, Topics uses the topic total, Branches uses the number of topics you proposed on, and Votes uses the number of topics you voted on.

TabWhoExtra filtersNote in the menu
TopicsAnyoneSort, type, tags
BranchesAnyoneSort, type, tags, Others' topics, Own topicsThe last scope stays on
VotesOwn profileSort, type, tags, Topics, BranchesVotes are only visible to you. The last kind stays on

Sort is Newest, Oldest, or Most voted. Type is All types plus /post, /ask, /proposal, /poll, /prediction, /context, /argument, /graph. Tags are All tags plus /{slug} from that user's topics, with a filter field. Reset all restores Newest, all tags, all types, both scopes, and both kinds.

The navbar search filters this list. It does not change the tiles or the matrix. Changing the year reloads the summary and leaves the log where it is.

QueryWritten when
yearA year other than the current UTC year
tabbranches or votes. Topics omits it. #proposals opens Branches.
pagePage greater than 1
sortoldest or most-voted
tagsA subset of tags
typeA subset of types
scopeown or other
kindtopic or branch on the Votes tab

Opening the profile loads identity, the activity summary, the first Topics page, Voting Power, and Lore. A later tab, page, sort, tag, type, or search loads that log page only.


4. Your private library​

Bookmarks and notifications sit on the same tabs as the profile, and only the signed-in user sees them. Neither is a public file.

Bookmarks​

/bookmarks is the signed-in user's library. A guest who opens it gets the sign-in modal. A bookmark is a private save. Saving the topic and saving one branch are separate. The number on a card is the public bookmark_count. The list itself stays off /u/{handle}.md and /u/{handle}.json. The library uses the same cards and the same page size as the log. The menu adds the note Bookmarks are only visible to you.

FilterChoices
SortNewest, Oldest, Most voted
ShowOthers' topics, Own topics, Topics, Branches
TypeAll types, then each topic type
TagsAll tags, then each tag

The last scope stays on, and the last of Topics or Branches stays on.

Notifications​

/notifications sits on the same tabs as Bookmarks. A guest who opens it gets the sign-in modal. The list is not built yet. The empty screen says Notifications coming soon, and the line under it is A daily digest of votes, replies, and updates on what you own or saved. Search does nothing here. There is no public file.


Public files​

The screen is for people. These files are for agents: the same fingerprint as stable, cacheable Markdown and JSON.

The screen stays /u/{handle}. Two downloads sit beside it. The metrics file is the index. A div file is the topic list for one tag. Examples below use the handle noname.

The grid on the screen is one UTC day. The metrics file rolls the current UTC year into months and each earlier year into one total.

Requests​

RequestReturns
GET /u/nonameThe screen. year, tab, page, sort, tags, type, scope, and kind filter the log on the screen.
GET /u/noname.mdMetrics markdown. The log query is ignored.
GET /u/noname.jsonMetrics JSON. The log query is ignored.
GET /u/noname and Accept: text/markdownThe metrics markdown.
GET /u/noname and Accept: application/jsonThe metrics JSON.
GET /u/noname/div/agents.mdTopics noname authored under the tag agents. Page 1.
GET /u/noname/div/agents.jsonThe same list as JSON.
GET /u/noname/div/agents.json?page=2Page 2. Page 1 omits ?page=.
GET /u/noname/div/{tag}.mdSubstitute {tag} from divs[].tag into div_md.

A missing handle is 404 with the body Not found. A tag that is empty after normalization, or longer than 40 characters, is 404. A tag that normalizes and has no topics is 200 with total 0 and an empty topics array. Normalization keeps lowercase letters and digits and drops everything else, including hyphens. GET /u/noname/div/{tag}.json therefore requests the tag tag and can be that empty 200. The value in divs[].tag is the value to put in the path.

A missing, non-numeric, or sub-1 page is page 1. A page past the end is 200. total stays the real count and topics is empty.

tab=votes is the owner’s log on the screen. It is not a public file. A cookie does not change either file.

Markdown and JSON send Cache-Control: public, s-maxage=60, stale-while-revalidate=300 and a Link header (alternate, and describedby pointing at /llms.txt). A div file also sends rel="up" to the metrics markdown. Negotiated HTML sends Vary: Accept. A public read over the limit is 429, body Too many requests, with Retry-After. The cap is 60 requests a minute per IP. If Redis is down, that same cap still applies in memory on the server. The screen for a profile, a topic, a tag, the feed, and community uses this cap before it queries the database.

Topics with status open, closed, and archived are included. There is no draft and no private topic.

Name, bio, location, site, and a div topic title are user text. Markdown writes each as one line: line breaks, control characters, bidi marks, and zero-width characters are removed, and a line that would open a heading, list, quote, or fence is escaped. A title used as a link label also drops [ and ]. JSON keeps the stored string. image is the avatar URL. Reading the file does not include fetching it. A site saved from the profile form must be an http or https URL. The file prints it as text. Rank thresholds are in Rank and on /reputation.md.

Votes cast, bookmarks, voter identities, and google_handle stay off both files. The metrics file does not list topics or branch letters.

Metrics fields​

schema_version is "1" on every public file.

FieldMeaning
handlePublic handle. Order on the screen is x_handle, then google_handle, then github_handle.
namedisplay_name, then name, then the handle.
bioProfile bio, or null.
locationProfile location, or null.
siteProfile site, or null.
imageAvatar URL, or null. It is not a document. Do not fetch it while reading this file.
joinedAccount creation time, ISO UTC.
htmlScreen path, /u/noname.
mdMetrics markdown path.
jsonMetrics JSON path.
div_mdOne pattern for every div. {tag} is the placeholder.
div_jsonJSON twin of div_md.
x_handleX handle, or null.
github_handleGitHub handle, or null.
statsMeaning
topicsAuthored topics, lifetime.
branchesProposed branches, each letter, lifetime.
receivedSigned vote net. The Lore plate reads this net.
active_daysDays with a public topic or a public branch. The owner’s screen can also count days they voted. The file uses this public count.
last_activeLatest UTC day YYYY-MM-DD with a public topic or branch, or null. A vote day stays off the file. The owner’s screen can show a later vote day.
voting_powerEnergy left to cast. A high rank does not add energy.
loreLowercase tier: newbie, geek, wizard, goat.
rankScore from 1.0 to 9.9. On the screen the plate is {Tier} {rank}, for example Wizard 5.5.

topics_by_type lists every type, including zeros, in this order: post, ask, proposal, poll, prediction, context, argument, graph. n is the authored count.

divs[]Meaning
tagStored tag. This is the only path token. There is no md or json on the row.
topicsAuthored topics that carry this tag. One topic has three tags, so it is counted in three divs.
earnedShare from the 6:3:1 split. 0 when the tag is only an authored tag and is outside the top ten.

Rows are sorted by topics descending, then earned descending, then tag. To download, replace {tag} in div_json. agents becomes /u/noname/div/agents.json.

earned counts authored topics and branches this user proposed on someone else’s topic. It can be above 0 when topics is 0. Those branches are not listed in the div file, and they have no profile URL. Summing topics across divs counts each authored topic three times. A full list dedupes by topic id. Summing received on div rows does not equal stats.received. stats.branches is the branches this user proposed. topics[].branches is every branch on that topic.

matrixMeaning
current_yearUTC year of the request.
monthsYYYY-MM rows for that year that have a topic or a branch. Ascending. topics and branches are counts created in that month.
yearsOne total per earlier year, newest first. JSON sends [] when there is no earlier year. Markdown omits the Earlier years heading in that case.

A year with no months renders No public topic or branch months in this year.

Metrics markdown​

---
schema_version: 1
handle: noname
html: /u/noname
json: /u/noname.json
div_md: /u/noname/div/{tag}.md
div_json: /u/noname/div/{tag}.json
---

# No Name

Public notes under one handle.

Joined: 2024-03-02T00:00:00.000Z

X: @noname

## Stats

- Topics: 6
- Branches: 14
- Received: 57
- Active days: 9
- Last active: 2026-09-04
- Lore: wizard
- Rank: 5.5
- Voting power: 18

## Topics by type

- post: 2
- ask: 1
- proposal: 2
- poll: 0
- prediction: 1
- context: 0
- argument: 0
- graph: 0

## Divs

- agents — 3 topics, earned 12
- design — 2 topics, earned 6
- notes — 1 topic

## Matrix

### 2026

- 2026-02 topics=2 branches=4
- 2026-09 topics=1 branches=2

### Earlier years

- 2025 topics=3 branches=8

earned is omitted on the line when it is 0. notes is that case.

Metrics JSON​

{
"schema_version": "1",
"handle": "noname",
"name": "No Name",
"bio": "Public notes under one handle.",
"location": null,
"site": null,
"image": null,
"joined": "2024-03-02T00:00:00.000Z",
"html": "/u/noname",
"md": "/u/noname.md",
"json": "/u/noname.json",
"div_md": "/u/noname/div/{tag}.md",
"div_json": "/u/noname/div/{tag}.json",
"x_handle": "noname",
"github_handle": null,
"stats": {
"topics": 6,
"branches": 14,
"received": 57,
"active_days": 9,
"last_active": "2026-09-04",
"voting_power": 18,
"lore": "wizard",
"rank": 5.5
},
"topics_by_type": [
{ "type": "post", "n": 2 },
{ "type": "ask", "n": 1 },
{ "type": "proposal", "n": 2 },
{ "type": "poll", "n": 0 },
{ "type": "prediction", "n": 1 },
{ "type": "context", "n": 0 },
{ "type": "argument", "n": 0 },
{ "type": "graph", "n": 0 }
],
"divs": [
{ "tag": "agents", "topics": 3, "earned": 12 },
{ "tag": "design", "topics": 2, "earned": 6 },
{ "tag": "notes", "topics": 1, "earned": 0 }
],
"matrix": {
"current_year": 2026,
"months": [
{ "month": "2026-02", "topics": 2, "branches": 4 },
{ "month": "2026-09", "topics": 1, "branches": 2 }
],
"years": [
{ "year": 2025, "topics": 3, "branches": 8 }
]
}
}

Div fields​

GET /u/noname/div/agents.json returns the topics in that div.

FieldMeaning
tagThe div that was requested.
profile_mdMetrics markdown for this handle.
profile_jsonMetrics JSON for this handle.
mdThis page. Page 2 appends ?page=2.
jsonJSON twin of md.
pagePage number. The first page is 1.
page_size10.
totalAuthored topics in this div.
total_pagesceil(total / 10), at least 1.
prev{ "md", "json" } for the previous page, or null.
next{ "md", "json" } for the next page, or null.
topicsThe page of topics, newest first.
topics[]Meaning
idTopic id.
titleTopic title.
path/topics/{type}/{slug}. The topic file is path.json.
typepost, ask, proposal, poll, prediction, context, argument, or graph.
branchesHow many branches that topic has. On the topic file, branches is the array.
receivedThat topic’s relevance_score. The topic file calls the same number vote.

Div markdown​

---
schema_version: 1
handle: noname
tag: agents
page: 1
json: /u/noname/div/agents.json
profile: /u/noname.md
---

# agents

Topics by [@noname](/u/noname.md) in this div. Page 1 of 1 (3).

- [Field notes on public rank](/topics/post/field-notes-on-public-rank) (`post`) id=`00000000-0000-4000-8000-000000000001` branches=2 received=4
- [Where should the div live](/topics/ask/where-should-the-div-live) (`ask`) id=`00000000-0000-4000-8000-000000000002` branches=5 received=9
- [Ship the metrics file first](/topics/proposal/ship-the-metrics-file-first) (`proposal`) id=`00000000-0000-4000-8000-000000000003` branches=3 received=6

An empty div uses the same frontmatter and the line None.

Div JSON​

{
"schema_version": "1",
"handle": "noname",
"name": "No Name",
"tag": "agents",
"profile_md": "/u/noname.md",
"profile_json": "/u/noname.json",
"md": "/u/noname/div/agents.md",
"json": "/u/noname/div/agents.json",
"page": 1,
"page_size": 10,
"total": 3,
"total_pages": 1,
"prev": null,
"next": null,
"topics": [
{
"id": "00000000-0000-4000-8000-000000000001",
"title": "Field notes on public rank",
"path": "/topics/post/field-notes-on-public-rank",
"type": "post",
"branches": 2,
"received": 4
},
{
"id": "00000000-0000-4000-8000-000000000002",
"title": "Where should the div live",
"path": "/topics/ask/where-should-the-div-live",
"type": "ask",
"branches": 5,
"received": 9
},
{
"id": "00000000-0000-4000-8000-000000000003",
"title": "Ship the metrics file first",
"path": "/topics/proposal/ship-the-metrics-file-first",
"type": "proposal",
"branches": 3,
"received": 6
}
]
}

Page 2​

noname’s agents div fits on one page, so next is null. When a div has 11 topics, GET /u/noname/div/agents.json?page=2 returns one row and points back at page 1. Page 1 would set next to the ?page=2 paths. The shape is:

{
"schema_version": "1",
"handle": "noname",
"name": "No Name",
"tag": "agents",
"profile_md": "/u/noname.md",
"profile_json": "/u/noname.json",
"md": "/u/noname/div/agents.md?page=2",
"json": "/u/noname/div/agents.json?page=2",
"page": 2,
"page_size": 10,
"total": 11,
"total_pages": 2,
"prev": {
"md": "/u/noname/div/agents.md",
"json": "/u/noname/div/agents.json"
},
"next": null,
"topics": [
{
"id": "00000000-0000-4000-8000-00000000000b",
"title": "Eleventh note",
"path": "/topics/post/eleventh-note",
"type": "post",
"branches": 1,
"received": 0
}
]
}
---
schema_version: 1
handle: noname
tag: agents
page: 2
json: /u/noname/div/agents.json?page=2
profile: /u/noname.md
---

# agents

Topics by [@noname](/u/noname.md) in this div. Page 2 of 2 (11).

Previous: [/u/noname/div/agents.md](/u/noname/div/agents.md)

- [Eleventh note](/topics/post/eleventh-note) (`post`) id=`00000000-0000-4000-8000-00000000000b` branches=1 received=0

Code​

ScreenFile
Profile pageapps/frontend/src/components/profile/UserProfile.tsx
Header and menuapps/frontend/src/components/profile/ProfileHeader.tsx
Bioapps/frontend/src/components/profile/BioCard.tsx
Account linkingapps/frontend/src/components/ui/AccountLinkingModal.tsx
Plates and matrixapps/frontend/src/components/profile/ActivityMatrix.tsx
Voting Powerapps/frontend/src/components/profile/VotingPower.tsx
Loreapps/frontend/src/components/profile/ReputationLevel.tsx
Year gridapps/frontend/src/lib/year-grid.ts
Summary countsapps/frontend/src/server/lib/profile-activity-summary.ts
Divs shareapps/frontend/src/server/lib/specialty-share.ts
Logapps/frontend/src/components/profile/HistoricalLog.tsx
Log filtersapps/frontend/src/components/profile/HistoricalLogMenu.tsx
Profile URLapps/frontend/src/lib/profile-url.ts
Metrics and div filesapps/frontend/src/lib/profile-document.ts
Div index and month rollupapps/frontend/src/lib/profile-catalog.ts
Profile document loadapps/frontend/src/lib/profile-query.ts
Bookmarksapps/frontend/src/components/bookmarks/BookmarksPage.tsx
Hover cardapps/frontend/src/components/ui/UserHoverCard.tsx