ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RuView homecore-migrate:把 Home Assistant 迁移评审的六条纪律落到 Rust 源码里

RuView homecore-migrate:把 Home Assistant 迁移评审的六条纪律落到 Rust 源码里 RuView homecore-migrate把 Home Assistant 迁移评审的六条纪律落到 Rust 源码里【免费下载链接】RuViewπ RuView turns commodity WiFi signals into real-time spatial intelligence, vital sign monitoring, and presence detection — all without a single pixel of video.项目地址: https://gitcode.com/GitHub_Trending/wi/RuView本篇围绕 RuView 仓库中 homecore 迁移评审技能 展开它规定了“评审一次 Home Assistant 迁移”时必须遵守的六条纪律——先 inspect 后写入、把.storage与 YAML 视为不可信的带版本输入、未知 schema 版本硬性失败、保留未知的前向兼容字段、显式目标路径加原子 no-clobber 写入、任何输出中绝不出现密钥明文。读完本文你可以理解 RuView 的homecore-migrate工具v2/crates/homecore-migrate/是如何逐条落实这些纪律的并掌握一条从inspect到import-*的安全迁移操作路径以及每条纪律背后的 Rust 实现证据。迁移评审技能六条纪律的原文与定位harness/homecore/skills/migrate.md 是 homecore 元框架metaharness下的一个“技能”文件——供本地 Claude Code / Codex 等 Agent 宿主在探索仓库时遵循的评审清单。全文只有 6 行要点但每一行都对应homecore-migrate工具中一段可验证的实现任何写入之前先运行迁移 CLI 的 inspect 路径把.storage与 YAML 当作不可信的带版本输入对待对不支持的 schema 版本要求硬性失败保留未知的前向兼容 config-entry 字段使用显式目标路径和原子 no-clobber 写入错误、日志、issue 或转写文本中绝不允许出现密钥值。文档最后还有一条元规则自动化转换、密钥引用解析和集成执行必须按“当前实现的真实状态”来描述。这条“能力诚实”原则与 homecore 元框架 README 中的 Capability honesty 一节呼应目录区分 implemented、feature-gated、provider-required 与 integration-dependent 行为包装好的引用只是导航证据源码、测试与已接受的 ADR 才是权威。该技能所在的homecore元框架本身是只读的它映射能力到源码与验证命令、暴露一个有界 MCP 服务器、可委派仓库探索给本地 Agent CLI但“不会自行启动 home server、修改配置、迁移数据或发布代码”见 harness/homecore/README.md。因此skills/migrate.md的正确读法是它定义的是迁移实现应满足的评审契约而契约的执行体是homecore-migratecrate。实现主体homecore-migrate crate 的结构迁移决策的权威记录是 ADR-165: HOMECORE-MIGRATE。背景是 ADR-126 决定在 Rust 中原生重实现 Home Assistant用户存量 HA 安装的配置落在磁盘两处.storage/*.json——版本化 JSON 信封{ version, minor_version, data }保存实体注册表、设备注册表与 config entries顶层 YAML——secrets.yaml、automations.yaml。ADR-165 指出这份外来状态在安全意义上是“不可信”的schema 会随 HA 版本漂移静默误解析会污染整个导入后的家庭数据因此必须钉死信任边界与导入契约。实现落在 v2/crates/homecore-migrate按 crate 文档 的模块划分模块职责storageHaStorageDir/HaStorageEnvelope、read_envelope(path)、原子写入storage_format版本化格式解析器当前为v13未知minor_version→ 硬错误entity_registrycore.entity_registry→Vechomecore::EntityEntrydevice_registry支持的 HA v13 设备字段 →homecore::DeviceEntryconfig_entries无损、版本化的 HOMECORE 表示 类型化警告secretssecrets.yaml→HashMapString, String带脱敏错误automationsautomations.yaml计数 ID 列表转换为 P2cli/mainclap 子命令与 JSON 摘要输出验证方式是 crate 自带的cargo test -p homecore-migrate与cargo clippy -p homecore-migrate --all-targets -- -D warnings见 v2/crates/homecore-migrate/README.md 的 Validation 一节。纪律一先 inspect后写入技能第一条要求“任何写入之前先运行 inspect 路径”。CLI 侧这对应一组完全只读的子命令。src/cli.rs 中Command枚举定义了七个子命令inspect、import-entities、import-devices、inspect-config-entries、import-config-entries、inspect-secrets、inspect-automationsinspect 系列只接受一个--storage或--config-dir参数根本没有目标写入参数——写入只能来自显式的import-*命令。src/main.rs 中Inspect分支的行为是“探测 报告”逐个检查core.entity_registry、core.device_registry、core.config_entries是否存在存在则读取并打印计数实体数、设备数、config-entry 数与 domain 列表任何一项解析失败也只是打印ERROR — {e}而不是中断整个预览。inspect-secrets打印密钥名称但值一律渲染为redactedinspect-automations打印自动化数量与id/alias列表。实操流程因此是两段式的# 1) 无风险预览只读不产生任何目标文件 homecore-migrate inspect --storage ~/.homeassistant/.storage homecore-migrate inspect-secrets --config-dir ~/.homeassistant homecore-migrate inspect-automations --config-dir ~/.homeassistant # 2) 确认无误后再写入显式目标目录 homecore-migrate import-entities \ --storage ~/.homeassistant/.storage \ --to ~/.homecore/storageADR-165 把inspect明确列为正面后果之一“inspect给用户一个写入前的无风险 dry run。”纪律二.storage与 YAML 是不可信的带版本输入“不可信”在这里不是指恶意输入而是指格式可能随 HA 版本漂移。信封层结构在 src/storage.rs 中定义pub struct HaStorageEnvelope { pub version: u32, /// Introduced in HA 2022.x for backwards-compatible schema additions. #[serde(default)] pub minor_version: u32, pub key: String, /// Inner payload. Parsed by versioned format-specific code. pub data: serde_json::Value, }两个值得注意的设计每个.storage/*.json共享同一外层信封read_envelope(path)只负责解外层包装data保持为未类型化的serde_json::Value交给storage_format::vN下的版本化解析器当前实现为 src/storage_format/v13.rs进一步反序列化。注释直接标注了来源HA 的homeassistant/helpers/storage.py的Store._write_data。minor_version带#[serde(default)]旧版 HA 的信封没有这个字段时默认为 0而 unit 测试envelope_missing_minor_version_defaults_to_zero锁定了这一行为src/storage.rs。对“不可信”的防御还体现在错误处理上整个 crate 使用统一的结构化错误类型MigrateErrorsrc/lib.rs覆盖 I/O、JSON 解析、YAML 解析、密钥解析、不支持的 schema 版本、意外存储键、缺失字段与 entity_id 解析失败。ADR-165 记录的安全审查结论是畸形/带类型标签/截断的.storageJSON 与 YAML只能报错、绝不 panic生产代码中所有unwrap/expect均为测试专用。纪律三未知 schema 版本必须硬失败这是 ADR-165 标注的“承重安全规则”the load-bearing safety rule未知minor_version是硬错误而不是静默的 best-effort 解析。错误变体在 src/lib.rs 中#[error( unsupported schema version in {file}: \ version{version} minor_version{minor_version}. \ Upgrade homecore-migrate or downgrade HA to a supported release. )] UnsupportedSchemaVersion { file: String, version: u32, minor_version: u32 }错误信息本身也给出了两条明确的出路升级homecore-migrate以支持新版本或降级 HA 到受支持版本——即“宁可拒绝不可损坏”fail-closed。v2/crates/homecore-migrate/README.md 的 Remaining limitations 一节同样强调比 HA registry minor version 13 更新的新字段需要显式更新解析器未知版本一律 fail closed。这与 ADR-165 的正面后果一致schema 漂移会大声失败而不是悄悄污染导入后的家庭数据。纪律四无损保留未知的前向兼容字段对core.config_entries技能要求“保留未知的前向兼容 config-entry 字段”。实现上的契约是见 v2/crates/homecore-migrate/README.md 与 src/config_entries.rsconvert_config_entries()输出一个版本化的homecore.config_entries存储信封HOMECORE v1/minor 0原始行逐字保留each original row is retained verbatim因此 HA 侧未来新增的字段不会在导入时丢失不支持的 domain 与不可移植的字段不丢弃而是产生类型化警告typed warningscode字段做 snake_case 标签随结果一并上报。目标端文件映射关系源HA.storage目标HOMECORE storage格式core.entity_registrycore.entity_registryHA 兼容 v1/minor 13 信封core.device_registrycore.device_registryHA 兼容 v1/minor 13 信封core.config_entrieshomecore.config_entriesHOMECORE v1/minor 0 信封设备注册表的转换覆盖支持的 v13 字段identifiers、connections、versions、serial number、labels、topology 与 config-entry 链接。需要强调的是边界README 明确写着 config entries 是storage-compatible, not runtime-compatible——导入条目只是把数据持久化到 HOMECORE并不会安装或执行原来的 HA Python 集成必须由一个 HOMECORE 插件显式认领该 domain 并消费保留下来的源载荷。这正是技能最后一条元规则按当前实现状态描述自动化转换、密钥引用解析与集成执行的落点这三件事在当前版本中均未实现工具只做 inspect。纪律五显式目标与原子 no-clobber 写入技能第五条对应两个实现面显式目标所有 import 命令必须带--to参数与原子写入永不隐式覆盖已存在文件。写入核心是 src/storage.rs 的write_json_atomic_noclobber/write_json_atomic。流程是序列化为 pretty JSON在目标同目录创建.target.pid.seq.tmp临时文件create_new(true)保证不撞名写入字节后sync_all()落盘通过fs::hard_link(temp, target)原子发布硬链接创建若目标已存在会返回AlreadyExists这与 POSIXrename的“先检查后重命名仍可能覆盖”语义不同——no-clobber 是文件系统原子保证的不是应用层检查成功后删除临时文件失败则清理临时文件并把AlreadyExists统一渲染为destination exists; refusing to overwrite。这里有一个微妙的竞态论证源码注释src/storage.rs指出如果两个进程同时导入同一目标硬链接的AlreadyExists能让失败方明确输掉竞态而 rename 语义下后到者会静默替换先到者的结果。覆盖是显式选择的逃生舱import-entities/import-devices/import-config-entries都支持--force见 src/cli.rs 的参数注释用于修复坏行后重跑或 HA 侧变化后重新导入。--force路径改为“先移除旧文件、再走同一个 hard_link 发布步骤”源码注释src/storage.rs诚实记录了这一权衡它短暂放大了崩溃窗口remove 与 hard_link 之间崩溃会丢失旧文件而非保留旧文件但这是显式请求覆盖的可选代价默认的 no-clobber 原子性不受影响同时选择 removehard_link 而非 rename-over-existing是为了规避 Windows 上ERROR_ACCESS_DENIED的共享冲突抖动。每次成功导入输出单行机器可读的 JSON 摘要src/main.rs 定义ImportSummary{kind:device_registry,imported:8,warning_count:0,warnings:[],destination:/home/user/.homecore/storage/core.device_registry}warnings数组在import-config-entries中会携带纪律四所述的类型化警告脚本可以直接解析判断导入质量。纪律六密钥值绝不进入任何输出这是六条纪律中唯一涉及安全泄露面的一条也是 ADR-165 在 2026-06 安全审查中专门补强的一项。问题出在serde_yaml的错误消息对类型标签强转错误例如port: !!int value它会逐字引用出错标量invalid value: string the-secret-value而这条消息会经InspectSecretsCLI 路径传播到 stderr——绕过了 CLI 有意为之的redacted设计把密钥值泄漏进日志。修复在 src/secrets.rsread_secrets不再让secrets.yaml解析失败落入通用的MigrateError::YamlParse { source }变体而是映射到专门的脱敏变体src/lib.rs#[error( secrets.yaml parse error in {path} (line {line}, column {column}): \ malformed YAML (value content redacted) )] SecretsParse { path: String, line: usize, column: usize }该变体刻意不嵌入底层serde_yaml::Error只携带文件路径与一个粗糙的行列位置来自serde_yaml::Error::location()让用户能定位问题而不打印值。这条规则由测试malformed_secrets_error_never_contains_secret_value锁定src/secrets.rs 起断言渲染后的错误以及其完整的#[source]链都不包含密钥值——即连 Rust 错误链上任何上游 message 也被检查而不只是最外层字符串。技能第 6 条的覆盖范围比错误消息更广错误errors、日志logs、issue、转写文本transcripts。与之配套的其他“零密钥输出”设计包括inspect-secrets的redacted渲染src/main.rs 中每个键打印为{key} redacted以及inspect对 secret/automation 列表的脱敏输出ADR-165 §2.3 称之为 “redacted secret/automation lists”。诚实的边界当前实现状态按技能文档的元规则以下状态必须如实描述依据 v2/crates/homecore-migrate/README.md 的 Remaining limitations 与 ADR-165 §2.5自动化转换未实现只 inspectautomations.yaml计数 ID/alias 列表不生成homecore-automationYAML!secret引用解析未实现除secrets.yaml本身外其他 YAML 文件中的密钥引用不会解析墓碑tombstone不导入已删除的实体/设备不留痕无并行 recorder 导出side-by-side 运行时模式依赖homecore-recorderADR-132当前是 feature-gated 的 no-op 桩性能数字是估计值ADR-165 明确标注 README 中的性能图信封解析 5 ms、1000 实体加载 50 ms为估计值尚待基准验证不应作为事实引用。另外ADR-165 还澄清了一个仓库历史细节homecore-migratecrate 早期引用的是“幻影身份” ADR-134与磁盘上真实的 ADR-134《First-Class CIR Support》撞号2026-06-12 的编号冲突决议后重指到 ADR-165crate 内残留的 “ADR-134” 字样应读作 ADR-165。验证与延伸阅读运行迁移相关测试与 lintcargo test -p homecore-migrate、cargo clippy -p homecore-migrate --all-targets -- -D warningsv2/crates/homecore-migrate/README.md。迁移契约的权威 ADRdocs/adr/ADR-165-homecore-migrate-from-home-assistant.md其中 §2.4 记录了安全审查的逐项结论源永不被修改、目标写入均为显式--to且 no-clobber、路径为用户提供的目录拼接固定文件名、未知 schema 版本 fail-closed、无 SQL/shell 注入面。评审纪律的上游载体harness/homecore/skills/migrate.md 与 harness/homecore/README.mdhomecore 元框架的只读边界与能力诚实原则。决策链ADR-126HOMECORE 主决策→ ADR-132recorderP2 导出目标→ ADR-165本文的迁移契约→ ADR-285homecore 元框架见 docs/adr/ADR-285-homecore-wasm-first-metaharness.md。【免费下载链接】RuViewπ RuView turns commodity WiFi signals into real-time spatial intelligence, vital sign monitoring, and presence detection — all without a single pixel of video.项目地址: https://gitcode.com/GitHub_Trending/wi/RuView创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表