Why: Project work currently reaches model calls without current authorized project facts or a persisted input receipt. Evidence: SELF go test ./... -count=1, targeted go test -race for W6 paths, go vet ./..., and CGO_ENABLED=0 go build ./cmd/agent-system passed on this change set. Impact: Add optional X1 interfaces, trusted persisted work-task binding, request-scoped context injection, evidence reauthorization, and attempted/responded/unknown manifests. Existing non-project behavior stays available. Refs: TT-C01 TT-C02 TT-C03 TT-C04; stage5 W6; Dev stage6 X1 public extension request r1
58 lines
1.6 KiB
Go
58 lines
1.6 KiB
Go
package projectcontext
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/sha256"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"agent-system-backend/pkg/extension"
|
|
)
|
|
|
|
func NewAttemptID() (string, error) {
|
|
var id [16]byte
|
|
if _, err := rand.Read(id[:]); err != nil {
|
|
return "", err
|
|
}
|
|
return fmt.Sprintf("%x", id), nil
|
|
}
|
|
|
|
// ValidateCurrent rejects a stale candidate when a later provider read has
|
|
// changed the permission/publication epoch or any source actually selected for
|
|
// model input. Candidate-only references do not count as model evidence.
|
|
func ValidateCurrent(m extension.ProjectContextManifest, b extension.ProjectContextBundle) error {
|
|
if b.Status != extension.ProjectContextReady || b.ProjectID != m.ProjectID || b.Version != m.Version ||
|
|
b.Watermark != m.Watermark || b.AuthorizationEpoch != m.AuthorizationEpoch || b.PublicationEpoch != m.PublicationEpoch {
|
|
return errors.New("project context changed before model send")
|
|
}
|
|
for _, used := range m.Included {
|
|
found := false
|
|
for _, item := range b.Items {
|
|
if item.SourceID != used.SourceID || item.Revision != used.Revision || item.Hash != used.SourceHash {
|
|
continue
|
|
}
|
|
actual := fmt.Sprintf("%x", sha256.Sum256([]byte(item.Text)))
|
|
if actual == used.InputSHA256 {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
return fmt.Errorf("project context source %q changed before model send", used.SourceID)
|
|
}
|
|
}
|
|
for _, offered := range m.OfferedReferences {
|
|
found := false
|
|
for _, current := range b.Evidence {
|
|
if current == offered {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
return fmt.Errorf("project evidence reference %q withdrawn before model send", offered.ID)
|
|
}
|
|
}
|
|
return nil
|
|
}
|