Skip to content

Assistant dock mark: click-only contact, then the face; quiet focus return - #68

Draft
SashaMIT wants to merge 14 commits into
developfrom
feat/assistant-dock-mark-0.7.1
Draft

SashaMIT wants to merge 14 commits into
developfrom
feat/assistant-dock-mark-0.7.1

Conversation

@SashaMIT

@SashaMIT SashaMIT commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Small and independent of #67. Base develop. No Rust, no capsule contract change.

Branch shape (checked against origin/develop at f346147)

  • Commits not in develop (git log --no-merges origin/develop..HEAD): six, all about the dock mark:
    • dd9d74ca feat(home-gui): the Assistant toggle wears the Elastos mark with a click-only contact
    • f88ff13a fix(home-gui): focus handed back after the Assistant face closes raises no dock label
    • b35ae724 test(home): drop the dock mark source-text contracts
    • 12e69240 ci: run the dock mark unit test in source-gate (its ci.yml line was dropped when merge 25cc022f took develop's scripts/test-source-gate.sh layout; net zero in the PR diff)
    • d5521076 fix(home-gui): a dock mark opening made stale during the contact does not toggle the face
    • 0c749d67 fix(home-gui): the dock mark toggle recovers when the contact motion fails
  • Plus five merges of origin/develop (b750d142, 25cc022f, 503ca923, e46139c4, ba845d7d). Every second parent is in develop (git merge-base --is-ancestor), and so is 501b411c1, the parent of dd9d74ca (the old feat/0.7.1-models base). Nothing from another feature branch rides along.
  • The merge-base diff (git diff origin/develop...HEAD) touches only: capsules/assistant/browser/icons/icon-*.png, capsules/home-gui/browser/{home-gui-template.html, shell-assistant-face.js, shell-assistant-mark.js, shell-surface.js, style.css}, capsules/home-gui/browser/icons/assistant-mark/**, justfile, scripts/home-assistant-mark.test.mjs.

What a person sees

  • The Assistant toggle wears the Elastos two-layer mark: frosted-glass upper chevron composited live over the orange lower chevron (real alpha, not baked in). Drawn at 90.9% of the slot so its top and bottom sit on the launcher glyph's.
  • Still at rest: no load, hover or idle motion.
  • Click: the chevrons close toward each other (240 ms), return to rest (170 ms), and only then does the face open. Equal and opposite 10.35% travel keeps them aligned at contact.
  • Coming back from the Assistant no longer floats the "Assistant" label over the mark. Hover (after the usual beat) and keyboard focus still show it.

How it is built

  • shell-assistant-mark.js (new): the whole sequence is Web Animations on the two layers, transform-only; the return ends on the resting transform, so releasing the filled animations changes nothing on screen. Repeat clicks are ignored until the sequence settles. Reduced motion opens immediately. A non-opening activation (closing an open face) skips the motion. Presentation only, no authority.
  • If the face opens by another path during the contact (Agent space, a launch), or the mark is unbound, the stale opening is dropped instead of toggling the face shut.
  • If the contact motion throws (a chevron layer missing, animate() failing), the click guard and data-animating are released in finally and the face still opens. Before this, the guard stayed set and the toggle ignored every later click until reload.
  • shell-assistant-face.js binds the mark and no longer mounts the capsule glyph on the toggle; the mark is part of the face cadence Home owns, like the launcher's dock art. The Assistant capsule's icons/icon-*.png are the static mark so Launcher and dock agree.
  • Focus return: the dock's label showed on every focusin, including the focus Home hands back to the toggle when the face closes. The face now restores focus through the dock (restoreDockFocus in shell-surface.js), which keeps that one focus quiet. The label answers only the person's own hover or keyboard arrival.

Gates (what is in this diff)

  • scripts/home-assistant-mark.test.mjs, 8 cases: full sequence and ordering, repeat-click guard, reduced motion, non-opening activation, unbind/null, stale opening during the contact is not toggled shut, unbind during the contact opens nothing, a throwing contact still opens and the toggle keeps answering. Runs in just verify (justfile) and in CI test-behaviour through the scripts/*.test.mjs glob in scripts/test-behaviour.sh.
  • Not in this diff: no home-entropy-check contract. The mark checks added in dd9d74ca/f88ff13a were removed again in b35ae724, and scripts/home-entropy-check.mjs no longer exists on develop (deleted in a32e3e24).
  • Not covered by an automated test: restoreDockFocus (focus return raises no label) and the face-side wiring in shell-assistant-face.js.
  • Re-run on this branch: home-agent-shell-smoke, home-shell-regression-smoke, check-capsule-templates, check-product-data, git diff --check pass. home-clipboard-source-gate fails on capsules/chat-room/browser/chat-room.js, which this PR does not touch; it fails the same way on develop (f346147).
  • Author's manual check, not reproduced here: headless on a throwaway Home with a virtual passkey (Chromium): static under hover; contact at ~250 ms with glass +10.35% / orange −10.35% exactly; back at rest ~435 ms; morph starts only after; four rapid clicks → one opening; reduced motion → zero chevron animations; after closing the face the layers are at identity with no live animations and no label.

Made with Cursor

Part of #84.

@irzhywau irzhywau added this to the 0.7.1 milestone Sep 29, 2026
SashaMIT and others added 2 commits September 29, 2026 21:14
…ick-only contact

Two layers in one square — frosted-glass upper chevron over the complete
orange lower chevron — composited live. Still at rest: no load, hover or idle
motion. A real activation plays the whole contact before anything else moves:
the chevrons close (240 ms) and return to rest (170 ms), and only then does
the face open. Equal and opposite 10.35% travel keeps them aligned; the return
ends on the resting transform, so releasing the filled animations changes
nothing on screen. Repeat clicks
wait for the sequence; reduced motion opens immediately; closing an open face
skips the contact. Drawn at 90.9% of the slot so its top and bottom sit on
the launcher glyph's. Presentation only.

The toggle no longer wears the capsule glyph: the mark is part of the face
cadence Home owns, like the launcher's dock art. Unit test wired into verify;
the entropy check guards the contract.

Co-authored-by: Cursor <cursoragent@cursor.com>
…es no dock label

Closing the face returns focus to the toggle, and the dock showed the item's
label on every focusin — so "Assistant" floated over the mark each time the
person came back from the Assistant, though they had neither hovered nor
tabbed to it. The dock label answers the person's own arrival: hover after a
beat, keyboard focus at once. Focus Home hands back itself is neither, so the
face now restores it through the dock (restoreDockFocus), which keeps that one
focus quiet. Hover and keyboard labels are unchanged; the entropy check
guards the contract.

Co-authored-by: Cursor <cursoragent@cursor.com>
SashaMIT and others added 3 commits October 2, 2026 19:20
home-entropy-check.mjs tests source text and is being retired (#194).
home-assistant-mark.test.mjs covers the mark's behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@andersalm

Copy link
Copy Markdown
Contributor

Postponed to 0.8.1: old draft, not part of 0.8.0.

@andersalm andersalm modified the milestones: 0.8.0, After 0.8.0 Oct 13, 2026
SashaMIT and others added 4 commits October 16, 2026 02:58
…k-mark-0.7.1

# Conflicts:
#	.github/workflows/ci.yml
…k-mark-0.7.1

Co-authored-by: Cursor <cursoragent@cursor.com>
…k-mark-0.7.1

Co-authored-by: Cursor <cursoragent@cursor.com>
…k-mark-0.7.1

Co-authored-by: Cursor <cursoragent@cursor.com>
… not toggle the face

The mark decides at click time that the activation is an opening, plays
the 410 ms contact, then calls toggleAssistantFace(). If the face opened
by another path in that window (Agent space, a launch request), the
toggle closed it: the click asked for the face and shut it. Re-check the
opening after the contact and drop it when stale, and drop it when the
mark was unbound mid-flight.

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

handleClick set running = true, awaited playContact() and only then
cleared it. If playContact threw (a chevron layer missing from the
template, animate() throwing), the guard stayed set and every later
click was ignored: the Assistant toggle was dead until reload. Release
the guard and the animating flag in finally, and still open the face,
since the motion is presentation only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W6Qn9RX7LDqrwiAfNC2F2K
cargo-audit fails on every PR: zip 2.4.2 in elastos/Cargo.lock and in
capsules/object-provider/Cargo.lock (through its elastos-server path
dependency) has three advisories against ZipArchive::extract and the
stream extract API. The runtime calls neither; it reads each entry
itself. zip 9.0.4 is the patched release.

- elastos-server uses zip 9.0.4, still without default features. 9.x has
  no separate flate2 feature; deflate-flate2 now enables the dependency.
- Both lockfiles change only for zip: nix 0.31.3 and typed-path come in,
  derive_arbitrary goes. `cargo update -p zip` also moved unrelated range
  dependencies (windows-sys, getrandom); those lines stay as they were,
  and `cargo metadata --locked` accepts both files.
- ZipFile::name now returns a Result. The ZIP readers report an error as
  "invalid ZIP archive entry".
- Whole-archive extract keeps its rule for entry names. zip 9
  enclosed_name turns "/a.txt" into "a.txt" and folds "x/../a.txt" into
  "a.txt", so an entry that extract refuses today would be written. The
  runtime now checks the name with the rule zip 2.x applied: no NUL byte,
  no root or drive prefix, no climb above the archive root.

test_library_provider_extract_zip_refuses_absolute_dotdot_and_symlink_entries
covers absolute, "..", inner "..", backslash and symlink entries. It
passes on zip 2.4.2 and with this change, and fails on the Absolute.zip
case when extract uses zip 9 enclosed_name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W6Qn9RX7LDqrwiAfNC2F2K
claude and others added 2 commits October 17, 2026 08:42
zip 9 for RUSTSEC-2026-0367/0368/0369 so cargo-audit passes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W6Qn9RX7LDqrwiAfNC2F2K
…d retry (#381)

Port of develop commit 5051505 (Anders Alm). The test flaked in CI with
"WouldBlock" at journal.rs:4223 on PR heads that predate the fix.

(cherry picked from commit 5051505)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W6Qn9RX7LDqrwiAfNC2F2K
@SashaMIT

Copy link
Copy Markdown
Contributor Author

Review: pass. Tests 6–8 fail before the fixes and pass at 269064f; the smokes pass. Ready for Anders once CI is green.

@andersalm

Copy link
Copy Markdown
Contributor

Audit, 1 November: every change in this PR is on develop and in the 2.0.0 candidates, including the stale-opening guard, the try/finally recovery and test cases 6 to 8 (scripts/home-assistant-mark.test.mjs, 8 cases, run by test-behaviour.sh and just verify). Nothing here is lost; this PR can be closed as landed when you are ready.

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.

4 participants