# 5A PluginLoader 程式 repo 結構檢查與實作前盤點

本文件承接 [5A PluginLoader 實作前確認表](phase-five-a-pluginloader-preimplementation-checklist.md) 與 [第五階段 Loader 到 Service 後續文件 / 實作 / 驗收範圍補齊表](phase-five-loader-to-service-scope-acceptance-plan.md)。

使用者已確認 5A 七項決策；本文件完成程式 repo 唯讀結構檢查，固定最小 PluginLoader 的候選檔案、測試命令、可承接能力與停止線。本文件仍不是程式實作授權，下一步需先整理「5A 最小 PluginLoader 實作前最後確認」。

## 0. 文件狀態

| 項目 | 內容 |
|---|---|
| 文件狀態 | 已完成 |
| 建立日期 | 2026-06-07 |
| 對應節點 | 5A PluginLoader 程式 repo 唯讀結構檢查 |
| 程式 repo | `hs-device-control-template` |
| 本機檢查路徑 | `C:\Users\Evan\OneDrive - 鴻森智能科技有限公司\重要資料\hs-device-control-template` |
| 本機 branch | `poc/nmodbus-tcp` |
| 本機 commit | `6f34bb9`，4D 最小 Application plugin contract |
| 遠端 main | `a8b522b`，main 已合併 `poc/nmodbus-tcp` |
| 工作樹 | 乾淨 |
| 是否修改程式 repo | 否，只做唯讀盤點與測試基準驗證 |

## 1. 檢查結論

| 項目 | 結論 |
|---|---|
| 5A 承接位置 | 可承接在 `src/HS.DeviceControl.Application/Plugins`。 |
| 測試承接位置 | 可承接在 `tests/HS.DeviceControl.Application.Tests`。 |
| 是否需新增專案 | 不需要，`HS.DeviceControl.Application` 與 `HS.DeviceControl.Application.Tests` 已在 solution。 |
| 是否已有 `IPluginLoader` | 尚未存在，可作為 5A 候選新增 public contract。 |
| 是否已有真正 Loader | 尚未存在；目前只有 metadata catalog / verification / audit contract。 |
| 是否已有外部 DLL 載入 | 未發現 `Assembly.Load`、`LoadFrom`、`LoadFile` 或 `AssemblyLoadContext`。 |
| 是否需改 config schema | 5A 不需要；`samples/config/appsettings.json` 目前沒有 plugin / loader 設定。 |
| 是否需改 DB / WebApi / ServiceHost | 5A 不需要；DB audit、auth / Swagger、Windows Service 仍留到 5C / 5D / 5E。 |

## 2. 現有可承接能力

| 現有檔案 | 目前能力 | 5A 意義 |
|---|---|---|
| `PluginDescriptor.cs` | 定義 plugin metadata、checksum、contract version、source、enabled / disabled。 | 可作為 Loader request 的輸入來源，不需改成 DLL path。 |
| `IPluginCatalogService.cs` / `PluginCatalogService.cs` | 列出並驗證 metadata catalog。 | 5A Loader 可依 catalog result 選擇 plugin，不需掃描資料夾。 |
| `PluginCatalogResult.cs` | 回傳 catalog 成功 / 失敗與標準錯誤。 | 可沿用 result pattern。 |
| `PluginVerificationResult.cs` / `PluginVerificationCheck.cs` | 表示 metadata verification 結果與安全摘要。 | 5A 可把 Loader 的 metadata checks 回填到 verification result。 |
| `PluginLoadState.cs` | 已有 Discovered、Verified、Rejected、Disabled、Faulted，並預留 Loaded。 | 5A 第一版仍建議不產生真正 Loaded，除非文件另行確認。 |
| `PluginAuditRecord.cs` | 表示 audit 安全摘要，但不寫 DB。 | 5A 可產生 audit summary，DB 寫入留 5C。 |
| `PluginContractTextSafety.cs` | 檢查敏感字串與疑似檔案路徑。 | 5A 可沿用，不暴露正式路徑、password、token。 |
| `ApplicationErrorCodes.cs` | 已有 `APP-0331` 到 `APP-0335` plugin 相關錯誤碼。 | 若 5A 需要 Loader 專屬錯誤碼，需在最後確認表列出。 |

## 3. 候選新增檔案

以下是 5A 最小 metadata-only PluginLoader 的候選檔案，實作前仍需最後確認。

| 類型 | 候選檔案 | 說明 |
|---|---|---|
| Loader interface | `src/HS.DeviceControl.Application/Plugins/IPluginLoader.cs` | 最小 public contract；不得包含外部 DLL 載入或 assembly API。 |
| Load request | `src/HS.DeviceControl.Application/Plugins/PluginLoadRequest.cs` | 建議只包含 `PluginId`、expected contract version、operator / request source 等安全摘要。 |
| Load result | `src/HS.DeviceControl.Application/Plugins/PluginLoadResult.cs` | 建議回傳 success、plugin id、state、checks、warnings、code、message、error、time taken。 |
| Loader options | `src/HS.DeviceControl.Application/Plugins/PluginLoaderOptions.cs` | 建議只放 expected contract version、是否允許 disabled 等非敏感設定；不放 path / secret。 |
| Loader service | `src/HS.DeviceControl.Application/Plugins/PluginLoaderService.cs` | 以 `IPluginCatalogService` 的 metadata 做選擇與驗證；不得掃描 folder 或載入 DLL。 |
| Tests | `tests/HS.DeviceControl.Application.Tests/PluginLoaderServiceTests.cs` | 驗證成功、缺 metadata、disabled、version mismatch、checksum mismatch、unsafe source 與停止線。 |

## 4. 候選修改檔案

| 檔案 | 候選修改 | 注意事項 |
|---|---|---|
| `ApplicationErrorCodes.cs` | 視需要新增 Loader 專屬錯誤碼，例如 loader request invalid / plugin not found / contract mismatch。 | 屬 public constant 變更，需在 5A 最後確認表明列。 |
| `PluginLoadState.cs` | 原則上不修改；第一版建議仍不產生真正 `Loaded`。 | 若要改狀態語意，必須停下確認。 |
| `PluginCatalogService.cs` | 原則上不修改；Loader 可使用既有 catalog result。 | 若要改 catalog validation，需避免破壞 4D contract。 |

## 5. 測試策略

| 測試項目 | 建議驗證 |
|---|---|
| 成功 metadata-only load | 找到 enabled plugin、contract version 相容、checksum 符合時回 success / verified。 |
| plugin not found | 不存在的 plugin id 回標準錯誤，不丟 exception。 |
| disabled plugin | disabled plugin 不可被視為可載入，除非 options 明確允許且文件已確認。 |
| contract mismatch | expected contract version 不符時回拒絕結果。 |
| checksum mismatch | 宣告 checksum 不符時回拒絕結果；第一版只比對 metadata 字串，不讀 DLL。 |
| unsafe source / message | source 或錯誤訊息含正式路徑、password、token 時需遮蔽或拒絕。 |
| no assembly loading | 程式碼與測試不得呼叫 `Assembly.Load`、`LoadFrom`、`LoadFile`、`AssemblyLoadContext`。 |

## 6. 已執行檢查

| 檢查 | 指令 / 方式 | 結果 |
|---|---|---|
| 程式 repo remote | `git remote -v` | `origin` 指向 `https://github.com/Hongsen-tw/hs-device-control-template.git`。 |
| 本機工作樹 | `git status --short --branch` | `poc/nmodbus-tcp...origin/poc/nmodbus-tcp`，無未提交變更。 |
| 遠端基準 | `git ls-remote origin main poc/nmodbus-tcp` | `main=a8b522b`，`poc/nmodbus-tcp=6f34bb9`。 |
| Plugin 結構 | `rg --files src tests docs samples scripts` 與 `rg Plugin...` | 已確認 `Application.Plugins` 與 Application.Tests 可承接。 |
| DLL 停止線 | `rg "Assembly\.Load|LoadFrom|LoadFile|AssemblyLoadContext|\.dll"` | 未命中 production code；只在既有測試中用 `C:\plugins\mock-light.dll` 驗證 unsafe source。 |
| config schema | 讀取 `samples/config/appsettings.json`、`AppSettingsConfig.cs`、`ConfigValidator.cs` | 目前沒有 plugin / loader schema；5A 不需修改。 |
| Application tests | `dotnet test tests\HS.DeviceControl.Application.Tests\HS.DeviceControl.Application.Tests.csproj --no-restore` | 40 passed，0 failed，0 skipped。 |

## 7. 明確停止線

| 停止線 | 說明 |
|---|---|
| 不載入外部 DLL | 5A 只做 metadata-only Loader，不呼叫 assembly loading API。 |
| 不掃描 plugin folder | 不讀正式 plugin folder、不保存正式 path、不建立 path schema。 |
| 不改 config schema | plugin path、enable flag、trust policy 留到 5B。 |
| 不建 DB audit table | audit DB 寫入與 DDL 留到 5C。 |
| 不改 WebApi auth / Swagger | auth / Swagger 留到 5D。 |
| 不建立 Windows Service | Windows Service 留到 5E。 |
| 不接真實硬體或案場 plugin | 5A 只處理共用 Application 層 metadata Loader。 |

## 8. 建議下一步

本次唯讀結構檢查已確認 5A 可在 Application 層安全承接。建議下一步建立「5A 最小 PluginLoader 實作前最後確認表」，逐項確認：

1. 是否新增 `IPluginLoader`、`PluginLoadRequest`、`PluginLoadResult`、`PluginLoaderOptions`、`PluginLoaderService`。
2. 是否允許新增 Loader 專屬 Application error codes。
3. 是否確認第一版只回 `Verified / Rejected / Disabled / Faulted`，不產生真正 DLL loaded 狀態。
4. 是否確認測試只跑 Application.Tests，不跑外部 DLL、DB、WebApi auth 或 Windows Service。
5. 是否確認實作後需做 stage / commit 前確認，再由目標模式續行。
