Add snapshot, signature, and drift guard support for Vertex AI, Cloudflare Workers AI, and Perplexity API, backed by a queryable audit table and recent-window view. This commit also wires the audit query layer into daily signal materialization and report generation so structure drift becomes a first-class signal instead of a log-only artifact.
197 lines
5.6 KiB
Go
197 lines
5.6 KiB
Go
//go:build llm_script
|
|
|
|
package main
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type officialImportSignatureAuditViewRow struct {
|
|
SourceKey string
|
|
RecentRank int
|
|
CheckedAt time.Time
|
|
Status string
|
|
StructureState string
|
|
StructureChanged bool
|
|
DriftDetected bool
|
|
BaselineInitialized bool
|
|
StructureSHA256 string
|
|
PreviousObservedSHA256 sql.NullString
|
|
SnapshotPath sql.NullString
|
|
SignaturePath sql.NullString
|
|
ErrorMessage sql.NullString
|
|
}
|
|
|
|
type officialImportSignatureAuditSourceSummary struct {
|
|
SourceKey string
|
|
RunsInWindow int
|
|
ChangedRuns int
|
|
LatestCheckedAt time.Time
|
|
LatestStatus string
|
|
LatestStructureState string
|
|
}
|
|
|
|
func queryOfficialImportSignatureAuditWindow(db *sql.DB, limitPerSource int, sourceKey string, changesOnly bool) ([]officialImportSignatureAuditSourceSummary, []officialImportSignatureAuditViewRow, error) {
|
|
query, args := buildOfficialImportSignatureAuditViewQuery(limitPerSource, sourceKey, changesOnly)
|
|
rows, err := db.Query(query, args...)
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("query recent signature audit view: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
items := make([]officialImportSignatureAuditViewRow, 0)
|
|
for rows.Next() {
|
|
var item officialImportSignatureAuditViewRow
|
|
if err := rows.Scan(
|
|
&item.SourceKey,
|
|
&item.RecentRank,
|
|
&item.CheckedAt,
|
|
&item.Status,
|
|
&item.StructureState,
|
|
&item.StructureChanged,
|
|
&item.DriftDetected,
|
|
&item.BaselineInitialized,
|
|
&item.StructureSHA256,
|
|
&item.PreviousObservedSHA256,
|
|
&item.SnapshotPath,
|
|
&item.SignaturePath,
|
|
&item.ErrorMessage,
|
|
); err != nil {
|
|
return nil, nil, fmt.Errorf("scan recent signature audit view: %w", err)
|
|
}
|
|
items = append(items, item)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
summaries := summarizeOfficialImportSignatureAuditRows(items)
|
|
return summaries, items, nil
|
|
}
|
|
|
|
func buildOfficialImportSignatureAuditViewQuery(limitPerSource int, sourceKey string, changesOnly bool) (string, []any) {
|
|
filters := []string{"recent_rank <= $1"}
|
|
args := []any{limitPerSource}
|
|
if strings.TrimSpace(sourceKey) != "" {
|
|
filters = append(filters, fmt.Sprintf("source_key = $%d", len(args)+1))
|
|
args = append(args, strings.TrimSpace(sourceKey))
|
|
}
|
|
if changesOnly {
|
|
filters = append(filters, "structure_changed = TRUE")
|
|
}
|
|
|
|
query := fmt.Sprintf(
|
|
`SELECT
|
|
source_key,
|
|
recent_rank,
|
|
checked_at,
|
|
status,
|
|
structure_state,
|
|
structure_changed,
|
|
drift_detected,
|
|
baseline_initialized,
|
|
structure_sha256,
|
|
previous_observed_structure_sha256,
|
|
snapshot_path,
|
|
signature_path,
|
|
error_message
|
|
FROM official_import_signature_audit_recent_view
|
|
WHERE %s
|
|
ORDER BY source_key, checked_at DESC, recent_rank ASC`,
|
|
strings.Join(filters, " AND "),
|
|
)
|
|
return query, args
|
|
}
|
|
|
|
func summarizeOfficialImportSignatureAuditRows(rows []officialImportSignatureAuditViewRow) []officialImportSignatureAuditSourceSummary {
|
|
if len(rows) == 0 {
|
|
return nil
|
|
}
|
|
summaries := make([]officialImportSignatureAuditSourceSummary, 0)
|
|
indexBySource := make(map[string]int)
|
|
for _, row := range rows {
|
|
index, exists := indexBySource[row.SourceKey]
|
|
if !exists {
|
|
index = len(summaries)
|
|
indexBySource[row.SourceKey] = index
|
|
summaries = append(summaries, officialImportSignatureAuditSourceSummary{
|
|
SourceKey: row.SourceKey,
|
|
LatestCheckedAt: row.CheckedAt,
|
|
LatestStatus: row.Status,
|
|
LatestStructureState: row.StructureState,
|
|
})
|
|
}
|
|
summary := &summaries[index]
|
|
summary.RunsInWindow++
|
|
if row.StructureChanged {
|
|
summary.ChangedRuns++
|
|
}
|
|
if row.RecentRank == 1 {
|
|
summary.LatestCheckedAt = row.CheckedAt
|
|
summary.LatestStatus = row.Status
|
|
summary.LatestStructureState = row.StructureState
|
|
}
|
|
}
|
|
return summaries
|
|
}
|
|
|
|
func renderOfficialImportSignatureAuditReport(out io.Writer, limitPerSource int, sourceKey string, changesOnly bool, summaries []officialImportSignatureAuditSourceSummary, rows []officialImportSignatureAuditViewRow) {
|
|
_, _ = fmt.Fprintf(out, "Official Import Signature Audit Report window_per_source=%d source_key=%s changes_only=%t\n",
|
|
limitPerSource, valueOrAll(sourceKey), changesOnly)
|
|
if len(summaries) == 0 {
|
|
_, _ = fmt.Fprintln(out, "summary: no rows")
|
|
return
|
|
}
|
|
|
|
_, _ = fmt.Fprintln(out, "summary:")
|
|
for _, summary := range summaries {
|
|
_, _ = fmt.Fprintf(out,
|
|
"source=%s runs=%d changed_runs=%d latest_checked_at=%s latest_state=%s latest_status=%s\n",
|
|
summary.SourceKey,
|
|
summary.RunsInWindow,
|
|
summary.ChangedRuns,
|
|
summary.LatestCheckedAt.Format("2006-01-02 15:04:05"),
|
|
summary.LatestStructureState,
|
|
summary.LatestStatus,
|
|
)
|
|
}
|
|
|
|
_, _ = fmt.Fprintln(out, "rows:")
|
|
for _, row := range rows {
|
|
_, _ = fmt.Fprintf(out,
|
|
"source=%s recent_rank=%d checked_at=%s state=%s changed=%t status=%s drift=%t baseline_initialized=%t sha=%s previous_sha=%s snapshot=%s signature=%s error=%s\n",
|
|
row.SourceKey,
|
|
row.RecentRank,
|
|
row.CheckedAt.Format("2006-01-02 15:04:05"),
|
|
row.StructureState,
|
|
row.StructureChanged,
|
|
row.Status,
|
|
row.DriftDetected,
|
|
row.BaselineInitialized,
|
|
row.StructureSHA256,
|
|
nullStringOrNone(row.PreviousObservedSHA256),
|
|
nullStringOrNone(row.SnapshotPath),
|
|
nullStringOrNone(row.SignaturePath),
|
|
nullStringOrNone(row.ErrorMessage),
|
|
)
|
|
}
|
|
}
|
|
|
|
func nullStringOrNone(value sql.NullString) string {
|
|
if !value.Valid || strings.TrimSpace(value.String) == "" {
|
|
return "none"
|
|
}
|
|
return value.String
|
|
}
|
|
|
|
func valueOrAll(value string) string {
|
|
if strings.TrimSpace(value) == "" {
|
|
return "all"
|
|
}
|
|
return strings.TrimSpace(value)
|
|
}
|