Public: anyone can read this; the crew can change it.
The front page: the forge featured with its crew at work, the best public apps ranked, the owner pins and hides #687
Check · Review · Land · Live done — Landed and live in production.
Closes #686
shipped production is serving it for issue #686 — its issue is already done deploy d909ee7
Closes #686
Stacked on #728; merge that one first.
One path. A stranger arrives, sees the forge and a few live apps, and opens one or signs in. The page is decided in one place (actions/front.ts). The page at /, GET /api/v1/front and the MCP tool front_page all answer from it, so they never disagree.
- Featured is the first repository a site admin pinned that a stranger can read. If there is none, it is the top-ranked app. It shows what makes a forge different: the crew at work on it right now, by issue. When nobody is working, it shows when the repository last shipped and how many changes merged this month. Pin
trevato/forgefirst and the forge features itself once it is public. Until then the next public pin is featured, or the top-ranked app if there are no other pins. - The shelf: the remaining pins, in order. Then public apps ranked by signals already in the database:
- forks made by people (an agent's working fork does not count); - pulls merged in the last 30 days; - awake hours; - how recently the last pull merged (deploys do not count, because a booting forge redeploys everything).
Likes will count once #602 lands. One owner gets at most two of the top eight places. The shelf shows only apps a stranger can open (public repository and public app access), that are up or wake on a visit, and that have a thumb taken as a stranger at production's current commit. An app without one waits for the looks sweep from #684. It is never shown as a broken image or an empty box. The shelf holds 12 tiles, then one link: "All N public apps" (/apps).
- The owner's say:
/frontshows the same page to anyone. A site admin there also gets pin, unpin, move up/down, hide and show controls, and a box to pin any repository. A private pin says it waits and stays hidden until the repository is public. The studio home links to/frontfor admins. The same setting isPUT /api/v1/front {pinned, hidden}and MCPfront_page {pinned?, hidden?, dryRun}(dry by default). Picks live in a newfront_picktable (migration 51, in the agreed order). - Removed: the old order (newest app first) and the old fallback to the owner's desktop picture. Two door tests in
test/studio.test.tsmove to the new contract.
Safety. What a stranger sees is worked out on every request from canRead with no user, so a repository made private leaves the page on the next load. Only the scores are cached, for one minute, per forge. Each request makes a fixed number of grouped reads: at most 200 public apps and 12 pins, plus one lookup of active runs for the featured repository. Nothing spends money and nothing wakes an app. Only a site admin sees the picks or changes them; refusals are tested for a stranger, a plain member (API, form, MCP) and a cross-origin form post.
Tests. New test/front.test.ts (8 tests, in the gate) covers:
- ranking order and the per-owner cap;
- signals read from a fixture;
- refusals;
- private, gated, failed, unpictured, legacy-thumb and old-commit apps all absent;
- pin order, hide, private pin skipped, the forge featured once public;
/frontcontrols;- MCP dry run versus write;
- crew at work.
test/mcp.test.ts lists the tool. test/studio.test.ts door tests follow the new contract. tsc --noEmit is clean. front, studio, mcp, looks and check-list: 205 pass. Before the last rebase, the local full gate failed only on tests that also fail on main locally (crew stand-in assignment) or pass when run alone (commit-identity).
Looks. Pull previews have no app runtime, so I took the looks from a local forge seeded with production's 22 public apps. Each app has its real name and description, its real ships, and a real guest screenshot taken through the edge, reduced to 640×400. Desktop 1280 and iPhone 15: no broken images, no sideways scroll. Tiles are 246 px wide on desktop and 174 px on a phone, two per row. The files are on the steward's machine, not attached here: there is no upload route.
🤖 Generated with Claude Code
Closes #686
Stacked on #684 (front-page thumbs); merge that first. Work in progress: the description is filled in when it is ready for review.
🤖 Generated with Claude Code