101 lines
4.4 KiB
Go
101 lines
4.4 KiB
Go
package domain
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.cin.su/m/Assistant/contracts/capability"
|
|
)
|
|
|
|
func TestRepeatedCapabilityFailuresDegradeSkillWithoutDeletingHistory(t *testing.T) {
|
|
profile := skillProfile()
|
|
profile.SupportingExperienceRefs = []capability.SkillEvidenceRef{"experience:success-1"}
|
|
for _, ref := range []capability.SkillEvidenceRef{"experience:failure-1", "experience:failure-2", "experience:failure-3"} {
|
|
next, err := ObserveSkillOutcome(profile, capability.SkillOutcomeObservation{ExperienceRef: ref, Outcome: capability.UsageFailed, ObservedAtUnixMillis: profile.RecordedAtUnixMillis + 100})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
profile = next
|
|
}
|
|
if profile.Status != capability.SkillDegraded {
|
|
t.Fatalf("expected degraded skill, got %#v", profile)
|
|
}
|
|
if len(profile.SupportingExperienceRefs) != 1 || len(profile.KnownFailureExperienceRefs) != 3 {
|
|
t.Fatalf("skill degradation must preserve success/failure evidence: %#v", profile)
|
|
}
|
|
}
|
|
|
|
func TestFastPathDeclinesUnsupportedInputAndEscalatesToThinking(t *testing.T) {
|
|
decision, err := DecideFastPath(skillProfile(), false, 900, false, false, 2000)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if decision.Decision != capability.FastPathEscalate || decision.DeclineReason != capability.FastPathOutOfDistribution || !decision.RequiresCognition {
|
|
t.Fatalf("unexpected fast path decision: %#v", decision)
|
|
}
|
|
}
|
|
|
|
func TestActiveSkillCanApplyFastPathWhenFreshAndConfident(t *testing.T) {
|
|
decision, err := DecideFastPath(skillProfile(), true, 950, false, false, 2000)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if decision.Decision != capability.FastPathApplied || decision.RequiresCognition {
|
|
t.Fatalf("unexpected fast path decision: %#v", decision)
|
|
}
|
|
}
|
|
|
|
func TestUnknownAndSkippedOutcomesDoNotBecomeSkillFailures(t *testing.T) {
|
|
profile := skillProfile()
|
|
for _, outcome := range []capability.UsageOutcomeClass{capability.UsageUnknown, capability.UsageSkipped} {
|
|
next, err := ObserveSkillOutcome(profile, capability.SkillOutcomeObservation{ExperienceRef: capability.SkillEvidenceRef("experience:" + string(outcome)), Outcome: outcome, ObservedAtUnixMillis: profile.RecordedAtUnixMillis + 1})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if next.ObservedFailureCount != profile.ObservedFailureCount || len(next.KnownFailureExperienceRefs) != len(profile.KnownFailureExperienceRefs) || next.ConfidenceMillis != profile.ConfidenceMillis {
|
|
t.Fatalf("outcome %q was incorrectly recorded as failure: %#v", outcome, next)
|
|
}
|
|
profile = next
|
|
}
|
|
}
|
|
|
|
func TestCandidateNeedsIndependentRepeatableValidationBeforeActive(t *testing.T) {
|
|
profile := skillProfile()
|
|
profile.Status = capability.SkillCandidate
|
|
profile.VerifiedOutcomeCount = 1
|
|
profile.SupportingExperienceRefs = []capability.SkillEvidenceRef{"experience:1"}
|
|
if _, err := ValidateSkill(profile, "evaluation:independent", true, true, 2000); err == nil {
|
|
t.Fatal("one success promoted a skill")
|
|
}
|
|
profile.VerifiedOutcomeCount = 2
|
|
profile.SupportingExperienceRefs = append(profile.SupportingExperienceRefs, "experience:2")
|
|
validated, err := ValidateSkill(profile, "evaluation:independent", true, true, 2000)
|
|
if err != nil || validated.Status != capability.SkillValidated {
|
|
t.Fatalf("validation=%#v err=%v", validated, err)
|
|
}
|
|
active, err := ActivateSkill(validated, 2100)
|
|
if err != nil || active.Status != capability.SkillActive {
|
|
t.Fatalf("activation=%#v err=%v", active, err)
|
|
}
|
|
}
|
|
|
|
func skillProfile() capability.SkillProfile {
|
|
return capability.SkillProfile{
|
|
ID: "skill-obvious-reminder-response-v1",
|
|
Revision: 1,
|
|
Name: "Resolve obvious reminder continuation",
|
|
Description: "Use a recent unambiguous reminder/attention target for complete/snooze/cancel without cognition.",
|
|
ApplicableContext: []string{"continuity:reminder-response"},
|
|
ImplementationRef: "continuity:human-response-target-resolver-v1",
|
|
ImplementationVersion: "1",
|
|
Status: capability.SkillActive,
|
|
ConfidenceMillis: 850,
|
|
LastValidatedUnixMillis: 1000,
|
|
RecordedAtUnixMillis: 1000,
|
|
SupportingExperienceRefs: []capability.SkillEvidenceRef{"experience:1", "experience:2"},
|
|
IndependentEvaluationRefs: []capability.SkillEvidenceRef{"evaluation:independent"},
|
|
ValidationEvidenceRefs: []capability.SkillEvidenceRef{"evaluation:independent"},
|
|
VerifiedOutcomeCount: 2,
|
|
MustNotWorsenSatisfied: true,
|
|
}
|
|
}
|