Docs run: the handbook still says a share is a link (#529 2/3, shipped v0.6.212) #585

Closed
opened 2026-09-17 23:36:31 +00:00 by Cordy · 2 comments
Owner

The #529 2/3 slice shipped in v0.6.212 with no documentation. docs/handbook/index.md states the rule it broke:

Every shipped feature that changes admin or user behavior updates a page here in the same release cycle, like the changelog.

Sharing changed shape rather than gaining an option, so this is not a matter of adding a paragraph: several pages now assert something that is no longer true. This issue is the docs run that closes that gap.

What changed in v0.6.212

The model, stated once so every page below can be written against it:

  • A share now carries an addressee — a local account or a group — not only a link. The file appears for that person under /shared, reached as its owner, so contents resolve exactly as they do for the owner.
  • Three role labels over primitives that already existed: Can view → read, Can edit → write, Can upload → AllowUpload (folders only).
  • Links split in two. An internal link is just the file's URL — no stored object, nothing to expire, revoke or count, and it grants nothing to someone who does not already have access. A public link is the existing /s/ surface, unchanged: password, expiry, upload, mode selector.
  • Recipients cannot re-share. Structural, not policy: scope.Driver.Delegated answers "was this path reached through someone else's grant", and the API refuses before writing. Only the owner manages the grant list.
  • Internal sharing has its own admin switch (ShareInternalDisabled), separate from the public-link switch. Stored negative, so an instance upgrading into the field keeps sharing on. TestPublicLinkPolicyDoesNotGovernGrants pins the separation.
  • Recipient picker is search-only (GET /api/v1/recipients?q=). Minimum 2 characters; a shorter query is a 400, not an empty list. Prefix-only on token boundaries (., -, _, space, @). Capped at 20 after ranking. Caller excluded from their own results. Deliberately not the admin candidates endpoint, which enumerates everything and would have 403'd for non-admins anyway.
  • Shares view has two tabs. My shares lists grants and public links together, grouped by file. Shared with me is flat, one row per granted item, showing via {group} where a grant came from group membership.

Surfaces to work through

docs/handbook/sharing.md — the main one. It opens with "Two ways to get a file to someone else, depending on whether they run Cairn" and a two-row table, then says "This page is about links." All three statements are now wrong. Needs a third row (recipient on this instance → internal grant → their /shared), the grants section, the role labels, the internal/public link split, and the no-re-share rule. Its "What this protects — stated precisely" section currently reasons only about the public surface serving ciphertext; grants need the parallel paragraph (below).

The encryption sentence — folded in here from #571 item 4. What the encryption does and does not protect against now that a share means the server opens the owner's file for the recipient. It was the last open item on #571 and it belongs in this run rather than on its own: a sentence about grants is unintelligible on a page that does not yet document grants. Same wording should serve #238, which is the standing question about whether cross-instance transfer should be client-side E2E — so write it once, precisely, and reference it from both. The existing "This is not zero-knowledge, and we won't call it that" paragraph is the right register and the right neighbour.

docs/handbook/index.md — the Pages table describes sharing.md as "Share links: modes, what they protect, policy". Needs rewording once the page covers grants.

docs/handbook/groups.md — currently frames app-owned groups around "peering and admin-group use". Receiving a share is now a third use, and it is the one most users will meet first. Also: a group-derived grant follows membership, so leaving a group takes the file access with it — that belongs here as much as in sharing.md.

docs/handbook/users-access.md — the picker draws on accounts and groups. Worth a short note on why it is search-only and why an operator cannot get a full recipient list out of it, since that will otherwise read as a missing feature.

docs/handbook/file-browser.md — row-menu actions and the Shares view; both changed.

docs/handbook/encryption.md — check whether the key-custody discussion needs the grant path spelled out (the server resolving the owner's identity to serve a recipient).

docs/handbook/spaces.md — genuine open question rather than a known edit: how grants interact with space membership, and whether a space file can be granted onward. Check against the Delegated refusal before writing anything.

README.md and ARCHITECTURE.md — check whether either describes sharing as links-only. This is the sharing analogue of the #124 tripwire, and like #124 it should be written from what shipped, not from intent.

Not documentation, but found during this review

The admin Sharing page subtitle still reads "Who may create share links, and the limits the server enforces on them." The page now governs grants too, so the sentence is stale in the product, not just in the docs. Small copy fix, i18n ×4 — worth doing in the same round so the page and the handbook agree.

Notes for whoever picks this up

  • v0.6.212's CHANGELOG entry is the most complete prose description of the slice and a good source; it is deliberately written as one feature story rather than ten PRs.
  • The decision records live in the #571 comments (picker design, the two-switch separation, the structural re-share refusal) and in the PR bodies for #575, #576, #581, #582, #583.
  • The panel itself has not yet been visually reviewed on the dogfood — the admin switch has, the dialog and tabs have not. If a fix round changes behaviour, it lands before the docs describe it.
The #529 2/3 slice shipped in **v0.6.212** with no documentation. `docs/handbook/index.md` states the rule it broke: > Every shipped feature that changes admin or user behavior updates a page here in the same release cycle, like the changelog. Sharing changed shape rather than gaining an option, so this is not a matter of adding a paragraph: several pages now assert something that is no longer true. This issue is the docs run that closes that gap. ## What changed in v0.6.212 The model, stated once so every page below can be written against it: - A share now carries an **addressee** — a local account or a group — not only a link. The file appears for that person under `/shared`, reached **as its owner**, so contents resolve exactly as they do for the owner. - **Three role labels** over primitives that already existed: Can view → `read`, Can edit → `write`, Can upload → `AllowUpload` (folders only). - **Links split in two.** An *internal link* is just the file's URL — no stored object, nothing to expire, revoke or count, and it grants nothing to someone who does not already have access. A *public link* is the existing `/s/` surface, unchanged: password, expiry, upload, mode selector. - **Recipients cannot re-share.** Structural, not policy: `scope.Driver.Delegated` answers "was this path reached through someone else's grant", and the API refuses before writing. Only the owner manages the grant list. - **Internal sharing has its own admin switch** (`ShareInternalDisabled`), separate from the public-link switch. Stored negative, so an instance upgrading into the field keeps sharing on. `TestPublicLinkPolicyDoesNotGovernGrants` pins the separation. - **Recipient picker is search-only** (`GET /api/v1/recipients?q=`). Minimum 2 characters; a shorter query is a 400, not an empty list. Prefix-only on token boundaries (`.`, `-`, `_`, space, `@`). Capped at 20 **after** ranking. Caller excluded from their own results. Deliberately *not* the admin candidates endpoint, which enumerates everything and would have 403'd for non-admins anyway. - **Shares view has two tabs.** *My shares* lists grants and public links together, grouped by file. *Shared with me* is flat, one row per granted item, showing **via {group}** where a grant came from group membership. ## Surfaces to work through **`docs/handbook/sharing.md` — the main one.** It opens with "Two ways to get a file to someone else, depending on whether they run Cairn" and a two-row table, then says "This page is about links." All three statements are now wrong. Needs a third row (recipient on this instance → internal grant → their `/shared`), the grants section, the role labels, the internal/public link split, and the no-re-share rule. Its "What this protects — stated precisely" section currently reasons only about the public surface serving ciphertext; grants need the parallel paragraph (below). **The encryption sentence — folded in here from #571 item 4.** What the encryption does and does not protect against *now that a share means the server opens the owner's file for the recipient*. It was the last open item on #571 and it belongs in this run rather than on its own: a sentence about grants is unintelligible on a page that does not yet document grants. Same wording should serve **#238**, which is the standing question about whether cross-instance transfer should be client-side E2E — so write it once, precisely, and reference it from both. The existing "This is not zero-knowledge, and we won't call it that" paragraph is the right register and the right neighbour. **`docs/handbook/index.md`** — the Pages table describes `sharing.md` as "Share links: modes, what they protect, policy". Needs rewording once the page covers grants. **`docs/handbook/groups.md`** — currently frames app-owned groups around "peering and admin-group use". Receiving a share is now a third use, and it is the one most users will meet first. Also: a group-derived grant follows membership, so leaving a group takes the file access with it — that belongs here as much as in sharing.md. **`docs/handbook/users-access.md`** — the picker draws on accounts and groups. Worth a short note on why it is search-only and why an operator cannot get a full recipient list out of it, since that will otherwise read as a missing feature. **`docs/handbook/file-browser.md`** — row-menu actions and the Shares view; both changed. **`docs/handbook/encryption.md`** — check whether the key-custody discussion needs the grant path spelled out (the server resolving the owner's identity to serve a recipient). **`docs/handbook/spaces.md`** — genuine open question rather than a known edit: how grants interact with space membership, and whether a space file can be granted onward. Check against the `Delegated` refusal before writing anything. **`README.md` and `ARCHITECTURE.md`** — check whether either describes sharing as links-only. This is the sharing analogue of the #124 tripwire, and like #124 it should be written from what shipped, not from intent. ## Not documentation, but found during this review The admin **Sharing** page subtitle still reads "Who may create share links, and the limits the server enforces on them." The page now governs grants too, so the sentence is stale in the product, not just in the docs. Small copy fix, i18n ×4 — worth doing in the same round so the page and the handbook agree. ## Notes for whoever picks this up - v0.6.212's CHANGELOG entry is the most complete prose description of the slice and a good source; it is deliberately written as one feature story rather than ten PRs. - The decision records live in the #571 comments (picker design, the two-switch separation, the structural re-share refusal) and in the PR bodies for #575, #576, #581, #582, #583. - **The panel itself has not yet been visually reviewed on the dogfood** — the admin switch has, the dialog and tabs have not. If a fix round changes behaviour, it lands before the docs describe it.
Author
Owner

Unblocked, with one carve-out.

The panel has now been verified live on v0.6.213 in both directions with a real second account — picker, grant creation, both Shares tabs, and the /shared round trip as the recipient. See the #571 thread for what was confirmed.

So most of this issue can proceed. Two sections should wait, because open fixes will change what is true:

  • Roles. Do not write the three-label section yet. Can upload does not exist in the product — only Can view and Can edit ship today (#589). Writing it from the issue's intent rather than from what shipped is precisely the #124 mistake.
  • What a recipient can do. Hold this too. #588 will change which actions a recipient is offered on a delegated path; today the menu offers writes the server refuses. Any sentence about recipient capability written now will be wrong twice — once against today's behaviour and once against the fix.

Everything else is settled and safe to write from: the addressee model, the internal/public link split, the no-re-share rule, the search-only picker and why it refuses a blank query, the two admin switches and their separation, and the two Shares tabs.

Also decided since this issue was written: the share dialog's policy notices stay neutral, not amber — the amber style remains reserved for administrator-actionable faults (v0.6.211). If the docs describe or screenshot those states, describe them as notices.

**Unblocked, with one carve-out.** The panel has now been verified live on v0.6.213 in both directions with a real second account — picker, grant creation, both Shares tabs, and the `/shared` round trip as the recipient. See the #571 thread for what was confirmed. So most of this issue can proceed. Two sections should wait, because open fixes will change what is true: - **Roles.** Do not write the three-label section yet. `Can upload` does not exist in the product — only `Can view` and `Can edit` ship today (**#589**). Writing it from the issue's intent rather than from what shipped is precisely the #124 mistake. - **What a recipient can do.** Hold this too. **#588** will change which actions a recipient is offered on a delegated path; today the menu offers writes the server refuses. Any sentence about recipient capability written now will be wrong twice — once against today's behaviour and once against the fix. Everything else is settled and safe to write from: the addressee model, the internal/public link split, the no-re-share rule, the search-only picker and why it refuses a blank query, the two admin switches and their separation, and the two Shares tabs. Also decided since this issue was written: the share dialog's policy notices stay **neutral, not amber** — the amber style remains reserved for administrator-actionable faults (v0.6.211). If the docs describe or screenshot those states, describe them as notices.
Author
Owner

Done — #591, plus the held paragraph in #593. All shipped in v0.6.214, so the handbook and the release it describes landed in the same tag.

What each surface got:

  • sharing.md rewritten: three-way opening table, the grants section (addressee model, two roles, search-only picker with the enumeration rationale, group grants following membership, the structural re-share refusal quoting the server's own error), the encryption paragraph written to serve #238 (a grant moves no key material; the server opens the owner's file for the recipient; server-side transparent, not end-to-end; why peering re-encrypts instead), Internal link, the Shares view, and all public-link content preserved under "Public links". The "what a recipient is offered" paragraph was deliberately held out of #591 and shipped inside #593 with the behaviour it describes.
  • index.md, groups.md, file-browser.md, README.md, ARCHITECTURE.md per the issue — including the §4 historical clause "encrypted-content share links remain out (#19)" corrected to what shipped in v0.6.4–v0.6.6.
  • encryption.md: the operational note claiming share links over encrypted content are unsupported was five months stale; replaced with the current truth plus the grants boundary.

Deliberate deviations from the issue text, recorded:

  1. Roles are documented as two, not three. The rev-2 mockup settled "upload a public-link checkbox rather than a per-person role"; #589 is closed as superseded on that evidence. The docs state the settled design with its reasoning.
  2. users-access.md untouched. The picker rationale (search-only, no enumeration) lives in sharing.md where users meet the picker; the admin page never surfaces recipients, so a note there would explain an absence nobody encounters on that page. If an operator FAQ grows later, it can point at sharing.md.
  3. spaces.md untouched, deliberately. Recon found that resolveOwned permits any space member to grant space content outward — whether that is intended is an open product question, now #595. The docs say nothing about space-file grants until it is decided; writing either answer now would be deciding it by documentation.

The amber-vs-neutral notice decision from the #571 thread is baked in: the dialog's policy notices are described as notices.

**Done — #591, plus the held paragraph in #593. All shipped in v0.6.214, so the handbook and the release it describes landed in the same tag.** What each surface got: - **sharing.md** rewritten: three-way opening table, the grants section (addressee model, two roles, search-only picker with the enumeration rationale, group grants following membership, the structural re-share refusal quoting the server's own error), the encryption paragraph written to serve #238 (a grant moves no key material; the server opens the owner's file for the recipient; server-side transparent, not end-to-end; why peering re-encrypts instead), Internal link, the Shares view, and all public-link content preserved under "Public links". The "what a recipient is offered" paragraph was deliberately held out of #591 and shipped inside #593 with the behaviour it describes. - **index.md, groups.md, file-browser.md, README.md, ARCHITECTURE.md** per the issue — including the §4 historical clause "encrypted-content share links remain out (#19)" corrected to what shipped in v0.6.4–v0.6.6. - **encryption.md**: the operational note claiming share links over encrypted content are unsupported was five months stale; replaced with the current truth plus the grants boundary. **Deliberate deviations from the issue text, recorded:** 1. **Roles are documented as two, not three.** The rev-2 mockup settled "upload a public-link checkbox rather than a per-person role"; #589 is closed as superseded on that evidence. The docs state the settled design with its reasoning. 2. **users-access.md untouched.** The picker rationale (search-only, no enumeration) lives in sharing.md where users meet the picker; the admin page never surfaces recipients, so a note there would explain an absence nobody encounters on that page. If an operator FAQ grows later, it can point at sharing.md. 3. **spaces.md untouched, deliberately.** Recon found that `resolveOwned` permits any space member to grant space content outward — whether that is intended is an open product question, now **#595**. The docs say nothing about space-file grants until it is decided; writing either answer now would be deciding it by documentation. The amber-vs-neutral notice decision from the #571 thread is baked in: the dialog's policy notices are described as notices.
Cordy closed this issue 2026-09-18 02:02:04 +00:00
Sign in to join this conversation.
No labels
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Cordy/Cairn#585
No description provided.