# 4D 最小 Application plugin contract 實作前最後確認表

本文件承接 [4D PluginLoader contract 草案 / 實作前確認表](phase-four-d-pluginloader-contract-preimplementation-checklist.md) 與 [4D PluginLoader 程式 repo 結構檢查表](phase-four-d-pluginloader-code-structure-preimplementation-checklist.md)，用來在修改程式 repo 前最後確認 4D 最小 Application plugin contract 的候選檔案、欄位、測試策略與停止線。

本文件仍不代表同意建立真正 PluginLoader、不代表同意建立 `IPluginLoader` public contract、不代表同意掃描 plugin folder、載入外部 DLL、執行外部 plugin 程式碼、修改 Adapter public contract、修改 config schema、執行 DB DDL 或接真實硬體。

## 0. 確認狀態

| 項目 | 內容 |
|---|---|
| 文件狀態 | 已確認 |
| 整理日期 | 2026-06-06 |
| 確認日期 | 2026-06-06 |
| 對應階段 | 第四階段 4D 最小 Application plugin contract |
| 程式 repo | `hs-device-control-template` |
| 程式 branch | `poc/nmodbus-tcp` |
| 程式基準 commit | `a846212 新增 4C ServiceHost 第一版與驗收測試` |
| 前置確認 | 4D 邊界分析、決策確認、contract 確認、程式 repo 唯讀結構檢查均已完成 |
| 使用者確認 | `4D 最小 contract 確認` 七項皆同意 |
| 確認後可進入 | 程式 repo 最小 Application plugin contract 實作；本機實作與測試已完成 |
| 本文件仍不做 | 不修改程式 repo、不建立 Loader、不載入 DLL、不改 Adapter / config / DB |

## 1. 實作定位

| 原則 | 說明 |
|---|---|
| Application contract only | 只補 `HS.DeviceControl.Application/Plugins` 的 model / result / audit 類別。 |
| Metadata 仍不是載入授權 | 即使 metadata 驗證成功，也不代表可載入 DLL 或執行 plugin。 |
| State 只表示審核狀態 | `Verified`、`Rejected`、`Disabled`、`Faulted` 不觸發任何 loader lifecycle。 |
| Audit 只做安全摘要 | audit record 不寫 DB、不保存正式路徑、不包含 secret 或完整 exception。 |
| 測試先於擴大 | 第一版只用 Application.Tests 驗證 contract，不做外部 DLL 測試。 |

## 2. 預計新增檔案

| 檔案 | 原因 | 邊界 |
|---|---|---|
| `src/HS.DeviceControl.Application/Plugins/PluginLoadState.cs` | 定義 plugin metadata / verification 後的狀態語意。 | 狀態不代表 DLL 已載入。 |
| `src/HS.DeviceControl.Application/Plugins/PluginVerificationCheck.cs` | 讓 verification result 可列出來源、版本、checksum、敏感資訊等子檢查摘要。 | 不讀取真實 DLL。 |
| `src/HS.DeviceControl.Application/Plugins/PluginVerificationResult.cs` | 定義 4D 最小 verification result。 | 不呼叫 loader、不執行 plugin。 |
| `src/HS.DeviceControl.Application/Plugins/PluginAuditRecord.cs` | 定義 audit summary contract。 | 不寫 DB、不保存正式路徑或 secret。 |
| `tests/HS.DeviceControl.Application.Tests/PluginVerificationResultTests.cs` | 驗證 verification result 的成功 / 失敗 / warning / safe message。 | 不依賴外部 DLL。 |
| `tests/HS.DeviceControl.Application.Tests/PluginAuditRecordTests.cs` | 驗證 audit record 可保存安全摘要且遮蔽敏感資訊。 | 不寫 DB。 |

## 3. 預計修改檔案

| 檔案 | 原因 | 邊界 |
|---|---|---|
| `src/HS.DeviceControl.Application/Plugins/PluginDescriptor.cs` | 以相容方式補 `ContractVersion`、`Source`、`Enabled`、`DisabledReason`。 | 不移除既有 constructor；不破壞既有測試。 |
| `src/HS.DeviceControl.Application/Plugins/PluginCatalogService.cs` | 補 metadata 欄位、disabled、source / contract version 的基本驗證。 | 仍不讀檔、不掃描 folder。 |
| `src/HS.DeviceControl.Application/Common/ApplicationErrorCodes.cs` | 補 4D plugin verification / audit 相關錯誤碼。 | 不改既有 `APP-03xx` 定義。 |
| `tests/HS.DeviceControl.Application.Tests/PluginCatalogServiceTests.cs` | 補 contract version、source、disabled、sensitive metadata 測試。 | 不新增測試套件。 |

## 4. 明確不修改

| 不修改項目 | 原因 |
|---|---|
| `HS.DeviceControl.sln` | 不新增專案；SDK-style project 會自動納入 `.cs`。 |
| `HS.DeviceControl.Core` | 4D 最小 contract 屬 Application 層，不進 Core。 |
| `HS.DeviceControl.Adapters` | 不改 `IDeviceAdapter`、`ExecuteResult`、`DeviceCommand`。 |
| `HS.DeviceControl.ServiceHost` | 不建立 loader lifecycle、不改啟動方式。 |
| `HS.DeviceControl.WebApi` | 不新增 plugin route、controller、DTO、auth 或 Swagger 設定。 |
| `devices.json` / `workflows.json` / `appsettings.json` | 不新增 plugin folder、DLL path、來源白名單或敏感資訊欄位。 |
| `Infrastructure.MySql` | 不建立 audit table、不寫 DB、不執行 DDL / ALTER TABLE。 |
| 外部 DLL / plugin folder | 不掃描、不載入、不執行。 |

## 5. 欄位建議

| Contract | 建議欄位 |
|---|---|
| `PluginLoadState` | `Discovered`、`Verified`、`Rejected`、`Disabled`、`Faulted`、`Loaded`；其中 `Loaded` 僅保留未來語意，第一版不得產生。 |
| `PluginVerificationCheck` | `Name`、`Success`、`Code`、`Message`。 |
| `PluginVerificationResult` | `Success`、`Code`、`Message`、`PluginId`、`State`、`Checks`、`Warnings`、`TimeTakenMs`、`Error`。 |
| `PluginAuditRecord` | `AuditId`、`PluginId`、`Decision`、`Reason`、`Operator`、`Source`、`Checksum`、`CreatedAtUtc`。 |
| `PluginDescriptor` 擴充 | `ContractVersion`、`Source`、`Enabled`、`DisabledReason`。 |

## 6. 測試策略

| 測試 | 驗證目的 |
|---|---|
| `PluginVerificationResult.Ok` | 成功結果需有 `Success=True`、`Code=NONE`、`State=Verified`，且可承接 checks / warnings。 |
| `PluginVerificationResult.Fail` | 失敗結果需有錯誤碼、`State=Rejected` 或 `Faulted`，且不包含 sensitive detail。 |
| Disabled plugin | `Enabled=false` 或 disabled reason 時不可被視為可載入。 |
| Contract version missing | 缺少 contract version 時 catalog / verification 應回標準錯誤。 |
| Source missing or unsafe | 缺少 source 或 source 含 path / secret 時應拒絕。 |
| Audit summary | audit record 不包含 password、token、connection string、正式路徑。 |
| No loader API | 測試不使用 `Assembly.Load`、`LoadFrom`、`LoadFile`，不建立 DLL fixture。 |

## 7. 七項確認

使用者已確認以下七項，全部同意後已允許修改程式 repo 的最小 Application plugin contract 範圍。

| 編號 | 決策項 | 建議確認 | 影響 |
|---:|---|---|---|
| 1 | 4D 第一版只做 Application plugin contract | 同意後只改 `HS.DeviceControl.Application` 與 Application.Tests。 | 不新增 Loader 專案。 |
| 2 | 新增 `PluginLoadState`、`PluginVerificationCheck`、`PluginVerificationResult`、`PluginAuditRecord` | 同意後可新增 public model。 | 固定第一版最小資料模型。 |
| 3 | 相容擴充 `PluginDescriptor` | 同意後可補 `ContractVersion`、`Source`、`Enabled`、`DisabledReason`。 | 不移除既有 constructor。 |
| 4 | 擴充 `PluginCatalogService` 基本驗證 | 同意後可補 source / contract version / disabled 驗證。 | 仍不讀檔、不掃描 folder。 |
| 5 | 補 Application plugin 錯誤碼 | 同意後可新增 `APP-033x` 常數。 | 不改既有錯誤碼。 |
| 6 | 測試只跑 Application.Tests，必要時再跑 full solution | 同意後先驗證 4D 最小 contract。 | 不跑 DB manual-only 測試。 |
| 7 | 保留所有 Loader / DLL / config / Adapter / DB 停止線 | 同意後仍不得建立 Loader、載入 DLL、改 config schema 或 DB。 | 避免第四階段失控擴大。 |

建議回覆格式：

```text
4D 最小 contract 確認：
1. 同意
2. 同意
3. 同意
4. 同意
5. 同意
6. 同意
7. 同意
```

## 8. 建議下一步

4D 最小 contract 已完成確認，程式 repo 也已完成本機實作與測試驗證。建議接著查看 [4D 最小 Application plugin contract 實作與驗收紀錄](phase-four-d-pluginloader-application-contract-implementation-record.md) 與 [4D PluginLoader 完成稽核表](phase-four-d-pluginloader-completion-audit.md)，再執行程式 repo stage / commit 前確認。
