telemetry

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package telemetry contains the local, sanitized measurement stream.

The public event constructor intentionally accepts only typed closed values. Prompts, diffs, outputs, paths, and free text have no field in this package.

Index

Constants

View Source
const (
	CurrentSchemaVersion = "2"
	NoData               = "no-data"
	LevelUser            = "user"
	LevelFull            = "full"

	EventToolCall            = "tool_call"
	EventVerify              = "verify"
	EventApply               = "apply"
	EventDiscard             = "discard"
	EventRemediation         = "remediation"
	EventEscalation          = "escalation"
	EventFlowNode            = "flow_node"
	EventGateDecision        = "gate.decision"
	EventVerifyDenial        = "verify.denial"
	EventReviewDisagreement  = "review.disagreement"
	EventCleanExitClose      = "cleanexit.close"
	EventPreflightCheck      = "preflight.check"
	EventMissionInterruption = "mission.interruption"
	EventClarityProbe        = "clarity.probe"
	EventContextPack         = "context.pack"
	EventContextAnchor       = "context.anchor"
	EventContextHandoff      = "context.handoff"
	EventLedgerDecision      = "ledger.decision"
	EventCostTrace           = "cost.trace"
)
View Source
const (
	MetricFirstPassVerify      = "verify_first_pass_pct"
	MetricRemediation          = "remediation_iterations_per_mission"
	MetricEscalation           = "escalation_pct"
	MetricAutoApply            = "auto_apply_without_intervention_pct"
	MetricMissionApplyP50      = "mission_to_apply_p50_ms"
	MetricMissionApplyP95      = "mission_to_apply_p95_ms"
	MetricMissionsPerDay       = "missions_per_day"
	MetricRevertedApplyPct     = "apply_reverted_pct_heuristic"
	MetricMissionBytesIn       = "mission_bytes_in"
	MetricMissionBytesOut      = "mission_bytes_out"
	MetricMissionInterruptions = "mission_interruptions"
	MetricCleanExitResult      = "clean_exit_result"
)

Variables

This section is empty.

Functions

func EmitBestEffort

func EmitBestEffort(event Event)

func EmitBestEffortInput

func EmitBestEffortInput(input EventInput)

func EmitBestEffortInputLive added in v0.4.0

func EmitBestEffortInputLive(w io.Writer, input EventInput)

EmitBestEffortInputLive writes the same v2 envelope to the local store and, when w is set, as one NDJSON line to w. Serve must not pass stdout.

func FormatFullStats

func FormatFullStats(stats Stats) string

func FormatStats

func FormatStats(stats Stats) string

func GateVerdictRank

func GateVerdictRank(verdict string) int

func NewTraceID

func NewTraceID() string

func ProjectID

func ProjectID(root string) string

ProjectID derives the stable local identity used by the rest of JACU. A registration path cannot return an error without changing the MCP startup contract, so an invalid root becomes a bounded sentinel and telemetry is still isolated from the governed result.

func TelemetryEnabled

func TelemetryEnabled() bool

func WriteLive added in v0.4.0

func WriteLive(w io.Writer, event Event)

WriteLive encodes a validated event as NDJSON. It does not persist.

func WriteLiveInput added in v0.4.0

func WriteLiveInput(w io.Writer, input EventInput)

WriteLiveInput encodes EventInput as NDJSON without persisting. Used for progress pulses (verify running) that must appear before Execute finishes.

Types

type Event

type Event struct {
	SchemaVersion    string    `json:"schema_version"`
	Timestamp        time.Time `json:"ts"`
	Level            string    `json:"level"`
	ProjectID        string    `json:"project_id"`
	TraceID          string    `json:"trace_id"`
	RunID            string    `json:"run_id,omitempty"`
	MissionID        string    `json:"mission_id,omitempty"`
	ProgramID        string    `json:"program_id,omitempty"`
	Module           string    `json:"module"`
	Stage            string    `json:"stage"`
	Event            string    `json:"event"`
	Tool             string    `json:"tool,omitempty"`
	Status           string    `json:"status"`
	DurationMs       int64     `json:"duration_ms,omitempty"`
	Measurement      string    `json:"measurement,omitempty"`
	InputBytes       int64     `json:"input_bytes,omitempty"`
	OutputBytes      int64     `json:"output_bytes,omitempty"`
	Capped           bool      `json:"capped,omitempty"`
	DegradedPartial  bool      `json:"degraded_partial,omitempty"`
	Ceremony         string    `json:"ceremony,omitempty"`
	Risk             string    `json:"risk,omitempty"`
	Verdict          string    `json:"verdict,omitempty"`
	Iteration        int       `json:"iteration,omitempty"`
	ExitReason       string    `json:"exit_reason,omitempty"`
	Reason           string    `json:"reason,omitempty"`
	ProgramKnown     bool      `json:"program_known"`
	Auto             bool      `json:"auto,omitempty"`
	Intervention     bool      `json:"intervention,omitempty"`
	DiffBytes        int64     `json:"diff_bytes,omitempty"`
	FilesChanged     int       `json:"files_changed,omitempty"`
	Resolved         string    `json:"resolved,omitempty"`
	Result           string    `json:"result,omitempty"`
	FailureClass     string    `json:"failure_class,omitempty"`
	Round            int       `json:"round,omitempty"`
	Divergences      int       `json:"divergences,omitempty"`
	DivergenceField  string    `json:"divergence_field,omitempty"`
	VarianceRuns     int       `json:"variance_runs,omitempty"`
	SpecBytes        int64     `json:"spec_bytes,omitempty"`
	SpecBytesDelta   int64     `json:"spec_bytes_delta,omitempty"`
	CoverageBPS      int       `json:"coverage_bps,omitempty"`
	ItemsRequired    int       `json:"items_required,omitempty"`
	ItemsIncluded    int       `json:"items_included,omitempty"`
	AnchorsLost      int       `json:"anchors_lost,omitempty"`
	BudgetBytes      int64     `json:"budget_bytes,omitempty"`
	RequestedBytes   int64     `json:"requested_bytes,omitempty"`
	RemainingBytes   int64     `json:"remaining_bytes,omitempty"`
	RequiredOverflow bool      `json:"required_overflow,omitempty"`
}

Event is the only record written to the local stream. Keep this struct closed: adding a field is a telemetry contract change and needs a test.

func DecodeEvent

func DecodeEvent(encoded []byte) (Event, error)

func FilterProject

func FilterProject(events []Event, projectID string) []Event

FilterProject keeps the shared local store from mixing independent repositories in one project's diagnosis.

func NewEvent

func NewEvent(input EventInput) (Event, error)

func NewFullEvent

func NewFullEvent(input EventInput) (Event, error)

NewFullEvent exposes the same closed typed surface at the owner's detail level. It deliberately reuses EventInput: there is no full-level escape hatch for prompts, diffs, outputs, paths, or free text.

func NewToolCallEvent

func NewToolCallEvent(projectID, traceID, tool, status string, durationMs int64) (Event, error)

func (Event) Validate

func (event Event) Validate() error

type EventInput

type EventInput struct {
	SchemaVersion    string
	Timestamp        time.Time
	Level            string
	ProjectID        string
	TraceID          string
	RunID            string
	MissionID        string
	ProgramID        string
	Module           string
	Stage            string
	Event            string
	Tool             string
	Status           string
	Duration         time.Duration
	Measurement      string
	InputBytes       int64
	OutputBytes      int64
	Capped           bool
	DegradedPartial  bool
	Ceremony         string
	Risk             string
	Verdict          string
	Iteration        int
	ExitReason       string
	Reason           string
	ProgramKnown     bool
	Auto             bool
	Intervention     bool
	DiffBytes        int64
	FilesChanged     int
	Resolved         string
	Result           string
	FailureClass     string
	Round            int
	Divergences      int
	DivergenceField  string
	VarianceRuns     int
	SpecBytes        int64
	SpecBytesDelta   int64
	CoverageBPS      int
	ItemsRequired    int
	ItemsIncluded    int
	AnchorsLost      int
	BudgetBytes      int64
	RequestedBytes   int64
	RemainingBytes   int64
	RequiredOverflow bool
}

EventInput uses a duration instead of an unbounded free-form duration string. Every field maps to an allowlisted Event field.

type GitHistory

type GitHistory struct{ Repo string }

type ModuleStats

type ModuleStats struct {
	Events      int
	InputBytes  int64
	OutputBytes int64
	Measurement string
}

type Stats

type Stats struct {
	Since                 time.Time
	Until                 time.Time
	FirstPassVerifyPct    float64
	RemediationIterations float64
	EscalationPct         float64
	AutoApplyPct          float64
	MissionApplyP50Ms     int64
	MissionApplyP95Ms     int64
	MissionsPerDay        float64
	ToolP95Ms             map[string]int64
	RevertedApplyPct      float64
	RevertHeuristic       bool
	Available             map[string]bool
	Modules               map[string]ModuleStats
	MissionBytesIn        int64
	MissionBytesOut       int64
}

func ComputeStats

func ComputeStats(events []Event, since, until time.Time, history *GitHistory) (Stats, error)

func ReportStats

func ReportStats(root string) Stats

type Store

type Store struct {
	// contains filtered or unexported fields
}

func NewStore

func NewStore() Store

func NewStoreAt

func NewStoreAt(base string) Store

func NewStoreAtWithLimits

func NewStoreAtWithLimits(base string, segmentBytes, totalBytes int64, months int) Store

NewStoreAtWithLimits is intended for deterministic package tests. Production constructors retain the fixed 8MiB/128MiB/12-month policy.

func (Store) Directory

func (store Store) Directory() string

func (Store) Emit

func (store Store) Emit(event Event) error

func (Store) ReadSince

func (store Store) ReadSince(since time.Time) ([]Event, error)

Jump to

Keyboard shortcuts

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