package steme // QueryParams defines parameters for querying assertions. // // All fields are optional. Use QueryBuilder for fluent construction. type QueryParams struct { // Filter by subject entity Subject *string `json:"subject,omitempty"` // Filter by predicate/relation Predicate *string `json:"predicate,omitempty"` // Filter by lifecycle stage Lifecycle *LifecycleStage `json:"lifecycle,omitempty"` // Filter by epoch (hex-encoded) Epoch *string `json:"epoch,omitempty"` // Apply a lens for conflict resolution Lens *Lens `json:"lens,omitempty"` // Maximum number of results to return (defaults to 100) Limit int `json:"limit,omitempty"` // Filter by visual similarity (hex-encoded pHash, 16 chars). // Returns assertions whose visual_hash has hamming distance <= VisualThreshold. VisualNear *string `json:"visual_near,omitempty"` // Maximum hamming distance for visual matching (0-64, default: 8). // Lower values require closer visual similarity. VisualThreshold *uint32 `json:"visual_threshold,omitempty"` } // QueryBuilder provides a fluent API for building query parameters. type QueryBuilder struct { params QueryParams } // NewQuery creates a new query builder. // // Example: // // params := steme.NewQuery(). // WithSubject("Tesla_Inc"). // WithPredicate("has_revenue"). // WithLens(steme.LensConsensus). // WithLimit(10). // Build() func NewQuery() *QueryBuilder { return &QueryBuilder{ params: QueryParams{ Limit: 100, // Default limit }, } } // WithSubject filters by subject entity. func (b *QueryBuilder) WithSubject(subject string) *QueryBuilder { b.params.Subject = &subject return b } // WithPredicate filters by predicate/relation. func (b *QueryBuilder) WithPredicate(predicate string) *QueryBuilder { b.params.Predicate = &predicate return b } // WithLifecycle filters by lifecycle stage. func (b *QueryBuilder) WithLifecycle(lifecycle LifecycleStage) *QueryBuilder { b.params.Lifecycle = &lifecycle return b } // WithEpoch filters by epoch (hex-encoded, 32 bytes). func (b *QueryBuilder) WithEpoch(epochHex string) *QueryBuilder { b.params.Epoch = &epochHex return b } // WithLens applies a conflict resolution lens. func (b *QueryBuilder) WithLens(lens Lens) *QueryBuilder { b.params.Lens = &lens return b } // WithLimit sets the maximum number of results. func (b *QueryBuilder) WithLimit(limit int) *QueryBuilder { b.params.Limit = limit return b } // WithVisualNear filters by visual similarity to a reference pHash. // // This enables finding assertions with visually similar screenshots or images. // The hash should be a hex-encoded 8-byte perceptual hash (16 characters). // // The threshold is the maximum hamming distance (0-64, default: 8): // - 0: Exact match only // - 8: ~12.5% bit difference, catches resizing/compression // - 16: ~25% bit difference, more lenient // // Assertions without a visual_hash are excluded from results. // // Example: // // params := steme.NewQuery(). // WithSubject("Tesla_10K"). // WithVisualNear("a3f2b1c4d5e6f708", 5). // Build() func (b *QueryBuilder) WithVisualNear(hash string, threshold uint32) *QueryBuilder { b.params.VisualNear = &hash b.params.VisualThreshold = &threshold return b } // Build returns the constructed QueryParams. func (b *QueryBuilder) Build() QueryParams { return b.params } // QueryResult represents the response from a query operation. type QueryResult struct { // Matching assertions Assertions []AssertionResponse `json:"assertions"` // Total number of results returned TotalCount int `json:"total_count"` // Whether there are more results beyond the limit HasMore bool `json:"has_more"` } // AssertionResponse represents a single assertion in query results. type AssertionResponse struct { // Content-addressed hash of this assertion (hex-encoded) Hash string `json:"hash"` // The subject entity Subject string `json:"subject"` // The predicate/relation Predicate string `json:"predicate"` // The object value Object ObjectValue `json:"object"` // Confidence score (0.0 to 1.0) Confidence float64 `json:"confidence"` // Hash of parent assertion (hex-encoded, optional) ParentHash *string `json:"parent_hash,omitempty"` // Hash of source evidence (hex-encoded) SourceHash string `json:"source_hash"` // Source authority tier SourceClass SourceClass `json:"source_class"` // Perceptual hash for visual anchoring (hex-encoded, optional) VisualHash *string `json:"visual_hash,omitempty"` // Epoch ID (hex-encoded, optional) Epoch *string `json:"epoch,omitempty"` // Lifecycle stage Lifecycle LifecycleStage `json:"lifecycle"` // Agent signatures Signatures []SignatureEntry `json:"signatures"` // Creation timestamp (Unix epoch) Timestamp uint64 `json:"timestamp"` // Semantic embedding vector (optional) Vector []float32 `json:"vector,omitempty"` } // CreateResponse represents the response from a create operation. type CreateResponse struct { // Content-addressed hash of the created resource (hex-encoded) Hash string `json:"hash"` // Status message Status string `json:"status"` } // SkepticQueryParams defines parameters for the skeptic endpoint. type SkepticQueryParams struct { // Subject entity to analyze (required) Subject string `json:"subject"` // Predicate/relation to analyze (required) Predicate string `json:"predicate"` } // SkepticResult represents the "Trust but Verify" response. // // Unlike QueryResult which picks a winner, SkepticResult shows all // competing claims with their relative weights. type SkepticResult struct { // The subject that was queried Subject string `json:"subject"` // The predicate that was queried Predicate string `json:"predicate"` // Overall resolution status Status ResolutionStatus `json:"status"` // Conflict score (0.0 = unanimous, 1.0 = chaos) ConflictScore float64 `json:"conflict_score"` // All distinct claims, ranked by weight_share descending Claims []ClaimSummary `json:"claims"` // Total number of candidate assertions considered CandidatesCount int `json:"candidates_count"` // Unix timestamp when this view was computed ComputedAt uint64 `json:"computed_at"` // Which lens was used (always "Skeptic") LensName string `json:"lens_name"` } // ClaimSummary represents a single competing claim. type ClaimSummary struct { // The claimed value Value ObjectValue `json:"value"` // Normalized weight (0.0 to 1.0) relative to all claims WeightShare float64 `json:"weight_share"` // Number of assertions making this exact claim AssertionCount uint32 `json:"assertion_count"` // Hash of the representative assertion (hex-encoded) RepresentativeHash string `json:"representative_hash"` // Source provenance Source SourceSummary `json:"source"` // Agents supporting this claim SupportingAgents []AgentSummary `json:"supporting_agents"` } // SourceSummary provides minimal source info for provenance. type SourceSummary struct { // Hash of the source document (hex-encoded) SourceHash string `json:"source_hash"` // Visual anchor hash (hex-encoded, optional) VisualHash *string `json:"visual_hash,omitempty"` } // AgentSummary provides minimal agent info for attribution. type AgentSummary struct { // Agent's public key (hex-encoded) AgentID string `json:"agent_id"` // Trust score at query time (0.0 to 1.0) TrustScore float64 `json:"trust_score"` } // TraceParams defines parameters for tracing agent queries. // // Used to debug "Why did the agent think that?" for incident investigation. type TraceParams struct { // Agent public key to trace (hex-encoded, 32 bytes) - required AgentID string `json:"agent_id"` // Start of time range (Unix timestamp) - required From string `json:"from"` // End of time range (Unix timestamp, defaults to now) To string `json:"to,omitempty"` // Filter by subject pattern (e.g., "Tesla*", "auth/*") Subject string `json:"subject,omitempty"` // Maximum number of results (default: 100) Limit int `json:"limit,omitempty"` } // TraceResult represents the response from a trace operation. type TraceResult struct { // Matching query audit records Audits []QueryAuditRecord `json:"audits"` // Total number of results returned TotalCount int `json:"total_count"` // Agent ID that was traced (hex-encoded) AgentID string `json:"agent_id"` // Time range start (Unix timestamp) FromTimestamp uint64 `json:"from_timestamp"` // Time range end (Unix timestamp) ToTimestamp uint64 `json:"to_timestamp"` } // QueryAuditRecord represents a single query audit entry. type QueryAuditRecord struct { // Unique identifier for this query (hex-encoded, 32 bytes) QueryID string `json:"query_id"` // Agent public key who made the query (hex-encoded, optional) AgentID *string `json:"agent_id,omitempty"` // Unix timestamp when the query was executed Timestamp uint64 `json:"timestamp"` // Query parameters that were used Params QueryParamsAudit `json:"params"` // Hash of the winning assertion (hex-encoded, optional) ResultHash *string `json:"result_hash,omitempty"` // Confidence score of the result ResultConfidence float32 `json:"result_confidence"` // Assertions that contributed to the result ContributingAssertions []ContributingAssertion `json:"contributing_assertions"` } // QueryParamsAudit represents the parameters used in a query. type QueryParamsAudit struct { // Subject filter (optional) Subject *string `json:"subject,omitempty"` // Predicate filter (optional) Predicate *string `json:"predicate,omitempty"` // Lifecycle filter (optional) Lifecycle *LifecycleStage `json:"lifecycle,omitempty"` // Epoch filter (hex-encoded, optional) Epoch *string `json:"epoch,omitempty"` // Lens used (optional) Lens *Lens `json:"lens,omitempty"` } // ContributingAssertion represents an assertion that contributed to a query result. type ContributingAssertion struct { // Hash of the assertion (hex-encoded) AssertionHash string `json:"assertion_hash"` // Weight in the resolution (1.0 for winner) Weight float32 `json:"weight"` // Hash of the source evidence (hex-encoded) SourceHash string `json:"source_hash"` // Lifecycle stage of the assertion Lifecycle LifecycleStage `json:"lifecycle"` } // SupersessionType defines how an assertion is being superseded. type SupersessionType string const ( // SupersessionInvalidate means the old assertion was factually incorrect. SupersessionInvalidate SupersessionType = "Invalidate" // SupersessionTemporal means the old assertion was correct but now outdated. SupersessionTemporal SupersessionType = "Temporal" // SupersessionRefinement means the old assertion was a simplification. SupersessionRefinement SupersessionType = "Refinement" // SupersessionRequiresReview means the old assertion needs human review. SupersessionRequiresReview SupersessionType = "RequiresReview" // SupersessionAdditive means the new assertion adds context without invalidating. SupersessionAdditive SupersessionType = "Additive" ) // SupersedeParams defines parameters for creating a supersession. type SupersedeParams struct { // Hash of the assertion being superseded (hex-encoded, 32 bytes) TargetHash string `json:"target_hash"` // How the target is being superseded SupersessionType SupersessionType `json:"supersession_type"` // Human-readable explanation (for audit trail) Reason string `json:"reason"` // Hash of the replacement assertion (hex-encoded, optional) // None for RequiresReview or pure invalidation. NewHash string `json:"new_hash,omitempty"` // Public key of the agent creating the supersession (hex-encoded, 32 bytes) AgentID string `json:"agent_id"` // Signature over the supersession content (hex-encoded, 64 bytes) Signature string `json:"signature"` } // SupersedeResult represents the response from a supersede operation. type SupersedeResult struct { // Status message Status string `json:"status"` // Hash of the target assertion that was superseded (hex-encoded) TargetHash string `json:"target_hash"` // Type of supersession applied SupersessionType SupersessionType `json:"supersession_type"` // Unix timestamp when the supersession was recorded Timestamp uint64 `json:"timestamp"` }