Commit Graph
8 Commits
Author SHA1 Message Date
samiandClaude Opus 5 9624e685af docs: cmake/platform.cmake belongs to PKG/QA, not PORT (ADR 0020 amendment)
CI / clang-format (push) Canceled after 0s
CI / testserver (push) Canceled after 0s
CI / bootstrap-script (push) Canceled after 0s
CI / bootstrap-script-2604 (push) Canceled after 0s
CI / extension-lint (push) Canceled after 0s
CI / build (clang) (push) Canceled after 0s
CI / build (gcc) (push) Canceled after 0s
CI / sanitizers (dev) (push) Canceled after 0s
CI / sanitizers (tsan) (push) Canceled after 0s
CI / clang-tidy (push) Canceled after 0s
CI / conformance (push) Canceled after 0s
CI / nightly-integration (push) Canceled after 0s
CI / gui-dod (push) Canceled after 0s
CI / gui-dod-nightly (push) Canceled after 0s
As written, ADR 0020 gave PORT ownership of cmake/platform*.cmake while also
making PORT wait for Phase 0 — but Phase 0's seams are exactly what needs
velox_platform_sources() to select platform/linux/*.cpp. PORT cannot start until
Phase 0 lands, and Phase 0 cannot land without the file PORT owns. PKG/QA caught
the circularity before writing anything, which was the right call.

Central OS detection is root build infrastructure, so it stays with PKG/QA and
lands during Phase 0. PORT keeps the per-OS backend directories and the macOS
and Windows packaging, and owns no part of cmake/.

Also drops a hardcoded test count from the PORT definition of done; the suite
number moves every round and the gate is that it stays green.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-15 17:46:48 +04:00
sami 4e87730ce9 merge: lane/daemon — velox-nmhost, systemd units, velox(1) man page
CI / clang-format (push) Canceled after 0s
CI / testserver (push) Canceled after 0s
CI / bootstrap-script (push) Canceled after 0s
CI / bootstrap-script-2604 (push) Canceled after 0s
CI / extension-lint (push) Canceled after 0s
CI / build (clang) (push) Canceled after 0s
CI / build (gcc) (push) Canceled after 0s
CI / sanitizers (dev) (push) Canceled after 0s
CI / sanitizers (tsan) (push) Canceled after 0s
CI / clang-tidy (push) Canceled after 0s
CI / conformance (push) Canceled after 0s
CI / nightly-integration (push) Canceled after 0s
CI / gui-dod (push) Canceled after 0s
CI / gui-dod-nightly (push) Canceled after 0s
2026-09-15 17:38:46 +04:00
samiandClaude Opus 5 facd851824 docs: define the cross-platform porting strategy (ADR 0020, macOS first)
CI / clang-format (push) Canceled after 0s
CI / testserver (push) Canceled after 0s
CI / bootstrap-script (push) Canceled after 0s
CI / bootstrap-script-2604 (push) Canceled after 0s
CI / extension-lint (push) Canceled after 0s
CI / build (clang) (push) Canceled after 0s
CI / build (gcc) (push) Canceled after 0s
CI / sanitizers (dev) (push) Canceled after 0s
CI / sanitizers (tsan) (push) Canceled after 0s
CI / clang-tidy (push) Canceled after 0s
CI / conformance (push) Canceled after 0s
CI / nightly-integration (push) Canceled after 0s
CI / gui-dod (push) Canceled after 0s
CI / gui-dod-nightly (push) Canceled after 0s
The tree is Ubuntu-first, but the Linux-specific surface is about ten files and
already sits at the bottom of the I/O and RPC stacks. Rather than fork the repo
or scatter ifdefs, platform differences go behind narrow seams with one backend
directory per OS, selected centrally in cmake/platform.cmake.

Linux stays the reference implementation and its behaviour does not change: the
owning lanes (CORE, DAEMON) move today's Linux code behind the seams on Ubuntu
first, with the suite still green, before any macOS code exists. A new PORT lane
owns only the per-OS backends, so macOS work never writes shared logic and
CLAUDE.md's lane rule stays intact.

Adds ADR 0020 (the decision and phases), docs/08-porting.md (seam list, API
mapping for macOS and Windows, dependency table, verification gates) and
docs/agents/AGENT-PORT.md (the lane brief), plus the PORT row in the ownership
table.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-15 17:36:27 +04:00
samiandClaude Sonnet 5 eb72aa522c daemon: build velox-nmhost, systemd socket activation + units, velox(1) man page
Closes build order items 7 (the systemd half) and 9 (D11 in deferrals.md).

velox-nmhost (nmhost/src/main.cpp, 185 lines): a poll()-driven byte pump between
Firefox's native-messaging framing on stdio (4-byte native-byte-order length prefix)
and veloxd's own NDJSON framing on the Unix socket. Reframes each direction, no JSON
parsing, no retry/backoff (the extension relaunches a fresh host on its own
reconnect), exits the moment either side closes. Deliberately dependency-free — no
veloxd_* library, no nlohmann_json — since it runs unconfined outside Firefox's
sandbox regardless of packaging format.

Two real bugs found and fixed while getting the integration test to actually pass
rather than hang, both exactly the class of bug a "trivial pump" invites:
1. Never set the pumped fds non-blocking, so the "drain what's available" read loop
   blocked on its own second read() instead of returning to poll().
2. stdin and stdout are two different descriptors (0 and 1), not one — an early draft
   polled POLLOUT on fd 0, which is opened read-only, so EOF and writability were
   never both observable through the same pollfd entry.

packaging/nativehost/com.velox.host.json + its own README.md supersede
AGENT-DAEMON.md's stale "four locations" line: spike S1 / ADR 0003 found only three
manifest locations are real (~/.mozilla/native-messaging-hosts/ for BOTH deb/tarball
and snap Firefox, /usr/lib/mozilla/... for deb/tarball only, the flatpak sandbox path)
— the fourth, ~/snap/firefox/common/.mozilla/..., is not read by snap Firefox at all.
The README spells out the per-user-manifest / postinst enumeration implication for
PKG/QA (postinst runs once as root; the two ~/-relative locations are per-user) and
flags that docs/07-packaging.md's own install-layout line only shows the one
root-owned path.

Socket activation: rpc/systemd_activation.cpp is a from-scratch sd_listen_fds() (env
vars only — LISTEN_PID/LISTEN_FDS, fd 3 — no libsystemd link) that UdsServer::start()
checks first, skipping its own create/bind/chmod/listen when systemd already bound
the socket. packaging/systemd/velox.socket + velox.service are the unit pair,
verified both by systemd-analyze verify and by an actual fork/dup2/execve simulation
of the activation handshake — a real session.hello round-tripped over the handed-off
fd with no bind() ever called inside the daemon for that run. velox.service
deliberately skips ProtectSystem=/ProtectHome=/ReadWritePaths=: saveTo.allowedRoots is
user-configurable to anywhere on the filesystem, and a sandbox here would turn a
legitimately-configured save location into an opaque EROFS/EACCES instead of the
daemon's own clear -32011.

cli/man/velox.1 documents the CLI as it actually exists today (add/ls/pause/resume/rm,
--json) — the queue/settings subcommands AGENT-DAEMON.md's build order originally
sketched aren't implemented in cli/src/main.cpp yet, so the page doesn't claim they
are. Checked warning-free with groff -mandoc -ww -z.

Full ctest: 57/57 (excluding the pre-existing, unrelated conformance failure noted in
earlier commits).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01GRDjHGgpYmMoPE2UFbe7pP
2026-09-12 22:46:52 +04:00
samiandClaude Sonnet 5 99b429abfa pkg: fix qt6 svg dev package name — libqt6svg6-dev has no 26.04 candidate
`apt-cache policy libqt6svg6-dev` is "Candidate: (none)" on 26.04; the package
that carries the Svg headers and Qt6SvgConfig.cmake is qt6-svg-dev. Since
gui/CMakeLists.txt landed on main the root build's
find_package(Qt6 ... Svg REQUIRED) is live, so a clean 26.04 box could not
configure the project at all. Same name in README.md and AGENT-PKG-QA.md.

Reported in gui/docs/pkg-qa-requests-m1.md R1.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_0143aKiohmDiyefJBwHDJJqw
2026-09-10 14:58:10 +04:00
samiandClaude Sonnet 5 f60070c420 mockd: add --tasks N — a plausible large synthetic table for GUI's DoD
GUI's M1 definition of done is "10 000 synthetic rows scroll at 60 fps with
flat memory over 10 minutes (mockd --tasks 10000)". This flag was missing from
the four unhappy-path flags that did land; the brief's own flag list omitted
it, which is corrected here too.

--tasks seeds a plausible population rather than N copies of one row: varied
state, size (log-uniform 50 KB - 20 GB), category, queue position and
description, drawn from the same category.list / queue.list fixtures the rest
of mockd already serves so a synthetic task can never name a category or
queue those methods don't also return. State distribution is roughly
55% complete / 8% failed / 4% cancelled / 6% paused / 2% retry_wait / 25%
queued, using the new TaskErrorCode taxonomy for failures.

"Progress advances across the whole set, not a handful of live rows" ruled
out the obvious cheap answer. A bounded, rotating pool of concurrently-active
downloads (--active-cap, default 24) is fed continuously from each queue's
FIFO — with the rest of that queue's queuePosition renumbered on every
promotion, as a real scheduler would — and a small fraction of active tasks
hit a transient failure and cycle through retry_wait before rejoining, so the
pool keeps rotating through new rows for the whole run instead of draining
once. Verified over a 10000-task, 60-second run: 61.5 MB RSS flat, and the
active pool's membership meaningfully different after 60s.

tick() only ever walks the active pool plus due retry-wait entries, never the
full task list, so its cost stays flat regardless of --tasks. A manual
download.add is still admitted immediately regardless of --active-cap — a
human driving the GUI by hand must never wait behind synthetic load.

Fixed a latent double-push while building this: any task 'connecting' at the
top of a tick was pushed to the progress batch once for the transition and
again at the loop's unconditional final push, inflating event.task.progress
payloads with a duplicate entry for that taskId. It predates this change (the
original tick() had the same shape) but only became visible once several
tasks are legitimately 'connecting' in the same tick, which --active-cap's
continuous promotion now does routinely.

--seed makes a run reproducible, which matters when a GUI bug only shows up
at a particular row.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_012fgjnqFCS5h5L7gZTZo3rV
2026-09-10 00:01:44 +04:00
samiandClaude Opus 5 e88edd5bd6 docs: add dispatch prompts and correct the toolchain survey
- docs/agents/PROMPTS.md: six copy-paste agent prompts, wave ordering
  (PROTO + PKG/QA first, the other four at contract freeze) and the
  git worktree commands
- Correct the bootstrap section: an earlier check ran with a restricted
  PATH and wrongly reported the machine as bare. git 2.53, CMake 4.2.3,
  g++ 15.2, ninja, Qt 6 dev, libcurl, SQLite, nlohmann-json, ffmpeg and
  clang-format/tidy are all present; only libqt6svg6-dev, libsecret-1-dev,
  nodejs/npm and clang are missing. Flag that CMake 4.x rejects
  cmake_minimum_required below 3.5.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-09 18:23:12 +04:00
samiandClaude Opus 5 8bb683b09d scaffold: project structure, wire contract, roadmap and agent briefs
Lays out Velox Download Manager (IDM-class download manager for Ubuntu
26.04) as a monorepo ready for parallel lane development. No implementation
code by design.

- docs/: architecture, roadmap M0-M7, IDM-parity GUI spec, engine design,
  Firefox extension spec, risks/spikes, packaging
- contracts/: wire-contract skeleton (JSON Schema + fixture templates) —
  the single synchronization point between lanes
- docs/agents/: one brief per lane (PROTO, CORE, DAEMON, GUI, EXT, PKG/QA)
  with owned directories, build order and definition of done
- CLAUDE.md: rules of engagement — lane ownership, layering, non-negotiables
- CMake scaffolding with dev/tsan/release/ci presets

Two environment findings shape the design: Firefox here is the Mozilla snap
(native-messaging risk, so the extension carries a loopback-WebSocket
fallback), and Wayland forbids passive clipboard monitoring (so clipboard
capture is explicit-action-first).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-09 18:21:11 +04:00