From 6ea1d4b729bdfc8c40f0d631dba223d8784e3653 Mon Sep 17 00:00:00 2001 From: Mikhail Date: Sat, 29 Aug 2026 11:12:42 +0300 Subject: [PATCH] GEN2-014: add reflex lifecycle and escalation --- contracts/capability/reflex_v2.go | 61 ++++++++++++++++++++++++ dev/ACTIVE_TASK.json | 2 +- modules/capability/domain/reflex.go | 22 +++++++++ modules/capability/domain/reflex_test.go | 21 ++++++++ 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 contracts/capability/reflex_v2.go create mode 100644 modules/capability/domain/reflex.go create mode 100644 modules/capability/domain/reflex_test.go diff --git a/contracts/capability/reflex_v2.go b/contracts/capability/reflex_v2.go new file mode 100644 index 0000000..7c67249 --- /dev/null +++ b/contracts/capability/reflex_v2.go @@ -0,0 +1,61 @@ +package capability + +type ReflexID string +type ReflexLifecycle string +type ReflexKind string + +const ( + ReflexCandidate ReflexLifecycle = "CANDIDATE" + ReflexValidating ReflexLifecycle = "VALIDATING" + ReflexActive ReflexLifecycle = "ACTIVE" + ReflexDegraded ReflexLifecycle = "DEGRADED" + ReflexStale ReflexLifecycle = "STALE" + ReflexSuspended ReflexLifecycle = "SUSPENDED" + ReflexRetired ReflexLifecycle = "RETIRED" + ReflexDeterministicCode ReflexKind = "DETERMINISTIC_CODE" + ReflexRule ReflexKind = "RULE" + ReflexWorkflow ReflexKind = "WORKFLOW" + ReflexQueryTemplate ReflexKind = "QUERY_TEMPLATE" + ReflexSmallModelChain ReflexKind = "SMALL_MODEL_CHAIN" + ReflexBoundedAdapter ReflexKind = "BOUNDED_ADAPTER_OPERATION" +) + +type ShadowPolicy struct { + Enabled bool + SampleRateMillis int64 + ComparatorRef string + MaxShadowCostMicros *int64 + EligibleErrorCostClasses []string +} +type RevalidationPolicy struct { + MaxAgeMillis *int64 + RevalidateOnDependencyRevisionChange bool + RevalidateOnWorldVersionChange bool + RevalidateAfterFailureCount *int64 + RevalidateAfterCorrectionCount *int64 + SampleAuditRateMillis *int64 +} +type Reflex struct { + ID ReflexID + PrincipalID string + SourceSkillRef SkillID + CreatedAt int64 +} +type ReflexRevision struct { + ReflexID ReflexID + Revision int64 + SourceSkillRevision int64 + Kind ReflexKind + Applicability ApplicabilitySpec + ImplementationRef string + ImplementationVersion string + ArtifactDigest string + DependencyRefs []string + ValidationEvidenceRefs []SkillEvidenceRef + KnownFailureExperienceRefs []SkillEvidenceRef + Shadow ShadowPolicy + Revalidation RevalidationPolicy + LastValidatedAt int64 + Lifecycle ReflexLifecycle + RecordedAt int64 +} diff --git a/dev/ACTIVE_TASK.json b/dev/ACTIVE_TASK.json index 72c44c9..d33a2bc 100644 --- a/dev/ACTIVE_TASK.json +++ b/dev/ACTIVE_TASK.json @@ -1 +1 @@ -{"task_file":"dev/tasks/GEN2-013-migrate-skill-v1-to-skill-v2-with-applicability-versioning-and-evidence.json","task_id":"GEN2-013","task_revision":1} +{"task_file":"dev/tasks/GEN2-014-add-explicit-reflex-lifecycle-shadow-reasoning-and-revalidation.json","task_id":"GEN2-014","task_revision":1} \ No newline at end of file diff --git a/modules/capability/domain/reflex.go b/modules/capability/domain/reflex.go new file mode 100644 index 0000000..ce637ba --- /dev/null +++ b/modules/capability/domain/reflex.go @@ -0,0 +1,22 @@ +package domain + +import ( + "fmt" + "git.cin.su/m/Assistant/contracts/capability" +) + +func ValidateReflexRevision(v capability.ReflexRevision) error { + if v.ReflexID == "" || v.SourceSkillRevision < 1 || v.Kind == "" || v.ImplementationRef == "" || v.Lifecycle == "" || v.RecordedAt < 1 { + return fmt.Errorf("invalid reflex revision") + } + if v.Lifecycle == capability.ReflexActive && len(v.ValidationEvidenceRefs) == 0 { + return fmt.Errorf("active reflex requires evidence") + } + return nil +} +func ReflexFallback(d capability.FastPathDecision) string { + if d.Decision == capability.FastPathApplied { + return "reflex" + } + return "skill->reasoning" +} diff --git a/modules/capability/domain/reflex_test.go b/modules/capability/domain/reflex_test.go new file mode 100644 index 0000000..ad9aa98 --- /dev/null +++ b/modules/capability/domain/reflex_test.go @@ -0,0 +1,21 @@ +package domain_test + +import ( + "git.cin.su/m/Assistant/contracts/capability" + "git.cin.su/m/Assistant/modules/capability/domain" + "testing" +) + +func TestReflexActiveRequiresEvidenceAndFallbacks(t *testing.T) { + v := capability.ReflexRevision{ReflexID: "r", SourceSkillRevision: 1, Kind: capability.ReflexRule, ImplementationRef: "rule", Lifecycle: capability.ReflexActive, RecordedAt: 1} + if domain.ValidateReflexRevision(v) == nil { + t.Fatal("active reflex without evidence") + } + v.ValidationEvidenceRefs = []capability.SkillEvidenceRef{"eval"} + if err := domain.ValidateReflexRevision(v); err != nil { + t.Fatal(err) + } + if domain.ReflexFallback(capability.FastPathDecision{Decision: capability.FastPathEscalate}) != "skill->reasoning" { + t.Fatal("missing escalation") + } +}