iT邦幫忙

2026 iThome 鐵人賽

DAY 18
0
ChatGPT & Codex

當 Codex 開始自己工作:從 Prompt Engineering 到 Agent Governance系列 第 18 篇

Day 18|Execution Environment Identity:同一個 Repo 換台機器,為什麼 Verification 就不一樣?

  • 分享至 

  • xImage
  •  

Codex Day 18 Execution Environment Identity

Day 17 把 Targeted、Regression、Smoke 各自的責任拆開後,還有一個常見誤區:

同一個 Repository、同一個 commit,Verification 結果應該一樣。

但 Android / Gradle 的實際驗證曾出現另一種情況:同一份 code state 還沒進到測試本體,結果就先被執行環境決定了。

Android SDK、JBR、Gradle cache、shell 與 CLI availability,都可能先於 source code 決定 verification command 能不能成立。

Code Identity 相同,不代表 Execution Environment Identity 相同。

一次根本沒有進到測試本體的失敗

在一個 Android 專案的 verification record 裡,原本要執行:

gradlew.bat :app:testDebugUnitTest
--tests tw.com.dailycheckin.evidence.EvidenceSanitizerTest

這次不是 assertion failure,也不是 Kotlin compile error;實際狀態是:

TEST_NOT_STARTED / ENVIRONMENT_FAILED

原因是當時 local.properties 指向的 Android SDK 不存在。即使換到 sandbox 外重試,仍得到同樣結果;Kotlin compilation 與 Gradle test 都沒有開始。

如果只看到「Gradle command failed」,很容易直接往 source code、test code 或 build script 找問題;但這次失敗發生在測試本體之前。

原本的假設:

command failed → code / test 有問題

被 Evidence 改成:

command 是否真的進入被驗證的那一層,要先看 execution environment。

因此非零 exit 不能一律叫做「測試失敗」;先確認 command 是否真的進入被驗證的那一層。

Fallback PASS 也不能偷換成原本的 PASS

同一份 verification record 後來使用既有 cache、可用的 JBR runtime 與 Kotlin compiler 做較小範圍的 fallback verification。

結果:

pure Kotlin compilation: PASS
JUnit: OK (5 tests)

但這份 Evidence 明確留下限制:

  • 不是 Android build;
  • 不是完整 Gradle test;
  • 不是 full handler regression suite。

重點不是「最後還是有 PASS」,而是 fallback 改變了 Verification Scope。

原本要證明的是 Android / Gradle 路徑中的特定 test;fallback 最後只能證明部分純 Kotlin logic 在另一組 runtime/toolchain 條件下成立。

所以不能寫成:

Gradle test failed
→ fallback passed
→ verification passed

比較準確的是:

canonical verification
→ ENVIRONMENT_FAILED / TEST_NOT_STARTED

fallback verification
→ PASS
→ narrower claim only

Execution Environment 一變,Evidence 能支撐的 Claim 也跟著變。

Codex Day 18 execution environment verification scope

這篇和 Deployment Environment 不同

Bento 系列的 Environment Boundary 比較接近:

localhost
vs
remote Worker
vs
production-like runtime

那是在問服務「部署到哪裡」之後,CORS、network path、runtime behavior 是否仍成立。

這篇關心的是 Agent 自己「站在哪裡執行」:

OS
runtime / JBR
Android SDK
Gradle user home / cache
shell
filesystem
sandbox
CLI availability

兩者都叫 environment,但責任不同:Deployment Environment 是被驗證系統所在的位置;Execution Environment 是 Agent 產生 Evidence 時所在的位置。

Environment policy 不能只存在某次 Session

環境問題如果每次都靠 Agent 臨場猜,會出現另一種 drift:

Session A
→ cache path A
→ PASS

Session B
→ 隨手換另一個 -g path
→ PASS / FAIL

Session C
→ 再重新下載或改 build 設定

最後三個 Session 即使都寫「我有跑 Gradle」,其實未必在同一個 execution contract 下工作。

shared verification rule 對 Windows Gradle 做了更窄的規定:

if ([string]::IsNullOrWhiteSpace($env:GRADLE_USER_HOME)) {
    $env:GRADLE_USER_HOME = Join-Path $env:USERPROFILE '.gradle'
}

如果 GRADLE_USER_HOME 已經存在,就保留;如果為空,才從 USERPROFILE 推導。

同時禁止幾種過去看似方便、但會讓環境身分越來越模糊的 fallback:

C:\.gradle
C:.gradle
repo-local .gradle-user
arbitrary -g fallback path

這條規則不是讓 Gradle 比較「聰明」,而是把一部分 environment identity 固定下來,並要求 verification evidence 記錄最後使用的 GRADLE_USER_HOME,以及它是 preserved 還是 derived。

Fallback 的目的不是把結果弄綠

fallback 不是:

canonical command 跑不起來,就想辦法找一條會 PASS 的路。

比較安全的流程是:

canonical command
↓
identify why it cannot run
↓
classify environment / dependency / command failure
↓
use an approved fallback only if one exists
↓
record changed environment + changed scope
↓
limit the completion claim

如果 fallback 需要改 source、改 wrapper version、改 gradle.properties,只是為了解決 cache / permission / SDK 狀態,那通常已經跨過合理邊界。

環境問題不該被偽裝成 code fix。

Environment Drift 和 Code Drift 要先分流

遇到 verification 差異時,可以先分成兩組問題。

第一組:

same HEAD
same command
different environment
different result

優先比較:

  • OS / shell;
  • runtime / JDK / JBR;
  • SDK availability;
  • cache / dependency state;
  • sandbox / filesystem permission;
  • required CLI 是否存在。

第二組:

same environment
different HEAD
different result

才更有理由優先追 code change。

這個分流主要是避免一種高成本誤判:

為了修執行環境,去修改原本沒有壞的程式。

最小 Environment Contract

長期 Repository 不一定需要厚重的 setup manual。

但如果它要求 Agent 自主 verification,至少要能回答:

  • canonical verification command 與 supported runtime / toolchain;
  • 必要的 environment state;
  • approved fallback,以及 fallback 後少了哪些 Verification Scope;
  • optional tooling;
  • sandbox / credential / device limitation。

這些資訊不只是 onboarding;它們會直接決定一份 PASS 能被帶多遠。

Environment Identity 讓 Verification 變成完整句子

Day 16 把 Evidence Provenance 補上 state、method、environment、limitation;Day 17 再拆開不同 test type 各自在證明什麼。

Day 18 補上一個常被省略的判斷:

Environment 不是 PASS 旁邊的附註,而是 PASS 成立條件的一部分。

所以一個可信的 verification claim 比較像:

在某個 state、某個 execution environment,用某個 method,針對某個 risk 得到 PASS;fallback 若改變 runtime 或 scope,就另外標示,其餘範圍未驗。

這比單純一句「tests passed」少了一點俐落,卻多了下一個人真正能判斷的資訊。

下一篇會把焦點從 Evidence 切回 Authority:即使 Agent 已經證明自己有能力執行某件事,也不代表這次就被授權執行那個 action。


上一篇
Day 17|Targeted、Regression、Smoke 到底各自在證明什麼?
系列文
當 Codex 開始自己工作:從 Prompt Engineering 到 Agent Governance 共 18 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言