evidence

package
v0.0.0-...-3107470 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 29, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package evidence defines secret-free normalized evidence records for UI observations collected by browsertools adapters.

The package enforces a two-layer model:

  • RawRecord: untrusted, tool-specific output. May contain credentials, cookies, or other secrets. MUST NOT be committed to source control; use it only transiently inside adapter code.

  • Record: normalized, prompt-safe observation. All sensitive fields must be replaced by redaction markers before a Record is constructed. This is the type that flows into the draft builder and review bundle.

Records serialize deterministically: encoding/json sorts struct fields by declaration order and map keys alphabetically. Slice fields (CandidateLocators, CandidateOutputs, Diagnostics) must be sorted before serialization; use MarshalDeterministic which handles this automatically.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MarshalDeterministic

func MarshalDeterministic(rec Record) ([]byte, error)

MarshalDeterministic returns the canonical JSON encoding of rec. It deep-copies and sorts all slice fields before encoding, so repeated calls on the same value produce identical bytes and the caller's slice order is not modified.

func Sort

func Sort(records []Record)

Sort sorts a slice of Records into a stable canonical order: (Origin, ObservedAt, Provenance.Tool). ObservedAt values must be in UTC (as produced by Normalize) for this ordering to be chronologically correct.

func SortDiagnostics

func SortDiagnostics(diags []Diagnostic)

SortDiagnostics sorts diagnostics in-place by (Level, Message).

func SortLocators

func SortLocators(locs []CandidateLocator)

SortLocators sorts candidate locators in-place by (Role, Name, Text). Including Text breaks ties when Role and Name are identical.

func SortOutputs

func SortOutputs(outs []CandidateOutput)

SortOutputs sorts candidate outputs in-place by Key.

Types

type CandidateLocator

type CandidateLocator struct {
	Role          string `json:"role"`
	Name          string `json:"name,omitempty"`
	Text          string `json:"text,omitempty"`
	Value         string `json:"value,omitempty"`
	AmbiguityNote string `json:"ambiguityNote,omitempty"`
}

CandidateLocator is an accessibility-tree locator candidate observed during a UI session. It mirrors the locator shape in the browser-profile schema.

type CandidateOutput

type CandidateOutput struct {
	Key            string            `json:"key"`
	Type           string            `json:"type"`   // JSON type: string, integer, number, boolean, array, object, null
	Source         string            `json:"source"` // a11y, jsonld, microdata, css
	Locator        *CandidateLocator `json:"locator,omitempty"`
	Selector       string            `json:"selector,omitempty"`       // CSS selector; only when source=css
	FallbackReason string            `json:"fallbackReason,omitempty"` // required when source=css
	Property       string            `json:"property,omitempty"`       // microdata/jsonld property name
}

CandidateOutput is a candidate output extraction observed or inferred during evidence collection. An empty Source is an unbound schema/extraction hint that cannot be promoted automatically. Bound sources must be one of a11y, jsonld, microdata, or css and carry their source-specific fields.

type Diagnostic

type Diagnostic struct {
	Level   string `json:"level"` // "info", "warn", "error"
	Message string `json:"message"`
	Field   string `json:"field,omitempty"` // dot-path to the affected field
}

Diagnostic is an observation note, warning, or error attached to a Record.

type LocatorDecision

type LocatorDecision struct {
	ActionHint string           `json:"actionHint" yaml:"actionHint"`
	Locator    CandidateLocator `json:"locator" yaml:"locator"`
	Rationale  string           `json:"rationale" yaml:"rationale"`
}

LocatorDecision records a reviewer's explicit resolution of ambiguous locator evidence. The selected locator is identified by its portable role/name/text/value fields; AmbiguityNote is evidence and is ignored when matching the decision. Rationale is required for a decision to resolve a promotion-blocking ambiguity.

func (LocatorDecision) Matches

func (d LocatorDecision) Matches(actionHint string, loc CandidateLocator) bool

Matches reports whether the decision resolves loc for actionHint.

type ObservationKind

type ObservationKind string

ObservationKind mirrors the uws.browser.1.5 schema enum for how the profile was learned.

const (
	// ObservationA11ySnapshot means evidence was captured from an accessibility tree snapshot.
	ObservationA11ySnapshot ObservationKind = "accessibility_snapshot"
	// ObservationDOMText means evidence was captured from raw DOM text content.
	ObservationDOMText ObservationKind = "dom_text"
	// ObservationScreenshotOCR means evidence was captured via OCR on a screenshot.
	ObservationScreenshotOCR ObservationKind = "screenshot_ocr"
	// ObservationOther means evidence was captured through another means.
	ObservationOther ObservationKind = "other"
)

type Provenance

type Provenance struct {
	Tool    string `json:"tool"`
	Version string `json:"version,omitempty"`
	Session string `json:"session,omitempty"`
}

Provenance records what tool and session produced this evidence. The Session field is an opaque reference only — it must never hold a credential, cookie, or authentication token.

type RawRecord

type RawRecord struct {
	// Record holds the partially-populated normalized view. RedactionStatus
	// is set to RedactionPending until normalization is complete.
	Record Record

	// RawData is the raw bytes from the tool. Excluded from JSON serialization;
	// never log or store it without explicit redaction review.
	RawData []byte `json:"-"`
}

RawRecord wraps untrusted tool output before normalization. It MUST NOT be committed to source control or passed outside the adapter that created it. Call Normalize to produce a safe Record.

func (*RawRecord) Normalize

func (r *RawRecord) Normalize() (Record, error)

Normalize validates r.Record for completeness and redaction compliance, then returns a deep-copied, sorted Record. The original RawRecord is never modified. Call this at the adapter boundary after applying all redactions.

type Record

type Record struct {
	// Origin is the browser origin (scheme + host + optional port) where the
	// observation was made. Must match the profile's info.origin allowlist.
	Origin string `json:"origin"`

	// ObservationKind records how the evidence was captured.
	ObservationKind ObservationKind `json:"observationKind"`

	// ObservedAt is the RFC-3339 timestamp of the observation. Always stored in
	// UTC (Z suffix) to guarantee lexicographic sort stability.
	ObservedAt string `json:"observedAt"`

	// ActionHint is the action name this evidence was collected for, if known.
	ActionHint string `json:"actionHint,omitempty"`

	// CandidateLocators are a11y locator candidates for the observed interaction
	// target, in preference order.
	CandidateLocators []CandidateLocator `json:"candidateLocators,omitempty"`

	// CandidateOutputs are output extraction candidates observed or inferred.
	CandidateOutputs []CandidateOutput `json:"candidateOutputs,omitempty"`

	// RedactionStatus records whether sensitive fields were reviewed.
	RedactionStatus RedactionStatus `json:"redactionStatus"`

	// RedactedFields lists dot-paths to fields that were replaced with
	// "[REDACTED]" markers. Non-empty only when RedactionStatus is
	// RedactionCompleted.
	RedactedFields []string `json:"redactedFields,omitempty"`

	// Diagnostics are notes, warnings, or errors from the adapter.
	Diagnostics []Diagnostic `json:"diagnostics,omitempty"`

	// Provenance records which tool produced this record.
	Provenance Provenance `json:"provenance"`
}

Record is a normalized, secret-free evidence record for a single UI observation. It is safe to store in source control and to pass to the draft builder.

Use MarshalDeterministic to serialize; it sorts all slice fields before encoding so repeated calls produce identical bytes.

type RedactionStatus

type RedactionStatus string

RedactionStatus records whether a Record's sensitive fields have been reviewed and redacted.

const (
	// RedactionNotRequired means the record contained no sensitive fields.
	RedactionNotRequired RedactionStatus = "not_required"
	// RedactionCompleted means sensitive fields were found and replaced with
	// markers listed in RedactedFields.
	RedactionCompleted RedactionStatus = "redacted"
	// RedactionPending means the record has not yet been reviewed for secrets.
	// Records in this state must not leave the adapter boundary.
	RedactionPending RedactionStatus = "pending"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL