Files
weichen 44ccd63d3b Add trusted project context to work model calls
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
2026-10-14 04:09:58 +00:00

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
}