Files
weichenandCursor ffb93dc55d feat(artifactvault): add eligibility, encrypted CAS, and idempotent publisher
Keep vault roots off ./data/dev and reject unknown types or sensitive payloads before staging.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 10:51:25 +00:00

212 lines
6.8 KiB
Go

package artifactvault
import (
"context"
"fmt"
"time"
"github.com/jackc/pgx/v5/pgxpool"
)
// EnumerateTerminals lists only immutable ledger / completed-turn facts. Workspace paths are forbidden.
func EnumerateTerminals(ctx context.Context, pool *pgxpool.Pool, env string) ([]TerminalRow, error) {
if pool == nil {
return nil, fmt.Errorf("artifactvault: no database")
}
var rows []TerminalRow
approved, err := enumerateApproved(ctx, pool, env)
if err != nil {
return nil, err
}
rows = append(rows, approved...)
commits, err := enumerateAgentCommits(ctx, pool, env)
if err != nil {
return nil, err
}
rows = append(rows, commits...)
sealed, err := enumerateSealed(ctx, pool, env)
if err != nil {
return nil, err
}
rows = append(rows, sealed...)
replies, err := enumerateAssistant(ctx, pool, env)
if err != nil {
return nil, err
}
rows = append(rows, replies...)
return rows, nil
}
func LoadExclusions(ctx context.Context, pool *pgxpool.Pool) (map[string]string, error) {
out := map[string]string{}
if pool == nil {
return out, nil
}
q, err := pool.Query(ctx, `SELECT logical_resource_id, reason FROM artifact_backfill_exclusions WHERE expires_at > now()`)
if err != nil {
return nil, err
}
defer q.Close()
for q.Next() {
var id, reason string
if err := q.Scan(&id, &reason); err != nil {
return nil, err
}
out[id] = reason
}
return out, q.Err()
}
func enumerateApproved(ctx context.Context, pool *pgxpool.Pool, env string) ([]TerminalRow, error) {
q, err := pool.Query(ctx, `
SELECT d.doc_id, d.project_id, d.review_snapshot_id, d.approved_at, COALESCE(b.content_markdown,'')
FROM document_records d
LEFT JOIN document_snapshots s ON s.id = d.review_snapshot_id
LEFT JOIN document_content_blobs b ON b.content_sha256 = s.content_sha256
WHERE d.current_state = 'approved' AND d.approved_at IS NOT NULL`)
if err != nil {
return nil, err
}
defer q.Close()
var out []TerminalRow
for q.Next() {
var docID string
var projectID, snapID int64
var approvedAt *time.Time
var md string
if err := q.Scan(&docID, &projectID, &snapID, &approvedAt, &md); err != nil {
return nil, err
}
row := TerminalRow{
Facts: ApprovedFacts("approved", approvedAt, snapID),
Request: PublishRequest{
ArtifactType: TypeApprovedDocument, Environment: env, ProjectID: projectID,
ProjectExternalKey: ProjectKeyFromID(projectID), LogicalResourceID: docID,
SourceEventKind: "approved", SourceEventID: fmt.Sprintf("approved:%s:%d", docID, snapID),
SourceSnapshotID: snapID, Payload: []byte(md), TerminalState: "approved",
},
}
if snapID <= 0 || md == "" {
row.MissingEvidence = true
row.Reason = "missing_review_snapshot"
}
out = append(out, row)
}
return out, q.Err()
}
func enumerateAgentCommits(ctx context.Context, pool *pgxpool.Pool, env string) ([]TerminalRow, error) {
q, err := pool.Query(ctx, `
SELECT e.doc_id, e.id, e.to_snapshot_id, COALESCE(r.project_id,0), COALESCE(b.content_markdown,'')
FROM document_change_events e
LEFT JOIN document_records r ON r.doc_id = e.doc_id
LEFT JOIN document_snapshots s ON s.id = e.to_snapshot_id
LEFT JOIN document_content_blobs b ON b.content_sha256 = s.content_sha256
WHERE e.change_kind = 'agent_commit'`)
if err != nil {
return nil, err
}
defer q.Close()
var out []TerminalRow
for q.Next() {
var docID string
var eventID, snapID, projectID int64
var md string
if err := q.Scan(&docID, &eventID, &snapID, &projectID, &md); err != nil {
return nil, err
}
row := TerminalRow{
Facts: AgentCommitFacts(snapID),
Request: PublishRequest{
ArtifactType: TypeAgentCommit, Environment: env, ProjectID: projectID,
ProjectExternalKey: ProjectKeyFromID(projectID), LogicalResourceID: docID,
SourceEventKind: "agent_commit", SourceEventID: fmt.Sprintf("ev:%d", eventID),
SourceSnapshotID: snapID, Payload: []byte(md), TerminalState: "committed",
},
}
if snapID <= 0 || md == "" {
row.MissingEvidence = true
row.Reason = "missing_commit_snapshot"
}
out = append(out, row)
}
return out, q.Err()
}
func enumerateSealed(ctx context.Context, pool *pgxpool.Pool, env string) ([]TerminalRow, error) {
q, err := pool.Query(ctx, `
SELECT v.doc_id, v.id, v.head_snapshot_id, v.sealed_at, COALESCE(r.project_id,0), COALESCE(b.content_markdown,'')
FROM document_versions v
LEFT JOIN document_records r ON r.doc_id = v.doc_id
LEFT JOIN document_snapshots s ON s.id = v.head_snapshot_id
LEFT JOIN document_content_blobs b ON b.content_sha256 = s.content_sha256
WHERE v.status = 'sealed' AND v.sealed_at IS NOT NULL`)
if err != nil {
return nil, err
}
defer q.Close()
var out []TerminalRow
for q.Next() {
var docID string
var verID, snapID, projectID int64
var sealedAt *time.Time
var md string
if err := q.Scan(&docID, &verID, &snapID, &sealedAt, &projectID, &md); err != nil {
return nil, err
}
row := TerminalRow{
Facts: SealedFacts(sealedAt, snapID),
Request: PublishRequest{
ArtifactType: TypeSealedVersion, Environment: env, ProjectID: projectID,
ProjectExternalKey: ProjectKeyFromID(projectID), LogicalResourceID: fmt.Sprintf("%s:v%d", docID, verID),
SourceEventKind: "version_sealed", SourceEventID: fmt.Sprintf("ver:%d", verID),
SourceSnapshotID: snapID, Payload: []byte(md), TerminalState: "sealed",
},
}
if snapID <= 0 || md == "" {
row.MissingEvidence = true
row.Reason = "missing_sealed_head"
}
out = append(out, row)
}
return out, q.Err()
}
func enumerateAssistant(ctx context.Context, pool *pgxpool.Pool, env string) ([]TerminalRow, error) {
q, err := pool.Query(ctx, `
SELECT t.session_id, t.client_turn_id, t.assistant_message_id, t.completed_at, t.project_id,
COALESCE(m.content,''), COALESCE(m.export_policy,'none')
FROM chat_turns t
LEFT JOIN chat_messages m ON m.id = t.assistant_message_id
WHERE t.status = 'completed' AND t.completed_at IS NOT NULL`)
if err != nil {
return nil, err
}
defer q.Close()
var out []TerminalRow
for q.Next() {
var sessionID, clientTurnID, content, policy string
var msgID, projectID int64
var completedAt *time.Time
if err := q.Scan(&sessionID, &clientTurnID, &msgID, &completedAt, &projectID, &content, &policy); err != nil {
return nil, err
}
logical := fmt.Sprintf("msg:%d", msgID)
row := TerminalRow{
Facts: AssistantFacts("completed", completedAt, msgID, policy),
Request: PublishRequest{
ArtifactType: TypeAssistantReply, Environment: env, ProjectID: projectID,
ProjectExternalKey: ProjectKeyFromID(projectID), LogicalResourceID: logical,
SourceEventKind: "assistant_completed", SourceEventID: sessionID + ":" + clientTurnID,
SourceMessageID: msgID, Payload: []byte(content), TerminalState: "completed",
},
}
if msgID <= 0 || content == "" {
row.MissingEvidence = true
row.Reason = "missing_completed_body"
}
out = append(out, row)
}
return out, q.Err()
}