feat(linux): bring desktop support up to date - #71
Conversation
Add the versioned Aiden Remote API, secure local and Tailscale pairing, resumable chat streams, and workspace, file, Git, model, schedule, and attachment operations. Extract shared application services and cover authorization, idempotency, replay, revocation, opaque handles, and transport behavior.
Expose pairing, connection status, approved roots, device revocation, and local or Tailscale controls in Electron settings. Introduce Aiden On The Go during onboarding, synchronize appearance tokens, and cover the settings and end-to-end lifecycle.
Add the SwiftUI iPhone and iPad companion with secure pairing, adaptive workspace and chat navigation, resumable SSE streaming, files, Git, scheduled tasks, App Intents, Live Activities, voice input, native Markdown, and Aiden appearance. Include physical-device tests, signing metadata, TestFlight workflows, ASC monitoring, release-policy checks, and required upstream notices.
Record the Aiden Remote API, threat model, phased Aiden On The Go implementation and verification history, TestFlight status, and remaining release work. Remove the obsolete CLAUDE.md instructions while retaining the active migration plan and required attribution history.
Persist bounded per-provider model visibility, apply it across Mac and Telegram selection surfaces, and keep existing hidden selections executable. Normalize custom provider PNG/SVG artwork on the Mac and project only bounded PNG data through the remote model catalog.
Render Mac-normalized custom provider artwork, filter hidden models while preserving current hidden selections, remove the model-row Aiden ghost, and replace the speech status sentence with a reduced-motion-safe animated waveform.
Remove the opaque bottom safe-area pane and reserve scroll-content clearance so chat rows flow beneath the Liquid Glass action while the final row remains reachable.
Advance app, tests, and widget build metadata to 8 while retaining the pre-release 0.1.0 marketing version.
Record the exact VALID build resource, internal tester assignment, external NOT_APPLICABLE state, physical-device verification, and release scope.
update .papercuts/troubleshooting.md as part of the reviewed Aiden On The Go and Remote Access update.
update docs/aiden-remote-api-v1.md as part of the reviewed Aiden On The Go and Remote Access update.
update docs/plans/README.md as part of the reviewed Aiden On The Go and Remote Access update.
remove docs/plans/aiden-remote-multi-instance-hardening-plan.md as part of the reviewed Aiden On The Go and Remote Access update.
update docs/security/aiden-remote-threat-model.md as part of the reviewed Aiden On The Go and Remote Access update.
update docs/testing/aiden-on-the-go/phase-12.md as part of the reviewed Aiden On The Go and Remote Access update.
update docs/testing/aiden-on-the-go/phase-6.md as part of the reviewed Aiden On The Go and Remote Access update.
update ios/ASC_CLI.md as part of the reviewed Aiden On The Go and Remote Access update.
update ios/AidenOnTheGo.xcodeproj/project.pbxproj as part of the reviewed Aiden On The Go and Remote Access update.
update ios/AidenOnTheGo/ContentView.swift as part of the reviewed Aiden On The Go and Remote Access update.
update ios/AidenOnTheGo/Features/Remote/AidenChatFeature.swift as part of the reviewed Aiden On The Go and Remote Access update.
update ios/AidenOnTheGo/Features/Remote/AidenPairingView.swift as part of the reviewed Aiden On The Go and Remote Access update.
There was a problem hiding this comment.
ℹ️ The incremental delta is clean — no new issues. The six prior findings remain open in their threads and are unchanged by these commits: the Fedora CI job, the
native/helpers, thepackage.jsontest registration, and the portal paths are all untouched, and the new code is a read-only diagnostic plus test-fixture/layout repairs.
Reviewed changes (delta since the review of 9fc021a)
- Fedora Computer Use host prerequisite diagnostic — a new read-only
scripts/linux-computer-use-host-preflight.mjs(plus 29 adversarial tests registered intest:linux-contractsand acomputer-use:linux-host-preflightscript) inspects/etc/os-release,/sys/kernel/security/lsm, and/sys/fs/selinux/enforcewith a bounded non-shell reader, emits derived reason codes only, and pinsacceptanceEstablished/trustPolicyVerified/computerUseEnabledto false. - Providers action group wraps at narrow widths —
max-w-fullon the header action group lets the existingflex-wrapabsorb the 17px overflow at 390px content width instead of forcing horizontal scroll. - E2E relaunch mutation hook —
AidenE2e.relaunch(beforeLaunch?)runs fixture mutations only aftercloseAidenhas verified the previous Electron process exited; the empty-chat migration spec now seeds and asserts disk state inside that hook, and the Settings geometry test polls until the renderer observes the native content width before measuring overflow. - Plan and papercut bookkeeping — the Linux parity plan records Phase 5 (Fedora SELinux admission prerequisites, explicitly not implemented) and Phase 6 (narrow Providers and migration fixture repair), including the OrbStack non-SELinux kernel limitation.
DeepSeek Flash | 𝕏
There was a problem hiding this comment.
ℹ️ The incremental delta is clean — no new issues. The Fedora RPM prerequisite finding from the prior review is addressed in this commit; the five other prior findings remain open in their threads and are unchanged (this commit touches only CI, a policy test, and docs).
Reviewed changes (delta since the review of b637bfd)
- Fedora private-bus prerequisite — the
linux-rpmjob's dnf line now installsdbus-daemon, which ships/usr/bin/dbus-run-sessionon Fedora 44 (verified against the Fedora 44 package file list), sotest:global-shortcuts-portalcan start its private session bus instead of failing before the RPM acceptance steps. - CI policy pin —
check-ci-policy.test.mjsgains an assertion that the Fedora job installsdbus-daemon, so a future edit that drops the prerequisite fails the policy suite; the suite passes 6/6 locally. - Plan and papercut bookkeeping — the parity plan records Phase 8 (Fedora CI prerequisite repair and the isolated Fedora 44 VM status), and the papercuts file records the missing-
dbus-run-sessiondiagnosis.
The hosted Fedora job on this head is the remaining live validation of the prerequisite.
DeepSeek Flash | 𝕏
There was a problem hiding this comment.
Important
The new registry registration fails closed when the app's .desktop file is not discoverable, which removes hold dictation from npm run dev and plain non-integrated AppImage runs on backends that accept the previous unregistered connection (KDE). The GNOME gate, the SELinux prerequisite probe, and the mock/test additions are otherwise clean.
Reviewed changes (delta since the review of f620ef1)
- GNOME hold-dictation gate — the helper probes
NameHasOwner("org.gnome.Shell")before any portal call and returnsunavailableon GNOME sessions, keeping toggle dictation instead of risking a lost release edge; the protocol suite gains agnome-runningcase. - Portal app registration — the helper registers the fixed
com.sambitcreate.aiden-agentapp id withorg.freedesktop.host.portal.RegistrybeforeCreateSession, treatingUnknownInterface/UnknownMethodas legacy portals; the mock and protocol tests gainregistry-rejected,registry-unknown-interface, andregistry-unknown-methodcases. - Disposable Fedora SELinux prerequisite probe — a new
scripts/linux-selinux-boundary-probe/experiment (CIL deny overlay, native holder/attacker fixture, evidence verifier, always-run cleanup) proves file/socket/entrypoint denial, effective-allow removal, matching enforcing AVCs, and restoration on a real enforcing VM;verify.test.mjsandcleanup.test.mjsare registered intest:linux-contracts. - Docs and papercuts — the parity plan records Phases 9/10 (enforcing Fedora VM, portal registration, modifier-release loss) and the troubleshooting log records the five host findings.
ℹ️ Nitpicks
- GNOME sessions now always fail hold setup, but
docs/linux.md:106-108still tells users to choose Hold in Settings → Voice and assign a chord, and the Voice radio still offers it; the failure only surfaces as the generic Settings toast. A sentence noting GNOME keeps toggle dictation would keep the guide accurate. - The probe has two evidence assertions that cannot fail:
run.sh:131writeshardened-holder-check.txtunconditionally andverify.mjs:17asserts its constant content, whilerun.sh:144writesrestored-holder-context.txtthat nothing reads. The holder's real self-check is enforced by the ready socket (start_holder) — consider dropping the marker or deriving it from the holder.
DeepSeek Flash | 𝕏
There was a problem hiding this comment.
ℹ️ The incremental delta is clean — no new issues. The descriptor-delegation probe is well-covered (successful baselines, exact-PID/context AVCs, effective-allow subtraction, restoration, and always-run cleanup), and the prior open findings are unchanged.
Reviewed changes (delta since the review of 6a7b585)
- Descriptor delegation probe —
delegation.cadds an SCM_RIGHTS receiver and a fork + explicitsetconinherited-descriptor child;run.shdrives both through bounded transient systemd units, andverify.mjsnow requires successful token-read baselines, exact receiver PID/context and private-filefd { use }AVCs, removal of the stockunconfined_t → aiden_boundary_probe_t:fd useallow, and restoration of both cases. - Cleanup coverage —
cleanup.shstops an outstanding delegation unit and reaps the receiver before UID removal;cleanup.test.mjsexercises receiver-wait and systemctl-stop failures. - Cua driver gap audit — a new
docs/plans/linux-cua-driver-gap-audit.mdrecords the pinned driver's Linux artifact hashes, the Wayland opt-in gate, the Shell 45–48 extension compatibility gap, the unauthenticatedorg.cua.WinRectssession-bus endpoint, and portal-based alternatives; the parity plan records Phase 11 and the failed outgoing-exec experiment as explicitly uncounted. - Papercuts — the systemd-run/dbus-broker descriptor-forwarding limitation and the launch-policy
fd/usefinding are recorded.
DeepSeek Flash | 𝕏
There was a problem hiding this comment.
ℹ️ The incremental delta is clean — no new issues. The new disposable Electron role-transition probe follows the established SELinux-probe pattern, its 25 fixture tests are registered in
test:linux-contractsand pass, and the open findings from earlier reviews remain unchanged in their threads (thepackage.jsonedit registers only the two new probe tests).
Reviewed changes (delta since the review of 2391787)
- Added a disposable Electron process-role probe — a new Fedora 44 / GNOME Wayland fixture launches a root-owned Electron 43.1.1 copy from a fixed system unit into
aiden_electron_role_probe_main_t, transitions its Electron andbin_t/shell_exec_texecs into..._child_t, and requires observed main/zygote/renderer/GPU/network/Node roles, renderer seccomp and NoNewPrivs, child-context shell/command output, and exact-126 direct/forged attacks with no residualexecute_no_transor outsider transition. - Covered the verifier and cleanup adversarially —
verify.mjsrejects 17 mutated evidence shapes (missing roles, wrong UIDs, sandbox flags, wrong attack outcomes, remaining allows) andcleanup.shwithcleanup.test.mjsproves every teardown step still runs after each injected failure. - Registered the new tests and recorded the phase — both probe test files are appended to
test:linux-contracts, and the parity plan plus papercuts log record the CIL, Fedoradomtrans_pattern, NNP-transition, and GNOME-scope-migration observations, with production Computer Use explicitly still disabled.
DeepSeek Flash | 𝕏
There was a problem hiding this comment.
ℹ️ The incremental delta is clean — no new issues. The protected-IPC probe follows the established disposable SELinux-probe pattern, its 13 fixture tests are registered in
test:linux-contractsand pass locally (full suite green, scoped lint clean), and the seven open findings from earlier reviews are unchanged: this commit touches nonative/helper,shortcut.ts,linux-dictation-portal.ts, ordocs/linux.md, and thepackage.jsonedit appends only the two new probe tests totest:linux-contracts.
Reviewed changes (delta since the review of fe42fa2)
- Selective protected-socket transfer probe — a new manual, disposable-VM
scripts/linux-protected-ipc-probe/experiment hasfixture.ccreate generic andaiden_ipc_protected_socket_t-labeled socketpairs, delegate one endpoint over an ordinary unconfined listener withSCM_RIGHTS, and report both sides' UID/PID/context/socket label/roundtrip outcomes. - One-line deny overlay with retained creator
fd use—aiden_ipc_probe_deny.cilsubtracts onlyunconfined_domain_type → aiden_ipc_protected_socket_t:unix_stream_socket { read write }, while the base policy keepsunconfined_t → aiden_ipc_sender_t:fd useand generic read/write, so a coarse creator-domain denial cannot explain the protected result. - Evidence verifier and adversarial coverage —
verify.mjsrequires the generic roundtrip and creatorfd useto survive under the overlay, the protected endpoint to be omitted withMSG_CTRUNCand no descriptor (errno 0), an exact enforcing receiver socket-object AVC, effective-allow removal viasesearch, and full restoration; 13verify.test.mjs/cleanup.test.mjscases mutate the evidence and inject teardown failures, and both files are appended totest:linux-contracts. - Plan bookkeeping — the parity plan records Phase 13 (including the live
SO_PEERCRED/SO_PEERPIDFDcreator-vs-holder observation and the explicitly unproved boundaries) and the plans index updates its status line.
DeepSeek Flash | 𝕏
There was a problem hiding this comment.
ℹ️ No critical issues — the new combined Electron/SCM_RIGHTS probe is well-covered and its fixture tests are all fail-able. One minor evidence-scoping nit inline.
Reviewed changes (delta since the review of 88592ef)
- Added the combined Electron protected-socket fixture — a new native
ipc-server.c/ipc-addon.c/ipc.hexperiment creates all four generic/protected socketpairs from one sender process and receives endpoints inside the actual Electron main and Node utility through a synchronous N-API 8 addon, so main must complete both token/ACK roundtrips while the utility gets the generic endpoint and loses the protected one withMSG_CTRUNC. - Extended the deny overlay to the protected object — the CIL subtracts
unix_stream_socket { read write }on..._protected_tfrom every domain except main and sender while retaining creatorfd use, generic read/write, andgetoptlabel inspection, and restricts entry into the sender domain to the root-managed unit. - Added the IPC verifier and adversarial coverage —
verify-ipc.mjsrequires four same-creator cells, cross-checks native receiver PIDs/contexts/socket labels against the root process receipt, and matches an exact enforcingunix_stream_socketAVC to the utility PID; 15 new mutations plus the sender cleanup failure case were added, and I traced each one to a failing assertion. - Extended the run harness and cleanup —
run.shcompiles the fixture with GCC, starts the separate sender unit before Electron, pins audit capture to a tail offset with an inode check, andcleanup.sh/stop-processes.pystop both units, drain the sender domain through pidfds, and remove the IPC runtime directory. - Recorded the phase and audit status — the parity plan documents Phase 14 results and opens Phase 15 (release package provenance), the plans index updates its status line, and the Cua audit notes the isolated ARM64
--versioncheck.
DeepSeek Flash | 𝕏
There was a problem hiding this comment.
ℹ️ The incremental delta is clean — no new issues. The attestation pin, action inputs, permission set, and verification flags were checked against the pinned action's own
action.yml/README (tagv4.2.2), thegh attestation verifymanual, and the release workflow parsed as YAML; the policy suite passes 8/8 and every new mutation fails the assertion it targets. The seven earlier findings and the journal-timestamp nit remain open in their threads.
Reviewed changes (delta since the review of eb69555)
- Gated the Linux release job to main —
linux-releasenow requiresgithub.ref == 'refs/heads/main'and overrides the inheritedcontents: writewithcontents: read,id-token: write, andattestations: write; the dependentpublishjob cannot ship a release from another ref becausepublish-github-release.shrequires exactly two verified assets per Linux kind. - Attested the verified Linux artifacts — a pinned
actions/attest@1e69f48(v4.2.2) step runs after the contract, build, and GUI-smoke steps and before staging, hashing the AppImage, deb, rpm, andlatest-linux*.ymlsubjects withcreate-storage-recordandpush-to-registrydisabled, so no registry or artifact-metadata permission is needed. - Pinned the policy in tests —
check-ci-policy.test.mjsgains a workflow-contract test plus 12 mutations that reject an unpinned action, a branch-dispatch bypass, missing publish/smoke gates, extra permissions, missing or broadened subjects, custom predicates, registry publication, and ignored failures. - Documented the provenance workflow —
docs/releasing.mdexplains the main-only attestation and gives agh attestation verifycommand that binds the approved commit, workflow identity, main ref, and SLSA predicate, while listing what the attestation does not prove; the parity plan records Phase 15 and opens Phase 16.
DeepSeek Flash | 𝕏
There was a problem hiding this comment.
ℹ️ The incremental delta is clean — no new issues. The new payload-inventory utility is well-scoped and fail-closed, its 26 tests are fail-able and correctly registered, and the open findings from earlier reviews remain unchanged in their threads: this commit touches no
native/helper,shortcut.ts,linux-dictation-portal.ts,docs/linux.md, or probe harness, and a repo-wide grep still finds none of the six policy-contract test files in any npm script.
Reviewed changes (delta since the review of d4da7d6)
- Added a deterministic finalized-payload inventory utility —
scripts/linux-payload-inventory.mjscomputes a canonical JSON inventory (paths, types, full permission modes, sizes, SHA-256) of a quiescent payload tree, rejecting symlinks, hard links, special files, noncanonical roots, oversized inputs, and entries that change mid-read; the expected manifest must live outside the tree and is created exclusively with mode0600. - Covered the utility adversarially —
scripts/linux-payload-inventory.test.mjsadds 26 tests: eight verification mutations, file/directory/hard-link and ancestor-symlink rejection, FIFO and sparse-size bounds, in-flight metadata-change detection, 24 malformed-schema mutations, manifest link/overwrite refusal, and CLI exit codes. - Registered the suite and documented the contract — the new test file is appended to
test:linux-contracts;docs/computer-use-integration.mdrecords the operator workflow and explicit non-goals (no publisher authentication, immutable installation, or TOCTOU boundary); the parity plan closes Phase 16 and opens Phase 17; papercuts record the electron-builder afterPack mutation finding.
DeepSeek Flash | 𝕏
There was a problem hiding this comment.
✅ No new issues found. The new Phase 17 stager is fail-closed by construction, its unprivileged contracts pass locally, and the seven open findings from earlier reviews are untouched by this delta.
Reviewed changes (delta since the review of 6ca07f2)
- Added a root-only managed-payload stager —
native/linux-managed-payloadis a new Linux-only Rust CLI that requires host root and SELinux enforcing, accepts only a protectedlocal-staging-onlyapproval bound to the exact inventory-file SHA-256, validates the Phase 16 inventory schema, and pins source, store, and input paths withopenat2(BENEATH|NO_SYMLINKS|NO_MAGICLINKS|NO_XDEV) plusO_PATHclassification. - Copies and publishes without replacement — bytes are copied into fresh root-owned inodes under the store's exact SELinux creation context (fscreate set/readback, restored or the process aborts), the source and destination are rehashed against the approved digests, records are written
0400, and the inventory-digest-named generation is published withrenameat2(RENAME_NOREPLACE)plus parent fsync; failures before the rename remove only the private.staging-*tree. - Added adversarial coverage — seven unprivileged Rust tests cover schema/approval mutations, duplicate fields, UTF-16 path ordering, byte/entry/depth bounds, and CLI behavior, and an ignored trusted-root Fedora SELinux integration suite exercises retained-writer separation, path replacement, devices, links, ACLs, capabilities, filename transitions, publication collisions, and injected cleanup failures; the npm wrapper is registered in
test:linux-contracts. - Wired and pinned the native build dependencies — both Ubuntu jobs install
libselinux1-dev, the Fedora container installslibselinux-develpluscargo/rust, and a newcheck-ci-policytest rejects a workflow that drops any of them. - Recorded Phase 17 and its explicit limits — the parity plan, plans index, computer-use integration doc, crate README, and papercuts describe the local-staging scope and keep release authentication, activation, confinement, and Computer Use disabled.
Verification this run: read the incremental delta end to end and the new crate files at HEAD; compiled the crate with the pinned toolchain and ran its seven unprivileged tests (pass; the ignored root suite is Fedora-only); ran scripts/check-ci-policy.test.mjs (9/9); confirmed Fedora 44's rust package depends on rust-std-static and that the Ubuntu x64 and arm64 runner images ship Cargo 1.98.1; confirmed the six policy-contract test files are still absent from every npm script despite the package.json edit, and that no other prior finding site was touched.
DeepSeek Flash | 𝕏
There was a problem hiding this comment.
Important
The new standalone Linux-installer workflow cannot pass its verification step on Ubuntu: the "no GitHub CLI" case in scripts/install.test.mjs only hides gh when the system binary lives outside ${bin}:/usr/bin:/bin (true on macOS), but the Ubuntu 24.04 runner image ships GitHub CLI at /usr/bin/gh, so the real CLI runs and the assertion fails. Both matrix jobs (ubuntu-24.04 and ubuntu-24.04-arm) stop before any build. Details inline.
Reviewed changes (delta since the review of cf88433)
- Added a verified cross-platform installer — a new repository-root
install.shselects the exact macOS DMG or Linux deb/rpm/AppImage for the host architecture and distro family, verifies the release SHA-256 and (on Linux)gh attestation verifyprovenance before installing, and uses private staging with armed rollback for macOS replacement and AppImage promotion. - Added a standalone Linux-installer workflow —
.github/workflows/linux-installers.ymlis a manual, non-publishingworkflow_dispatchjob that builds, verifies, and uploads x64 and arm64 AppImage/deb/rpm artifacts plusSHA256SUMSandinstall.sh, withcontents: readonly. - Wired the installer into the release —
publish-github-release.shnow requires an executableinstall.sh, copies it into the distribution directory, and adds it toSHA256SUMSand the release asset list;publish-github-release.test.mjspins the new asset. - Added focused installer tests —
scripts/install.test.mjscovers artifact selection (including Rosetta), option/version rejection, checksum and provenance gates, AppImage staging and hostile destinations, and macOS rollback arming, and is registered intest:branding. - Documented the install and release path — README,
docs/linux.md,docs/releasing.md, the parity plan (Phase 18), and the troubleshooting log describe the installer, the current v0.40.0 asset gap, and the manual workflow's non-publishing boundary.
ℹ️ Installer install branches lack live end-to-end acceptance
The installer is now the primary install command in the README, but the recorded live acceptance is the signed-DMG --download-only path; the macOS system install (sudo/ditto/promotion/rollback) and the Linux deb/rpm/AppImage branches are covered only by the function harness and stubbed commands, and no release carries Linux assets yet. Running one real system install over an existing app, a forced rollback, and one real deb/rpm/AppImage install before the next accepted release would exercise the paths the curl command now advertises.
Technical details
# Live acceptance gap for the advertised install paths
## Affected sites
- `install.sh:320-401` — macOS system install: staging, `ditto`, promotion, verification, rollback cleanup.
- `install.sh:326-360` — Linux deb/rpm/AppImage install branches.
- `scripts/install.test.mjs` — exercises these via the function harness and stubbed `mv`/`ln`; the AppImage tests deliberately stub the GNU-only flags, so the real commands never run.
## Required outcome
- At least one real macOS system install that replaces an existing app and recovers from a forced verification failure, and one real deb, rpm, and AppImage install (or a documented decision that `--download-only` plus package-manager smoke tests are sufficient).
## Open questions for the human (optional)
- Is a live system-install acceptance run planned before the next release, or is the harness coverage considered sufficient for now?DeepSeek Flash | 𝕏
There was a problem hiding this comment.
✅ No new issues found. This delta resolves the installer-fixture portability finding from the prior review: the fixture now runs against a closed tool
PATH, soghis genuinely absent in the no-CLI case. Verified on this Ubuntu 24.04 runner — the suite passes 11/11 (previously 10/11 with the real/usr/bin/ghrunning), and removing thehas gh || failguard frominstall.shstill fails the no-gh case, so the assertion remains fail-able.
Reviewed changes (delta since the review of c674a5c)
- Closed the installer fixture
PATH—linuxDownloadFixturebuilds a dedicatedbindirectory and symlinks exactly the tools the installer invokes (awk,cat,chmod,cp,grep,mkdir,mktemp,rm,rmdir, plus the first availablesha256sum/shasum), so the Ubuntu runner's preinstalled/usr/bin/ghcan no longer leak into theincludeGh: falsecase. - Invoked
/bin/shby absolute path — every fixtureexecFileAsync("sh", …)call now uses the known/bin/sh, since the closedPATHno longer resolvesshthrough Node's process launcher. - Recorded the fixture lessons — two troubleshooting entries document the host-dependent missing-tool fixture and the closed-
PATHshell-resolution consequence.
DeepSeek Flash | 𝕏
There was a problem hiding this comment.
Important
The new SELinux regression test cannot pass for the reason it is named for: its error conflict expectation comes from an unrelated uid/gid mismatch in the fixture, while the actual security-label denial path returns error io_failed. Details inline.
Reviewed changes
- Bounded the Linux subreaper reap —
cleanup_groupnow reaps withWNOHANGunder the shared 1 s deadline, andnative-c-build-core.test.mjspins the bounded shape. - Registered the six platform-policy suites —
test:linux-contractsnow runs all six files; 99 TypeScript and 153 Node contract tests pass locally. - Deferred portal-dictation teardown —
applyNowkeeps the portal bound until the replacement chord registers, and a supersededDictationHoldSettingsTransactionbind disables the portal it opened. - Accepted empty portal trigger text and gated hold setup — an empty
trigger_descriptionbecomesnull, andlinuxDictationHoldSetupAvailable()requires a discoverable.desktopentry. - Timezone-independent journal evidence — the Fedora diagnostic probe captures
@$(date +%s)forjournalctl --since, pinned by a new fixture test. - Docs and plan bookkeeping — the desktop-entry requirement and fail-closed SELinux metadata limit are documented, and Phase 19 records the remediation.
DeepSeek Flash | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — this run covered the single commit 4747cf9 since the prior pullfrog review, which repairs the SELinux metadata regression test and adds the denied-capability fail-closed case.
- Fixed the SELinux metadata fixture ownership —
startHelpernow accepts agid, and both metadata tests spawn the helper as65534:65534, so the staged file matches the source and the test reaches the xattr path instead of failing on an unrelated uid/gid mismatch. - Asserted the permitted label-copy path — the renamed SELinux test now expects
committed, verifies the replacement bytes, the preserved:bin_t:label, andfinalize, matching the Fedora 44 Enforcing VM observation. - Added the fail-closed capability case — a new test puts
cap_net_bind_service=epon the source and assertscommitreturnserror io_failedwhile the original bytes and capability survive, so thecopy_supported_xattrsdenial path now has a fail-able regression test. - Corrected the behavior docs —
docs/linux.md, the parity plan's Phase 19 validation text, and a papercut entry now describe label preservation as policy-dependent and record the denied-capability result.
DeepSeek Flash | 𝕏

Summary
Linux now carries the current desktop surface, native helpers, package/update contracts, and x64/arm64 AppImage, DEB, and RPM delivery. The branch adds Fedora GNOME/SELinux evidence and staged security prerequisites for future Computer Use admission while keeping that capability disabled until the remaining production boundary is proven.
The release path now attests verified Linux packages and update feeds. A manual Linux-installer workflow builds and verifies both architectures without publishing a release. The checked-in POSIX installer selects the matching macOS or Linux artifact, verifies checksums and platform identity/provenance, preserves package-manager ownership, and uses rollback-safe private staging. The accepted release publisher includes the installer and its checksum.
Current capability boundary
mainafter merge and needs a subsequent accepted release for Linux assets. Intel macOS also needs a signed/notarized x64 DMG.Validation
npm run test— complete repository suite passednpm run test:branding— 43 TypeScript tests and 41 Node tests passednpm run test:linux-contracts— 152 passed, 2 expected platform skipsgit diff --checkpassedExact-head hosted validation is tracked by the current PR checks.