Skip to content

feat(linux): bring desktop support up to date - #71

Open
sambitcreate wants to merge 246 commits into
mainfrom
feature/linux-desktop-support
Open

feat(linux): bring desktop support up to date#71
sambitcreate wants to merge 246 commits into
mainfrom
feature/linux-desktop-support

Conversation

@sambitcreate

@sambitcreate sambitcreate commented Aug 30, 2026

Copy link
Copy Markdown
Owner

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

  • Ordinary Linux desktop, Telegram, Remote Access, scheduled tasks, providers, workspace tools, native helpers, and package/update behavior are implemented and tested.
  • Dictation uses the validated Linux toggle flow because GNOME currently loses modifier-release events for hold-to-talk.
  • Computer Use remains disabled on Linux. Authenticated production admission, active-generation launch, complete confinement, and the live GNOME capture/input driver remain separate work.
  • The current public v0.40.0 release predates Linux artifacts and includes only the arm64 macOS build. The new install command becomes usable from main after 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 passed
  • npm run test:branding — 43 TypeScript tests and 41 Node tests passed
  • npm run test:linux-contracts — 152 passed, 2 expected platform skips
  • installer/publisher focused suite — 16 passed, including checksum/provenance, hostile destination, rollback failure, and signal interruption cases
  • focused shortcut, portal, native runner, and Electron-role suites passed
  • lint, type checking, POSIX shell syntax, workflow YAML parse, and git diff --check passed
  • Fedora 44 SELinux Enforcing root regressions preserved a permitted non-default label and failed closed with original bytes/capability intact when capability copying was denied
  • signed public v0.40.0 arm64 DMG passed download, checksum, Developer ID, Gatekeeper, bundle, version, team, and architecture verification
  • OrbStack Ubuntu x64 selected the exact DEB artifact
  • each implementation phase passed two independent GPT-6 Astra medium reviews after remediation
  • all automated review threads are resolved

Exact-head hosted validation is tracked by the current PR checks.

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.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ 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, the package.json test 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 in test:linux-contracts and a computer-use:linux-host-preflight script) inspects /etc/os-release, /sys/kernel/security/lsm, and /sys/fs/selinux/enforce with a bounded non-shell reader, emits derived reason codes only, and pins acceptanceEstablished/trustPolicyVerified/computerUseEnabled to false.
  • Providers action group wraps at narrow widthsmax-w-full on the header action group lets the existing flex-wrap absorb the 17px overflow at 390px content width instead of forcing horizontal scroll.
  • E2E relaunch mutation hookAidenE2e.relaunch(beforeLaunch?) runs fixture mutations only after closeAiden has 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.

Pullfrog  | Fix it ➔View workflow run | Using DeepSeek Flash𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ 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-rpm job's dnf line now installs dbus-daemon, which ships /usr/bin/dbus-run-session on Fedora 44 (verified against the Fedora 44 package file list), so test:global-shortcuts-portal can start its private session bus instead of failing before the RPM acceptance steps.
  • CI policy pincheck-ci-policy.test.mjs gains an assertion that the Fedora job installs dbus-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-session diagnosis.

The hosted Fedora job on this head is the remaining live validation of the prerequisite.

Pullfrog  | Fix it ➔View workflow run | Using DeepSeek Flash𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 returns unavailable on GNOME sessions, keeping toggle dictation instead of risking a lost release edge; the protocol suite gains a gnome-running case.
  • Portal app registration — the helper registers the fixed com.sambitcreate.aiden-agent app id with org.freedesktop.host.portal.Registry before CreateSession, treating UnknownInterface/UnknownMethod as legacy portals; the mock and protocol tests gain registry-rejected, registry-unknown-interface, and registry-unknown-method cases.
  • 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.mjs and cleanup.test.mjs are registered in test: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-108 still 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:131 writes hardened-holder-check.txt unconditionally and verify.mjs:17 asserts its constant content, while run.sh:144 writes restored-holder-context.txt that 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.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using DeepSeek Flash𝕏

Comment thread native/global-shortcuts-portal/main.c

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ 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 probedelegation.c adds an SCM_RIGHTS receiver and a fork + explicit setcon inherited-descriptor child; run.sh drives both through bounded transient systemd units, and verify.mjs now requires successful token-read baselines, exact receiver PID/context and private-file fd { use } AVCs, removal of the stock unconfined_t → aiden_boundary_probe_t:fd use allow, and restoration of both cases.
  • Cleanup coveragecleanup.sh stops an outstanding delegation unit and reaps the receiver before UID removal; cleanup.test.mjs exercises receiver-wait and systemctl-stop failures.
  • Cua driver gap audit — a new docs/plans/linux-cua-driver-gap-audit.md records the pinned driver's Linux artifact hashes, the Wayland opt-in gate, the Shell 45–48 extension compatibility gap, the unauthenticated org.cua.WinRects session-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/use finding are recorded.

Pullfrog  | Fix it ➔View workflow run | Using DeepSeek Flash𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ 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-contracts and pass, and the open findings from earlier reviews remain unchanged in their threads (the package.json edit 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 and bin_t/shell_exec_t execs 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 residual execute_no_trans or outsider transition.
  • Covered the verifier and cleanup adversariallyverify.mjs rejects 17 mutated evidence shapes (missing roles, wrong UIDs, sandbox flags, wrong attack outcomes, remaining allows) and cleanup.sh with cleanup.test.mjs proves 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, Fedora domtrans_pattern, NNP-transition, and GNOME-scope-migration observations, with production Computer Use explicitly still disabled.

Pullfrog  | Fix it ➔View workflow run | Using DeepSeek Flash𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ 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-contracts and pass locally (full suite green, scoped lint clean), and the seven open findings from earlier reviews are unchanged: this commit touches no native/ helper, shortcut.ts, linux-dictation-portal.ts, or docs/linux.md, and the package.json edit appends only the two new probe tests to test: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 has fixture.c create generic and aiden_ipc_protected_socket_t-labeled socketpairs, delegate one endpoint over an ordinary unconfined listener with SCM_RIGHTS, and report both sides' UID/PID/context/socket label/roundtrip outcomes.
  • One-line deny overlay with retained creator fd useaiden_ipc_probe_deny.cil subtracts only unconfined_domain_type → aiden_ipc_protected_socket_t:unix_stream_socket { read write }, while the base policy keeps unconfined_t → aiden_ipc_sender_t:fd use and generic read/write, so a coarse creator-domain denial cannot explain the protected result.
  • Evidence verifier and adversarial coverageverify.mjs requires the generic roundtrip and creator fd use to survive under the overlay, the protected endpoint to be omitted with MSG_CTRUNC and no descriptor (errno 0), an exact enforcing receiver socket-object AVC, effective-allow removal via sesearch, and full restoration; 13 verify.test.mjs/cleanup.test.mjs cases mutate the evidence and inject teardown failures, and both files are appended to test:linux-contracts.
  • Plan bookkeeping — the parity plan records Phase 13 (including the live SO_PEERCRED/SO_PEERPIDFD creator-vs-holder observation and the explicitly unproved boundaries) and the plans index updates its status line.

Pullfrog  | Fix it ➔View workflow run | Using DeepSeek Flash𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ 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.h experiment 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 with MSG_CTRUNC.
  • Extended the deny overlay to the protected object — the CIL subtracts unix_stream_socket { read write } on ..._protected_t from every domain except main and sender while retaining creator fd use, generic read/write, and getopt label inspection, and restricts entry into the sender domain to the root-managed unit.
  • Added the IPC verifier and adversarial coverageverify-ipc.mjs requires four same-creator cells, cross-checks native receiver PIDs/contexts/socket labels against the root process receipt, and matches an exact enforcing unix_stream_socket AVC 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 cleanuprun.sh compiles the fixture with GCC, starts the separate sender unit before Electron, pins audit capture to a tail offset with an inode check, and cleanup.sh/stop-processes.py stop 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 --version check.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using DeepSeek Flash𝕏

Comment thread scripts/linux-electron-role-probe/run.sh Outdated

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ 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 (tag v4.2.2), the gh attestation verify manual, 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 mainlinux-release now requires github.ref == 'refs/heads/main' and overrides the inherited contents: write with contents: read, id-token: write, and attestations: write; the dependent publish job cannot ship a release from another ref because publish-github-release.sh requires 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, and latest-linux*.yml subjects with create-storage-record and push-to-registry disabled, so no registry or artifact-metadata permission is needed.
  • Pinned the policy in testscheck-ci-policy.test.mjs gains 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 workflowdocs/releasing.md explains the main-only attestation and gives a gh attestation verify command 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.

Pullfrog  | Fix it ➔View workflow run | Using DeepSeek Flash𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ 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 utilityscripts/linux-payload-inventory.mjs computes 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 mode 0600.
  • Covered the utility adversariallyscripts/linux-payload-inventory.test.mjs adds 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.md records 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.

Pullfrog  | Fix it ➔View workflow run | Using DeepSeek Flash𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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 stagernative/linux-managed-payload is a new Linux-only Rust CLI that requires host root and SELinux enforcing, accepts only a protected local-staging-only approval bound to the exact inventory-file SHA-256, validates the Phase 16 inventory schema, and pins source, store, and input paths with openat2 (BENEATH|NO_SYMLINKS|NO_MAGICLINKS|NO_XDEV) plus O_PATH classification.
  • 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 with renameat2(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 installs libselinux-devel plus cargo/rust, and a new check-ci-policy test 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.

Pullfrog  | Fix it ➔View workflow run | Using DeepSeek Flash𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.sh selects 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 verify provenance 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.yml is a manual, non-publishing workflow_dispatch job that builds, verifies, and uploads x64 and arm64 AppImage/deb/rpm artifacts plus SHA256SUMS and install.sh, with contents: read only.
  • Wired the installer into the releasepublish-github-release.sh now requires an executable install.sh, copies it into the distribution directory, and adds it to SHA256SUMS and the release asset list; publish-github-release.test.mjs pins the new asset.
  • Added focused installer testsscripts/install.test.mjs covers artifact selection (including Rosetta), option/version rejection, checksum and provenance gates, AppImage staging and hostile destinations, and macOS rollback arming, and is registered in test: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?

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using DeepSeek Flash𝕏

Comment thread scripts/install.test.mjs

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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, so gh is 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/gh running), and removing the has gh || fail guard from install.sh still fails the no-gh case, so the assertion remains fail-able.

Reviewed changes (delta since the review of c674a5c)

  • Closed the installer fixture PATHlinuxDownloadFixture builds a dedicated bin directory and symlinks exactly the tools the installer invokes (awk, cat, chmod, cp, grep, mkdir, mktemp, rm, rmdir, plus the first available sha256sum/shasum), so the Ubuntu runner's preinstalled /usr/bin/gh can no longer leak into the includeGh: false case.
  • Invoked /bin/sh by absolute path — every fixture execFileAsync("sh", …) call now uses the known /bin/sh, since the closed PATH no longer resolves sh through Node's process launcher.
  • Recorded the fixture lessons — two troubleshooting entries document the host-dependent missing-tool fixture and the closed-PATH shell-resolution consequence.

Pullfrog  | Fix it ➔View workflow run | Using DeepSeek Flash𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 reapcleanup_group now reaps with WNOHANG under the shared 1 s deadline, and native-c-build-core.test.mjs pins the bounded shape.
  • Registered the six platform-policy suitestest:linux-contracts now runs all six files; 99 TypeScript and 153 Node contract tests pass locally.
  • Deferred portal-dictation teardownapplyNow keeps the portal bound until the replacement chord registers, and a superseded DictationHoldSettingsTransaction bind disables the portal it opened.
  • Accepted empty portal trigger text and gated hold setup — an empty trigger_description becomes null, and linuxDictationHoldSetupAvailable() requires a discoverable .desktop entry.
  • Timezone-independent journal evidence — the Fedora diagnostic probe captures @$(date +%s) for journalctl --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.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using DeepSeek Flash𝕏

Comment thread scripts/subagent-file-mutator.test.mjs Outdated

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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 ownershipstartHelper now accepts a gid, and both metadata tests spawn the helper as 65534: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, and finalize, matching the Fedora 44 Enforcing VM observation.
  • Added the fail-closed capability case — a new test puts cap_net_bind_service=ep on the source and asserts commit returns error io_failed while the original bytes and capability survive, so the copy_supported_xattrs denial path now has a fail-able regression test.
  • Corrected the behavior docsdocs/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.

Pullfrog  | View workflow run | Using DeepSeek Flash𝕏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants