logicsrc/docs/openprofile.md
Anthony Ettinger 9ba3d5c108
OpenProfile 0.3: Gender and Voice in the identity block (#172)
How a machine should sound when it speaks for you, and the order a reader
chooses in: Voice, then Gender, then Pronouns, never a name or a photo.
Gender means the same in the identity block and under Match. The first
reader is nixamp's party line, which reads trollbox lines to the people
on the phone in a room in the author's voice (nixamp 0.23.5).


Claude-Session: https://claude.ai/code/session_01GxYGCCvvuhVAkU1W2iJKTV

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 21:50:52 -07:00

18 KiB

OpenProfile.md

OpenProfile.md is one Markdown file that says who you are and where you are, for people and agents alike. It is the profile equivalent of meta tags: a small, plain document any site can serve, any platform can link to, and any reader (a person, a crawler, an agent, a job board, a resharing network) can read without being taught a schema first. It is maintained by Profullstack, Inc. as part of the LogicSRC open-standards surface.

Status: 0.3. This is a description of a convention already in use by myna and agenticjobs, published so others can serve and read the same file.

Slug: openprofile

The problem

Every platform has a profile page, and every profile page is a dead end. Your Bluesky bio cannot tell a job board what you write about. Your GitHub page cannot tell a resharing network which topics you will boost and what that costs. An agent has it worse: it has a handle on six networks, an operator somewhere behind it, and no place where all of that is written down together.

The pieces already exist. rel="me" proves two pages belong to the same person. OpenGraph tells a link unfurler what a page is about. A resume says what you have done. What is missing is the one file that ties a name to its accounts, its topics, its terms, and (for an agent) the person answerable for it, in a form that survives being copied between tools.

The shape

# Ada Lovelace

- **Kind**: person
- **Handle**: @ada
- **Web**: https://ada.example
- **Email**: ada@example.com
- **Avatar**: https://ada.example/ada.png
- **Pay**: eip155:8453:0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf
- **Resume**: https://agenticjobs.work/candidates/ada/resume.md

Writes about machines that do not exist yet.

## Accounts

- [Bluesky](https://bsky.app/profile/ada.example)
- [Mastodon](https://mathstodon.xyz/@ada)
- [GitHub](https://github.com/ada)
- [Blog](https://ada.example/blog)

## Topics

- computing, mathematics, poetry, analytical engines, #babbage

## Reshare

- **Networks**: bluesky, mastodon
- **Topics**: computing, mathematics
- **Rate**: $0.05/reshare
- **Limit**: 3/day
- **Not**: gambling, politics

An agent's file adds one section:

# Athena

- **Kind**: agent
- **Handle**: @athena
- **Web**: https://athena.example

Ships small fixes to open source projects, nightly.

## Operator

- **Name**: Ada Lovelace
- **Profile**: https://ada.example/.well-known/openprofile.md
- **Email**: ada@example.com

A person who wants to be matched, on a dating site or anywhere else that pairs people, adds two more:

## Match

- **Born**: 1990-05-12
- **Gender**: woman
- **Orientation**: bisexual
- **Status**: single
- **Monogamy**: monogamous
- **Height**: 168 cm
- **Children**: none
- **Wants children**: open
- **Smoking**: never
- **Drinking**: socially
- **Religion**: none
- **Politics**: left
- **Seeking**: everyone
- **For**: long-term
- **Ages**: 30-45
- **Distance**: 50 km
- **Not**: smokers, long-distance

## Photos

- https://ada.example/photos/garden.jpg
- https://ada.example/photos/engine.jpg

The rules

There are nine, and every one of them degrades rather than fails.

1. One # heading, and it is the name. A document with more than one is read using the first; a document with none still parses, and a reader that wants a name can say it does not have one.

2. The bullet list directly under the name is the identity block. Each item is Key: value, with or without **bold** on the key, or a bare [label](url). The keys a reader should understand are:

  • Kind: person, agent or organization. Absent means unstated, which a reader should say rather than assume. bot is accepted as an alias for agent; org and company for organization.
  • Handle: the name you go by, with or without a leading @. One handle, the one you would write on a slide. Per-network handles belong in Accounts.
  • Web: your home page. Where the file itself lives is a separate question, answered under Discovery.
  • Email, Location, Pronouns, Timezone, Languages: kept as written.
  • Gender: kept as written. woman, man and non-binary are the words in common use, and any other word is kept too. It may sit here or under Match, and means the same in both; a reader takes whichever it finds first.
  • Voice: how a machine should sound when it speaks for you. female, male, or a provider's voice id kept as written (Telnyx.KokoroTTS.am_adam, ElevenLabs.Premade.Rachel). A platform that reads your words aloud (a phone room reading a chat line, a screen reader for your posts) chooses from Voice, then Gender, then Pronouns, and never from a name, a photo or another site. Absent all three, it picks one and keeps picking the same one for you.
  • Avatar: an image URL.
  • DID: a decentralized identifier for the same person or agent: did:key:z6Mk..., did:web:example.com, or an AT Protocol did:plc:.... Kept as written; a reader that resolves DIDs may check the document behind it, and one that does not shows it. A DID issued by a service that also vouches for agents (CoinPay issues one per account and lets a person's stand behind an agent's) is how Operator becomes checkable rather than stated.
  • Pay: where money for you goes. A CAIP-10 account (eip155:8453:0x...), a bare address, a Lightning address, or a payment page URL. Readers that move money must show it and ask; readers that do not can ignore it.
  • Resume: the URL of an OpenResume.md file. The resume says what you have done; this file says who and where you are. Each may link to the other.

Values that look like an email address or a URL become links; anything else stays text. Unknown keys are kept as written, so Discord, PGP and Calendar all work without anyone having to add them to a list.

3. A single prose line between the identity block and the first ## is the headline. One line. It is the bio a directory shows next to your name. More than one line, and only the first is treated that way; the rest is kept as prose.

4. ## opens a section. The text is kept verbatim, and separately normalised for matching, so Accounts, Profiles, Elsewhere and Find me are one thing to a reader and four different words on the page. The normalised names in common use are accounts, topics, reshare, operator, match, photos, broadcast, guest, links, about, projects, services and contact. Broadcast and Guest are specified on their own as OpenBroadcast and OpenGuest: the show a person hosts and the appearances a person offers, matched against each other. Dating, Matching, Partner and Looking for normalise to match. A section whose name matches none of them keeps its own name and is not dropped.

5. Every bullet under Accounts is one account, and the URL is the identity. [Bluesky](https://bsky.app/profile/ada.example) names a platform and a page; the page is what matters, and the label is only what to call it. bluesky: ada.example and https://bsky.app/profile/ada.example on a line of their own are accepted too. A reader derives the network from the host when it knows the host, and from the label when it does not. An account is a claim until it is verified (see Verification), and a reader should show the difference.

6. Topics are the words you would use to find yourself. Comma-separated on one line or one per bullet, with or without a leading #. Readers lowercase them, strip the #, trim, and match loosely: a prefix, a plural, a hyphen for a space. machine-learning and Machine Learning are the same topic. Mapping topics onto a controlled vocabulary is the reader's job, and doing it at write time destroys the information.

7. Reshare states what you will amplify for other people, and what it costs. It is how a resharing network knows you exist. The keys:

  • Networks: which of your accounts will reshare, by network name (bluesky, mastodon, x, nostr, linkedin, ...). Absent means every account under Accounts on a network that supports resharing.
  • Topics: what you will reshare. Absent means your profile Topics.
  • Not: topics you refuse, matched the same loose way. A hit here wins over a hit in Topics.
  • Rate: what one reshare costs the author. free (the default when the section exists and the key does not), or an amount with a unit: $0.05/reshare, $0.10/reshare/network. A rate without Pay in the identity block is a request that cannot be honoured, and a reader should say so rather than treat it as free.
  • Limit: the most reshares you will do, 3/day or 20/week. Absent means the reader's own default, which should be small.

No Reshare section means you are not offering to reshare. Nothing here obliges anyone to send you anything; it is an offer, and the matching, the sending and the paying are all the reader's business.

8. Operator names the person answerable for an agent. An agent's profile carries it; a person's does not. Name and either Profile (the operator's own OpenProfile.md, which is the strong form) or Email, and optionally DID, the operator's identifier, which a reader can match against the DID in the operator's own file. A reader that meets an agent without an Operator section should say the operator is unstated. Operators can chain: an agent run by an agent names that agent, whose profile names a person. A reader following the chain stops after a few hops and reports what it found.

9. Match says what a matching platform needs, and only what you chose to publish. A dating site, a co-founder board and a roommate finder match on the same few facts, and today each holds them in its own form behind its own login. The section has two kinds of key, about you and about who you are looking for, and every one is optional.

About you:

  • Born: an ISO date (1990-05-12), a year, or an age. A date wins over a year, a year over an age. A reader computes age at read time and shows the age, not the date; a platform stores the date only if the person entered it on that platform.
  • Gender, Orientation, Pronouns (Gender and Pronouns may also sit in the identity block, where they mean the same): kept as written. woman, man, non-binary, straight, gay, bisexual, pansexual, asexual, queer are the words in common use, and any other word is kept too.
  • Status: single, divorced, widowed, separated, partnered, married. Monogamy: monogamous, non-monogamous, open.
  • Height: 168 cm or 5'6". Body: kept as written.
  • Children: none, a count, or a count with a word (2, grown). Wants children: yes, no, open, undecided.
  • Smoking, Drinking, Cannabis, Drugs: never, socially, often, quit.
  • Religion, Politics, Ethnicity, Education, Work, Diet, Pets, Exercise, Zodiac: kept as written. Work here is one line; the Resume link in the identity block is where the detail lives. A reader may compute Zodiac from Born when it is absent.

About who you seek:

  • Seeking: the genders you want to be matched with: women, men, everyone, or a list.
  • For: long-term, short-term, marriage, casual, friends, open to either, or a list.
  • Ages: a range, 30-45. Distance: a radius from Location, 50 km, 30 mi, or anywhere.
  • Not: dealbreakers, matched loosely against the other profile's Match values and Topics the way Reshare's Not is matched. A hit here wins over everything else.

Values are matched loosely, as Topics are. Unknown keys are kept, so a platform that matches on something this list lacks adds its own key and loses nothing. Absence is unstated: a platform shows unstated, never a default, and never a guess made from the avatar, the name or anything else in the file.

Two rules a matching platform does not degrade on. Born is the one key it must have: a reader that finds no Born, or computes an age under 18 from it, does not list the profile in a matching context at all. And the section is public by nature: orientation, religion, politics, ethnicity and health-adjacent keys are the categories of personal data most laws protect, so a person puts here what they would put on a public profile page and nothing a platform would have to hold under a lock. A platform that imports a Match section stores no more of it than the person confirmed on that platform, shows where it came from, and drops it when the file drops it.

## Photos goes with it: one image URL per bullet, the first is the lead, and Avatar in the identity block stays the small square picture a directory shows next to the name.

Discovery

The file is served, not registered. There are three ways to find it, and a reader should try all three.

1. Well-known. A domain that is a person or an agent serves the file at /.well-known/openprofile.md. This is the canonical location for a personal site.

2. A link element. Any HTML page can point at the file:

<link rel="openprofile" href="https://ada.example/.well-known/openprofile.md">

A home page points at its owner. A platform that hosts many people points each profile page at that person's file, wherever it is served. The same relation works as an HTTP header for responses that are not HTML:

Link: <https://ada.example/.well-known/openprofile.md>; rel="openprofile"

3. A conventional path on a platform. A platform serving profiles for its users serves openprofile.md next to the profile page: https://agenticjobs.work/candidates/ada/openprofile.md. The <link> on the profile page should point at it, so a reader that only knows the page still finds the file.

Serve it as text/markdown; charset=utf-8. A Content-Disposition: attachment header is fine for a download link and wrong for the well-known location, where a reader is fetching rather than saving.

Verification

An account under Accounts is a claim that a page belongs to the person named at the top of the file. The claim is verified when the page points back.

  • The platform profile page carries <link rel="openprofile"> or <a rel="me"> to the OpenProfile.md URL, or to a page that carries <link rel="openprofile"> to it.
  • Or the platform bio, website field or pinned post contains the OpenProfile.md URL in plain text, for platforms with no way to set a link relation.

A reader shows a verified account as verified and an unverified one as claimed. It never hides an unverified one, because most accounts will be unverified for a while, and a claim is still information.

Two profiles that link to each other through Operator and through an account are the same trust chain: the agent says who runs it, and the person's file lists the agent under Accounts. Either link alone is a claim; both together are a verification.

What is deliberately absent

No required fields. A document consisting of a name and one line of prose is a valid OpenProfile.md.

No schema version. Readers ignore what they do not recognise. A profile written today has to be readable in five years by software nobody has written yet.

No signatures. A signed profile is a good idea and a different specification. Verification here is bidirectional linking, which every platform already supports in some form, and which is what rel="me" has used for twenty years.

No structured topic taxonomy. Topics are the words people wrote, and so are Match values.

No inference. A reader never fills a Match key from a photo, a name, a handle or another site. What is not written is unstated, and a platform that wants it asks the person.

No JSON. A reader may compute a structured view (name, kind, identity pairs, accounts with derived networks, topics, reshare terms, operator) and use it for matching and search. That view is derived, and it is regenerated from the Markdown on every read. The Markdown is the canonical copy. A product that stores the parse and treats the Markdown as an export has implemented a form with a Markdown skin, and the person no longer owns their profile.

Reading one

A conforming reader:

  1. Fetches the file from any of the three discovery locations and parses it under the eight rules.
  2. Keeps every line it does not understand.
  3. Reports absence as absence: an unstated Kind, an unstated operator, an unverified account.
  4. Matches topics loosely and lets Not win.
  5. Never moves money on the strength of Rate alone. Pay says where; the reader's own agreement with the person says whether.
  6. Lists a profile for matching only when Born is present and gives an age of 18 or more, and stores no more of Match than the person confirmed with it.

Writing one

By hand, in any editor, in five minutes. Or:

  • myna profile write builds one from the accounts myna is logged into and the topics in its settings, and myna profile show prints it. myna reshare join publishes the Reshare section to the myna reshare network.
  • agenticjobs serves one for every public candidate at /candidates/<slug>/openprofile.md, derived from the candidate's OpenResume.md, and links it from the profile page.
  • OpenResume.md: what you have done, in the same spirit. A profile links to a resume through Resume; a resume links to a profile through Profile in its contact block.
  • OpenBroadcast and OpenGuest: the Broadcast and Guest sections, for matching hosts with guests.
  • OpenJob: what the work is.
  • OpenCreds: where the tokens behind the accounts are kept. A profile never contains a credential.
  • ASDLC: how the tools that serve and read these files get built.

Version history

Version Date Change
0.1 2026-09-12 First publication: eight rules, three discovery locations, bidirectional verification, Reshare and Operator sections.
0.1.1 2026-09-12 DID in the identity block and in Operator: did:key, did:web and AT Protocol did:plc accepted verbatim.
0.2 2026-09-13 Rule 9, Match: the keys a dating site or any matching platform needs, about you and about who you seek; Born required for matching and 18 or over; no inference; Photos section.
0.3 2026-09-13 Gender and Voice in the identity block: how a machine should sound when it speaks for you, and the order a reader chooses in (Voice, Gender, Pronouns, never a name or a photo). First reader: nixamp's party line reading trollbox lines to callers.

License

The specification text is CC BY 4.0. Serve it, copy it, extend it.