main
55
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
62af6e82c7 |
The engine on UXP RB_20261027 (T-551..T-554): the queue rebased, 0060 dropped, every pin, the device checked
The owner's choice of 2026-11-02 after T-551's check found the tag: the update now, patch 0060 (the roots, byte-identical upstream) dropped, special attention to the certificate and HTTPS changes. - update-engine.sh RB_20261027 / --finish: the 72 patches on the tag (0060 fell away as already applied), jihad/uxp-RB_20261027 at 52ad9ab66e in third_party/uxp, the queue rewritten and renumbered from 0060, the pins (engine-version.env, the OE recipe, .gitmodules, the UA and the three start pages: UXP/6b18be9), JIHAD_APP_BUILD_ID 20261103000000; patch-queue.sh --check, check-engine-pins.sh and check-engine-api.py (baseline rewritten, unchanged) agree. - docs/ENGINE-SOURCE.md: the base, the dropped 0060, the renumbering, and the range's 12 commits each with its disposition — the two NSS certificate commits (emSign removed after the eMudhra compromise; certdata to Sept 2026) were on the device since the roots of 2026-10-25 and are the base's now; no PSM, TLS protocol, HSTS or certificate-UI change in the range; the memory-safety fixes (the JS OOB array copy, the jar: flag, feTile, the layout frame table, the mutation observer's strong ref, SQLite 3.54.1) taken with the base. - audit-roots.py against the fetched release certdata and the CCADB report: identical set and trust, none removed, RESULT OK (docs/rounds/certs-2026-11-03). - Desktop: the full build clean; 14 of 18 tests pass, the four left are the desktop GTK path's known read-back limit. ARM: libxul, the daemon, the bundle, the three packages; full pushes to all three variants; default-check x3 faults 0; the daemon's start line 28 of 29 optional exports as before. The areas the commits touch, on the device (tools/device/engine-checks.sh, new): about:settings, about:personas and about:addons through jar: under the flag change, cookies through the new SQLite, an SVG filter page with feTile and its overflow case (render/goanna/test/jihad-svg-filter.html, new), a long press's selection; faults 0. The certificate kit's checks (tools/device/cert-checks.sh): the TLS 1.0 refusal, the clean loads, expired / wrong.host / self-signed / untrusted-root with the SSL confirm's right flags, OCSP revocation enforced on grc.com, ssl.com and DigiCert's demos, revoked.badssl.com's CRL-only case invisible as before: nothing changed with the base. Records: docs/rounds/engine-rb27-2026-11-03/notes.txt. - tools/device/cert-checks.sh and t502/enyo-restore-job.sh (new): the certificate kit's device checks under a hand-started daemon, and the Enyo job put back after any spike round. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
62df604c54 |
Licensing audit: notices for everything bundled, no borrowed marks
The owner: "ensure that all software patent and trademark licenses in the repo are being respected". A read-only audit of what the packages carry found no blocker and these gaps, all closed here (the record is impl-review-findings-6.md, "Licensing audit"): - NOTICE names the runtime the engine ships with: glibc 2.23 as crosstool-NG modifies it (LGPL-2.1), the GCC 9.4.0 runtime (GPL-3.0 with the Runtime Library Exception), and the eight Debian jessie libraries, with the FreeType disclaimer, Lato, the hyphenation patterns, and where the corresponding source is. licenses/ gains LGPL-2.1, GPL-3.0 and the GCC exception from the pinned tarballs and Debian's copyright files from the sysroot; every package ships all of licenses/ and CREDITS.md, checked in the payload preflight. - NOTICE names the modified engine's source (the fork, branch, pinned commit, base release, the patches), as MPL-2.0 3.2 asks. - README and LICENSE no longer call the packages Apache-2.0 and MPL-2.0 only; the dead licensing.shtml reference is replaced by the UXP LICENSE and TRADEMARK files and Moonchild's legal and redist pages. - Apache-2.0 4(b) change notices on the 29 HP-derived files changed since import. - A drawn magnifier is the DuckDuckGo engines' icon; Google's logo is Google's only; the unused Bing logo is gone. - The engine's services-sync.js defaults pointed at Moonchild's Sync, key server and add-on host: blanked at bundle time, checked. - The "Blazer" keyword, the Goanna-mark tagline, a stray screenshot and a .bak dropped; the HP SDK's terms stated where it is downloaded; CREDITS records the logo's origin and the screenshot strip's licence. Deferred to the next engine build: about:credits' URL and --disable-ffmpeg (the system-libavcodec path is dead on the device). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XM9EDSp83ZFRhggY4RCT9X |
||
|
|
cfbfbcf293 |
T-469: review round 24 (the inspector, for Codex): webOS's store gives roots only, the CA question only for a page
Codex's owed review of Tier 78, round 22 and Tier 83, run by the Cavekit inspector (the owner).
Tier 83 (REQUEST CHANGES):
- P1: Trust Always puts a site's own certificate in Certificate Manager's store, and a router's or
NAS box's (openssl req -x509) also says cA=TRUE, so R4 would have made it a root for every site
at the next start. R4 now takes only roots: self-issued, keyUsage allowing keyCertSign, no
subjectAltName or extendedKeyUsage. The daemon tells the component (jihad-platform-cert) about
every certificate its SSL dialog installs, and R4 never takes one (its SHA-256 kept in
jihad.security.webos_certs.accepted). An intermediate is no longer taken either.
- P2: a hidden blob: frame reached the engine's CA import and raised the question over the page.
The question now needs a one-use offer made by a CA certificate opened as the page itself (HTTP
in _caLoad, data:/file: in the content policy), or it refuses without a word.
- P3: only frames (subdocument, object) are cancelled, not a script's fetch; the question also
refuses a site's certificate that says cA=TRUE; the proxy-login marker is "[proxy] ", which no
site's host can produce; webOS's proxy setting keeps its last plan (jihad.proxy.webos.last) when a
read fails instead of going direct; card-selftest marks hook lines at or after the screenshot's
second, across midnight. Matching removed roots by Subject+SPKI was tried and dropped: Mozilla
removed old issues of roots it still trusts with the same name and key (GTS R1-R4, GlobalSign,
Firmaprofesional).
Round 22 (APPROVE): card-picture updates have their own observer topic (a Persona id of "thumbs"
was ambiguous); the cost of making them on the engine's thread is written down.
Tier 78 (APPROVE): the gallery offers the bundled set too, so one removed there stays removed;
link-style buttons and the toast's Undo are 44 px tall; the Personas test server reads Carbon
Light's picture from its package.
Device (CE 3.1.0, all three on daemon 06e75a68): R4 trusted the same 5 roots; a router certificate
with an IP SAN skipped as siteLike, one without keyUsage as noCertSign, a CA with keyCertSign
trusted, then removed; Trust Once logged the site certificate as never to be taken and the session
serial was swept; a blob: CA frame refused with no dialog; the test CA link still asked ("Offered by
192.168.1.245:8896"); a router certificate link refused; proxy logins read "The proxy ..." (Enyo,
Mochi) and "[proxy] ..." (Mojo's sheet).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed
|
||
|
|
e223591f81 |
T-457, T-458, T-459, T-464: proxies and webOS's certificates
The settings page gets a Proxy section (Advanced) and a Certificates section (Security), cavekit-proxies-certs.md: - Proxy: No proxy (now the default), webOS's own proxy setting, the Riverstone Relay, WebOne, my own proxy (HTTP/HTTPS/SOCKS, direct list) and a PAC URL, read from and written to the engine's network.proxy.* prefs. The engine's "system proxy" (type 5) reads GNOME's settings and does nothing in the headless build; it is gone from the page. - webOS's proxy setting: the daemon reads com.palm.connectionmanager/getNwProxiesConfig on its own Luna connection at start, at every card connect and on request, and components/jihadProxy.js applies it when the user chose to follow it. - components/jihadCerts.js: at the first page (the daemon announces "jihad-nss-ready"), the CA certificates in webOS's stores that are not HP's 3.0.5 roots, not removed by Mozilla, not Jihad's own and not expired are trusted in memory (NSS temporary certificates). The lists come from HP's doctor image and CCADB (render/goanna/certs/make-cert-lists.py). Switching the setting off takes the trust away at once and clears TLS sessions and idle connections that were checked under it. - The Relay's CA is carried and pinned; trusted only when the user turns it on while the Relay is in use, never through a store or a link. - Opening a CA certificate asks on the card (a JS nsICertificateDialogs), including one sent as a download (WebOne's); the added CAs are listed in Settings with Remove. - A proxy's 407 names the proxy; Enyo and Mochi say "The proxy ... requires a username and password". Found on the way: JS components are read as Latin-1, so non-ASCII in their strings came out garbled (the print status's ellipsis, the persona importer's BOM strip); escaped. The install scripts leave a byte-identical adapter alone: replacing one LunaSysMgr has mapped left a deleted file on / that kept it read-write. Device (Enyo, CE 3.1.0): the five newer roots trusted and nothing written to cert9.db; a SwissSign 2022-1 site loads with the setting on and fails off; a Certificate Manager CA trusted after a start and gone after removal; the Relay re-signs with its CA off and loads with it on; manual, PAC, webOS's setting and a login proxy through a PC test proxy; WebOne 0.18.3's CA from its link, then https through it; the Relay's CA refused from a link. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed |
||
|
|
23ffd9af83 |
Engine: UXP RB_20261006; updates in two commands; a release build in Thumb-2
The owner, 2026-10-12: "Proceed with the UXP update, with a focus on making future updates easier, and optimizing the code where possible, while supporting modern web standards. target the latest release". The engine (third_party/uxp) moves from master b2594a4 (2026-06-30) to the release RB_20261006 (5f290d1, about 170 upstream changes: NSS 3.90.14 and security fixes, constructable style sheets, URL.parse(), revert-layer, aspect-ratio for grid items, :has(), typing speed, leak fixes), branch jihad/uxp-RB_20261006 at 706d4782ba. Our 39 commits came across with git's three-way merge and no conflict, now one commit per patch (the squash of 0001-0031 split); the six files both sides changed were read: only --disable-npapi-gtk2 had to go (upstream now offers GTK2 NPAPI to GTK toolkits only). check-engine-api.py: 0 FAIL, baseline re-written, no signature changed. Future updates: - build/engine/update-engine.sh [TAG] puts the queue (build/desktop/patches, now git mails) on a release with git am -3 in a worktree, lists the files both sides changed and runs the API check; --finish writes the queue again, checks the branch out and rewrites every pin (engine-version.env with the new UXP_TAG, the OE recipe, the user agent, the three start pages); --abort, --pins. - make-device-bundle.sh reads the ICU data file's name from engine-version.env. - render/goanna/EngineCalls.h: the 15 positional engine calls behind named wrappers. - docs/ENGINE.md §6 is the procedure in those terms, with the full variant push an engine update needs (push-engine-update.sh does not carry the engine's own JS, CSS and chrome). Optimised: mozconfig.goanna-arm is a release build (--enable-release --enable-gold: dead-code removal and identical-code folding, both off in developer mode) in Thumb-2 (--with-thumb=yes). Stripped libxul 46.2 -> 30.2 MB (-35%), its code -43%; an idle daemon 33.8 MB resident against 36 MB before. Modern web: a Settings switch for CSS :has(), off by default as upstream releases ship it (slow on some pages). render/goanna/test/modern-web.html reports the features. Fixed on the way: postinst/prerm took the initramfs rootfs line for a read-write /, so a read-only root was never remounted and the install failed; they read the real root mount now. The daemon includes nsIDocument.h before nsIPresShell.h, which the new StyleSheet.h needs. JIHAD_APP_BUILD_ID bumped. The UA and start pages say Goanna/6.9 UXP/5f290d1. Device, all three (a full push-variant.sh each): 11 of 11 optional exports; Enyo: the feature page before (no adoptedStyleSheets, replaceSync, URL.parse, revert-layer, :has) and after (all, :has with its switch on), TLS 1.3 on howsmyssl.com, a Persona worn and taken off, Palefill enabled, about:config, Flash at 23-25 fps; Mochi: the feature page; Mojo: Wikipedia. Nothing pushed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed |
||
|
|
272ce0cdb4 |
Tier 79: the keyboard on Jihad's pages, card pictures, add-on preferences that fit; round 20
The owner's evening list: - Opening about:settings, about:preferences, about:personas or about:addons takes the focus off the address field in all three shells, so the keyboard goes down and the whole page shows (device, all three: Jihad page -> BODY, example.org -> INPUT kept). - The daemon clears the page's focus when the window grows back by a keyboard's height at the same width with a field focused, so no caret is left behind (built; needs a finger). - Installed Personas' cards draw an 800 px copy of their picture, made once beside it and pruned, instead of the full header that the image cache kept dropping (device, Enyo). - An add-on's preferences stack as blocks, dark text fields, trimmed desktop margins: nothing is cut off or needs a sideways scroll (device, Mochi, Palefill). - Mochi defines Mojo.handleGesture, LunaSysMgr's way of giving a card its flicks, which Enyo 2 lacks: a flick on the web view reaches the adapter, in whole numbers. Inspector round 20 (Codex out of credits): about:addons measures only the shown view's items and can shrink again; a page's own scroll jump inside the streaming window is judged once the stream pauses instead of being lost; CREDITS keeps the three CC pictures in the README strip; AMO card state, https-only redirects, a full /tmp answered; licences for the formerly bundled Personas; the two sheets loaded apart and checked in the bundle; dead code removed; kits corrected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed |
||
|
|
df590b3be4 |
Codex round 17: the site-test restore checks copies by md5; Persona update and colour fixes
build/webos-oe/test-site-profile.sh: - Every copy (backup and restore, files and both folders) is judged by md5, not by cp's exit status: the device's BusyBox cp can report EBADF for a copy that landed. - The backup records each folder's entry count (hidden and nested entries too) and every file's md5; restore refuses a backup that does not match, before touching anything. - extensions.ini and addons.json are backed up too (an add-on install rewrites them). - A restore that did not finish leaves the daemon stopped and the backup kept, and still reports whether the test CA is in the profile; an unreadable certificate database is never taken for "CA gone". - Setup checks cert9.db and user.js arrived whole and that the daemon came back up; a setup stopped part-way says to run restore. Each device script has its own name and removes itself. about:personas: only a higher version is offered as an update, and an answer about another Persona or without a version counts as not checked. jihadPersonas.js: a colour-only Persona's drawn picture keeps translucent colours translucent (an opaque pair is written byte for byte as before, so its id is unchanged); a multi-picture static theme that fails part-way removes the pictures it had put in place. Enyo: the ink reload/stop glyphs for a light address field no longer depend on the lazy browser view existing. Mojo: highlighted menu labels take the theme's highlight text colour. cavekit-personas-ui.md R3: an update or re-install of the worn Persona replaces it without Undo, by design. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed |
||
|
|
948e1c88be |
T-390..T-394, T-400..T-413: inspector round 14 fixed; kits and build site brought up to date
The inspector's review of 69c44675..efa6844a (Codex out of credits until 4:59 PM): - A colour-only Persona's gradient is stretched over the bar (fit "stretch"), not drawn cover, which showed one blended row. The component, the three shells and the Personas pane. - The pane draws a layered Persona's first picture at its own size, not cover. - Re-installing the Persona being worn under the same id repaints the cards (wearTheme through rewear; LWTM sends nothing when currentTheme is set to the same id). - Colour slots are parsed (inIDOMUtils.colorToRGBA) and sent as rgb()/rgba(); anything else is dropped, so a value cannot carry more CSS into the shells' stylesheets. - The per-Persona pixel budget is checked from each picture's header before it is copied or shrunk. - about:personas ignores replies to requests it has since replaced, and takes the page number from the reply. - test-site-profile.sh: the backup is removed only after the copies and the CA check pass; files absent at setup, an existing user.js, what the test added, a missing certutil and an empty address are all handled. - lightweightThemes.update.enabled is named false beside extensions.update.enabled (check-engine-api.py knows both it and xpinstall.whitelist.add are read by the engine). Found on the device: the restore's clean-up used grep -x, which the TouchPad's BusyBox 1.17 grep lacks, so every file looked unlisted and Enyo's profile jihad-themes/ and extensions/ were emptied by both of the day's restores. Membership is now decided in plain sh and must find the list's own first line before anything is removed (run on the device against a scratch directory). Enyo was repaired by hand: its 13 pictures copied from Mochi under the same names (md5-identical to Mojo's) and Palefill re-offered (1.30, active). Checked on the device (Enyo, Mochi, Mojo): the stretched gradient (Enyo measured #3e2164 top, #7c3aa8 bottom for #3b1d5e/#7a3fa8), the pane's layered row, a same-id re-install repainting (#cc2222), hsl() arriving as rgb() and a shadow value dropped, the setup/restore cycle, and against the local site: the front page, an add-on page, a 404, about:personas' pager (page 1 of 2 → 2 of 2) and "More on the web". Kits: cavekit-persona-formats.md and cavekit-addons-site.md ticked with what was measured; R1/R2's about:personas card, R4's index fields and R11's getMoreURL narrowed. Open: the site's layouts on other screens, a typed search (a finger), the deploy (the owner's). Review round 14 recorded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed |
||
|
|
efa6844a64 |
T-392: a Persona's other colours reach the address field, the menus, the second bar and the start page
cavekit-persona-formats.md R3, in all three shells, each as one generated stylesheet (menus are rebuilt each time they open, the fields swap nodes or come twice): toolbar_field / _text / _border and the _focus pair on the address field; popup, popup_text, popup_border and popup_highlight on the shell's own menus and sheets; ntp_background and ntp_text on the start page; icons choosing the light or dark glyph set; Mojo's command row filled with the toolbar colour. A classic Persona or none empties the sheet and every part looks as before. - Enyo: the app and popup menus keep the framework's border widths (their content is laid out inside them with negative margins — a 1 px border pulled the app menu off the left edge), filled with the theme's colour, the theme's border as an outline; the field's reload and stop glyphs switch to the ink set on a light field. - Mochi: the field's ink glyphs sit on a light disc when the field is dark; a hook step shows the start page overlay. - Mojo: the start page is a document in the WebView, so its two colours travel in its url like its shortcuts, and start.html now applies both again on hashchange — re-opening it with a new fragment is a same-document navigation that never re-ran its script (its shortcuts had the same problem). Device (all three, 2026-10-11): the colour-only test Persona paints the bar, the field (cream, gold border, purple text; white and black while focused), the menus (purple, gold, light text) and the start page (Enyo and Mojo on screen; Mochi's computed colour, its overlay not showing over a loaded page); the four-layer test Persona draws its moon, sun, hills and dots in Mochi and Mojo as in Enyo; wearing Space Fantasy / Aurora Silk / Lime Fizz afterwards puts every part back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed |
||
|
|
9e10469957 |
T-390/T-391: colour-only themes and layered pictures become Personas
A theme package's extras are kept beside its Persona (extras-<hash of id>.json in jihad-themes, checked when read, deleted with the Persona), because the engine's theme manager keeps only its own fields and insists on a header picture: - colour-only packages (no usable picture, a frame colour) get a small picture drawn from the frame and toolbar colours (a hand-written PNG, stored deflate) and are fitted to the bar; - every picture of theme_frame and additional_backgrounds (up to 6) is kept, bounded (4 MB, 4096^2 pixels each, 6 Mpx per Persona), with its alignment and tiling; SVG is left out; - the colour slots of cavekit-persona-formats.md R3 are read and sent to the cards (painting them is next); a site or index Persona may carry them too; - the cards and the Personas pane draw the layers as CSS multiple backgrounds; a one-picture Persona keeps its old id. Device (Enyo): the colour-only test package paints a purple gradient bar; the four-layer test package shows its moon, sun, tiled dots and repeat-x hills where the theme puts them. The shells read the layer list with a cross-window array check (instanceof failed: the theme is parsed in another window). render/goanna/test/personas/make-format-tests.py draws the test packages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed |
||
|
|
faa34d132a |
Personas pane in about:addons: art, Wear with Undo, author and version, install from file, a Frutiger Aero set; wallpaper pictures fitted
cavekit-personas-ui.md, with the owner's same-day direction folded in ("try and wear seem
duplicative", "author and version fields should be shown for all personas", "default version
1.0", "call themes Personas consistently", "add fruiter aero style themes", "blue nebula looks
like it isnt working properly", "dark fox preview in about:addons not working", "the aero themes
dont display consistently ... like the others").
- components/jihadPersonas.js decorates the engine's own about:addons (no engine change): the
category is "Personas"; each row shows its picture over its accent colour with the name in
its text colour on a readable pane, its version (1.0 when it names none), its author, the one
in use marked and first; Wear / Take off / Remove at 44 px; a "Default look" entry; an Undo bar
for 30 s after any change; Get Personas (AMO) and Install from file (the .xpi files in
/media/internal/downloads or /media/internal). Rows added while the pane is open are picked up
when their binding attaches. Refreshes run on the component's own timers (the page's
setTimeout, called from the component, never fired).
- Removing a converted Persona deletes its picture from the profile.
- The resource://jihad-themes mapping is made whenever a theme URL is resolved: the constructor
runs before the profile is known, so after a daemon restart every converted Persona's picture
failed to resolve.
- Wallpaper-sized pictures (AMO's 3840x2160) are kept 1600 px wide at install (decoded straight
at that size; full size they exceed the 32 MB image cache and never drew in the engine), and
the cards fit them to the bar (headerFit) instead of showing their dark corner.
- render/goanna/personas/: five original Frutiger Aero Personas drawn by make-aero-personas.py,
bundled and added to each profile's Persona list once (not worn).
- Settings -> Appearance is a summary with Manage Personas (opens the pane); "Persona" in the
confirm, the toasts and Settings.
Device (Enyo, 2026-10-08): wear from the pane, Undo back, Remove (picture deleted), install a
downloaded AMO Persona from file (confirm, applied), Blue Nebula re-installed as 1600x900 and
drawn fitted, the Aero set listed and worn.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed
|
||
|
|
cefb03a88e |
Owner's finger test: Mojo width loop, inspector P1 (unbounded URLs / NULL strings), menus and theme polish, About page, README, Flash games
From the owner's 2026-10-07 finger-test report: - Mojo: pages no longer shrink to a stripe. The daemon re-sent the meta viewport whenever its computed initial scale changed; the Mojo WebView sizes its node from that scale, so each re-send narrowed the page (768 -> 526 -> ... -> 76 px). Re-sent only when the page's declaration changes, as the stock server does. - Mojo: the command-row circles take the theme's accent colour (bookmark glyph included). - Mochi: rounded dropdowns; the app menu sits flush with the left edge. - Enyo: refresh glyph centred in the address field; a typed file:/// address opens instead of searching. - Home button default is DuckDuckGo Lite in all three shells and the settings page; a stored old default moves once. - Settings gains an About pane (interface, version, engine, Flash, licences), read at run time. - README rewritten around what only Jihad does on webOS, with device screenshots. - Flash test page (render/goanna/test/flash-test-page/) with five real archive.org games. Inspector round 8b on the previous fixes (Codex out of credits mid-review): - P1: every URL the daemon sends is bounded, and the shared YAP codec never drops a field (an oversized string is sent empty) or yields NULL (an unreadable one reads as "") - a page could otherwise crash the card host through strlen(NULL). - History traversals keep their old re-drive; Open In New Card takes web addresses only; the preview mark matches the engine's 30 s; the hold generation is per request and counts pass-through gestures. Still open (docs/PICKUP.md): Mojo pinch in-then-out goes grey (structural), Mochi text soft at ~1.43 zoom, long-press by finger not reproduced by script. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed |
||
|
|
86f0eee1d5 |
Codex r7 + inspector r8 fixes; menus match on all three shells; Flash pacing for games; Mojo pinch; DuckDuckGo Lite default
Review fixes (device-verified where noted):
- Re-driven navigations carry the engine's own referrer and policy (content navigations) or the
link's rules (taps: rel=noreferrer, referrerpolicy, <meta name=referrer>), and ALWAYS the
initiating document's principal - a withheld referrer no longer makes the load a system one
(file: and top-level data: are refused again). Six referrer cases and both escapes checked.
- Page titles and URLs bounded on the wire (1024 / 8192 bytes) and title changes coalesced to
one per 500 ms (a 50 Hz flood: 12 sends in ~6 s).
- Personas: theme origin and base taken at the event; previews only from https sites with the
install permission, reset when the page is left; only the installed theme is remembered;
card JSON sanitised and bounded; requests from a document with no site ignored. Static-theme
XPIs: manifest <= 64 KB, image <= 4 MB copied through the bounded reader stream (a size-lying
entry stops at its declared size), pending file kept only on yes, hash-named.
- Enyo: the theme lives in ActionBar and reaches the lazily created start page and browser views.
- Settings page migrates only its own stored search engine; confirm text overload-proof.
Menus (owner: the upper-right menu the same on all three, Atlas as reference):
- Mochi: Share / New Card / Bookmarks menus and the app menu Find on Page / Settings / Print,
opened from the card's title bar through Mojo.relaunch (palm-command open-app-menu).
- Mojo: no icons beside the URL (owner); Share and Bookmarks are command-menu submenus on the
bottom circles; reload/stop inside the address field (owner); app menu Find / Settings /
Print; new Bookmarks, Downloads and Print scenes and models.
Flash (owner: optimize for gaming):
- Partial paints were never taken since
|
||
|
|
20310b3e09 |
Personas on all three shells with Firefox's light/dark icon sets; AMO static themes; DuckDuckGo Lite the default search
Personas (lightweight themes) are now verified on the device in all three shells with Water-Like by stick177, the owner's test persona: installed from a theme site (confirm in the card's own dialog), painted on the top chrome at once and at every start, removed live from Settings > Appearance. The toolbar glyphs follow the theme the way Firefox 52, Pale Moon and Basilisk do: an ink icon set when the theme's text colour is dark (generated by luminance inversion from the isis-browser art and our own icons; Mochi's as data URIs). A -webkit-mask approach was tried first and renders inverted on this WebKit. Enyo's Onyx toolbar border-image is turned off under a theme (it painted over the header). The notification door lets a theme's JSON through whole. AMO serves every former persona as a WebExtension static theme, which this engine refuses (ERROR_WEBEXT_FILE). A theme-only package is now read by components/jihadPersonas.js, its image unpacked into the profile and applied as a lightweight theme with the user's yes; the cards get the image as a file URL. Verified with AMO's water_like-2.0.xpi. DuckDuckGo Lite and DuckDuckGo HTML join the search engines in every shell and on the settings page; Lite is the default, and a stored "duckduckgo" from before (the old default) moves to Lite once, recorded so a later deliberate choice of the full site stays. Test hooks: Enyo answers a confirm through the popup's own Accept; Mojo gains a click step and an address-field blur; the toolbar probe counts ink glyphs; the persona test site lays its buttons out as large fixed blocks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed |
||
|
|
5ccc50f424 |
Personas (lightweight themes) — in progress: engine events, component, Luna getTheme, Mochi verified; Enyo/Mojo/buttons/static-theme XPI untested
Firefox 52, Pale Moon and Basilisk personas are one format: the lightweight theme JSON a theme site dispatches with InstallBrowserTheme / Preview / Reset. The engine already has LightweightThemeManager; this adds the browser's half: GoannaRenderPage catches the events on the content document, the pump hands them to components/jihadPersonas.js, which asks the user through the existing confirm door, applies through the manager, records the theme in a pref and pushes it on the notification channel; the daemon answers getTheme over Luna for a card that starts later. The notification door lets theme JSON through whole (it cut everything at 200 characters). The three shells paint the header image and colours on their top chrome and tint their button glyphs with textcolor; the settings page gains an Appearance section; a theme-only WebExtension static theme (what AMO serves every former persona as) is converted to a lightweight theme when its install fails as corrupt. Device-verified on Mochi only: install from a theme site, confirm, toolbar painted live and at start. Untested: Enyo and Mojo, the button tint on any shell, the static-theme conversion, the Appearance section. Test assets under render/goanna/test/personas (Water-Like by stick177, the owner's test persona). Tabs kit: the strip takes the theme too. PICKUP has the exact state and the next steps; stopped at the usage limit. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed |
||
|
|
2b1e749133 |
Go-ahead session: reinstall audit for Enyo and Mojo, reboot test, a real print, Codex round 6 fixes, tabbed-browsing groundwork
With the owner's go-ahead for everything that needs no hands on the device: Enyo and Mojo were removed through the supported installer and installed from nothing, with the citizen-audit snapshots around each step: prerm left no app dir, job, shim, impl, role/service file, state dir or socket; the hub forgot the name; the other daemons kept their PIDs; the fresh postinst registered the role live, the db8 kinds (Enyo), and started the daemon from the app's own deviceroot with the Luna service up on first start. Palefill landed in each fresh profile. Enyo's history was exported from db8 and put back; Mojo's localStorage history restored from a backup. The device was then rebooted: all three daemons up from the shipped upstart jobs, registered on first start, cards rendering, root read-only. One page was printed from the Mochi dialog, to the IPP sink first and then to the Epson over IPPS (job accepted). Codex reviewed the range only the inspector had seen. Fixed: the padlock followed the requested address, so a typed https url showed the previous page's padlock (and its certificate) under the new address — Enyo and Mochi now show it only for the address the engine has committed; Cut compared text alone, so the same text in another field could be deleted — the copy now remembers its field (weakly) and its time, and a cut needs the same field within 15 s; copied text is let go after 15 s instead of living with the page; the host test sinks return the count OnNotification now asks for; push-engine-update.sh refuses a full push from a stale bundle before touching the device. Tabbed browsing: groundwork only, by the owner's word. A kit (cavekit-tabbed-browsing.md), a design note (docs/TABS-GROUNDWORK.md: pages held in the daemon, one connection per card, tab commands over the variant's own Luna service, the YAP contract untouched; one adapter per tab rejected on 37.7 MB of shared memory per connection) and Tier 71 of the build site, every task pending. The OE recipe's SRCREV moves to db070f0003, the engine commit the gitlink already carries. Kits, build site, review record, loop log, evidence and PICKUP updated. Pushes are the owner's. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed |
||
|
|
31c5f445e9 |
Review round 4: Palefill installer (Codex) and the last fix round (inspector)
Codex, on the Palefill installer: an add-on the manager would disable at once is not installed (and not recorded as offered); the bundle requires the installer component as it requires the file; a copy counts as handed over only when the notification reached a subscriber (OnNotification returns the count); the add-on manager's provider module is pushed only with the libxul it was staged with, and its companion goes with it. Palefill's own whole-response buffering is left as its design and documented. The inspector, on the last fix round: the "pressed field must be the focused one" rule passed for <body>, which contains everything - the focused element must now be a text control or inside an editing host; Cut said "Cut." over a target it could not edit - it refuses unless an editing host and reports only what it removed; read-only fields had lost Copy (a control's own selection is invisible to the window's) - they stay on the field path, readOnly rides the hold answer and the menus drop Paste and Cut; script and style text is skipped by the bounded copy walk; an unreadable protocol version is no longer reported as SSL 3; the push script no longer dies on a bundle without bundled-addons/. On the device (Enyo, scripted): a hold on a read-only field offers Select All, then Copy, no Paste, no Cut, and the copy lands; a word copy and a hold on a normal field are as before. Daemon b7be3e3c on all three variants. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed |
||
|
|
debd19341d |
Pages stay painted: frames are composed; padlock shows the certificate; review fixes
Three pieces of work that share files, plus what two adversarial reviews found in them (Codex until its credits ran out, then the Cavekit inspector). THE PAGE STAYS PAINTED (owner: "pages only load when observed ... the entire page should stay rendered at once unless it's very long, so that navigation and zooming is smooth") - The painted region uses the whole shared segment: 4096 rows in portrait, up from a 2048 cap that stood on a worry about a GPU texture limit. Measured: a 4096-row region wraps and blits. JIHAD_REGION_ROWS_CAP is the way back. - Rendering that region whole for every frame does not survive its size: 4096 rows of a real page measured 300-1400 ms, with the daemon deaf to input meanwhile. Frames are now COMPOSED: rows the newest frame already holds are copied from its buffer, rows it lacks are rendered (at most 768 a frame, so a region grows over a few frames), the visible band is drawn as before, and at z~1 the band of the frame copied from is redrawn from the document where it is no longer this frame's band (fixed headers, the caret). Same page: 110-180 ms a frame. - What a copy cannot know is whether the page changed off screen, so after a frame that reacted to a change the off-screen rows are swept, a few hundred at a time, by maintenance frames once the page is loaded and still, with a pause between sweeps. Rows that are owed a sweep do not count as covering a pan. A large change at the same scroll repaints the band only. - Zoomed in, the region is as wide as the content, up to two viewports, so a sideways pan has something to show. The adapter's rotation guard now compares bufferWidth (the viewport) rather than renderedWidth (the region); the header layout is unchanged. - The coverage margin scales with the region, so a short or wide region is not judged uncovered at the position it was just painted for. - <state>/dump-request writes one frame to /tmp for inspection (refused when /tmp is short of room: forgotten dumps once filled that 40 MB RAM disk). CORRECTION to |
||
|
|
657282c431 |
Long-press on a page raises a menu, as a right-click does on a desktop
Owner: "long pressing on the page doesn't do anything but it should, like on a
desktop browser". It did something only on links and images; everywhere else
the hold reached the engine as a contextmenu event and that was the end of it.
Now, in all three shells:
on text the word under the finger is selected and the menu offers Copy,
Select All, Back/Forward (when there is somewhere to go),
Reload, Add Bookmark, Find on Page
on a field the field takes the focus with the caret where the press was,
and the menu offers Paste, Select All, and Copy/Cut when
something in it is selected
on nothing the same page menu, without Copy
A press inside what is already selected keeps the selection (so Select All,
then a press, then Copy copies the page), as a right-click does.
How it is put together, within the frozen contract:
- The card does not claim a hold that is not on a link or an image. The
adapter then sends holdAt as it always did; the daemon dispatches the page's
contextmenu event, focuses a field that was not focused, and hands the press
to a new bundled component, components/jihadPageCommands.js, which does the
selecting and answers on the notification channel: page-hold
{editable, selected}. The card that was waiting opens its menu on that.
- Select All, Copy and Cut are the adapter's own selectAll / copy / cut, which
were stubs in the daemon; they now reach the component. Commands act on what
the last press was on: the page's text even while a field has the focus.
- The clipboard belongs to LunaSysMgr and only a card can write or read it.
Copied text therefore goes to the card as a one-call script in the app's own
clip/ directory (the one place a card may load a local file from), announced
as page-copied with the file's name; the file lives fifteen seconds. The
hit-test schema forbids extra keys and the notification channel is public
and cut at 200 characters, so neither could carry it.
- Paste is the card reading the clipboard and sending the text with
insertStringAtCursor. The system's paste is asynchronous and was measured
taking more than 60 ms, so the read watches for up to 600 ms.
- The engine's selectAtPoint adds a range (every word ever pressed stayed
highlighted), takes two words when the press is on a word's last half-letter,
and selects the nearest word for a press on empty space. All three are
corrected in the component.
Mojo's web view claims no hold at all, so there every hold goes this way and
the card the user is in opens the menu.
prerm also removes the clip/ directory. card-selftest.sh reads the gzipped log
generations; the hooks gain h (hold), m (list/pick the menu), c/k (read/set the
clipboard) and p.
On the device (Enyo and Mochi, scripted holds through the adapter's
mouseHoldAt - not a finger): a hold on a word selects that one word and Copy
puts it on the clipboard; a hold on empty space offers no Copy; a hold on a
field, Paste, lands the clipboard at the pressed position; Select All then Cut
empties the field, fires its input event and leaves the text on the clipboard;
Select All on the page with a field focused selects the page, and Copy copies
it. Mojo's menu has not run: it has no test hook and needs a finger.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed
|
||
|
|
b38a87fcd9 |
one Settings: the cards' own "Browser Settings" panels are merged into the settings page
Owner: "merge browser settings into settings", "remove Help", "print is
greyed out".
The settings page (about:settings / about:preferences) was already the one
surface the three shells share, but the Enyo and Mochi cards each kept a second
panel for what the page could not do. It can now:
- Search engine: a row in the Browser pane. Stored with the home target and
the start-page links in jihad.chrome.settings and adopted by the cards from
the url fragment, like those. Fixed list (DuckDuckGo, Google, Wikipedia),
the same three ids in each shell.
- Clear Data: Bookmarks, History, Cookies, Cache, each asking on the page
before it runs (the row turns into the question, with Clear and Cancel).
Cookies and cache are the engine's and are cleared there. Bookmarks and
history are lists the card keeps, so the page asks the cards over the
notification channel ("chrome-clear-..." categories; a card carries the
request out and shows the sentence as its toast). History also clears the
engine's Places record.
- Flash was already the "Adobe Flash" row in Content.
Shells: one "Settings" menu entry each. Enyo loses its Preferences view and
Mochi its JihadPreferences panel. Enyo no longer uses com.palm.universalsearch:
upstream wrote the SYSTEM-WIDE default search engine whenever the browser's
choice changed and wiped the system's optional engine list when browser history
was cleared. Mojo's address bar now follows the chosen engine too, and its
history list answers the page's clear request.
Enyo app menu: Help is gone (it launched the system help app at an HP address
that no longer exists). Print is never greyed out: upstream disabled it while a
page was still loading - measured, a page sitting at 99% left it dead for
seconds - and off a page; now it prints what is on screen, and on the start
page says there is nothing to print.
Mochi: a card opened ON a page no longer focuses the address bar, which put the
keyboard over the lower half of that page.
Verified on the device with real clicks sent through the adapter (clickAt, what
a tap becomes; card-selftest.sh <shell> run settings:<steps>): Enyo - engine
changed to Google and back, the card's default search followed; a test bookmark
cleared, toast shown. Mochi - the same, plus history 4 -> 0, cookies and cache
cleared (daemon: notify privacy ...). Mojo's change is not yet run on the device.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed
|
||
|
|
de0bc0f183 |
Enyo shell: Print opens the browser's own printer dialog
The app menu's Print used the system PrintDialog and the frozen printFrame command. The system dialog lists HP printers only, and printFrame is a no-op in this daemon, so Print could not print on anything. JihadPrintDialog asks the daemon to look for printers, lists each one as it answers (name, then model and address), takes a typed address for a printer discovery cannot see, and shows the job's progress and result. The daemon's "print-..." notifications go to the dialog while it is open and to a toast otherwise. $enyo-lib/printdialog is no longer loaded. On the device, driven through the shell's own handlers by the test hook (card-selftest.sh enyo run print[:address]): the dialog listed the Epson ET-2800 at 192.168.1.253 and a Mac-shared ET-2720; with the test sink's address typed in, it was found, picked and sent one sheet, the dialog ended on "Sent 1 page to ...", and the sink's copy of the sheet is the page. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed |
||
|
|
640ab93fc4 |
Enyo toolbar: the Bookmarks/History icon's circle is whole
The previous version copied its neighbours' habit of cutting the outline away around the accent. On a circle that reads as a broken circle - the ring resumed under the ribbon's notch, so the notch and the cut added up to a hole (the owner: "the circle is incomplete, gap just below the bookmark glyph"). The ring is now left whole and the ribbon laid over its right edge, placed so the ring runs into the ribbon's left tail rather than under its notch. Checked in a device screenshot: same rows as Share and New Card (42..61). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed |
||
|
|
ac972e214f |
Enyo toolbar: the Bookmarks/History icon built the way Share and New Card are
The owner asked for it to be more in line with the two icons it stands beside. Those two share one construction, read off their pixels: a body drawn as a 2 px outline standing on rows 24-25, a solid accent in the upper right (rows 5-15), the outline cut away for 2 px around the accent and resuming at row 18, white at an opacity falling 6.4 a row from 224 to 96 with every upward-facing edge one step brighter, a one-row black shadow, and pressed a solid white core in an rgb(83,183,255) glow that leaves the middle of the body dark. The clock's ring is now that outlined body, its hands are 2 px, and the ribbon is the accent where the plus and the arrow are. The previous redraw kept the ribbon at the lower right and used the house's heavy finish, which left it bolder and higher than its neighbours. Measured in a device screenshot: share, new card and this icon occupy the same rows (42..61) and the same width. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
904be8a0bf |
Enyo toolbar: the Bookmarks/History icon at its neighbours' weight and on their line
The design is kept (a clock with a bookmark ribbon over its lower right). Its strokes were 2 px beside 3 px neighbours, it stood two pixels below their line (down to y = 27) and a pixel right of centre, and its shading was its own. Redrawn with the ring and hands at the neighbours' weight, in the box they use (y 5..25, centred), and finished by the same code as the Home icon. make-enyo-home-icon.py becomes make-enyo-toolbar-icons.py and writes both. Measured in a device screenshot: share, new card and this icon all start at the same row and end within a pixel of each other. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
5264c925af |
Enyo toolbar: a Home icon drawn like the icons beside it
The first home icon was a flat grey house filling its 32x32 cell edge to edge, with a flat blue pressed state - larger and flatter than the stock webOS glyphs it sits between. Read off those glyphs: white at an opacity that falls from about 86% to 56% down the glyph, over a soft black shadow; pressed, solid white inside an rgb(92,172,230) glow; about 24 px wide with a margin. packaging/branding/make-enyo-home-icon.py draws the house to those numbers (roof with eaves, chimney, walls, door) and writes the two-state sprite. Checked in the toolbar on the device. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
aab915975b |
Enyo shell: View Certificate works on webOS CE
The certificate view asked com.palm.certificatemanager for the details and enabled its button only when that answered; on webOS CE a card gets 'Service does not exist', so the button was dead. It now loads the details the daemon writes into the app's own directory while the warning is open (the same file the Mochi shell reads) and falls back to the service if that file is absent. A certificate with neither a common name nor an organization no longer throws (the code set a control that does not exist), and a date that does not parse is shown as sent instead of failing in the formatter. Device: button enabled, issued to / issued by / validity / serial shown. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
8b27842ca2 |
Enyo shell: the three content rows leave the card panel; the Flash switch becomes real
Owner decision 2026-10-02 (cavekit-preferences-ui.md R2): Block Popups, Accept Cookies and Enable JavaScript are owned by the settings page. The card panel loses the three rows and gains a More Settings entry that opens the page, and the card no longer re-applies a copy an older version stored in db8 - a stored 'blockPopups: false' with no row left to change it would otherwise be sent at every launch. The Enable Flash switch wrote the system preference 'flashplugins', which nothing in this browser reads. It now reads and sets the daemon's value through the variant's Luna service, and says so when no Flash plugin is installed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
57eb48724c |
Session 2026-08-15: audio backend, chrome-typing fix, cert store, device verification
Engine audio (gre-widgets R1/R7): switch cubeb ALSA -> PULSE backend, which is what webOS's audio policy requires. mozconfig --enable-pulseaudio, pulse-0.9.22 sysroot headers matching the device ABI, and patch 0030 targeting JIHAD_PULSE_SINK. Device-verified AUDIBLE (user-confirmed "I hear the tone"): decode -> cubeb pulse -> DAC -> codec -> speaker/headphone. The prior ALSA backend was silent because it presented as an anonymous ALSA-plugin stream that module-palm-policy muted; the pulse-native stream identifies as the app and is left at full volume. Chrome-page typing (preferences-ui R6): GoannaRenderPage::InsertText recovers a null mFocusedEditable from document.activeElement, which dodges the focus-manager window-scoping that made chrome documents (about:preferences) unable to receive typed text. Device-verified: text now inserts into about:preferences fields. Cert store (browser-services R5): new JihadCertStore dlopens libPmCertificateMgr and integrates accept/trust with the webOS platform cert store; three defects fixed (empty certFile, nsresult-in-Palm-ordinal-space, Trust-Always vs Trust-Once). Device-verified end to end incl. the platform store write. IPC contract (ipc-contract R1): vendored + patched the YAP generator so a regeneration reproduces the shipped wire with zero hand edits. Touch events (input-bridging R3): doTouchEvent enabled behind JIHAD_TOUCH_EVENTS, 28-byte NpPalmTouchEvent header re-staged, double-activation suppressor. Non-blocking toast (gre-widgets R5): daemon PostNotification + Luna subscription + card toasts; device-verified. Mojo settings entry (preferences-ui R4): app-menu Settings item + settingsUrl(), per product-owner direction reversing the earlier no-mojo-settings instruction. All three variants now have a settings entry. Plus: opal machine kernel string corrected (shortloin), prebuilt-input manifests, build-goanna-arm.sh pipefail fix, desktop test harnesses (prefsui, xpi-mismatch), and extensive device verification recorded in context/impl/impl-device-2026-08-15.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
c2106583af |
about:preferences + settings merge, home button, start-page links
Adds an in-browser settings page and moves the two settings the card shells own
(home button target, start-page shortcut list) toward it. Device-verified on a
TouchPad throughout; kit counts re-counted programmatically, not asserted.
about:preferences / about:settings
- nsIAboutModule JS component + a chrome://jihad-prefs/ package. No C++ change
and no daemon rebuild for the page itself: the engine's own about: table stays
the two static credit pages it was written for.
- In-content HTML, not <prefwindow>. That is a chrome-WINDOW binding and this
embedding has no window to open one in -- the same assumption class that broke
about:addons. Basilisk's shape with Pale Moon's panes.
- Installed by BOTH builds; both now fail loudly rather than skipping when inputs
are missing, which is how the two builds drifted in the first place.
Shell changes
- Home button right of forward in all three variants, default
https://start.duckduckgo.com/ (about:home is not a page this engine serves).
- Start-page links customizable. Mojo's start page is a DOCUMENT rendered by the
engine, so its list travels in the url fragment; isStartPage() now compares
without it.
- Mojo command row: scrolls, circular, centred, find is an icon.
- Mojo url bar: TextField is two nodes that swap on blur, so the field chrome
belongs on the container.
Engine / daemon
- jihad::GetChromeSettings + a getChromePrefs Luna method (works, but private-bus
only today -- see the handoff).
- find_test.cpp now ASSERTS hit/miss and gates the exit code on it. It previously
printed the result and asserted nothing, so it could not fail because of find.
Runs green for find on the desktop harness.
Fixes found by adversarial review (see docs/HANDOFF-2026-08-06.md)
- Restored the Enyo preferences panel's reachability and five handlers a bounded
delete had removed, which had taken the search selector, the JS/Flash toggles
and all four clear-data actions out of the product.
- adoptFromUrl is gated on the url PATH, not the scheme: about:blank is
content-loadable, so a scheme check let any visited page rewrite the home button.
Stored urls allowlisted to https?: and our own about: pages.
- Removed three decorative rows (a pref existing is not a pref being honored) and
fixed the localized read of intl.accept_languages.
- Mojo history had never persisted: Mojo.stringifyJSON does not exist in this
framework build.
Known-broken, with the next step for each, in docs/HANDOFF-2026-08-06.md:
page->card settings sync, public-bus Luna, and an unexplained scroll report.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JJ8PNmUneWxA3QM3Z3W1aw
|
||
|
|
0facbb4ffb |
The Luna service works: our daemon now answers clearCache and clearCookies
Registered per variant rather than as com.palm.browserServer, which is the stock daemon we
coexist with. On device the daemon logs `luna: serving palm://net.riverstonerelay.jihadBrowser/
{clearCache,clearCookies}`, luna-send returns returnValue:true, and -- the part that matters,
because a true from the STOCK browser is precisely the false pass this was written around --
our own daemon logs `luna: clearCookies` and `luna: clearCache`. The hub routes to us and our
handlers run, calling the same jihad::ClearCookies/ClearCache the YAP commands already use.
Three things had to be right and each was wrong first, so each is now written down where the
next person will meet it:
A Luna service name may not contain a hyphen. LS2 rejects it at the CALLER with "_UriParse:
Not a valid service name" before any daemon is involved, and LSRegister fails -1027. Our YAP
names all have hyphens, so the Luna name is the camel-cased form -- jihadBrowser,
jihadBrowserMochi, jihadBrowserMojo -- matching the platform's own idiom.
The hub needs prv and pub role files keyed on exeName, and exeName is the BUNDLED LOADER
ld-2.23.so, not jihad-browserserver, because the upstart job execs through it.
LSMethod has three fields on this device. I copied the two-field shape from luna-sysmgr's
sources in this workspace, which are LS1-era, but the TouchPad ships luna-service2. With two
fields the library walks the table at an 8-byte stride where it reads 12: registration
succeeds, the service appears on the bus, and every call answers `Unknown method
"clearCookies" for category "/"`. A registration that succeeds while registering nothing is
the worst shape of wrong.
Not re-verified in this run: that a non-empty store is emptied. The cookie store was empty
before and after, so only the routing was exercised end to end.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
||
|
|
473ea279f1 |
New kit: in-browser preferences, and fix the Mojo launcher title
The Mojo variant showed as "Jihad Browser" in the launcher. The repo had said "Jihad Mojo" since the rename; the DEVICE had a stale appinfo.json, because neither push-engine-update.sh nor push-card-js.sh carries app metadata -- only a full variant push or a real .ipk install does. So the repo was right, the device was wrong, and nothing in the fast loop would ever have corrected it. Pushed the file and restarted LunaSysMgr; all three now read Jihad Enyo, Jihad Mochi and Jihad Mojo. The trap is written into the device build README, since the next rename would hit it the same way. Adds cavekit-preferences-ui.md for about:preferences / about:settings in the Pale Moon and Basilisk idiom, across all three variants. Two facts establish what the work actually is, both by inspection rather than assumption: UXP ships the prefwindow/prefpane/preference XBL machinery in toolkit/content/widgets/preferences.xml but there is NO about:preferences page in the GRE -- it is application-supplied in both forks -- and this port already ships two app-supplied chrome pieces, the branding package and the XPI install prompt, so the mechanism is proven rather than speculative. The requirement worth reading first is R5. Settings are currently three different stories: the Enyo app pushes preferences into the engine through the frozen YAP commands, the Mochi app persists the same toggles to db8 and deliberately never pushes them, and Mojo has no preferences UI at all. A shared engine-side page is the only surface that can be the same in all three, and R5 requires one source of truth per setting rather than two that disagree silently -- which is the failure the Mochi omission already is. R2 forbids decorative controls for the same reason, and R3 requires a change to be proven from the profile rather than from the UI that made it, the pattern that closed about:config. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
0b1dd43422 |
Docs: reconcile kits and READMEs with the current state of the project
The kits and READMEs had drifted from the code in ways that would mislead the next reader — several said the card dev loop was broken, the <select> popup blocked, and only the Enyo variant live on hardware. All three are now false. Kits: - overview: rewritten device-reality block (three variants live; dev loop restored and how; select popup closed on all three; the -webkit- prefix constraint), priorities re-ordered around the now-unblocked queue, and the per-domain requirement counts re-derived from the kit files — the old "12 domains, 62 requirements" summary had drifted from what it summarised. Totals are now counted, not asserted: 13 domains, 77 requirements, 274 acceptance criteria (204 met / 18 partial / 52 open). - ui-shell R5, mochi R6: card-side <select> popup, device-verified. The Enyo one records the standing rule the investigation established — there is no app-side popup code, and re-adding an onOpenSelect handler or patching BasicWebView.showPopupMenu breaks it. - mojo: R1-R3 and most of R4 marked met against device evidence, plus a new R6 for the command-menu actions (new card / history / share, history without db8 kinds). - offscreen R7 (new): "engine popups reach the user" — collects the separate-display-root defect that had only lived in impl notes. Its <select> criterion is met; the <menupopup> overlay-composite criteria are diagnosed and open, and are now the top priority. addons R2 gains a tools-menu criterion pointing at it. - Both UI kits record the platform constraint: the card WebKit ignores unprefixed box-sizing/flexbox. READMEs: root status/known-issues/roadmap rewritten (three variants live, scrolling and long-press and <select> done, <menupopup> named as what remains); build/webos-oe gains a deploy-scripts section explaining why push-card-js.sh distrusts a naive push; the three app READMEs record their own popup story and the prefix constraint; AGENTS.md notes that the adversarial reviewer is Opus, plus the novacom stdin-EOF race and the JS cache. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
ca4dcc52ec |
Start pages: same logo, name, engine line and hint on all three variants
The Mojo start page was a plain text document while Enyo and Mochi showed the bundled logo; it now carries the same logo, title, engine line and colours, laid out to match. All three gained the "Type a web address or a search in the bar above, then press Enter." line, in the same position and wording. The two card-chrome variants build the page from their frameworks; Mojo's stays a packaged document (a Mojo scene has no equivalent overlay, and the file renders through our own engine anyway). Device-verified on all three. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
322f26bda2 |
Select popup anchors under the tapped box (daemon ships the rect)
The stock anchor path is dead in this embedding: enyo.WebView.openSelect positions from _selectRect, which only webviewClick(inSender, inEvent, inInfo) sets — and BasicWebView declares no onClick event, so inInfo can never arrive and every popup opened dead-centre (Opus review #8; user report). The daemon owns the element, so it ships the geometry: BuildSelectPopup appends an ADDITIVE "rect" key (card px) to the popup JSON — the framework's own parse ignores unknown keys, so the isis shape consumers are untouched. Mapping is the exact inverse of docToViewport: at z~1 card px == getBoundingClientRect px; zoomed, engine scroll parks at 0 and the visual-viewport pan carries the offset (card = (client + pan) * z). Card side (JihadEngineOverride): delegating patches on enyo.WebView.showSelect (capture m.rect) and openSelect (top edge at the box bottom, centred on the box, clamped to the screen, flipped above when it would run off the bottom; no rect -> original centre behaviour). Device-verified on fb1: the list opens flush under the <select>. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
e3de7d8afa |
Select popup works: daemon emits the isis JSON shape; card side is the stock framework
Root cause of the empty popup (impl-select-popup-2026-08-03.md): the card never needed ANY app-side popup. enyo.WebView consumes the inner BasicWebView's onOpenSelect itself (showSelect -> createSelectPopup -> PopupList) and replies via selectPopupMenuItem — it never re-publishes the event, so the app's onOpenSelect handler was unreachable dead code. The framework parses items[].text/isEnabled (+ top-level selectedIdx) — the isis BrowserComboBox shape — while our daemon wrote label/enabled/selected, so the framework built a list of undefined captions: the "empty popup". Daemon now emits the isis shape byte-for-byte (text/isEnabled/isSeparator/isLabel + selectedIdx); the app's custom popup and handlers are deleted. Opus adversarial review (FIX-FIRST verdict) hardened the reply path, folded in: - #1 disabled options were selectable: the framework PopupList never reads its disabled flag, so ApplySelectPopup is the only enforcement point — re-read the options, refuse disabled (attr or enclosing disabled <optgroup>, #2), out-of-range (#4, page JS can rewrite options while the popup is up), and no-op picks (#3: re-selecting the current option must not fire change). - #6 a short/empty popup-json write now fails closed (unlink + drop) — the card otherwise throws inside createSelectPopup after showSpinner() and the modal scrim sticks until relaunch. - #7 popup id sequence is process-global (isis idSeq parity) so a daemon page rebuild cannot reuse an id the framework has cached a stale popup under. Device-verified: the popup renders all options with captions (fb1 + daemon log paint after the injected tap). Follow-ups: optgroup header rows (#5, needs a reply-index remap), mochi/mojo card-side handlers (both currently drop showPopupMenu silently). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
512ede2fa0 |
Card dev loop restored: push-card-js.sh proves reloads; start page says Jihad Browser
Two root causes of the frozen card-JS loop, both nailed on device: 1. novacom run DISCARDS output that arrives after host stdin EOF (channel close races the reply). luna-send's bus round-trip lost that race under load, so running/close/launch "returned nothing" — hold stdin open (sleep N |) and the flake vanishes (2/2 vs 0/3, reproducible). 2. The WebAppMgr in-process JS cache really does serve the previous build after a plain close+relaunch (disk md5 new, card booted the old stamp). A LunaSysMgr restart per cycle busts it deterministically (now the default). push-card-js.sh encodes the whole loop: per-push @DEV@ stamp sed'd into the JS, md5 both sides, close by the REAL processid (response field is lowercase "processid", close request wants camelCase "processId"), relaunch, then REQUIRE the stamp in /var/log/messages — the only accepted proof of a reload. Also wakes/holds the device (doze silently no-ops luna-send) and routes every device command through a pushed helper (novacom mangles quoted args). Browser.js: [JIHAD-BOOT] runtime boot marker + [JSEL] select-popup diagnostic. StartPage.js / mochi JihadBrowser.js: brand title under the start-page logo is always "Jihad Browser" (user request; verified on device for Enyo). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
8cc69a5e14 |
Select popups: ClickAt never falls through for a dropdown; card list = plain buttons
Daemon: a dropdown <select> tap now always returns from ClickAt (whether it
queued the card popup or a dedup skipped a duplicate), so it can no longer fall
through to a normal click that focus-rings the <select> ("box around Apple") or
opens the engine's own 0x0 combobox.
Card: switched the option list from PopupSelect.setItems (which rendered empty on
device) to a plain Popup with an explicit Button per option built in
showSelectPopup — predictable rendering. UNVERIFIED on device: the card froze on
an early cached build all session (fresh JS would not load despite reboot /
killall LunaSysMgr / version bump / md5-verified disk) and card enyo.log stopped
reaching palm-log, so the empty popup could not be diagnosed between "still stale
JS" and "Popup content doesn't paint in this embedding". The two broken dev-loop
tools and the restore-the-loop-first plan are in
context/impl/impl-select-popup-2026-08-03.md. The daemon/engine/adapter half is
device-verified and solid.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TzkQtdXpngYfZ2yG1XDfkB
|
||
|
|
ab86fa87e3 |
Select popups: card-native <select> list via the Atlas msgPopupMenuShow contract
isis/Atlas never rendered <select> dropdowns card-side — QtWebKit/WPE paint the combobox into the plugin surface, so neither has an onOpenSelect handler. Goanna can't (the native combobox is a separate 0x0 display root), so this takes Atlas's IPC contract (inherited byte-identical) and renders the list in the card: - Engine: a dropdown-<select> tap reads its options via nsIDOMHTMLSelectElement, serializes them, holds the element, and skips the normal click; a 700 ms/same- element dedup collapses the raw+gesture double tap. - Daemon: writes the option JSON to <state>/popup-<id>.json (R8-safe 0644) and emits msgPopupMenuShow; the choice returns via asyncCmdPopupMenuSelect -> ApplySelectPopup (SetSelectedIndex + input/change; -1 = dismiss). - Card: the framework BasicWebView ALREADY implements showPopupMenu -> onOpenSelect, so we do NOT patch it (an earlier patch shadowed it with a broken this.bubble()). Browser.js maps onOpenSelect to a native PopupSelect list and replies with the chosen index. Desktop-proven end to end (build-popup-probe.sh): a <select> tap emits popupMenuShow with the correct options to the adapter. On device the daemon side is verified and the popup renders over the plugin, but showed empty under stale WebAppMgr JS and the card began crash-looping from the day's LunaSysMgr churn — full state + the reboot-and-retest plan in context/impl/impl-select-popup-2026-08-03.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TzkQtdXpngYfZ2yG1XDfkB |
||
|
|
3590b93b46 |
Apps: rename to Jihad Enyo / Jihad Mochi / Jihad Mojo; start page follows the card
Display names per user direction — launcher titles plus each UI's own branding. The Enyo start page drops its fixed 1024px box for flex centring, so the brand block re-centres under the VKB (verified on fb1: card shrunk to 602, block centred) and in landscape. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TzkQtdXpngYfZ2yG1XDfkB |
||
|
|
5895f45f34 |
Device: root-cause stale app JS and the "card never reaches the adapter" bug
Neither was a defect in this project's code. 1. App JS. WebAppMgr caches an app's sources in-process, so editing the file on disk and relaunching the card keeps running the old script. killall LunaSysMgr (upstart respawns WebAppMgr too) makes new code run on the next launch -- no reboot, no version bump, no reinstall. This looked already ruled out because earlier killall/reboot attempts had "failed". They were run while a palm-install from an earlier turn was STILL RUNNING and a second one had been started against the same app id: two installers writing the same app directory. Every datapoint from that window is untrustworthy. palm-install is also unusable for iteration here (44 MB hung twice, no staging file, no ipkg process on device); novacom put of the single changed file is ~10 s and md5-verifiable. Proven by reproducing the anomaly -- two adjacent statements where only the first ever logged -- in three code shapes (long message, plain message in try/catch, buffered stamps flushed from a known-good emitter) against a file md5-identical to local and provably the only copy in all six ApplicationPath scan dirs. After the restart every stamp appeared. 2. NPP_New. The isis UI keeps the browser pane display:none and 0x0 until the user navigates, and WebKit does not instantiate a plugin for a hidden zero-size element. Launch with a target URL and it flips to 768x942, hidden=NONE, openURL=function. The stock adapter behaves identically, so this is the UI's design and must not be "fixed". Adapter paint diagnostics: log the graphicsContext pointer and the computed blit rects. On device dstBuffer is legitimately NULL because webOS selects the PGContext path, so "dstBuf=(nil)" alone could not distinguish "took the PGContext path" from "bailed at the dstBuffer guard" -- the ambiguity that made a blank card unreadable from this log. Also documents, in DEVICE-BUILD.md, that the ARM scripts run INSIDE the container (running them on the host gives a misleading "cross-build libxul first" even with the ARM libxul present), that the image is jihad-goanna-build rather than jihad-xtool-build (which has no pkg-config), and that /sysroot must be arm-sysroot/root -- one level deeper than the directory name suggests. Screenshots must come from /dev/fb1 (the app layer). fb0 carries the status bar, app chrome and system alerts, so an fb0 capture shows chrome over a blank content area and reads as "rendering is broken" when it is fine. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JDvWTswwcSHQHVA1gD795L |
||
|
|
c43c29ef64 |
Finding: app JS updates never reach the running card (P1)
Two adjacent statements in JihadEngineOverride.js call the same log() function. The first appears in palm-log on every launch; the second -- a short canary added specifically to disambiguate -- never does. The on-device file provably contains both (grep + md5 match after install), only one file in the app patches the prototype, depends.js lists it once and first, no rootfs copy shadows it, and no extractfs entry exists. The card is running a stale parse. Every method failed to change that: ipkg -o install, version bumps 1.0.0 -> 1.0.1 -> 1.0.2, five killall LunaSysMgr, a full reboot, palm-launch -c then relaunch, and luna-send to com.palm.appinstaller/installNoVerify -- the service Preware and WOQI actually use. The installs DO update the payload on disk; the running card just never picks it up. This matters twice over. It blocks iterating on app/ at all, and it silently invalidated part of the card->adapter investigation, which was reasoning about source the device was not executing. It is also the tenth-plus instance of the session's recurring pattern: an instrument that stays silent is indistinguishable from a system that is fine. The canary was added to break exactly that ambiguity and is what proved this. The user's requirement -- a LunaSysMgr restart should suffice to install -- is therefore unmet in a stronger sense than first thought: today not even a reboot is enough for app JS. Leads recorded in context/impl/impl-stale-app-js.md, including checking for a per-app copy under /var/palm/jail/<appid>/, logging a per-build stamp to compare against disk, and reading the appinstaller response that was never collected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JDvWTswwcSHQHVA1gD795L |
||
|
|
7e94b1bcb7 |
Fix all 8 XUL-input review findings; harness proven able to fail
F-1 (P0) fixed daemon-side rather than in the adapter: MouseEvent records a tap-shaped down/up pair, ClickAt matches it (<=1000ms, <=24px) and stands down, so one tap delivers one click sequence again. Chosen over an adapter fix because no desktop harness runs the adapter (an adapter fix would ship on an argument), because it does not depend on shouldPassInputEvents() staying what it is, and because suppressing clickAt wholesale would also silence its hit-test, near-miss link targeting and VKB classification on exactly the pages where the pen path is live. Two measurements show nothing is lost: the raw pair alone both checks a checkbox and navigates an <a href> via the engine's own default action -- which is why clickAt's direct-navigate had to be suppressed too, or one tap starts two loads. F-2/F-3 replace state-inference with delivery detection: a one-shot capture-phase click listener on the tapped control, so the fallbacks fire only when no click reached it. defaultPrevented is now observable and logged rather than guessed at. F-3 also adds the missing GetDisabled -- load-bearing, since a disabled control gets no click and would otherwise read as a dropped event. F-5: nine phases now gate rc and the script propagates it. The failure path was DEMONSTRATED three ways (a real pre-fix defect, deliberately removed gates, and a null deref), and that demonstration caught a fail-open in the fix itself: rc=384 printed as exit 128 through 8-bit truncation, colliding with the shell's signal encoding. Tenth fail-open found in this project's verification code. Also fixed: phase C's default click coordinate was the viewport centre, so D/E could never observe the button or filter box without a hand-passed JIHAD_XUL_CLICK -- the "operable" claim had rested on that. F-4/F-6 reduce the code comments, handoff and kit to what is actually established: the dropped-event defect is fixed and desktop-proven; the 2026-07-20 SIGSEGV remains unattributed because a discarded event cannot dump core; keyboard-into-XUL is InsertText only, as KeyEvent is still widget-dropped. F-7 requires the tap to have caused the focus before adopting a text control -- the first attempt broke phase E, caught by the harness one run later. F-8 tightens the console bridge to an about: allowlist (the prefix admitted about:blank). NEW F-9 (P1, not fixed, recorded): asyncCmdMouseEvent dispatches DOM events synchronously in the YAP socket callback, which is the rule clickAt exists to obey after a teardown there once rebooted the device. Harmless while events were discarded; live since T-067 and now the primary tap path on user-scalable=no pages. Needs the device to fix safely. F-1 is desktop-verified only, and its device confirmation is BLOCKED (not pending) behind the separate plugin-instantiation failure: with no adapter connecting, the wire mouseEvent path cannot be exercised on hardware at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JDvWTswwcSHQHVA1gD795L |
||
|
|
1f66f125c9 |
Kits: about:addons + XPI support as a requirement (and the P0's real cause)
The device SIGSEGV and the add-ons feature turn out to be the same missing
piece. Instrumented the daemon's init and localized the crash in one device
round-trip:
init: XRE_NotifyProfile (DoStartup: prefs + addons + profile-after-change)
Segmentation fault EXIT=139
With JIHAD_NO_PROFILE_NOTIFY=1 it reaches "engine up; serving YAP" and binds its
socket. So the crash is inside DoStartup, and the cause is that the daemon
embeds via XRE_InitEmbedding2 with no application.ini and therefore registers no
nsIXULAppInfo at all. AddonManager.jsm:778 does setCharPref(..., appinfo.version)
on a value that does not exist -> NS_ERROR_ILLEGAL_VALUE, and the daemon dies in
the same window. Registering a real app identity is both the crash fix and the
prerequisite for every part of the add-on stack.
New cavekit-addons-extensions.md (6 requirements) + build-site Tier 10
(T-062..T-066). Verified while drafting that nothing needs adding to the engine
build: nsAboutRedirector already maps about:addons, and the manager UI, the XPI
installer UI, locale, skin and AddonManager modules all already ship in the
device bundle. Scope recorded honestly: UXP is a Firefox-52-era fork, so this is
the CLASSIC XPI stack, not WebExtensions; and about:addons is a XUL document,
which collides with this project's recorded XUL input hazard -- called out as
part of R2 rather than left to be discovered on hardware.
Also fixes the record: the addons.manager error is NOT pre-existing noise as I
first triaged it. XRE_NotifyProfile is new in
|
||
|
|
e36c8cccfd |
Three independent packages, run in place from cryptofs (R7 + R8)
Enyo, Mochi and Mojo now ship as three fully standalone browsers. Nothing is
co-owned, so nothing needs refcounting: each has its own MIME, adapter shim +
impl, YAP name, socket, upstart job, daemon process and runtime state dir. One
source builds all three -- identity arrives on the compiler command line, and a
half-defined identity is a compile error rather than a silent cross-variant
hijack.
Nothing is written to /media/internal any more. That vfat volume is the user's
USB storage; the engine, daemon and bundled glibc now execute in place from the
app's own cryptofs deviceroot, which is the Atlas model (attributed in NOTICE).
The rootfs footprint is bounded to the three files webOS forces on us and is
reversed exactly by prerm.
Verified on the TouchPad, Enyo variant, 0 failures: installs from a
self-contained .ipk, deploys its own shim/impl/upstart job, serves its own
socket, and runs its daemon out of the app bundle -- with every stock checksum
unchanged and /media/internal clean.
Four defects fixed to get there, each of which would have shipped:
- ipkg without -o installs into the rootfs, not the app partition
- the ARM dist's icudt78l.dat is a symlink into the build container, so the
bundler silently shipped no ICU data and no GRE resources; missing required
files now fail the build instead of the device
- ICU_DATA was never set, so libxul aborted in u_init() on every start
- `| grep -q` under `set -o pipefail` fails on SIGPIPE; the R8 "no
/media/internal" assertion was failing OPEN
Also fixes all nine findings from the fable adversarial review of the download
lifecycle (context/impl/impl-review-findings-downloads.md), including two P1s:
downloads were addressed to the last-connected card rather than the originating
one, and a failed temp-file setup emitted a start with no terminal, forever.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JDvWTswwcSHQHVA1gD795L
|
||
|
|
76401efecc |
db8: grant .mochi/.mojo app ids full CRUD on the shared Jihad kinds (F-A01)
A db8 kind's owner must equal the registering app id, so the variants can never own the shared kinds; explicit per-variant caller grants (not a trailing wildcard — wildcard-caller matching unverified on this build) in the Enyo-owned permission files. Mochi db8 features therefore require the Enyo variant installed; register-db-kinds.sh re-run applies the grant to an already-registered device. On-device verification pending hardware. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
478c61650a |
Enyo start page: centred brand block matching the Mochi variant
Replace the single large logo with a centred block — a smaller (132px) logo, the 'Jihad Browser' name, and 'Enyo UI ★ Goanna/6.9 UXP/b2594a4' — so the Enyo and Mochi start pages match (logo size + text). The old .startpage-placeholder is kept (the resize keyboard-repaint workaround references it) but draws nothing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FTDsTcrUkBYzor1aaS9RUG |
||
|
|
216bae1671 |
Bookmarks: save even when thumbnail generation fails (device fix)
Device: 'adding bookmarks via share menu doesn't show up in bookmarks'. The bookmark record never reached the db even though the kind + write are fine (history, same DbService, works). Root: addBookmark called createPageImages() BEFORE the put — that runs saveViewToFile/generateIconFromFile/resizeImage via callBrowserAdapter, writing under /var/luna/data/browser/icons (mode d-wxr----t, owner luna) which the app user can't write; the failure propagated and aborted addBookmark before bookmarksService.put ran. Wrap createPageImages in try/catch (addBookmark + showAddtoLauncherDialog) so the essential bookmark always saves; thumbnails stay best-effort. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FTDsTcrUkBYzor1aaS9RUG |
||
|
|
39944f5c45 |
Fix universalSearch to query Jihad-owned db kinds (completes db-kind migration)
appinfo.json universalSearch dbQuery still pointed at the stock
com.palm.browser{bookmarks,history}:1 kinds — repoint to the Jihad-owned kinds
so launcher/just-type search reaches the app's actual bookmarks + history.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FTDsTcrUkBYzor1aaS9RUG
|
||
|
|
da0152cf4e |
Fix History/bookmarks/prefs: Jihad-owned db8 kinds (self-contained)
Root cause (device 'History is not working'): the app wrote to the stock kinds
com.palm.browser{history,bookmarks,preferences}:1, which are owned by
com.palm.app.browser and whose permissions grant only com.palm.app.enyo-browser
+ com.palm.launcher — NOT net.riverstonerelay.jihad-browser. Every Jihad db
write was permission-denied, so History/Bookmarks stayed empty.
Fix (matches the self-contained architecture): ship app-OWNED kinds
net.riverstonerelay.jihad-browser.{history,bookmarks,preferences}:1 with
permissions granting the Jihad app id full CRUD (+ launcher read), and repoint
all 8 dbKind references (HistoryList/BookmarkList/URLSearch/BrowserApp). Proven
on device: putKind/putPermissions as the app identity succeed, and a history
put+find round-trips (was errorCode -3963 db:permission-denied before).
A real ipk install registers app/db/kinds via the OS appinstaller; the SDK
palm-install dev shortcut skips that, so build/webos-oe/register-db-kinds.sh
registers them on a dev-installed device (idempotent).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FTDsTcrUkBYzor1aaS9RUG
|
||
|
|
1f5866724d |
Codex gpt-5.6-sol review fixes: F-208/209/210/212
F-208 (P1) / F-209 (P2): remove the app-side key-bridge from JihadEngineOverride.js. It logged charCode/keyCode (keystroke leak, F-163) and forwarded keys that the daemon also inserts (double-insert risk). The webOS VKB does not raise document key events for our swapped-type plugin anyway, so the bridge was dead code — typing is handled entirely in the daemon's keyDown. The override now only swaps the plugin MIME. F-210 (P2): validate the Unicode scalar before UTF-8 encoding in keyDown — reject the UTF-16 surrogate range and code points above U+10FFFF so we never emit malformed UTF-8 into the DOM value. (We deliberately do NOT reject keycodes 0x25-0x28 as "arrows": the VKB delivers the actual character in the key field, so those are the % & ' ( symbols.) F-212 (P2): detach the cached shm attachments in freeze(). The production segments are IPC_RMID-marked, so holding an attach kept them alive and could exhaust the device's scarce shared memory while the card was backgrounded. thaw() re-validates and maybePaint() re-attaches on demand. F-211 (buffer flow-control) left as accepted/known: strict returnBuffer gating risks deadlocking typing if the adapter doesn't reliably return a buffer; 2-buffer alternation + fast blit keeps tearing unlikely and the next keystroke's paint self-corrects. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016MYQTq14u2BT67nroRijWA |