# 5B config schema 邊界分析

本文件承接 [第五階段 Loader 到 Service 後續文件 / 實作 / 驗收範圍補齊表](phase-five-loader-to-service-scope-acceptance-plan.md)、[5A 最小 PluginLoader 完成稽核表](phase-five-a-pluginloader-completion-audit.md) 與 [外部 DLL manual-only fake verifier 實作與驗收紀錄](phase-five-external-dll-manual-only-implementation-acceptance-record.md)。

本文件只整理 5B config schema 的邊界、候選檔案、設定欄位草案、測試策略與停止線。5B 會影響設定契約，因此在使用者完成七項確認前，不修改程式 repo。

## 0. 文件狀態

| 項目 | 內容 |
|---|---|
| 文件狀態 | 已建立，等待 5B 七項確認 |
| 建立日期 | 2026-06-07 |
| 對應節點 | 第五階段 5B config schema |
| 程式 repo | `hs-device-control-template` |
| 程式 branch | `poc/nmodbus-tcp` |
| 程式基準 | `bc3f191`，外部 DLL manual-only fake verifier |
| 本次是否修改程式 repo | 否，只做唯讀檢查與文件整理 |
| 下一步 | 等待使用者確認 `5B config schema 實作前確認` 七項 |

## 1. 5B 目標

| 目標 | 說明 |
|---|---|
| 固定 plugin / loader 設定位置 | 建議放在 `appsettings.json`，避免新增啟動檔案或改變啟動方式。 |
| 建立安全預設值 | 預設不掃描 plugin folder、不載入外部 DLL、不允許 manual external verification。 |
| 補上 validator | 缺少必要欄位、欄位型別錯誤、不安全摘要或不合法版本需回傳標準 config validation error。 |
| 保留舊設定相容性 | 現有 `samples/config/appsettings.json` 不含 plugin 設定時，仍應可載入既有第一階段 / 第四階段測試流程。 |
| 連接 5A / 外部 DLL 既有 contract | 僅描述 metadata 與 gate 設定，不引入真實 DLL path 或執行行為。 |
| 建立測試證據 | Core config tests 與 solution tests 需覆蓋成功、缺欄位、不合法欄位與舊設定相容性。 |

## 2. 唯讀檢查結果

| 檢查項目 | 結果 |
|---|---|
| 文件 repo 狀態 | `main...origin/main`，乾淨。 |
| 程式 repo 狀態 | `poc/nmodbus-tcp...origin/poc/nmodbus-tcp`，乾淨。 |
| 現有 config loader | `ConfigLoader` 只載入 `devices.json`、`workflows.json`、`appsettings.json`。 |
| 現有 appsettings model | `AppSettingsConfig` 目前只有 `Log`、`Debug`、`Watchdog`。 |
| 現有 validator | `ConfigValidator` 驗證 Log 與 Watchdog，尚未驗證 PluginLoader / Plugins。 |
| 現有 sample config | `samples/config/appsettings.json` 只有 Log、Debug、Watchdog。 |
| 5A Loader options | `PluginLoaderOptions` 已有 expected contract version、checksum、disabled review。 |
| 外部 DLL manual options | `ExternalDllManualVerifierOptions` 預設 gate 關閉。 |
| DB / WebApi / ServiceHost | 5B 不需要修改 DB、WebApi、ServiceHost 或 Windows Service。 |

## 3. 建議 schema 草案

以下是 5B 可討論的最小設定草案；實際程式欄位需等待七項確認後才可落地。

```json
{
  "PluginLoader": {
    "Enabled": false,
    "ExpectedContractVersion": "1.0",
    "ExpectedChecksum": "",
    "AllowDisabledPluginReview": false,
    "AllowManualExternalDllVerification": false
  },
  "Plugins": [
    {
      "PluginId": "mock-light-plugin",
      "DisplayName": "Mock Light Plugin",
      "ContractVersion": "1.0",
      "Checksum": "metadata-checksum",
      "SourceSummary": "built-in metadata sample",
      "Enabled": true,
      "DisabledReason": "",
      "Capabilities": [
        {
          "CapabilityId": "light-command",
          "DeviceType": "Light",
          "CommandName": "LightOn"
        }
      ]
    }
  ]
}
```

## 4. 欄位邊界

| 欄位 | 建議規則 |
|---|---|
| `PluginLoader.Enabled` | 預設 `false`；未啟用時不建立可執行 loader 行為，只允許設定被解析與驗證。 |
| `PluginLoader.ExpectedContractVersion` | 可為空；若有值，需為安全短字串，不可包含路徑或敏感片段。 |
| `PluginLoader.ExpectedChecksum` | 可為空；若有值，只能代表 metadata 摘要，不讀取外部檔案。 |
| `PluginLoader.AllowDisabledPluginReview` | 預設 `false`，僅控制 metadata review 結果，不代表允許執行 plugin。 |
| `PluginLoader.AllowManualExternalDllVerification` | 預設 `false`；即使開啟，也只可連到 manual-only fake verifier，不代表載入真實 DLL。 |
| `Plugins[].PluginId` | 必填且不可重複。 |
| `Plugins[].SourceSummary` | 只能是安全摘要，不可放完整路徑、正式機資訊、secret、connection string 或正式 port。 |
| `Plugins[].Capabilities` | 第一版只描述能力 metadata，不改 Adapter public contract。 |

## 5. 候選程式檔案

若使用者確認 5B 七項，候選變更範圍如下：

| 類型 | 候選檔案 | 說明 |
|---|---|---|
| Config model | `src/HS.DeviceControl.Core/Configuration/AppSettingsConfig.cs` | 新增 `PluginLoader` 與 `Plugins` 設定模型。 |
| Config validation | `src/HS.DeviceControl.Core/Configuration/ConfigValidator.cs` | 驗證欄位必填、重複、型別、安全摘要與 safe default。 |
| Config loader | `src/HS.DeviceControl.Core/Configuration/ConfigLoader.cs` | 原則上不改讀檔清單，只維持載入 `appsettings.json`。 |
| Sample config | `samples/config/appsettings.json` | 加入最小、非敏感、metadata-only 範例。 |
| Config docs | `docs/config-schema.md` | 同步新 schema 與驗證規則。 |
| Core tests | `tests/HS.DeviceControl.Core.Tests/ConfigValidatorTests.cs`、`tests/HS.DeviceControl.Core.Tests/ConfigLoaderTests.cs` | 驗證新欄位、舊設定相容性與錯誤訊息。 |

## 6. 驗收策略

| 驗收項目 | 預期證據 |
|---|---|
| 舊設定相容性 | 現有 sample config 可載入，既有 ConfigLoader / Validator tests 通過。 |
| 成功 config | plugin loader 與 plugin metadata 欄位合法時驗證通過。 |
| 缺必填欄位 | plugin id 缺少、重複或空白時驗證失敗。 |
| unsafe source | 疑似完整路徑、帳密、connection string 或正式連線資訊需被拒絕。 |
| safe default | 未設定 plugin loader 時不得自動啟用 loader、外部 DLL 或 manual gate。 |
| 停止線掃描 | 新增程式不得出現外部載入 API、真實 DLL path、plugin folder scan、DB DDL、auth secret 或 Windows Service 安裝。 |
| 文件同步 | README、config schema、status / progress 與 public 鏡像需同步。 |

## 7. 明確排除

- 不載入外部 DLL。
- 不掃描 plugin folder。
- 不新增真實 DLL path 欄位。
- 不保存 secret、token、connection string、正式 IP、正式 port 或正式帳號。
- 不建立 DB audit table，不執行 DDL / ALTER TABLE / Apply。
- 不修改 WebApi route、auth 或 Swagger。
- 不修改 ServiceHost 或 Windows Service。
- 不改 Adapter public contract。
- 不改專案啟動方式。

## 8. 下一步

請先確認 [5B config schema 實作前確認表](phase-five-b-config-schema-preimplementation-checklist.md) 七項。確認前，只能停留在文件與唯讀檢查；確認後才可進入程式 repo 的最小 config schema 實作。
