chore: establish local platform baseline

This commit is contained in:
Codex Local
2026-08-26 06:41:54 +08:00
commit 29bdf4900f
575 changed files with 95644 additions and 0 deletions
+408
View File
@@ -0,0 +1,408 @@
package firmwareconformance
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
"regexp"
"strings"
"time"
"github.com/google/uuid"
)
const (
DeviceEvidenceSchema = "firmware-device-evidence-v1"
ReportSchema = "firmware-conformance-report-v1"
)
var digestPattern = regexp.MustCompile(`^[0-9a-f]{64}$`)
type CloudRollout struct {
ID string `json:"id"`
ReleaseID string `json:"release_id"`
Status string `json:"status"`
Assignments []CloudAssignment `json:"assignments"`
}
type CloudAssignment struct {
DeviceID string `json:"device_id"`
DeviceModel string `json:"device_model"`
PreviousVersion string `json:"previous_version"`
Status string `json:"status"`
Events []CloudEvent `json:"events"`
}
type CloudEvent struct {
ID string `json:"id"`
CommandID string `json:"command_id"`
CommandStatus string `json:"command_status"`
AssignmentStatus string `json:"assignment_status"`
Phase string `json:"phase"`
ProgressPercent *int `json:"progress_percent"`
ResultCode string `json:"result_code"`
ActiveSlot string `json:"active_slot"`
TargetSlot string `json:"target_slot"`
PreviousSlot string `json:"previous_slot"`
FailedSlot string `json:"failed_slot"`
BootAttemptID string `json:"boot_attempt_id"`
RollbackApplied *bool `json:"rollback_applied"`
RollbackVersion string `json:"rollback_version"`
InstalledVersion string `json:"installed_version"`
VerifiedSHA256 string `json:"verified_sha256"`
VerifiedSigningKeyID string `json:"verified_signing_key_id"`
ResultDigest string `json:"result_digest"`
ReportedAt time.Time `json:"reported_at"`
}
type DeviceEvidence struct {
SchemaVersion string `json:"schema_version"`
EvidenceSource string `json:"evidence_source"`
CandidateVersion string `json:"candidate_version"`
BuildDigest string `json:"build_digest"`
DeviceID string `json:"device_id"`
DeviceModel string `json:"device_model"`
HardwareRevision string `json:"hardware_revision"`
ReleaseID string `json:"release_id"`
CommandID string `json:"command_id"`
Scenario string `json:"scenario"`
BootloaderVersion string `json:"bootloader_version"`
PartitionTableSHA256 string `json:"partition_table_sha256"`
SecureBootEnabled bool `json:"secure_boot_enabled"`
ArtifactSHA256 string `json:"artifact_sha256"`
SigningKeyID string `json:"signing_key_id"`
InitialSlot string `json:"initial_slot"`
TargetSlot string `json:"target_slot"`
FinalSlot string `json:"final_slot"`
InitialVersion string `json:"initial_version"`
TargetVersion string `json:"target_version"`
FinalVersion string `json:"final_version"`
BootAttemptID string `json:"boot_attempt_id"`
CollectedAt time.Time `json:"collected_at"`
Events []DeviceEvent `json:"events"`
}
type DeviceEvent struct {
Phase string `json:"phase"`
OccurredAt time.Time `json:"occurred_at"`
ActiveSlot string `json:"active_slot,omitempty"`
TargetSlot string `json:"target_slot,omitempty"`
ResultCode string `json:"result_code,omitempty"`
BootAttemptID string `json:"boot_attempt_id,omitempty"`
}
type Check struct {
Code string `json:"code"`
Status string `json:"status"`
Detail string `json:"detail"`
}
type Report struct {
SchemaVersion string `json:"schema_version"`
Result string `json:"result"`
GeneratedAt time.Time `json:"generated_at"`
CandidateVersion string `json:"candidate_version"`
BuildDigest string `json:"build_digest"`
EvidenceScope string `json:"evidence_scope"`
ExternalValidationRequired bool `json:"external_validation_required"`
DeviceID string `json:"device_id"`
ReleaseID string `json:"release_id"`
RolloutID string `json:"rollout_id"`
CommandID string `json:"command_id"`
Scenario string `json:"scenario"`
CloudEventCount int `json:"cloud_event_count"`
DeviceEventCount int `json:"device_event_count"`
InputSHA256 map[string]string `json:"input_sha256"`
Checks []Check `json:"checks"`
Disclaimer string `json:"disclaimer"`
}
func ParseCloud(content []byte) (CloudRollout, error) {
var envelope struct {
Data json.RawMessage `json:"data"`
}
if err := json.Unmarshal(content, &envelope); err != nil {
return CloudRollout{}, fmt.Errorf("decode cloud rollout: %w", err)
}
payload := content
if len(envelope.Data) > 0 && string(envelope.Data) != "null" {
payload = envelope.Data
}
var rollout CloudRollout
if err := json.Unmarshal(payload, &rollout); err != nil {
return CloudRollout{}, fmt.Errorf("decode cloud rollout data: %w", err)
}
if rollout.ID == "" || rollout.ReleaseID == "" {
return CloudRollout{}, errors.New("cloud rollout is missing id or release_id")
}
return rollout, nil
}
func ParseDeviceEvidence(content []byte) (DeviceEvidence, error) {
var evidence DeviceEvidence
decoder := json.NewDecoder(bytes.NewReader(content))
decoder.DisallowUnknownFields()
if err := decoder.Decode(&evidence); err != nil {
return DeviceEvidence{}, fmt.Errorf("decode device evidence: %w", err)
}
var trailing any
if err := decoder.Decode(&trailing); !errors.Is(err, io.EOF) {
return DeviceEvidence{}, errors.New("device evidence contains trailing JSON data")
}
return evidence, nil
}
// ParseReport reads the exact report format emitted by cmd/firmware-conformance.
// Strict decoding prevents an unreviewed producer extension from being treated as
// release evidence by downstream packaging tools.
func ParseReport(content []byte) (Report, error) {
var report Report
decoder := json.NewDecoder(bytes.NewReader(content))
decoder.DisallowUnknownFields()
if err := decoder.Decode(&report); err != nil {
return Report{}, fmt.Errorf("decode firmware conformance report: %w", err)
}
var trailing any
if err := decoder.Decode(&trailing); !errors.Is(err, io.EOF) {
return Report{}, errors.New("firmware conformance report contains trailing JSON data")
}
return report, nil
}
func Evaluate(cloud CloudRollout, device DeviceEvidence, generatedAt time.Time) Report {
report := Report{
SchemaVersion: ReportSchema, Result: "PASS", GeneratedAt: generatedAt.UTC(), CandidateVersion: device.CandidateVersion,
BuildDigest: device.BuildDigest, EvidenceScope: "PROTOCOL_SIMULATION", ExternalValidationRequired: true,
DeviceID: device.DeviceID, ReleaseID: device.ReleaseID, RolloutID: cloud.ID, CommandID: device.CommandID, Scenario: device.Scenario,
CloudEventCount: 0, DeviceEventCount: len(device.Events), InputSHA256: map[string]string{}, Checks: []Check{},
Disclaimer: "一致性通过只证明所提供设备证据与云端固件时间线相互匹配;不替代真实Bootloader、闪存掉电一致性、硬件安全或生产发布验收。",
}
if device.EvidenceSource == "HARDWARE" {
report.EvidenceScope = "HARDWARE_CAPTURE"
}
add := func(code string, ok bool, detail string) {
status := "PASS"
if !ok {
status = "FAIL"
report.Result = "FAIL"
}
report.Checks = append(report.Checks, Check{Code: code, Status: status, Detail: detail})
}
add("DEVICE_EVIDENCE_SCHEMA", device.SchemaVersion == DeviceEvidenceSchema, "设备证据必须使用"+DeviceEvidenceSchema)
add("EVIDENCE_SOURCE", device.EvidenceSource == "SIMULATOR" || device.EvidenceSource == "HARDWARE", "证据来源必须明确为SIMULATOR或HARDWARE")
buildOK := strings.TrimSpace(device.CandidateVersion) != "" && strings.HasPrefix(device.BuildDigest, "sha256:") && digestPattern.MatchString(strings.TrimPrefix(device.BuildDigest, "sha256:"))
add("CANDIDATE_IDENTITY", buildOK, "候选版本和sha256构建摘要必须完整")
identityOK := validUUID(device.DeviceID) && validUUID(device.ReleaseID) && validUUID(device.CommandID) && device.DeviceModel != "" && device.HardwareRevision != ""
add("DEVICE_IDENTITY", identityOK, "设备、发布和命令必须使用公开UUID,并提供型号与硬件版本")
platformOK := device.BootloaderVersion != "" && digestPattern.MatchString(device.PartitionTableSHA256)
add("DEVICE_PLATFORM_METADATA", platformOK, fmt.Sprintf("Bootloader=%s,安全启动=%t,分区表摘要必须为SHA-256", device.BootloaderVersion, device.SecureBootEnabled))
artifactOK := digestPattern.MatchString(device.ArtifactSHA256) && device.SigningKeyID != ""
add("ARTIFACT_IDENTITY", artifactOK, "设备证据必须绑定完整制品摘要和签名密钥编号")
assignment, found := findAssignment(cloud.Assignments, device.DeviceID)
add("CLOUD_ASSIGNMENT", found, "云端批次必须包含目标设备且只能匹配一条分配")
add("RELEASE_BINDING", cloud.ReleaseID == device.ReleaseID, "设备证据发布编号必须与云端批次一致")
if found {
report.CloudEventCount = len(assignment.Events)
}
cloudArtifactBound := false
if found {
for _, event := range assignment.Events {
if event.VerifiedSHA256 == device.ArtifactSHA256 && event.VerifiedSigningKeyID == device.SigningKeyID {
cloudArtifactBound = true
break
}
}
}
add("CLOUD_ARTIFACT_BINDING", cloudArtifactBound, "云端阶段时间线必须包含与设备一致的已验证摘要和签名密钥")
commandBound := found && len(assignment.Events) > 0
if commandBound {
for _, event := range assignment.Events {
if event.CommandID != device.CommandID {
commandBound = false
break
}
}
}
add("COMMAND_BINDING", commandBound, "全部云端阶段事件必须绑定同一设备命令")
cloudTimelineOK := found && validateCloudTimeline(assignment.Events)
add("CLOUD_TIMELINE_INTEGRITY", cloudTimelineOK, "事件编号、结果摘要哈希、接收时间和顺序必须有效")
deviceTimelineOK := validateDeviceTimeline(device.Events, device.CollectedAt)
add("DEVICE_TIMELINE_INTEGRITY", deviceTimelineOK, "设备事件必须按时间升序且不晚于证据采集时间")
terminalPhase, scenarioOK := scenarioTerminalPhase(device.Scenario)
add("SCENARIO_SUPPORTED", scenarioOK, "场景必须为AB_SUCCESS、AB_ROLLBACK、POWER_LOSS_AFTER_STAGE或POWER_LOSS_DURING_BOOT")
required := []string{"staging", "reboot_pending", "boot_verifying", terminalPhase}
cloudPhasesOK := scenarioOK && found && containsPhaseSequence(cloudPhases(assignment.Events), required)
deviceRequired := append([]string{}, required...)
if device.Scenario == "POWER_LOSS_AFTER_STAGE" {
deviceRequired = []string{"staging", "power_loss_after_stage", "reboot_pending", "boot_verifying", terminalPhase}
}
if device.Scenario == "POWER_LOSS_DURING_BOOT" {
deviceRequired = []string{"staging", "reboot_pending", "boot_verifying", "power_loss_during_boot", "boot_verifying", terminalPhase}
}
devicePhasesOK := scenarioOK && containsPhaseSequence(devicePhases(device.Events), deviceRequired)
add("CLOUD_PHASE_SEQUENCE", cloudPhasesOK, "云端必须按顺序留存写入、待重启、健康确认和终态")
add("DEVICE_PHASE_SEQUENCE", devicePhasesOK, "设备侧必须提供与场景一致的本地阶段顺序")
bootAttemptOK := found && device.BootAttemptID != ""
if bootAttemptOK {
seen := false
for _, event := range assignment.Events {
if event.BootAttemptID == "" {
continue
}
seen = true
if event.BootAttemptID != device.BootAttemptID {
bootAttemptOK = false
}
}
bootAttemptOK = bootAttemptOK && seen
}
add("BOOT_ATTEMPT_BINDING", bootAttemptOK, "设备和云端必须引用同一启动尝试编号")
phaseTimeOK, maxSkew := phaseTimeCorrelation(assignment.Events, device.Events)
add("PHASE_TIME_CORRELATION", found && phaseTimeOK, fmt.Sprintf("同名设备/云端阶段最大时间差为%s,允许10分钟", maxSkew.Round(time.Second)))
slotOK := device.InitialSlot != "" && device.TargetSlot != "" && device.InitialSlot != device.TargetSlot
versionOK := device.InitialVersion != "" && device.TargetVersion != "" && device.FinalVersion != ""
outcomeOK := false
if found && scenarioOK && len(assignment.Events) > 0 {
finalEvent := assignment.Events[len(assignment.Events)-1]
if terminalPhase == "rolled_back" {
outcomeOK = assignment.Status == "FAILED" && finalEvent.CommandStatus == "FAILED" && finalEvent.Phase == "rolled_back" && finalEvent.RollbackApplied != nil && *finalEvent.RollbackApplied && finalEvent.RollbackVersion == device.InitialVersion && device.FinalSlot == device.InitialSlot && device.FinalVersion == device.InitialVersion
slotOK = slotOK && device.FinalSlot == device.InitialSlot
versionOK = versionOK && device.FinalVersion == device.InitialVersion
} else {
outcomeOK = assignment.Status == "CONFIRMED" && finalEvent.CommandStatus == "SUCCEEDED" && finalEvent.Phase == "confirmed" && finalEvent.InstalledVersion == device.TargetVersion && finalEvent.VerifiedSHA256 == device.ArtifactSHA256 && finalEvent.VerifiedSigningKeyID == device.SigningKeyID && device.FinalSlot == device.TargetSlot && device.FinalVersion == device.TargetVersion
slotOK = slotOK && device.FinalSlot == device.TargetSlot
versionOK = versionOK && device.FinalVersion == device.TargetVersion
}
}
add("SLOT_TRANSITION", slotOK, "目标分区必须不同于初始分区,成功或回退后的活动分区必须符合场景")
add("VERSION_TRANSITION", versionOK, "最终版本必须与成功升级或自动回退结果一致")
add("TERMINAL_OUTCOME", outcomeOK, "云端命令、分配终态、设备分区和最终版本必须一致")
return report
}
func SHA256(content []byte) string {
digest := sha256.Sum256(content)
return hex.EncodeToString(digest[:])
}
func validUUID(value string) bool {
_, err := uuid.Parse(value)
return err == nil
}
func findAssignment(items []CloudAssignment, deviceID string) (CloudAssignment, bool) {
var result CloudAssignment
count := 0
for _, item := range items {
if item.DeviceID == deviceID {
result = item
count++
}
}
return result, count == 1
}
func validateCloudTimeline(events []CloudEvent) bool {
if len(events) == 0 {
return false
}
for index, event := range events {
if !validUUID(event.ID) || !validUUID(event.CommandID) || !digestPattern.MatchString(event.ResultDigest) || event.ReportedAt.IsZero() {
return false
}
if index > 0 && event.ReportedAt.Before(events[index-1].ReportedAt) {
return false
}
}
return true
}
func validateDeviceTimeline(events []DeviceEvent, collectedAt time.Time) bool {
if len(events) == 0 || collectedAt.IsZero() {
return false
}
for index, event := range events {
if event.Phase == "" || event.OccurredAt.IsZero() || event.OccurredAt.After(collectedAt) {
return false
}
if index > 0 && event.OccurredAt.Before(events[index-1].OccurredAt) {
return false
}
}
return true
}
func scenarioTerminalPhase(scenario string) (string, bool) {
switch scenario {
case "AB_SUCCESS", "POWER_LOSS_AFTER_STAGE", "POWER_LOSS_DURING_BOOT":
return "confirmed", true
case "AB_ROLLBACK":
return "rolled_back", true
default:
return "", false
}
}
func cloudPhases(events []CloudEvent) []string {
result := make([]string, 0, len(events))
for _, event := range events {
result = append(result, event.Phase)
}
return result
}
func devicePhases(events []DeviceEvent) []string {
result := make([]string, 0, len(events))
for _, event := range events {
result = append(result, event.Phase)
}
return result
}
func containsPhaseSequence(actual, required []string) bool {
position := 0
for _, value := range actual {
if position < len(required) && value == required[position] {
position++
}
}
return position == len(required)
}
func phaseTimeCorrelation(cloud []CloudEvent, device []DeviceEvent) (bool, time.Duration) {
maximum := time.Duration(0)
matched := 0
for _, local := range device {
closest := time.Duration(1<<63 - 1)
for _, remote := range cloud {
if remote.Phase != local.Phase {
continue
}
difference := remote.ReportedAt.Sub(local.OccurredAt)
if difference < 0 {
difference = -difference
}
if difference < closest {
closest = difference
}
}
if closest == time.Duration(1<<63-1) {
continue
}
matched++
if closest > maximum {
maximum = closest
}
}
return matched >= 4 && maximum <= 10*time.Minute, maximum
}