Documentation
¶
Overview ¶
Package bugreport files a defect in forge itself with the Reliant engineering team: `forge report-bug`.
Inside Reliant an agent files with reliant's own report_bug tool, whose record the worker's log pipeline ships to our telemetry. A forge running in Claude Code, Codex or Cursor, or at a person's terminal, has no such pipeline, so it posts the report to the control plane's public ingest, controlplane.v1.ForgeReportService/FileBugReport, which writes the same kind of issue record (control-plane docs/design/forge-cli-reports.md).
forge sends NOTHING unless someone files a report. There is no automatic crash or error reporting and no telemetry. What a report carries is listed in docs/report-bug.md; Payload is all of it.
The report id is minted here, so it can be printed whatever the ingest answers, and a repeat of a report filed in the last 30 minutes returns the first report's id without sending anything (State).
Index ¶
Constants ¶
const ( // Procedure is the ingest rpc. Procedure = "controlplane.v1.ForgeReportService/FileBugReport" // EndpointEnv overrides the control plane reports go to (a dev or // staging control plane). Unset, reports go to cloud.DefaultEndpoint. EndpointEnv = "FORGE_REPORT_ENDPOINT" // DedupeWindow is how long a filed report answers a repeat of itself. DedupeWindow = 30 * time.Minute // MaxTitleBytes bounds redacted UTF-8 title bytes including the marker. MaxTitleBytes = 200 // MaxTextBytes bounds redacted UTF-8 text bytes including the marker. MaxTextBytes = 4000 )
const StateFile = "report-bug.json"
StateFile is the file, in forge's config directory, that holds this machine's install id and the reports filed in the last DedupeWindow.
Variables ¶
This section is empty.
Functions ¶
func CommandLine ¶
CommandLine is args joined into one line with every value that could hold a secret removed: the value of a secret-named flag becomes redact.Marker, the value of a report text flag becomes "…", and every remaining argument is redact.Text'd (credential shapes, home directories). The program path is reduced to its base name.
func DefaultEndpoint ¶
func DefaultEndpoint() string
DefaultEndpoint is EndpointEnv when set, cloud.DefaultEndpoint otherwise.
func Fingerprint ¶
Fingerprint names the defect a title describes, for local deduplication: the title redacted, lowercased, its words kept and every word holding a digit dropped (ids, counts and ports vary between two sightings of one defect). reliant's report_bug deduplicates by the same rule.
func Severities ¶
func Severities() []string
Severities are the accepted severities, most severe first.
Types ¶
type ClientContext ¶
type ClientContext struct {
ForgeVersion string `json:"forgeVersion,omitempty"`
OS string `json:"os,omitempty"`
Arch string `json:"arch,omitempty"`
CommandLine string `json:"commandLine,omitempty"`
ProjectForgeVersion string `json:"projectForgeVersion,omitempty"`
Harness string `json:"harness,omitempty"`
InstallID string `json:"installId,omitempty"`
GoVersion string `json:"goVersion,omitempty"`
}
ClientContext is the wire form of Context.
type Context ¶
type Context struct {
// ForgeVersion is this binary's version (buildinfo.Version()).
ForgeVersion string
// ProjectForgeVersion is forge.yaml's forge_version of the project forge
// ran in, "" outside one.
ProjectForgeVersion string
// Harness is the agent harness forge detected, "" for a person.
Harness string
// Args is the command line (os.Args). It is redacted by CommandLine.
Args []string
}
Context is what forge knows about where it ran. The caller supplies it; nothing here reads the environment beyond the OS and architecture.
type Filer ¶
type Filer struct {
// Endpoint is the control plane's base URL.
Endpoint string
// Token is a forge login to present, "" for none. It only adds the
// caller's ids to the record; the ingest ignores one it cannot validate.
Token string
// State is where the install id and recent reports are kept.
State *State
// Now is the clock; tests pin it.
Now func() time.Time
// contains filtered or unexported fields
}
Filer files reports.
type Payload ¶
type Payload struct {
ReportID string `json:"reportId"`
Severity string `json:"severity"`
Title string `json:"title"`
Summary string `json:"summary,omitempty"`
Expected string `json:"expected,omitempty"`
Actual string `json:"actual,omitempty"`
Evidence string `json:"evidence,omitempty"`
Client ClientContext `json:"client"`
}
Payload is exactly what is sent: FileBugReportRequest in protojson.
type Report ¶
type Report struct {
// Severity is critical (data loss, or nothing can proceed), high (it
// blocks the task), medium (there is a workaround) or low (cosmetic).
Severity string `json:"severity"`
// Title is one line naming the defect; ids and numbers go in Evidence.
Title string `json:"title"`
Summary string `json:"summary,omitempty"`
Expected string `json:"expected,omitempty"`
Actual string `json:"actual,omitempty"`
// Evidence is how to reproduce it: commands, output, file paths.
Evidence string `json:"evidence,omitempty"`
}
Report is what the reporter writes. Its JSON form is what `forge report-bug --json` reads.
type Result ¶
type Result struct {
// ReportID is the report's id: this report's, or the earlier one a
// duplicate was answered with.
ReportID string `json:"report_id"`
// Duplicate: the same report was filed within DedupeWindow, and nothing
// was sent.
Duplicate bool `json:"duplicate,omitempty"`
// FiledAt is when ReportID was filed.
FiledAt time.Time `json:"filed_at"`
}
Result is a filed report.
type State ¶
type State struct {
// contains filtered or unexported fields
}
State is this machine's report state: a random install id, minted on first use, which is the ingest's per-install rate-limit key, and the reports filed recently, which answer a repeat with the first report's id.
A state file that cannot be read or written never stops a report: the report is sent with a fresh install id and is simply not deduplicated.