Documentation
¶
Overview ¶
Package insight produces the proactive "what's broken / what to look at" digest — the verdict founders actually want instead of a dashboard. Every finding is computed exactly from the deterministic engine, so it can't be hallucinated. Shared by the dashboard, the /v1/notable API, the MCP tool, and the daily brief.
Index ¶
- Constants
- func DetectJourney(evs []event.Event) []funnel.Step
- func EventVerbIs(name string) string
- func HumanEngine(name string) string
- func HumanEvent(name string) string
- func HumanEventBase(name string) string
- func HumanEventIng(name string) string
- func HumanEventNoun(name string) string
- func HumanSegment(prop, value string) string
- func HumanStep(name string) string
- func Text(findings []Finding) string
- func UpIsBad(name string) bool
- type Finding
Constants ¶
const ( KindDropoff = "funnel_dropoff" KindSegment = "segment" KindAnomaly = "anomaly" KindTrend = "trend" KindRetention = "retention" KindAIVis = "ai_visibility" KindReadable = "site_readable" KindCrawl = "ai_crawl" )
Kinds name the DETECTOR behind a finding. Downstream surfaces (the fix brief, the cloud's fix-PR runner) branch on these. They must never branch on Title: Title is a sentence written for a human and gets reworded whenever the wording improves, which would silently break a consumer in another repository with nothing failing loudly.
const ReadableEvent = "$site_readable"
ReadableEvent is what the cloud's scanner writes after checking the project's own site.
Variables ¶
This section is empty.
Functions ¶
func DetectJourney ¶ added in v0.29.0
DetectJourney is detectJourney, exported.
Other packages need the SAME funnel this package's verdict describes — the error report's impact join, for one. Exporting the existing detector rather than letting each caller write its own is the whole point: two detectors would eventually disagree, and then one screen would say "checkout dropped" about a funnel another screen never mentions.
func EventVerbIs ¶ added in v0.29.0
EventVerbIs returns the verb that agrees with HumanEventNoun(name) — "are" for the plural autocapture nouns, "is" otherwise. A custom event keeps "is": the operator named it "signup", not "signups", and "signup is up 6%" is what they expect to read.
func HumanEngine ¶ added in v0.19.0
HumanEngine renders an engine name for prose. An engine we have not met still has to read as a name rather than as a row key, and the "-grounded" suffix has to become the thing it actually means.
func HumanEvent ¶ added in v0.16.1
HumanEvent is the PAST-tense form, for "after they ___". Custom events are returned unchanged: the operator chose "signup" or "checkout" and it already reads as English, so dressing it up would be worse and would stop matching what they see in filters, the API and their own tracking code.
func HumanEventBase ¶ added in v0.16.1
HumanEventBase is the infinitive, for "go on to ___".
func HumanEventIng ¶ added in v0.16.1
HumanEventIng is the gerund, for "from ___ to ___".
func HumanEventNoun ¶ added in v0.16.1
HumanEventNoun is the plural noun, for "___ dropped 20% in the last 24h", where an action cannot be the subject: "viewed a page dropped 100%" is not a sentence.
func HumanSegment ¶ added in v0.16.1
HumanSegment turns a raw property match into a phrase. `country=US` is how a filter is written, not how a person describes a group of visitors.
Types ¶
type Finding ¶
type Finding struct {
Severity string `json:"severity"` // warn | info
Title string `json:"title"`
Detail string `json:"detail"`
// The machine half. Every value below was already in the detector's hand when it wrote the
// sentence above, so acting on a finding never means re-reading its prose.
Kind string `json:"kind"`
Metric string `json:"metric,omitempty"` // the event this is about
Steps []string `json:"steps,omitempty"` // the funnel it was computed over
From string `json:"from,omitempty"` // the step users reach
To string `json:"to,omitempty"` // the step they fail to reach
Prop string `json:"prop,omitempty"` // the segment property being blamed
Value string `json:"value,omitempty"` // the segment value being blamed
Rate int `json:"rate,omitempty"` // the headline percentage (signed for deltas)
N int `json:"n,omitempty"` // the base the rate is computed over
}
Finding is one notable thing, ranked by severity ("warn" before "info").
func Generate ¶
Generate returns the digest: the biggest funnel leak, the headline event's week-over-week change, and the retention read — computed exactly. Generate detects the journey itself. Use it where there is no page context: the CLI, the morning brief, an MCP call.
func GenerateForFunnel ¶ added in v0.15.4
GenerateForFunnel is Generate over a CALLER-SUPPLIED funnel.
The dashboard picks its funnel one way (top events by volume, ordered by journey) and this package picked its own another way (first-touch coverage), so one page could show a funnel pane reading "$pageview → $engagement → $click" while its own verdict card said "overall $pageview→$deadclick conversion is 7%". Both were internally honest and the page still contradicted itself about what "the funnel" is. Passing the page's steps in makes the verdict describe the funnel the reader is actually looking at.
steps with fewer than 2 entries falls back to detecting, so existing callers are unchanged.
func (Finding) Fingerprint ¶ added in v0.19.0
Fingerprint is a finding's identity ACROSS PROCESSES: sha1 of the lowercased, trimmed title, first 12 hex chars. The cloud's fix-PR runner derives its branch name and its idempotency key with the exact same recipe (lib/finding-id.ts). If the two ever diverge, a brief, the email link that opens it and the PR opened from it stop being about the same thing — and nothing errors. Do not change this on one side.