<feed xmlns='http://www.w3.org/2005/Atom'>
<title>newos4/modules/core/module-loader.js, branch v4.6.156</title>
<subtitle>newOS4 - the browser terminal that runs WebX11 user spaces</subtitle>
<id>https://newos.webx11.duckdns.org/newos4/atom?h=v4.6.156</id>
<link rel='self' href='https://newos.webx11.duckdns.org/newos4/atom?h=v4.6.156'/>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/'/>
<updated>2026-11-07T18:29:06+00:00</updated>
<entry>
<title>fix(newos4): workspace re-opened the modules panel every tick; picker lost two cards; commander was black</title>
<updated>2026-11-07T18:29:06+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-07T18:29:06+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=a46ebee30cfbbac86abb45068411bc28e1c65503'/>
<id>urn:sha1:a46ebee30cfbbac86abb45068411bc28e1c65503</id>
<content type='text'>
Three defects reported against v4.6.155, each reproduced before touching code:

1. 'the modules tab keeps opening' (workspace). api.capture() runs dispatchCommand() for real, and
   the Modules card called bare 'modules' — whose only effect is terminal.openModuleManager().
   Every 15 s refresh re-opened the panel (measured: #module-manager display:flex at t+9s and
   t+18s). The card now captures 'listmods' (same inventory as text), and api.capture() refuses
   UI-only commands outright so a future card cannot reintroduce it.

2. 'the picker got reduced to 4 items'. showPicker() used this.list() once four modes were
   registered — but modes are lazy, so that is 'modes you have already visited'. It now always
   renders the six in level order, taking registered specs for label/tagline.

3. 'commander is mostly black' on a phone. The base sheet's #ui-root rule used
   body[data-ui-mode]:not(...) #ui-root (1,2,1) and therefore beat every mode's own
   body[data-ui-mode='x'] #ui-root (1,1,1): commander/studio/cockpit asked for display:grid and got
   flex column. Commander collapsed to a 253 px centre column in an 844 px page with both rails
   hidden. Base specificity is now (1,0,0) with an explicit !important hide for classic/boot, and
   the commander phone query pins grid-template-rows: minmax(0,1fr) so the single row fills.

Measured after: picker 6 cards after visiting four modes; #module-manager stays display:none
across a refresh cycle; commander display:grid, phone centre 390x810 with a 673 px terminal,
desktop 232/788/260 columns. probe-ui-modes.py --cycle -&gt; ALL PASS, 13 checks; shell test 25/25.
v4.6.156
</content>
</entry>
<entry>
<title>fix(newos4): second review round — identity for every stock node, load dedup, sweep race, a11y</title>
<updated>2026-11-07T18:03:38+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-07T18:03:38+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=05d72563637e88825ff852d803621c567de47e34'/>
<id>urn:sha1:05d72563637e88825ff852d803621c567de47e34</id>
<content type='text'>
Four models (kimi-k2.7-code, deepseek-v4-pro, minimax-m3, glm-5.3) reviewed the shipped change
set. Review log with every accepted and rejected finding:
.hermes/plans/2026-11-07_163420-newos4-six-ui-modes.review-log.md

- identity guard now covers every snapshot node, not just #terminal-container: terminal.js also
  binds #output, #command-input, #input-area and #status-bar, so a cloned one leaves the terminal
  writing into a detached node while the page looks perfect
- _restoreStock anchors on the next stock node already home, then on the recorded trailing
  sibling; a raw child index was measured wrong (terminal,input,status-bar,quick-actions)
- _loading map: a double-clicked card or a repeated 'ui easy' loads the mode once
- _sweepPending returns while that id is in flight instead of declaring failure at 6 s and
  overwriting the stored preference
- _syncChrome() on every switch (quick-actions was left in the tab order behind the mode root)
- picker: role=dialog/aria-modal/labelledby/focus, shown after 600 ms instead of waiting for a
  registration that never happens with lazy modes, and suppressed when ?ui= already applied
- ?ui= must be one of the six; _loadMode only accepts packages['ui-&lt;id&gt;']; hasOwnProperty on modes
- VFS names are shell-quoted before reaching api.exec (cat/edit)
- refresh generation no longer bumps per tick (slow captures left later panes at '...')
- easy: padding shorthand reset the 34 px footer reserve (footer overlapped the composer)
- cockpit panes get tabIndex and focus; F1/F12 left to the browser; nothing swallowed in inputs
- api.el lost its unused innerHTML sink; the test lost its _parseArgs stub (it hid the regression)
- v4.6.155
</content>
</entry>
<entry>
<title>chore(newos4): v4.6.153 — cache-bust the review fixes</title>
<updated>2026-11-07T17:57:47+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-07T17:57:47+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=e0b87c7b5a902dea69ac45ffa2e525387edebf42'/>
<id>urn:sha1:e0b87c7b5a902dea69ac45ffa2e525387edebf42</id>
<content type='text'>
</content>
</entry>
<entry>
<title>feat(newos4): six interface modes (easy -&gt; cockpit) over one terminal</title>
<updated>2026-11-07T17:19:47+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-07T17:19:47+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=aac2b1c0689aefeb140e08c24278ec486611fe10'/>
<id>urn:sha1:aac2b1c0689aefeb140e08c24278ec486611fe10</id>
<content type='text'>
Symptom: newOS4 had exactly one layout. A first-time user had no way in that did
not require learning commands, and an operator had no surface showing live runtime
state; the only way to see heap/VFS/tool-call telemetry was to type cat /sys/...

Root cause: no UI layer existed. main.html hard-codes one flex column, and
terminal.js binds the stock nodes by id at construction, so an alternative layout
had to either duplicate the output stream or reparent the real nodes.

Fix:
- modules/core/module-uishell.js (new): mode registry, #ui-root, stock-node
  snapshot/restore, identity check that reverts to classic when a mode removes or
  clones #terminal-container, shell-docked #ui-foot (the AI stop button exists in
  every mode), ui command, gated first-run picker, ?ui= honoured only if the mode
  actually registers, lazy mode loading via the same loader ext modules use.
- modules/ext/ui-{easy,chat,studio,workspace,commander,cockpit}.js (new): six
  reparenting skins with scoped CSS. Workspace/commander/cockpit read real /sys/*
  mounts and captured command output; no value on screen is invented.
- modules/test/test-ui-shell.js (new): 25 assertions - teardown, clone rejection,
  failed-mount fallback, footer docking, destructive-mode rejection.
- terminal.js: register the shell; make one failing ext module stop aborting the
  rest of the serial load loop (it did, silently, which is why six ui-* files at
  the end of extKeys never loaded).
- module-loader.js: LATEST_VER v4.6.152. The six ui-* keys are deliberately NOT
  in extKeys - see the rate-limit note below.
- admin/scripts/probe-ui-modes.py (new): 6 modes x 2 viewports plus a --cycle pass
  that switches all seven states on ONE page and asserts the output node keeps its
  identity.

Also fixed, found while testing (pre-existing, production-affecting):
- nginx limit_req zone=webx11 burst 50 -&gt; 200. One newOS4 boot fans out ~40 assets;
  the bucket emptied mid-boot and every later module got 503. Measured in
  webx11.error.log: "limiting requests, excess: 50.696 by zone webx11" against
  modules/ext/ui-chat.js. A reload within ~50 s silently broke modules. Sustained
  rate unchanged at 60r/m.

Verified: node modules/test/test-ui-shell.js -&gt; 25/25; removing both _restoreStock()
calls measures 20/25 with five FAILs; probe-ui-modes.py --cycle against production -&gt;
ALL PASS, 13 checks; served bytes: v4.6.152 x3 in main.html, class UIShellModule x1
in core-bundle.js, six ui-* packages in packages.json.
</content>
</entry>
<entry>
<title>release: v4.6.151 — wget that actually saves, web_fetch that actually pages</title>
<updated>2026-11-06T15:19:59+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-06T15:19:59+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=0cb252dfbeb02d23cd92bad3ca8df76be22d9f92'/>
<id>urn:sha1:0cb252dfbeb02d23cd92bad3ca8df76be22d9f92</id>
<content type='text'>
S1 (reported by agent-os4-maint-01, wrongly refuted by the chat auto-reply):
wget existed but was unusable and dishonest.
- Cause 1: _cmdWget used the page's own fetch(url), so every cross-origin URL
  died on CORS ("Failed to fetch"). Measured in the served v4.6.150 page:
  fetch(cgit README) threw, /api/fetch returned 200/1954 bytes.
- Cause 2: _vfsWriteBytes ignored writeFile()'s boolean, so the command printed
  a green tick when the target directory did not exist. Measured:
  fs.writeFile('nosuchdir/x.txt') === false.
- Cause 3: bytes were round-tripped through String.fromCharCode, mangling UTF-8.
- Fix: fetch through /api/fetch (raw source), mkdir -p, writeFile + read-back
  verification, error instead of a tick on failure. Register curl with
  -s/-o parsing delegating to the same writer so the two cannot drift.

S2 (same reporter): web_fetch could not page and said it could.
- Cause: the handler honoured max_chars up to 50 000, then _clipToolResult kept
  toolResultChars-200 = 11 800, so 38 200 chars vanished silently; offset was
  not in the schema and was never read, so next_offset pointed at a page the
  caller could not request again.
- Fix: offset/next_offset/total_chars/source_bytes in the contract; the page is
  built, measured against the clip budget and shrunk until the envelope fits,
  so next_offset - returned_chars is always 0.
- Also fixed: _clipToolResult appended "0 of N chars withheld" when the content
  already fitted, claiming a loss that did not happen.

C1: fetch &lt;url&gt; --save=FILE — the only terminal path from a remote URL to the
VFS, so a 90 KB source page no longer has to be read through 3 000-char
scrollback.

Proxy: /api/extract now returns source_bytes (raw page size) and
content_chars_utf16. Python len() counts code points while JS String.length
counts UTF-16 units; 7 astral characters in the changelog left a 7-char gap at
the end of a 90 KB page (measured). _html_ok declares charset=utf-8.

Verified: node --check on all four modules; py_compile; bundles rebuilt;
served bytes identical to disk for all five assets at ?v=v4.6.151; live in the
browser: curl -s -o review/main.md &lt;cross-origin&gt; saved 1954 chars with the
correct head, a 404 wrote no file, fetch --save wrote 91 518 chars,
web_fetch p1 returned 11 754 with next_offset 11 754 (gap 0), page 2 started at
a different offset with next 23 496.
</content>
</entry>
<entry>
<title>release(v4.6.150): commit the module work that has been live but uncommitted</title>
<updated>2026-11-06T10:45:21+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-06T10:45:21+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=03143a6e88832d06c7b08cdbf8de96ba79bda7d6'/>
<id>urn:sha1:03143a6e88832d06c7b08cdbf8de96ba79bda7d6</id>
<content type='text'>
Operator commit-approve, 2026-11-06. These changes have been served since
2026-11-02/03 while git HEAD still stamped v4.6.146, so the mirror published a
tree four builds behind the running instance and the release tag named the
wrong build.

module-orchestrator.js — orchestrate-parallel reported success it could not
prove. Results are now recorded by sub-task id through a resultSink handed to
delegateTask (harvest matched by currentTask/lastTask strings, which a later
delegation on the same agent overwrote, losing finished work as "agent not
found"); the tally counts summaries with status ok instead of
Promise.allSettled resolutions (a spawn refusal fulfils with undefined and used
to print green); and a busy agent is no longer reused at pool cap, where two
siblings erased each other's lease. Guard:
modules/test/test-orchestrator-parallel-harvest.js (16 cases, reproduces the
one-agent three-sub-task cap case that printed 3/3 succeeded).

module-billing.js — the balance said "not signed in — newOS4 sends no session
token", which was already false: the browser sends the HttpOnly cookie and
parse_bearer_token() falls back to it. `cost` is on by default (the flag was
opt-in and nobody knew the command existed; `cost off` opts out) and the
command now prints today's platform spend from GET /api/billing/usage?days=1
alongside the session estimate.

modules/ext/webdav.js — the inline WebView detector missed "Version/4.0"
Android WebViews, including the operator's own phone, so the login offered a
Telegram widget that cannot complete there. It now delegates to
modules/wx11-tg-webview.js when the page loaded it and keeps a matching
fallback (wv token, Version/4.0-Android, Telegram, FBAN/Instagram/Line).

modules/ext/media.js — text analysis model renamed deepseek-v4-flash -&gt;
deepseek-v4.1-flash in both the field and the printed label.

main.html + module-loader.js — v4.6.146 -&gt; v4.6.150 in LATEST_VER and the three
asset queries; core-bundle.js rebuilt (rebuild-bundles.py reports it already
in sync, 1,250,569 bytes).

Verified: node --check on all six scripts and the new test; the 16-case
orchestrator guard passes against the deployed bundle (ORCH_SRC=...); bundle
rebuild is a no-op; core-bundle.js?v=v4.6.150 answers 200.
</content>
</entry>
<entry>
<title>refactor(dashboard): one dashboard — port billing/API keys, 301 the duplicate</title>
<updated>2026-11-02T21:18:09+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-02T21:18:09+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=e081d986ef0562cb9983fd1d8ff189bc0c13c975'/>
<id>urn:sha1:e081d986ef0562cb9983fd1d8ff189bc0c13c975</id>
<content type='text'>
Two dashboards existed and had drifted apart: root /dashboard.html (118 KB single file with
Subscription &amp; Usage + API Keys) and /spaces/dashboard.html (34 KB shell + assets/js/dashboard-*.js).
The nginx log settles which one is real: 77.211.5.129 requests /spaces/dashboard.html and never
the root page. Tonight's fixes landed on the root page twice before that was noticed.

Neither page was a superset, so deleting outright would have lost features:
  root only      -&gt; Subscription &amp; Usage card, API Keys card (create/revoke/reveal)
  spaces only    -&gt; 2FA/TOTP, change password, delete space, email change, files, logs

assets/js/dashboard-billing.js + assets/css/dashboard-billing.css (new)
  loadSubscription / loadApiKeys / cancelSubscription / createApiKey / revokeApiKey /
  copyNewApiKey / dismissNewKey + isProPlusPlan / capPlan, lifted verbatim from the root page,
  wrapped in an IIFE that re-exports the onclick handlers on window; getAuthHeaders() reads the
  modular app's localStorage.webx11_session_id; PRO_PLUS_PLANS carried over (its absence threw
  "PRO_PLUS_PLANS is not defined" and silently hid both cards on the first attempt)

spaces/dashboard.html
  the two cards inserted after the Activity Logs card, plus the css/js includes
  dashboard-auth.js showDashboard() calls loadSubscription() once the view is up

retirement
  root dashboard.html deleted (git rm); `location = /dashboard.html { return 301
  /spaces/dashboard.html$is_args$args; }` so bookmarks keep working and ?next= survives
  links repointed in ai-api.html (6), ai-course.html (3), models.html (1), newOS4 hint string
  (v4.6.146 + rebuilt bundles so the cached bundle cannot serve the old URL)

Measured (playwright, 390x844 WebView UA, agando's real session):
  subscriptionCard display block, height 315px, plan "Free", price "EUR0/mo", badge "Free",
  usage "$0.00 / inf", API-keys card hidden for a free plan, 0 console warnings
  /dashboard.html?next=/skills.html -&gt; 301 -&gt; /spaces/dashboard.html?next=/skills.html, 200,
  login card + Telegram button present
</content>
</entry>
<entry>
<title>fix(auth-ui): stop offering a Telegram widget where it cannot work</title>
<updated>2026-11-02T21:02:45+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-02T21:02:45+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=d01d94bed3038b4fc122b2cc17f0773b9bf4dc9f'/>
<id>urn:sha1:d01d94bed3038b4fc122b2cc17f0773b9bf4dc9f</id>
<content type='text'>
Two hosts cannot complete the widget flow and both are in use: an Android WebView /
in-app browser (the operator's phone UA ends "; wv)") and a desktop browser that blocks
the popup or hands the link to the Telegram app. The widget needs a popup that can
postMessage back into the opener; in those hosts the link lands in a browser tab or in
Chrome with no opener, onTelegramAuth never fires, and the login card looks dead —
"it opens my default browser" (reported twice: phone, then Max's laptop).

modules/wx11-tg-webview.js (new)
  WX11TG.isWebView()  -&gt; "; wv)", Telegram in-app, Meta in-app UAs
  WX11TG.dropWidgets()-&gt; removes already-rendered oauth.telegram.org iframes/scripts

dashboard.html
  code box is open by default and drops the nested &lt;details&gt;
  WebView: widget removed + "cannot work inside an app window" hint
  desktop: if the widget was clicked and onTelegramAuth has not fired in 12 s, open the
  code flow with a hint instead of leaving a dead card

spaces/newos4 (webdav-login panel)
  in a WebView the widget is never injected, the mount is hidden and the device-code
  flow starts by itself; desktop keeps the widget unchanged
  version v4.6.145

Measured with playwright (390x844 WebView UA and 1440x900 Chrome):
  WebView  -&gt; 0 Telegram iframes, hint shown, code box open, real WX11- code minted
  desktop  -&gt; widget still rendered, code box open, real WX11- code minted
  newOS4 WebView -&gt; no widget injected, code area auto-visible, code WX11-..., no JS errors
  newOS4 desktop -&gt; widget still offered
</content>
</entry>
<entry>
<title>fix(auth): one session writer for every login path; expire dead credentials</title>
<updated>2026-11-02T20:51:31+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-02T20:51:31+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=6ebfaf0323259d07ccb485af82fac70a7b42fdf6'/>
<id>urn:sha1:6ebfaf0323259d07ccb485af82fac70a7b42fdf6</id>
<content type='text'>
Third occurrence of the same class of bug, and the first fix is why: commit e95b7be
(2026-11-01, "multi-session .newsession v3") touched exactly ONE hunk of
auth-file-api.py — handle_login. handle_device_poll, handle_telegram_login and
handle_register kept overwriting the whole .newsession with a single-session v2
payload, so a phone sign-in logged the desktop out and the loser held a session id
no store knew: permanent `401 Invalid session or API key` (newOS4 asked for a login
it could never complete). Measured: agando's store held 1 entry (sha8 45cb7819) while
the phone sent 9ac607f1 for 3 h; 26 device-polls in 2 s from one page minted 26
cookies and only the last write survived, which also drained the shared nginx
`webx11` zone (11x 503 on /admin/api/*).

api/webx11_auth.py
  - add_session() is now THE writer: v3 `sessions[]` (cap 5) under a per-user
    `flock` (LOCK_DIR outside the spaces), plus the legacy `.session` mirror
  - module-level import so no handler has to reach for it lazily

api/auth-file-api.py
  - device-poll / telegram-login / register / recover-by-backup-code all call
    add_session(); a bare write_newsession_file() is now only the admin-gated
    handle_create_session
  - handle_device_poll runs its approved branch under a per-code `flock` and mints
    exactly one session per approved code (idempotent under a poll storm), with a
    cheap pre-lock reject so unvalidated codes cannot mint lock files
  - handle_me_cookie expires an unknown session cookie (Set-Cookie Max-Age=0,
    code SESSION_DEAD): the cookie is HttpOnly, so no page could ever clear a dead
    credential and every load re-sent it

api/newcrypto.py
  - write_newsession_file() is atomic (tmp + fsync + os.replace); the temp name
    carries pid+tid because a fixed `&lt;file&gt;.tmp` lets two concurrent writers of one
    store steal each other's temp file (reproduced: FileNotFoundError)

admin-login.html      single-flight poll (polling/finished guards) — 26 calls -&gt; 1
dashboard.html        device-code fallback when the Telegram popup has no opener
spaces/newos4/*       401 -&gt; session-repair notice + endpoint normalisation, v4.6.144
nginx                 /api/auth/ + /api/security/ on zone wx11auth (120r/m, burst 60)
admin/scripts/verify-session-writers.py  NEW static guard, wired into smoke-auth.sh

Proof (live, after restart): 5 concurrent polls on one approved code -&gt; 5x approved,
1 distinct session id, store v3 with 2 entries, pre-fix session still valid; dead
cookie -&gt; 401 + Set-Cookie expiry, valid cookie -&gt; 200; 200-call auth burst -&gt; 503s
only on /api/auth/, /admin/ stayed 302; smoke-auth.sh PASS. Guard RED (3 offenders)
-&gt; GREEN. Backups: /home/darkbot/backups/authfix-20261102_214424
</content>
</entry>
<entry>
<title>fix(newos4): read_file pages were silently truncated; delegation no longer invents "completed"</title>
<updated>2026-11-02T20:21:24+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-02T20:21:24+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=e2f36467748943639c960453549b6b91c8cc7ab2'/>
<id>urn:sha1:e2f36467748943639c960453549b6b91c8cc7ab2</id>
<content type='text'>
Two defects found by re-deriving a report that claimed both were still open.

read_file paging (module-aiassist.js)
- A page larger than the result clip was clipped AFTER read_file had computed
  next_offset. On the last page next_offset is null, so the model was told
  truncated:false while its tail had been removed: measured 11 890 of 19 999
  chars delivered, returned:19999, no pointer to the rest - 8 109 chars lost
  with no way to ask for them.
  * the clip now sets truncated=true and next_offset=offset+keep when it removes
    the tail of a page that had no continuation (and never splits a surrogate pair)
  * read_file caps a page at the result budget (min(pageCap, toolResultChars-200)),
    so a page is always delivered whole and next_offset is exactly contiguous
  Live v4.6.143: 19 999-char file -&gt; page 11 800 (next_offset 11 800), page 2
  8 199 (next_offset null): 11 800 + 8 199 = 19 999, nothing withheld. A model
  asking for limit:32000 is clamped to 11 800 and told truncated:true.
  The ~500-char symptom was the 500-char floor: a caller passing limit:200 gets
  500, which is why targeted sed -n reads looked better than the tool.

Delegation reporting (module-orchestrator.js, module-aiassist.js)
- chat() returning {content} was already fixed in 8a9333b, but three other places
  still substituted the word "completed" for an absent answer, so the symptom
  survived: delegateTask's outbox wrote status:'completed' even when the worker
  returned nothing; the delegate_task tool returned {success:true, result:"completed"};
  orchestrate-parallel summarised an unmatched agent as {status:'ok',
  result:'completed (agent recycled)'} and a missing outbox as "completed (no outbox)".
- Now: an empty/undefined answer is status 'failed' with error 'agent produced no
  answer' / 'no result in outbox' / 'agent not found — result unverifiable', and
  the tool returns success:false with result:null.

Tests: test-delegation-reporting.js 6 (RED 3/6 against HEAD: D3/D4 success:true,
D5 the literal "completed"), test-tool-context-bound 26 with E6-E8 (RED 24/2:
truncated:false, next_offset null). maintain 27/27.
</content>
</entry>
</feed>
