e5835a4(前回レポート)。本サイクルは 5468afb までを評価本レポートは現在のmainを評価します。SonarQubeとOpenSSFのスコアはリポジトリ内容からの推定で、公式scannerは実行していません。penetration testも対象外です。macOSエージェントの実行コストは1台での実測であり、その旨を明示しています。
総合グレード: A(前回: A)
コードにCritical/Highの不具合は見つかりませんでした。
本レポートは当初、プロセスの後退を理由にA−で公開しました。v2.0.0・v2.0.1・v2.0.2のいずれにも署名済み資産が1つも付いていなかったためです。 署名パイプラインは存在し、文書化され、わずか1サイクル前に独立検証も済ませていました。単に実行されなかっただけです。前回・前々回のレポートが揃って「最も強いサプライチェーン特性」と呼んだ項目で、です。
これは是正しました。 v2.0.2には4点セット(アーカイブ、チェックサム、detached signature、公開鍵)が揃っています。v2.0.2タグから同じKMS鍵・同じ手順で生成し、ローカルの生成物ではなくダウンロードした成果物に対して検証しました。グレードはAに戻ります。この欠落は消さずに記録します。2026-08-22より前に2.0.xをダウンロードした人には、検証する手段が何もありませんでした。 これは「パイプラインに何ができるか」ではなく「何が出荷されたか」の事実です。v2.0.0とv2.0.1は資産なしのままで、2.0.2に置き換えられています。
それ以外は前進しています。過去最大のサイクルで、58件のPR(#213–#270)がマージされ、製品は2.0.0を経て2.0.2へ、macOSエージェントは0.2.x台から8回の公開リリースを経て0.5.29へ進みました。エージェントは「動く試作」から「起動したまま放置できるもの」になりました — ローカルで照合する脅威インテリジェンス、時間集計から描く地球儀・sankey・タイムライン、インストール前にパッケージを検証する更新経路、収集が止まったら止まったと言う自己監視、そして2度のプロファイリングを経て、常時起動を利用者が悩まなくて済む程度の待機コストです。
本サイクルの中心はエージェントの信頼性の作業です。 無人で動くことが目的のエージェントが、実環境で1日後にCPUコアの41%と325MBを消費していました。原因は個別に切り分け可能で、個別に修正しました — windowを持たないaccessory appでmacOSのApp Nappがrun-loopのTimerを絞ること、SwiftUI TimelineViewが毎フレーム配下全体を再レイアウトすること、OSSystemExtensionRequestが保持されず応答が返らないこと、windowがcloseしても解放されないこと。本レポート執筆時点の実測で、ホストプロセスは2時間2分経過で0.0% CPU・126MB、システム拡張は3時間37分経過で1.7%・18MBで待機しています。
本レポートには新しい節を追加しました: §6「Macアプリケーションとしてのエージェント評価」です。Swiftのソースとしてではなく、利用者がインストールし、システム拡張を許可し、起動しっぱなしにするアプリケーションとして評価します。カーネルに近い拡張を入れてもらうプライバシーツールは、Apple自身の基準 — notarization、sandbox、最小権限のentitlement、正直なプライバシー表明、アクセシビリティ、ローカライズ、電力 — で信頼を得る必要があります。結果は良好ですが、明確な欠落が1つあります。プライバシーマニフェストがありません。
| 評価軸 | 結果 | 判定 |
|---|---|---|
| OWASP ASVS Level 1 | 14領域中14領域が適合または緩和済み | 完全適合 |
| OpenSSF Scorecard | 推定約9.4/10 | Signed-Releasesを回復。v2.0.2が署名資産を持ち、ダウンロードして検証済み |
| ISO/IEC 25010 | 平均9.1/10 | 高品質 |
| Node.js Best Practices | 47/50 | 優秀 |
| SonarQube相当gate | 合格、coverageはA | High以上のblockerなし |
| macOSアプリ品質(§6、新規) | 45/50 | 良好。診断情報が欠落 |
e5835a4)以降の変更58件のPR(#213–#270)がマージされました。計測コミット以降に#271が加わっています。PRを経ずにmainへ入ったコミットが1件あります。テーマ別に整理します。
| テーマ | 内容 | PR |
|---|---|---|
| エージェントの可視化 | アプリ別sankey、共有期間上のアプリ別タイムライン、位置情報と通信の弧を描く地球儀、それらと並ぶ接続ログの復帰 | #227–#233 |
| エージェントの履歴とコスト | 生ウィンドウ+時間単位の畳み込みによるSQLite履歴。チャートは生行ではなくその集計から描画 | #219, #253, #251 |
| エージェントの脅威インテリジェンス | フィードをローカルで照合、行選択時に一致内容の全体を表示、2つのフォールバックモードを実測して文書化 | #234, #236, #237, #257, #258 |
| エージェントの更新 | 署名付きリリース情報の確認、検証済みパッケージで停止する定期チェック、sandbox下で更新をそもそもインストール可能にするための4件の修正 | #216, #217, #239–#248 |
| エージェントの自己監視 | 記録が止まったことを検知して通知。その後、検知が実際に発火するよう修正し、実機で確認 | #255, #256 |
| エージェントの実行コスト | 監視対象のMac上で最も重いプロセスであることをやめた。常時起動も、開いて眺めることも軽い。keychain読み取りをメインスレッドから外した | #259–#262 |
| 宛先の名前 | アプリケーションが要求した名前をローカル限定で保持、要求時にTLS SNIを読む、エージェント観測の宛先を補強 | #226, #254, #215 |
| データの忠実性 | 終了したフローの実バイト数、ローカルポート不明の観測の保全、再起動後も読める送信待ちキュー | #225, #223, #218 |
| 配布 | インストーラパッケージとしてのビルドと公開、dl.egressview.comの入口、www.egressview.comの製品サイト |
#247, #263–#265, #268–#270 |
Timerを絞るため、定期処理はProcessInfo.beginActivityのスコープ内でバックグラウンドキュー上のDispatchSourceTimerに変更。TimelineViewは毎フレーム配下全体を再レイアウトするため、地球儀は独自のクロックを持つNSViewにし、3/5/15 fpsから選べるようにしました。OSSystemExtensionRequest.propertiesRequestは応答が返らないことがあり、フレームワークはrequestを保持しないため、ヘルスプローブ側で保持し20秒で諦めるようにしました。windowは一度作って持ち続けていたので、必要時に作りcloseで解放するようにしました。メモリが「増えなくなる」のではなく「戻る」のは、最後の1つによるものです。spctl --assessは使えません(spctlがsandboxを継承して失敗する)。これが数バージョンにわたり「アプリ内更新が一切インストールできなかった」原因です。 現在の検証器はcodesignの出力から署名チームIDを読み、実行中のアプリのチームと一致しないパッケージを拒否します。notarizationはインストール時にインストーラ側が独立して強制します。「更新がある」から「インストールされた」までの経路を正しくするのに4回の是正リリースを要しました。各失敗は均さずに記録しています。dl.egressview.comとwww.egressview.comはいずれも、origin access control配下の非公開S3バケットをCloudFrontで配信し、セキュリティヘッダを付け、第三者アセットを一切持ちません。製品サイトは必要な条件(対応ルーターかMac)をREADMEの奥ではなく最初に示します。release-signing/unsigned-releases.jsonに理由付きで記録され、署名済みの2.0.2に置き換えられています。原因には対処済みです。リリースはdraftへアップロードし、リリースページが配信するものを検証してから公開に切り替える1コマンドになり、その後ろに公開時・編集時・週次のワークフローゲートがあります。エージェントの.pkgはAppleによりnotarize・stapleされており、これは実在し独立に検証できる署名ですが、プロジェクト自身のチェックサムやdetached signatureは付いていません。public/js/ai-insights.js(892行)とsrc/history.js(847行)が最大のまま。src/db-migrate.jsは818行、src/routes/agents.jsは707行に増加。npm auditはbetter-sqlite3のamalgamation内部のSQLite CVEを見られません。この盲点は手動確認手順とともに文書化済みです。viewerとして認証します。これはデモの趣旨どおりで、資格情報は公開されず、書き込みは二重に拒否されます。| 確認項目 | 結果 |
|---|---|
| Hub unit test(coverage付き) | 2,188件成功、0件失敗(497 suite) |
V8 coverage(npm run test:coverage、計装対象のサーバサイドツリー) |
line 84.62% / branch 80.00% / function 81.47% |
| CIのcoverage下限 | line 83% / branch 79% / function 80% — 合格 |
| macOSエージェントのSwiftテスト | XCTest 409件(2件skip)+ swift-testing 10件、失敗0 |
| parser fuzz | 30件成功(3 suite) |
| Playwright browser smoke | CI gate合格(単一spec、1,901行) |
| ESLint | 合格 |
| フロントエンドHTML挿入監査 | innerHTML / insertAdjacentHTML 代入 0件 |
| 本番依存のaudit | 脆弱性0件(本番依存 175件) |
| secret scan | 合格。高シグナルのsecretも環境固有のLAN IPも検出なし |
| ASH(Automated Security Helper) | 5 scannerで actionable 0件(bandit / checkov / detect-secrets / npm-audit / semgrep)。suppressed 37件。tool 3.5.7 |
| GitHub ActionsのSHA固定 | 23/23 固定、未固定 0 |
| インストール済みエージェント: Gatekeeper | spctl accepted、source = Notarized Developer ID |
| インストール済みエージェント: hardened runtime | CodeDirectory flags=0x10000(runtime)、secure timestampあり |
| インストール済みエージェント: notarizationチケット | stapler validate 成功 |
| 公開リリースの検証 | v2.0.2がアーカイブ+チェックサム+detached signature+公開鍵を保持。 v2.0.2タグからKMS egressview-release-2026で署名。4つの資産をリリースページからダウンロードし、そこで検証した: shasum -c OK、openssl pkeyutl -verify Signature Verified Successfully、ダウンロードした公開鍵のfingerprintは別系統の資格情報で提供されるDNS TXTのtrust anchorと一致。改竄3ケース(アーカイブ/チェックサム/署名)はいずれも非ゼロ終了。v2.0.0とv2.0.1は資産なしのまま。エージェントの.pkgリリースはnotarize済みパッケージのみ |
| 指標 | 値 |
|---|---|
Hubのソース行数(src, public/js, server.js, mcp-server.js) |
33,787(34,890) |
| Hubのテスト行数(unit / integration / smoke / fuzz / portability) | 36,411(35,011) |
| Test対source比率 | 107.8%(100.3%) |
| macOSエージェントのSwiftソース行数 | 23,058行 / 115ファイル |
| macOSエージェントのSwiftテスト行数 | 7,013行 / 44ファイル |
| unit testファイル | 163(151) |
| integration testファイル | 4 |
| fuzz testファイル | 3(2)、3 suite |
| browser smokeファイル | 1(1,901行) |
| portability testファイル | 1(323行) |
src/配下のソースモジュール |
124(124) |
| pollerモジュール | 16(16) |
| routeモジュール | 19(19) |
| permission matrix上のHTTP route | 111(108) |
| MCP tool | 11 |
| permission matrixのエントリ | 122(119) |
| routeのアクセス種別内訳 | permission 94 / authenticated 1 / agent 6 / public 10 |
| 定義済み権限 | 8(運用権限7 + agent.ingest) |
| ロール | 3(viewer / operator / admin) |
| 本番依存 | 直接13、解決後175 |
docs/配下の文書 |
39(47) |
| DBスキーマバージョン | 16(16) |
| パラメータ化SQLのprepare箇所 | 198(196) |
サーバサイドのvar |
0 |
eval / new Function |
0 |
| TODO/FIXME/HACKマーカー | 0 |
innerHTML / insertAdjacentHTML |
0 |
| CIワークフロー | 4(CI / macOS agent / GitHub Pages / Product site) |
| CIのNode.jsバージョン | 22 / 24 / 26 |
| リリース署名鍵 | 1本(KMS Ed25519)。最後に使用したのはv2.0.2 |
括弧内は前回レポートの値(変化があったもののみ)。docs/の件数減は.ja.mdの統合によるもので、文書が削除されたわけではありません。
判定: 完全適合(14領域中14領域が適合または緩和済み)。
| 領域 | 状態 | 根拠 |
|---|---|---|
| 認証 | Pass | 版付きKDF移行を伴うscrypt、timing-safe比較、256bitセッショントークン、遅延失敗、IP単位のロックアウト、PKCE付きGoogle OIDC。エージェントのbearer secretはpepper付きHMAC-SHA256でハッシュ化 |
| セッション管理 | Pass | ハッシュ化トークン、スライディング期限、失効、パスワード変更時の処理、定期整理、ロール束縛セッション |
| アクセス制御 | Pass | HTTP route 111件のうち、94件が権限gate、1件が認証のみ、6件がエージェント認証、10件が公開。deny-by-defaultの境界をWebSocketハンドシェイクにも同一に適用。permission matrixは122件。エージェント登録は管理者承認が必須 |
| 入力検証 | Pass | JSON 64KB上限、endpointモジュールでの厳格なZod、未知キーの拒否、文字列・範囲の上限、外向きendpointへのSSRF guard。エージェント観測はZodとSQLite CHECK制約で二重検証(64bitバイトカウンタは十進文字列として範囲検査) |
| 暗号 | Pass | secretと相関IDにrandomBytes/UUID、session/TOFU/principalHashにSHA-256、エージェント資格情報にHMAC-SHA256、timing-safe比較、MCPのJWT検証にRS256、リリース署名にKMS Ed25519 |
| エラー処理 | Pass | 汎用500応答、スタック非露出、リクエスト相関付きサーバログ |
| データ保護 | Pass | 設定・バックアップ・TLS鍵はmode 0600。公開設定とログからsecretを除外。API identityとエージェント資格情報はハッシュのみ保存。エンドポイント側ではHub資格情報をkeychainに置き、メインスレッド外で読む |
| 通信 | Pass | HTTPS/HSTS対応、OIDCコールバックはsecure redirectを強制、MCP OAuthはHTTPS JWKS。公開Webプロパティは2つともHTTPS専用かつHSTS付き |
| 悪意あるコード | Pass | evalなし。フロントエンドのHTML挿入監査をCIで強制 |
| ファイル処理 | Pass | アップロード上限、バックアップ名の検証、traversal検査、fail-closedなrestore/migration。ダウンロードした更新パッケージは実行中アプリの署名チームと照合してからインストール |
| API | Pass | メソッド別route、厳格スキーマ、応答サイズ・時間の上限、認証付きエクスポート、MCPレート制限、冪等なエージェントingest |
| 設定 | Pass | 資格情報のハードコードなし、設定例、secret scan、本番でのデモモード拒否 |
| ビジネスロジック | Pass | CSRF保護付きHttpOnly cookie、API identityの明示的権限トークン、試行回数制限付きの管理者承認エージェント登録、deny-by-defaultの強制 |
| 監査とログ | Pass | 追記専用のaudit_events(仮名化されたactorHash/principalHash)、24時間周期で強制する180日保持、クライアントアドレスをkey化したMCP独立の監査ストア |
推定スコア: 8.9/10(前回: 約9.4)。
| チェック | スコア | 根拠 |
|---|---|---|
| Pinned dependencies | 10 | 4ワークフロー全体で、GitHub Actions参照23件すべてを完全commit SHAに固定 |
| Token permissions | 10 | 既定はread-only。Pagesと製品サイトのデプロイが必要分のみ拡張(OIDC用のid-token: write、contents: writeなし) |
| Dangerous workflow | 10 | pull_request_targetなし。デプロイジョブは、mainに限定したenvironmentを介してmainでのみ動作 |
| Binary artifacts | 10 | コミット済みバイナリなし |
| Security policy | 10 | SECURITY.mdと非公開の脆弱性報告 |
| License | 10 | AGPL-3.0-only |
| SAST | 10 | ASH(5 scanner)、secret scan、ESLint、フロントエンド挿入監査、npm audit |
| Vulnerabilities | 10 | CIで本番npm audit。本レビューでは0件 |
| Dependency updates | 10 | npmとActionsに週次Dependabot、7日のcooldown付き |
| CI tests | 10 | PRでunit/coverage、parser fuzz、browser smoke、offline portability。Node 22/24/26マトリクス。swift testと未署名ビルドを行う独立のmacOSエージェントワークフロー |
| Maintained | 10 | 本サイクルで58 PRと11リリース |
| Code review | 8 | 必須チェック付きのPRワークフロー。本サイクルで1コミットがPRを経ずにmainへ到達 |
| Fuzzing | 5 | 信頼できない機器入力を読む関数をparser fuzzでカバー(時間予算と形状のアサーション付き)。継続fuzzingサービスではない |
| Signed releases | 8 | このチェックは直近リリースの資産を拡張子で検査します。v2.0.2が署名資産を持ち、チェックサムと公開鍵も揃っており、ダウンロードした成果物に対して検証済みです。KMS Ed25519鍵は多系統でのfingerprint公開とtrust registryのテストを伴って登録されています。残り2点にはSLSA provenanceが必要です |
本レポート初版でこの項目を2点としたのは、直近3リリースが何も持っていなかったためです。 いま8点なのは、それが是正されたからであって、評価を甘くしたからではありません。署名は引き続きCIではなくワークステーションで行います — 鍵をワークフローに移せば署名できる主体が広がるため、意図的な選択です — が、忘れられる手順ではなくなりました。npm run release:publishがリリースそのものであり、公開時・編集時・週次でゲートが公開結果を検査します。
| 特性 | スコア | 強み | 残る課題 |
|---|---|---|---|
| 機能適合性 | 9 | 複数ルーター収集、プロセス単位の帰属とローカル脅威照合を持つmacOSエージェント、エージェント/ルーター相関、AI insights、エクスポート、OAuth付きMCP | OpenAPI契約なし |
| 性能効率性 | 9 | WAL、バッチ、上限付きサマリ、エージェントスコープのインデックス、エージェントのチャート背後の時間集計、そして約1桁削減したエージェント実行コスト | バックアップ検査は依然として短時間のホストレベル遅延を生み得る |
| 互換性 | 9 | Node 22/24/26、全面的なJA/EN、Yamaha/Cisco/ASUS/conntrack経路、macOS 13+のエージェント、/直下でもプロキシ配下のサブパスでも正しく動作 |
ハードウェア固有の検証はCI上でfixture依存のまま |
| 使用性 | 9 | レスポンシブUI、セットアップガイド、自動検出、ヘルス診断、公開read-onlyデモ、停止したら停止と言うnotarize済みエージェント、ダウンロード前に要件を示す製品サイト | ルーター側の設定が依然として実際の導入コスト |
| 信頼性 | 9 | fail-closedなmigration/restore/config、health/readiness、キャンセル、レート制限、event-loop watchdog、「通信がない」と「記録していない」を区別するエージェント自己監視 | watchdogの復帰は外部サービスマネージャに依存 |
| セキュリティ | 10 | OIDC/PKCE、RBAC、独立したagent種別を含むdeny-by-default権限、CSRF、ハッシュのみの資格情報、管理者承認の登録、MCP OAuth/JWKS、監査証跡、SSRF guard、最小権限のentitlementを持つsandbox化・notarize済みエージェント | – |
| 保守性 | 9 | Hub 124モジュールに加え、23k行のSwiftエージェントが自前の7k行のテストを持つ。Hubのtest対source比率107.8%、permission matrix、parser fuzz | 700行超のモジュールが4つ |
| 移植性 | 9 | クラウド中立プロファイル、KMS署名済みの可搬ソースバンドル、オフラインモード、版付きロールバック、Node 22/24/26 CI | サポート対象の本番OCIイメージ/service unitなし |
平均: 9.1/10。
適合度: 47/50(94%)。 実質的な内容は前回から変化していません。今回の新材料はSwift側にあり、§6で評価します。
AsyncLocalStorageで上限付きのX-Request-Idコンテキストを付与し、クエリ文字列はログに出しません。減点は、既定のハードウェア連携CIがないこと、サポート対象のプロセスマネージャ/OCI成果物がないこと、OpenAPI契約がないことによります。
| 指標 | 結果 | 評価 |
|---|---|---|
| 信頼性 | 既知のCritical/High不具合なし。エージェントの実行コストと収集停止の不具合は修正済みで実機確認済み | A |
| セキュリティ | 未解決の高シグナルsecretや依存の指摘なし。完全なRBAC、監査、SSRF保護、sandbox化・notarize済みエージェント | A |
| 保守性 | 700行超のモジュールが4つ。いずれもテストで囲まれている | A |
| Coverage | line 84.62% / branch 80.00% / function 81.47%(CI gateが検査するスコープ) | A |
| 重複 | 手動・静的レビューで実質的な新規重複は検出せず | A(推定) |
品質gate: 合格。 ただしこのgateが測るのはコードであり、リリースが正しく公開されたかは測りません。本サイクルの後退はまさにそこにあります。
| ファイル | 行数 | 所見 |
|---|---|---|
public/js/ai-insights.js |
892 | 通知とinsightの描画が1つのビューモジュールを共有 |
src/history.js |
847 | query/cache/bootstrapを抽出した後もストア調整が大きい |
src/db-migrate.js |
818 | スキーマ移行 v1–v16 |
server.js |
812 | 初期化と依存の結線 |
public/js/log.js |
734 | ページング・絞り込み・描画が1つのビューモジュールを共有 |
src/routes/agents.js |
707 | エージェントの登録・承認・ingest・capability route。本サイクルで24%増加 |
public/js/graph.js |
679 | 抽出済みのgraphヘルパ/パネル/レンダラを調整 |
src/devices.js |
665 | デバイス識別・永続化・マージのライフサイクル |
src/pollers/cisco.js |
661 | 抽出済みparser/handshakeモジュール周りの状態付きSSHライフサイクル |
src/mcp-publication-gate.js |
639 | 公開判定、クライアントのリリースタイミング、診断 |
src/pollers/yamaha.js |
627 | アダプタparser周りの状態付きSSHライフサイクル |
public/js/devices.js |
594 | デバイスUIの調整 |
public/js/auth-socket.js |
575 | 認証対応ソケットの初期化と再接続 |
mcp-server.js |
570 | トランスポート初期化とOAuth結線 |
src/ai-provider.js |
563 | SSRF guard付きのマルチプロバイダAIクライアント |
Swift側ではXcode/Host/ObservationWindowController.swiftがエージェント内で群を抜いて最大のファイルで、現在は接続ログ、sankey、タイムライン、地球儀、そしてそれらが共有する期間選択を抱えています。エージェントにおけるai-insights.js相当であり、分割の第一候補です。
エージェントはSwiftのソースであるだけでなく、利用者がインストールし、システム拡張を許可し、起動しっぱなしにするアプリケーションです。本節ではそれとして評価します。基準はAppleのプラットフォーム要件(notarization、hardened runtime、App Sandbox、entitlement、プライバシーマニフェスト)、macOS Human Interface Guidelines、アクセシビリティとローカライズ、電力挙動です。
スコア: 45/50。
| 領域 | スコア | 根拠 | 欠落 |
|---|---|---|---|
| Gatekeeperとnotarization | 5/5 | インストール済みの0.5.29 build 91に対し、spctl -a -t installはaccepted、source = Notarized Developer ID。stapler validateも成功するため、ネットワーク往復なしで起動する。ビルドスクリプトはパッケージング工程でnotarizeとstapleを行う |
– |
| hardened runtimeと署名 | 5/5 | CodeDirectory flags=0x10000(runtime)とsecure timestamp。ホストとシステム拡張は--options runtimeで個別に署名し、署名後とパッケージング往復後の両方で--strict検証 |
– |
| App Sandboxと最小権限 | 5/5 | ホストと拡張の両方がsandbox化。ホストが持つentitlementはちょうど5つ — app group、network client、user-selectedファイルの読み書き、system-extensionインストール、network-extensionのcontent filter。com.apple.security.files.allも、temporary-exception系のentitlementも一切ない |
– |
| プライバシー表明 | 5/5 | アプリ本体とシステム拡張の両方がPrivacyInfo.xcprivacyを同梱。リポジトリ内にあるだけでなく、ビルド成果物のバンドル内に存在することを実測で確認した。いずれもNSPrivacyTracking: false、トラッキングドメインなし、空のNSPrivacyCollectedDataTypes(開発者が到達できる形で何も送信しないため、これが正確)を宣言し、エージェントが実際に使う2つの要理由カテゴリに理由を付けている — user defaults(CA92.1 / 1C8F.1)と file timestamp(C617.1、自分で書いたファイルのサイズ読み取り)。NSSystemExtensionUsageDescriptionは引き続き正確かつ具体的。docs/agent-privacy.ja.mdがエージェントの接続先ホスト、送るもの、返るものをすべて列挙している — dl.egressview.comへの接続がアクセスログを持つCDNにクライアントIPを知らせることを含めて。都合の良い事実だけを並べるプライバシーページなら省く点である。宣言していない要理由カテゴリへの呼び出しがソースに現れたら、リポジトリのテストが失敗する |
– |
| ローカライズ | 5/5 | en.lprojとja.lprojがそれぞれ491キーで完全一致 — 片方にしか存在しないキーはゼロ。UI言語は起動時固定ではなく利用者が選べるロケールに従う |
– |
| アクセシビリティ | 4/5 | 単純な件数から受ける印象より良い。独自描画の3つの可視化(地球儀・sankey・タイムライン)はいずれも、描かれている内容を要約したaccessibilityLabelを計算して公開し、装飾画像はaccessibilityHidden、メニューバーボタンは状態をアクセシビリティラベルとして持つ。キーボードショートカット/ヘルプの修飾子が13箇所 |
VoiceOver自体での監査記録がない。要約はunit testで確認しているが、スクリーンリーダーでは確認していない |
| 電力とリソース挙動 | 5/5 | 本機での実測: ホスト2時間2分で0.0% CPU / 126MB RSS、拡張3時間37分で1.7% / 18MB。定期処理はApp Nappが絞るrun-loopタイマーではなくbeginActivityスコープ内のdispatch sourceタイマー。地球儀は3/5/15 fpsから選べる再描画。windowはcloseで解放されるためメモリが戻る |
1台・1標本 |
| HIG適合 | 4/5 | メニューバー常駐のみ(LSUIElement)で、バックグラウンド観測者として正しい形。windowは必要時に生成。ログイン項目はレガシーヘルパではなくSMAppServiceで管理。最小macOSは13.0 |
現行HIGに対するレビュー記録がない。ウィンドウ状態の復元は未実装 |
| 更新とアンインストール | 4/5 | 署名付きリリース情報に対するアプリ内更新チェック。ダウンロードしたパッケージの署名チームIDを実行中アプリと照合してからインストールし、notarizationはインストーラが独立に強制。Hub登録を失効させる一級のアンインストール経路があり、Hubに到達できない場合は資格情報を保全する | .pkgリリースにプロジェクト自身のチェックサムやdetached signatureがない(§2)。sandbox下でアプリ内更新を成立させるのに4回の是正リリースを要した |
| 診断 | 3/5 | インストール時に、再起動が実際に何をしたかを記録する計装済みログを書き出す。Swiftテストは419件、失敗0 | クラッシュレポートも、利用者がエクスポートできる診断バンドルもない。 他人のMac上で不調が起きたとき、送ってもらえる成果物が存在しない |
このスコアを最も動かす2つの行動(優先順):
本節が以前「最も明確な欠落」として挙げたプライバシーマニフェストは同梱済みで、その宣言は意志ではなくテストによってソースに結び付けられています。
コードは良好な状態にあり、macOSエージェントは大きく成熟しました。起動しっぱなしのコストがほぼ無くなり、止まったら止まったと言い、自分の更新を検証し、Appleのプラットフォーム要件 — notarize、staple、hardened、sandbox、そして実際に使うentitlementだけを保持 — を満たしています。ローカライズはキー単位で完全であり、独自描画の可視化は不透明な絵として放置されず、アクセシビリティの要約を与えられました。サイドロードされるユーティリティの通常水準ではありません。
実行コストの作業には1文を割く価値があります。この失敗は特定の、示唆的な種類のものだったからです。CPUコアの41%を消費するエージェントは、性能問題ではなく信頼の問題です。 マシンが外へ何を送っているかを見るためにシステム拡張を許可してくれと頼むツールが、同時にそのマシン上で最も重いプロセスであってはなりません。4つの無関係な原因はいずれも、ポーリング間隔を延ばして覆い隠すのではなく個別に診断して修正され、結果は推測ではなく実機で確認されました。
本サイクル唯一の後退はコードではなくリリース公開にあり、それは解消されました。 3つの製品リリースが署名済み資産なしで公開されました。前回・前々回のレポートが揃って「署名され独立に検証可能なリリース」を最強のサプライチェーン特性として挙げてきたプロジェクトで、です。人が実際にダウンロードするバージョンで守られない検証の約束は、検証の約束ではありません。 v2.0.2は同じ鍵・同じ手順で署名され、そして重要なことに、リリースページからダウンロードした状態の成果物に対して、別系統の資格情報で提供されるDNSのfingerprintと照合し、改竄3ケースがいずれもfail-closedすることまで確認しました。以前のレポートが述べていた特性が、主張ではなく回復されています。
「無かった理由」に対処しました。署名そのものより、そちらが重要でした。 署名は人が覚えていなければならない手順であり、3回連続で飛んだという事実は、覚えていることが管理策ではないことの証拠です。 パイプラインは一度も失敗していません。失敗したのはその周りの規律です。リリースは1コマンドになり、タグと一致しない作業ツリーからは着手せず、改竄3ケースが落ちることを証明し、draftへアップロードし、リリースページからダウンロードした状態の資産を検証してから公開に切り替えます。どこかで落ちれば残るのはdraftであって、検証手段の無い公開済みリリースにはなりません。公開時・編集時・週次のワークフローが公開結果を検査し、別経路で作られたリリースも捕まえます。署名は意図的にワークステーションに残します。 鍵をCIへ移すことは、規律の問題をサプライチェーンの問題に置き換える取引だからです。
改善リストの残りは種類として変わりません — 利用者がエクスポートできる診断、Signed-Releasesの残点を埋めるSLSA provenance、継続fuzzing、OpenAPI契約、サポート対象のservice成果物。いずれもリリースのblockerではありません。