Compare commits

..
Author SHA1 Message Date
m 36272b9036 GEN2-019: add advisory consequence assessment
CI / test (push) Failing after 29s
2026-08-29 11:28:52 +03:00
m a779568622 GEN2-018: add bounded perspectives over Work Graph
CI / test (push) Failing after 27s
2026-08-29 11:28:05 +03:00
7 changed files with 112 additions and 1 deletions
+24
View File
@@ -0,0 +1,24 @@
package work
type ConsequenceAssessment struct {
ID string
TargetRefs []string
Impact int64
Reversibility int64
Uncertainty int64
Scope int64
Recoverability int64
CostOfError int64
ExpectedConsequences []string
MitigationOptions []string
RequiresDryRun bool
RequiresBackup bool
RecommendedConfirmation string
OwnerAccepted bool
EvidenceRefs []EvidenceRef
RecordedAtUnixMillis int64
}
func (a ConsequenceAssessment) Valid() bool {
return a.ID != "" && len(a.TargetRefs) > 0 && a.Impact >= 0 && a.Impact <= 1000 && a.Reversibility >= 0 && a.Reversibility <= 1000 && a.Uncertainty >= 0 && a.Uncertainty <= 1000 && a.Recoverability >= 0 && a.Recoverability <= 1000 && a.RecordedAtUnixMillis > 0
}
+26
View File
@@ -0,0 +1,26 @@
package work
type PerspectiveID string
type PerspectiveSpec struct {
ID PerspectiveID
ObjectiveLens string
RetrievalProfileRef string
EvaluationCriteria []string
CapabilityRequirements []string
ExpectedOutputShape string
Critic bool
}
type SpecialistAssignment struct {
Perspective PerspectiveSpec
SubtaskRef string
EvidenceRefs []EvidenceRef
}
type TeamDecision struct {
UseTeam bool
Reason string
Assignments []SpecialistAssignment
}
func (p PerspectiveSpec) Valid() bool {
return p.ID != "" && p.ObjectiveLens != "" && len(p.EvaluationCriteria) > 0 && p.ExpectedOutputShape != ""
}
+1 -1
View File
@@ -1 +1 @@
{"task_file":"dev/tasks/GEN2-017-extend-work-into-durable-longrunningwork-investigation.json","task_id":"GEN2-017","task_revision":1}
{"task_file":"dev/tasks/GEN2-019-add-consequence-risk-assessment-without-artificial-capability-blacklist.json","task_id":"GEN2-019","task_revision":1}
+14
View File
@@ -0,0 +1,14 @@
package domain
import "git.cin.su/m/Assistant/contracts/work"
func AssessConsequences(id string, target string, impact, reversibility, uncertainty, recoverability, cost int64, at int64) work.ConsequenceAssessment {
a := work.ConsequenceAssessment{ID: id, TargetRefs: []string{target}, Impact: impact, Reversibility: reversibility, Uncertainty: uncertainty, Recoverability: recoverability, CostOfError: cost, RecordedAtUnixMillis: at}
a.RequiresDryRun = impact >= 700 || reversibility >= 700
a.RequiresBackup = reversibility >= 500
a.RecommendedConfirmation = "STANDARD"
if uncertainty*cost > 500000 {
a.RecommendedConfirmation = "EXPLICIT_OWNER_CONFIRMATION"
}
return a
}
+13
View File
@@ -0,0 +1,13 @@
package domain_test
import (
"git.cin.su/m/Assistant/modules/work/domain"
"testing"
)
func TestConsequenceAdvisesMitigationWithoutCapabilityBlacklist(t *testing.T) {
a := domain.AssessConsequences("a", "database:a", 800, 800, 900, 300, 900, 1)
if !a.Valid() || !a.RequiresDryRun || !a.RequiresBackup || a.RecommendedConfirmation != "EXPLICIT_OWNER_CONFIRMATION" {
t.Fatalf("%#v", a)
}
}
+17
View File
@@ -0,0 +1,17 @@
package domain
import "git.cin.su/m/Assistant/contracts/work"
func AssembleSpecialists(p work.PerspectiveSpec, subtasks []string) work.TeamDecision {
if !p.Valid() {
return work.TeamDecision{Reason: "invalid perspective"}
}
if len(subtasks) < 2 {
return work.TeamDecision{Reason: "single reasoning path is sufficient"}
}
assignments := make([]work.SpecialistAssignment, 0, len(subtasks))
for _, s := range subtasks {
assignments = append(assignments, work.SpecialistAssignment{Perspective: p, SubtaskRef: s})
}
return work.TeamDecision{UseTeam: true, Reason: "independent subtasks justify bounded perspectives", Assignments: assignments}
}
+17
View File
@@ -0,0 +1,17 @@
package domain_test
import (
"git.cin.su/m/Assistant/contracts/work"
"git.cin.su/m/Assistant/modules/work/domain"
"testing"
)
func TestPerspectiveTeamIsBoundedByIndependentSubtasks(t *testing.T) {
p := work.PerspectiveSpec{ID: "architect", ObjectiveLens: "architecture", EvaluationCriteria: []string{"correctness"}, ExpectedOutputShape: "finding"}
if d := domain.AssembleSpecialists(p, []string{"a"}); d.UseTeam {
t.Fatal("team for one subtask")
}
if d := domain.AssembleSpecialists(p, []string{"a", "b"}); !d.UseTeam || len(d.Assignments) != 2 {
t.Fatalf("%#v", d)
}
}