# 5A 最小 PluginLoader 實作前最後確認表

本文件承接 [5A PluginLoader 程式 repo 結構檢查與實作前盤點](phase-five-a-pluginloader-code-structure-preimplementation-checklist.md)，用於在真正修改程式 repo 前，最後確認 5A 最小 PluginLoader 的 public contract、候選檔案、測試範圍與停止線。

本文件不是外部 DLL 載入、config schema、DB audit、auth / Swagger 或 Windows Service 的授權。上述能力仍需在 5B 到 5E 另外建立文件、確認表、測試與驗收紀錄。

## 0. 文件狀態

| 項目 | 內容 |
|---|---|
| 文件狀態 | 待使用者確認 |
| 建立日期 | 2026-06-07 |
| 對應節點 | 5A 最小 PluginLoader 程式實作前最後確認 |
| 程式 repo | `hs-device-control-template` |
| 目標 branch | `poc/nmodbus-tcp` |
| 程式基準 | `6f34bb9`，4D 最小 Application plugin contract |
| 文件基準 | 已完成 5A 程式 repo 唯讀結構檢查，Application.Tests 40 passed |
| 是否修改程式 repo | 否，本文件只做最後確認 |

## 1. 預計新增 / 修改檔案

| 類型 | 檔案 | 目的 |
|---|---|---|
| 新增 | `src/HS.DeviceControl.Application/Plugins/IPluginLoader.cs` | 建立最小 Loader public contract，只接受 metadata request，不暴露 DLL 載入 API。 |
| 新增 | `src/HS.DeviceControl.Application/Plugins/PluginLoadRequest.cs` | 定義安全的 load request，例如 `PluginId`、expected contract version、operator / request source。 |
| 新增 | `src/HS.DeviceControl.Application/Plugins/PluginLoadResult.cs` | 回傳 success、plugin id、state、checks、warnings、code、message、error、time taken。 |
| 新增 | `src/HS.DeviceControl.Application/Plugins/PluginLoaderOptions.cs` | 定義非敏感選項，例如 expected contract version、是否允許 disabled plugin。 |
| 新增 | `src/HS.DeviceControl.Application/Plugins/PluginLoaderService.cs` | 以 `IPluginCatalogService` 的 metadata 做選擇與驗證，不掃描 folder、不讀 DLL。 |
| 新增 | `tests/HS.DeviceControl.Application.Tests/PluginLoaderServiceTests.cs` | 覆蓋成功、plugin not found、disabled、contract mismatch、checksum mismatch、unsafe source 與停止線。 |
| 修改 | `src/HS.DeviceControl.Application/Common/ApplicationErrorCodes.cs` | 視需要新增 Loader 專屬錯誤碼，避免用籠統錯誤表示 Loader 失敗原因。 |

## 2. Loader 專屬錯誤碼建議

| 建議錯誤碼 | 建議常數名稱 | 使用情境 |
|---|---|---|
| `APP-0341` | `PluginLoadRequestInvalid` | request 缺少必要欄位或格式不合法。 |
| `APP-0342` | `PluginLoadPluginNotFound` | catalog 找不到指定 plugin id。 |
| `APP-0343` | `PluginLoadContractMismatch` | expected contract version 與 plugin metadata 不相容。 |
| `APP-0344` | `PluginLoadChecksumMismatch` | metadata 宣告 checksum 與預期值不一致；5A 不讀實體 DLL。 |
| `APP-0345` | `PluginLoadRejected` | metadata safety check 或 disabled policy 導致拒絕。 |

## 3. 5A 最後確認項目

| # | 確認項目 | 預設建議 | 狀態 |
|---:|---|---|---|
| 1 | 同意在 `HS.DeviceControl.Application.Plugins` 新增 `IPluginLoader`、`PluginLoadRequest`、`PluginLoadResult`、`PluginLoaderOptions`、`PluginLoaderService`。 | 同意 | 待確認 |
| 2 | 同意 5A 第一版採 metadata-only / catalog-driven，使用 `IPluginCatalogService`，不得掃描 plugin folder、不得呼叫 assembly loading API。 | 同意 | 待確認 |
| 3 | 同意 5A 第一版只回傳 `Verified`、`Rejected`、`Disabled`、`Faulted` 等 metadata 狀態，不產生真正外部 DLL `Loaded` 狀態。 | 同意 | 待確認 |
| 4 | 同意在 `ApplicationErrorCodes.cs` 新增 Loader 專屬錯誤碼 `APP-0341` 到 `APP-0345`，用於 request invalid、plugin not found、contract mismatch、checksum mismatch、load rejected。 | 同意 | 待確認 |
| 5 | 同意測試只新增 `PluginLoaderServiceTests.cs`，驗證 Application.Tests 與 solution tests；不新增 DB、WebApi、ServiceHost、外部 DLL 或 Windows Service 測試。 | 同意 | 待確認 |
| 6 | 同意實作後執行停止線掃描，確認 production code 未出現 `Assembly.Load`、`LoadFrom`、`LoadFile`、`AssemblyLoadContext`、plugin folder scan 或真實 `.dll` 載入。 | 同意 | 待確認 |
| 7 | 同意 5A 實作完成後先建立實作 / 驗收紀錄與 stage / commit 前確認，再決定是否 commit / push；若要擴大到外部 DLL、config schema、DB audit、auth / Swagger 或 Windows Service，必須另行確認。 | 同意 | 待確認 |

## 4. 明確不授權項目

| 不授權項目 | 原因 |
|---|---|
| 外部 DLL 掃描 / 載入 | 需等外部 DLL manual-only 節點與信任模型另行確認。 |
| plugin folder 設定 | 需等 5B config schema 確認。 |
| DB audit table / DDL | 需等 5C DB audit 確認，且正式 DDL / ALTER TABLE 必須停下。 |
| WebApi auth / Swagger | 需等 5D 確認，涉及安全模型與部署設定。 |
| Windows Service 安裝 | 需等 5E 確認，不在 5A 程式實作範圍。 |
| 真實硬體 / 案場 plugin | 5A 只建立 Application metadata Loader，不接真實設備。 |

## 5. 建議回覆格式

```text
5A 最小 PluginLoader 實作前最後確認：
1. 同意
2. 同意
3. 同意
4. 同意
5. 同意
6. 同意
7. 同意
```

## 6. 確認後下一步

使用者確認七項後，才進入程式 repo 的 5A metadata-only PluginLoader 實作。實作時仍必須維持停止線：不載入外部 DLL、不掃描 plugin folder、不改 config schema、不建 DB audit table、不改 WebApi auth / Swagger、不建立 Windows Service。
