アーキテクチャ
SwiftUI アプリ、同梱の Python ヘルパー、スナップショットストア、エクスポーターがどのように連携するか。
プロセスは 2 つでジョブは一度に 1 つ
アプリはネイティブの SwiftUI プログラムです(Apple silicon 上の macOS 27 以降のみを対象とし、必要な箇所では AppKit アダプターを使います)。ジオメトリの処理はすべて、短時間だけ動作する別の Python ヘルパープロセスで行われます。そのため UI の応答性が保たれ、エンジンがクラッシュやタイムアウトを起こしてもアプリが巻き込まれることはありません。
| 項目 | 方針 |
|---|---|
| ネイティブアプリ | SwiftUI。ファイルパネルとドロップ連携には AppKit アダプター |
| ジオメトリ | engine/(numpy、scipy、trimesh、shapely/GEOS を使用) |
| プロセス境界 | ジョブごとに 1 つのワーカープロセス。ジョブは逐次実行 |
| ワーカーの配布 | PyInstaller で固めた arm64 の Python ヘルパーを、アプリバンドルに埋め込み |
| 配布形態 | Mac App Store 外で配布する単体アプリ |
アプリはヘルパーを自身のバンドル内(Contents/)から解決し、明示的な実行ファイル URL と引数配列で起動します(シェルは介しません)。環境変数は最小限で、PATH=/usr/bin:/bin、LANG=en_US.UTF-8、PYTHONNOUSERSITE=1 のみを渡します。システムの Python は使いません。
責務の分担
アプリは、ファイルのアクセス権限、取り込み時のスナップショット、ジョブの状態、プロセスのライフサイクル、ユーザーに見せるエラー、最終的な保存を担当します。ワーカーは、パース、完全な監査、保守的な修復、シリアライズ後のバイト列の検証、そしてジョブ専用のステージングディレクトリ内に候補 STL と詳細な JSON レポートを生成することを担当します。ワーカーは結果の保存先を決めることはなく、元のパスを上書きする権限を与えられることもありません。
データの流れ
スナップショット。
SnapshotStoreがアプリ専有の非公開ルート(モード0700)を作成し、ドロップされたファイルをジョブごとのディレクトリにinput.stl(モード0400)としてコピーします。元ファイルはローカルにある通常の.stlファイルでなければなりません。エイリアス、シンボリックリンク、リモートのファイルは拒否され、ファイルサイズは 64 MiB までに制限されます。また、読み込み中に元ファイルが変更されていないことを再確認します。スナップショットの SHA-256 が記録されます。ワーカーの実行。 アプリは標準入力に JSON リクエストを 1 つ送り、標準出力から改行区切りの JSON イベントを読み取ります。ワーカープロトコルを参照してください。
検証。 結果を受け取ると、アプリはプロセスの終了ステータスを確認し、候補ファイルとレポートの成果物をそれぞれ宣言された SHA-256 とサイズで検証し、非公開の入力スナップショットが改変されていないことを確認します。
確認。 候補を伴う検証済みの
repaired結果だけが「Repair ready」になります。候補は保存されるか、クリアされるか、アプリが終了するまでステージングに残ります。保存していない結果は終了時に失われます。エクスポート。 ユーザーが保存すると、アプリのエクスポーターは候補を保存先ボリューム上の非公開のステージングフォルダにコピーし、バイト列を再検証したうえで、既存の名前をすべて拒否するアトミックなハードリンクで公開します。出力の名前は
<stem>-fixed.stlで(以降-fixed-2、-fixed-3と続きます)、名前の比較は大文字小文字を区別せずに行われます。レポートも同じ方法で<stem>-report.jsonとしてエクスポートできます。保存先のファイルシステムが名前を保持できない場合は、両方の名前が収まるようにステムを末尾から短くし、STL とそのレポートは同じ短縮後のステムを使います。保存を参照してください。
Note
アプリが上書きを行うことはありません。これは CLI の --overwrite とは別の話で、アプリはこのオプションを公開していません。CLI を参照してください。
ジョブの状態
キューには次の状態が表示されます。Queued、Checking、Repairing、Verifying、No repair needed、Checked, review needed、Repair ready、Saving、Saved、Cannot repair safely、Check incomplete、Error、Canceled。変更が不要なファイルでも警告がある場合は「review needed」と表示され、失敗とは区別されて扱われます。
後片付けとプライバシー
キャンセルまたは失敗したジョブのステージングディレクトリは、ワーカーの終了を回収した時点で削除されます。クラッシュで残ったものは、所有権マーカー(ユーザー、UUID、デバイス、inode)とロックされていないリースによってアプリ所有であることが証明できる場合に限り、次回起動時に回収されます。モデルのバイト列はログに記録されず、テレメトリ、実行時のダウンロード、ネットワーク通信は一切ありません。