Files
onyx/project.yml
T
ScarriffleandClaude Opus 5 3da673662f Zwischenablage, Notizen und der Gesichtsvergleich
Drei neue Module nach dem Bauplan von `ShelfProvider`: reine Regeln getrennt vom
Zustand, versionierte Indexdatei, Inhalte in Dateien statt in `UserDefaults` —
was dort steht, liest jedes Programm mit `defaults read` mit.

Die Zwischenablage achtet `ConcealedType`, `TransientType` und
`AutoGeneratedType`. Diese Marken sind eine Verabredung zwischen Programmen und
kein Systemdienst; wer sie missachtet, sammelt fremde Passwörter ein.

Der Gesichtsvergleich stand im Plan als der eine echte Unsicherheitsfaktor. Ein
Spike hat ihn erledigt: `VNGenerateFaceprintRequest` gibt es nicht, aber
`VNGenerateImageFeaturePrintRequest` ist öffentlich, liefert 768 Elemente und
ein Abstandsmaß — Faktor 3,5 Trennschärfe. Kein eigenes CoreML-Modell nötig.

`FaceMatcher` entscheidet über mehrere Posen, mehrere Einzelbilder und eine
Sperre nach Fehlversuchen. Die Schwelle liegt bewusst nicht mittig: ein falsches
Ja ist ein Fremder am entsperrten Rechner, ein falsches Nein nur ein Passwort,
das man ohnehin kennt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 21:06:06 +02:00

190 lines
8.0 KiB
YAML

name: Onyx
options:
bundleIdPrefix: com.scarriffleservices
deploymentTarget:
macOS: "26.0"
createIntermediateGroups: true
groupSortPosition: top
settings:
base:
DEVELOPMENT_TEAM: PP34X97WS3
SWIFT_VERSION: "6.0"
MARKETING_VERSION: "0.1.0"
CURRENT_PROJECT_VERSION: "1"
ENABLE_HARDENED_RUNTIME: YES
# KEIN --deep.
#
# Es überträgt die Entitlements der App auf jede eingebettete Binary. Der
# privilegierte Helfer bekam dadurch application-identifier, weatherkit und
# application-groups verpasst — allesamt eingeschränkte Entitlements, die
# ein Provisioning-Profil verlangen. Ein nacktes Kommandozeilenprogramm kann
# aber keines einbetten, also lehnte AMFI den Start ab:
#
# amfid: OnyxHelper not valid: Code=-413 "No matching profile found"
# taskgated-helper: Disallowing com.scarriffleservices.onyx.helper
# because no eligible provisioning profiles found
#
# Für das ad-hoc signierte MediaRemoteAdapter.framework wird --deep nicht
# gebraucht: dafür ist disable-library-validation da.
SWIFT_STRICT_CONCURRENCY: complete
# Xcode lagert im Debug-Build den Programmcode in eine eigene dylib aus
# (für SwiftUI-Vorschauen). Das Hauptprogramm ist dann nur noch ein Rumpf —
# und TCC ordnet Berechtigungsanfragen dem Rumpf zu, der weder Info.plist
# noch Entitlements trägt. Ergebnis: requestFullAccessToEvents() liefert
# kommentarlos false, ohne dass je ein Dialog erscheint.
ENABLE_DEBUG_DYLIB: NO
packages:
OnyxKit:
path: Packages/OnyxKit
targets:
# Der privilegierte Helfer. Läuft als root und tut genau eine Sache:
# Lüfterdrehzahlen setzen. Kein Netzwerk, keine Oberfläche, kein
# Dateizugriff — je weniger hier steht, desto kleiner die Angriffsfläche.
OnyxHelper:
type: tool
platform: macOS
sources:
- path: OnyxHelper
excludes:
- "*.plist"
dependencies:
- package: OnyxKit
product: OnyxHelperProtocol
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.scarriffleservices.onyx.helper
PRODUCT_NAME: OnyxHelper
CODE_SIGN_STYLE: Automatic
SKIP_INSTALL: YES
# Kommandozeilenprogramme haben kein Bundle. Die Kennung muss deshalb
# in die Binary selbst — sonst signiert codesign sie unter dem
# Dateinamen und die Signaturprüfung zwischen App und Helfer scheitert.
INFOPLIST_FILE: OnyxHelper/Info.plist
CREATE_INFOPLIST_SECTION_IN_BINARY: YES
Onyx:
type: application
platform: macOS
sources:
- path: Onyx
dependencies:
- target: OnyxHelper
embed: false
- package: OnyxKit
product: OnyxCore
- package: OnyxKit
product: OnyxHelperProtocol
- package: OnyxKit
product: OnyxDesign
- package: OnyxKit
product: OnyxNotch
- package: OnyxKit
product: OnyxWidgetKit
- package: OnyxKit
product: OnyxMenuBar
- package: OnyxKit
product: CalendarProvider
- package: OnyxKit
product: WeatherProvider
- package: OnyxKit
product: MediaProvider
- package: OnyxKit
product: MetricsProvider
- package: OnyxKit
product: NetworkProvider
- package: OnyxKit
product: AudioProvider
- package: OnyxKit
product: ShelfProvider
- package: OnyxKit
product: ActivityProvider
- package: OnyxKit
product: ClipboardProvider
- package: OnyxKit
product: NotesProvider
postBuildScripts:
# Der Helfer und seine Plist müssen an genau diese Stellen: SMAppService
# sucht die Plist unter Contents/Library/LaunchDaemons und liest von dort
# den Pfad zum Programm.
- name: Helfer und Launchd-Plist einbetten
script: |
APP="$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH"
mkdir -p "$APP/MacOS" "$APP/Library/LaunchDaemons"
cp "$BUILT_PRODUCTS_DIR/OnyxHelper" "$APP/MacOS/OnyxHelper"
cp "$SRCROOT/OnyxHelper/com.scarriffleservices.onyx.helper.plist" \
"$APP/Library/LaunchDaemons/"
# Der Helfer wird eigenständig signiert — die Signatur der App deckt
# ihn nicht ab, und ohne gültige eigene Signatur lehnt launchd ihn ab.
#
# `-i` ist Pflicht: Xcode signiert Kommandozeilenprogramme sonst mit
# dem Produktnamen ("OnyxHelper") als Bezeichner. Die App prüft aber
# auf com.scarriffleservices.onyx.helper und würde ihren eigenen
# Helfer ablehnen.
# Zeitstempel im Release, keiner im Debug.
#
# Die Notarisierung verlangt einen sicheren Zeitstempel; ohne ihn
# lehnt Apple das Paket ab, und zwar erst nach dem Hochladen. Im
# Debug wäre er nur eine Netzanfrage bei jedem Bauen.
if [ "$CONFIGURATION" = "Release" ]; then
TIMESTAMP="--timestamp"
else
TIMESTAMP="--timestamp=none"
fi
codesign --force --options runtime $TIMESTAMP \
-i com.scarriffleservices.onyx.helper \
--sign "$EXPANDED_CODE_SIGN_IDENTITY" "$APP/MacOS/OnyxHelper"
# Kein Neusignieren der App hier: Xcode signiert sie als letzten
# Schritt, nach diesem Skript. Das repariert das Siegel von selbst
# und legt im Debug-Build auch get-task-allow bei, ohne die im
# Skript nachzubauen wäre — nachgemessen an der Reihenfolge im
# Bauprotokoll (PhaseScriptExecution vor CodeSign Onyx.app).
# Bewusst ohne outputFiles: mit ihnen überspringt Xcode den Schritt,
# solange die Plist unverändert ist — auch wenn sich das Programm oder
# die Signaturvorgaben geändert haben.
# Der MediaRemote-Adapter wird aus dem mitgelieferten Quellcode gebaut,
# nicht als fertige Binary eingecheckt: so ist nachvollziehbar, was da
# läuft, und die Ad-hoc-Signatur passt zum restlichen Bundle.
#
# Er darf NICHT gelinkt werden. Geladen wird er von /usr/bin/perl, einem
# berechtigten Systemprogramm — im eigenen Prozess greift Apples
# Entitlement-Prüfung und es käme gar nichts an.
- name: MediaRemote-Adapter bauen und beilegen
script: |
# Im Release mit der echten Identität signieren: ad-hoc signierte
# Bibliotheken lehnt die Notarisierung ab.
if [ "$CONFIGURATION" = "Release" ]; then
export SIGN_IDENTITY="$EXPANDED_CODE_SIGN_IDENTITY"
fi
OUT="$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/Vendor" \
"$SRCROOT/Scripts/build-mediaremote-adapter.sh"
inputFiles:
- $(SRCROOT)/Scripts/build-mediaremote-adapter.sh
outputFiles:
- $(BUILT_PRODUCTS_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/Vendor/mediaremote-adapter.pl
# Das Menüleistensymbol soll das Glyph aus dem App-Icon zeigen, nicht die
# abgerundete Kachel mit Verlauf. actool kompiliert das .icon-Bündel zu
# .icns und Assets.car und legt nichts Lesbares ins Bundle — und eine
# einzelne Datei daraus lässt sich nicht als Ressource referenzieren.
# Deshalb kopieren statt duplizieren: es bleibt bei einer Quelldatei.
outputFiles:
- $(BUILT_PRODUCTS_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/quartz.svg
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.scarriffleservices.onyx
INFOPLIST_FILE: Onyx/Info.plist
CODE_SIGN_ENTITLEMENTS: Onyx/Onyx.entitlements
CODE_SIGN_STYLE: Automatic
# Kein App-Sandbox: der privilegierte Helper, IOKit und der
# MediaRemote-Adapter sind damit unvereinbar. Der App-Group-Container
# bleibt trotzdem erreichbar — siehe docs/spikes/D-appgroup.md.
ENABLE_APP_SANDBOX: NO
ENABLE_USER_SCRIPT_SANDBOXING: NO
COMBINE_HIDPI_IMAGES: YES
# Icon-Composer-Bündel (Onyx/AppIcon.icon). actool übernimmt daraus
# alle Größen und die Transluzenz-Darstellung von macOS 26.
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon