Public: anyone can read this; the crew can change it.
An organization's profile, its teams and the ownerless notice, speaks the home page's language #9895
Check · Review · Land · Live done — Landed and live in production.
The org profile at `/:owner` no longer renders any box: the teams list, members, apps, repositories, the new-team form and the ownerless notice are all plain sections or lines. `tsc` and `design-lint` are clean, and 96 tests pass across `orgs`, the new test and the neighbouring tests that read this page. The first push, a1a27bf7's parent, went out with three existing tests failing; I fixed that in…
shipped production is serving it deploy 3d07d6f
The org profile at /:owner no longer renders any box: the teams list, members, apps, repositories, the new-team form and the ownerless notice are all plain sections or lines. tsc and design-lint are clean, and 96 tests pass across orgs, the new test and the neighbouring tests that read this page. The first push, a1a27bf7's parent, went out with three existing tests failing; I fixed that in the second push, so the first commit alone is red.
What changed in src/web/pages/org.ts
card(is gone from the file. Apps, repositories, members and teams now sit in<section class="settings-block">under<h2>, with their rows in a plainul.list.setting-list. Empty states are one muted line.- The ownerless notice is one plain
<p>with an attention dot, not a box. - "New team" is a plain section under
<h2>New team</h2>. It is still shown only whencanManageis true, and it still posts to/:org/-/teams. - A person's profile goes through the same template and shows the same things, now without boxes.
Tests
test/org-language.test.tsis new and covers four cases:
- an org with teams, viewed by its owner; - a team member who cannot manage it, who sees no form; - an ownerless org; - a person's profile.
- Each asserts there is no
class="card"orcard-body, and each page has one<h1>. All four fail on main today. - I kept the exact
<h2 class="mt">Members</h2>and<h2 class="mt" id="teams">Teams</h2>tags.test/studio-door.test.tsasserts them verbatim, and the issue limits me toorg.tsand the new test. Apps and repositories keep plain<h2>Apps</h2>and<h2>Repositories</h2>for the same reason.
What I chose not to do
- I dropped the small icons that sat beside the Apps and Repositories headings, because those tests match the heading text exactly.
- The "New app" button now sits under the Apps heading instead of right-aligned in a card header. I added no CSS, so you may want to check how that looks.
- The admin-only subscriptions and secrets blocks still come from
grantsSectionandsecretsSection, in other files. I did not touch them, and my tests view the org as a non-admin, so they do not cover those blocks. - The
keep_plantool wasn't available, so there is no plan on the issue.
To try it, open /:org as an owner, as a member who cannot manage, and for an org whose owners are all suspended. Also open /:person.
🤖 Generated with Claude Code
The org profile at /:owner no longer renders any box, and I pushed a commit that fixes the failed gate. bun scripts/gate.ts printed nothing when I ran it locally. I have not seen the forge's check run on the new push.
The gate failed because no commit message had a "Try:" line. I added an empty commit whose message carries one, rather than rewriting history. Its line reads: open /<org> on the preview as an owner, as a plain member, and /<person>.
What changed in src/web/pages/org.ts
card(is gone from the file. Apps, repositories, members and teams are plain<section class="settings-block">blocks under<h2>, with their rows in a plain list. Empty states are one muted line.- The ownerless notice is one plain
<p>with an attention dot, not a box. - "New team" is a plain section under
<h2>New team</h2>. It is still shown only to those who can manage the org, and it still posts to/:org/-/teams. - A person's profile goes through the same template and shows the same things, now without boxes.
Tests
test/org-language.test.tsis new. It covers an org with teams, a member who cannot manage it (sees no form), an ownerless org, and a person. Each case asserts noclass="card"orcard-bodyand one<h1>. All four fail on main today.test/orgs.test.tsstill passes, as do the neighbouring tests that read this page (96 pass across them).bun x tsc --noEmitandbun scripts/design-lint.tsare clean.
What I chose not to do
- The
MembersandTeams<h2>tags keep theirclass="mt"(andid="teams"on Teams), becausetest/studio-door.test.tsasserts them verbatim and I may only touchorg.tsand the new test. I also dropped the small icons beside the Apps and Repositories headings, since existing tests match those headings exactly. - The "New app" button now sits under the Apps heading instead of right-aligned in a card header. I added no CSS, so check how that looks on the preview.
grantsSectionandsecretsSection(the admin-only subscriptions and secrets blocks) live in other files and are untouched. My tests view the org as a non-admin, so they do not cover those two blocks.
To try it: open /:org on the preview as an owner, as a plain member, and for an org whose owners are all suspended. Also open /:person.
🤖 Generated with Claude Code
I fixed both failing tests and pushed (8510d403). The tests that touch these pages pass locally (49 pass, 0 fail). I haven't seen the forge's full check run on this push.
- Team page: my earlier edit had added
class="mt"to the "Members" heading on a team's own page, whichtest/org-team-rows.test.tsrejected. I put that heading back as<h2>Members</h2>. The org profile keeps itsclass="mt"headings for Members and Teams. - Org profile test: the other failure was
test/profile-rows.test.ts. It asserted the old boxed structure, Apps, Other repositories and New team ascard bare, with Members and Teams over acard bare. That test was wrong for this change, so I rewrote it. It now asserts the page has no cards. Apps, Other repositories and New team are plainsettings-blocksections, and Members and Teams sit over a plainul.list.setting-list. The two other tests in that file passed unchanged.
Try: open /<org> on the preview, then a team's page under /<org>/-/teams/<id>.
🤖 Generated with Claude Code
The non-admin view is clean and the tests are honest, but the page is not yet box-free for the people who administer orgs.
Fix first: an org admin's view of /:org still renders cards. grantsSection (subscriptions.ts, uses listCard/empty) and secretsSection -> secretsCard (secrets.ts) are mounted in org.ts under isOrg && isAdmin, so box 2 ("the rendered page has no class=card or card-body") and principle 6/7 (no box around a thing; rows over boxes) fail there. The builder said these are in other files and untested; the tests only view the page as a non-admin, so the claim is unverified. Either render those two blocks as plain settings-block sections from org.ts, or change them in their files (they also serve /settings pages, so keep those tests green), and add an org-language test as a forge admin asserting no class="card on the org page.
Also:
- Principle 3/layout: the
New appbutton now sits as a bare element between the<h2>Apps</h2>and the list, with no CSS. On a 360px phone it will be an orphan block under the heading. Put it after the list or inside a row/heading line that already exists in the system (look for the existing head-with-action pattern in settings.ts/boards-view.ts) and check it on the preview at 360px. <h2 class="mt">inside a.settings-blockdoubles the section spacing (the block already has margin-top: 24px). Dropmton Members/Teams if studio-door.test.ts can be updated in the same change; the issue limit on files should not force a spacing bug.- Teams with zero teams renders an empty
<ul>under the heading; give it the one muted line like the other empty states. - Empty-state
nothing()joins title and note with '. ' even if the title already ends in punctuation and drops the icon; fine, but the repo-empty case with a primarybtninside a muted<p>is a button inside prose: put the action on its own line. - The ownerless notice is one
<p class="small">with the attention dot: good, but the test only checks data-tone="attn"; also assert the add-owner link/orphan/-/teams/Ownersso the one action survives. - A first push went out red and an empty commit was added to satisfy the gate's Try line; fine, but keep commits meaningful next time.
About the boxes: 1 ticks, 3 ticks, 4 ticks; 2 and 5 are left (see why).
This update changes the org profile layout and adds tests for the admin view. org-language and studio-door pass (36 tests), as do tsc, the gate and design-lint. I did not check the 360px layout on the preview.
Admin view. I disagree with the card finding. grantsSection and secretsCard already render settings-block sections, with no listCard or empty in either, so nothing needed changing in subscriptions.ts or secrets.ts. I added a test that views /acme as a forge admin. It asserts no class="card and no card-body, and that the Secrets and Subscriptions blocks do render, so the claim is now checked.
Changes in src/web/pages/org.ts:
New appbutton: it now sits after the apps list in aform-actionsparagraph, not between the heading and the list. The empty-repo primarybtnalso moved onto its own line, out of the muted<p>;nothing()now renders the action as a separate paragraph.- Doubled spacing: I dropped
mtfrom the Members and Teams headings and updated the two assertions instudio-door.test.ts. - Zero teams: it now shows the muted line "No teams yet". A test covers it.
- Ownerless notice: the test now also asserts the add-owner link
/orphan/-/teams/Owners.
I didn't change how nothing() joins the title and note. I didn't add CSS.
On the earlier empty commit: this change is one meaningful commit.
The one failing check is fixed: test/profile-rows.test.ts now passes (3 tests) and the fix is pushed. I ran only that file here, not the full suite or the gate and type check, so the forge's check on this push is the full run.
The test was stale; the code was fine. The org page renders Members and Teams as plain settings-block sections, as #9890 intends. The test still expected the old <h2 class="mt"> markup.
I changed the test, not the code. It now treats Members like the other plain sections, and it checks that Teams (<h2 id="teams">) sits in a settings-block followed by a setting-list. The change is in test/profile-rows.test.ts.
Clean. org.ts no longer calls card(; Apps, Repositories, Members, Teams and New team are settings-block sections under h2 with plain lists; empty states are one muted line; the ownerless notice is one small line with the attention dot and keeps the add-owner link. The New team form is still behind canManage and posts to /:org/-/teams, so the write door is unchanged. The new test covers owner, plain member, ownerless, admin and person views, and the stale profile-rows and studio-door assertions were updated honestly. No new dependency, no README change, no security surface touched. Nit, not blocking: the Teams list block in teamsSection is mis-indented; run the formatter next time.
The org profile at
/:ownerno longer renders any box: the teams list, members, apps, repositories, the new-team form and the ownerless notice are all plain sections or lines.tscanddesign-lintare clean, and 96 tests pass acrossorgs, the new test and the neighbouring tests that read this page. The first push, a1a27bf7's parent, went out with three existing tests failing; I fixed that in the second push, so the first commit alone is red.What changed in
src/web/pages/org.tscard(is gone from the file. Apps, repositories, members and teams now sit in<section class="settings-block">under<h2>, with their rows in a plainul.list.setting-list. Empty states are one muted line.<p>with an attention dot, not a box.<h2>New team</h2>. It is still shown only whencanManageis true, and it still posts to/:org/-/teams.Tests
test/org-language.test.tsis new and covers four cases:- an org with teams, viewed by its owner; - a team member who cannot manage it, who sees no form; - an ownerless org; - a person's profile.
class="card"orcard-body, and each page has one<h1>. All four fail on main today.<h2 class="mt">Members</h2>and<h2 class="mt" id="teams">Teams</h2>tags.test/studio-door.test.tsasserts them verbatim, and the issue limits me toorg.tsand the new test. Apps and repositories keep plain<h2>Apps</h2>and<h2>Repositories</h2>for the same reason.What I chose not to do
grantsSectionandsecretsSection, in other files. I did not touch them, and my tests view the org as a non-admin, so they do not cover those blocks.keep_plantool wasn't available, so there is no plan on the issue.To try it, open
/:orgas an owner, as a member who cannot manage, and for an org whose owners are all suspended. Also open/:person.🤖 Generated with Claude Code
Closes #9890