uttrflow / uttrflow/uttrflow-swift

The offline audit leaves out the clipboard, history, dictionary and AI suggestions modules, and its binary check sees only URLSession

Open
#665 0 comments 0 reactions 0 assignees View on GitHub
area:build area:general enhancement P2
Dominant language
Swift
Stars
4
Forks
17
Avg merge
3h 32m
Merged PRs (30d)
277

Description

## What happens

`SECURITY.md` makes this promise: dictation never touches the network once the model is on disk, and "the clipboard, history, dictionary and snippets must never leave the Mac". It names `Scripts/offline_audit.sh` as the assertion. The script covers less than that:

- **Modules.** The source check lists only `UttrflowCore UttrflowAudio UttrflowSpeech UttrflowAI UttrflowContext UttrflowInput UttrflowPipeline` (`Scripts/offline_audit.sh:47-50`). It omits these, so a `URLSession` added to any of them passes:
- `UttrflowClipboard`, `UttrflowHistory` and `UttrflowSettings`;
- `UttrflowDictionary`, which is on the dictation path because `UttrflowSpeech` and `UttrflowAI` depend on it;
- `UttrflowPredict`, `UttrflowPredictStore` and `UttrflowPredictCapture`, which read typed text;
- `UttrflowUX` and `UttrflowLocalModel`.
- **Patterns.** `NETWORK_PATTERN` (`:55`) does not match `Data(contentsOf:)` / `String(contentsOf:)` on a remote URL, `Network.framework` C calls (`nw_connection_*`), or system download APIs. One example is `AssetInventory.assetInstallationRequest(...).downloadAndInstall()` in `Sources/UttrflowSpeech/AppleSpeechBackend.swift:37-38`, a download on the speech path that no check sees.
- **Binary check.**
- It counts undefined `urlsession` symbols only (`:312-321`), so `NWConnection` / `NWListener` (used in `Sources/UttrflowAccount/LoopbackListener+System.swift`) and socket calls are invisible to it.
- It allowlists both `UttrflowSpeech` and the app target `Uttrflow` (`:317`), so the per-module check says nothing about either.
- It inspects `.build/*.build` objects, not the embedded Sparkle framework.
- **No build.** With no built binary, the script prints a note and passes (`:267-268`).

## Why it matters

The offline promise is the claim `SECURITY.md` calls the product's security boundary, and `make verify` is where contributors learn they broke it. Today a pull request that adds a network call to the clipboard or suggestions code passes every gate.

## Acceptance criteria

- The source check covers every module that handles user text (clipboard, history, dictionary, snippets, settings, the suggestion modules and UX), with the account, updater and model-download files as the named exceptions.
- The pattern also matches `contentsOf:` with a non-file URL, `nw_` calls and `downloadAndInstall`, or the check is inverted: an allowlist of files that may import `Foundation` networking types.
- The binary check looks for Network.framework and socket symbols as well as URLSession, and does not allowlist the app target wholesale.
- In CI (`make verify`), a missing binary is a failure rather than a note.
- `Docs/offline.md` lists what is checked.

Contributor guide

Open the contributing guide

Research direction

Start with SECURITY.md and Scripts/offline_audit.sh, especially the module list, source-pattern check, binary check, and missing-binary path. Inspect the named Swift files and targets, then run make verify to understand the current assertions. Done means all acceptance criteria are covered, Docs/offline.md describes the checks, and CI fails when the binary is missing.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, shell, swift
Domain
ci-cd, documentation, security
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.