From 60da6a1d2ac7ba3e34ac9895ecd145f4420a185a Mon Sep 17 00:00:00 2001 From: "claudebot.disnetdev.com (did:plc:n6ku5xddiuguwze3f356evla)" Date: Tue, 18 Aug 2026 16:39:24 +0000 Subject: [PATCH] Say what the app does, not how the data model works MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Second pass over UI copy, addressing the review of the previous one. Where a string described records, repos, the registry, the fold or a PDS, it now describes what a person gets: - Members and guest comments on the space page are stated as who belongs and what the switch invites, with the private case saying it is unavailable and why in one sentence. - The registry row's durability tooltip reads `durabilityNote` instead of repeating its two strings, which is what that constant exists for. - The docs setup card names the types it is about to add, restoring the antecedent the previous pass removed and leaving no bare identifiers. - "fixture" is gone from the one place a person is offered the demo. - Swept the same vocabulary through the type registry surfaces, the picker, the account panel, the doc reader, the review card, the write errors, and Diagnostics' three notes so they agree. - An append-only successor is "Request a replacement" rather than "Request a superseding record"; its tests follow. Private mode's device panel keeps "envelope", "endpoint" and "peer" — that surface is where those are the fact — but its tooltips no longer explain replicas or repos. Co-Authored-By: claudebot.disnetdev.com (did:plc:n6ku5xddiuguwze3f356evla) --- packages/ui/src/lib/components/Account.svelte | 7 ++-- .../ui/src/lib/components/Diagnostics.svelte | 4 +- .../ui/src/lib/components/DocReader.svelte | 5 +-- .../src/lib/components/GuestComposer.svelte | 2 +- .../ui/src/lib/components/NewRequest.svelte | 6 +-- packages/ui/src/lib/components/NewType.svelte | 2 +- packages/ui/src/lib/components/PaneBar.svelte | 2 +- .../ui/src/lib/components/PlusMenu.svelte | 2 +- .../src/lib/components/PrivateDevices.svelte | 24 ++++++------ .../ui/src/lib/components/Skeleton.svelte | 2 +- .../ui/src/lib/components/SpacePicker.svelte | 15 ++++--- .../ui/src/lib/components/UnitDetail.svelte | 10 ++--- packages/ui/src/lib/components/Verdict.svelte | 2 +- packages/ui/src/lib/docs.ts | 6 +-- packages/ui/src/lib/requests.test.ts | 6 +-- packages/ui/src/lib/requests.ts | 4 +- packages/ui/src/lib/write.ts | 8 ++-- .../ui/src/routes/g/[did]/[rkey]/+page.svelte | 4 +- .../src/routes/p/[project]/docs/+page.svelte | 21 ++++++++-- .../routes/p/[project]/settings/+page.svelte | 2 +- .../routes/p/[project]/userinput/+page.svelte | 2 +- .../userinput/userinput-page.svelte.test.ts | 2 +- packages/ui/src/routes/space/+page.svelte | 39 +++++++++---------- 23 files changed, 93 insertions(+), 84 deletions(-) diff --git a/packages/ui/src/lib/components/Account.svelte b/packages/ui/src/lib/components/Account.svelte index 3fbe630..05f56fe 100644 --- a/packages/ui/src/lib/components/Account.svelte +++ b/packages/ui/src/lib/components/Account.svelte @@ -104,7 +104,8 @@

- Records you write land in your own repo. This tab holds a session, never a password. + Everything you write is stored in your own account. This tab holds a session, never a + password.

{:else if !writable} diff --git a/packages/ui/src/lib/components/NewType.svelte b/packages/ui/src/lib/components/NewType.svelte index cb3fd3b..505df6c 100644 --- a/packages/ui/src/lib/components/NewType.svelte +++ b/packages/ui/src/lib/components/NewType.svelte @@ -106,7 +106,7 @@ /> {#if taken}

- The registry already carries {name.trim()}. + This space already has {name.trim()}.

{/if} diff --git a/packages/ui/src/lib/components/PaneBar.svelte b/packages/ui/src/lib/components/PaneBar.svelte index 019b15b..42130f5 100644 --- a/packages/ui/src/lib/components/PaneBar.svelte +++ b/packages/ui/src/lib/components/PaneBar.svelte @@ -26,7 +26,7 @@ const freshness = $derived.by(() => { if (space.fixture) return undefined if (session.error) return { kind: 'stale' as const, text: 'stale', title: session.error } - if (session.syncing) return { kind: 'live' as const, text: 'syncing…', title: 'Reading member repos' } + if (session.syncing) return { kind: 'live' as const, text: 'syncing…', title: 'Catching up with everyone' } const age = space.syncedAt ? relativeTime(space.syncedAt, new Date().toISOString()) : '' return { kind: 'live' as const, text: age ? `synced ${age}` : 'synced', title: space.syncedAt ?? '' } }) diff --git a/packages/ui/src/lib/components/PlusMenu.svelte b/packages/ui/src/lib/components/PlusMenu.svelte index ce92899..ef12610 100644 --- a/packages/ui/src/lib/components/PlusMenu.svelte +++ b/packages/ui/src/lib/components/PlusMenu.svelte @@ -157,7 +157,7 @@ {/each} {#if offered.length === 0} {/if} {/if} diff --git a/packages/ui/src/lib/components/PrivateDevices.svelte b/packages/ui/src/lib/components/PrivateDevices.svelte index d31c2f6..5af8dcf 100644 --- a/packages/ui/src/lib/components/PrivateDevices.svelte +++ b/packages/ui/src/lib/components/PrivateDevices.svelte @@ -175,14 +175,14 @@ kind: 'accent', glyph: '◈', text: 'private', - title: 'this space’s records travel in signed envelopes and reach no PDS', + title: 'everything here is signed and never reaches a public server', }} />

- This space’s records are in this browser and in the other members’ replicas, and on no PDS. What is - public is the directory below: the signing keys each member publishes, so anybody can verify what - they wrote. + Everything in this space is in this browser and on the other members’ own devices, and on no public + server. What is public is the list of devices below: the signing keys each member publishes, so + anybody can verify what they wrote.

{#if error} @@ -230,7 +230,7 @@ Another window of this browser holds the connection and this one shares it; closing that window hands it to this one. {/if} - Its bootstrap names {status.founder} as the founder{status.peerHints.length > 0 + The ticket this browser joined with names {status.founder} as the founder{status.peerHints.length > 0 ? `, and ${status.peerHints.join(', ')} as expected to be reachable` : ''}.

@@ -268,7 +268,7 @@ /> {:else if row.here === 'retired'} {/if} {#if row.directory} @@ -277,7 +277,7 @@ kind: 'accent', glyph: '●', text: 'published', - title: 'in the device directory this replica has read', + title: 'the other members can see this device', }} /> {:else} @@ -286,7 +286,7 @@ kind: 'flat', glyph: '⋯', text: 'not in the directory', - title: 'published to your repo, but this replica has not read it back yet', + title: 'published, but not visible here yet', }} /> {/if} @@ -299,7 +299,7 @@ kind: 'flat', glyph: '⊘', text: 'disconnected', - title: 'its address was withdrawn, so no replica connects to it; its records still count', + title: 'its address was withdrawn, so nothing connects to it; what it wrote still counts', }} /> {/if} @@ -399,7 +399,7 @@ kind: 'accent', glyph: '●', text: 'published', - title: 'in the device directory this replica has read', + title: 'the other members can see this device', }} /> {#if device.retiredAt} @@ -408,7 +408,7 @@ kind: 'flat', glyph: '⊘', text: 'disconnected', - title: 'its owner withdrew its address; nothing connects to it, and its records still count', + title: 'its owner withdrew its address; nothing connects to it, and what it wrote still counts', }} /> {/if} @@ -419,7 +419,7 @@ {#if others.length > 0}
Other members’ devices {liveOthers.length}

- Read from their own repos. This is the whole of what a private space still asks a PDS for. + Read from each member’s own account — the only thing a private space still looks up publicly.

    {#each liveOthers as device (device.did + device.deviceKeyId)}{@render otherRow(device)}{/each} diff --git a/packages/ui/src/lib/components/Skeleton.svelte b/packages/ui/src/lib/components/Skeleton.svelte index 29cbec5..7c4ba5e 100644 --- a/packages/ui/src/lib/components/Skeleton.svelte +++ b/packages/ui/src/lib/components/Skeleton.svelte @@ -46,7 +46,7 @@
    -

    Opening — reading the space record, then every member’s repo.

    +

    Opening — catching up on what everyone here has written.

    {#each ROWS as index (index)} - {space.name || - (space.private ? 'A private space' : 'Could not read this space record')} + {space.name || (space.private ? 'A private space' : 'Could not open this space')} {#if space.name && space.description} {space.description} @@ -196,7 +195,7 @@ {/if} {#if space.private} - + private {/if} @@ -205,14 +204,14 @@ {/each}
{:else if owned.status === 'loading'} -
In your repo
-

Reading your repo…

+
Your spaces
+

Looking for your spaces…

{/if} {#if owned.status === 'failed'} - + {/if} {/if} @@ -280,7 +279,7 @@
demo data, no network
diff --git a/packages/ui/src/lib/components/UnitDetail.svelte b/packages/ui/src/lib/components/UnitDetail.svelte index f141d23..6eb7580 100644 --- a/packages/ui/src/lib/components/UnitDetail.svelte +++ b/packages/ui/src/lib/components/UnitDetail.svelte @@ -415,10 +415,10 @@ {/if} {/each} {#if requestFor} - request + request {/if} {#if version} - artifact + artifact {/if} @@ -594,14 +594,14 @@ href={pr.href} target="_blank" rel="noopener" - title={pr.uri ? 'This forge gives a pull record no page of its own — opens the repository’s pull list.' : undefined} + title={pr.uri ? 'This forge has no page for a single pull request — opens the repository’s pull list.' : undefined} >{pr.number ? `pull request #${pr.number}` : pr.uri ? 'pull requests' : 'pull request'} ↗ {#if pr.uri} - pull + pull {/if} {:else if pr?.uri} - pull + pull {/if} {#if version?.mergedAt} merged · {stamp(version.mergedAt)} diff --git a/packages/ui/src/lib/components/Verdict.svelte b/packages/ui/src/lib/components/Verdict.svelte index 4074dfc..925443b 100644 --- a/packages/ui/src/lib/components/Verdict.svelte +++ b/packages/ui/src/lib/components/Verdict.svelte @@ -109,7 +109,7 @@ Review of {pinned}

- Pinned to {pinned} by cid. + Stays attached to {pinned}, not to whatever lands next. {#if answering && asker} · answering {asker.handle ?? asker.name}'s request {/if} diff --git a/packages/ui/src/lib/docs.ts b/packages/ui/src/lib/docs.ts index 5c86198..a7a19fa 100644 --- a/packages/ui/src/lib/docs.ts +++ b/packages/ui/src/lib/docs.ts @@ -71,14 +71,14 @@ export const TIERS: readonly Tier[] = [ id: 'dev', label: 'Dev', blurb: - 'The project’s standing memory, as the agents read it. Every version of these rides in a turn’s bundle.', + 'The project’s standing memory, as the agents read it. Every version of these goes to an agent whenever it takes on work here.', }, { id: 'user', label: 'User', - blurb: 'Product documentation, one page per feature, written from the records above.', + blurb: 'Product documentation, one page per feature, written from the pages above.', type: USER_DOC_TYPE, - sources: 'the system records this page documents', + sources: 'the system pages this page documents', }, { id: 'roadmap', diff --git a/packages/ui/src/lib/requests.test.ts b/packages/ui/src/lib/requests.test.ts index 44be618..c3f38b0 100644 --- a/packages/ui/src/lib/requests.test.ts +++ b/packages/ui/src/lib/requests.test.ts @@ -104,7 +104,7 @@ describe('what asking for another version is called', () => { it('never offers to revise an append-only record — only to supersede it', () => { const adr = unitsOf(space.index, project()).find((entry) => entry.type === 'adr') if (!adr) throw new Error('fixture unit missing') - expect(successorLabel(space.index, adr, adr.current)).toBe('Request a superseding record') + expect(successorLabel(space.index, adr, adr.current)).toBe('Request a replacement') }) }) @@ -145,7 +145,7 @@ describe('the successor button on a system row', () => { const chain = sys('adr', 2) expect(drift(chain)).toBe(0) expect(successorAction(space.index, chain, chain.current, 3)).toEqual({ - label: 'Request a superseding record', + label: 'Request a replacement', primary: true, }) }) @@ -174,7 +174,7 @@ describe('the successor button on a system row', () => { ).toBe('v4 already requested') expect( successorAction(space.index, { ...chain, openRequest: pending }, chain.current, 0).pending, - ).toBe('A superseding record is already requested') + ).toBe('A replacement is already requested') }) }) diff --git a/packages/ui/src/lib/requests.ts b/packages/ui/src/lib/requests.ts index 91afd77..5e61b9d 100644 --- a/packages/ui/src/lib/requests.ts +++ b/packages/ui/src/lib/requests.ts @@ -96,7 +96,7 @@ export function buildableTypes( * supersedes it. Both facts come from the registry (§3.3). */ export function successorLabel(index: MaterializedIndex, unit: UnitView, basis?: UnitVersion): string { - if (durabilityOf(index, unit.type) === 'append-only') return 'Request a superseding record' + if (durabilityOf(index, unit.type) === 'append-only') return 'Request a replacement' const next = (basis?.version ?? unit.versions.length) + 1 return `Request ${typeLabel(unit.type)} v${next}` } @@ -275,7 +275,7 @@ export function successorAction( if (unit.versions.length > 0 && unit.openRequest) { action.pending = living ? `v${unit.versions.length + 1} already requested` - : 'A superseding record is already requested' + : 'A replacement is already requested' } return action } diff --git a/packages/ui/src/lib/write.ts b/packages/ui/src/lib/write.ts index 0ef52f6..542bcae 100644 --- a/packages/ui/src/lib/write.ts +++ b/packages/ui/src/lib/write.ts @@ -224,7 +224,7 @@ function recordingWriter(writer: RecordWriter, did: string, records: StoredRecor */ export async function write(args: string[]): Promise { const credentials = signedIn() - if (!credentials) throw new Error('Sign in to write to your own repo.') + if (!credentials) throw new Error('Sign in to write.') const transport = spaceTransport() if (!transport) { throw new Error('The demo is read-only. Open a live space to make changes.') @@ -305,7 +305,7 @@ export interface UploadedImage { */ export async function uploadImage(file: PickedFile): Promise { const credentials = signedIn() - if (!credentials) throw new Error('Sign in to add an image — it is a record in your own repo.') + if (!credentials) throw new Error('Sign in to add an image — it is stored in your own account.') const transport = spaceTransport() if (!transport) { throw new Error('The demo is read-only. Open a live space to make changes.') @@ -397,7 +397,7 @@ async function uploadPrivateImage( */ export async function createSpace(args: string[]): Promise { const credentials = signedIn() - if (!credentials) throw new Error('Sign in to create a space — it is a record in your own repo.') + if (!credentials) throw new Error('Sign in to create a space — it is stored in your own account.') const transport = spaceTransport() ?? new FetchRepoTransport(new Identities().pdsResolver) try { return await runCli(args, dependencies(credentials, transport)) @@ -428,7 +428,7 @@ export async function writeGenesis( transport?: RepoReadTransport, ): Promise { const credentials = signedIn() - if (!credentials) throw new Error('Sign in to create a space — its device key is a record in your own repo.') + if (!credentials) throw new Error('Sign in to create a space — its device key is stored in your own account.') const reads = transport ?? spaceTransport() ?? new FetchRepoTransport(new Identities().pdsResolver) const result = await runCli(args, privateDependencies(credentials, reads, replica)) await replica.settle() diff --git a/packages/ui/src/routes/g/[did]/[rkey]/+page.svelte b/packages/ui/src/routes/g/[did]/[rkey]/+page.svelte index 8e59653..c78de3b 100644 --- a/packages/ui/src/routes/g/[did]/[rkey]/+page.svelte +++ b/packages/ui/src/routes/g/[did]/[rkey]/+page.svelte @@ -64,7 +64,7 @@ {#if !goal}

No such goal

-

Nothing in this space matches that record.

+

Nothing in this space matches that address.

{:else}
@@ -94,7 +94,7 @@ than below it. They say what this work IS, which is what a reader wants while they are still reading the head, and any active member may edit them here. --> - + {#if goal.origin}{/if}
+

Setting up adds:

+
    + {#each missing as draft (draft.name)} +
  • {draft.name} — {draft.description}
  • + {/each} +
@@ -320,7 +325,7 @@

{#if tier === 'dev'} - This project has no system records yet. They are written by agents — ask for one from + This project has no system documents yet. They are written by agents — ask for one from System. {:else} No {tierById(tier).label.toLowerCase()} pages yet. @@ -402,6 +407,14 @@ .group > summary:hover { color: var(--ink); } .group > summary .n { font-weight: 500; letter-spacing: 0; font-variant-numeric: tabular-nums; } + /* The setup card's list of what registering adds. Typography matches `.empty p`, which the rest of + the card is written in, so the list reads as part of the same sentence rather than as data. */ + .setup-list { + margin: 6px 0 12px; padding-left: 18px; + font-size: 13.5px; line-height: 1.55; color: var(--ink-2); + } + .setup-list li + li { margin-top: 3px; } + @media (max-width: 720px) { .docs { grid-template-columns: minmax(0, 1fr); gap: 14px; } } diff --git a/packages/ui/src/routes/p/[project]/settings/+page.svelte b/packages/ui/src/routes/p/[project]/settings/+page.svelte index e2ea175..3ded1fa 100644 --- a/packages/ui/src/routes/p/[project]/settings/+page.svelte +++ b/packages/ui/src/routes/p/[project]/settings/+page.svelte @@ -211,7 +211,7 @@ {/if} Goals System - +

diff --git a/packages/ui/src/routes/p/[project]/userinput/+page.svelte b/packages/ui/src/routes/p/[project]/userinput/+page.svelte index 1dbc289..a3e1c87 100644 --- a/packages/ui/src/routes/p/[project]/userinput/+page.svelte +++ b/packages/ui/src/routes/p/[project]/userinput/+page.svelte @@ -253,7 +253,7 @@ of this" are different sentences (`userinput.ts`). --> {#if failed}

- {failed === 1 ? 'One record was' : `${failed} records were`} unavailable or malformed, so + {failed === 1 ? 'One item was' : `${failed} items were`} unavailable or malformed, so {failed === 1 ? 'it is' : 'they are'} not listed.

{/if} diff --git a/packages/ui/src/routes/p/[project]/userinput/userinput-page.svelte.test.ts b/packages/ui/src/routes/p/[project]/userinput/userinput-page.svelte.test.ts index 57a7022..51397dd 100644 --- a/packages/ui/src/routes/p/[project]/userinput/userinput-page.svelte.test.ts +++ b/packages/ui/src/routes/p/[project]/userinput/userinput-page.svelte.test.ts @@ -268,7 +268,7 @@ describe('the userinput section', () => { ) await render() - expect(text()).toContain('One record was unavailable or malformed') + expect(text()).toContain('One item was unavailable or malformed') expect(text()).toContain('One moderator grant pins an earlier version of this board') host.querySelector('button.row')?.click() flushSync() diff --git a/packages/ui/src/routes/space/+page.svelte b/packages/ui/src/routes/space/+page.svelte index d9d43f6..5da4b12 100644 --- a/packages/ui/src/routes/space/+page.svelte +++ b/packages/ui/src/routes/space/+page.svelte @@ -1,6 +1,7 @@