A person's OpenProfile.md: public when switched on, corrected from every surface - #74
Merged
Merged
Conversation
…ery surface
The openprofile job assembles a file and rewrites it on every run. What it
must never rewrite is what the person, or the operator for them, decided:
so those decisions live beside it (openprofile_settings, migration 0036),
as the overlay @profullstack/openprofile applies everywhere, a public
switch that is off until somebody turns it on, a handle, and who claimed
the profile and how.
Rendering moves to @profullstack/openprofile so the file is the same shape
every house app serves; Topics are one per bullet now.
Public means public to everyone, minus email, phone and a Contact section:
GET /api/v1/people/{id}/openprofile.md answers with no key and CORS, and
GET /api/v1/openprofiles lists every public profile newest change first,
paged by cursor, for nichedb.dev to pull. A suppressed person is never
public, and a private profile 404s to a stranger so nothing is learned.
Editing: PUT /api/v1/people/{id}/openprofile takes the whole file as
text/markdown or a JSON overlay (identity, headline, sections, public,
handle). The operator may, as with every other write about a person; so
may the person, carrying an OpenAccess bearer with the openprofile:edit
scope whose principal is provably them (a verified email, or the
OpenProfile.md they publish). The first edit by the person is their
claim. POST .../openprofile/publish {public} is the operator's switch.
`og profile <id> | edit | publish`, MCP update_openprofile and
publish_openprofile, and the scope in /.well-known/openaccess.json.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S7yeJUHGxA4P5N74xnsRPQ
Both blocks sit above the session guard and both stay. #73 took migration 0036, so the settings table is 0037. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S7yeJUHGxA4P5N74xnsRPQ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
OutreachGraph's half of the OpenProfile rollout (Anthony, 2026-09-13: "anywhere openprofile is implemented they should be able to edit from there via api/cli/mcp/pwa/desktop", "integrate on outreachgraph.com profiles too and publish those back if public").
@profullstack/openprofile(buildOpenProfilein providers); Topics one per bullet.openprofile_settings:public(default off),handle,overrides_json, owner and claim,updated_at. The openprofile job rewritesopenprofilesand never touches this.GET /api/v1/people/{id}/openprofile.mdis keyless with CORS when public, 404 to strangers otherwise;GET /api/v1/openprofiles?since=&limit=&cursor=lists public profiles for nichedb.dev. Suppressed people are never public (publish refuses with 409, the listing and the file drop them).PUT /api/v1/people/{id}/openprofile(text/markdown whole file, or JSON overlay withpublic/handle); operator auth as every write, or an OpenAccess bearer withopenprofile:editwhose principal matches a verified email (person_emails.verified, or a corroborated email identity) or the person's published profile URL.verifyBeareris injectable; production verifies against openaccess.logicsrc.com via@logicsrc/openaccess.POST .../openprofile/publish {public}is operator-only.og profile <id>,og profile edit <id> [--file]($EDITOR otherwise),og profile publish <id> --public|--private;og openprofilekept as an alias. MCPupdate_openprofile,publish_openprofile; the client gainedput./.well-known/openaccess.jsonnames theopenprofile:editscope. README section added.<link rel="openprofile">on a public person page, because OutreachGraph has no public person page; the listing'spageis the file itself.Tests:
apps/api/src/openprofile-public.test.ts(flip, stripping, suppression, paging, overlay round trip, markdown PUT, bearer subject checks), CLI and MCP tests extended;bun run checkgreen (1499 tests).🤖 Generated with Claude Code
https://claude.ai/code/session_01S7yeJUHGxA4P5N74xnsRPQ