(item CreatedItemReport, repoOverride string, objectKind string, load mutableStateLoader, strongOnMerge bool)
| 25 | type mutableStateLoader func(repo string, number int) (map[string]any, bool, error) |
| 26 | |
| 27 | func evalRetainedUpdate(item CreatedItemReport, repoOverride string, objectKind string, load mutableStateLoader, strongOnMerge bool) OutcomeReport { |
| 28 | repo := resolveItemRepo(item, repoOverride) |
| 29 | num := resolveItemNumber(item) |
| 30 | outcomeEvalUpdateLog.Printf("Evaluating retained update: kind=%s, type=%s, repo=%s, num=%d", objectKind, item.Type, repo, num) |
| 31 | report := OutcomeReport{ |
| 32 | Type: item.Type, |
| 33 | ObjectURL: item.URL, |
| 34 | ObjectNumber: num, |
| 35 | Repo: repo, |
| 36 | } |
| 37 | if num == 0 || repo == "" { |
| 38 | outcomeEvalUpdateLog.Printf("Missing execution state: num=%d, repo=%s", num, repo) |
| 39 | report.Result = OutcomeUnknown |
| 40 | report.Detail = "missing execution state" |
| 41 | report.OutcomeEvaluation = OutcomeEvaluation{ |
| 42 | OutcomeStatus: OutcomeStatusUnknown, |
| 43 | EvidenceStrength: EvidenceNone, |
| 44 | Signal: "missing_execution_state", |
| 45 | } |
| 46 | return report |
| 47 | } |
| 48 | if item.BeforeState == nil || item.AfterState == nil { |
| 49 | report.Result = OutcomeUnknown |
| 50 | report.Detail = "missing execution state" |
| 51 | report.OutcomeEvaluation = OutcomeEvaluation{ |
| 52 | OutcomeStatus: OutcomeStatusUnknown, |
| 53 | EvidenceStrength: EvidenceNone, |
| 54 | Signal: "missing_execution_state", |
| 55 | } |
| 56 | return report |
| 57 | } |
| 58 | |
| 59 | currentState, merged, err := load(repo, num) |
| 60 | if err != nil { |
| 61 | report.Result = OutcomeError |
| 62 | report.EvalError = err.Error() |
| 63 | return report |
| 64 | } |
| 65 | |
| 66 | comparison := compareRetainedUpdateState(item.BeforeState, item.AfterState, currentState, mutableTrackedFields(item.Type)) |
| 67 | outcomeEvalUpdateLog.Printf("State comparison for %s #%d: changed=%d, retained=%d, reverted=%d, replaced=%d, merged=%v", |
| 68 | objectKind, num, len(comparison.Changed), len(comparison.Retained), len(comparison.Reverted), len(comparison.Replaced), merged) |
| 69 | if len(comparison.Changed) == 0 { |
| 70 | report.Result = OutcomeUnknown |
| 71 | report.Detail = "no persisted state delta" |
| 72 | report.OutcomeEvaluation = OutcomeEvaluation{ |
| 73 | OutcomeStatus: OutcomeStatusUnknown, |
| 74 | EvidenceStrength: EvidenceNone, |
| 75 | Signal: "no_state_delta", |
| 76 | } |
| 77 | return report |
| 78 | } |
| 79 | |
| 80 | switch { |
| 81 | case len(comparison.Retained) == len(comparison.Changed): |
| 82 | report.Result = OutcomeAccepted |
| 83 | if strongOnMerge && merged { |
| 84 | report.Detail = objectKind + " update retained and merged" |
no test coverage detected