16.3 Integration Maintenance

This chapter collects source-level contracts that are deliberately omitted from the user task guides. Optional package APIs and renderers evolve, so recheck the upstream interfaces and keep compatibility behavior bounded when changing an integration.

16.3.1 Build and live-verification boundary

For a source checkout, use the Emacs selected by local.mk. Run make check-emacs before diagnosing compilation, make bytecode after an ordinary Lisp edit, and make bytecode-rebuild after switching branches or changing a macro or public interface. Tests deliberately prefer source and therefore do not prove that the byte-code used by a live profile is current. Verify the rebuilt byte-code in a fresh Emacs rather than relying on a file reload when compiled dependants may already be resident.

16.3.2 Notmuch contracts

The live module is registered as an optional package integration. Its stable extension points are the Hello, Search, Show, and Tree mode hooks; Search and Show mode maps; public interactive commands; and public Search/Show accessors. Advice is installed only when a target exists and is target-aware, so a nested or programmatic upstream call does not claim the outer user’s feedback.

The Show landing and visibility paths also read renderer metadata such as :headers-overlay, :message-visible, message extents, :notmuch-part, part-hidden state, and Notmuch part-button types. Missing optional metadata should reduce presentation detail rather than authorize an operation. Review these adapters whenever the Notmuch renderer changes.

Each user-owned asynchronous Search process carries its own completion state as a process property. The upstream sentinel renders first; Emacsvox then clears that property before delivering exactly one terminal result. The owning buffer and process status are authoritative. A killed owner remains silent, concurrent buffers cannot overwrite one another, and the global refresh-all path intentionally acquires no ownership.

Run make notmuch-test for the explicit source suite. After current byte-code exists, run make compiled-notmuch-test; it verifies the exact loaded emacsvox-notmuch.elc, compiler version, and the same focused selector, including real displayed-window reading for both advance paths.

16.3.3 Agent Shell contracts

Use M-x emacsvox-agent-shell-enable to reinstall speech hooks after deliberately disabling them or while testing live integration changes.

The integration uses three deliberately different contract layers:

LayerAgent Shell ownerEmacsvox rule
Public structured APIagent-shell-subscribe-to, agent-shell-unsubscribe, agent-shell-status, and agent-shell-shell-buffer; lifecycle, permission, and tool eventsPrimary authority for processing, completion, errors, permission urgency, and tool status. The public turn boundary triggers inspection of renderer-owned response sections. Event and response data is treated as untrusted content and bounded before automatic Aural submission.
Experimental renderer metadataagent-shell-ui-state, agent-shell-ui-section, rendered Markdown table/source properties, and renderer-owned facesFeature-detected navigation and presentation input. Renderer group provenance outranks provider-controlled IDs; prose and IDs cannot manufacture structured permission or lifecycle authority.
Private compatibility fallbackThe aggregate agent-shell--state, the legacy viewport ownership resolver, viewport position helpers, and legacy face, prompt, or ID inferenceKept in narrow adapter functions for older Agent Shell releases or incomplete renderers. A missing optional detail may reduce header or navigation richness but must not create a permission action or completed response.

The lifecycle subscription currently consumes init-started, init-finished, session-selected, session-restored, input-submitted, turn-complete, and error. Dedicated subscriptions consume permission-request, permission-response, and tool-call-update. Add new semantic behavior at the public event layer when Agent Shell exposes it; keep renderer and private fallbacks isolated and covered by compatibility tests.

16.3.4 WSL2 Omnivox development staging

This section describes the reproducible source-build path, not the ordinary pre-built WSL2 installation. The complete source-build prerequisite checklist is in Building Omnivox For WSL2. Dependency ownership is deliberately split across three boundaries:

BoundarySupplied byDependencies
Windows and WSL hostMaintainerWSL interoperation, powershell.exe, wslpath, Windows .NET Framework 4.7.2 or newer, Docker with Linux/AMD64 support, Git, Make, download and checksum tools, standard GNU shell utilities, network access, and writable Windows LocalAppData.
Pinned release toolchainEmacsvox targetThe immutable Rust/Debian container, MinGW cross tools and runtime DLLs, CMake, Clang and libclang, eSpeak build dependencies, Roslyn, and .NET 4.0 reference assemblies. The exact versions and downloaded-package hashes live in servers/omnivox-release/toolchain.lock.
Build sourceGit checkoutsThe current Emacsvox checkout and the Omnivox checkout selected by OMNIVOX_DIR, including Omnivox’s locked Rust dependencies.

make verify-windows-omnivox-toolchain prepares the cached Roslyn inputs, builds the Docker image, and validates this boundary before compilation. The full target then builds the two 32-bit helpers deterministically, builds native and Windows Omnivox in the container, stages a content-addressed payload, and verifies the Windows-local copy. A host Rust installation, MinGW installation, Visual Studio, .NET SDK, or system eSpeak installation is not an input to this release path.

Maintainers testing tracked Emacsvox or Omnivox changes may use make windows-omnivox-dev. That target records both worktree-diff hashes and labels the result as a development build; it is not the clean release procedure. See servers/omnivox-release/README.org for the pinned toolchain, licensing, provenance, and restaging contract.

Do not bypass the Omnivox release target manually or clean either repository to make its release guard pass. Use make windows-omnivox only for the reproducible clean-release path documented in the user-facing WSL2 route.