Skip to content

feat(channels): edit channel details with confirmed saves - #369

Merged
tellaho merged 6 commits into
mainfrom
tho/channel-details
Sep 29, 2026
Merged

tellaho merged 6 commits into
mainfrom
tho/channel-details

Conversation

@tellaho

@tellaho tellaho commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Category: new-feature

User Impact: Channel owners and admins can edit the name, description, and supported privacy setting together in Channel Settings, with clear Save and Cancel actions.

Problem: Channel Settings does not show the full channel details or offer a deliberate way to update them. A missing save response must not encourage users to send the same change again blindly.

Solution: Show verified details and open a focused shared dialog for editing, with Unicode-aware input limits and compact counters beside labels only near the limit. Save rechecks authority, confirms the relay's resulting metadata, and offers check-only recovery when the outcome is uncertain.

Scope: ordinary stream/forum channels on hosts providing the dedicated details capability. Public → private is supported with an explanation before Save; private → public, member administration, Leave, and packaged/native writer parity are not included. No automatic retries or durable recovery queue; concurrent writers can still race after the last version check.

Changes

File changes

dev/relay-broker-api.test.mjs
Exercise the dedicated routes through the real broker HTTP contract, including live-owner requirements, malformed commands, foreign signers, and unchanged lifecycle/outbox admission.

dev/relay-broker.mjs
Expose narrowly validated details signing/publication on the existing community-bound live connection.

docs/channels.md
Document editing, limits, permissions, uncertainty, adapter limitations, and the approved FOUNDATION integration rationale.

src/bundled/channels/ChannelDetailsEditor.test.tsx
Cover deliberate Save/Cancel, accessible validation, input caps, focus and nested Escape, pending dismissal guards, and recovery across remounts and identity changes.

src/bundled/channels/ChannelDetailsEditor.tsx
Keep the destination-bound draft in the shared Dialog. Cap Name/Description at 120/1,000 code points, preserve existing suffixes during middle edits, and show numeric label-row counters only near the limits.

src/bundled/channels/ChannelSettingsPanel.tsx
Show description and explicit visibility, and offer the capability-backed editor only on eligible channel views.

src/bundled/channels/Channels.module.css
Wrap descriptions safely and align compact counters with their labels without changing shared controls.

src/bundled/channels/ChannelsPage.tsx
Pass the session-owned details capability into Settings.

src/features/relay/channel-details-protocol.ts
Define bounded metadata drafts and commands, exact signed metadata/authority interpretation, and private-only visibility changes.

src/features/relay/channel-details.test.ts
Cover fresh authority checks, stale bases, signer integrity, cancellation, rejection versus uncertainty, check-only recovery, and real session wiring.

src/features/relay/channel-details.ts
Own writes and session-memory uncertainty. Recheck permissions before signing/publication and require matching fresh metadata before reporting success.

src/features/relay/contracts.ts
Represent description and explicitly known visibility without treating missing metadata as public.

src/features/relay/discovery.ts
Project signed details while keeping work-session metadata out of ordinary descriptions.

src/features/relay/fold.test.ts
Update the discovery shape assertion for the added metadata fields.

src/features/relay/prepared.test.ts
Update the prepared discovery shape assertion without changing membership or cache behavior.

src/features/relay/session.ts
Compose the feature owner at the approved import, construction, exposure, cancellation, clear, and disposal seams (13 added lines); no session redesign.

src/features/relay/store.test.ts
Cover description-only updates, explicit/unknown visibility, clearing descriptions, and exclusion of work-session machine metadata.

src/features/relay/store.ts
Include description and visibility in snapshot equality so metadata-only edits reach subscribers.

src/features/relay/transport.ts
Expose the optional, dedicated details writer without widening the ordinary message writer.

Reproduction steps

  1. Run the browser app with its configured development broker; restart an already-running broker if it predates the new details routes.
  2. Open an ordinary channel where you are a direct owner/admin, then Channel Settings → Edit details. Confirm Name, Description, and Visibility are shown, and Save changes is disabled until a valid change is made.
  3. Type or paste into Name and Description. New input stops at 120 and 1,000 Unicode code points; existing over-limit relay values can be reduced or replaced without silently truncating their text, and Save stays invalid until they meet the limits; near-limit counters appear on the label row as 108/120 and 900/1,000. Shorter values have no counter or routine helper text.
  4. Change fields, select Private, and inspect the consequence text without saving. Cancel, then reopen: the original values should return. Escape should dismiss the select first, then the edit dialog, without closing Settings prematurely.
  5. Live-write acceptance still required: use a disposable channel for Save. Confirm the panel/header/sidebar use the relay-confirmed values. Test public → private only on a channel intended to become private; this editor cannot undo it.
  6. Exercise uncertain-save recovery in a controlled environment: the submitted draft must lock and Check save status must read without publishing another command.

Validation and remaining gates

  • Rebased onto 3a19fa43075283423c88a68d4a1362fade28ad3e without conflicts. git range-diff reports both feature commits unchanged; newer mainline changes were retained without modifying their tests.
  • At clean head 7ef88c5b1b95ec218953fe0418cad177a921e043, mandatory push hooks passed TypeScript, 184 related Vitest files / 2,816 tests, and design-system types/guards. git diff --check passed and remote HEAD was verified.
  • Before rebase, the final editor snapshot passed 405 Vitest files / 4,798 tests and real Chromium checks of caps/middle edits, counters, Cancel/reopen, focus/nested Escape, and narrow layout. This is earlier-snapshot evidence, not a claim that the full suite ran at the rebased head.
  • No browser test cases added or removed. State/authority matrices are colocated unit/component/broker tests; existing hosted CI supplies broader coverage.
  • Remaining gates: live Save/privacy and live revocation/recovery acceptance, final human acceptance, and reviewer confirmation of these fixes remain outstanding. GitHub currently marks the PR ready; that state was not changed by this follow-up and does not establish acceptance. No real channel details or privacy write was performed during the agent walkthroughs.

Review fixes at 804b51fc5ccd39e4811342221e90a6e274556ee0

  • Conflict reload adopts authoritative private visibility while retaining editable name/description drafts; regressions cover reload followed by Save in the component and real capability.
  • Input limits block inserted growth without truncating existing over-limit relay content. Regression cases cover deletion, selection replacement, middle edits, emoji and returning within limits for both fields.
  • Name normalization matches the relay's Unicode White_Space and interleaved leading-hash rules. Noncanonical commands are rejected before signing; U+0085, U+FEFF and other boundary differences are covered through confirmation.
  • Mandatory push hooks passed TypeScript, 184 related Vitest files / 2,827 tests (including all 19 editor tests and 25 capability/protocol tests), and design-system types/guards at that clean head. Remote HEAD and git diff --check verified.
  • Actual Chromium app at the same head passed native insertion/replacement at capacity, U+0085 draft validation, numeric counter, and Cancel/reopen checks. Existing-over-limit and privacy-conflict cases are component/capability test evidence, not live relay writes. No browser-suite cases added or removed.
  • Optional already-private visibility-tag optimization is deferred; this follow-up fixes the three correctness blockers without expanding the command contract.

Screenshots / demos

Actual running-app captures at 804b51fc, in dark theme and cropped to the dialog. Both use neutral sample text entered as unsaved drafts and then cancelled; no channel was renamed or changed for these images.

Normal fields: no routine character hints

Edit channel details with neutral unsaved sample name and description

Near the limit: numeric count on the label row

Description label with a compact 950/1,000 counter and neutral unsaved sample text


Implementation and PR preparation assisted by Carl (AI), under Taylor Ho's direction.

@tellaho
tellaho marked this pull request as ready for review September 28, 2026 21:32
@tellaho
tellaho requested review from a team, comp615 and wesbillman as code owners September 28, 2026 21:32

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Carl, an automated reviewer, commenting via Wes’s GitHub account.

Changes required. Reviewed head 7ef88c5b1b95ec218953fe0418cad177a921e043 against base 3a19fa43075283423c88a68d4a1362fade28ad3e. Three P2 correctness findings are inline: conflict recovery, destructive input limiting, and relay name canonicalization. Fix those with regression coverage.

Required publication hygiene: remove or replace the employee-only issue link and private conversation link in Overview, and recapture the first screenshot using neutral sample channel data rather than the internal description/ticket references. This is a public repository; private workflow context does not belong in the public PR. The code diff did not expose those details.

Hosted CI is green; targeted diagnostics reproduced the findings at this clean head. Live Save/privacy/revocation/recovery and human acceptance remain unverified, as the PR records. Keep those gates explicit. Browser-only scope and check-only uncertain recovery are accepted; no native adapter or recovery subsystem expansion is requested.

Optional: emit the private visibility tag only for an actual public→private transition. Sending it on every already-private rename causes redundant relay cache invalidation and visibility-change records.

Comment thread src/bundled/channels/ChannelDetailsEditor.tsx Outdated
Comment thread src/bundled/channels/ChannelDetailsEditor.tsx Outdated
Comment thread src/features/relay/channel-details-protocol.ts Outdated
@tellaho

tellaho commented Sep 28, 2026

Copy link
Copy Markdown
Contributor Author

@wesbillman Fixed the three correctness blockers in 804b51fc:

  • Conflict reload adopts authoritative private visibility without discarding text edits; reload → Save is covered in the editor and capability.
  • Input limiting preserves existing over-limit content during deletion/replacement and blocks only inserted growth; Save remains invalid until within limits.
  • Names use the relay’s Unicode whitespace/hash canonicalization before signing, with matching confirmation and U+0085/U+FEFF regressions.

Removed the internal workflow links from the public description and replaced both screenshots with verified real-app captures containing only neutral, unsaved sample text. All three directly addressed threads are resolved.

Validation at that clean head: mandatory hooks passed TypeScript, 184 related Vitest files / 2,827 tests, and design-system checks; remote HEAD verified; DCO passed. Actual Chromium checks passed native insertion/replacement at capacity, Unicode draft validation, counter rendering and Cancel/reopen. Broader CI is still running. Live Save/privacy/revocation/recovery and final human acceptance remain unverified. The optional already-private visibility-tag optimization is deferred.

Please recheck the fixes; no approval or merge performed.

— Carl (AI), implementing under Taylor Ho’s direction.

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Star Lord’s automated source review via Wes’s account — follow-up to the previous review.

Reviewed head 804b51fc5ccd39e4811342221e90a6e274556ee0 against pinned base 3a19fa43075283423c88a68d4a1362fade28ad3e.

The three prior correctness findings are addressed in source: conflict reload adopts authoritative private visibility while retaining text; input limits preserve existing over-limit content during reductions/replacements; and name canonicalization matches the relay’s Unicode whitespace/leading-hash rules before signing and confirmation. The added regression cases cover those paths. The public description no longer contains the previously flagged internal links, and I inspected both replacement screenshots: they use neutral sample text.

One new P2 integration finding is inline: the eagerly mounted details reader is incompatible with the browser fixture’s incomplete visibility metadata. This is new evidence from the hosted merged-tree run, not a request to weaken fail-closed validation or expand the accepted feature scope.

Validation limits: source/artifact inspection only; I did not execute PR code, tests, or an app, and did not perform live writes. Hosted run 36490169550 tested merge 0ddda28ba5951932457bbdb9bec842e74993be1c (head above plus main a2bfc8120233453b376c2382ad8e990b987bdbda), not just the pinned review base. Browser shards 1 and 3 fail in both engines. JavaScript separately reports 5,001 passing tests and one timeout in live.test.ts (“keeps quiet-channel unread evidence when another filter fills its replay allowance”); its cause is not established here. Do not treat the earlier targeted-hook pass as a green merged-tree result. Live Save/privacy/revocation/recovery and human acceptance remain outstanding as documented.

This is a non-blocking COMMENT review, not approval or merge authorization. The optional already-private visibility-tag optimization remains optional.

Comment thread src/bundled/channels/ChannelSettingsPanel.tsx
@tellaho
tellaho force-pushed the tho/channel-details branch 2 times, most recently from a773589 to 61e2b3d Compare September 28, 2026 23:17
@tellaho

tellaho commented Sep 28, 2026

Copy link
Copy Markdown
Contributor Author

AI-generated update from Carl, acting for Taylor.

@wesbillman The browser-fixture integration blocker is fixed in 61e2b3d7a3d9b7ffb7e8d6e72549993e438edab8 (rebased onto f310994e). Ordinary fixture channels now include explicit public visibility; private-session and DM metadata, malformed/unknown unit cases, and production verification remain unchanged. Both affected journeys wait for the independent details permission read before their existing global alert assertions. The inline thread is resolved.

Validation:

  • Reproduced the verification alert in Chromium and WebKit before the fixture repair.
  • bin/pnpm test:browser tests/browser/unread.spec.mjs tests/browser/agent-activity.spec.mjs --project chromium --project webkit --no-deps: all 24 cases passed at the clean pushed head, with no retries or weakened assertions.
  • Push hooks: TypeScript, 2,841 related tests, and design checks passed. DCO passed; fresh hosted CI is still running.

No production changes in this fix. Live Save/privacy/recovery and human acceptance remain unverified; this is not approval or merge authorization.

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Star Lord automated source follow-up (via Wes's account)

Reviewed head 61e2b3d7a3d9b7ffb7e8d6e72549993e438edab8 against base 2dd479666ca5bd40166b7e3e79cf3fb0872baa28.

The previous P2 browser-fixture integration finding is addressed. tests/browser/fixture.mjs:732–748 now supplies explicit public visibility for ordinary channels while excluding private sessions and both DM fixture families. The production fail-closed validation remains intact. The changed Settings journeys wait for the independent details permission read before their existing global alert assertions, rather than suppressing errors or adding sleeps. No browser cases were added/removed by the repair. No actionable code defect found in this follow-up; minimalness/elegance/correctness: 9/10 each for the repair.

P2 — The new repair commit republishes internal identifiers in public attribution

The new 61e2b3d7 commit's Co-authored-by address includes an internal deployment hostname and stable agent identifier. The same address appears in all six attached commits. This is public Git metadata, separate from the repaired PR description/screenshots. Please replace the internal address with an approved public attribution address, preserving the actual contributor credit and valid DCO sign-offs. Have the authorized contributor perform any history update; do not substitute another person's authorship or remove required certification. The identifiers are intentionally not repeated here. This is a public-material privacy finding, not a credential-exposure claim.

The description's two older-snapshot images were inspected again and show neutral sample drafts; the previously flagged internal coordination links remain removed. The new commit metadata is fresh publication evidence for this finding, not a reopening of the accepted editor scope.

Evidence and limitations

  • Source-only: I ran no PR code, tests, builds, installs, app, or live channel writes. The verified 1,677-file snapshot remained unchanged. Reviewed the repair, its fixture consumers, and existing error/retry versus success/cancel focus paths; runtime focus and live-write acceptance are not certified.
  • Hosted run 36497211181 checked merge 4eb79ddd12d56e7c1e06d1be739cdda7d3909af4, combining the head/base above. Logs show the formerly failing profile-activity Settings scenario and both unread Settings scenarios passing in Chromium and WebKit.
  • The snapshot is not fully green: five browser shards passed; WebKit shard 1 was cancelled after the relevant profile-activity case passed, leaving that shard incomplete and CI required failed. Windows validation was skipped. Rust/tool integration, browser measurements, and JavaScript passed; JavaScript reported 5,087 tests/419 files (356.88s wall, 628.61s summed test execution). These are hosted observations, not local execution or a controlled before/after performance claim.
  • Complete final browser validation, live Save/privacy/revocation/recovery, and human acceptance remain explicit gates. The optional already-private visibility-tag optimization remains optional.

Non-blocking COMMENT only; no approval or merge authorization.

@tellaho
tellaho force-pushed the tho/channel-details branch from 61e2b3d to da7d2d4 Compare September 29, 2026 05:22
tellaho and others added 6 commits September 29, 2026 09:03
Add permission-gated name, description, and public-to-private editing in channel settings. Keep signing and publication behind a dedicated capability, require fresh relay readback, and preserve uncertain-save recovery without replay.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Use the shared modal for channel details with deliberate save and cancel, guarded recovery, connected field errors, and focus restoration. Cap name and description edits by Unicode code point while preserving suffixes and show compact label-row counts only near each limit.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Reconcile enforced private visibility on reload while preserving name and description edits. Cover conflict/reload/save in the editor and production capability.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Cap inserted growth against the previous length without truncating existing excess. Keep reductions and replacements exact and require valid lengths before Save.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Share Unicode White_Space normalization between the editor and command validation, preserving the relay treatment of U+0085 and U+FEFF. Reject noncanonical commands before signing and cover canonical readback.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Give ordinary browser fixture channels explicit public visibility without changing private-session or DM metadata. Wait for the independent details permission read before diagnostic assertions, retaining the existing global error checks.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
@tellaho
tellaho force-pushed the tho/channel-details branch from da7d2d4 to be82347 Compare September 29, 2026 16:14
@tellaho

tellaho commented Sep 29, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto 14a2e7ed585b130315629ded39d1b83b05eb2a53 and pushed be823473c6c60dcc4afac77d05fdf7804f9fd28d. GitHub now reports no merge conflict.

The conflict was two independent tests appended to dev/relay-broker-api.test.mjs. Both main's explicit-owner community setup test and this PR's channel-details authorization/publication test are preserved verbatim. git range-diff shows only the insertion context changed across the six feature commits; no production logic or assertions were changed to resolve it.

Validation at the new head:

  • Required push hooks: TypeScript, 187 Vitest files / 2,946 tests, and design-system types/guards passed. This includes all 81 broker API tests, 19 editor tests, and 25 details capability/protocol tests.
  • 46 Chromium/WebKit cases passed across Settings, activity/profile, menu focus, and unread journeys (bin/pnpm test:browser channel-settings.spec.mjs agent-activity.spec.mjs unread.spec.mjs menu-dismiss.spec.mjs --project chromium --project webkit --no-deps --workers=1; the unread selector also includes sidebar/thread unread files).
  • git diff --check, commit attribution audit, remote-head verification, and hosted DCO passed. Fresh CI is running, not yet an all-green result.

Existing attribution is unchanged; its separate policy question remains open. Live Save/privacy/recovery and final human acceptance remain outstanding. No merge or PR-state change.

— Carl (AI), acting at Taylor Ho's request.

@tellaho
tellaho merged commit 73f2a7c into main Sep 29, 2026
20 checks passed
@tellaho
tellaho deleted the tho/channel-details branch September 29, 2026 18:07
johnmatthewtennant pushed a commit that referenced this pull request Sep 29, 2026
…t-update-drafts

* commit '0a4982797f38164d75e3e8f48e58fabb9dd59e66': (66 commits)
  Show saved local and relay inventory while retaining existing import controls (#286)
  feat(channels): edit channel details with confirmed saves (#369)
  test(channels): discover the hoverable width for activity corners (#416)
  Fix flaky WebKit menu focus browser test (#409)
  Test Goose connections and fix Pi test false failures (#383)
  feat: open threads with verified newest-first windows (#154)
  Add agent conversation context selection (#382)
  test: keep behavioral coverage without cosmetic matrices (#410)
  Fix reading position and composer caret on channel return (#411)
  fix(channels): prevent clipped activity rows and remove separators (#377)
  ci: publish signed macOS updater artifacts in prereleases (#387)
  feat(messages): add jump to latest controls (#374)
  Align reply summaries with message content (#408)
  Add centered thinking pills to agent avatars (#351)
  Keep focus where the user moved it when a menu finishes closing (#355)
  Browse legacy identities without a destination and review text before cloning (#285)
  Show separate identity cards and prevent duplicate imports (#225)
  Polish message and thread spacing, grouping, and typography (#364)
  Remove the Away avatar badge stroke (#395)
  fix(profiles): hide activity on human profiles (#391)
  ...

Signed-off-by: Sol <49aa1f65411fd096d2e2ec144f1e7aa36fdc76d1b907cfdf7be000c66f9d3b8e@buzz.block.builderlab.xyz>
morgmart added a commit that referenced this pull request Sep 29, 2026
…redesign

* origin/main:
  Show saved local and relay inventory while retaining existing import controls (#286)
  feat(channels): edit channel details with confirmed saves (#369)
  test(channels): discover the hoverable width for activity corners (#416)

Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Co-authored-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz>
johnmatthewtennant pushed a commit that referenced this pull request Sep 29, 2026
* origin/main: (25 commits)
  Show saved local and relay inventory while retaining existing import controls (#286)
  feat(channels): edit channel details with confirmed saves (#369)
  test(channels): discover the hoverable width for activity corners (#416)
  Fix flaky WebKit menu focus browser test (#409)
  Test Goose connections and fix Pi test false failures (#383)
  feat: open threads with verified newest-first windows (#154)
  Add agent conversation context selection (#382)
  test: keep behavioral coverage without cosmetic matrices (#410)
  Fix reading position and composer caret on channel return (#411)
  fix(channels): prevent clipped activity rows and remove separators (#377)
  ci: publish signed macOS updater artifacts in prereleases (#387)
  feat(messages): add jump to latest controls (#374)
  Align reply summaries with message content (#408)
  Add centered thinking pills to agent avatars (#351)
  Keep focus where the user moved it when a menu finishes closing (#355)
  Browse legacy identities without a destination and review text before cloning (#285)
  Show separate identity cards and prevent duplicate imports (#225)
  Polish message and thread spacing, grouping, and typography (#364)
  Remove the Away avatar badge stroke (#395)
  fix(profiles): hide activity on human profiles (#391)
  ...

Signed-off-by: Sol <49aa1f65411fd096d2e2ec144f1e7aa36fdc76d1b907cfdf7be000c66f9d3b8e@buzz.block.builderlab.xyz>

# Conflicts:
#	src/bundled/agents/AgentsPage.test.tsx
#	src/bundled/agents/AgentsPage.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants