Repository navigation
glance: resolve sys.digest sources from host-held digests (ADR 0002 M4) - #87
Conversation
01a6992 to
7f69f61
Compare
8936e05 to
f389f27
Compare
c985173 to
ae86163
Compare
… GPU timing, terminal shortcuts) Makepad main 39a9de88 adds a hidden map's idle frame loop fix (#79), Android HTTP without redirects (#75), the sheets font by crate (#80), Linux GL remote grabs (#93), Android Vulkan without a debug messenger (#92), the touch-down power hint (#83), GL GPU timing (#81), atlas text on phones (#82), the DrawText current-list fix (#89), terminal keyboard shortcuts (#76) and the terminal on OpenHarmony (#91), and OpenHarmony's keyboard, Studio, GL lifetimes and idle frames (#84, #85, #88, #87), through Octoscript-Makepad 62760863 (#70). makepad #90 is not in it. - root Cargo.toml: makepad and octoscript-makepad revisions together; native-apps.json (Sheets, Terminal), regenerated pins unchanged otherwise - both native-runtime.lock.json files - runtime-patches.lock.json: the settings patch is rebased onto 39a9de88 with the same added and removed lines; its touch-down line in MakepadActivity.java now sits next to #83's hint, and draw_text.rs context follows #87's cfg. The system-back, IME and two Windows patches reapply unchanged. The map, OpenHarmony GL-lifetime and DrawText patches are dropped: they are makepad #79, #88 and #89, now upstream. New tree 976bf55b. - Cargo.lock: unchanged - the three pinned-hash docs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… GPU timing, terminal shortcuts) Makepad main 39a9de88 adds a hidden map's idle frame loop fix (#79), Android HTTP without redirects (#75), the sheets font by crate (#80), Linux GL remote grabs (#93), Android Vulkan without a debug messenger (#92), the touch-down power hint (#83), GL GPU timing (#81), atlas text on phones (#82), the DrawText current-list fix (#89), terminal keyboard shortcuts (#76) and the terminal on OpenHarmony (#91), and OpenHarmony's keyboard, Studio, GL lifetimes and idle frames (#84, #85, #88, #87), through Octoscript-Makepad 62760863 (#70). makepad #90 is not in it. - root Cargo.toml: makepad and octoscript-makepad revisions together; native-apps.json (Sheets, Terminal), regenerated pins unchanged otherwise - both native-runtime.lock.json files - runtime-patches.lock.json: the settings patch is rebased onto 39a9de88 with the same added and removed lines; its touch-down line in MakepadActivity.java now sits next to #83's hint, and draw_text.rs context follows #87's cfg. The system-back, IME and two Windows patches reapply unchanged. The map, OpenHarmony GL-lifetime and DrawText patches are dropped: they are makepad #79, #88 and #89, now upstream. New tree 976bf55b. - Cargo.lock: unchanged - the pinned-hash docs under phone/docs; rom/docs/home-build.md follows in its own change, so this one does not trigger rom.yml (whose jobs local CI cannot run) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… GPU timing, terminal shortcuts) Makepad main 39a9de88 adds a hidden map's idle frame loop fix (#79), Android HTTP without redirects (#75), the sheets font by crate (#80), Linux GL remote grabs (#93), Android Vulkan without a debug messenger (#92), the touch-down power hint (#83), GL GPU timing (#81), atlas text on phones (#82), the DrawText current-list fix (#89), terminal keyboard shortcuts (#76) and the terminal on OpenHarmony (#91), and OpenHarmony's keyboard, Studio, GL lifetimes and idle frames (#84, #85, #88, #87), through Octoscript-Makepad 62760863 (#70). makepad #90 is not in it. - root Cargo.toml: makepad and octoscript-makepad revisions together; native-apps.json (Sheets, Terminal), regenerated pins unchanged otherwise - both native-runtime.lock.json files - runtime-patches.lock.json: the settings patch is rebased onto 39a9de88 with the same added and removed lines; its touch-down line in MakepadActivity.java now sits next to #83's hint, and draw_text.rs context follows #87's cfg. The system-back, IME and two Windows patches reapply unchanged. The map, OpenHarmony GL-lifetime and DrawText patches are dropped: they are makepad #79, #88 and #89, now upstream. New tree 976bf55b. - Cargo.lock: unchanged - the pinned-hash docs under phone/docs; rom/docs/home-build.md follows in its own change, so this one does not trigger rom.yml (whose jobs local CI cannot run) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A glance card may declare `sys.digest(app:, id:)` (Octoscript #40); the glance service fills it in when it realizes the card, from the toolbox run results the host keeps for the calling app, instead of the card carrying the findings as text. - glance_digest.rs: reads `<apps root>/.host/toolbox/<app>/toolbox/runs/ <template>/<run>.json` (host-owned, outside the app's jail, so an app cannot forge a digest) and returns one template-independent record: status, topic, language, summary, retrieved_at, count, points {id, text, label, cite, citations: [source index]}, sources {id, n, title, source, url, published_at}. A source is kept only if the run's host provenance lists its id with the same http(s) URL; a point only if it still cites a kept source; model text with a URL is dropped. Caps on the file (512 KiB) and every field. Missing, expired (48 h after the run), malformed or failed digests resolve to an empty record with $state failed. - glance.rs: `app` must be the caller (its id or launcher id), never an argument's say-so; the resolved value and $status replace anything the publisher sent; a bound card expires no later than its digest; after a publish, each template folder keeps its 8 newest results plus every run a live card binds. - news-brief.card: the M4 News digest card bound to `sys.digest(app: "os.news", id: "glance")`; OCTOSENSE_GLANCE_DEMO=digest publishes it. - Octoscript #40 (sys.digest) is already in main's pins (Octoscript 5991dfae, Octoscript-Makepad 8f103d0c); rebased onto main, the PR's own repin commits are dropped. - Rebased onto main: composes with the in-card sys.chat (glance_chat.rs): digests resolve into the card's data first, then its chat is seeded and the card lowered; the card keeps both its digests and its L0 source. - glance_digest::digest_root reads under the host storage's apps root (octosense_ai_host::toolbox_root), where the toolbox writes its runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A card notification's second line (#290) falls back to the card's own summary in its data. For a card bound to `sys.digest`, that data is the host's digest (glance_digest.rs), so the line now reads the data the store keeps rather than the arguments the publisher sent, which could carry a summary the card itself refuses. A card without kept L0 data (a script card) reads its arguments as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GlanceCard gained `digests` in this branch. The phone feed test's `card` helper in mobile_pages.rs, added on main after this branch forked, built a GlanceCard without the field, so the shell's lib tests stopped compiling once the branch was rebased onto main. The sample cards bind no digests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ae86163 to
6106cc3
Compare
|
Local CI passed on 6106cc3 ( GitHub would run for this PR: desktop.yml, phone.yml, apps.yml. Merged on this local pass (macOS runner queue); GitHub CI runs on the merge commit on main.
Notes:
|
|
The Linux-host steps also passed on this same head, 6106cc3. Run 1 started 2026-10-02T15:31:57 ( The merge evidence is run 2, a Mac-only Rebasing onto main needed one trivial compile fix, commit 6106cc3. The phone feed test's |
Part of #63, milestone M4 in ADR 0002.
Dependencies merged. OctoSense-org/OctoScript#40 (
sys.digestin the L0 catalog) merged as30a21b78, and OctoSense-org/OctoScript-Makepad#50, which repins Octoscript to it, merged asc29cfb84. Bothnative-runtime.lock.jsonfiles and the rootCargo.tomlpin Octoscript-Makepadc29cfb84(octoscript-makepad,octoscript-node) and Octoscript30a21b78, and so do the docs that name them.Rebased onto main (2026-10-01). The conflicts were resolved against main's current design:
Cargo.tomland bothnative-runtime.lock.jsonfiles: main's pins (makepade29a0eaa, App Hub, the contract crate and so on), with only the Octoscript and Octoscript-Makepad revisions moved.Cargo.lockneeded no change, because both resolve to.sources/paths.phone/docs/makepad-fork.mdandrom/docs/home-build.mdname the new revisions.glance.rs: main's interactive cards (Interactive glance cards under the publishing app's policy [skip ci] #153) addedscriptcards andGlanceCard::contained.sys.digestresolution applies only tosource(L0) cards, since ascriptcard carries its own values and binds no digest. Both fields are kept.Caller::Containedis now a struct variant, so the test usesCaller::granted.glance_digest::digest_rootnow resolves under the host storage's apps root, usingoctosense_ai_host::toolbox_root. That is where main's system toolbox (G3 host tools,host_tools/toolbox.rs) writes its run results, so the glance service reads the same folder the toolbox writes. It isNoneuntil the host storage exists.A glance card can now declare
sys.digest(app:, id:). When the glance service realizes the card, it fills that source from the digests the host holds for the calling app, with provenance. The card no longer has to carry the findings as text.Where digests come from (
crates/shell/src/glance_digest.rs)<app folder>/toolbox/runs/<template>/<run>.json(RunOptions::write_result, feat(toolbox): the system toolbox's workflow template library #82). The shell reads the file directly and has no crate dependency on the unmerged toolbox.<apps root>/.host/toolbox/<app id>, outside the app's jail (<apps root>/<app id>). If the file lived in the jail, the app could forge a digest, citations included. When the toolbox is wired into the shell, it must be given this folder.data.digest, topic-briefdata.brief, …):status,topic,language,summary,retrieved_at,countpoints: rows{id, text, label, cite, citations: [source index]}sources: rows{id, n, title, source, url, published_at}retrieved_atis the newest provenanceretrieved_atamong the kept sources, falling back tostarted_at.provenancelists its id with the same http(s) URL.sources, andciteholds the same list as 1-based text.sources[].url.$state.failed.statusis one ofmissing,expiredorfailed, and the card renders its own "no digest yet" vocabulary. A mismatch means the file'sapp_idorrun_iddiffers from the request.Binding (
glance.rs)appmust be the publisher, which is the caller: its app id, or its launcher id (newsforos.news). Any other value is refused at publish. The folder read is always the caller's, whatever the card says.[A-Za-z0-9_-]{1,64}, the run-id charset, so there's no path traversal. The checker enforces this for literals, and the resolver enforces it again for all ids. An id can also come from a state initial (id: state.run).$statusreplace anything the publisher put indata.started_at. A card bound to a current digest expires no later than the digest does.glance) overwrites the same file on each run and republishes the card.Retention
After a publish that binds digests, each of the app's template folders keeps its 8 newest results plus every run id that a live glance card of that app binds (
GlanceCard::digests). Everything else is deleted. Nothing else in the shell deletes run results.M4 card
crates/shell/resources/glance/news-brief.cardbindssys.digest(app: "os.news", id: "glance"). It shows the topic, summary, points with their citation numbers, and the numbered sources. When the digest is missing it falls back to its own vocabulary.OCTOSENSE_GLANCE_DEMO=digestpublishes it.OCTOSENSE_GLANCE_DEMO=1still publishes the old data-fed demo.Tests (all pass locally)
city-infrastructurecase); topic-brief gives the same shape; missing, expired, malformed, other-app, traversal and oversized digests; links only from provenance; caps; failed runs; retention; RFC 3339 parsing.datais ignored; expiry is capped by the digest; another app'sappis refused; Maps gets its own empty folder; a missing or expired digest renders the absence text; publishing prunes old runs but keeps bound ones.python3 tools/setup.py --no-hub. They were re-run after the repin toc29cfb84, with.sourcesrefreshed bysetup.py --no-hub --update(plain setup refuses to move a checkout). All of these pass:python3 tools/setup.py --check --cargoandpython3 tools/native_apps.py --checkpython3 -m unittest discover -s tools -p 'test_*.py'desktop/: the threecargo check --locked -p octosense …builds andbash ../tools/check-shell-graph.sh -p octosensephone/: the threecargo check --locked -p octosense-home …builds andbash ../tools/check-shell-graph.sh -p octosense-homephone/:cargo test --locked --features mobile-apps -p octosense-shell -p octosense-home -p octosense-app-policy -p octosense-app-hub -p octosense-appcard -p octosense-ai-host(shell: 736 passed), plus theappcard(app-appcard) andhost_tools(toolbox-peers) runsHeadless render (before the rebase; not repeated)
The desktop build ran with its window hidden (
MAKEPAD_HIDE_WINDOWS=1,--remote,--test-action glance,OCTOSENSE_GLANCE_DEMO=digest,OCTOSENSE_APP_DATApointing at a scratch apps root). Frames came from the remote/groute; I took no OS screenshots.glance.json: the log showsglance: os.news published digestand the panel lays the tile out at 328×260, the cap. It shows the topic, summary, three cited points (1, 2, 3) and the sources list, and the rest is clipped at the tile cap.Open
card-host) doesn't resolvesys.digestyet, so a bundle's ownpage.cardthat declares it renders the empty state.🤖 Generated with Claude Code