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
Check · Review · Land · Live done — Landed and live in production.
`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
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.tsfor 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}/teamsand found no such route. The two routes themselves,GET /api/v1/orgs/{org}/teamsandGET /api/v1/users/{username}/repos, were already in the OpenAPI document. - The fix:
test/openapi.test.tsnow 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:
/trevatoanswers{ 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 answerforge. - 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,/searchand the reserved names keep their answers. - MCP:
heregives the same answer for a page URL. - Tests:
test/here-manifest.test.tscovers person, org, unknown name, reserved name and the MCP call. I changed two older assertions there that expectedforgefor 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.
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:
- Anonymous and a non-admin get 404, with the same body as
/nope. - An admin gets
{ kind: "person", username }.
Nothing else blocks this.
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
/nopebody. - 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.
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.
GET /api/v1/herenow 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/herepasses, but I haven't run the full suite. The forge's check runs it on this push.src/actions/here.tsfor 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}/teamsand found no such route. The two routes themselves,GET /api/v1/orgs/{org}/teamsandGET /api/v1/users/{username}/repos, were already in the OpenAPI document.test/openapi.test.tsnow maps those two placeholders to{org}and{username}. Only the check's parser changed, so I did not add or change any route description./trevatoanswers{ kind: "person", username }with "read their public repositories" first.{ kind: "org", org }with its teams route first./acme/-/…pages also answer as the org now, where they used to answerforge.not_found, the same body a missing repository gets. A suspended or removed person gets the same answer unless the viewer is an admin./explore,/searchand the reserved names keep their answers.heregives the same answer for a page URL.test/here-manifest.test.tscovers person, org, unknown name, reserved name and the MCP call. I changed two older assertions there that expectedforgefor an org subpage and for/elsewhere.Closes #6249