/Users/ar/Projects/PrivateVoice/03-O./Users/ar/Projects/PrivateVoice/03-O/C1.source/privatevoice.src.2.2.2 build20260703.0335, restoring reviewed 2.2.1 fixes into the current active source and producing four real-user test candidate packages.enabled.codebase-memory-mcp 0.8.1.Users-ar-Projects-PrivateVoice-03-O..codebase-memory/artifact.json must record project Users-ar-Projects-PrivateVoice-03-O before each freeze / release package..codebase-memory/graph.db.zst; metadata: .codebase-memory/artifact.json./Users/ar/Projects/PrivateVoice/03-O.codebase-memory-mcp cli index_repository '{"repo_path":"/Users/ar/Projects/PrivateVoice/03-O"}'.indexed_at, commit, node count, and edge count are recorded in .codebase-memory/artifact.json..git, K3.运营与发布资料/legacy-运营资料/PrivateVoice-26.0604上架, K3.运营与发布资料/legacy-运营资料/运营文档, C1.source/privatevoice-2.2.1-recovered.src, C1.source/privatevoice.src/frontend/dist, C1.source/privatevoice.src/frontend/node_modules.codebase-memory-mcp cli search_graph '{"project":"Users-ar-Projects-PrivateVoice-03-O","query":"model registry","limit":5}'.CODEGRAPH.md..codebase-memory/ before each source freeze, version freeze, formal rollback-capable test package, or release package; daily Coder work-in-progress changes do not force a refresh..codebase-memory/artifact.json path, indexed commit, freeze commit, and whether the two commits match or differ only by .codebase-memory/ artifact updates.C1.source/privatevoice.src/main.go: process startup, data migration, logger, single-instance guard. Unix single-instance locking starts from the existing temp lock path, but falls back to the app support directory when sandbox runtime denies temp lock access; a genuinely held temp lock remains authoritative and must not be bypassed.C1.source/privatevoice.src/app.go: Wails app wiring, settings window, tray, recorder, hotkey loop, ASR init, paste orchestration.C1.source/privatevoice.src/embed.go: embeds frontend assets and app/tray icons.C1.source/privatevoice.src/frontend/package.json / package-lock.json: frontend dependency graph. @wailsio/runtime is pinned to 3.0.0-alpha.79; App Store / release candidate preparation must not use latest or a lockfile / node_modules version drift.C1.source/privatevoice.src/internal/model/profile.go: model and language IDs, model profile shape, install status types.C1.source/privatevoice.src/internal/model/registry.go: language profile order, model profiles, language profiles, and normalization. Runtime model download URLs are part of the App Store / privacy evidence chain and must remain HTTPS-only; internal/model/model_test.go guards this invariant.C1.source/privatevoice.src/internal/modelselection/selection.go: resolves current language and model, including manual-model fallback.yue-HK, displayed as 粤语.sensevoice-yue-2025-09-09.LanguageParam="yue".C1.source/privatevoice.src/internal/audio/recorder.go; recorder state is prepared under Recorder.mu, but malgo.Device.Start() runs after releasing that mutex so miniaudio capture callbacks can enter onData() and fill PCM during device startup. On macOS, C1.source/privatevoice.src/internal/audio/microphone_darwin.go preflights / requests microphone authorization before native device initialization; denied / restricted microphone state returns audio.ErrMicrophonePermission and does not enter initDevice / native Start(). Start() registers a cancellable start intent before microphone authorization, so Stop() / StopAndGetSamples() during a pending TCC request is preserved and prevents late-granted authorization from continuing into native init/start. A separate recorder lifecycle lock keeps Close() from releasing the native context while Start() is using it. If Stop() / StopAndGetSamples() is called while native Start() is still in flight, or after Start() has entered but before a device is published, it snapshots buffered PCM immediately, records the stop intent, and cleans up the initialized / started device when the startup path returns. Native device startup logs Audio device initialized; starting native device, emits a 2s pending diagnostic if ma_device_start() does not return, and logs Native audio device start returned before Recording started.C1.source/privatevoice.src/internal/hotkey/hotkey_darwin.goC1.source/privatevoice.src/internal/hotkey/hotkey_windows.goC1.source/privatevoice.src/internal/hotkey/hotkey.go; R222 maps 0x5C to macOS R-⌘ and Windows R-Win.R-⌘ / L-⌘ polling logs include HID physical state, CombinedSession physical state, event-tap tracked state, recent fallback state, aggregate modifier flag state, event flags, tap startup / disabled counters and the selected source. Side-specific hotkeys only accept reliable side-specific sources (physicalHID, physicalCombined, eventTap, recent). aggregateCommandFlag is diagnostic-only because macOS aggregate Command flags cannot distinguish left vs right Command.C1.source/privatevoice.src/app.go; hold pre-capture marks pending state and schedules a cancellable activation timer on initial key-down, while recorder startup runs outside the app mutex so slow audio device startup cannot delay holdActivationDelay confirmation. Physical modifier keys that emit no repeated key-down event still enter recording; release-before-confirm and combination-key detection cancel pending pre-capture. Normal release waits for startup-period PCM before StopAndGetSamples -> ASR -> text output when native recorder startup is still in flight; if PCM never arrives before the bounded wait, it stops without ASR and reports an audio-not-ready failure instead of a false no_voice. Escape / combination cancellation while startup is blocked remains cancel-only and must not enter ASR.C1.source/privatevoice.src/internal/config/config.go: first generated config uses hold; default hotkey is build-scoped. Non-App-Store builds keep the R222 platform default (0x5C on macOS / Windows), Windows keeps R-Win, and darwin && appstore first generated config uses HotkeyVK=0 to represent "trigger key not set". Existing config files load through a legacy-safe fallback so missing HotkeyVK does not inherit the R222 new default.C1.source/privatevoice.src/internal/config/default_hotkey_appstore_darwin.go and default_hotkey_default.go: build-tag seam for the AX / MAS unset-default policy.C1.source/privatevoice.src/internal/input/paste_darwin.goC1.source/privatevoice.src/internal/input/paste_windows.goC1.source/privatevoice.src/internal/textoutput/: output router after ASR post-processing and user dictionary application.internal/input.Paster path through router_default.go, preserving paste then type fallback behavior.darwin && appstore builds use internal/axinput for Accessibility focused-element direct insert and treat AXValue replacement plus write-after-readback verification as the only success condition. If the system-wide focused element is unavailable, the driver retries through the system focused application and the frontmost application accessibility element before reporting target=unknown. Direct-insert failure diagnostics are logged only as generalized categories and AX numeric error codes, never transcript, target, method, message, window title, or document title.textoutput.Result and expose clipboard fallback through services.TextOutputService; fallback does not auto-paste by default. When CopyToClipboard=true and the failed AX target is safe for fallback, the appstore route writes the recognized text to the pasteboard for manual paste while still reporting direct output failure; known Terminal, iTerm, Warp, shell, console, or terminal-role targets remain blocked so fallback operations cannot modify known non-writable command-line windows. target=unknown can still expose explicit clipboard fallback because it only writes the pasteboard and does not modify the focused app. AX-10DT adds a default-off AutoPasteExperiment flag for darwin && appstore: when explicitly enabled, the app captures a frontmost app identity at recognition pipeline start, then the router re-reads the current frontmost identity before any pasteboard write; if the identity is unavailable, changed, or terminal/console-like, the automatic experiment is cancelled before touching the pasteboard. Safe automatic experiment writes verify the pasteboard before sending exactly one synthetic Cmd+V. When CopyToClipboard=false, the experiment uses PrepareClipboardFallback / RestoreClipboardFallback token semantics instead of a tokenless write, so changed-clipboard restore rules stay intact. This experiment is not the default direct-insert path and is tracked by clipboard_auto_paste_experiment, not directInserted=true. The macOS AX fallback driver declares NSPasteboardTypeString before writing and verifies pasteboard writes by reading back the requested string before returning success or a restore token; write / clear failures return a failed result and are logged only as generalized status, booleans, token presence, and text length.C1.source/privatevoice.src/frontend/src/components/settings/GeneralPage.svelte and C1.source/privatevoice.src/frontend/src/components/settings/PermissionsPage.svelte expose production fallback controls through TextOutputFallbackPanel.svelte: refresh latest output status, explicitly prepare clipboard fallback, and restore original clipboard without overwriting a user-changed clipboard. Fallback UI shows only generalized status and action messages, never transcript text, target, method, message, window title, or document title. app.go emits text-output:updated after each production output result so an already-mounted Settings page refreshes pending fallback state without auto-pasting or exposing transcript, target, method, message, window title, or document title text in the event payload or default production output logs. Frontend fallback controls key their prepared-token state by the backend result createdAt and poll latest status while mounted so a missed Wails event cannot leave the button bound to an old prepared token; each new output clears the old token / prepared state so the user can prepare the latest retained text, while restore / skip-restore messages remain visible for the same output result.CGEventPost, automatic Cmd+V, system input-method installation, release/tag/manifest actions.C1.source/privatevoice.src/internal/engine/engine_darwin.goC1.source/privatevoice.src/internal/engine/engine_windows.goC1.source/privatevoice.src/internal/engine/engine_linux.goC1.source/privatevoice.src/internal/overlay/overlay_darwin.goC1.source/privatevoice.src/internal/overlay/overlay_windows.gohotkeyReadyText in C1.source/privatevoice.src/app.go; unset trigger keys (HotkeyVK=0 / empty display name) must show 触发键未设置 instead of concatenating an empty key into hold/tap prompts.SenseVoice only.model.IsModelSupportedInCurrentBuild.windows_preview_unsupported.C1.source/privatevoice.src/scripts/build-windows-preview.sh.C1.source/privatevoice.src/scripts/verify-windows-qa-evidence.sh.C1.source/privatevoice.src/scripts/build-local-macos.sh.C1.source/privatevoice.src/scripts/build-appstore-macos.sh; the appstore-local bundle must remove the sherpa-onnx Go module cache LC_RPATH from the main executable so dyld resolves @rpath/libsherpa-onnx-c-api.dylib and @rpath/libonnxruntime.*.dylib from Contents/Frameworks before any external module-cache path. Because hardened runtime library validation rejects self-signed local dylibs without a real Team ID, this script prefers an available Apple Development: identity for appstore-local QA signing, with PRIVATEVOICE_APPSTORE_LOCAL_SIGN_IDENTITY / PRIVATEVOICE_LOCAL_SIGN_IDENTITY as explicit overrides. For local QA App refresh without DMG / ZIP / package output, run it with PRIVATEVOICE_APPSTORE_LOCAL_APP_ONLY=1.PRIVATEVOICE_APP_VERSION and PRIVATEVOICE_APP_BUILD. The override is applied to both Go binary version metadata via -ldflags -X main.appVersion/main.appBuild and the assembled bundle Info.plist (CFBundleShortVersionString / CFBundleVersion), so MAS proof candidates can use 2.2.3 plus a fresh build without prematurely changing the default source Info.plist.C1.source/privatevoice.src/build/darwin/PrivacyInfo.xcprivacy and copy it to Contents/Resources/PrivacyInfo.xcprivacy. The current manifest declares NSPrivacyAccessedAPICategoryFileTimestamp / C617.1 for app-owned and user-selected file metadata checks used by model, log, history, diagnostics, updater, path, and startup workflows; do not add required-reason categories without source or bundle evidence.C1.source/privatevoice.src/scripts/build-macappstore-pkg-macos.sh; before signing it resolves the requested app signing identity to a concrete SHA1 leaf fingerprint and verifies that fingerprint is present in the embedded provisioning profile DeveloperCertificates. This prevents building ASC candidates whose app executable or nested dylibs are signed by a same-named but profile-mismatched certificate.C1.source/privatevoice.src/scripts/build-local-macos-universal.sh.C1.source/privatevoice.src/scripts/build-local-macos-monterey.sh.C1.source/privatevoice.src/scripts/build-release-macos.sh.LSMinimumSystemVersion=14.0.Run from C1.source/privatevoice.src:
npm --prefix frontend ls --omit=dev --all
npm --prefix frontend run build
go test ./...
go test -tags appstore ./internal/textoutput ./services
./scripts/verify-ax-output-boundary.sh
GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ go test -exec=/usr/bin/true ./...
./scripts/build-windows-preview.sh
./scripts/build-local-macos.sh arm64
./scripts/build-local-macos.sh x86_64
./scripts/build-local-macos-universal.sh
./scripts/verify-windows-qa-evidence.sh /path/to/qa-evidence-YYYYMMDD-HHMMSS.zip