feat(t208): close candidate decision feedback loop

This commit is contained in:
QiuSW
2026-07-28 11:57:25 +08:00
parent 2a5ded42b5
commit e7f4c3e114
35 changed files with 2854 additions and 203 deletions
@@ -18,11 +18,12 @@ import (
)
const (
executionResultEventsOperation = "EVENTS"
executionResultEvidenceOperation = "EVIDENCE"
executionResultCandidatesOperation = "CANDIDATES"
executionResultCompleteOperation = "COMPLETE"
executionResultFailOperation = "FAIL"
executionResultEventsOperation = "EVENTS"
executionResultEvidenceOperation = "EVIDENCE"
executionResultCandidatesOperation = "CANDIDATES"
executionResultHumanReviewOperation = "HUMAN_REVIEW"
executionResultCompleteOperation = "COMPLETE"
executionResultFailOperation = "FAIL"
manualFirstMode = "MANUAL_FIRST"
aiAssistedMode = "AI_ASSISTED"
@@ -531,21 +532,16 @@ func validateCandidateCommand(command StoreExecutionCandidatesCommand) error {
} else if command.Provenance != nil {
return executionResultInvalid("provenance", "must be omitted for MANUAL_FIRST")
}
strictSKUMatching := command.ExecutionMode == aiAssistedMode &&
command.Provenance.SchemaVersion >= 2
for index, candidate := range command.Candidates {
if candidate.Ordinal != index+1 ||
!validCandidate(candidate, command.ExecutionMode) ||
(strictSKUMatching && !validSKUMatchedCandidate(candidate)) {
!validCandidate(candidate, command.ExecutionMode) {
return executionResultInvalid("candidates", "must be continuous, bounded observations")
}
}
if strictSKUMatching && len(command.Candidates) > 0 &&
(command.Recommendation == nil ||
command.Recommendation.CandidateOrdinal != 1) {
if command.ExecutionMode == manualFirstMode && command.Recommendation != nil {
return executionResultInvalid(
"recommendation",
"must select the first sorted SKU-matched candidate",
"must be omitted for MANUAL_FIRST",
)
}
if command.Recommendation != nil {
@@ -553,7 +549,12 @@ func validateCandidateCommand(command StoreExecutionCandidatesCommand) error {
if recommendation.CandidateOrdinal < 1 ||
recommendation.CandidateOrdinal > len(command.Candidates) ||
!validAuditText(recommendation.PolicyVersion, 128) ||
!validStringList(recommendation.Reasons, 8, 160) {
!validStringList(recommendation.Reasons, 8, 160) ||
(command.ExecutionMode == aiAssistedMode &&
command.Provenance.SchemaVersion >= 2 &&
!validSKUMatchedCandidate(
command.Candidates[recommendation.CandidateOrdinal-1],
)) {
return executionResultInvalid("recommendation", "is invalid")
}
}
@@ -638,7 +639,8 @@ func validSKUMatchedCandidate(candidate ExecutionCandidate) bool {
value.Score >= 0.75 &&
value.Confidence >= 0.75 &&
len(value.RejectionReasons) == 0 &&
len(value.HardConstraints) == 2
len(value.HardConstraints) == 2 &&
allHardConstraintsMatch(value.HardConstraints)
}
func validCandidateHardConstraints(
@@ -653,7 +655,9 @@ func validCandidateHardConstraints(
seen := map[string]struct{}{}
for _, value := range values {
if (value.Kind != "COLOR" && value.Kind != "SIZE") ||
value.Status != "MATCH" ||
(value.Status != "MATCH" &&
value.Status != "MISMATCH" &&
value.Status != "UNKNOWN") ||
!validAuditText(value.Expected, 128) ||
!validAuditText(value.Evidence, 160) {
return false
@@ -666,6 +670,17 @@ func validCandidateHardConstraints(
return len(seen) == 2
}
func allHardConstraintsMatch(
values []CandidateHardConstraintEvaluation,
) bool {
for _, value := range values {
if value.Status != "MATCH" {
return false
}
}
return true
}
func validProvenance(value *ExecutionProvenance) bool {
return value != nil &&
validAuditText(value.ProviderID, 64) &&