<feed xmlns='http://www.w3.org/2005/Atom'>
<title>newos4/CHANGELOG.md, 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>docs(newos4): rebuild changelog for v4.6.152</title>
<updated>2026-11-07T17:29:03+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-07T17:29:03+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=e894b666fd9d51f41fd9f9c7a2a3e0cf4fef2511'/>
<id>urn:sha1:e894b666fd9d51f41fd9f9c7a2a3e0cf4fef2511</id>
<content type='text'>
</content>
</entry>
<entry>
<title>docs(newos4): v4.6.152 changelog + change-history row for the six modes</title>
<updated>2026-11-07T17:20:27+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-07T17:20:27+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=c2f5c87529376c9f0a5d577378505489de8c85b8'/>
<id>urn:sha1:c2f5c87529376c9f0a5d577378505489de8c85b8</id>
<content type='text'>
</content>
</entry>
<entry>
<title>chore(changelog): regenerate for v4.6.150</title>
<updated>2026-11-06T10:45:26+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-06T10:45:26+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=65b28012ed3aa492604310b43fc499cc13a592c6'/>
<id>urn:sha1:65b28012ed3aa492604310b43fc499cc13a592c6</id>
<content type='text'>
</content>
</entry>
<entry>
<title>chore(changelog): regenerate after the render and ordering fixes</title>
<updated>2026-11-06T10:41:00+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-06T10:41:00+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=15b42d6379484bb3f439eb5d7f77f12877f74497'/>
<id>urn:sha1:15b42d6379484bb3f439eb5d7f77f12877f74497</id>
<content type='text'>
</content>
</entry>
<entry>
<title>fix(changelog): keep the newest commits of a build; wrap long detail URLs</title>
<updated>2026-11-06T10:40:54+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-06T10:40:54+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=7bdcd58762c60c9501657b9df2983999f276f8b1'/>
<id>urn:sha1:7bdcd58762c60c9501657b9df2983999f276f8b1</id>
<content type='text'>
Symptom: after bodies were rendered, this fix's own commit was missing from
its own entry, and a long URL inside an expanded detail was clipped at the
right edge on a 390 px screen.

Cause: items took group[:MAX_ITEMS] from a CHRONOLOGICAL list, so a 17-commit
build showed its first 14 and dropped the newest three (the count line said
"…and 3 more", hiding which three). And the injected detail CSS set no
overflow-wrap, so a 47-character URL pushed the paragraph to 320 px of
unbreakable text — the document stayed at 0 overflow only because the li
clipped it.

Fix: show group[-MAX_ITEMS:] and label the omitted ones "…and N earlier
commit(s)"; entry.commits follows the same slice. overflow-wrap:anywhere on
detail p/ul. The CSS block is now re-emitted from DETAIL_CSS behind
BEGIN/END sentinels instead of being write-once, and the first version's
sentinel-less block is stripped on sight so no page keeps two copies.

Verified: 390 px — p scrollWidth == clientWidth == 320, document overflow 0,
URL wraps; newest entry lists c759c50 and this commit; island 83 entries,
14 commit chips matching 14 shown items; CHANGELOG.md byte-identical on a
second run.
</content>
</entry>
<entry>
<title>fix(changelog): render the commit body, not just the subject</title>
<updated>2026-11-06T10:37:11+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-06T10:37:11+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=1983ce5796e45b312b142554cb717db7f8978bc8'/>
<id>urn:sha1:1983ce5796e45b312b142554cb717db7f8978bc8</id>
<content type='text'>
Symptom: the mirrored CHANGELOG.md (and the page) showed one-line commit
summaries while README promises "every shipped fix, symptom -&gt; cause -&gt; fix -&gt;
verified". A reviewer measured the gap from the public mirror and could only
conclude the claim overpromised.

Cause: scripts/build-changelog.py:59 formatted commits with %s only; %b was
never read, so the verification prose every fix commit carries (5b55af9 is a
typical one) was discarded before rendering. The MD writer then replaced every
tag with a backtick, so nothing richer could have survived anyway.

Fix: read %b with a %x02 terminator (line-based parser, multi-line body), split
it into paragraph/bullet blocks capped at 900 chars with a visible marker, and
render it twice from one source: as a native &lt;details&gt; per item on the page
(its renderer already assigns item HTML, so no JS change; CSS injected once
behind a sentinel) and as nested bullets under the line in CHANGELOG.md. The
"every build" gap note and the page dek were rewritten to describe what the
file now contains.

Verified: page 100 details render, first opens 23 -&gt; 232 px with 3 paragraphs,
no horizontal overflow, island parses (83 entries); two consecutive runs are
byte-identical for CHANGELOG.md; the double-escape bug this surfaced (code
spans shipped as &amp;amp;lt;sha&amp;amp;gt;) is fixed and grep for &amp;amp;lt; is 0.
</content>
</entry>
<entry>
<title>fix(changelog): stop prepending the preamble on every run</title>
<updated>2026-11-05T19:40:17+00:00</updated>
<author>
<name>WebX11 SysOp</name>
<email>darkmotox11@gmail.com</email>
</author>
<published>2026-11-05T19:40:17+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=842357847dee369da41e690a3069905200adf124'/>
<id>urn:sha1:842357847dee369da41e690a3069905200adf124</id>
<content type='text'>
write_md() put the H1 + description inside the generated body and also kept
old[:m.start()], so each regeneration added another copy: 44 runs left 44 H1s and
pushed the first release to line 179. Only the region between the markers is
generated now, an existing file with N copies is collapsed to one, and an assert
refuses to write a file containing two generated regions (proven RED by injecting
a duplicate). Regenerated: 83 entries, 185 commits, first heading v4.6.146 (was
v4.6.135 - the file had not been committed since 2026-11-02).
</content>
</entry>
</feed>
