4D PluginLoader contract 草案 / 實作前確認表
本文件承接 4D PluginLoader 邊界分析 與 4D PluginLoader 決策確認表,整理 4D 進入任何程式修改前需要再次確認的 contract 草案、候選檔案、測試策略與停止線。
本文件記錄使用者已同意 4D contract 七項文件型決策;此同意只代表可進入程式 repo 唯讀結構檢查與最小 contract 實作評估,不代表已同意建立 PluginLoader、建立 IPluginLoader public contract、掃描 plugin folder、載入外部 DLL、執行外部程式碼、修改 IDeviceAdapter public contract、修改 config schema、導入 plugin framework、保存正式 DLL 路徑、接真實硬體、執行正式 DB DDL 或改變程式啟動方式。
0. 確認狀態
| 項目 | 內容 |
| 文件狀態 | 已確認 |
| 整理日期 | 2026-06-06 |
| 確認日期 | 2026-06-06 |
| 對應階段 | 第四階段 4D PluginLoader contract |
| 程式基準 commit | a846212 新增 4C ServiceHost 第一版與驗收測試 |
| 本文件目標 | 固定 metadata、verification result、state、audit、候選檔案、測試策略與停止線 |
| 確認後可進入 | 程式 repo 唯讀結構檢查與最小 contract 實作評估 |
| 本文件仍不做 | 不建立 Loader、不載入 DLL、不掃描 plugin folder、不改 Adapter / config / DB、不接真實硬體 |
1. Contract 第一版定位
| 原則 | 說明 |
| Contract 先於 Loader | 先固定資料模型、狀態、錯誤與測試語意,不建立實際 Loader。 |
| Metadata 不等於載入授權 | metadata 通過格式檢查仍不得自動進入 Loaded。 |
| Verification 是獨立結果 | checksum、來源、版本、敏感資訊與人工核准都要回到標準結果。 |
| State 不直接執行 | Discovered、Verified、Rejected、Disabled、Faulted 只代表狀態語意,不代表呼叫 DLL。 |
| Audit 先採安全摘要 | 可先定義 audit record,不寫 DB、不保存正式路徑或敏感資訊。 |
| Lifecycle 由 ServiceHost 承接 | 未來若有 Loader lifecycle,應由 ServiceHost 組裝,不由 WebApi Controller 載入 DLL。 |
2. Metadata contract 草案
| 欄位 | 建議語意 | 第一版限制 |
PluginId | Plugin 唯一識別,需穩定且不可空白。 | 不得含路徑、IP、Port 或 secret。 |
DisplayName | 人員可讀名稱。 | 不作為安全判斷依據。 |
Version | Plugin 版本。 | 需與 contract version 分開。 |
ContractVersion | 目標 Application / Adapter contract 版本。 | 不相容時只能拒絕,不自動降級。 |
Source | plugin 來源,例如 repository fixture 或受控白名單來源。 | 不接受任意資料夾。 |
Checksum | artifact checksum 宣告值。 | 本階段只定義欄位與比對規則,不讀檔。 |
Capabilities | 對應 3D capability、device type、command name。 | 不得繞過 Resource / Command / Adapter 邊界。 |
Enabled | 是否允許被 catalog 顯示為可候選。 | 不代表可載入或可執行。 |
DisabledReason | 停用原因。 | 不保存敏感資訊或完整例外。 |
3. Verification result 草案
| 欄位 | 建議語意 |
Success | 驗證是否通過。 |
Code | 標準錯誤碼,建議延續 Application APP-03xx 區段或另列 APP-04xx 候選。 |
Message | 安全摘要,不包含 secret、正式路徑、完整 stack trace。 |
PluginId | 對應 plugin identity。 |
State | 驗證後狀態,例如 Verified、Rejected、Disabled、Faulted。 |
Checks | 來源、checksum、版本、敏感資訊、人工核准等子檢查摘要。 |
Warnings | 非阻擋但需提示的問題。 |
TimeTakenMs | 驗證耗時。 |
4. State contract 草案
| 狀態 | 語意 | 是否可執行 |
Discovered | 已發現 metadata 或候選描述。 | 否 |
Verified | metadata、來源、checksum、版本與必要核准通過。 | 否,本階段仍不載入 |
Rejected | 驗證失敗或來源不可信。 | 否 |
Disabled | 被人工或策略停用。 | 否 |
Faulted | 驗證或未來 lifecycle 發生錯誤。 | 否 |
Loaded | 保留給未來 Loader 實作。 | 本階段不可使用 |
5. Audit contract 草案
| 欄位 | 建議語意 | 限制 |
AuditId | 單筆 audit 識別。 | 可用記憶體或測試用 id,不寫正式 DB。 |
PluginId | 對應 plugin。 | 不可空白。 |
Decision | Verified、Rejected、Disabled、Faulted 等結果。 | 不等於執行授權。 |
Reason | 人工或系統原因摘要。 | 不包含 secret、正式路徑或完整 exception。 |
Operator | 操作者或系統來源。 | 若無正式帳號,只能用測試值。 |
Source | 安全來源摘要。 | 不保存完整正式 DLL path。 |
Checksum | checksum 摘要。 | 可遮罩或縮短。 |
CreatedAtUtc | 發生時間。 | 使用 UTC。 |
6. 候選程式檔案
以下只是使用者確認後的候選範圍,尚未授權修改程式 repo。
| 類型 | 候選檔案或位置 |
| Application plugin contract | src/HS.DeviceControl.Application/Plugins/* |
| Verification model | src/HS.DeviceControl.Application/Plugins/PluginVerificationResult.cs |
| State enum | src/HS.DeviceControl.Application/Plugins/PluginLoadState.cs |
| Audit model | src/HS.DeviceControl.Application/Plugins/PluginAuditRecord.cs |
| Catalog extension | 既有 IPluginCatalogService / PluginCatalogService,僅評估是否補只讀查詢 |
| 測試 | tests/HS.DeviceControl.Application.Tests/Plugins/* |
| Solution | 原則上不新增專案,不需修改 .sln |
| 文件 | contract 決策確認、程式 repo 結構檢查、實作紀錄、完成稽核、驗收紀錄 |
7. 測試策略
| 測試 | 目的 | 本輪是否可確認 |
| Metadata required fields | 驗證必要欄位缺漏會回標準錯誤。 | 可確認 |
| Sensitive data rejection | 驗證 metadata 內含 password、token、connection string、正式 IP / Port 時被拒絕。 | 可確認 |
| Checksum mismatch | 驗證 checksum 不符會回 Rejected。 | 可確認,但不讀真實 DLL |
| Version mismatch | 驗證 contract version 不相容會被拒絕。 | 可確認 |
| Disabled plugin | 驗證停用 plugin 不可被視為可載入。 | 可確認 |
| Audit summary | 驗證 audit 不含 secret 或正式路徑。 | 可確認 |
| Loader lifecycle | 驗證 load / unload / recover。 | 不可確認,需另行授權 |
| External DLL test | 使用測試 DLL 驗證載入。 | 不可確認,需另行授權 |
8. 七項 contract 確認表
使用者已同意以下七項,可進入程式 repo 唯讀結構檢查與最小 contract 實作評估。
| 編號 | 決策項 | 確認結果 | 影響 |
| 1 | 4D contract 第一版放在 Application Plugins 區域 | 已同意,第一版只評估 Application 層 model / service extension。 | 不新增 Loader 專案。 |
| 2 | 第一版新增或補齊 metadata / verification / state / audit contract | 已同意,可盤點候選 model 與 tests。 | 不載入 DLL。 |
| 3 | 不建立 IPluginLoader public contract | 已同意,Loader 仍留在後續階段。 | 避免過早固定載入 API。 |
| 4 | 不修改 IDeviceAdapter public contract | 已同意,plugin capability 必須經 Adapter / dispatcher 邊界承接。 | 保持既有分層。 |
| 5 | 不修改 config schema,不保存正式 DLL path 或敏感資訊 | 已同意,只做 model / test,不改 devices.json、workflows.json、appsettings.json。 | 避免未成熟 schema 進正式契約。 |
| 6 | 測試只做 metadata / verification / audit,不做外部 DLL | 已同意,測試不呼叫 assembly loading API。 | 降低外部程式碼風險。 |
| 7 | 程式修改前先做唯讀結構檢查並回報候選檔案 | 已同意,先盤點程式 repo,再決定是否實作。 | 保留使用者確認點。 |
使用者確認文字:
4D contract 確認:1. 同意 ... 7. 同意
9. 仍需停止的項目
- 不建立
PluginLoader 程式。 - 不建立
IPluginLoader public contract。 - 不掃描 plugin folder。
- 不載入外部 DLL。
- 不呼叫
Assembly.Load、LoadFrom、LoadFile 或類似 API。 - 不執行外部 plugin 程式碼。
- 不新增或更換 plugin framework / DI framework / sandbox 套件。
- 不修改
IDeviceAdapter public contract。 - 不修改 Core / Adapters / Infrastructure / Application 既有 public method 簽章。
- 不修改
devices.json、workflows.json、appsettings.json schema。 - 不保存密碼、Token、IP、Port、完整 connection string、正式 DLL 路徑或正式環境資訊。
- 不執行 DB 寫入、DDL、ALTER TABLE 或正式 Apply。
- 不接真實硬體或案場客製 plugin。
10. 建議下一步
七項確認已完成,且程式 repo 唯讀結構檢查已整理完成。下一步建議進入 4D 最小 Application plugin contract 實作前最後確認,確認 PluginLoadState、PluginVerificationResult、PluginAuditRecord 與測試策略後,再決定是否修改程式 repo。