Carries the master sync forward (invariant-companion cleanup, alpha.3 bump);
regenerates the client api catalog so ISession lists both killJob and the new
loadThrough, and refreshes the new ptc-python-turn scenario's system-prompt
pin for this branch's bash timeout-promotion schema text.
Absorbs the repo-wide no-op invariant companion removal (ui-jobs loses its
placeholder companion, export, and devDep), the 0.1.2-alpha.3 release bump,
and the tool-subagent-report package retirement; regenerates the client slot
catalog for the shifted contract line numbers.
Observation (re)opens run on caller stacks — a React expand click, a
carrier retry — whose dynamic context has not declared remote.session, so
the ClientJobOutput wiring resolves the namespace to a concrete value while
the plugin's own context is current, exactly as the activity client did.
Caught by the live-job-stream web e2e, whose goldens (with the
background-job-list pair) now carry the ui-jobs list name; the client-apply
spec gains a jobOutput wiring smoke.
The regenerated session namespace requires the new stream; the fake serves
a never-yielding generator, and job-output.client.spec exercises the real
consumer.
Chinese sides of the jobs, jobs-local, tool-bash, tool-pwsh, tool-workflow,
session-controller, and ui-jobs pages follow their English edits; the
generated en-only catalogs (config catalog, capability seams, event
producer/consumer) get the same section surgery by hand; the activity
subsystem page triplet is fully removed and the jobs page carries the
record contract in both languages with fresh type-equiv manifest entries.
The three prior activity notes point at the superseding note. Web e2e label
assertions follow the ui-jobs copy, and the three test call sites that
invoked run() bare pass the producer face.
packages/activity/* and packages/api/activity-controller are removed. The
web roster is the session control stream's jobs frames alone; per-job output
observation rides session.observeJob and the client ctx.jobOutput service.
ui-activity returns to its upstream name ui-jobs and renders the single
roster — a row is expandable exactly when its job declared a record
(outputTotal present). Composition rows, dependency-policy exemptions,
tsconfig aliases and references, generated catalogs, and the docs pages
follow; the activity subsystem page is deleted and the jobs page gains the
record contract. The superseding Agent Note records the decision and points
the three prior notes at it.
SessionJob rows carry outputTotal exactly for record-declaring jobs, and a
new session.observeJob stream serves one job's retained record from an
absolute offset (anchor, coalesced output frames, terminal status) with the
fenced read resolved from the request's session — the same authorization
shape as the jobs roster. The client half gains ctx.jobOutput: the
reference-counted per-job observation service and its accumulated view
model, ported from the activity controller this replaces.
loadThrough now assigns its low-water target only when it owns the loop
(retargeting stays inside the running-jump branch): a call refused while
a plain load-earlier pull holds the pager no longer leaves jumpTargetSeq
behind to drag a later jump all the way to the head. The loop also
carries the doOpen stale-pass guard so a mid-flight resync stops it
instead of paging the new stream generation toward the old target.
READMEs record the rail's outline merge and the loadThrough paging
verb in both languages; the feature Agent Note owns the decision,
alternatives (sparse windows, minSeq wire bound, outline RPC, height
estimation), and coverage map. Regenerates the client/API catalogs the
widened faces feed.
Session.loadThrough(seq) loops the existing prepend pager (200-message
pages) until the window covers the target seq, with a shared low-water
retarget for repeated calls, a no-progress guard against empty pages
still claiming history, and loadOlder's fail-soft error posture. Busy
state rides the existing loadingOlder snapshot bit.
- protocol: isDSHRemoteGatewayError -> isDSHRemoteError (the class is
protocol-wide, not Gateway-specific); remoteErrorOf drops its
instanceof Error precondition and tests the marker plus a string code
structurally, so a marked failure from another realm no longer reads
as a local defect.
- session-controller: the live-follow packed-record protocol violation
now throws a marked RemoteError('gateway/internal'), landing the
session in openState=error instead of an unhandled rejection;
pinned at the transport and session levels.
- util-time: correct the invariant companion's @module name.
- regenerate the tool-cordis catalog for the marker rename.
- api/gateway: $host caches its RemoteHostFacts record and mints a new
one only when home changes, so snapshot readers compare by reference;
identity pinned in the client spec.
- client/ui-tool, client/ui-workspace: the hooks channel exposes the
host facts record as hostInfo and components select the field they
need (useHostInfo(info => info.home)); row-component contracts are
unchanged.
- new cookbook page adding-a-remote-api (en/zh): the five-step HOW-TO
for declaring, failing, registering, consuming, and testing a Remote
endpoint.
- new Agent Note ctx-remote-failure-vocabulary records this round's
decisions and alternatives; the 2026-08-02 and 2026-08-10 notes are
rewritten to the shipped facts (RemoteError vocabulary, $host, the
retired ApiProxy statements).
- package READMEs pick up the new failure-face contracts
(typert/protocol, api/gateway, api/remotes,
test-support/client-runtime), dsh-util-time gains its README and
registry entries, and stale connection/WorkspaceError/legacy-code
statements are corrected (ui-settings, ui-settings-models,
workspace-controller, docs/subsystems/typert incl. the
TypertGatewayErrorCode type-equiv block).
- packages/AGENTS.md gains the Remote-failure rule bullet; its doc
budget rises 675 -> 714: the bullet is the compressed remainder
after relocating detail to the cookbook and the Agent Note.
- api/gateway: mark terminal Remote-stream escapes (carrier retry
exhaustion and pre-acceptance end classification) as
RemoteError('gateway/internal') at the two escape points; marked
failures pass through verbatim. The carrier class stays the
retry-internal signal for carrierFailed and the ended(true) retry
trigger. Regression coverage lands on the session and workspace
stream consumers.
- client/ui-tool, client/ui-workspace: read $host.home through a hooks
observable subscribed to connection/reset; the slot renderer memoizes
inject results per entry, so the previous plain-value injection froze
home at the first render.
- client/ui-settings-models: components no longer receive ctx; apply
binds the credential and settings Remote operations into callbacks,
and the settings/conflict code judgment stays in the apply world.
- classify a carrier throw under a caller-aborted signal as
gateway/cancelled instead of gateway/internal, matching the code the
Host produces when the abort wins the wire round-trip.
- read $host facts from the construction-time Connection handle,
matching $stream; the service cannot be replaced without restarting
this plugin, so the live re-lookup was dead complexity.
- state rebuiltFailure's actual contract in its comment: codes pass
through verbatim without runtime validation.
- correct the @module name in dsh-util-time.
- python/sdk-runtime: add @deepseek-ai/dsh-util-time so the runtime
dependency closure stays closed (dsh-subagent now depends on it).
- api/gateway: drop the dsh.client.external request for
dsh-typert-protocol and admit the protocol package into INLINE_SAFE
instead. The loader module table has no supplier for the protocol
package, so the built client factory threw at require time; the
protocol layer is duplication-safe by design (string marker,
code-based discrimination), which is the inline-safe admission
criterion.
- api/gateway tests: cover the $host getter (live service read,
pre-ready home, and the construction-time fallback after the
Connection service is withdrawn).
Single RemoteError with a merge-extensible, domain-prefixed code map;
owners throw at the failure point; streams surface marked failures;
clients consume ctx.remote directly with isRemoteFailure as the only
discrimination point and construct no failure instances.