---
license: "MIT. Translation of the Hermes Agent documentation, Copyright (c) 2025 Nous Research. See https://wiki.winsmux.dev/hermes/licenses.txt"
title: "PM 監査の修正状況"
description: ""
upstream_path: developer-guide/pm-audit-status.md
upstream_blob: d91cc20f151850173b68225fe1bdf4aed5c78186
sources:
  - https://hermes-agent.nousresearch.com/docs/developer-guide/pm-audit-status
---

# PM 監査の修正状況 {#pm-audit-remediation-status}

これは過去の監査の記録であり、最新の HEAD のリリース状況を示すページではありません。
以下の件数とネイティブ環境での受領記録は、それぞれに書かれたリビジョンにだけ当てはまります。
その後の作業で、共有バンドルの組み立て、署名付きパッケージの E2E、安定版の
リリースゲート、Termux の APT 配布、Python 3.14 が加わりました。これらの変更によって、
以前のテストの受領記録の範囲がさかのぼって広がるわけではありません。

現在の実装の取り決めについては、[パッケージ管理](/hermes/docs/reference/package-management/)、
[共有バンドルビルド](/hermes/docs/developer-guide/shared-bundle-builds/)、[安定版リリース](/hermes/docs/developer-guide/stable-releases/)、
[バンドル版の更新の受け入れ検査](https://github.com/NousResearch/hermes-agent/blob/main/tests/install/BUNDLED_UPDATES.md)を参照してください。

この変更は、ブランチ全体を対象にした監査で見つかった問題の修正を取り込むものです。
リリースの証明書ではありません。監査では `49945b14029e09fef608db9ede899377cdb54e11` を
マージベース `433f7196760e5d76f77ea6d5464ee7f1b602a4ee` と比較しました。

## ドキュメント監査後のランタイムの修正 {#runtime-repairs-after-the-documentation-audit}

監査では、Electron での Python の配置の食い違い、Nix で Python の系列が固定されていること、
cryptography の要件の矛盾、クリーンな Windows でのセットアップの失敗が見つかりました。
その後の対応では、それぞれを担当する実装を変更しています。

- バンドルビルダーは、完成したペイロードを検査し、その起動パスを公開します。
  Electron はこの取り決めをそのまま使い、ペイロードの探索、取り込み、作成は行いません。
- Nix は、Python のメジャー・マイナーバージョンを `pm/lock.json` から選びます。uv2nix の環境、
  パッケージの上書き、追加パッケージ、開発者用シェルは、その系列を使います。
  実際の Nix の評価とビルドの受け入れ検査は、引き続き CI のゲートです。
- cryptography の直接の要件とセキュリティ上の上書きは、`uv.lock` にある修正済みの
  バージョンに合わせてあります。上書きは、引き続きベンダー SDK の古い上限を回避します。
- ブートストラップは uv の終了を待ってから、Python から直接 PM を実行します。
  これにより、ブートストラップが実行ファイルを掴んだままにならず、PM が自分の uv のエントリーを置き換えられます。
- PM の受領記録の公開では、共有ロックの下で、標準ライブラリだけを使ったアトミックな JSON の書き込みを行います。
  失敗の報告で `utils` 経由の PyYAML の import はしなくなりました。
- 使われていなかった開発シェルのコマンドは削除しました。セットアップと、有効化、
  `deactivate` が、PM を使う開発者向けの唯一の経路です。

ネイティブの Windows での確認は、使い捨てのホームで、空のツールストアから始めました。
セットアップが完了し、PM が依存関係の世代を公開し、PowerShell での有効化によって
ストアのインタープリターとソースの CLI が動きました。別に行った PM のインストールも、
実際の依存関係の確認に通りました。これらの確認は、署名付きパッケージのインストール、
更新、Nix のビルドを証明するものではありません。PM のプラグイン・設定と YAML の、より広い結び付きは変わっていません。
[開発者向けのワークフロー](/hermes/docs/reference/package-management/#developer-workflow)では、
ランタイムの有効化と、それとは独立したテスト用・エディター用の環境を区別しています。

## 実施した修正 {#implemented-repairs}

| 指摘 | 実装 |
| --- | --- |
| C01, C11, C12, C24 | 削除済みの TLS の import を取り除き、ACP のファイルのデコード、プロキシのパスの所有、監視 SDK の呼び出しを修正。 |
| C02 | コード実行のスキーマ、登録、子プロセスのライフサイクルの扱いを復元。 |
| C03, C04, C17 | 更新のメタデータのコマンドを読み取り専用に保ち、プラグインの更新を同期し、フィードの識別情報を正しく比較。 |
| C05, C27, C28 | インストールの閉包に管理対象の Python を含め、インストーラーの段階の振り分けとランタイムの選択を修正。 |
| C06, C07, C09 | サポートしていない SCM の機能を削除。Scheduled Task による監督は残し、デスクトップの終了時に関係のないランタイムを保護。 |
| C08, C19 | App Installer のチェッカーを修正し、意味のある更新の状態を復元。 |
| C10 | アンインストールの振り分けと、所有するリンクの削除を修正。 |
| C13, C14 | 公開の前に、完全な依存関係の環境を1つ準備。宣言された制約と明示的な固定を保ち、互換性のある推移的な更新は許可。インフラの失敗でプラグインが無効になることはない。 |
| C15, C18 | 公開に失敗したとき、回復できるツールストアのエントリーを残す。情報ファイルと設定はアトミックに書き込み、受領記録はコンテキストごとに持つ。 |
| C16, C29 | 削除された依存関係のヘルパーを移行し、依存関係が足りないときのヒントを復元。 |
| C20, C21 | プラットフォームごとのテストの選択を修正し、削除済みの import を検出するガードが実際のソースを調べるようにした。 |
| C22, C23 | 変更不可のリリース成果物をフィードより先に公開し、FFmpeg の成果物をターゲットごとに解決。 |
| C25 | 一時停止したダウンロード、再開用のハンドル、単一のワーカーによる所有を保つ。 |
| C26 | 起動時の経路とプラグインの定期実行の経路を、既存の担当部分につないだ。 |

実装したことは、すべてのプラットフォームの受け入れテストが完了したことを意味しません。
アップデーター、バックアップ、セットアップ、音声・テキストのヘルパー、いくつかのプラグインは、
整理した関心事ごとに1つの実装を使うようになりました。ランタイムのパスは、
`pm/environments.py` を共通の担当にしています。

## 残件を閉じるための実装 {#closure-implementation}

| 取り決め | 担当と証拠 |
| --- | --- |
| 中断した公開 | `hermes_cli/runtime_state.py` が、古い設定と、提案された設定のハッシュをジャーナルに記録します。起動時には、依存関係を有効化する前に回復します。回復処理は、関係のない編集を上書きしません。実際のサブプロセスを使うテストで、情報ファイルの公開の前と後で終了させています。 |
| 稼働中の世代の回収 | 起動時に、公開用のロックの下で世代のリースを保持します。`pm gc` が削除するのは、選ばれておらず、稼働中の読み取り側がいない、リース管理下の世代だけです。テストでは、回収の実行中に実際の読み取り側を動かし続けています。 |
| 受領記録の対応付け | PM の完了通知には、呼び出した更新の ID が入ります。アップデーターは、失敗したステップと拒否の理由も含めて、その完了通知を埋め込みます。入れ子のコマンドやコピーされたコンテキストが、外側の受領記録を確定させることはできません。 |
| 警告の表示先 | Doctor は、更新チェッカーのローカルでの来歴の規則を使います。デスクトップは同期の状態を読み、正常に何もしなかった場合と、埋め込まれた失敗とを区別します。 |
| アップデーターの所有 | チェックアウトの確認と受け渡しは `electron/updater/checkout.ts` が担当します。`main.ts` はその依存関係を渡します。 |
| Windows での再起動 | 切り離された PowerShell の待機プロセスが、終了前にパッケージの識別情報を記録し、元のプロセスが終わるのを待ってから、インストールされたバージョンが変わるのを待ちます。登録に失敗した場合は、手動で開き直すよう促す警告を出します。 |
| テストの健全性 | TCC の動作は、実際のホストのマーカーを使います。インストーラーのソースを grep する形のアサーションは削除しました。ランタイムとインストーラーの動作テストは残っています。 |

## 実行して確かめたこと {#verified-execution}

- ネイティブの Windows で最後に完了した Python の実行では、3,746 ファイルで 44,557 件が成功、1 件が
  失敗、1,404 件がスキップでした。実行中、Python のソースのハッシュは
  変わりませんでした。再試行で成功した HTTP のテストも1件報告されました。
  そのあと、インストール ID の競合と HTTP のテストを修正しました。この2ファイルは、再試行なしで
  35 件のテストに通りました。これは、最終的なツリーでのテストスイート全体の成功ではありません。
- ルートの `npm run check` は、MSIX のパッケージングも含めて終了コード 0 で完了しました。
  デスクトップ UI: 7,231 件成功。Electron: 2,311 件成功、23 件スキップ。TUI:
  1,719 件成功、8 件スキップ。ダッシュボード: 291 件成功。ルートの JS: 77 件成功。
  型チェックと lint にエラーはありませんでした。既存の lint の警告は残っています。この
  パッケージングの確認では、主のビルドディレクトリにある既存のペイロードを使っており、
  別に検証した監査用の新しいペイロードは使っていません。
- 実際のコアのプロジェクトは、ワークスペースのヘルパーを通して解決・ビルドできました。
  import は生成されたワークスペースから解決され、ソースのロックファイルは変わりませんでした。
- ネイティブの ARM64 で新しく作った PM バンドルは、固定されたツールの確認と、すべての追加機能を含む
  環境のビルドを完了しました。そのマニフェストには、ソースツリー
  `60c9fb444c93e8a79ae22a01677c3291385343a6` が記録されています。
- 作り直した軽量版のデスクトップは、隔離したホームで実際のバックエンドを2回起動し、
  HTTP 200 を返し、正常に終了しました。ホームのエントリーは再起動後も残っていました。
- 実際に隔離した API サーバーのメッセージングゲートウェイは、通常のデスクトップの終了のあとも、
  PID と起動時刻を保っていました。デスクトップのバックエンドは止まり、ゲートウェイは止まりませんでした。
- 実際のパッケージングのツールチェーンで、軽量版の MSIX をビルドしました。Windows Sandbox で
  バージョン `0.17.0.0` をインストールし、`0.17.0.1` に更新し、アンインストール後に残っていないことを確認しました。
  テスト用の証明書の作成と信頼の設定は、使い捨てのゲスト環境の中だけで行いました。

- ペイロードのツリー `60c9fb44...` から、別途、新しいバンドル版の MSIX を作りました。
  展開した成果物に含まれる CLI が動き、import はそのペイロードの中で解決され、
  `hermes serve` は HTTP 200 を返しました。Sandbox への配備は、展開先のパスが
  誤っていたため失敗しました。バンドル版のインストールを証明するものではありません。
- プラグインの確認は、最初の定期処理の周回から実行されるようになり、ネットワークでの確認は
  設定された間隔のゲートで制御されます。実際に隔離したゲートウェイが、1周回の間を空けて、成功した
  プラグインの確認の受領記録を2つ書き出しました。自動適用は無効にしていました。

これらの受領記録は、それぞれ異なる層を対象にしています。軽量版パッケージの配備と、展開した状態での
ランタイムの起動は、バンドル版のインストールや、App Installer をきっかけにした再起動を証明するものではありません。
今回の受け入れ確認の証拠として、LLM へのリクエストを送ったテストはありません。

## マージ可能な状態にするための締めくくり {#merge-ready-closeout}

このブランチには、上流の `5bd439d3ed4ae5f099857813383389dcd0ab4369` が含まれています。
以前の監査で挙げた次の制限は解消しました。

- コンテキストだけのホームは、ジャーナルからの回復、選ばれたランタイムの状態、
  プラグインの和集合で、1つの依存関係のルートを共有します。回帰テストのまとまりは、
  71 件のテストに通り、ホストによるスキップが 8 件でした。
- `tests/tools/test_subagent_steer.py` が、相対パスの `MagicMock` の
  データベースを作っていました。そのモックの親は、データベースを持たないと明示するようにしました。委任の
  検証のまとまりは、新しいゴミを残さずに通りました。以前のゴミは、
  リポジトリの外にアーカイブしてあります。
- Docker のブートストラップには、サードパーティの依存関係がまだない段階で PM が import する、
  標準ライブラリだけのランタイムのパスとロックの担当部分が含まれています。この修正のあと、両方のアーキテクチャのビルドが
  通りました。
- インストーラーのパスの探索は、存在しないロックファイルを読まなくなりました。PowerShell 5.1 と
  7 のインストーラーのテストが CI で通りました。
- サービスのランタイムの選択では、選ばれた環境を解決する共通の仕組みを使います。
  管理対象の Node のパスは、PM の情報ファイルが渡します。ネイティブのフィクスチャーは使い捨てのホームを使います。
- Windows のアップデーターは、明示的なフィードの上書きが設定されていない限り、登録済みの
  App Installer の取得元を使います。終了処理の前に記述ファイルをダウンロードし、
  ローカルのファイルを開きます。無効にされた
  `ms-appinstaller:` プロトコルは必要ありません。

## E2E 以外の締めくくり {#non-e2e-closeout}

`a27cd5902a446eb4f1e457e09904d75edc616c2e` での CI のワークフロー全体は、
正常に完了しました。

- Linux: 46,041 件成功、失敗 0 件、492 件スキップ。再試行でだけ成功した不安定なテストはなし。
- macOS: 94 件成功、失敗 0 件、121 件スキップ。再試行でだけ成功した不安定なテストはなし。
- Windows: 178 件成功、失敗 0 件、174 件スキップ。パイプの排出を扱うフィクスチャー1件が、
  コールドスタートの子プロセスがアイドル時間の枠を超えたため、再試行でだけ成功しました。

コミット `04182813cfa74111c6e4e10bedcc0f9de6510f55` は、Windows での
入れ子のプロセスの並行数を、フィクスチャーのアサーションを緩めずに制限します。
また、compute ホストの stdin のフレーミングも修正しています。実際の Windows の子プロセスは、
最初のターンは受け取れたものの、その後の制御フレームをテキストのストリーム経由で
受け取れていませんでした。バイトストリームの読み取り側は、実際の割り込みと
2ターン目のテストに通りました。これらのテストは、現在は各ネイティブ OS のレーンで実行されます。

ほかのテストの修正は、ワーカーのスケジューリングと、テスト対象の動作を区別するものです。
圧縮のテストはエンジンに入るのを待ち、cron のアサーションは
ブロックされた作業を観測し、孤立したプロセスの後片付けでは再開用のロックが空いていることを確かめ、
ホスト型のルームのテストは、並行して取ったスナップショットのあとに、確定が永続化されたことを観測します。
対象を絞った親側の検証では、ゲートウェイ・委任のテスト 638 件、
cron・衛生管理のテスト 41 件、圧縮の隔離のテスト 4 件、ホスト型・compute の
テスト 53 件、実際の子プロセス・compute のプロトコルのテスト 19 件が通りました。これらのまとまりは重なっており、
スイート全体の合計ではありません。

ブラウザーの BOM の回帰テストは、読み取りの修正前には失敗し、修正後には通りました。
そのファイルは 79 件のテストに通り、ホストによるスキップが 2 件でした。Windows の落とし穴の確認と
プラグインの互換性の確認は、すべて通りました。

## バンドルの受け入れ検査（別の作業系統） {#bundle-acceptance-separate-workstream}

`07ee9299790e5635fd917da1769f969f14fc8030` からビルドした、実際のバンドル版の Windows ARM64 MSIX は、
使い捨ての Windows Sandbox にバージョン `0.17.0.0` としてインストールされました。登録されたアプリは UI を表示し、
「バージョン情報」は埋め込まれたランタイムを示し、パッケージに含まれるバックエンドは
HTTP 200 を返しました。署名していないビルド成果物の SHA-256 は
`31d3dfb53977e0e8fd662d0ef2475a7be92a31a49d6e514ceed812099867f304` です。
テスト用の署名と信頼の設定は、ゲスト環境の中だけで行いました。

ゲスト環境は、更新と再起動の確認が完了する前に終了させました。
自動更新の受け入れについては、何も主張していません。この成果物は、その後の上流の
取り込みと compute ホストの修正よりも前のものです。バンドルの E2E の作業は、
既存のインストール・更新のテスト群に属するもので、ローカルの Sandbox を使う2本目の
パイプラインではありません。

## 残っているゲート {#remaining-gates}

- 最終的な HEAD でのネイティブの CI で、再試行でだけ成功する失敗なしに最新の修正を確認する必要があります。
- メンテナーが `needs-decision` の扱いを決め、レビューのあとに
  `ci-reviewed` を付ける必要があります。手動の CI では、PR 専用のレビューゲートは飛ばされます。
- パッケージの自動更新と再起動は、引き続き別の E2E の作業系統が担当します。

正準となる PM の PR を1つにするよう求めたトリアージの依頼に従い、PR #95281 は
#102765 に置き換えられたものとして閉じました。重複のラベルは外しました。承認の
ラベルを自分で付けることはしていません。

[a27cd5902a での検証済みの CI](https://github.com/NousResearch/hermes-agent/actions/runs/34059149746)。
正確な HEAD での検証には、上流の検証用ブランチで同じワークフローを使います。
以前の GitHub のグラフでの失敗では、
`resource_exhausted: gitmon refuses to schedule us: fail-fast:network` が報告されていました。

外部の監査ディレクトリには、元の指摘、正確なテストの選択、
実行ごとのログ、ソースのスナップショット、レビューの裁定が入っています。ホストのアプリケーション、
証明書の信頼、本番のサービスは、その監査のあいだ変更していません。
その監査ではリリースを公開していません。これは、その後の実行について述べたものではありません。
