fix(desktop): restore channel header hidden behind shared backdrop - #2139
Merged
Merged
Conversation
PR #2108 added z-0 to the channel content section, creating a stacking context that flattened the header's z-30 beneath the sibling z-30 shared header backdrop — the backdrop painted over the channel name, badges, and action buttons. The z-0 was unnecessary: the focus drawer's z-41 already wins over the section's contents without it. Adds a paint-order regression guard to the focus-mode e2e spec that compares the header's and backdrop's stacking branches directly, since neither toBeVisible() nor elementFromPoint (backdrop is pointer-events-none) can detect this occlusion.
thomaspblock
approved these changes
Jul 19, 2026
BradGroux
pushed a commit
to BradGroux/buzz
that referenced
this pull request
Aug 23, 2026
tucktuck101
pushed a commit
to tucktuck101/buzz
that referenced
this pull request
Sep 17, 2026
Serina's call, 2026-09-15: each pass stamps a fresh per-pass run identifier alongside its verdicts, and a verdict carrying a prior pass's identifier is a replay rather than a re-run. Chosen over comparing the two passes' raw stdout, which fails against the exact thing block#2139 asks it to detect - a deterministic verifier returning byte-identical output twice is the healthy case, so matching bytes cannot distinguish a real re-run from a cache hit. The limitation is recorded rather than hidden: a fresh identifier proves a dispatch happened, not that it was independent of the first pass's reasoning. STEP 2 now requires the skill to say so. Signed-off-by: test <test@example.com>
tucktuck101
pushed a commit
to tucktuck101/buzz
that referenced
this pull request
Sep 17, 2026
…ock#2139) Adds section 4a to verify-claims/SKILL.md. The run-twice rule was decided 2026-09-04 but had no observable, so a pass that re-checked every claim and a pass that replayed the first pass's verdicts were indistinguishable from outside - and caching those verdicts is the obvious optimisation. The observable, per Serina's 2026-09-15 decision: a per-pass run identifier, generated fresh before the pass dispatches anything and stamped on every verdict it produces. A verdict carrying the previous pass's identifier was replayed, not re-checked. Comparing the two passes' raw stdout was rejected when the decision was taken: a deterministic verifier returning byte-identical output twice is the healthy case, so matching bytes cannot distinguish a re-run from a cache hit. The identifier alone is not enough, so it is bound to evidence - one recorded invocation per CITED CLAIM per pass, not one per pass. A pass over six claims that records one invocation has not re-checked the other five whatever its verdicts are stamped with, which is the evasion the round-2 review found the earlier wording allowed. An inspector counts cited claims against invocation records and requires equality. Invocation records identify their claim by location and citation rather than reproducing its text, matching the discipline check-page's findings already follow, so this new evidence channel does not become a way for draft content to outlive the draft. The limitation is recorded rather than hidden: a fresh identifier and a matching record prove a dispatch HAPPENED, not that it was INDEPENDENT. An agent could re-dispatch carrying the first pass's reasoning and still produce a well-shaped record. Isolation stays a property of how step 2 is followed. Verification: python3 launchpad/agents/the-professor/tools/check_professor.py --offline -> ALL NETWORK-FREE CHECKS PASSED (the invocation CI uses). All seven local section references (2, 2a, 2b, 2c, 3, 4, 4a) resolve to real headings. Not verified: procedure text, which the harness asserts nothing about. STEP 3 exercises the contract; the replay-negative case lands in STEP 8. Signed-off-by: test <test@example.com>
tucktuck101
pushed a commit
to tucktuck101/buzz
that referenced
this pull request
Sep 17, 2026
…into draft-page (block#2138, block#2139) draft-page mentioned verify-claims exactly once before this, inside baseline mode's numbered step 5. The ordinary drafting path went check-page -> screen-sensitive -> write, so the gate Serina declared mandatory and unskippable on 2026-09-04 was wired into one mode and absent from the path almost every page takes. Restructured the tail of the procedure. Step 8 no longer authorises the write - it authorises step 9. Two new steps and a renumber: 9. the claim gate. Third, always after the other two, never beside them. Any verdict other than SUPPORTED on any claim stops the write entirely, as does a dispatch that produced no verdict at all. No partial-write path and no write-the-supported-sections path. Findings use screen-sensitive's shape so review has one place to look. A draft with zero behaviour claims still runs the gate and records that it found none - it never skips, and never invents a claim to have something to verify. 10. the final independent pass, and ALL THREE gates run in it, not just verify-claims. A fix made in response to step 9 is an edit after check-page and screen-sensitive already ran, so re-running only the claim gate leaves those two holding verdicts about a page that no longer exists - a repair could introduce a secret or break a citation after screening and still reach the target path. Any edit after this sequence invalidates it and requires the whole sequence again from check-page. 11. the existing post-write ledger and index hand-off, unchanged. Baseline mode now points at steps 9 and 10 by number rather than naming the gate before either had a step to point at, and takes no carve-out from the edit-invalidates-the-sequence rule. Forward references corrected in the same pass: step 6 said the ledger append happens 'in step 8' (now 11) and that 'both gates below' need the complete draft (now three). Verification: python3 launchpad/agents/the-professor/tools/check_professor.py --offline -> ALL NETWORK-FREE CHECKS PASSED. verify-claims now appears 8 times, across the step 9 and 10 procedure text, baseline mode and the checklist, against 1 before - and that 1 was not in the ordinary path. Not verified: procedure text, which the harness asserts nothing about. Signed-off-by: test <test@example.com>
tucktuck101
pushed a commit
to tucktuck101/buzz
that referenced
this pull request
Sep 17, 2026
…into update-page (block#2138, block#2139) update-page contained zero occurrences of verify-claims before this. It went check-page -> screen-sensitive -> overwrite the real file. Same shape as STEP 4's draft-page change, restructured 6-9: step 6 is the sensitivity gate and no longer authorises the overwrite, step 7 is the claim gate, step 8 is the final pass over all three gates, step 9 is the existing post-write ledger append. ONE DECISION THIS STEP HAD TO MAKE, flagged in the file as needing confirmation. Neither block#2138 nor the plan says whether the claim gate inherits step 5's deliberate whole-page scope. check-page runs page-wide because a section-scoped edit can break a page-level rule. Dispatching every claim on the page would multiply every update's cost by the page's total claim count, doubled again by run-twice, for claims nothing in the edit could have invalidated. Split, on the grounds that it is not a weakening: - the UNSOURCED check runs over the WHOLE page. It needs no dispatch, so it is free, and a section-scoped edit genuinely can strip the only citation backing a claim elsewhere - the same cross-section failure step 5 already scopes page-wide for. - the per-claim dispatch covers only the rewritten section. A claim in an untouched section is checked against an untouched citation; rewriting a different section cannot change whether that citation supports it. A citation that has since gone stale is scan-repo's job to detect, not this gate's to re-litigate on every unrelated edit. The free half runs page-wide and the paid half runs where the content changed. The alternative is strictly more expensive with no failure mode identified that it catches and this does not. Also fixed: a cross-reference to draft-page section 8's retry-safety note, which STEP 4 moved to section 11. Verification: python3 launchpad/agents/the-professor/tools/check_professor.py --offline -> ALL NETWORK-FREE CHECKS PASSED. Headings run 0, 1, 1a, 2-9 contiguously. Not verified: procedure text, which the harness asserts nothing about. Signed-off-by: test <test@example.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
#2108 (focused thread mode) added
z-0to the channel content<section>. That created a stacking context which flattened the header'sz-30beneath the siblingz-30shared header backdrop — so the backdrop painted over the entire channel header: name, badges, and action buttons.Fix
Remove the
z-0. It was unnecessary for the focus drawer's layering — the drawer'sz-41already paints above the section's contents (maxz-40) without forcing a stacking context. Both focus-mode e2e tests still pass.Regression guard
Added a paint-order assertion to
thread-focus-mode.spec.tsthat compares the header's and backdrop's stacking-context branches directly. NeithertoBeVisible()norelementFromPointcan catch this occlusion (the backdrop ispointer-events-none, so hit-testing skips it). Verified the guard fails with thez-0re-added and passes with the fix.Testing
pnpm exec playwright test thread-focus-mode— 2 passed with fix; guard correctly fails whenz-0is reintroduced/channels/generalconfirms the full header (title, description, members, actions) is visible again