docs: record workspace behavior and complete requirement audit

This commit is contained in:
2026-10-24 19:37:56 +08:00
parent 656522edfe
commit d3165b1224
4 changed files with 72 additions and 11 deletions
+21 -8
View File
@@ -244,7 +244,7 @@ Each window has its own Presentation, layout/Mount/focus state, caches and nativ
Open Pages appear in the native shell tab bar. Set `page.title` to label a tab; omitted titles use their open-order number. Clicking a tab or its close control calls the actual Page's `activate()` or `close()` method in the existing VM; source overrides participate. Ctrl+Tab / Ctrl+Shift+Tab cycle pages, and Cmd/Ctrl+W closes the active page when the page has keyboard focus. Overflow arrows expose additional pages. Closed Pages follow managed references and GC; a retained Page can be reopened. The tab projection contains opaque session-local IDs and text, with weak reverse lookup in the runtime, and adds no Page roots. Requests carry the published layout version; an old tab event is rejected. Switching creates new presentation Mounts while preserving the business objects. See [tabs.endor](examples/tabs.endor).
The bar occupies 36 logical pixels when at least one Page is open. Page constraints use the remaining height; published Mount geometry and event coordinates remain relative to the content area. Window viewport snapshots continue to report the full native inner size. The host translates drawing and native pointer coordinates at this boundary. Console reset preserves the last picture with input disabled until a new live frame is published.
The macOS title strip occupies 44 logical pixels and shares its row with the native window controls. The left rail and title strip form one neutral chrome surface. Content is inset by a 56-pixel rail, an 8-pixel top gap, and 8 pixels at the right and bottom. Page constraints use the remaining height; published Mount geometry and event coordinates remain relative to the content area. Window viewport snapshots continue to report the full native inner size. The host translates drawing and native pointer coordinates at this boundary. Console reset preserves the last picture with input disabled until a new live frame is published.
`window.resize(width, height)`, `setTitle(text)` and `focus()` project requests to the GUI thread. `id()` returns an opaque runtime resource ID and `viewport()` reports actual logical dimensions. Requests are asynchronous and coalesced by kind; queried dimensions change when the native window reports them, and platform bounds can adjust requested sizes. This host accepts sizes from 1 to 4096 logical pixels per axis, with a native minimum of 720 by 480. Titles are UTF-8 text up to 4096 bytes with no control characters. See [window.endor](examples/window.endor).
@@ -268,13 +268,26 @@ A source subclass can override `paint(self, mount, geometry): DisplayList`. The
Renderer-dispatched paint runs in a read-only Aster call: existing heap objects cannot be modified; fresh result graphs may be allocated and filled. Existing globals, model fields, containers, Mounts and types remain protected. invalidate is rejected in this phase. All overrides share one VM budget. Read dependencies are currently recorded per object, with versions used to detect changes without depending on bounded change-notification delivery. Native frames keep their existing dependency/cache behavior. Derived allocations do not produce application change notifications, preventing temporary results from causing redraw feedback. This protects managed heap writes; trusted Rust host implementations must also respect read-only calls for external state and I/O. Paint errors stop the affected runtime before publication; failed PUT candidates preserve the previously running heap and frame.
Toggle developer tools with Command-Option-I or F12 on macOS, Control-Shift-I or
F12 on Windows/Linux. The compact Console, Sources, Network and Settings tabs
share a draggable dock edge. The Sources tree/source
boundary and Network's request/details boundary can also be dragged. Each content
area has independent vertical and horizontal scrolling, draggable scrollbar thumbs,
and trackpad support. Shift-wheel scrolls horizontally. Layout uses logical pixels
and the actual display scale; resize clamps pane sizes to keep controls reachable.
The application starts with one managed New tab. The + button and Cmd/Ctrl+T
create additional managed Pages; Cmd/Ctrl+W closes the active Page. New tabs expand
from left to right while existing tabs interpolate to their new bounds when space
becomes limited. Hover and selection use the same capsule geometry, and animated
pointer hits use the rendered bounds. Source and page identity remain in the VM;
chrome animation retains only projected scalar IDs and rectangles.
Console, Sources, Network and Settings are independent managed Pages with separate
view modules and window-local input/focus/scroll/selection state. They are not
opened by default and have no permanent rail/menu launchers. Their future
discovery UI is intentionally deferred. Existing integrations can call
`ui.developerTools("Console")`, `"Sources"`, `"Network"` or `"Settings"`.
F12, Cmd-Option-I and Cmd-Shift-I on macOS, or Ctrl-Shift-I elsewhere,
open/focus Console. Page closure, placement and GC use the ordinary Page methods.
Sources supports read-only drag selection, select-all/copy, and Shift+arrow
selection; source line numbers are excluded from copied text. The Console prompt
only captures pointer hits over its actual input lines.
See [the UI requirement audit](docs/ui-workspace-audit.md) for the full change
scope, design references, native verification and outstanding evidence.
Console is one live execution context: statements, function definitions and
expressions use the same VM and globals dictionary across submissions. There is no
+35
View File
@@ -0,0 +1,35 @@
# Window workspace requirement audit — 2026-10-24
This audit follows the full conversation, including later corrections. Implementation completion and native evidence are different columns. No claim is made that Chrome was personally measured.
| Requirement | Implementation | Evidence / limits |
| --- | --- | --- |
| One top row with native macOS controls | Transparent/full-size native title bar; reserved control space; 44 px tab strip | Actual Retina macOS windows viewed; native close/minimize/fullscreen controls retained |
| Continuous left/top chrome | One neutral background; 56 px left rail; inset content panel | Actual main and detached windows viewed; no Tools label or rail launchers |
| Larger symmetric round tabs, softer active state | Common capsule bounds, measured glyph centering, no hard active stroke | Native settled UI viewed; hover and selected use the same bounds |
| + and startup default page | One startup request guarded against duplicate resume; + release-inside; Cmd/Ctrl+T | Immediately after restart: pages().count = 1. Two native Cmd+T actions produced three tabs |
| New-tab motion, filled and unfilled | 200 ms cubic ease; new width grows from zero; existing bounds and + interpolate; scalar-only animation data | Real native new/close/fill operations completed; settled compression/overflow viewed. No frame-by-frame recording or Chrome timing comparison |
| Overflow and scrolling | Separate + reservation; arrows, edge dwell and hit bounds share tab viewport | Native overflow reached; + in overflow increased VM count 7 → 8. Dragging out of + kept count at 7 |
| Close/activate/reorder/migrate/detach | Ordinary managed Page methods retained; animated hit bounds and drag anchors use current visual bounds | Native close and drag-out to Endor Window 2 succeeded. API detach/move-back preserved Page 1:135:0. Native cross-window drop, dwell and mixed-DPI were not re-run in this final build |
| Four developer tools separated | Independent Page instances; Console/Sources/Network/Settings modules and separate per-view state | Earlier native top-level Sources/Console activation and read-only copy/paste verified; no nested navigation remains |
| Four tools not default or permanently placed | No Tools menu, rail buttons or new-page tool directory; existing API/shortcut retained | Final default surfaces viewed without tool entries |
| Source reading/selection/copy | Grapheme-boundary selection, no gutter in copy, select-all/copy, Shift navigation, drag edge scrolling | Native single-line drag/copy/paste verified earlier in this change. Final added keyboard/edge behavior compiled; not all combinations manually exercised |
| Clicking Console output must not jump to prompt/end | Input hit region restricted to actual prompt rows | Native reading/copy path verified earlier; no input hit over transcript-only area |
| Default page reflects Endor | Objects, code and UI share identity; persistence/model connections explicitly described as work in progress | Referenced chats read: 01a16819-28c3-7ce0-9423-0ffaa19402ce and 01a1689b-77d8-75a2-ba9e-b2fa3dce654e; actual native start surface viewed |
| Sensible source organization | Runtime/API tests separated; four page view modules; shared painter/selection; native tool Page factory; motion module | All-target Clippy compiled production and test sources. Runtime host reduced from ~7000 to ~1380 lines |
| Protect existing work | examples/README.md and examples/workspace.endor excluded; vendor/Aster untouched | git status checked before staging |
| Verification restrictions | fmt, all-target Clippy -D warnings, release build and manual native/API checks | No cargo test, smoke script, Docker, dependency test install or CI polling |
## Reference boundaries
The user's Chrome/Codex reference images supplied the single-row controls, capsules and continuous left/top chrome. The [Obsidian reading-view reference](https://forum.obsidian.md/t/make-button-to-switch-views-in-tab-title-bar-more-intuitive/89814/6) informed restrained contrast and pane separation.
The actual tools refused access to both Codex and Terminal. The available in-app browser exposes page content, not Chrome's native tab strip. No personal Chrome window/profile was operated. A Chromium source search was supplementary research, not an animation test; fetching the selected source page failed. Therefore the requested isolated Chrome comparison remains unverified.
## Manual request correction
One placement probe used unsupported == syntax and returned a parse error before execution. It was replaced with direct returned object-identity checks. Both the detached-window Page and moved-back Page returned 1:135:0. The failed expression is not counted as passing evidence.
## Remaining verification
Isolated Chrome timing/shape comparison, frame-by-frame animation capture, fresh native cross-window drop/dwell on the final build, mixed-DPI cross-screen interaction and exhaustive keyboard/source-selection combinations remain without new runtime evidence. These are not silently marked passed. The shipped Page lifetime/GC model was preserved; no new persistence or AI backend is claimed.
+13 -2
View File
@@ -56,8 +56,8 @@ a successful complete PUT also retains its candidate as the active program, acce
globals/service roots, collects cycles and requires an empty VM. Window frames
contain only immutable native data.
Tests in api.rs execute real HTTP CRUD, persistent Console/reset/PUT isolation and a controlled queued-PUT/DELETE race
without opening a window. Tests in endor_host.rs cover lifecycle, direct script and
Tests in api/tests.rs execute real HTTP CRUD, persistent Console/reset/PUT isolation and a controlled queued-PUT/DELETE race
without opening a window. Tests in endor_host/tests.rs cover lifecycle, direct script and
module entry, page methods, stable-slot insertion and tab drop/override/stale-target behavior, multiline inputs, original source ranges, malformed input,
owner/task cancellation, hidden-object delivery, stale request and callback failure, entry checks, source function/declared-field annotation checks, constructor side-effect prevention, native callback signature/pre-registration validation, shared field forwarding/function identity and REPL class redefinition, budgets, failure preservation, live object identity, explicit rendering,
compile-before-execute behavior and stale-result invalidation. They
@@ -252,3 +252,14 @@ The gc-lifecycle example and endor_host regression combine a mounted Page/Block
The API worker logs the submission identity once when a newly accepted input enters BeforeInput waiting. It omits source and runtime values, and resume quanta do not repeat it. This distinguishes cancellation of an accepted pre-input wait from cancellation of an unpublished candidate or a request still in the transport queue.
Property binding caches now consume synchronous precise ReadSet dependencies, replay validation through ObjectStore and exclude the same private presentation desktops as source layout/paint. Cached output equality still repairs a direct overwrite even when its compute dependencies are unchanged. ui.stats().bindingEvaluations counts computations in completed binding refreshes for this VM, including initial/hidden bindings, so unrelated REPL inputs can be checked without adding effects to read-only source compute functions.
Window workspace modules:
- `tabs.rs`: common tab/close/+ geometry, overflow and shared hover/active capsules.
- `tabs/motion.rs`: 200 ms eased geometry shared by painting and pointer hits.
- `system_ui/start_page.rs`: the Endor start page; future capabilities are marked as such.
- `ui_bridge/developer_pages.rs`: managed tool/start Pages, identity-preserving reopen and focus.
- `developer_tools/{console,sources,network,settings}.rs`: separate page views.
- `developer_tools/painter.rs`: reusable pane painting and response formatting.
- `developer_tools/selection.rs`: independent read-only source selection.
- `endor_host/tests.rs` and `api/tests.rs`: existing regression sources, moved with corrected include paths.
+3 -1
View File
@@ -58,7 +58,9 @@ scrollable stream as output. `src/clipboard.rs` guarantees UTF-8 for macOS clipb
subprocesses, independent of Finder's locale.
Tessera's developer tools are the first consumer. Domain actions, HTTP calls,
source navigation and Console execution remain in `developer_tools.rs`; none of
source navigation and Console execution remain in `developer_tools.rs` and its page modules; none of
those concepts enter this library. The library currently renders synchronously
with immediate state feedback; it is not an Endor component implementation, an
OS accessibility bridge or a separately published Cargo crate.
`start_page.rs` paints the built-in Endor start surface. Native window chrome uses the same neutral palette, while each tool Page has its own interaction state.