From 039f210b9af8e5b5aa38ff0597120d69088427f3 Mon Sep 17 00:00:00 2001 From: luvs01 <27862058+luvs01@users.noreply.github.com> Date: Thu, 10 Sep 2026 13:20:15 +0900 Subject: [PATCH 1/2] fix(codex): report a deferred Windows CLI inspection instead of an absent candidate On Windows the candidate-only provenance slice performs no candidate or configuration filesystem I/O, so it never consults the persisted runtime selection. When no proof-captured CODEX_CLI_PATH candidate is present it nevertheless reported reason "candidate_unavailable", asserting that no Codex CLI candidate exists even though availability was never observed. Operators whose runtime resolves through persisted "configured" state therefore saw a missing candidate while the runtime report showed a known version. Report the deferral that actually occurred instead. The defined "windows_inspection_deferred" reason already exists but was reachable only with an environment candidate. POSIX does read persisted state, so its absent-candidate answer is exact and stays unchanged. No filesystem access is added: the Windows path still performs zero I/O, and candidateAvailable, provenance, managed, selectionAttested, versionEvidence and shim status are unchanged. This intentionally replaces the previous test statement that pinned the "candidate_unavailable" wording on Windows. --- .../content/docs/fr/reference/cli/agents.md | 2 +- .../content/docs/ja/reference/cli/agents.md | 2 +- .../content/docs/ko/reference/cli/agents.md | 2 +- .../src/content/docs/reference/cli/agents.md | 5 +++- .../content/docs/ru/reference/cli/agents.md | 2 +- .../content/docs/tr/reference/cli/agents.md | 2 +- .../docs/zh-cn/reference/cli/agents.md | 2 +- .../docs/zh-tw/reference/cli/agents.md | 2 +- src/codex/cli-install-provenance.ts | 8 ++++- .../codex-cli-install-provenance.test.ts | 30 +++++++++++++++++-- 10 files changed, 46 insertions(+), 11 deletions(-) diff --git a/docs-site/src/content/docs/fr/reference/cli/agents.md b/docs-site/src/content/docs/fr/reference/cli/agents.md index 749119f70a..fe8f9bb9a6 100644 --- a/docs-site/src/content/docs/fr/reference/cli/agents.md +++ b/docs-site/src/content/docs/fr/reference/cli/agents.md @@ -264,7 +264,7 @@ ocx system settings --stream-mode eager-relay ocx system codex-cli-update check --json ``` -`check` n’interroge aucun registre de paquets et inspecte, dans des limites strictes, les éléments de provenance du candidat d’installation configuré, notamment l’emplacement expurgé de l’exécutable et les preuves de propriété. Le contexte de confiance du lanceur publié authentifie uniquement cet instantané du candidat, et non l’exécution réussie de Codex. Comme cette commande ponctuelle n’exécute jamais Codex, les candidats issus de l’environnement ou de l’état persistant restent purement informatifs (`managed: false`, normalement `selection_unattested`) et `selectionAttested` reste `false`. La sortie JSON contient `candidateAvailable`, `candidateVersion`, `candidateSource` et `selectionAttested: false`. Une exécution directe via Bun ou depuis les sources ne fournit pas la preuve du lanceur, ignore les candidats issus de l’environnement ou de l’état persistant et peut signaler `candidate_unavailable`. Sous Windows, cette première étape n’effectue aucune E/S de système de fichiers sur les chemins du candidat ou de configuration. Seul un candidat d’environnement absolu capturé par le lanceur de confiance peut recevoir une étiquette lexicale de bundle d’application ou de gestionnaire de versions ; tous les autres candidats Windows échouent de manière fermée. La commande n’exécute ni Codex ni aucun gestionnaire de paquets, ne répare aucun shim, n’écrit ni dans la configuration ni dans le cache, n’arrête aucun processus et n’installe rien. Les candidats intégrés à une application, issus d’un gestionnaire de versions reconnu, autonomes mais non vérifiés, ou associés à un état de shim ambigu sont signalés comme non gérés ou inconnus et ne sont jamais classés comme gérés. +`check` n’interroge aucun registre de paquets et inspecte, dans des limites strictes, les éléments de provenance du candidat d’installation configuré, notamment l’emplacement expurgé de l’exécutable et les preuves de propriété. Le contexte de confiance du lanceur publié authentifie uniquement cet instantané du candidat, et non l’exécution réussie de Codex. Comme cette commande ponctuelle n’exécute jamais Codex, les candidats issus de l’environnement ou de l’état persistant restent purement informatifs (`managed: false`, normalement `selection_unattested`) et `selectionAttested` reste `false`. La sortie JSON contient `candidateAvailable`, `candidateVersion`, `candidateSource` et `selectionAttested: false`. Une exécution directe via Bun ou depuis les sources ne fournit pas la preuve du lanceur, ignore les candidats issus de l’environnement ou de l’état persistant et peut signaler `candidate_unavailable`. Sous Windows, cette première étape n’effectue aucune E/S de système de fichiers sur les chemins du candidat ou de configuration. Seul un candidat d’environnement absolu capturé par le lanceur de confiance peut recevoir une étiquette lexicale de bundle d’application ou de gestionnaire de versions ; tous les autres candidats Windows échouent de manière fermée. Comme cette étape ne consulte jamais l’état persistant, une exécution Windows dépourvue d’un tel candidat d’environnement signale `windows_inspection_deferred` plutôt que `candidate_unavailable` : la commande ne peut pas observer si une CLI Codex est installée, elle signale donc le report de l’inspection au lieu d’affirmer qu’aucun candidat n’existe. La commande n’exécute ni Codex ni aucun gestionnaire de paquets, ne répare aucun shim, n’écrit ni dans la configuration ni dans le cache, n’arrête aucun processus et n’installe rien. Les candidats intégrés à une application, issus d’un gestionnaire de versions reconnu, autonomes mais non vérifiés, ou associés à un état de shim ambigu sont signalés comme non gérés ou inconnus et ne sont jamais classés comme gérés. ### `ocx config ...` diff --git a/docs-site/src/content/docs/ja/reference/cli/agents.md b/docs-site/src/content/docs/ja/reference/cli/agents.md index a223362a56..35e33ccac3 100644 --- a/docs-site/src/content/docs/ja/reference/cli/agents.md +++ b/docs-site/src/content/docs/ja/reference/cli/agents.md @@ -190,7 +190,7 @@ ocx system settings --stream-mode eager-relay ocx system codex-cli-update check --json ``` -`check` はパッケージレジストリに問い合わせず、設定済みのインストール候補について、秘匿化された実行ファイルの場所や所有権を示す根拠を含む来歴情報を、範囲を限定して検査します。公開ランチャー由来の信頼済みコンテキストが真正性を裏付けるのは候補のスナップショットだけであり、Codex が正常に実行されたことではありません。この単発コマンドは Codex を一切実行しないため、環境または永続化された状態から得た候補は報告対象にとどまります(`managed: false`、通常は `selection_unattested`)。`selectionAttested` は常に `false` です。JSON 出力には `candidateAvailable`、`candidateVersion`、`candidateSource`、`selectionAttested: false` が含まれます。Bun またはソースから直接起動するとランチャーの証明がないため、環境由来および永続化された候補を無視し、`candidate_unavailable` を報告することがあります。Windows では、この最初のスライスは候補や構成のパスに対するファイルシステム I/O を一切行いません。信頼済みランチャーが取り込んだ絶対パスの環境候補だけを、アプリ同梱またはバージョンマネージャーとして字句的に報告でき、それ以外の Windows 候補はすべて失敗時閉鎖になります。このコマンドは Codex やパッケージマネージャーの実行、shim の修復、設定やキャッシュ状態への書き込み、プロセスの停止、インストールを行いません。アプリ同梱、認識済みのバージョンマネージャー、未検証のスタンドアロン、曖昧な shim の各候補は管理対象外または不明として報告され、管理対象と判定されることはありません。 +`check` はパッケージレジストリに問い合わせず、設定済みのインストール候補について、秘匿化された実行ファイルの場所や所有権を示す根拠を含む来歴情報を、範囲を限定して検査します。公開ランチャー由来の信頼済みコンテキストが真正性を裏付けるのは候補のスナップショットだけであり、Codex が正常に実行されたことではありません。この単発コマンドは Codex を一切実行しないため、環境または永続化された状態から得た候補は報告対象にとどまります(`managed: false`、通常は `selection_unattested`)。`selectionAttested` は常に `false` です。JSON 出力には `candidateAvailable`、`candidateVersion`、`candidateSource`、`selectionAttested: false` が含まれます。Bun またはソースから直接起動するとランチャーの証明がないため、環境由来および永続化された候補を無視し、`candidate_unavailable` を報告することがあります。Windows では、この最初のスライスは候補や構成のパスに対するファイルシステム I/O を一切行いません。信頼済みランチャーが取り込んだ絶対パスの環境候補だけを、アプリ同梱またはバージョンマネージャーとして字句的に報告でき、それ以外の Windows 候補はすべて失敗時閉鎖になります。このスライスは永続化された選択状態を一切読み取らないため、そのような環境候補がない Windows 実行では `candidate_unavailable` ではなく `windows_inspection_deferred` を報告します。コマンドは Codex CLI が導入されているかどうかを観測できないので、候補が存在しないと断定せず、検査が延期されたことを報告します。このコマンドは Codex やパッケージマネージャーの実行、shim の修復、設定やキャッシュ状態への書き込み、プロセスの停止、インストールを行いません。アプリ同梱、認識済みのバージョンマネージャー、未検証のスタンドアロン、曖昧な shim の各候補は管理対象外または不明として報告され、管理対象と判定されることはありません。 ### `ocx config ...` diff --git a/docs-site/src/content/docs/ko/reference/cli/agents.md b/docs-site/src/content/docs/ko/reference/cli/agents.md index 76cef4bda7..2516d9f58c 100644 --- a/docs-site/src/content/docs/ko/reference/cli/agents.md +++ b/docs-site/src/content/docs/ko/reference/cli/agents.md @@ -217,7 +217,7 @@ ocx system settings --stream-mode eager-relay ocx system codex-cli-update check --json ``` -`check`는 패키지 레지스트리를 조회하지 않고, 설정된 설치 후보에 대해 전체 경로를 숨긴 실행 파일 위치와 소유권 근거를 포함한 provenance 정보를 제한된 범위에서 검사합니다. 신뢰할 수 있는 배포 런처 컨텍스트가 인증하는 것은 후보 스냅샷뿐이며, Codex가 성공적으로 실행되었다는 사실은 인증하지 않습니다. 이 단발성 명령은 Codex를 전혀 실행하지 않으므로 환경 또는 저장된 상태에서 얻은 후보는 보고 전용입니다(`managed: false`, 일반적으로 `selection_unattested`). `selectionAttested`는 항상 `false`입니다. JSON 출력에는 `candidateAvailable`, `candidateVersion`, `candidateSource`, `selectionAttested: false`가 포함됩니다. Bun이나 소스에서 직접 실행하면 런처 증거가 없으므로 환경 및 저장된 후보를 무시하고 `candidate_unavailable`을 보고할 수 있습니다. Windows에서는 이 첫 조각이 후보 또는 설정 경로의 파일시스템을 전혀 읽지 않습니다. 배포 런처가 증명한 절대 환경 후보에 한해서 앱 번들 또는 버전 관리자라는 어휘적 표지만 보고하며, 그 밖의 Windows 후보는 모두 실패 닫힘 처리합니다. 이 명령은 Codex나 패키지 관리자를 실행하거나 shim을 복구하지 않고, 설정 또는 캐시 상태를 쓰거나 프로세스를 중지하거나 어떤 것도 설치하지 않습니다. 앱에 포함된 후보, 인식된 버전 관리자의 후보, 검증되지 않은 독립 실행형 후보, shim 상태가 모호한 후보는 관리 대상이 아니거나 알 수 없는 것으로 보고되며, 관리 대상으로 분류되지 않습니다. +`check`는 패키지 레지스트리를 조회하지 않고, 설정된 설치 후보에 대해 전체 경로를 숨긴 실행 파일 위치와 소유권 근거를 포함한 provenance 정보를 제한된 범위에서 검사합니다. 신뢰할 수 있는 배포 런처 컨텍스트가 인증하는 것은 후보 스냅샷뿐이며, Codex가 성공적으로 실행되었다는 사실은 인증하지 않습니다. 이 단발성 명령은 Codex를 전혀 실행하지 않으므로 환경 또는 저장된 상태에서 얻은 후보는 보고 전용입니다(`managed: false`, 일반적으로 `selection_unattested`). `selectionAttested`는 항상 `false`입니다. JSON 출력에는 `candidateAvailable`, `candidateVersion`, `candidateSource`, `selectionAttested: false`가 포함됩니다. Bun이나 소스에서 직접 실행하면 런처 증거가 없으므로 환경 및 저장된 후보를 무시하고 `candidate_unavailable`을 보고할 수 있습니다. Windows에서는 이 첫 조각이 후보 또는 설정 경로의 파일시스템을 전혀 읽지 않습니다. 배포 런처가 증명한 절대 환경 후보에 한해서 앱 번들 또는 버전 관리자라는 어휘적 표지만 보고하며, 그 밖의 Windows 후보는 모두 실패 닫힘 처리합니다. 이 조각은 저장된 선택 상태를 전혀 읽지 않으므로, 그러한 환경 후보가 없는 Windows 실행은 `candidate_unavailable`이 아니라 `windows_inspection_deferred`를 보고합니다. 명령이 Codex CLI 설치 여부를 관측할 수 없으므로, 후보가 없다고 단정하는 대신 검사가 연기되었음을 보고합니다. 이 명령은 Codex나 패키지 관리자를 실행하거나 shim을 복구하지 않고, 설정 또는 캐시 상태를 쓰거나 프로세스를 중지하거나 어떤 것도 설치하지 않습니다. 앱에 포함된 후보, 인식된 버전 관리자의 후보, 검증되지 않은 독립 실행형 후보, shim 상태가 모호한 후보는 관리 대상이 아니거나 알 수 없는 것으로 보고되며, 관리 대상으로 분류되지 않습니다. ### `ocx config ...` diff --git a/docs-site/src/content/docs/reference/cli/agents.md b/docs-site/src/content/docs/reference/cli/agents.md index ab96881d11..4c963db73c 100644 --- a/docs-site/src/content/docs/reference/cli/agents.md +++ b/docs-site/src/content/docs/reference/cli/agents.md @@ -360,7 +360,10 @@ and `selectionAttested`. Inspecting the configured candidate requires a trusted a direct Bun/source launch has no such proof, ignores ambient and persisted candidate state, and may report `candidate_unavailable`. On Windows this first slice performs no candidate or configuration filesystem I/O: only a proof-captured absolute environment candidate can receive lexical app-bundle or version-manager labels; -every other Windows candidate fails closed. The command does not execute Codex or a package manager, repair a shim, +every other Windows candidate fails closed. Because that slice never consults persisted state, a Windows run +without such an environment candidate reports `windows_inspection_deferred` rather than `candidate_unavailable`: +the command cannot observe whether a Codex CLI is installed, so it reports the deferral instead of asserting +that no candidate exists. The command does not execute Codex or a package manager, repair a shim, write configuration or cache state, stop a process, or install anything. App-bundled, recognized version-manager, unverified standalone, and ambiguous shim states are reported as unmanaged or unknown and are never classified as managed. diff --git a/docs-site/src/content/docs/ru/reference/cli/agents.md b/docs-site/src/content/docs/ru/reference/cli/agents.md index 8df8175173..ec9a77e904 100644 --- a/docs-site/src/content/docs/ru/reference/cli/agents.md +++ b/docs-site/src/content/docs/ru/reference/cli/agents.md @@ -247,7 +247,7 @@ ocx system settings --stream-mode eager-relay ocx system codex-cli-update check --json ``` -`check` не обращается к реестру пакетов и в строго ограниченном объёме проверяет данные о происхождении настроенного кандидата, включая замаскированный путь к исполняемому файлу и подтверждения его принадлежности. Доверенный контекст опубликованного средства запуска подтверждает только подлинность снимка данных о кандидате, но не факт успешного запуска Codex. Поскольку команда выполняет только такую проверку и никогда не запускает Codex, кандидаты из окружения и сохранённых данных отображаются только в отчёте (`managed: false`, обычно `selection_unattested`). В выводе JSON присутствуют `candidateAvailable`, `candidateVersion`, `candidateSource` и `selectionAttested`, причём значение `selectionAttested` всегда равно `false`. Для проверки настроенного кандидата нужен доверенный контекст опубликованного средства запуска. При прямом запуске через Bun или из исходного кода такого подтверждения нет; в этом случае команда игнорирует кандидатов из окружения и сохранённых данных и может вернуть `candidate_unavailable`. В Windows этот первый этап вообще не выполняет файловый ввод-вывод по путям кандидата или конфигурации. Только абсолютный кандидат из окружения, зафиксированный доверенным средством запуска, может получить лексическую метку комплекта приложения или менеджера версий; все остальные кандидаты Windows отклоняются по принципу fail-closed. Команда не запускает Codex или менеджер пакетов, не восстанавливает shim, ничего не записывает в конфигурацию или кеш, не останавливает процессы и ничего не устанавливает. Кандидаты, входящие в комплект приложения, найденные в распознанных путях менеджеров версий, являющиеся непроверенными автономными установками или имеющие неоднозначное состояние shim, отображаются как `unmanaged` или `unknown` и никогда не классифицируются как `managed`. +`check` не обращается к реестру пакетов и в строго ограниченном объёме проверяет данные о происхождении настроенного кандидата, включая замаскированный путь к исполняемому файлу и подтверждения его принадлежности. Доверенный контекст опубликованного средства запуска подтверждает только подлинность снимка данных о кандидате, но не факт успешного запуска Codex. Поскольку команда выполняет только такую проверку и никогда не запускает Codex, кандидаты из окружения и сохранённых данных отображаются только в отчёте (`managed: false`, обычно `selection_unattested`). В выводе JSON присутствуют `candidateAvailable`, `candidateVersion`, `candidateSource` и `selectionAttested`, причём значение `selectionAttested` всегда равно `false`. Для проверки настроенного кандидата нужен доверенный контекст опубликованного средства запуска. При прямом запуске через Bun или из исходного кода такого подтверждения нет; в этом случае команда игнорирует кандидатов из окружения и сохранённых данных и может вернуть `candidate_unavailable`. В Windows этот первый этап вообще не выполняет файловый ввод-вывод по путям кандидата или конфигурации. Только абсолютный кандидат из окружения, зафиксированный доверенным средством запуска, может получить лексическую метку комплекта приложения или менеджера версий; все остальные кандидаты Windows отклоняются по принципу fail-closed. Поскольку этот этап вообще не читает сохранённое состояние выбора, запуск в Windows без такого кандидата из окружения возвращает `windows_inspection_deferred`, а не `candidate_unavailable`: команда не может определить, установлен ли Codex CLI, поэтому сообщает об отложенной проверке, а не утверждает, что кандидата нет. Команда не запускает Codex или менеджер пакетов, не восстанавливает shim, ничего не записывает в конфигурацию или кеш, не останавливает процессы и ничего не устанавливает. Кандидаты, входящие в комплект приложения, найденные в распознанных путях менеджеров версий, являющиеся непроверенными автономными установками или имеющие неоднозначное состояние shim, отображаются как `unmanaged` или `unknown` и никогда не классифицируются как `managed`. ### `ocx config ...` diff --git a/docs-site/src/content/docs/tr/reference/cli/agents.md b/docs-site/src/content/docs/tr/reference/cli/agents.md index 04e72a766c..234256edd6 100644 --- a/docs-site/src/content/docs/tr/reference/cli/agents.md +++ b/docs-site/src/content/docs/tr/reference/cli/agents.md @@ -294,7 +294,7 @@ ocx system settings --stream-mode eager-relay ocx system codex-cli-update check --json ``` -`check` paket kayıt defterine istek göndermez ve yapılandırmada belirtilen kurulum adayına ilişkin provenance kanıtını, maskelenmiş yürütülebilir dosya konumu ve sahiplik kanıtı dâhil, sınırlı biçimde inceler. Yayımlanmış başlatıcıdan gelen güvenilir bağlam aday anlık görüntüsünü doğrular; Codex'in başarıyla çalıştırıldığını doğrulamaz. Bu tek seferlik komut Codex'i hiçbir zaman çalıştırmadığından, ortamdan ve kalıcı kayıtlardan gelen adaylar yalnızca raporlanır (`managed: false`, genellikle `selection_unattested`). JSON çıktısında `candidateAvailable`, `candidateVersion` ve `candidateSource` alanları bulunur; `selectionAttested` değeri ise `false` kalır. Yapılandırmada belirtilen kurulum adayını incelemek için yayımlanmış başlatıcıdan gelen güvenilir bağlam gerekir; Bun ile veya kaynak koddan doğrudan başlatıldığında bu kanıt bulunmadığından ortamdaki ve kalıcı kayıtlardaki aday durumu yok sayılır ve `candidate_unavailable` bildirilebilir. Windows'ta bu ilk parça, aday veya yapılandırma yollarında hiçbir dosya sistemi G/Ç işlemi yapmaz. Yalnızca güvenilir başlatıcının yakaladığı mutlak bir ortam adayı sözcüksel olarak uygulama paketi ya da sürüm yöneticisi etiketi alabilir; diğer tüm Windows adayları kapalı başarısızlıkla reddedilir. Komut Codex veya bir paket yöneticisi çalıştırmaz, shim'i onarmaz, yapılandırmaya ya da önbellek durumuna yazmaz, hiçbir süreci durdurmaz ve hiçbir şey kurmaz. Uygulamayla birlikte paketlenmiş adaylar, tanınan sürüm yöneticisi yollarında bulunan adaylar, doğrulanmamış bağımsız adaylar ve belirsiz shim durumları `unmanaged` veya `unknown` olarak raporlanır; hiçbir zaman `managed` olarak sınıflandırılmaz. +`check` paket kayıt defterine istek göndermez ve yapılandırmada belirtilen kurulum adayına ilişkin provenance kanıtını, maskelenmiş yürütülebilir dosya konumu ve sahiplik kanıtı dâhil, sınırlı biçimde inceler. Yayımlanmış başlatıcıdan gelen güvenilir bağlam aday anlık görüntüsünü doğrular; Codex'in başarıyla çalıştırıldığını doğrulamaz. Bu tek seferlik komut Codex'i hiçbir zaman çalıştırmadığından, ortamdan ve kalıcı kayıtlardan gelen adaylar yalnızca raporlanır (`managed: false`, genellikle `selection_unattested`). JSON çıktısında `candidateAvailable`, `candidateVersion` ve `candidateSource` alanları bulunur; `selectionAttested` değeri ise `false` kalır. Yapılandırmada belirtilen kurulum adayını incelemek için yayımlanmış başlatıcıdan gelen güvenilir bağlam gerekir; Bun ile veya kaynak koddan doğrudan başlatıldığında bu kanıt bulunmadığından ortamdaki ve kalıcı kayıtlardaki aday durumu yok sayılır ve `candidate_unavailable` bildirilebilir. Windows'ta bu ilk parça, aday veya yapılandırma yollarında hiçbir dosya sistemi G/Ç işlemi yapmaz. Yalnızca güvenilir başlatıcının yakaladığı mutlak bir ortam adayı sözcüksel olarak uygulama paketi ya da sürüm yöneticisi etiketi alabilir; diğer tüm Windows adayları kapalı başarısızlıkla reddedilir. Bu parça kalıcı seçim durumunu hiç okumadığından, böyle bir ortam adayı bulunmayan Windows çalıştırmaları `candidate_unavailable` yerine `windows_inspection_deferred` bildirir: komut bir Codex CLI'nin kurulu olup olmadığını gözlemleyemez, bu yüzden aday bulunmadığını iddia etmek yerine incelemenin ertelendiğini bildirir. Komut Codex veya bir paket yöneticisi çalıştırmaz, shim'i onarmaz, yapılandırmaya ya da önbellek durumuna yazmaz, hiçbir süreci durdurmaz ve hiçbir şey kurmaz. Uygulamayla birlikte paketlenmiş adaylar, tanınan sürüm yöneticisi yollarında bulunan adaylar, doğrulanmamış bağımsız adaylar ve belirsiz shim durumları `unmanaged` veya `unknown` olarak raporlanır; hiçbir zaman `managed` olarak sınıflandırılmaz. ### `ocx config ...` diff --git a/docs-site/src/content/docs/zh-cn/reference/cli/agents.md b/docs-site/src/content/docs/zh-cn/reference/cli/agents.md index 89203420e9..8cd3c7bcf2 100644 --- a/docs-site/src/content/docs/zh-cn/reference/cli/agents.md +++ b/docs-site/src/content/docs/zh-cn/reference/cli/agents.md @@ -197,7 +197,7 @@ ocx system settings --stream-mode eager-relay ocx system codex-cli-update check --json ``` -`check` 不会向软件包注册表发起请求,只会在限定范围内检查已配置候选项的来源证据,包括经过脱敏的可执行文件位置和所有权证据。受信任的已发布启动器上下文只能验证该候选项快照,并不证明 Codex 已成功运行。由于这条一次性命令绝不会运行 Codex,来自环境变量和持久化记录的候选项仅用于报告(`managed: false`,通常为 `selection_unattested`);JSON 输出包含 `candidateAvailable`、`candidateVersion` 和 `candidateSource`,且 `selectionAttested` 始终为 `false`。检查已配置候选项需要受信任的已发布启动器上下文;直接使用 Bun 启动或从源码运行时没有这项证明,因此会忽略环境变量和持久化记录中的候选项状态,并可能报告 `candidate_unavailable`。在 Windows 上,这个首个切片不会对候选路径或配置路径执行任何文件系统 I/O。只有由受信任启动器捕获的绝对环境候选项可以获得应用捆绑或版本管理器的纯词法标签;其他所有 Windows 候选项都会以失败关闭方式处理。该命令不会运行 Codex 或软件包管理器,不会修复 shim,不会写入配置或缓存,不会停止进程,也不会安装任何内容。随应用捆绑的候选项、位于已识别版本管理器路径中的候选项、未经验证的独立候选项以及 shim 状态不明确的候选项,都会报告为 `unmanaged` 或 `unknown`,绝不会归类为 `managed`。 +`check` 不会向软件包注册表发起请求,只会在限定范围内检查已配置候选项的来源证据,包括经过脱敏的可执行文件位置和所有权证据。受信任的已发布启动器上下文只能验证该候选项快照,并不证明 Codex 已成功运行。由于这条一次性命令绝不会运行 Codex,来自环境变量和持久化记录的候选项仅用于报告(`managed: false`,通常为 `selection_unattested`);JSON 输出包含 `candidateAvailable`、`candidateVersion` 和 `candidateSource`,且 `selectionAttested` 始终为 `false`。检查已配置候选项需要受信任的已发布启动器上下文;直接使用 Bun 启动或从源码运行时没有这项证明,因此会忽略环境变量和持久化记录中的候选项状态,并可能报告 `candidate_unavailable`。在 Windows 上,这个首个切片不会对候选路径或配置路径执行任何文件系统 I/O。只有由受信任启动器捕获的绝对环境候选项可以获得应用捆绑或版本管理器的纯词法标签;其他所有 Windows 候选项都会以失败关闭方式处理。由于这个切片完全不读取持久化的选择状态,在没有此类环境候选项的 Windows 上运行时会报告 `windows_inspection_deferred` 而非 `candidate_unavailable`:该命令无法观测 Codex CLI 是否已安装,因此报告检查被推迟,而不是断言不存在候选项。该命令不会运行 Codex 或软件包管理器,不会修复 shim,不会写入配置或缓存,不会停止进程,也不会安装任何内容。随应用捆绑的候选项、位于已识别版本管理器路径中的候选项、未经验证的独立候选项以及 shim 状态不明确的候选项,都会报告为 `unmanaged` 或 `unknown`,绝不会归类为 `managed`。 ### `ocx config ...` diff --git a/docs-site/src/content/docs/zh-tw/reference/cli/agents.md b/docs-site/src/content/docs/zh-tw/reference/cli/agents.md index d04c099ebf..ec2dfac6ad 100644 --- a/docs-site/src/content/docs/zh-tw/reference/cli/agents.md +++ b/docs-site/src/content/docs/zh-tw/reference/cli/agents.md @@ -200,7 +200,7 @@ ocx system settings --stream-mode eager-relay ocx system codex-cli-update check --json ``` -`check` 不會向套件 registry 發出請求,只會在限定範圍內檢查設定中的安裝候選項來源證據,包括經過遮罩的可執行檔位置與所有權證據。正式發布的 launcher 所提供的可信內容只會驗證該候選項快照,並不證明 Codex 已成功執行。由於這個單次命令絕不會執行 Codex,來自環境變數與持久化記錄的候選項只供報告(`managed: false`,通常為 `selection_unattested`);JSON 輸出包含 `candidateAvailable`、`candidateVersion` 與 `candidateSource`,而 `selectionAttested` 維持 `false`。檢查設定中的安裝候選項時,必須有正式發布的 launcher 所提供的可信內容;直接使用 Bun 啟動或從原始碼執行時不具備這項證明,因此會忽略來自環境與持久化記錄的候選項狀態,並可能報告 `candidate_unavailable`。在 Windows 上,這個首個切片不會對候選路徑或設定路徑執行任何檔案系統 I/O。只有由可信 launcher 擷取的絕對環境候選項可以取得應用程式封裝或版本管理工具的純詞彙標籤;其他所有 Windows 候選項都會以失敗關閉方式處理。此命令不會執行 Codex 或套件管理工具、不會修復 shim、不會寫入設定或快取、不會停止程序,也不會安裝任何內容。隨應用程式封裝的候選項、位於已識別版本管理工具路徑中的候選項、未經驗證的獨立候選項,以及 shim 狀態不明確的候選項,都會報告為 `unmanaged` 或 `unknown`,絕不會歸類為 `managed`。 +`check` 不會向套件 registry 發出請求,只會在限定範圍內檢查設定中的安裝候選項來源證據,包括經過遮罩的可執行檔位置與所有權證據。正式發布的 launcher 所提供的可信內容只會驗證該候選項快照,並不證明 Codex 已成功執行。由於這個單次命令絕不會執行 Codex,來自環境變數與持久化記錄的候選項只供報告(`managed: false`,通常為 `selection_unattested`);JSON 輸出包含 `candidateAvailable`、`candidateVersion` 與 `candidateSource`,而 `selectionAttested` 維持 `false`。檢查設定中的安裝候選項時,必須有正式發布的 launcher 所提供的可信內容;直接使用 Bun 啟動或從原始碼執行時不具備這項證明,因此會忽略來自環境與持久化記錄的候選項狀態,並可能報告 `candidate_unavailable`。在 Windows 上,這個首個切片不會對候選路徑或設定路徑執行任何檔案系統 I/O。只有由可信 launcher 擷取的絕對環境候選項可以取得應用程式封裝或版本管理工具的純詞彙標籤;其他所有 Windows 候選項都會以失敗關閉方式處理。由於這個切片完全不會讀取持久化的選擇狀態,在沒有這類環境候選項的 Windows 上執行時會報告 `windows_inspection_deferred` 而非 `candidate_unavailable`:該命令無法觀測 Codex CLI 是否已安裝,因此會報告檢查被延後,而不是斷言候選項不存在。此命令不會執行 Codex 或套件管理工具、不會修復 shim、不會寫入設定或快取、不會停止程序,也不會安裝任何內容。隨應用程式封裝的候選項、位於已識別版本管理工具路徑中的候選項、未經驗證的獨立候選項,以及 shim 狀態不明確的候選項,都會報告為 `unmanaged` 或 `unknown`,絕不會歸類為 `managed`。 ### `ocx config ...` diff --git a/src/codex/cli-install-provenance.ts b/src/codex/cli-install-provenance.ts index ffca581f5f..5c253196ff 100644 --- a/src/codex/cli-install-provenance.ts +++ b/src/codex/cli-install-provenance.ts @@ -587,8 +587,14 @@ export async function inspectCodexCliInstall( const platform = deps.platform ?? process.platform; const candidate = observeCodexRuntimeCandidateReadOnly(deps); if (!candidate) { + // This slice reads no candidate or configuration file on Windows, so an + // absent proof-captured environment candidate does not establish that no + // Codex CLI exists: a persisted selection is simply never consulted there. + // Report the deferral that actually happened instead of the stronger claim + // that the candidate is unavailable. POSIX did observe persisted state, so + // its absent-candidate answer stays exact. return isWindowsPlatform(platform) - ? unknownWindowsReport("candidate_unavailable") + ? unknownWindowsReport("windows_inspection_deferred") : unknownReport("candidate_unavailable"); } diff --git a/tests/codex-integration/codex-cli-install-provenance.test.ts b/tests/codex-integration/codex-cli-install-provenance.test.ts index 31635b2afd..a62f5c7f9f 100644 --- a/tests/codex-integration/codex-cli-install-provenance.test.ts +++ b/tests/codex-integration/codex-cli-install-provenance.test.ts @@ -108,7 +108,7 @@ describe("Codex CLI install provenance", () => { expect(calls).toBe(0); }); - test("Windows does not read persisted candidate state", async () => { + test("Windows reports a deferred inspection rather than an absent candidate", async () => { let calls = 0; const report = await inspectCodexCliInstall({ ...noFilesystemDeps(() => { calls += 1; }), @@ -116,9 +116,35 @@ describe("Codex CLI install provenance", () => { configDir: "C:\\OpenCodex", env: { PATH: "C:\\Tools" }, }); + // Persisted state is still never read on Windows, so the command cannot + // know whether a candidate exists. It must not claim that none does. + expect(report.reason).toBe("windows_inspection_deferred"); expect(report.candidateAvailable).toBe(false); - expect(report.reason).toBe("candidate_unavailable"); + expect(report.candidateSource).toBeNull(); + expect(report.candidateVersion).toBeNull(); + expect(report.location).toBeNull(); + expect(report.provenance).toBe("unknown"); + expect(report.managed).toBe(false); + expect(report.selectionAttested).toBe(false); + expect(report.versionEvidence.kind).toBe("unavailable"); expect(report.shim.status).toBe("unknown"); + expect(report.evidence).toEqual([]); + expect(calls).toBe(0); + }); + + test("a POSIX run that observed no persisted candidate still reports it as unavailable", async () => { + let calls = 0; + const report = await inspectCodexCliInstall({ + ...noFilesystemDeps(() => { calls += 1; }), + platform: "linux", + configDir: "relative-config-dir", + env: { PATH: "" }, + }); + // The deferral wording is Windows-only: POSIX actually consults persisted + // state, so an absent candidate there remains an exact answer. + expect(report.reason).toBe("candidate_unavailable"); + expect(report.candidateAvailable).toBe(false); + expect(report.shim.status).toBe("not-tracked"); expect(calls).toBe(0); }); From 58ea8b62794e26102c5cf54ac6fd2ba0b078e956 Mon Sep 17 00:00:00 2001 From: luvs01 <27862058+luvs01@users.noreply.github.com> Date: Thu, 10 Sep 2026 13:50:11 +0900 Subject: [PATCH 2/2] test(codex): describe unobserved candidate evidence precisely --- src/codex/cli-install-provenance.ts | 4 ++-- .../codex-integration/codex-cli-install-provenance.test.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/codex/cli-install-provenance.ts b/src/codex/cli-install-provenance.ts index 5c253196ff..e595205518 100644 --- a/src/codex/cli-install-provenance.ts +++ b/src/codex/cli-install-provenance.ts @@ -591,8 +591,8 @@ export async function inspectCodexCliInstall( // absent proof-captured environment candidate does not establish that no // Codex CLI exists: a persisted selection is simply never consulted there. // Report the deferral that actually happened instead of the stronger claim - // that the candidate is unavailable. POSIX did observe persisted state, so - // its absent-candidate answer stays exact. + // that the candidate is unavailable. POSIX retains its existing result + // when no candidate is observed. return isWindowsPlatform(platform) ? unknownWindowsReport("windows_inspection_deferred") : unknownReport("candidate_unavailable"); diff --git a/tests/codex-integration/codex-cli-install-provenance.test.ts b/tests/codex-integration/codex-cli-install-provenance.test.ts index a62f5c7f9f..095ad2dc8a 100644 --- a/tests/codex-integration/codex-cli-install-provenance.test.ts +++ b/tests/codex-integration/codex-cli-install-provenance.test.ts @@ -132,7 +132,7 @@ describe("Codex CLI install provenance", () => { expect(calls).toBe(0); }); - test("a POSIX run that observed no persisted candidate still reports it as unavailable", async () => { + test("a POSIX run with no observed candidate retains candidate_unavailable", async () => { let calls = 0; const report = await inspectCodexCliInstall({ ...noFilesystemDeps(() => { calls += 1; }), @@ -140,8 +140,8 @@ describe("Codex CLI install provenance", () => { configDir: "relative-config-dir", env: { PATH: "" }, }); - // The deferral wording is Windows-only: POSIX actually consults persisted - // state, so an absent candidate there remains an exact answer. + // The relative configuration path is rejected without I/O. This control + // preserves the existing POSIX reason when no candidate is observed. expect(report.reason).toBe("candidate_unavailable"); expect(report.candidateAvailable).toBe(false); expect(report.shim.status).toBe("not-tracked");