Skip to content

Home 0.7.1: the Shelf morphs into the Agent; the agent harness is its own capsule on the typed model contract - #55

Closed
SashaMIT wants to merge 4 commits into
feat/home-first-run-seed-0.7.1from
feat/home-shelf-assistant-face-0.7.1
Closed

SashaMIT wants to merge 4 commits into
feat/home-first-run-seed-0.7.1from
feat/home-shelf-assistant-face-0.7.1

Conversation

@SashaMIT

@SashaMIT SashaMIT commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Home 0.7.1: the Shelf morphs into the Agent; the agent harness is its own capsule on the typed model contract

Stacked on #54 (feat/home-first-run-seed-0.7.1). Four commits, path-sliced:

  1. feat(runtime) — Home Agent workspace object + model attribution by capsule id
  2. feat(home) — Shelf morph, Agent Space, opaque frame seam (Home GUI only)
  3. feat(home-agent) — the harness as a capsule, typed contract, nothing the Runtime does not back
  4. test(home-agent) — capsule gate in just verify

Ownership split

Owns What
Home GUI Shelf → composer morph (FLIP), Home breathe/rise, Agent Space stage + pager, launching the frame via launchHomeTarget, viewer rail
home-agent capsule Sessions, projects, transcript, composer contents, model choice, Settings
Runtime /api/apps/home-agent/workspace (revisioned, principal-root protected, bounded JSON); model proxy allow-list + per-capsule run binding/audit

Seam is postMessage only, sender pinned to the frame window. Neither side touches the other's DOM (asserted by the gate).

There is one Shelf. The capsule's pill is the composer and nothing else: the URUX donor's copy of the dock row, the Apps launcher, the Space pager and the capsule-side FLIP morph (~700 lines of agent-shelf.js, ~1.5k lines of CSS) are gone. Every leave — dock toggle, Home button, Esc — is one Home-driven morph: the capsule asks (home-agent:close), Home fades the composer, takes the glass back, and lowers the room. Both legs are a 200 ms crossfade of the two pills, never a same-frame swap across two documents.

Inference

Only the typed model contract: offers_list → menu/Settings; runs_create with elastos.model.input.text/v1 {prompt}; runs_events by after_sequence; runs_cancel on Stop. No offer/provider/model named in source (gate). No offer → honest status line, no reply. Offer choice persists in the workspace.

Removed vs the URUX donor (nothing behind them on this Runtime)

Mock provider + seeded replies · tool grants and Inbox grant cards (/api/apps/home/agent/tools/*, /permissions, /machine do not exist here) · approval-mode chip · Chat/Build segment · Workbench rail (outputs/plan/diff/browser/terminal) · Studio · Usage · model catalog (Get/Mine/hardware estimate) · Settings Overview/Machine/Tools/Runtime/Permissions · temperature + reasoning-effort controls (typed input has no sampling knobs) · preview banner and all "preview"/"mock" copy. ~1.7k lines of CSS for those surfaces pruned; every remaining HTML class verified styled.

Also cut as dead on this Runtime: tool-timeline rows, artifact cards + their persistence (no producer without Studio; the code-block "Open" → Documents-in-viewer path stays), the hidden inference strip (the composer chip and the per-run status line carry no-offer / offline / failure), the think-storm QoS fixture, and every export, import, token and keyframe with no reader. Sidebar is 260 px (ChatGPT width).

Also fixed: session "…" menu state was undeclared after the capsule split (ReferenceError on open).

Verification

  • just verify source gates: alignment, capsule templates, home-entropy, home-agent-shell-smoke, clipboard gate, browser-entropy, inventory smoke, diff --check — pass
  • cargo fmt --check; cargo test -p elastos-server home_agent (7 tests) — pass; clippy clean at the Rust tip (Rust unchanged since)
  • ESLint no-undef across all capsule modules: 0 errors
  • scripts/carrier-dependency-generation-check.mjs fails identically on the base commit (expected one elastos-identity 0.6.0 package, found 0) — environment, not this branch
  • Headless (Playwright, fresh Home + fake OpenAI-compatible backend): open room → 0 theatre nodes, no preview text; model menu = 1 advertised offer, selected; send → typed run streams back, 1.0s · 39 tok · est.; Settings shows Models(offers)/Prompt only; leave → reload → reopen: session, project, model choice all persisted via GET /api/apps/home-agent/workspace; session menu + project create work; 0 page errors. Frame-sampled the morph both ways and on all three leave paths (dock toggle, Home button, Esc): capsule pill and Home glass crossfade (e.g. 0.63 / 0.43 mid-fade), composer chrome hidden until handover; pixel-diff of the room before/after the dead-code cut is zero outside the transcript

For the reviewer to decide

  • Workspace schema is opaque (bounded JSON, deny_unknown_fields on the envelope). Assistant does the same today; a typed document schema is a follow-up if wanted.
  • Vendored KaTeX (~250 KB fonts) for math in transcripts; and the capsule carries its own copies of elastos-ui.css, elastos-theme.js, shell-popovers.js, Inter — the frame is opaque-sandboxed and cannot share Home's.
  • home-entropy-check.mjs has no home-agent section yet; the same bans live in home-agent-shell-smoke.mjs.
  • The Agent room is a Space in the ring (pinned far left, reached from the left-edge switcher and the pager, as in the URUX donor). shell-stages.js lists it and calls bindAgentSpace hooks to open/close; it never imports the face, the harness or the capsule. This narrows the earlier gate line "Stages … migrate without the agent harness: no Agent Space" to that rule — your call whether the room belongs in the ring at all. Mission Control deliberately does not show an Agent tile (it holds no windows); the room is never restored from a saved session.

Follow-ups (need Runtime typed ops first)

Tool grants via Inbox · Library read · web search · Studio (typed video/image input) · Usage from provider metering · reasoning effort / sampling once the text input schema carries them.

SashaMIT and others added 2 commits September 3, 2026 19:27
… model attribution

The Home Agent capsule needs two things from the Runtime and nothing else.

Workspace: GET/PUT /api/apps/home-agent/workspace behind the capsule's launch
token. The document is an opaque, bounded JSON value (size and depth capped),
revisioned with if_revision so a stale writer gets 409 and never overwrites,
written as a principal-root protected object (ciphertext at rest, declared
for recovery) and isolated per principal. Mirrors the Assistant workspace
route.

Model proxy: home-agent joins the capsules allowed to call the typed model
contract (offers_list, runs_create, runs_events, runs_cancel). Runs are
bound and audited to the calling capsule id taken from the launch token's
executable actor, instead of the previous hardcoded "assistant".

Tests: absent-get is read-only at revision 0; round trip and restart preserve
the exact document; wrong capsule is 403 and principals stay isolated; stale
and future revisions fail without mutation; malformed requests fail closed;
the object is declared for recovery and stored as ciphertext; a home-agent
run binds and audits to "home-agent".

Co-authored-by: Cursor <cursoragent@cursor.com>
…ent Space

Home GUI owns the motion and the place, nothing else. The Shelf pill grows
into a composer face (FLIP in pixels — CSS cannot interpolate max-content →
fixed width), the Home surface breathes down and the Agent Space rises as a
stage the pager knows about. The room itself is the home-agent capsule in an
opaque-sandboxed frame, launched like the Wallet rail through launchHomeTarget.

The frame is reached only by postMessage with the sender pinned to the frame
window:
  Home → capsule   home-agent:open | home-agent:shelf-handover {on} | home-agent:close
  capsule → Home   home-agent:ready | home-agent:shelf-metrics {width,height,radius}
                   home-agent:close | home-agent:open-viewer
Home never reads the frame's DOM; the capsule never reaches Home's.

Co-authored-by: Cursor <cursoragent@cursor.com>
SashaMIT and others added 2 commits September 4, 2026 02:25
…model contract

The URUX agent harness — sessions, projects, transcript with thinking blocks
and progress, markdown and math, edit / delete / regenerate, follow-up queue,
attachments, dictation — lifted as the home-agent capsule with its visual
fidelity intact, and with everything the Runtime does not back removed.

Inference is the typed model contract or nothing. offers_list decides what
the model menu and Settings › Models show; a turn is runs_create with
elastos.model.input.text/v1 {prompt}, polled by runs_events after_sequence,
stopped with runs_cancel. No offer, provider or model is named in source.
When no offer is advertised the harness says so; it never answers for the
model. The model chosen in the menu is the one the run uses and it persists.

State the Runtime backs lives in the capsule's workspace object (revisioned,
principal-root protected): sessions, projects, prompt, notes, context budget,
thinking visibility, chosen offer, live usage ledger. No browser storage.

Removed because nothing behind them was real on this Runtime: the mock
provider and its seeded replies, tool grants and the Inbox grant cards
(library.read / web.search / wallet.sign routes do not exist here), the
approval-mode chip, Chat/Build segment, Workbench rail (outputs, plan, diff,
browser, terminal), Studio, Usage, model catalog with Get / Mine / hardware
estimate, Settings › Overview / Machine / Tools / Runtime / Permissions,
temperature and reasoning-effort controls (the typed input has no sampling
knobs), the preview banner and every "preview"/"mock" line of copy.

Also fixes session menu state that was undeclared after the capsule split
(opening a chat's "…" menu threw a ReferenceError).

Co-authored-by: Cursor <cursoragent@cursor.com>
…and the seam

node scripts/home-agent-shell-smoke.mjs, wired into `just verify`. Asserts in
source that no offer is named, no browser storage or provider ping is used,
no removed module or absent route is imported or called, no mock reply path
exists, the workspace client reads before it writes and reloads on 409, the
gateway route is principal-root protected and capsule-bound, index.html
carries no theatre surface or preview copy, Settings offers only what the
Runtime backs, and Home is reached by message only. Exercises the pure
model-contract module (offer eligibility, transcript prompt, run body,
after_sequence page reduction and its failure modes) directly.

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

irzhywau commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Closing as superseded: this work is already on upstream/0.7.1-dev, landed through #58.

GitHub could not auto-close this PR because the four commits were rebased into the
integration branch rather than merged, so the head 923193bb is not an ancestor of the
base. The content is equivalent. The rebased commits, all ancestors of
upstream/0.7.1-dev:

this branch on upstream/0.7.1-dev
96347635 4383992d feat(runtime): Home Agent capsule gets a workspace object and its own model attribution
2d5ab258 498dab20 feat(home): the Shelf morphs into the Agent composer and opens the Agent Space
239c6cb7 77498557 feat(home-agent): the agent harness as its own capsule, on the typed model contract
923193bb 47a44dfe test(home-agent): capsule gate for the typed contract, the workspace and the seam

A git range-diff shows three of the four identical. The one difference is in
77498557, which dropped this branch's addition of home-agent to
scripts/local-carrier-setup-smoke.sh. That entry was re-added by 450db538
(fix(home-agent): bind capsule handoffs to Home), so the base now carries four
home-agent references in that file against three here. Nothing from this branch is
missing downstream.

Re-merging is not an option worth taking. The merge base with upstream/0.7.1-dev is
2a49ea57, so a merge reports eight conflicts, six of them add/add on capsule files
that both sides created independently. Resolving them would risk reverting the
integration-only fixes that came with #58.

Base branch feat/home-first-run-seed-0.7.1 was itself merged via #54.

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