EasyUniversal / DocsДокументация · SDK 0.3Подписка Universal ↗
Easy Universal / Архитектура и статус

Архитектура runtime

AngelScript · native runtime · локальная сборка

Easy Universal SDK 0.3 architecture

Native Cloud scripts uses a fixed HTTPS origin, an embedded RSA-3072 publisher key,
WinHTTP and CNG. Its explicit client modal runs I/O and validation on a worker,
with signed cached browsing, exact dependencies, exclusive repository.lock,
bounded hash-verified snapshots and atomic active.json activation. Its GUI lists
only the latest numeric version of each script and has no archive/rollback action.
Cloud download refreshes the selected collection while preserving downloaded IDs;
legacy exact-version/rollback operations remain internal developer/test tools.
Open installed changes the viewed catalog without running a script; installed
sources are read-only in the client and integrity is checked before launch.
Normal mode has no test-key/transport configuration. Independent author signatures and root-authorized publisher/author key
rotation/revocation are verified by the native repository. Offline revocation
requires receipt of a new policy; see the validity and snapshot rules. See sdk/REPOSITORY_RU.md.

Current stable delivery: 1.0.0; SDK 0.3. The current Process/GUI/input/HTTP/delivery contracts
are in sdk/API.md and the linked SDK chapters. Dated phase sections below are
historical records; their earlier exclusions must not override current contracts.
The site has subscriber and administrator delivery; the developer distribution is
separate. driver/ adds caller-handle READ_INFO/READ to the compatible GET_INFO/PING baseline;
live kernel verification remains pending. The client's explicit
Check base driver action probes an already installed device using a hidden copy
of the same executable. A kill-on-close job owns the child; no inherited handles,
30-second deadline, nonblocking GUI polling, strict identity/ABI/capability/padding
and nonce validation. Protected builds retain authorization in that child.
Closing the client cancels it. Optional Read through driver or --process-backend driver
routes ProcessReader byte reads through READ using the same inherited VM_READ handle,
PID consent, quotas and all-or-nothing script results. Metadata and explicit writes
keep the Windows backend. Missing/incompatible driver fails before script callbacks;
there is no automatic fallback or driver installation.

Frame deadlines use steady_clock and waitable timers, including processing time
in the requested interval. Polling also avoids Sleep(1) system-tick rounding.
Snapshot timestamps use that monotonic clock. The preview pumps messages while
waiting, overruns do not cause catch-up bursts, and on_timer stays frame-based.
See sdk/FRAME_TIMING_RU.md for exact behavior and CLI --fps.

0.3 foundation: B1/B2

GUI preparation adds a separate consent-gated gui.json key/value store, loaded
before callbacks and checkpointed outside callbacks at most once per second
after successful frames, with final successful unload flush. Same-value updates
do not dirty state. Exclusive temporary writes and atomic replacement preserve
the last checkpoint on failure; crashes do not roll back earlier checkpoints.
Tabs, checkbox groups and HSV conversion/picker are optional script helpers.
Frame-local ui.theme palettes, local preview-only ui.keybind capture and optional
BoxLayout/ScrollPanel helpers extend this GUI path. Theme commands must be first;
capture cancels on focus loss, hidden controls, outside clicks and reload.
There are no global key hooks. See sdk/GUI_03_RU.md and RELEASE_03_STATUS_RU.md.

Runtime owns a unique IDataSource per worker. LocalDataSource owns the inherited
reader/writer handles and wraps the existing bounded ProcessReader/ProcessTools.
All Process API dispatch passes through this interface after permission checks.
Public SDK signatures, error channels and budgets remain unchanged. Scanning and
profile construction are still local-backend operations. Separate ExternalTelemetry
serves bounded scalar snapshots and updates over a local message-mode named pipe.
It does not implement arbitrary-address process operations or replace IDataSource.
Manifest source.read/source.write and separate explicit provider-PID/write grants
are required. A background thread checks server PID, validates schema/sequence,
expires snapshots and contains I/O deadlines; callbacks only inspect locked copies.
No IPC work runs on the main UI thread. The client Settings page takes a provider
PID and explicit source.read/source.write grants. See sdk/EXTERNAL_SOURCE_RU.md.
The worker emits bounded source metadata only on changes. The supervisor checks
identity, PID, state and effective capabilities against frozen grants, then
publishes a mutex-protected copy for the Settings page. No provider values are
included; diagnostics do not reset the frame watchdog or authorize any access.

SDK 0.2 process toolkit

New scan, handles_threads and write permissions require package API 0.2;
0.1 packages and the 0.1 wire/delivery contract remain accepted. PID handles
remain lifetime-bound, never silently reattached. The supervisor creates a
separate VM_WRITE/VM_OPERATION handle only after distinct explicit write consent
to the same PID; read-only handles are not upgraded. Writer handles are inherited
through the explicit list and closed by the worker and supervisor.
Bounded Toolhelp/NT metadata, readable module pattern scans and RIP arithmetic
run only in the worker. write_protected restores original page rights on both
success/failure, but partial bytes are not transactional. Profiles are bounded
package-private JSON files, created exclusively, with reparse checks. Diagnostics
are heuristic snapshots, not evidence of maliciousness or a trusted module oracle.
Native toolkit elapsed time is accounted separately from script execution;
operation quotas and the existing outer watchdog remain. No driver, injection,
protection bypass or privilege elevation is introduced. Historical read-only
sections below describe earlier milestones, not the opt-in 0.2 write grant.

RC20/RC21 read-only process metadata

The PID consent remains bound to the inherited target handle. A memory-map-only
package gets QUERY_INFORMATION | SYNCHRONIZE, not VM_READ. process_read additionally
requests VM_READ with full query rights for native module metadata; if full query
access fails and no memory map is declared, legacy limited-query byte reads may
still work. Module APIs can fail on that limited handle rather than escalating.

Worker VirtualQueryEx produces bounded memory_region snapshots. RC21 enumerates
native x64 module_info snapshots using PSAPI or NtQueryInformationProcess plus
bounded remote PEB/Ldr reads. Unsupported WOW64 is explicit, not guessed. Diff
compares separately collected sources by base/size/path; neither is an atomic
or independently trusted inventory. PEB validation rejects malformed cycles,
inconsistent backlinks/heads and oversized strings, returning no partial list.
Script-visible value objects own their strings and never write to the target.
See sdk/PROCESS_API_RU.md for permissions, native-call timing caveats and limits.

First-final preparation: POST, flow and stable distribution

POST shares bounded HTTP transport but additionally requires http_post in the
manifest, reviewed origin consent and an 8-KiB owned payload. Existing GET-only
packages retain read-only network capabilities. No custom headers or implicit
retry; cancellation cannot reverse a completed remote action. Flow is a script
module for variable-size row wrapping and measured/collapsible content.
Release checks update one dist/EasyUniversal directory without new ZIPs, rejecting
modified previously generated files rather than overwriting user edits.

RC19 virtualized script list and release criteria

ScrollList builds on the existing scroll/clip protocol without new native
registrations or grants. Only viewport-intersecting rows emit button commands;
empty/excess lists reset selection and offsets. Geometry normalizes before
native calls, with documented array/label/ID and shared command quotas.
Grid ensures a positive minimum cell width when the requested span is too small.
These helpers are explicit package modules, not automatic layout or game input.
RELEASE_READINESS_RU.md separates automated candidate checks from unverified
endurance and clean-machine work. Subscriber delivery and specific update/recovery
fixtures are now verified; consult the dated results in VERIFICATION.md for scope.

RC18 explicit scroll regions and clipping

Bounded scroll commands declare wheel regions; scripts apply the returned
offset to child coordinates. Nested clip commands intersect drawing and native
hit tests, require balanced stacks (maximum depth eight) and consume the shared
command quota. Widget clipping cancels fully hidden text focus/slider capture.
Native own-window wheel events coalesce per ID; callbacks consume bounded
deltas once and clear unused input. No game/global input hooks, new permissions,
implicit coordinate transforms, automatic layout or scrollbar drag support.

RC17 own-preview text input

Single-line UTF-8 values have a 1–128 byte script-declared limit. Native host
collects only its own WM_CHAR input, combines surrogate pairs and removes one
code point on Backspace. A focused append-only draft survives older IPC frames.
Text events coalesce in the existing bounded queue and cross the same snapshot
transport; runtime validates ID/UTF-8/controls/limits and expires unused events.
Hide, focus loss and Reload discard pending input; Enter and widget switches
retain queued values. No game/global keyboard hooks, new grants or clipboard
access. This is not full text editing, IME support or a secure password field.

RC15 typed settings and bounded computation queue

Typed config access keeps the existing string disk schema and consent/quota/
successful-unload rules. Invalid stored types/ranges return the typed fallback;
nonfinite float setters/defaults fail. The enabled query is safe without consent.

JobQueue owns up to four retained/pending results and one lazy native thread.
Only SHA256 over <=64 KiB and JSON acceptance over <=8 KiB/depth64 are supported.
Queued bytes are copied; callbacks poll locked result copies, never run arbitrary
AngelScript on this thread. Release/reset remove publication slots, IDs remain
monotonic, and completed canceled work cannot resurrect old results. Teardown
joins bounded computation; the existing outer worker watchdog remains containment.

Optional script modules provide menu layout/dropdown/color controls, freshness
and explicit orientation math; they are compiled as package sections, not
new pre-registered native UI or automatically detected game adapters.

RC14 reflected SDK and LLM package

Runtime engine registration is shared between load and the metadata-only
sdk-schema command. Reflection lists actual global functions, object methods,
properties and behaviours including official add-ons. Schema export does not
open a package, compile source, run callbacks or grant process/storage/network
access. JSON describes signatures, not permission policy or game compatibility.

The release pipeline generates a deterministic full LLM reference, index and
source hashes from current SDK documents and native reflection. A drift check
compares registered declarations and source bodies/hashes. The copied synthetic
settings template verifies denied storage and explicit-consent save/restore;
no live-game data or new runtime permissions are introduced.

RC13 client interaction

Source, Details and the package list share local mouse-wheel handling with their
custom scrollbars. High-resolution partial deltas accumulate per control; Windows
line/page preferences are respected. Scrolling does not move the caret or edit text.
The client message loop routes wheel input to the hovered visible text/list area,
even when another control has focus. No global input hook is installed.

A non-activating, click-through dark owned popup explains controls after two
seconds over the same control. The existing UI timer checks hover without blocking
or sleeping. Hints are hidden on clicks, keyboard input, commands, resize, focus
loss and modal interactions; placement is bounded by the monitor work area.

RC12 permission-gated HTTP queue

Manifest http permission requires one to four validated exact origins. The
client displays them and freezes a separate unchecked-by-default session grant;
fingerprint changes reset that grant. The supervisor passes only reviewed origins
to its child; runtime validates them against the manifest. Reload cannot change
origins, and unload/reload invalidate all outstanding results without reusing IDs.

One native worker thread services bounded GET requests. Script callbacks only
enqueue or inspect locked snapshots; no network operation runs on the UI or
script callback thread. Four slots include retained results; bodies are capped
at 64 KiB and headers at 16 KiB. A 250 ms post-completion delay paces requests.
No redirects, cookies, automatic authentication, proxy, uploads or script headers.
WinHTTP retains default TLS validation. Synchronous native calls have 500 ms
phase timeouts and a between-call three-second deadline; cancellation suppresses
publication but is not immediate socket interruption. Teardown joins the thread;
the existing supervisor watchdog bounds a stuck worker teardown.

Origin consent is not a hostile-script or IP sandbox: DNS is not pinned, granted
HTTPS hosts can resolve to private addresses, and trusted local loopback origins
are supported explicitly. No WebSocket, general script threads, game adapters,
process writes or protection bypass were added. See sdk/HTTP_RU.md.

RC11 typed SDK and UI extensions

Native vec2/vec3/matrix4 are value types registered through the generic calling
convention; pure operations reject invalid ranges. Projection exposes explicit
viewport and matrix/basis contracts rather than guessing a game engine. Out
values clear on failed projections; near/far clip Z is not tested.
Official unchanged scriptarray and scriptmath add-ons are registered through
portable bindings. Arrays include value types and owned buffer handles; normal
index failures are script exceptions. There is no independent per-array memory
quota; the worker process memory limit remains the outer resource boundary.

Reference-counted immutable memory_buffer owns a bounded byte copy. Process
snapshots share the existing consent/handle/budget checks; local field extraction
uses memcpy with subtraction-based range checks and does not touch the target.
An owned buffer is not a live view and does not guarantee an atomic target read.
Scripts may retain old snapshots, so freshness remains an adapter responsibility.

Slider/cycle extend the existing bounded validated command transport. Own-window
mouse events coalesce slider updates and hit-test in reverse drawing order.
Worker callbacks remain sequential; per-frame input clears after use. The host
does not execute script callbacks from its mouse procedure. New filled primitives
reuse the same GDI+ surface and existing command/color/coordinate limits.
No process writes, new grants, arbitrary networking, script threads or overlay
hijacking were introduced. These are additive API 0.1 functions, not Ech0 ABI parity.

RC9 Adapter SDK contract

Packages may declare a versioned adapter descriptor and up to eight additional
AngelScript sections, compiled into the same module. Source permissions and
existing user grants remain separate. Metadata is not evidence of compatibility.
Inspection hashes every module without execution; editor entrypoint writes are
blocked if a dependency changed. Reload cannot change adapter identity/source/
capabilities or permissions within the running session.

The worker owns a bounded normalized entity vector. It resets before each
on_frame, accepts publication only in that callback with a declared entities
capability and ready state, and clears invalid/duplicate/quota-exceeded data.
Loss of source access expires the snapshot. Source availability does not validate
game-specific structures; the author must do that before asserting ready.
Pure distance/projection functions have finite-value/matrix/viewport bounds.
There is no new process-opening, write, network, input or protection-bypass path.
The synthetic multi-file example verifies a common producer/consumer contract,
not Destiny 2 or another game's compatibility. External remains separate.

RC8 authorized telemetry extension

An explicit wt_telemetry manifest permission and per-session user grant enable
a separate bounded HTTP worker. It reads only localhost:8111 /indicators and
/state, without a proxy or redirects. Script callbacks take a locked snapshot,
not a synchronous network request. Invalid or older-than-two-second data is
unavailable. This is an own-vehicle instruments adapter, not arbitrary HTTP,
enemy telemetry, a protected-memory adapter or an anti-cheat bypass. Its offline
parser/consent/package tests do not establish live War Thunder compatibility.

GUI supervisor (same EasyUniversal.exe as the visible client)
  └─ Win32 job + inherited pipe + 5 s watchdog
       └─ worker (same executable, internal --worker command)
            ├─ package manifest and declared resources
            ├─ AngelScript engine and bounded callbacks
            ├─ deterministic own-application demo snapshot
            ├─ permission-gated SDK
            └─ batch JSON report or duplex NDJSON stream

The parent never executes script callbacks. It validates worker reports before
returning them. The child starts suspended and is assigned to a kill-on-close
job before execution. The job permits one process with a 128 MiB process-memory
limit. Only the report pipe and stdin (null for batch; a second pipe for stream)
are inherited. This is crash
containment, not an OS security boundary.

Each callback gets up to 100,000 AngelScript line-callback visits or 20 ms,
checked at script line boundaries. Native helpers can run between these checks;
the outer watchdog bounds the entire run, including compilation and teardown.
Scripts are limited to 128 KiB, manifests/resources to 8 KiB, graphics to
256 commands per frame, and results to 4 MiB. A run has 1–60 fixture frames.

Reload successfully unloads the old module, saves permitted configuration,
releases the engine and builds a new one. Callback failure stops processing;
on_unload is not invoked after a failed callback. Worker destruction still
releases native resources, and closing the job terminates a stuck child.

Reload rereads the manifest before unload and requires unchanged ID/permissions.
Entry/resources/version may change. Manual F5 in the own preview uses a separate
IPC acknowledgement without resetting frame sequence or clock. Old UI clicks
are cleared and snapshots paused while reload is pending. Failure stops the
session; there is no transactional rollback.

Streaming phase — 2026-10-02

The host sends one snapshot after ready, then one new snapshot per acknowledged
frame. There is at most one outstanding snapshot (backpressure, no unbounded
event queue). Sequence numbers start at zero, timestamps are monotonic session
milliseconds, and responses must match both exactly. Dimensions, coordinates
and clocks reach the SDK before events and frame callbacks. Events are bounded
to 16 strings of at most 256 bytes per snapshot. Reload keeps session numbering.

Each NDJSON frame contains complete validated commands. Validation now rejects
missing/unknown keys, unsupported types, invalid colors/radii/thickness and
nonfinite coordinates. Input lines are capped at 8 KiB, output lines at 256 KiB,
and total worker output at 4 MiB. stop is acknowledged with a final report,
but success is not forwarded until the worker actually exits. A stuck destructor
is still covered by the outer five-second session watchdog.

The first streaming milestone was bounded to 1–60 frames; current session
behavior is described in the long-session section below.
The initial host supplied a moving fixture with a 16 ms sleep after responses.
Current pacing uses deadlines; see FRAME_TIMING_RU.md. Real source adapters,
longer-session heartbeat and brokered storage are later
work. Concurrent writers and file-substitution attacks remain out of scope.

Native rendering phase — 2026-10-02

Read-only process access is a separate, opt-in facility: manifest permission
plus an explicit host-selected PID. The parent opens only VM_READ,
QUERY_LIMITED_INFORMATION and SYNCHRONIZE rights and inherits that handle
into the worker through the explicit handle list. Reads retain the same handle
across reloads, clear outputs on failure and have per-callback budgets. There
is no script-side attach, write, privilege escalation or protection bypass.
The owned process fixture tests this layer without using a game.

preview attaches a Win32 window and GDI+ renderer to the existing validated
stream. It does not attach to another process/window, install hooks or interact
with games. The supervisor owns the window; script callbacks remain in the
worker. Client dimensions are converted from physical pixels to logical units
using per-monitor DPI and sent in the next snapshot, with viewport.changed.

Current rendering reuses same-size ARGB bitmaps and layered-window buffers;
geometry changes only when required. Each changed frame is drawn and presented
as one image. Identical validated commands reuse the completed image when the
size, scale and transparency are unchanged. Command validation and script callbacks
still run; a draw failure invalidates the cached image. Native operations support alpha colors, anti-aliased lines/circles
and UTF-8 text rendered with Segoe UI. Bitmap dimensions are limited to
4096×4096 and scale to 0.5–4. Offscreen PNG export uses the same renderer.
No C++ exception propagates out of the Win32 window procedure.

The initial preview closed after a bounded session; the current long-session
mode supports normal stop on window close (details below). Cross-monitor
physical DPI transitions and GPU presentation/performance have not been manually
validated. GDI+ is a functional baseline, not a low-latency game renderer.

Interactive GUI phase — 2026-10-02

ui.button/ui.checkbox commands carry bounded geometry, label and a stable ID.
Duplicate IDs in a frame are rejected in both runtime and protocol validation.
The own-window host hit-tests in reverse drawing order, captures a mouse press,
then queues an activation only on matching release. Capture/focus loss cancels
the press. Input coordinates are converted to logical units; widget text is
clipped to its rectangle. The queue holds at most 12 events and is drained into
the next bounded snapshot; generic lifecycle events use the remaining slots.

The runtime consumes ui.click:<id> once per widget per snapshot. Checkbox
state belongs to the script, not to the renderer. Unknown IDs and old clicks
are not carried into subsequent frames. No input is sent to another application.
This is a two-control API, not a complete GUI framework or package manager.

Long-session phase — 2026-10-02

Batch run remains bounded to 60 frames/five seconds. Streaming supports
frame-count, timed and live modes, with million-frame/seven-day safety guards.
Only one snapshot remains outstanding. Completed frames are drained rather
than copied into an ever-growing history. Logs and callback timings are bounded
64/128-entry histories with total counters. Session output has per-message
limits; no accumulated 4 MiB lifetime cap is applied to streaming.

The native supervisor tracks validated protocol progress and kills a worker
after five seconds without it, including after a final report if destructors
never finish. Timed stops, window close and console interrupt request stop,
wait for any outstanding frame and then unload/save. Abrupt host termination
still kills the worker through its job. No complete OS sandbox is provided.

The six-second integration session and 2000-frame trusted-worker stress test
passed. This is not an hours-long endurance result. Blocking stdout consumers,
modal Win32 resize loops and hardware cross-monitor behavior need further work.

Local catalog phase — 2026-10-02

packages and inspect provide metadata-only catalog operations, deliberately
without constructing a runtime. A bounded, nonrecursive directory scan returns
valid entries and errors side by side. Repeated IDs invalidate every matching
catalog record. The host computes SHA-256 of source/resources and a content
fingerprint using Windows CNG; these hashes do not authenticate authors or
authorize execution. There is no signature, install/autostart registry or GUI
manager in the original catalog milestone. Explicit folder launch remains the separate runtime
operation. See sdk/CATALOG.md for file-size and race-condition limitations.

Local client phase

The client command adds a native package list and session actions around the
existing catalog/supervisor. The main UI thread never runs script callbacks.
A dedicated thread owns preview and worker supervision; atomic flags request
stop/reload and expose progress. Reports are consumed only after completion.
One package can run at a time; launch refreshes catalog validity/fingerprint,
and storage requires an unchecked-by-default explicit session grant.
The manager closes only after its session ends. Graphics initialization persists
across restarts, and renderer text formats use owned, not cached native objects.
Production startup/Refresh and post-save/import/removal catalog validation run
on a separate native thread. Only the UI applies completed metadata; one check
is permitted at a time. Rows remain until success, selection follows folder
identity rather than sorted index, and failure restores controls. Close requests
cooperative cancellation between directories/packages and waits for owned jobs.
This does not interrupt a pending filesystem operation. The deterministic internal
control self-test keeps synchronous transitions; native catalog UI stress tests
exercise the asynchronous production path directly.
See sdk/CLIENT.md for limitations and lifecycle behavior.

Source editor phase

A host-only SourceDocument holds manifest/source baselines for the selected
entrypoint. UTF-8 and byte limits are checked before native text display or save.
Save detects ordinary external modifications, writes an adjacent exclusive temp,
flushes and replaces only the entrypoint. It never executes callbacks. The same
client contains a native multiline editor, unsaved-buffer guards and navigation
to matching diagnostic lines. Save + Reload is gated by active package identity.
Only the completed session's copied diagnostics reach editor navigation; the UI
does not read the report concurrently with the supervisor thread.

The source view uses RichEdit for native editing/undo plus a bounded lexical
AngelScript highlighter. Known functions and types are indexed from the same
registered SDK schema used by sdk-schema; a delayed hover shows matching
declarations without executing source. Ctrl+Space adds a bounded declaration/scope
index and typed member completion; F12 navigates unambiguous source declarations.
F7 builds an in-memory source snapshot on a separate thread with global initialization
disabled and no script context. Changed snapshots invalidate diagnostics.
See sdk/EDITOR_SEMANTICS_RU.md for the completion limits.

Account submissions live on the website. A subscriber uploads declared UTF-8
files and exact dependencies, then an administrator reviews the immutable version.
A separate privileged one-shot service signs approved records with account-bound
author keys and atomically publishes the delegated index. Web cannot access keys/.
The timer checks every five minutes and renews policy/index with seven days left.

The compact dark client uses native owner-drawn rows/actions and session-only
accent/counter preferences. A bounded atomic target_fps reaches the supervisor
without altering the script API; snapshot deadlines use the selected cap and
include worker/render time.
This is pacing, not guaranteed presentation FPS. External remains separate.

Easy Universal — отдельный проект. Easy External не изменён.