Documentation
¶
Overview ¶
Package api serves the single-binary HTTP surface: event ingestion + the server-rendered dashboard. No web framework, no SPA build step — the whole UI is embedded in the binary and rendered fast on the server (the speed IS a feature).
Index ¶
- Constants
- Variables
- func EventGloss(name string) string
- func EventIsAuto(name string) bool
- func EventLabel(name string) string
- type GuardrailBreach
- type PathStep
- type ProposedFunnel
- type Server
- func (s *Server) EvaluateAlerts()
- func (s *Server) EvaluateGuardrails() []GuardrailBreach
- func (s *Server) Handler() http.Handler
- func (s *Server) SetActed(a *acted.Store)
- func (s *Server) SetAlerts(a *alert.Store)
- func (s *Server) SetAliases(a *alias.Map)
- func (s *Server) SetAudit(l *audit.Log)
- func (s *Server) SetCloudURL(u string)
- func (s *Server) SetCohorts(st *cohort.Store)
- func (s *Server) SetDefined(d *defined.Store)
- func (s *Server) SetDeploys(d *deploys.Store)
- func (s *Server) SetExportLinks(st *exportlink.Store)
- func (s *Server) SetFlags(f *flag.Store)
- func (s *Server) SetGSC(g *gsc.Store)
- func (s *Server) SetGeo(g *geo.Resolver)
- func (s *Server) SetGeoSampling(mode string)
- func (s *Server) SetGoals(g *goal.Store)
- func (s *Server) SetInsights(st *insights.Store)
- func (s *Server) SetMCPReadOnly(v bool)
- func (s *Server) SetReadKey(k string)
- func (s *Server) SetRuns(r *testrun.Store)
- func (s *Server) SetSettings(st *settings.Store)
- func (s *Server) SetShares(st *share.Store)
- func (s *Server) SetSurveys(sv *survey.Store)
- func (s *Server) SetTrackPlan(tp *trackplan.Store)
- func (s *Server) SetWebhooks(w *webhook.Store)
- func (s *Server) SetWriteKey(k string)
Constants ¶
const RevertEvent = desk.RevertEvent
RevertEvent is written into the operator's OWN event log when a flag is pulled.
Writing it as an event rather than only a log line is deliberate: it lands on the same timeline as the traffic it reacted to, it is queryable by every tool that reads events, and it shows up in the brief. An autonomous act that leaves no trace in the place people look is indistinguishable from a bug.
THE DEFINITION MOVED to internal/desk, and this is the alias so nothing else in this package had to change. The ledger has to find these receipts and the ledger is composed at the seam, so the name, the two timing constants and the kill switch all live where the page and the API can read them. Keeping a second literal here is exactly how the page would come to advertise a rule the actuator no longer follows.
Variables ¶
var Version = "0.1.0"
Version is the build version (overridable at build time via -ldflags).
Functions ¶
func EventGloss ¶ added in v0.36.0
EventGloss is the one-time explanation for events whose LABEL alone is still not enough.
"engaged" is the case that matters: it sounds like a judgement the tool made about the visitor, and nobody can act on it without knowing the rule. Returns "" when the label speaks for itself, so callers can render a gloss only where one is owed.
func EventIsAuto ¶ added in v0.36.0
EventIsAuto reports whether the SDK writes this event by itself.
The distinction the "$" was carrying, made available as a fact instead of a sigil: it is what separates "your product has no funnel yet" from "your product's funnel is bad", and the verdict card gets that wrong in the loudest possible way when it cannot tell them apart.
func EventLabel ¶ added in v0.36.0
EventLabel turns an event name into something a human reads without being taught the schema.
This is the single change four independent cold readers hit in every pane. The dashboard's headline metric rendered as "$pageview → $engagement → $click 8%" — a sentence in a language none of them spoke. A left-nav item was literally named "$pageview → $engagement → $click". "$crawler" appeared in a column headed VISITOR, and one reader said it looked like a person named $crawler had visited the site. Three empty states told the reader to send "$identify" without saying that was code they had to write.
The "$" prefix is real and meaningful — it marks events the SDK captures on its own, as opposed to ones the product sends deliberately — but that is a fact about our implementation, and the dashboard is not the place to teach it. Two surfaces keep the raw names because there they ARE the interface: the SQL pane and the raw event stream, where you are writing against the schema.
Deliberately a translation at the render boundary, not a rename. The stored names, the API, the SDK and every query are untouched — renaming events would break every customer's instrumentation to fix a reading problem.
Types ¶
type GuardrailBreach ¶ added in v0.51.0
type GuardrailBreach struct {
Flag string `json:"flag"`
Variant string `json:"variant"`
Result flag.GuardrailResult `json:"result"`
}
GuardrailBreach is one experiment failing one guardrail.
type PathStep ¶ added in v0.37.0
type PathStep struct {
Path string `json:"path"`
People int `json:"people"` // distinct people who reached it, IN ORDER
}
PathStep is one page in a proposed journey, with the evidence for it.
type ProposedFunnel ¶ added in v0.37.0
type ProposedFunnel struct {
Steps []PathStep `json:"steps"`
// Confident is true only when the shape looks like a funnel rather than a list of popular
// pages: each step must genuinely narrow, and the last step must be meaningfully rarer than
// the first. Without that test, "the three busiest pages" gets proposed as a journey and the
// suggestion is worse than none.
Confident bool `json:"confident"`
Why string `json:"why,omitempty"`
}
ProposedFunnel is a guess at what this product's conversion actually is.
func ProposeFunnel ¶ added in v0.37.0
func ProposeFunnel(evs []event.Event) ProposedFunnel
ProposeFunnel builds a funnel suggestion from page paths.
The rule is ORDER-AWARE: a step only counts someone who reached it AFTER the previous one, which is what makes this a journey rather than three independent page-popularity numbers. A naive version that just counted visits per page would happily propose /pricing → / → /docs, three popular pages nobody walks in that order.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
func (*Server) EvaluateAlerts ¶
func (s *Server) EvaluateAlerts()
func (*Server) EvaluateGuardrails ¶ added in v0.51.0
func (s *Server) EvaluateGuardrails() []GuardrailBreach
EvaluateGuardrails checks every running experiment's guardrails and records the verdict on the flag. Returns the breaches so a caller can act, alert, or ignore.
Safe to call on a schedule: it is a pure read plus a status write, and the sequential test it runs is always-valid, which is the whole reason that machinery was chosen. Checking every five minutes does not inflate anyone's false-positive rate.
func (*Server) SetActed ¶ added in v0.85.0
SetActed wires the outcome ledger: which findings a human said they acted on. Optional, like every sidecar store; without it the desk simply never shows the verified line.
func (*Server) SetAliases ¶ added in v0.4.0
SetAliases attaches the identity-stitching map (ingest records anon→user on $identify; the MCP import tool does the same for imported history).
func (*Server) SetCloudURL ¶ added in v0.12.1
SetCloudURL sets where the dashboard header's "Cloud ↗" link points. The hosted product passes the project's own page so a user who lands on their instance has a way back into their account. Empty (every self-hosted install) keeps the default link to smolanalytics.com, so a self-hoster never sees a cloud-specific or broken link.
func (*Server) SetCohorts ¶
SetCohorts swaps in a persistent cohort store (shared with MCP).
func (*Server) SetDefined ¶ added in v0.9.0
SetDefined attaches the retroactive defined-events store (shared with MCP + the dashboard "save as event" builder).
func (*Server) SetDeploys ¶ added in v0.9.3
SetDeploys attaches the store to both the HTTP server and the MCP server, so a marker recorded over HTTP is visible to the editor and vice-versa (one store, every surface).
func (*Server) SetExportLinks ¶ added in v0.8.0
func (s *Server) SetExportLinks(st *exportlink.Store)
SetExportLinks attaches the one-time export-link store (minted by the create_export_link MCP tool, served by GET /export/{token}).
func (*Server) SetFlags ¶ added in v0.9.6
SetFlags attaches the feature-flag store (shared with MCP + the SDK evaluate endpoint).
func (*Server) SetGSC ¶ added in v0.4.1
SetGSC attaches the Search Console store (dashboard card + MCP report).
func (*Server) SetGeo ¶ added in v0.9.1
SetGeo enables ingest-time country resolution (the IP is used for one lookup and never stored, only the ISO code lands on the event).
func (*Server) SetGeoSampling ¶ added in v0.50.0
SetGeoSampling records whether the CLOUD will actually run AI-visibility sampling for this instance. "managed" means it is funded and scheduled; anything else means it is not.
The card said "This starts by itself. Nothing to configure." to every hosted tenant, because the only thing it knew was that the instance was hosted. But sampling spends a real model call per question and the cloud funds it from the plan's AI allowance, which is zero on a trial — so for a trial user, and for anyone whose allowance does not cover a sweep, that card was a promise about something that would never happen, on any timescale, with nothing on the page saying why.
A paying customer staring at a permanently empty card decides the product is broken. A trial user decides the AI story does not work, and does not buy.
func (*Server) SetGoals ¶ added in v0.4.0
SetGoals attaches the goals store (dashboard card + MCP goal tools).
func (*Server) SetInsights ¶
SetInsights swaps in a persistent saved-reports store (shared with the MCP action tools, so "save this report" from the editor lands on the dashboard instantly).
func (*Server) SetMCPReadOnly ¶ added in v0.13.0
SetMCPReadOnly refuses every mutating MCP tool. The public demo serves /mcp with no credential on purpose (nothing is configured, so authorized() opens it), which also means any stranger could otherwise create flags, delete goals, mint export links or change retention on the very instance the marketing site renders.
func (*Server) SetReadKey ¶ added in v0.9.1
SetReadKey sets the SECRET read/MCP key. It authorizes reads (GET /v1/* reports, the raw export) and MCP — everything that returns data. It must NEVER be embedded in client code; only the write key is public. This is what stops a scraped write key from reading data.
func (*Server) SetRuns ¶ added in v0.91.0
SetRuns wires the test-run log. Optional: an instance with no runner attached renders the pane's empty state, which says how to write the first test rather than showing a zero.
func (*Server) SetSettings ¶
SetSettings swaps in a persistent settings store (project, keys, session secret).
func (*Server) SetSurveys ¶ added in v0.9.9
SetSurveys attaches the survey store (shared with MCP + the SDK active-surveys endpoint).
func (*Server) SetTrackPlan ¶ added in v0.3.0
SetTrackPlan attaches the tracking-plan store (shared with the MCP instrumentation tools). Held here as well as on the MCP server because the investigator's tracking-break gate needs it on the HTTP path too, and a second wiring call would be a second thing to forget.
func (*Server) SetWebhooks ¶
SetWebhooks / SetAlerts swap in the persistent notification stores (shared with MCP).
func (*Server) SetWriteKey ¶
SetWriteKey gates event ingestion behind a write key (production). Empty = open (dev). The SDK passes the same key.
Source Files
¶
- agent_api.go
- aicrawl.go
- alert_eval.go
- api.go
- ask.go
- ask_scope.go
- ask_toolkit.go
- auth.go
- auto_revert.go
- backtest.go
- cohort_api.go
- defined_api.go
- deploys_api.go
- errors_api.go
- eventlabel.go
- experiment_api.go
- explain_api.go
- explore.go
- export.go
- flags_api.go
- formula_api.go
- goals_api.go
- group_grain.go
- guardrail_eval.go
- heatmap_api.go
- insights_api.go
- investigate_api.go
- limits.go
- notify_api.go
- payments_api.go
- people_api.go
- proposefunnel.go
- query_api.go
- root.go
- sessions_api.go
- settings_api.go
- share_api.go
- shared.go
- sql_api.go
- surveys_api.go