Files
sanderling/cmd/internal-tools/confusion-matrix/checker.go
T
pj 56a002d87a feat(confusion-matrix): score the checker against a blind reviewer
Cross-tabulates the properties that fired against the human verdict, one
cell per implementation, over a sweep whose implementations all passed
their own generated tests. An implementation that failed to build, has no
usable run, or carries no filed verdict is listed as missing data rather
than counted as a clean cell.

Landing the package in one commit because the intermediate splits would
not link.
2026-08-17 23:27:47 +05:30

330 lines
9.8 KiB
Go

package main
import (
"bufio"
"encoding/json"
"fmt"
"maps"
"os"
"path/filepath"
"slices"
"strconv"
"strings"
)
const (
sweepManifestFileName = "sweep.json"
sweepRecordsFileName = "implementations.jsonl"
campaignManifestFileName = "campaign.json"
campaignRecordsFileName = "runs.jsonl"
traceFileName = "trace.jsonl"
surfacesExtractor = "locatableSurfaces"
maxRecordBytes = 4 * 1024 * 1024
maxTraceLineBytes = 16 * 1024 * 1024
)
// Run exclusion reasons, kept in the vocabulary analyze already uses so the two
// tools describe the same run the same way.
const (
reasonLaunchError = "launch error"
reasonTimedOut = "timed out"
reasonNonzeroExit = "nonzero exit"
reasonTraceError = "unreadable trace"
)
type sweepManifest struct {
SpecPath string `json:"spec_path"`
Implementations []struct {
Name string `json:"name"`
} `json:"implementations"`
}
type sweepRunRecord struct {
Seed int64 `json:"seed"`
ExitCode int `json:"exit_code"`
LaunchError string `json:"launch_error"`
CampaignDirectory string `json:"campaign_directory"`
}
type sweepImplementationRecord struct {
Name string `json:"implementation"`
FailedStage string `json:"failed_stage"`
Error string `json:"error"`
Runs []sweepRunRecord `json:"runs"`
}
type campaignRunRecord struct {
Seed int64 `json:"seed"`
ExitCode int `json:"exit_code"`
LaunchError string `json:"launch_error"`
TimedOut bool `json:"timed_out"`
TraceError string `json:"trace_error"`
RunDirectory string `json:"run_directory"`
ViolatedProperties []string `json:"violated_properties"`
}
// checkerVerdict is one implementation's whole checker side, pooled across the
// seeds it was swept at.
type checkerVerdict struct {
Implementation string
FailedStage string
FailedError string
RunsRecorded int
RunsUsable int
ExcludedByReason map[string]int
FiredProperties []string
// SurfacesObserved holds every locatable surface seen true on at least one
// step of at least one usable run. A surface missing from it was never
// located across the whole sweep of this implementation.
SurfacesObserved map[string]bool
SurfacesKnown bool
TraceErrors []string
}
func (v checkerVerdict) fired() bool { return len(v.FiredProperties) > 0 }
type checkerSide struct {
Directory string
SpecPath string
Planned []string
Verdicts []checkerVerdict
}
func loadChecker(directory string) (checkerSide, error) {
body, err := os.ReadFile(filepath.Join(directory, sweepManifestFileName))
if err != nil {
return checkerSide{}, fmt.Errorf("read %s: %w", sweepManifestFileName, err)
}
var declared sweepManifest
if err := json.Unmarshal(body, &declared); err != nil {
return checkerSide{}, fmt.Errorf("parse %s in %s: %w", sweepManifestFileName, directory, err)
}
side := checkerSide{Directory: directory, SpecPath: declared.SpecPath}
for _, planned := range declared.Implementations {
side.Planned = append(side.Planned, planned.Name)
}
records, err := readSweepRecords(filepath.Join(directory, sweepRecordsFileName))
if err != nil {
return checkerSide{}, err
}
for _, record := range records {
verdict, err := readImplementation(directory, record)
if err != nil {
return checkerSide{}, err
}
side.Verdicts = append(side.Verdicts, verdict)
}
slices.SortFunc(side.Verdicts, func(a, b checkerVerdict) int {
return strings.Compare(a.Implementation, b.Implementation)
})
return side, nil
}
func readSweepRecords(path string) ([]sweepImplementationRecord, error) {
file, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("read %s: %w", sweepRecordsFileName, err)
}
defer file.Close()
var records []sweepImplementationRecord
scanner := bufio.NewScanner(file)
scanner.Buffer(make([]byte, 0, 64*1024), maxRecordBytes)
lineNumber := 0
seen := map[string]bool{}
for scanner.Scan() {
lineNumber++
raw := strings.TrimSpace(scanner.Text())
if raw == "" {
continue
}
var record sweepImplementationRecord
if err := json.Unmarshal([]byte(raw), &record); err != nil {
return nil, fmt.Errorf("%s line %d: %w", sweepRecordsFileName, lineNumber, err)
}
if record.Name == "" {
return nil, fmt.Errorf("%s line %d names no implementation", sweepRecordsFileName, lineNumber)
}
if seen[record.Name] {
return nil, fmt.Errorf("%s line %d records %s a second time: its runs would be pooled twice",
sweepRecordsFileName, lineNumber, record.Name)
}
seen[record.Name] = true
records = append(records, record)
}
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("read %s: %w", sweepRecordsFileName, err)
}
return records, nil
}
func readImplementation(sweepDirectory string, record sweepImplementationRecord) (checkerVerdict, error) {
verdict := checkerVerdict{
Implementation: record.Name,
FailedStage: record.FailedStage,
FailedError: record.Error,
ExcludedByReason: map[string]int{},
SurfacesObserved: map[string]bool{},
}
fired := map[string]bool{}
for _, run := range record.Runs {
verdict.RunsRecorded++
if run.LaunchError != "" {
verdict.ExcludedByReason[reasonLaunchError]++
continue
}
directory := resolveCampaignDirectory(sweepDirectory, record.Name, run)
campaignRuns, err := readCampaignRuns(directory)
if err != nil {
return checkerVerdict{}, err
}
for _, campaignRun := range campaignRuns {
if reason := excludedBecause(campaignRun); reason != "" {
verdict.ExcludedByReason[reason]++
continue
}
verdict.RunsUsable++
for _, property := range campaignRun.ViolatedProperties {
fired[property] = true
}
observed, err := readObservedSurfaces(filepath.Join(directory, campaignRun.RunDirectory))
if err != nil {
verdict.TraceErrors = append(verdict.TraceErrors, err.Error())
continue
}
verdict.SurfacesKnown = true
for surface, seen := range observed {
if seen {
verdict.SurfacesObserved[surface] = true
}
}
}
}
if len(fired) > 0 {
verdict.FiredProperties = slices.Sorted(maps.Keys(fired))
}
if len(verdict.ExcludedByReason) == 0 {
verdict.ExcludedByReason = nil
}
return verdict, nil
}
// resolveCampaignDirectory prefers the path the sweep recorded and falls back to
// the layout it names, so a sweep directory read on another machine than the one
// that wrote its absolute paths still resolves.
func resolveCampaignDirectory(sweepDirectory, name string, run sweepRunRecord) string {
if run.CampaignDirectory != "" {
if _, err := os.Stat(run.CampaignDirectory); err == nil {
return run.CampaignDirectory
}
}
return filepath.Join(sweepDirectory, name, "seed-"+strconv.FormatInt(run.Seed, 10))
}
func readCampaignRuns(directory string) ([]campaignRunRecord, error) {
if _, err := os.Stat(filepath.Join(directory, campaignManifestFileName)); err != nil {
return nil, fmt.Errorf("read %s in %s: %w", campaignManifestFileName, directory, err)
}
file, err := os.Open(filepath.Join(directory, campaignRecordsFileName))
if err != nil {
return nil, fmt.Errorf("read %s: %w", campaignRecordsFileName, err)
}
defer file.Close()
var records []campaignRunRecord
scanner := bufio.NewScanner(file)
scanner.Buffer(make([]byte, 0, 64*1024), maxRecordBytes)
lineNumber := 0
for scanner.Scan() {
lineNumber++
raw := strings.TrimSpace(scanner.Text())
if raw == "" {
continue
}
var record campaignRunRecord
if err := json.Unmarshal([]byte(raw), &record); err != nil {
return nil, fmt.Errorf("%s line %d in %s: %w", campaignRecordsFileName, lineNumber, directory, err)
}
records = append(records, record)
}
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("read %s in %s: %w", campaignRecordsFileName, directory, err)
}
return records, nil
}
func excludedBecause(record campaignRunRecord) string {
switch {
case record.LaunchError != "":
return reasonLaunchError
case record.TimedOut:
return reasonTimedOut
case record.ExitCode != 0:
return reasonNonzeroExit
case record.TraceError != "":
return reasonTraceError
default:
return ""
}
}
type traceLine struct {
ExtractorChanges map[string]struct {
Curr json.RawMessage `json:"curr"`
} `json:"extractor_changes"`
}
// readObservedSurfaces replays one run's locatableSurfaces readings. The
// verifier emits every extractor as a change on the first snapshot and only on
// a difference afterwards, so a surface true on any recorded change was located
// at least once, and one absent from every change was never located at all.
func readObservedSurfaces(runDirectory string) (map[string]bool, error) {
path := filepath.Join(runDirectory, traceFileName)
file, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("read %s: %w", path, err)
}
defer file.Close()
observed := map[string]bool{}
found := false
scanner := bufio.NewScanner(file)
scanner.Buffer(make([]byte, 0, 64*1024), maxTraceLineBytes)
lineNumber := 0
for scanner.Scan() {
lineNumber++
raw := strings.TrimSpace(scanner.Text())
if raw == "" {
continue
}
var line traceLine
if err := json.Unmarshal([]byte(raw), &line); err != nil {
return nil, fmt.Errorf("%s line %d: %w", path, lineNumber, err)
}
change, present := line.ExtractorChanges[surfacesExtractor]
if !present || len(change.Curr) == 0 {
continue
}
var reading map[string]bool
if err := json.Unmarshal(change.Curr, &reading); err != nil {
return nil, fmt.Errorf("%s line %d: %s is not an object of booleans: %w",
path, lineNumber, surfacesExtractor, err)
}
found = true
for surface, located := range reading {
if located {
observed[surface] = true
}
}
}
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("read %s: %w", path, err)
}
if !found {
return nil, fmt.Errorf("%s records no %s reading: this run cannot say whether a surface was located",
path, surfacesExtractor)
}
return observed, nil
}