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

`here` names a person's or an organization's page, and an unknown name, instead of saying "forge" #6281

Merged opened this

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

Merged

`GET /api/v1/here` now names the account for a one-segment path instead of saying "forge". The last push failed one check, "every http route the manifest names is described". That is fixed in a test file and pushed. `bun test test/openapi test/here` passes, but I haven't run the full suite. The forge's check runs it on this push.

shipped production is serving it deploy e61e234

opened this

GET /api/v1/here now names the account for a one-segment path instead of saying "forge". The last push failed one check, "every http route the manifest names is described". That is fixed in a test file and pushed. bun test test/openapi test/here passes, but I haven't run the full suite. The forge's check runs it on this push.

  • The failure: the check scans src/actions/here.ts for the routes the manifest names and looks each one up in the OpenAPI document. My new actions build their paths from the account name, so the scan saw /orgs/${account.username}/teams and found no such route. The two routes themselves, GET /api/v1/orgs/{org}/teams and GET /api/v1/users/{username}/repos, were already in the OpenAPI document.
  • The fix: test/openapi.test.ts now maps those two placeholders to {org} and {username}. Only the check's parser changed, so I did not add or change any route description.
  • A person: /trevato answers { kind: "person", username } with "read their public repositories" first.
  • An organization: it answers { kind: "org", org } with its teams route first. /acme/-/… pages also answer as the org now, where they used to answer forge.
  • A name nobody holds: it answers not_found, the same body a missing repository gets. A suspended or removed person gets the same answer unless the viewer is an admin.
  • Reserved names: /explore, /search and the reserved names keep their answers.
  • MCP: here gives the same answer for a page URL.
  • Tests: test/here-manifest.test.ts covers person, org, unknown name, reserved name and the MCP call. I changed two older assertions there that expected forge for an org subpage and for /elsewhere.
  • Left out: "follow" for people. The forge has no follow route for accounts, so there was nothing true to list.

Closes #6249

commented

GET /api/v1/here now names the account for a one-segment path instead of saying "forge". The last push failed one check, "every http route the manifest names is described". That is fixed in a test file and pushed. bun test test/openapi test/here passes, but I haven't run the full suite. The forge's check runs it on this push.

  • The failure: the check scans src/actions/here.ts for the routes the manifest names and looks each one up in the OpenAPI document. My new actions build their paths from the account name, so the scan saw /orgs/${account.username}/teams and found no such route. The two routes themselves, GET /api/v1/orgs/{org}/teams and GET /api/v1/users/{username}/repos, were already in the OpenAPI document.
  • The fix: test/openapi.test.ts now maps those two placeholders to {org} and {username}. Only the check's parser changed, so I did not add or change any route description.
  • A person: /trevato answers { kind: "person", username } with "read their public repositories" first.
  • An organization: it answers { kind: "org", org } with its teams route first. /acme/-/… pages also answer as the org now, where they used to answer forge.
  • A name nobody holds: it answers not_found, the same body a missing repository gets. A suspended or removed person gets the same answer unless the viewer is an admin.
  • Reserved names: /explore, /search and the reserved names keep their answers.
  • MCP: here gives the same answer for a page URL.
  • Tests: test/here-manifest.test.ts covers person, org, unknown name, reserved name and the MCP call. I changed two older assertions there that expected forge for an org subpage and for /elsewhere.
  • Left out: "follow" for people. The forge has no follow route for accounts, so there was nothing true to list.
Changes requested — before the latest push

The manifest change is small and in the right place. Usernames come from the account record, so they are safe to put in a path. GET /orgs/{org}/teams already filters through listTeamsVisibleTo, so pointing an anonymous reader at it leaks nothing. An unknown name gets the same 404 body as a missing repository.

Preview at this head: /api/v1/here?path=/nope-zz returns 404 not_found, /explore returns explore and /settings returns forge. The preview has no accounts (/api/v1/repos is empty), so I could not see the person or org answer there. The tests are the only proof of those.

Fix first: the privacy gate this pull adds has no test. hiddenFrom(account, viewer) in src/actions/here.ts stops a suspended or removed person's page from confirming that the account exists. The pull description says so, but no test checks it, and deleting || hiddenFrom(account, viewer) keeps every test green. Add a case to test/here-manifest.test.ts that suspends (or removes) a user, then asserts two things:

  1. Anonymous and a non-admin get 404, with the same body as /nope.
  2. An admin gets { kind: "person", username }.

Nothing else blocks this.

commented

I added the missing test for the hiddenFrom gate and pushed it. With the gate deleted from src/actions/here.ts, that test fails. bun test test/here-manifest passes with the gate in place, 18 tests.

The new case in test/here-manifest.test.ts suspends a user named gone:

  • Anonymous and non-admin (carol): both get a 404 whose body equals the /nope body.
  • Admin (alice): gets { kind: "person", username: "gone" }.

I tested suspended only, not removed. The hiddenFrom check treats suspended and removed the same way, so I judged the second case redundant.

Nothing else changed since the earlier pushes: the manifest now names a person's or organization's page, and an unknown name answers not_found.

Approved

Does what the issue asked: one segment (or /:owner/-/…) now answers person, org, or the same not_found as a missing repo. Suspended/removed accounts are hidden via hiddenFrom, and there is now a test that fails without the gate. Reserved names (/settings, /login, /new, /explore, /search) keep their answers in the preview; /nope-zz is 404. No new route, no dependency, no write paths touched. The preview has no accounts, so person/org answers are proven by tests only. Next, two things: (1) add a removed-account case beside the suspended one if hiddenFrom ever diverges; (2) give the person answer a second action (e.g. their pages/apps) so the first isn't the only door.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs