Skip to content

feat: one sharing vocabulary across pastes, workspaces and the audit log - #74

Merged
darwin67 merged 4 commits into
mainfrom
feat/sharing-vocabulary
Oct 11, 2026
Merged

darwin67 merged 4 commits into
mainfrom
feat/sharing-vocabulary

Conversation

@darwin67

Copy link
Copy Markdown
Member

Summary

The design doc's "Vocabulary" section reduces four overlapping sharing concepts to three settings. Each one reads as a sentence. This PR puts those words in the interface. Stored values are unchanged (audience, external_sharing_policy, visibility), so the API, the CLI and existing audit metadata keep working.

Setting Was Now
Who can see this (paste) Workspace / Unlisted / Public Workspace / Anyone with the link / Public
Sharing outside the team (workspace) External sharing: Disabled / Unlisted links / Public Members only / Members may share a link / Members may also publish
Who can join (workspace) Visibility: Open / Private Anyone in the organization / Invite only

Commits

  1. TextbinWeb.Sharing holds every label, sentence and icon. The paste editor, detail page and list now use it. Pastes.audience_allowed?/2 is now public, so the editor disables options using the same rule the changeset enforces, not a copy of it.
  2. Workspace settings show a sentence under each setting, and the sentence follows the selection before you save.
  3. Workspace lists, the new-workspace form, the organization overview and the audit log all use the same labels. Older audit events render with the new words too.

⚠️ The design doc and the code disagree

The doc says tightening "Sharing outside the team" never changes pastes already shared. The code does the opposite: Organizations.clamp_paste_audiences/1 downgrades existing pastes when the setting is saved. I kept the code's behaviour, because it's the safer default for an owner shutting off external access. The wording follows the code:

  • Members only: "Links shared earlier stop working."
  • Members may share a link: "Public pastes become link-only."

Which one should win, the doc or the code? If the doc's behaviour is the intent, that change belongs in its own PR, together with a doc or code fix.

Test plan

  • mix test: 567 tests, 0 failures. New tests:
    • Unit tests for Sharing.
    • The settings sentence follows the selection without saving.
    • Audit descriptions for join and sharing changes.
    • Paste badges and sentences for link and public pastes.
  • mix credo reports no issues. mix compile --warnings-as-errors is clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_019fnjMN7WpEjQJD2zveakV6


Generated by Claude Code

The design doc collapses four overlapping sharing concepts into three
settings that each read as a sentence: "Who can see this" on a paste, and
"Sharing outside the team" and "Who can join" on a workspace. Add
TextbinWeb.Sharing as the single place those words live, and move the paste
editor, detail page and list onto it.

Stored values (audience, external_sharing_policy, visibility) are unchanged:
the API, the CLI and recorded audit metadata depend on them.

- Badges read "Anyone with the link" instead of "Unlisted".
- The detail sentence for a public paste says "Anyone can see this paste."
- A forbidden audience in the editor names the workspace setting that
  turns it off.
- Pastes.audience_allowed?/2 is now public so the editor disables options
  with the same rule the changeset enforces, instead of a copy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019fnjMN7WpEjQJD2zveakV6
…team"

Replace the "Visibility" (Open/Private) and "External sharing"
(Disabled/Unlisted links/Public) selects with the design doc's wording,
and put a sentence under each that describes the option being considered.
The form now re-renders on change so the sentence follows the selection
before anything is saved.

The sharing sentence states what tightening does to pastes that are
already shared, because Organizations clamps their audience on save:
"Members only" stops earlier links working and "Members may share a link"
turns public pastes link-only. The design doc says tightening never
changes existing pastes; the code does, and the wording follows the code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019fnjMN7WpEjQJD2zveakV6
Workspace lists, the new-workspace form and the organization overview say
"Who can join: Invite only" or "Anyone in the organization" instead of the
raw "open"/"private" value, with a building icon for open workspaces so
the globe stays reserved for public pastes.

Audit entries for these settings are titled "Who can join changed" and
"Sharing outside the team changed" and describe the change with the same
labels. Recorded metadata is unchanged, so older events render with the
new words too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019fnjMN7WpEjQJD2zveakV6
@github-actions github-actions Bot added the feat label Oct 11, 2026
Describe current access separately from admission: existing members keep access when a workspace becomes invite-only; owners add new members. Update LiveView sentence coverage. Verified 567 tests, Credo, and rendered private/open preview states.
@darwin67

darwin67 commented Oct 11, 2026 •

Copy link
Copy Markdown
Member Author

Oracle review complete: signed off after correcting the invite-only workspace explanation. Existing members retain access, including those who self-joined while open; owners must add new members. No permissions, stored values, or audience-clamp behavior changed. The nearby comment now describes policy tightening on save rather than autosave. Validation: mix precommit (567 ExUnit tests plus JS tests), mix credo, and real Chromium checks of private settings and the unsaved open-policy preview passed. Both screenshots were inspected for readable wording/layout. Corrections committed and pushed without rewriting published history. Review session and visual artifacts: https://ampcode.com/threads/T-01a12594-e2f1-75be-b343-9239564f5c84

Post-push CI is green: memory/local/S3 Elixir tests, Rust tests, formatting/linting, and production-container build all passed. Release/publication jobs skipped as expected.

@darwin67
darwin67 marked this pull request as ready for review October 11, 2026 04:37
@darwin67
darwin67 merged commit b0075af into main Oct 11, 2026
17 checks passed
@darwin67
darwin67 deleted the feat/sharing-vocabulary branch October 11, 2026 04:37
@chaba2-bot chaba2-bot Bot mentioned this pull request Oct 11, 2026
darwin67 added a commit that referenced this pull request Oct 11, 2026
## Summary

This settles the doc-vs-code mismatch flagged in #74.

`docs/design.md` said that tightening "Sharing outside the team" *never
changes pastes already shared*. The code does the opposite at two
layers:

- **On save:** `Organizations.clamp_paste_audiences/1` rewrites existing
audiences to fit the new setting.
- **On every read:** shared-link access re-checks the workspace's
current setting.

The code's behaviour is the one to keep:

- An owner who switches to "Members only", for example after a leak,
needs links already shared to stop working.
- Because the clamp rewrites stored audiences, loosening the setting
later doesn't quietly re-share anything.

The doc now describes that behaviour. The UI has said the same since
#74.

Doc-only change. No code changes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_019fnjMN7WpEjQJD2zveakV6

---
_Generated by [Claude
Code](https://claude.ai/code/session_019fnjMN7WpEjQJD2zveakV6)_

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants