feat(t208): close candidate decision feedback loop
This commit is contained in:
@@ -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) &&
|
||||
|
||||
Reference in New Issue
Block a user