Repository navigation
Rebuild vKore on libkore: Kore v0.40.0 machines and DagFS volumes - #53
Conversation
HostLink, the host-guest channel the first vKore was built around, never reached Kore's main line (Kore #722, #909 and #933 closed; #1015 is stale), so a Kore release could not speak to half of vKore, and the Kore crates it pinned by commit had drifted from any Kore that exists. This retires that half and rebuilds the host side on what Kore v0.40.0 offers: an ISO, its production gate's machine topology, console markers, QMP, and DagFS volumes, whose engine libkore now exports. Kore reaches vKore through one dependency, `kore-host` from libkore 83d8347 (Kore ab6e7b15), the exported `kore-vol` procedure over Kore's own filesystem engine. Nothing of Kore is copied here. - vkore-volume (new): volumes from the host. A browser actor holds one mount; listings, bounded head reads for previews (a PNG's size and Kore's capture record precede its pixels, so none are decoded), exports that never follow a symlink or overwrite unasked and publish a synced file, installs and removals through Kore's all-or-nothing publication, and project staging and bounded write-back. One opener per disk per process. - vkore-vm (rewritten): QEMU on Kore's gate topology, with the host's QEMU probed rather than assumed, firmware from QEMU's descriptors, the ISO's paging mode read through a bounded Joliet reader, QMP with command ids (a late reply is dropped, not taken for the next one, and a timeout inside a line loses nothing), and readiness from Kore's own console markers. - vkored (rewritten): machines and their private state, boot sessions with JSON-lines transcripts, the screenshots folder Kore's capture app needs, and the `vkore` CLI (probe, iso, machine, volume). Configurations are validated when written and when read. - vkore-ui (rewritten): Volumes and Machines, in-process. Shaping is confined to the bundled faces, so a host's own JetBrains Mono can no longer blank the window, and text from a guest or host is set through one guard that escapes what the face cannot draw, controls, direction overrides and invisible characters. Starting a machine releases its disk from the browser and reopens it when the machine stops. Render tests hold pages to no text refusals and to the scalar reference, pixel for pixel. - Removed: the HostLink endpoint and inference registry, the harness and its API, vkore-workspace, vkore-hostlink-ab, the launchers and gate scripts. Verified on a production Kore v0.40.0 ISO under QEMU 8.2.2 with TCG: boot to ready, PrintScreen, stop, and the capture read off the volume with its record, from the CLI, from the desktop under Xvfb, and by the opt-in host test. Not run: KVM, HVF, macOS, physical hardware, block devices. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ACHC7gzaAcosxJUPe73SWh
The README, desktop guide and vkored's README describe what vKore is now: machines on Kore's gate topology, volumes through Kore's own engine, the screenshot workflow end to end, and what is and is not verified. docs/compatibility.md records the identity (libkore 83d8347, Kore ab6e7b15, DagFS format 5, the v0.40.0 ISO's SHA-256, QEMU 8.2) and the guest contract vKore relies on, with how to move the pin. MIGRATION.md explains the retired HostLink half and how a channel comes back: through Kore and libkore, never ahead of them. AGENTS.md holds the working rules. The policy, package and add-on guides say they have no guest path until then. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ACHC7gzaAcosxJUPe73SWh
vKore's docs said Kore v0.40.0 does not act on the ACPI power button under QEMU. It does: the button leads into the same graceful power-off path `pwctl shutdown` takes. What failed was the register access: Kore read and wrote the PM1 status and enable registers a byte at a time, QEMU decodes them only as 16-bit words, and the button is bit 8, so it was never armed and a press was never seen. Kore 547af218 accesses them at their width; an ISO built from it, booted by vKore, powers off 0.4 s after the press (services asked to quiesce, the runtime torn down, ACPI S5), where before the stop waited out its grace period and ended QEMU. The compatibility record adds that ISO (SHA-256 7493248a...) and says what the host can and cannot trigger: shutdown through the button, while reboot and suspend remain `pwctl reboot` and `pwctl suspend` inside the guest. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ACHC7gzaAcosxJUPe73SWh
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.
|
copilot-pull-request-reviewer, this PR's only check, failed without reviewing anything: its session ended with HTTP 402, "You have exceeded your monthly quota". That is the organization's Copilot review quota, not this change. The same error stopped the reviewer on MicroPerceptron/kore#1475 and MicroPerceptron/libkore#31. A re-run won't pass until the quota resets or is raised. This repository has no CI workflows, so the gates were run locally on this branch: Generated by Claude Code |
…hing to copy ## Why `vkore volume @name shots --get ~/Pictures/kore`, as the README gives it, failed on a host without that folder: the export opened its destination and met `No such file or directory`, and `get` did the same. With no captures, `shots --get` instead said it had copied none into a folder that did not exist. And `shots` took any refusal for an empty folder, so a volume it could not read looked like one without screenshots, and with `--json` it printed prose. ## What - `Browser::export` reads its source first and then creates its destination, with any missing parents, as `mkdir -p` would: a path that names nothing leaves the host as it was. What the export writes below the destination still never follows a link. The desktop's Save goes through the same call, so a folder typed into its field is created too. - `Error::is_not_found` names the engine's not-found refusal; the project collector uses it instead of matching the engine's variant itself. - `shots`: a home not created yet, or one without the folder, holds no captures; any other refusal is reported as it is. With nothing to list it says so (`[]` with `--json`) and creates no folder. ## Verification - `cargo fmt --check`; `cargo clippy -D warnings` and `cargo test` for `vkore-volume` and `vkored`, on this commit alone. A new test: a missing source creates nothing, a missing nested destination is created, and a file where the destination should be is refused and kept. - By hand, through the release CLI on a machine's disk: `shots --get` into a missing nested folder, `get` into a missing folder, `get` of a missing path (refused, nothing created), and an empty home (no folder created, `[]` with `--json`). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ACHC7gzaAcosxJUPe73SWh
## Why MicroPerceptron/kore#1475 is merged, by rebase: the Kore commits vKore named (`ab6e7b15` for the engine, `547af218` for the power button) are `9d616ce0` and `7074bda2` on Kore's main, and MicroPerceptron/libkore#31 now exports its native tree at `7074bda2` (libkore `3aac3b5`). vKore's one compatibility identity moves with it, and its docs name commits Kore's main carries. ## What - `Cargo.toml`: `kore-host` at libkore `3aac3b5ce4870421581ffa9b8abc0837c63d2c41`. `Cargo.lock` moves the 16 libkore packages and no other package; Cargo re-resolves six Windows-only edges onto the `windows-sys` 0.59 already in the lock. - `docs/compatibility.md`: the identity (libkore `3aac3b5`, Kore `7074bda2`, and the `7074bda2` ISO's SHA-256 beside v0.40.0's); the PM1 fix by its main commit; what a stop means for a capture. - A capture and a graceful stop. Kore writes a capture seconds after PrintScreen (seven to ten under TCG here), and its shutdown does not wait for one still being written. v0.40.0 never hears the power button, so a stop gave the capture `--stop-after` plus the 10 s grace; a Kore that hears it powers off 0.35 s after the press, and `--stop-after 5` lost the capture. The README's round trip now waits 15 s, the compatibility and desktop docs say why, and so does `--screenshot`'s long help. - README: what is verified, against both ISOs. Block devices leave the list of what is not: a GPT disk on a loop device has been used through vKore. ## Verification Linux x86_64 container, QEMU 8.2.2 TCG, with this pin: - `cargo fmt --check`, `cargo clippy --workspace --all-targets -D warnings`, `cargo test --workspace` (117 passed). - The opt-in boot test (`vkore-vm --test host`) on the `7074bda2` ISO and on the v0.40.0 ISO: 3 passed each. - The `7074bda2` ISO (SHA-256 `b085e919…`), a fresh machine: ready (19/19 services, 45/45 apps, homes 1/1), PrintScreen, a graceful stop 0.35 s after the press. With `--stop-after` 5 or 7 the capture was lost; with 10 or 30 it was saved. `shots --get` copies it out with its record (build `7074bda28c41`), byte-identical to `volume cat`. - The v0.40.0 ISO, a fresh machine: ready (19/19, 44/44, 1/1), PrintScreen, the stop forced after the 10 s grace, the capture copied out. - A disk v0.40.0 formatted (and later Kore wrote), booted by the `7074bda2` ISO: vKore flags the changed ISO, Kore reaches ready and seeds its new app (45/45), and the volume holds both builds' captures. - A GPT disk on a loop device: a device format refused, an install through the partition node, exports through the partition and whole-disk nodes identical to the source, nothing outside the user partition changed. - The desktop under Xvfb: the disk opened on its screenshots, a capture previewed with its record and saved byte-identical, and the machine started headless, followed to ready and stopped gracefully in 0.3 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ACHC7gzaAcosxJUPe73SWh
## Why
The desktop on a physical machine, reading Kore's NVMe from Ubuntu, showed
a capture's record in the preview while a different row wore the
selection's magenta border: the selected capture had scrolled out of view,
and the row under the pointer had the border too. `widgets::Button::Row`
documents that only the selected row carries it; hover gave it one as well.
The same screenshot shows two smaller faults:
- The volume root's breadcrumb read `/ / work`. Its own crumb is `/`, and a
separator went before every component, the first one included.
- Counts did not agree with their nouns: "saved … (1 files, …)", and in the
CLI "1 directories".
## What
- A hovered row is tinted only. The magenta border is the selection's alone.
- The volume root's crumbs read `/ work / face-0`; a home's still read
`~0 / pictures`.
- Each view has one `count` helper ("1 file", "2 files"). It is used by the
desktop's save, import and staging lines, and by the CLI's `get`, `put`,
`shots --get`, `machine apply` and staging lines.
## Verification
- `cargo fmt --check`, `cargo clippy --workspace --all-targets
-D warnings` and `cargo test --workspace` (119 passed). New tests: a hovered
row never passes for the selected one, and a count agrees with its noun.
- Under Xvfb, on a machine's disk: the volume root walked to
`work/face-0/pictures`. With one row selected and another hovered, the
border is on the selection only and the hovered row is tinted. Save reports
"1 file, 33151 bytes".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ACHC7gzaAcosxJUPe73SWh
On a physical machine with Kore and Ubuntu on one NVMe disk, booted into Ubuntu, the desktop opened Kore's user volume through the disk's node. It previewed a 2880×1800 capture's record (125 % density) and saved it out: the first physical disk vKore has read. Writing to one is still unverified, and the list of what is not verified now says so instead of "physical hardware". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ACHC7gzaAcosxJUPe73SWh
…engine (#31) Host programs (vKore first) need to read and write Kore's DagFS volumes: a machine's disk image, or a Kore disk attached to Linux. This gives them Kore's own procedure and engine instead of a second implementation of the format. ## Changes - **`crates/host` (`kore-host`)** is the host-side facade. `kore_host::volume` re-exports the exported `kore-vol` library (`format`, `put`, `rm`, `read` and its `Mount`, the bounds, `FORMAT_VERSION`, `VolError::is_in_use`) and adds no behaviour of its own. It is `#[forbid(unsafe_code)]`. `AGENTS.md` records its rule: no second locate, recover or commit path, no host-side format writer, no parsing of volume bytes outside the engine. Behaviour changes go to Kore's `tools/kore-vol` and arrive through `tools/sync-native.py`. - **`native/`** is re-exported byte for byte at Kore `main` `7074bda28c416ffe34562857ee43cbc883482782`. That commit carries MicroPerceptron/kore#1475 (merged by rebase): `tools/kore-vol` as a library whose mount releases every engine handle it opens. `tools/kore-vol` is a new owner root. Following its path dependencies adds the filesystem service closure it drives (`kore-svc-dagfs`, `kore-svc-block`, `kore-svc-device`, `kore-svc-mm`, `kore-svc-swap`, `kore-nvme`, `kore-svc-extract-worker-c`), for 26 packages and 382 exact files. Publishing that closure was an explicit decision: the alternative is a second DagFS implementation. Eleven of main's commits since v0.40.0 (`e5e0b96a`) reach the closure; `docs/provenance.md` lists them. The DagFS on-disk format is unchanged (version 5). - **Advisories.** kore-wasi's Wasmtime requirements move to 48.0.8. The root `Cargo.lock` takes Wasmtime/Cranelift/Pulley 48.0.8 and zstd 0.13.4, zstd-safe 7.4.0 and zstd-sys 2.1.2. That clears nine RUSTSEC vulnerabilities and ten unsoundness notices, which fail the audit on every branch cut from `alpha`. Nothing else in either lock moves. - `Makefile` runs the exported `kore-vol` suites in `test`, formats `kore-host`, and keeps it out of Miri. `README.md`, `docs/integration.md` and `docs/provenance.md` describe the facade and the export. Commits: - `74524f9`: the facade, and the export with its volume closure. - `83d8347`: re-export at MicroPerceptron/kore#1475's `ab6e7b15`, where a mount releases every engine handle on every path. Before it, a long-lived reader could exhaust its session's 32 handles. - `7033ba6`: Wasmtime 48.0.8 and the zstd family, past the advisories. - `3aac3b5`: re-export at Kore `main` `7074bda2`, once MicroPerceptron/kore#1475 landed. ## Verification CI is green at `3aac3b5`: host (including `zig fmt`, `test-foreign` and `bindings-check`), the three targets, Miri, Advisories and Lockfile currency. `docs/provenance.md` records the local set. Local runs, with the pinned nightly: - **`3aac3b5`:** - Tests: the workspace (every feature except `test-foreign`), the native `kore-rt`/`kore-dagfs` suites, the exported `kore-vol` suites (1 unit, 9 CLI, 6 library) and its loop-device suite as root (4), `kore-host`'s volume tests, and the tool tests. - Checks: the no-default-feature check, Clippy and documentation with warnings denied, `cargo fmt --check`, the three Kore user-target checks for `kore-std`/`kore-ffi`/`kore-entry`, `check-alloc-symbols`, `check-entry`, Miri, the owner graph, the native drift check and the local-composition fixture. - Bindings: cbindgen regenerates `kore.h` byte-identical, and the C consumers compile for all three ISAs. - **`7033ba6`:** `cargo audit --deny warnings` exits 0 on both lockfiles; on the previous root lock it reports the 19 findings. Both lockfiles resolve `--locked`, and kore-wasi's tests pass. The export has run end to end in vKore at `3aac3b5` (MicroPerceptron/vkore#53, under QEMU 8.2.2 TCG): - A production ISO built from Kore `7074bda2`, and a production v0.40.0 ISO, each booted to ready. vKore read off the volume a screenshot the guest saved. - A disk v0.40.0 formatted was booted by the `7074bda2` ISO, and its volume read back with both builds' captures. - A GPT disk on a loop device took an install through its Kore user partition. It was read back through both the whole-disk and partition nodes, with nothing outside the partition touched. ## Not verified Physical hardware. ## Notes - The open HostLink PR (#22) predates this direction. HostLink never reached Kore's `main`; a host-guest channel would come through this same export path once Kore has one. --- 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01ACHC7gzaAcosxJUPe73SWh
vKore's first architecture was built around HostLink, a host-guest channel that never reached Kore's
main: MicroPerceptron/kore#722, MicroPerceptron/kore#909 and MicroPerceptron/kore#933 were closed, and MicroPerceptron/kore#1015 is stale. A Kore release could not speak to that half of vKore, and the Kore crates it pinned by commit had drifted from any Kore that exists. This PR retires that half and rebuilds vKore on what Kore actually offers a host:Kore reaches vKore through one dependency:
kore-hostfrom libkore (MicroPerceptron/libkore#31, pinned at3aac3b5, which exports Kore's main at7074bda2). Nothing of Kore is copied here.What vKore does now
vkore machine create|run|changes|apply): boots an ISO on Kore's gate topology with the host's QEMU probed rather than assumed, follows the boot by Kore's own markers (kernel, services, shell, ready, degraded, failed), and stops it with the power button. With Kore's main from7074bda2(MicroPerceptron/kore#1475) the stop is graceful, 0.35 s after the press. Older Kore under QEMU never hears the button, so vKore ends QEMU after--grace.vkore volume DISK info|ls|tree|cat|get|put|rm|format|shots): a machine's disk, an image, or a block device. Reads, previews (from a file's head, never decoding pixels), exports and installs go through Kore's all-or-nothing publication. Exports never go through a symlink, never over a file unasked, and are published only once synced. The folder an export is sent to is created if it does not exist.pictures/screenshotsbefore each boot, since Kore's capture app saves only into an existing folder. It lists and exports captures with their record (build, time, mode, region, uptime and any otherkore:keys). Kore writes a capture seconds after PrintScreen and a stop does not wait for it, so the documented round trip waits 15 s.vkore-ui): Volumes and Machines, in-process, Iced over Axiom.vkore-workspace,vkore-hostlink-ab, the launchers and gate scripts. The policy, package and add-on crates stay, with no guest path until a channel exists;MIGRATION.mdsays how one comes back (through Kore and libkore, never ahead of them).Commits:
5e39761: the rebuild.2d24e0f: docs (README,docs/compatibility.md,docs/desktop.md,MIGRATION.md,AGENTS.md).820d7fd: docs on why stops are graceful with the PM1 fix and were not before.82a035c: an export creates the folder it is sent to, once it has something to copy.shotsreports refusals instead of taking them for an empty folder.d8a8848: pin libkore3aac3b5(Kore main7074bda2), verified on that commit's ISO, and the capture timing a graceful stop exposes.07e10f5: in the desktop, a hovered row no longer wears the selection's border, the volume root's breadcrumb has one slash, and counts agree with their nouns (also in the CLI).ea6ab0d: README, the desktop on a physical Kore disk.Verification
Linux x86_64 container, QEMU 8.2.2 TCG, at
07e10f5:cargo fmt --all -- --check,cargo clippy --workspace --all-targets -- -D warningsandcargo test --workspace(119 tests) pass. The desktop's tests include headless page renders: no text refusals, and the shared kernels drawing a page pixel-identical to the scalar reference. The QMP client has tests for late replies, mid-line timeouts and line bounds.7074bda2and on a production v0.40.0 ISO.7074bda2ISO:vkore machine runboots to ready (19/19 services, 45/45 apps), presses PrintScreen, and stops gracefully.vkore volume @NAME shots --getcopies the capture out with its record, byte-identical to the volume's copy. With--stop-after5 or 7 the capture was lost; with 10 or 30 it was saved.7074bda2ISO: ready, with both builds' captures on the volume.On a physical machine with Kore and Ubuntu on one NVMe disk, booted into Ubuntu (run by the maintainer): the desktop opened Kore's user volume through the disk's node. It previewed a 2880×1800 capture's record and saved it out.
Not verified
KVM or HVF acceleration, writing to a physical disk, macOS, AMD hosts.
Notes
.cargo/config.tomlfetches it with Git credentials). Every other crate builds from public sources.--screenshotcannot wait for the save; the docs give a measured wait instead. A console marker for a saved capture, in Kore, would let it wait exactly.🤖 Generated with Claude Code
https://claude.ai/code/session_01ACHC7gzaAcosxJUPe73SWh