Files
Agent-System/internal/server/vault.go
T
weichenandCursor 2c1d040ccf feat(events): add FAV subscriber shadow without live writes
ObserveShadow computes intended outcome only and refuses FAV_DEGRADED_READ; HandleLease and Register(fav) stay fail-closed.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 04:25:17 +00:00

109 lines
2.9 KiB
Go

package server
import (
"context"
"fmt"
"net/http"
"sync/atomic"
"time"
"chat-agent-system/internal/artifactvault"
"chat-agent-system/internal/config"
)
// Vault HTTP + in-process publisher stubs for U7 incremental.
// Default: FAV_PUBLISHER_ENABLED=false, FAV_DEGRADED_READ=false.
// Full ingest hooks / enumerate backfill remain on feature/final-artifact-vault.
func (s *Server) initArtifactVault() {
if s == nil || s.cfg == nil {
return
}
// Publisher store stays nil unless explicitly enabled AND vault roots are set.
if !s.cfg.FAVPublisherEnabled {
return
}
if s.cfg.VaultStateRoot == "" || s.cfg.VaultMasterKey == "" {
return
}
if err := config.ValidateIndependentVault(s.cfg.VaultStateRoot, s.cfg.DataDir); err != nil {
return
}
ident := s.cfg.VaultStorageIdentity
if ident == "" {
env := s.cfg.Env
if env == "" {
env = "dev"
}
ident = "vault-" + env
}
store, err := artifactvault.NewFilesystemStore(s.cfg.VaultStateRoot, ident, []byte(s.cfg.VaultMasterKey))
if err != nil {
return
}
var reg artifactvault.Registry
if s.pool != nil {
reg = artifactvault.NewPGRegistry(s.pool)
} else {
reg = artifactvault.NewMemoryRegistry()
}
s.vaultStore = store
s.vaultReg = reg
s.vaultPub = &artifactvault.Publisher{Reg: reg, Store: store}
}
func (s *Server) startVaultPublisher() {
if s == nil || s.vaultPub == nil || s.cfg == nil || !s.cfg.FAVPublisherEnabled {
return
}
go func() {
t := time.NewTicker(2 * time.Second)
defer t.Stop()
for range t.C {
_ = s.vaultPub.Drain(context.Background())
}
}()
atomic.StoreInt32(&s.vaultPublisherStarted, 1)
}
func (s *Server) tryVaultDegraded(ctx context.Context, env, logical, projectKey string) ([]byte, string, error) {
if s == nil || s.vaultPub == nil || s.cfg == nil || !s.cfg.FAVDegradedRead {
return nil, "", fmt.Errorf("artifactvault: degraded read disabled")
}
return s.vaultPub.DegradedPayload(ctx, env, logical, projectKey)
}
func (s *Server) handleVaultStatus(w http.ResponseWriter, r *http.Request) {
_ = r
cfg := s.cfg
degraded := false
publisher := false
storeReady := false
if cfg != nil {
degraded = cfg.FAVDegradedRead
publisher = cfg.FAVPublisherEnabled
}
if s.vaultStore != nil {
storeReady = true
}
writeJSONResponse(w, http.StatusOK, map[string]any{
"status": "ok",
"consumer": "fav",
"consumer_mode": "off",
"publisher_enabled": publisher,
"publisher_running": atomic.LoadInt32(&s.vaultPublisherStarted) == 1,
"degraded_read": degraded,
"store_configured": storeReady,
"subscriber_default": false,
"shadow_observe": true,
"would_stage": false,
"would_publish": false,
"live_not_opened": true,
"note": "fav consumer remains OFF until separate approval; shadow computes intended outcome only; full FAV branch not merged",
})
}
func (s *Server) vaultPublisherRunning() bool {
return atomic.LoadInt32(&s.vaultPublisherStarted) == 1
}