10 KiB
PSP 数据契约
所有 SHA 使用 64 位小写 SHA-256;Git commit 使用仓库返回的完整 SHA。状态必须引用实际证据,不允许人工填写 passed 掩盖未执行步骤。
外部 hardware-topology.json
硬件事实文件保存在 PSP 仓库外,避免把附件绝对路径和调查状态写入正式配置。最小结构如下:
{
"schema_version": 1,
"project": "LY-SM-YT42-AI",
"chip": "CV1841CP",
"system_mode": "dualos",
"storage": {"type": "spinand", "capacity_bytes": 134217728},
"sources": [{"kind": "schematic", "path": "/absolute/file.pdf", "sha256": "<sha256>"}],
"conflicts": [],
"sensors": [{
"section": "sensor",
"model": "MIS40C1",
"enum_name": "<规格对应枚举名>",
"i2c_bus": 2,
"i2c_address": "0x30",
"mipi_device": 1,
"lane_count": 1,
"evidence_sources": [0],
"config_expectations": {"bus_id": 2, "sns_i2c_addr": "0x30", "devno": 1}
}]
}
config_expectations 使用目标 sensor_cfg.ini 的真实字段名,不由工具猜测别名。证据冲突未解决时 conflicts 保留明细且验证失败。Flash 型号未提供时可以省略 storage.model,但容量和介质类型不能省略。
外部三方差异报告
analyze_psp_delta.py 输出目标 HEAD/worktree 与参考 HEAD/worktree 四视图,记录两个完整 commit、双方 dirty 状态、参考 dirty paths,以及 matches_reference_head、matches_reference_dirty_worktree、target_unchanged、target_specific、unclassified_conflict 分类。报告保存在仓库外;引用参考脏内容时必须明确它不能由参考 commit 单独复现。
无参考 PSP 时四视图报告为 N/A,不伪造参考。psp_project_guard.py prepare-empty 的 manifest 使用 reference: null、reference_baseline: "empty"、空 source_inventory;外部 CV181X Media/AI 审计报告保存精确 Release 路径、configs.json / profile.json hash、全部字段默认值及实际差异。render_psp_handoff.py 传 --no-reference,交接中 reference_psp.source 和 commit 均为 null;不得用 "none" 之类假路径。
metadata/bsp.lock.json
PSP 仓库内保存 BSP handoff 的稳定摘要,不保存自身 commit:
{
"schema_version": 1,
"handoff_path": "/absolute/BSP/doc/bsp_adaptation/handoff/psp_handoff.json",
"handoff_sha256": "<sha256>",
"bsp_project": "CV1841CP-LY-SM-YT70_dualos",
"bsp_commit": "<完整Git SHA或旧交接中的null>",
"bsp_source_dirty": false,
"chip": "CV1841CP",
"build_id": "20260901_1",
"imgs_version_path": "/epbuild/EMX2.0/EmxRes/.../imgs/20260901_1",
"output_permissions": {
"policy": "a+rX",
"evidence_path": "/absolute/BSP/doc/bsp_adaptation/validation/output_permissions_20260901_1.json",
"output_root": "/epbuild/EMX2.0/EmxRes",
"imgs_version_path": "/epbuild/EMX2.0/EmxRes/.../imgs/20260901_1",
"passed": true
},
"image_partition_margin": {
"partition_table": "/absolute/BSP/configs/.../partition_spinand.xml",
"required_margin_bytes": 524288,
"checks": [
{
"image": "kernel.bin",
"image_size_bytes": 2621440,
"effective_partition_size_bytes": 3670016,
"actual_margin_bytes": 1048576,
"passed": true
},
{
"image": "rootfs.bin",
"image_size_bytes": 3145728,
"effective_partition_size_bytes": 4194304,
"actual_margin_bytes": 1048576,
"passed": true
}
]
},
"artifacts": [
{
"relative_path": "boot.bin",
"absolute_path": "/epbuild/.../boot.bin",
"size": 123,
"sha256": "<sha256>"
}
],
"mixed_build": null,
"warnings": []
}
混用构建时 mixed_build 记录每个文件来源、build ID、commit、hash、原因、风险、确认人和时间;默认值为 null。
metadata/allowed-overrides.json
为保持 psp.json 兼容,应用同名覆盖的精确白名单放在 sidecar:
{
"schema_version": 1,
"overrides": [
{
"psp_path": "configs/sdcard.json",
"application_path": "orgConfigs/sdcard.json",
"winner": "psp",
"reason": "板级存储配置由 PSP 提供",
"confirmed_by": "<负责人角色或姓名>",
"confirmed_at": "<ISO-8601>"
}
]
}
路径必须是仓库内精确相对路径,不允许绝对路径、.. 或通配符。
metadata/media-runtime-exception.json
仅在 Media profile 的运行库或驱动列表为空、但应用工程有已验证替代来源时使用:
{
"schema_version": 1,
"media_version": "<精确版本>",
"reason": "<为何 PSP 列表为空>",
"alternatives": [
{
"kind": "userspace_or_driver",
"source": "Public/EmxRes/<精确相对路径>",
"destination": "<组包目标相对路径>",
"sha256": "<实际文件hash>"
}
],
"confirmed_by": "<负责人>",
"confirmed_at": "<ISO-8601>"
}
正式 preflight 必须在当前应用工程中重新验证每个 source/hash 和目标映射。文件缺失、hash 漂移、Media 版本变化或 destination 未被实际打包时例外失效。
应用侧 psp.lock.json
由应用层创建,不放进 PSP 仓库:
{
"schema_version": 1,
"project_id": "LY-SM-YT70",
"psp_path": "psp",
"psp_repository": "<团队共享Git地址>",
"psp_commit": "<完整Git SHA>",
"expected_state": "candidate",
"bsp_build_id": "20260901_1",
"etunel_work_id": "<WORK_ID>",
"etunel_handoff_subtask": "<SUBTASK_ID>"
}
submodule gitlink 是实际锁定依据;lock 用于人和工具核对。两者不一致时停止构建。
CV18 Sensor 静态证据
validate_psp.py 的 checks.sensor_baseline 记录 sensor_cfg.ini 的绝对路径/hash、枚举头文件绝对路径/hash/enum tag/source、芯片系列和每个 Sensor section 的规格枚举名称、期望配置值、实际值及匹配结果。默认 source=bundled,由芯片系列自动选择 skill 内置枚举表;只有明确传入替代头文件时为 source=override。CV181X 的 expected_config_value 是枚举名称;CV184X 是从 _SNS_TYPE_E 解析出的规范十六进制值。
本地固定打包契约和 packaging-result.json
用户提供应用工程路径和芯片后,record_packaging_result.py contract 按 EMX2.1 固定目录与命令生成打包契约。契约不放进 PSP 仓库,机器 schema 为:
{
"schema_version": 2,
"contract_type": "emx21-project-packaging",
"contract_id": "<稳定且唯一的契约ID>",
"chips": ["CV1841CP"],
"project_root": "/absolute/application-project",
"psp_path": "/absolute/application-project/psp",
"working_directory": "/absolute/application-project/scripts",
"output_root": "/absolute/application-project/output",
"product_command": "./product.py",
"release_commands": ["./release.py 0", "./release.py 1"],
"success_exit_codes": [0]
}
四个路径必须严格满足上述父子关系,命令必须逐字匹配;应用工程路径、psp 子仓库或脚本无法验证时不得创建占位值或形成 packaged。release.py 1 还需要本轮用户确认 clean rebuild,不能只依赖契约中的允许列表。
record_packaging_result.py preflight 生成不可覆盖的 schema_version: 1 检查结果。候选提交前可以用 --psp-source <staging> 检查待导入内容;正式组包前必须使用应用工程内 psp、完整 commit 和 --formal。结果至少记录 PSP/脚本路径、资源来源映射、分区、BSP 分区比对、错误和警告。
validate_partition_closure.py 输出外部 schema_version: 1 分区检查报告,包含从 psp.json 推导的每个分区 offset/size、Boot/Default 逐字段比对,以及 mkAiData.py 参数、LEB 请求字节、PEB 保留字节和 DATA 容量。该报告通过后,才允许把分区相关修改标为检查通过。
record_packaging_result.py snapshot 生成不可覆盖的 schema_version: 3 快照,至少锁定契约路径/hash/id、打包前 PSP Git 状态、应用工程 Git 状态和既有 output 直接版本目录及目录树 hash。
record_packaging_result.py record 生成 schema_version: 2 的 packaging-result.json,至少包含 passed、契约路径/hash/id、芯片、PSP 仓库/commit/dirty、BSP build ID、应用工程路径/commit/dirty、执行目录、两阶段精确命令/退出码/日志证据、clean rebuild 确认状态、本轮新增版本目录绝对路径和完整文件清单,以及用户/项目指定烧录包的绝对路径、大小、mtime 和 SHA-256。日志证据只保存外部日志路径/hash/大小以及失败或警告的行号和行 hash,不复制日志正文。
本轮必须恰好新增一个 output/<版本>/ 直接子目录,且既有版本目录未被修改或删除。handoff 生成时再次核对契约文件和烧录包 hash。
外部 device-validation.json
{
"schema_version": 1,
"result": "PASS",
"evidence_source": "USER_REPORTED",
"psp_commit": "<完整Git SHA>",
"image_path": "/absolute/path/to/flash-package.img",
"image_sha256": "<sha256>",
"board": "LY-SM-YT70",
"hardware_revision": "<revision>",
"checks": [
{"name": "boot", "result": "PASS", "evidence": "<用户反馈摘要>"}
],
"unexecuted": [],
"issues": [],
"confirmed_by": "<用户或负责人>",
"confirmed_at": "<ISO-8601>"
}
适用检查未执行时总体结果不能为 PASS。
外部 application-integration.json
至少包含 schema、结果、PSP commit、应用仓库/commit、应用构建和打包命令/退出码、产物证据、覆盖检查、未执行项、应用负责人和确认时间。
外部 psp-handoff.json
由 render_psp_handoff.py 汇总,不复制 PSP 配置。至少包含项目/芯片、PSP 仓库/完整 commit/Git 状态、参考 PSP、BSP lock、Media/AIPlugin 基线、验证状态、烧录包、应用集成、Etunel 标识、自检、负责人确认、未执行项、警告、例外和风险。没有有效 Etunel 上下文时必须标记 etunel.sent=false。供 Etunel 使用时只允许 packaged 或 accepted,并记录 git ls-remote 对当前共享 URL/commit 的可达性结果;生成文件本身仍保持 sent=false。