Documentation
¶
Overview ¶
Package claim turns a merged pull request into a prediction with a deadline.
A claim is the missing noun. Analytics says what happened; a claim says what a change was SUPPOSED to make happen, and then the adjudicator holds the team to it at a date. Everything in the ship ledger hangs off this object, so the question that decides whether the ledger is a product or a form is: what fraction of real merges yield a checkable claim at all?
That is not a rhetorical question. Most merges are refactors, dependency bumps, CI fixes and copy tweaks with no measurable intent whatsoever, and a system that demands a claim for each one becomes an annoying form that makes a person do MORE product-management work, not less. So "no measurable intent" is a first-class outcome here, returned deliberately and counted, rather than an awkward edge case.
Deliberately deterministic. A model could read intent out of prose more sensibly, but the point of this pass is to measure the CEILING structurally before committing to the design: if the diff never touches a line that records an event, no amount of language understanding will make the result checkable, because there is nothing downstream to check it against.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Derived ¶
type Derived struct {
PR int `json:"pr"`
Verdict Verdict `json:"verdict"`
Metric string `json:"metric,omitempty"`
Why string `json:"why"`
Signals []string `json:"signals,omitempty"`
}
Derived is the outcome for one PR.
type PR ¶
type PR struct {
Number int
Title string
Body string
Files []string // paths touched
// Instrumented is the subset of Files that contain a tracking call for a known event. The
// caller resolves this, because only it knows how the product is instrumented.
Instrumented []string
// Events named anywhere in the title, body or diff.
Events []string
}
PR is the part of a pull request this needs. Deliberately small so it can be filled from the GitHub API, a local git log, or a test fixture without adapters.
type Verdict ¶
type Verdict string
Verdict is why a PR did or did not produce a claim. A closed set, because "we could not decide" has to be visible in the counts rather than hidden in a default.
const ( // Claimable — the change touches something measurable and an event can be named. Claimable Verdict = "claimable" // TouchesInstrumented — it changes instrumented code but names no specific event. Still // adjudicable against the events those files record, which is the narrower fallback design. TouchesInstrumented Verdict = "touches_instrumented" // NoMeasurableIntent — a refactor, a bump, a docs change. A correct and common answer. NoMeasurableIntent Verdict = "no_measurable_intent" // Unclear — user-facing but nothing connects it to a metric. This is the interesting bucket: // it is where instrumentation is missing, and it is the honest upper bound on how much better // a smarter deriver could do. Unclear Verdict = "unclear" )
type Yield ¶
type Yield struct {
Total int `json:"total"`
Claimable int `json:"claimable"`
TouchesInstrumented int `json:"touches_instrumented"`
Unclear int `json:"unclear"`
NoMeasurableIntent int `json:"no_measurable_intent"`
// StrictPct is the share yielding a claim with a named metric. BroadPct adds the ones
// adjudicable against whatever their instrumented files record — the narrower fallback.
StrictPct float64 `json:"strict_pct"`
BroadPct float64 `json:"broad_pct"`
// CeilingPct adds Unclear: what derivation could reach IF the product were fully instrumented.
// The gap between BroadPct and CeilingPct is an instrumentation problem, not a design problem,
// and those need opposite responses.
CeilingPct float64 `json:"ceiling_pct"`
}
Yield is the answer the whole test exists to produce.