fix(review): manifest deny_unknown_fields + каталог сигналов в sdk::vehicle

- deny_unknown_fields: опечатка в ключе capability (граница доверия F §3) не проглатывается.
- VEHICLE_SIGNALS → shturman_sdk::vehicle (single source; валидатор берёт оттуда).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
This commit is contained in:
2026-06-24 14:36:50 +03:00
parent 2b06ff749f
commit 69beaad596
4 changed files with 53 additions and 23 deletions
+22
View File
@@ -6,6 +6,7 @@ use serde::Deserialize;
/// Корень манифеста (`manifest.yaml`).
#[derive(Debug, Clone, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Manifest {
pub plugin: Plugin,
#[serde(default)]
@@ -15,6 +16,7 @@ pub struct Manifest {
}
#[derive(Debug, Clone, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Plugin {
/// reverse-DNS id; `ru.shturman.*` закрыт за first-party (проверяет валидатор, F §3).
pub id: String,
@@ -29,6 +31,7 @@ pub struct Plugin {
}
#[derive(Debug, Clone, Default, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Capabilities {
/// Только сигналы из каталога data-model (проверяет валидатор).
#[serde(default)]
@@ -46,6 +49,7 @@ pub struct Capabilities {
}
#[derive(Debug, Clone, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Network {
/// host-allowlist (намерение; строгая гарантия — forced-proxy, plugin-sdk §3).
#[serde(default)]
@@ -53,6 +57,7 @@ pub struct Network {
}
#[derive(Debug, Clone, Default, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ExtensionPoints {
#[serde(default)]
pub tiles: Vec<Tile>,
@@ -61,6 +66,7 @@ pub struct ExtensionPoints {
}
#[derive(Debug, Clone, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Tile {
pub id: String,
#[serde(default)]
@@ -68,6 +74,7 @@ pub struct Tile {
}
#[derive(Debug, Clone, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Intents {
/// Путь объекта `IntentHandler` (все фразы → сюда, plugin-sdk §2).
pub handler: String,
@@ -138,4 +145,19 @@ plugin:
fn rejects_malformed_yaml() {
assert!(Manifest::from_yaml(": : not yaml : :").is_err());
}
#[test]
fn rejects_unknown_field() {
// опечатка в ключе capability на границе доверия (F §3) не должна молча проглатываться
let bad = r#"
plugin:
id: dev.example.x
name: "x"
version: 0.1.0
shturman_api: "1"
capabilities:
vehicl_read: [speed]
"#;
assert!(Manifest::from_yaml(bad).is_err());
}
}