Skip to content

Release v0.7.1 (monthly developer release) - #140

Merged
andersalm merged 553 commits into
mainfrom
release/0.7.1
Sep 30, 2026
Merged

andersalm merged 553 commits into
mainfrom
release/0.7.1

Conversation

@andersalm

@andersalm andersalm commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

September release. This PR brings the 0.7.1 work line to main as v0.7.1. It is a snapshot for developers and testers, not a release for users. The release issue is #93.

What is in it

  • Everything on feat/0.7.1-models up to ea670e27 (fix(update): observe isolated Mac hop accurately #79 merged there with all 8 checks green). That is 552 commits since v0.7.0.
  • One commit on top, 4a6553cd: version 0.7.1 in elastos/Cargo.toml and in the 15 lock files (65 version lines, no other dependency changes), the version the carrier dependency check expects, a 0.7.1 section in elastos/CHANGELOG.md, and small fixes in docs/VERSIONING.md.

What it does not change

  • The signed installer, the update channel and the seed. No machine gets this version on its own.
  • Capsule manifest versions.
  • The GitHub binaries are unsigned source builds and report 0.7.1-dev.
  • The seed still serves an older signed preview that is also labelled 0.7.1. It goes away with the next signed release.

Checklist

Irzhy

  • Read the 0.7.1 section in elastos/CHANGELOG.md. Flag anything that is not true and any known limit that is missing.
  • Confirm that protected content stays inactive by default in this line. The 0.7.2 protected-content PRs are not in it.
  • Check the docs/VERSIONING.md change: monthly source releases use plain X.Y.Z, and -rc.N stays for signed candidates.
  • Approve. The 8 checks are green.
  • After the merge, wait until the CI run on main is green (it also warms the build caches for the tag build). Then create the signed tag v0.7.1 on the merge commit, as you did for v0.7.0. If you can't, say so and we push an annotated tag from Anders's account.

Anders

  • Read this checklist and say go.
  • Only if Irzhy can't approve tonight: allow a one-time admin merge. Admin protection is off for that merge only, restored at once, and the override is recorded in 0.8.0: Release 0.8.0 #93.

Release steps

Not in this release

Merge fix/browser-maturity at 5019635 (135 commits) into the
feat/0.7.1-integration head 093b51c. The donor carries the generalized
services layer (signed access messages, Exit and Engine service kinds,
grants with expiry, destination-side authorization) and the Runtime-routed
remote Engine path that both remote Qwen and remote Browser reuse.

Conflict resolution:
- docs/audits/ElastOS-Home-Journey-Audit.xlsx: keep the integration register;
  the donor version stays reachable at fix/browser-maturity.
- state.md: keep the current public checkpoint header.
- provider_resource.rs: keep both tests; map browser-engine `readiness` to
  Action::Read, which the donor manifest declares but never mapped.
- linux-source-home-restart-smoke.sh: keep both upgrade-receipt stubs.
- setup-source-home.sh: keep the integration media-tool and guest-helper
  blocks that the donor never had.
- home-passkey-virtual-auth-smoke.mjs: keep credential persistence,
  lock-face sign-in and the setup reminder from integration; keep Browser
  window selection, journey stages and qualification stop from the donor.
- capsule_inventory/preparation.rs tests: add the new carrier_endpoint field.
- carrier_engine_binding.rs: PROBE_SCOPE is test-only.
- browser-journey-harness.test.mjs: fixtures model the readiness wait and
  the setup reminder that Home now shows.

Verification:
  cargo check --locked --workspace --all-targets
  cargo fmt --all -- --check
  cargo test -p elastos-server --lib -- provider_resource remote_engine home_system carrier_engine home_services
    (132 pass; 3 home_system failures reproduce on 093b51c before this merge)
  node --test scripts/browser-viewer-restore.test.mjs (62)
  node --test scripts/lib/browser-journey-harness.test.mjs (28)
  node --test scripts/lib/browser-journey-viewer-reload.test.mjs (65)
  node scripts/home-entropy-check.mjs; node scripts/browser-entropy-check.mjs
  git diff --check
…reload

Reload scheduling: the viewer starts the Runtime status read and the display
attachment together and requires both before media connection and public
readiness. Remote run 96 spent 1019 ms on status and started attachment
3464 ms after reload, leaving 1536 ms of the five-second budget.

Reload evidence: the journey harness records per-substep timings for the
reload observer and rejects the old serial ordering.

Verification:
  node --test scripts/browser-viewer-restore.test.mjs
  node --test scripts/lib/browser-journey-viewer-reload.test.mjs
  node --test scripts/lib/browser-journey-harness.test.mjs
  node --check scripts/home-passkey-virtual-auth-smoke.mjs
  node scripts/browser-entropy-check.mjs
  node scripts/home-entropy-check.mjs
Add the `remote_model` service kind beside Exit and Engine. A contact can
request a person's local AI model; the owner approves in Inbox; the signed
decision carries a `remote_model_grant` with the Carrier ticket, the
`local_engines` offer scope, the five model operations and a six-hour expiry.
The consumer stores the grant on its request record.

Carrier `provider_invoke` with target `model` dispatches to
`gateway_model_service::invoke` with the Runtime data dir and verified network.
The owning Runtime verifies the grant from the source endpoint key, requires
an `assistant` or `home-agent` consumer capsule, rebuilds the request from the
typed fields only, and binds the run to a deterministic remote principal
derived from the source DID and the seed principal. Offers cross Carrier only
when they are local engines; `runs_create` is denied for any other offer;
provider errors cross as bounded classes. Every created run is indexed by
grant so a denial cancels the runs still open and reads stay possible for a
day after a run settles.

Verification:
  cargo check --locked -p elastos-server --all-targets
  cargo fmt --all -- --check
  cargo test -p elastos-server --lib -- gateway_model_service provider_resource
  node scripts/home-entropy-check.mjs
  git diff --check
A principal with an approved `remote_model` grant sees the contact's shared
offers in `offers_list` under `remote:<grant_id>:<offer_id>` ids with a
`remote_service` block, beside the local offers. `runs_create` on such an
offer, and `runs_get`, `runs_events` and `runs_cancel` for a run this Runtime
routed before, travel over Carrier `provider_invoke` to the granting Runtime
with the typed fields plus the grant, principal and consumer capsule. The
seed keeps a principal-scoped run route index so canonical run ids stay
unchanged for the Assistant.

A destination decision (`denied`, `rate_limited`, `offer_unavailable`,
`provider_failure`) is returned as a provider error. A failed or timed-out
Carrier call is returned as `transport_interrupted` with HTTP 503 and leaves
the run state unknown here; only the granting Runtime settles a run.
Unreachable grants contribute a `remote_services` status entry and no offers.

Verification:
  cargo check --locked -p elastos-server --all-targets
  cargo fmt --all -- --check
  cargo test -p elastos-server --lib -- gateway_model_remote gateway_model_service gateway_tests::model
  node scripts/home-entropy-check.mjs
  git diff --check
Merge fix/browser-maturity at bf846cd. The viewer starts the Runtime status
read and the display attachment together on reload and requires both before
media connection; the journey harness records per-substep reload timings.
The donor's update.rs slice stays uncommitted until its Rust tests run.

Verification:
  node --test scripts/browser-viewer-restore.test.mjs (67)
  node --test scripts/lib/browser-journey-harness.test.mjs (30)
  node --test scripts/lib/browser-journey-viewer-reload.test.mjs (66)
  node --check scripts/home-passkey-virtual-auth-smoke.mjs
  node scripts/browser-entropy-check.mjs; node scripts/home-entropy-check.mjs
  git diff --check
Services renders the `remote_model` kind on the Mine and People lists. Copy
and ordering come from one table per kind instead of a branch per kind, so
the Assistant is named as the consumer for model cards and Browser for the
others. Empty-state copy names all three kinds.

Verification:
  node --check capsules/services/browser/services.js
  node scripts/home-entropy-check.mjs
  cargo test -p elastos-server --lib -- services people_contact (28)
The consumer grant keeps the service display name from the request record;
offers routed through it carry `remote_service.display_name`, and the
Assistant's model menu shows "Model offer · via <name>" instead of
"this Home" for those rows.

Verification:
  cargo check --locked -p elastos-server
  cargo fmt --all -- --check
  node --check capsules/assistant/browser/model-contract.js
… Carrier

Two real Carrier nodes on one host: an owner with a fake `model` sub-provider,
a passkey principal, a signed contact chain and an approved `remote_model`
request record; a seed that speaks `provider_invoke` with its own device key.
The tests prove that only local-engine offers cross Carrier, that a run is
rebound to the deterministic remote principal with the grant as session and
grant id and the seed request id preserved, that a hosted offer is
`offer_unavailable`, that another seed principal is `denied` without reaching
the provider, that reads stay allowed after the owner denies the request while
`runs_create` is refused, and that a revoke sweep cancels the open run.

The harness found three defects, fixed here:
- the owning Runtime kept `op` in the rebuilt request, which the typed
  normalizer rejects for every operation; the same shape broke the revoke
  cancel sweep;
- the consumer dropped `request_id` together with the local binding, so the
  destination's typed structs would have refused every call;
- the Carrier invoker collapsed a destination decision to "invoke failed", so
  the consumer would have reported every denial as `transport_interrupted`.
  The invoker now passes a decision through as one fixed token from a bounded
  set; every other error stays redacted, as the existing test still asserts.

Verification:
  cargo test -p elastos-server --lib -- remote_model gateway_model_remote gateway_model_service test_carrier_provider_public_errors (17)
  cargo fmt --all -- --check
  node scripts/home-entropy-check.mjs
  git diff --check
…definition

The donor moved every Browser VM image refresh function, including
`browser_vm_backup_retention`, into `browser-vm-target-refresh.sh`, where the
"must be 1" rule still runs before any backup is created. The merged
`setup-source-home.sh` kept integration's validation call to the removed
function and failed at startup on the first installed run.

Verification:
  bash -n scripts/setup-source-home.sh
  bash scripts/setup-source-home-collaboration-config-smoke.sh
…quest in Inbox

The consumer's decision sync recognised a request only when its offer id
matched the Exit or Engine suffix for the contact, so an approved model
request stayed "Requested" on the seed while the owner's Inbox showed it
approved. The kind-to-offer-id relation now lives in one function that the
three Others card builders and the decision filter share, with a test that
walks every requestable kind.

Inbox copy for a service request now names the requested service (Browser
Engine, AI model, Browser Exit Node) and what approval does, from one table.

Found on the installed lane: Mac test Home d9ceb3d as owner, seed test root
d9ceb3d as requester, request delivered and approved, decision never applied.

Verification:
  cargo test -p elastos-server --lib -- services_kind_tests remote_model home_services (5)
  cargo fmt --all -- --check; node scripts/home-entropy-check.mjs; git diff --check
…l provider

The consumer proxy appended remote offers to the local `offers_list` reply.
A Home that runs no model provider (the Linux seed without a GPU) answered
`provider_error` there, so the Assistant showed "No model offer on this Home
yet" although a grant was approved. When remote grants exist and the local
reply is not `ok`, the proxy now starts from the empty typed offers list, with
`local_provider: "unavailable"`, and appends the granted offers to it.

Found on the installed lane: seed test root 54eae4d with an approved grant.

Verification:
  cargo test -p elastos-server --lib -- gateway_model_remote remote_model
  cargo fmt --all -- --check; node scripts/home-entropy-check.mjs; git diff --check
The services layer stores the granting Runtime's Carrier peer id under
`peer_did` (the wire shape shared with Engine grants). The Carrier route pins
ticket endpoints to a `did:key`, so the raw peer id matched no endpoint and
every consumer call ended as `transport_interrupted`. The consumer grant now
converts the peer id once, the way the Engine consumer does, and a malformed
id yields no grant.

Found on the installed lane: seed test root 36f4d7f with an approved grant,
`offers_list` reporting `remote_services[0].status = transport_interrupted`.

Verification:
  cargo test -p elastos-server --lib -- gateway_model_remote remote_model (11)
  cargo fmt --all -- --check; node scripts/home-entropy-check.mjs; git diff --check
… and reserve capacity first

Both run indexes read a `status` field to decide that a run had settled. A
`runs_events` page carries no status; its terminal event carries
`terminal: true`. The Assistant settles from that stream, so every completed
run stayed recorded as open on the owner and on the consumer, and the fake
provider in the loopback test added the field the real one lacks. One shared
predicate now reads the run view (`status`, `terminal`) and the events page
(`events[*].terminal`), and the test provider answers with the contract shapes.

Open records evaded pruning, so the owner index could fill; a `runs_create`
then dispatched model work and failed to record it. Both sides now reserve a
record slot before any dispatch and refuse with `rate_limited` when full; if
recording fails after a dispatch, the dispatched run is cancelled.

Verification:
  cargo test -p elastos-server --lib -- remote_model gateway_model (19)
  cargo fmt --all -- --check; node scripts/home-entropy-check.mjs; git diff --check
The consumer required a currently approved grant even to read or cancel a
run it had already routed, and the proxy skipped remote routing entirely when
no active grant remained. That contradicted the owning Runtime, which keeps
`runs_get`, `runs_events` and `runs_cancel` open for runs created under a
grant. The stored route now carries the granting Runtime's ticket and display
name; run operations always consult the route, settle through it when the
grant is gone, and only `runs_create` needs an active grant.

The loopback fixture gains the seed's own registry with a Carrier invoker, so
a test drives `route_run_operation` the way the seed gateway does: create
under an active grant, deny on the owner, then settle both event pages with
no active grant while a new create is refused with `denied`.

Verification:
  cargo test -p elastos-server --lib -- remote_model gateway_model consumer_path (20)
  cargo fmt --all -- --check; node scripts/home-entropy-check.mjs; git diff --check
… was delivered

The Inbox deny handler returned the gossip delivery error before its
cancellation sweep, so a denial the requester could not receive left that
requester's runs working on the owner's Runtime. Local revocation effects now
run first: the sweep always follows the recorded denial, and the delivery
result is returned after it. A settled cancel also closes the run record, so
a later sweep does not cancel the same run again.

Verification:
  cargo test -p elastos-server --lib -- remote_model gateway_model (21)
  cargo fmt --all -- --check; node scripts/home-entropy-check.mjs; git diff --check
The route's new `display_name` field had no default, so an installed
consumer index from the previous build failed to parse and every
`runs_create` on that Home returned "remote run index parse". Both new
fields now default to empty, and a test parses a legacy index.

Found on the installed lane: seed test root 5f31a93 with three routes from
9bef09a.

Verification:
  cargo test -p elastos-server --lib -- gateway_model_remote remote_model
  cargo fmt --all -- --check; node scripts/home-entropy-check.mjs; git diff --check
An open record whose settlement a Runtime never observed stayed forever.
No offer runs longer than its provider-bounded runtime, so an open record
now leaves after the same retention window measured from its creation.

Observed on the installed lane: three records from earlier builds stayed
open after their runs had long completed.

Verification:
  cargo test -p elastos-server --lib -- remote_model gateway_model (21)
  cargo fmt --all -- --check; node scripts/home-entropy-check.mjs; git diff --check
…ial is saved

The previous repair ran the cancellation sweep on every denial result,
including one that failed before anything was saved. The decision lookup is
principal-scoped while the sweep selects runs from the shared index by grant
id, so another Inbox principal who knew a request id could cancel the
owner's runs, and a failed save could cancel work under a grant that stayed
approved.

The recorded decision is now a typed outcome: `Err` means nothing was saved,
`Ok` carries the message and a separate delivery result. The Inbox deny
action saves the principal-scoped denial, then sweeps, then reports the
delivery result. Gateway-level tests cover another principal (no cancel,
grant stays approved), a denial that could not be saved (no cancel), and a
saved denial whose delivery failed (the open run is cancelled and a new
create is refused).

Verification:
  cargo test -p elastos-server --lib -- remote_model gateway_model (23)
  cargo fmt --all -- --check; node scripts/home-entropy-check.mjs; git diff --check
The previous capacity check counted records and released the index lock
before dispatch, so two creates could both pass the last free slot; it also
refused a retry of an already recorded request when the index was full.

Both indexes now keep pending reservations beside their records. A create
first recognises an existing record for the same grant, principal and
request id (a retry after a lost reply consumes no slot; the provider's
create is idempotent), otherwise it holds a slot under one lock and one
index write. The slot is committed with the run's record or released when
nothing was dispatched; a slot older than ten minutes returns to capacity.

Tests: two concurrent creates at the last slot dispatch exactly one run and
the other is refused with `rate_limited`; a recorded request retries through
a full index without a new slot while an unrelated request is refused; the
consumer's retry reuses its route.

Verification:
  cargo test -p elastos-server --lib -- remote_model gateway_model (25)
  cargo fmt --all -- --check; node scripts/home-entropy-check.mjs; git diff --check
…e journal prunes a run

The provider journal keeps a run for its offer's retention; a consumer that
reconnects later found only a provider error and showed "Run acceptance is
unknown" for a run that had completed. The owning Runtime's record now keeps
the run's operation and the terminal status it observed. When the provider
no longer knows a run, `runs_get` answers with that status (or an honest
`settlement_unknown` when no settlement was observed), marked
`settlement_source: runtime_index` and `output_retained: false`, and
`runs_events` answers an empty final page. Ownership checks still apply.

Verification:
  cargo test -p elastos-server --lib -- remote_model gateway_model (26)
  cargo fmt --all -- --check; node scripts/home-entropy-check.mjs; git diff --check
…ser ask again

The seed card kept reading Approved after the six-hour model grant expired,
and selecting it again did nothing because the offer was already subscribed.
The card now shows Expired and Ask to use sends a fresh request. The unused
access-grants summary field is not part of this change.

Verification:
  cargo test -p elastos-server --lib -- an_approved_model_grant_past_its_expiry remote_model gateway_model (27)
  cargo fmt --all -- --check; node scripts/home-entropy-check.mjs; git diff --check
Replay after journal cleanup answers from the owner record and a live
journal read. Only a missing-run reply uses the status-only fallback.
Assistant settles a terminal create or a retained events page at the
client cursor.
fix(build): pin x264 fetch to its commit and tree
docs: record task permissions and GitHub work rules
docs: continue issue work while CI runs
Bind local chat to engine context limits
Read the operator fixture DID before starting its gateway and verify the bootstrap identity before peer admission. Anchor update and cache stages to exact lines, require the expected binary hash, and bind response-loss classification to host exit 75.

Validation: seven mocked/pure observer tests, four AGENTS source gates, YAML parsing and shell syntax. The spoofed-target regression fails on the prior observer and passes here.
fix(update): observe isolated Mac hop accurately
Workspace version 0.7.1 in elastos/Cargo.toml, the Runtime lock file and
the 14 capsule lock files that pin Runtime crates (65 version lines; no
other dependency changes). The carrier dependency check expects
elastos-identity 0.7.1. CHANGELOG gains the 0.7.1 developer-release
section. VERSIONING.md drops stale version numbers, points release status
to the GitHub release issue and records that monthly source releases use
plain X.Y.Z.
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