diff --git a/cmd/service-prober/debug.go b/cmd/service-prober/debug.go
index a76f7e2a982e1b020f2bacb53de7c1108b6d63ad..1991454d6ae305108ecc19551694fcedd8c79e10 100644
--- a/cmd/service-prober/debug.go
+++ b/cmd/service-prober/debug.go
@@ -91,9 +91,9 @@ func (d *debugServer) handleDebugHome(w http.ResponseWriter, req *http.Request)
 	}
 	errsOnly := (req.FormValue("errs") == "y")
 	if errsOnly {
-		d.store.DoErrs(appendResult)
+		d.store.EachErrs(appendResult)
 	} else {
-		d.store.DoOk(appendResult)
+		d.store.Each(appendResult)
 	}
 
 	debugHomeTpl.Execute(w, map[string]interface{}{
@@ -129,6 +129,6 @@ func (s *dumpResultStore) Push(r *probes.Result) {
 	}
 }
 
-func (s *dumpResultStore) DoOk(func(*probes.Result))   {}
-func (s *dumpResultStore) DoErrs(func(*probes.Result)) {}
-func (s *dumpResultStore) Find(string) *probes.Result  { return nil }
+func (s *dumpResultStore) Each(func(*probes.Result))     {}
+func (s *dumpResultStore) EachErrs(func(*probes.Result)) {}
+func (s *dumpResultStore) Find(string) *probes.Result    { return nil }
diff --git a/probes/probe.go b/probes/probe.go
index d7a977f348f44b7fa128d0ac73789212dd96c9cc..6856e629c6fbe8258cb7209d1ae5afe22ad20dbc 100644
--- a/probes/probe.go
+++ b/probes/probe.go
@@ -19,6 +19,7 @@ var (
 	defaultTimeout  = 5 * time.Minute
 )
 
+// SpecCommon holds the parameters common to all probe specifications.
 type SpecCommon struct {
 	Type     string             `json:"type"`
 	Name     string             `json:"name"`
@@ -42,10 +43,13 @@ type config struct {
 	Probes []*rawSpec             `json:"probes"`
 }
 
+// ProbeImpl is the probe-specific implementation interface.
 type ProbeImpl interface {
 	RunProbe(context.Context, *log.Logger) error
 }
 
+// Spec is the generic interface for probe implementation factory
+// functions.
 type Spec interface {
 	Build(map[string]interface{}) (ProbeImpl, error)
 }
@@ -58,6 +62,26 @@ func RegisterProbeType(ptype string, pfunc probeParserFunc) {
 	probeRegistry[ptype] = pfunc
 }
 
+// ParseConfig parses a JSON-encoded configuration and returns a list of
+// Probe objects that can be executed or sent to the scheduler.
+//
+// Configuration parsing has a few phases: decoding the configuration
+// itself is a relatively complex task, as we are implementing
+// polymorphysm on probe definitions (via their "params"
+// attribute).This requires a multi-level approach in Go, where JSON
+// parsing is split into generic / specific stages, with the latter
+// delegated to a type-specific parser accessed via a global
+// registry. The result of this process is a "template" probe called a
+// Spec, which has to be an interface type because the actual struct
+// definition is private to the specific probe implementation.
+//
+// Then, parameterization is applied, potentially generating multiple
+// Probes from each Spec. Variables are expanded, and all necessary
+// information is bound together in the runtime-ready Probe object.
+// The variable expansion process is reflect-heavy but is only
+// performed once at the start of the process. The resulting Probe
+// objects are minimal and lean.
+//
 func ParseConfig(data []byte, resultStore ResultStore) ([]*Probe, error) {
 	var cfg config
 	if err := json.Unmarshal(data, &cfg); err != nil {
@@ -148,6 +172,9 @@ func checkUniqueness(probes []*Probe) error {
 	return nil
 }
 
+// A Probe holds all the runtime information necessary to run a single
+// probe, combining the SpecCommon parameters with a ProbeImpl to
+// actually execute the probe.
 type Probe struct {
 	spec        SpecCommon
 	impl        ProbeImpl
@@ -157,6 +184,7 @@ type Probe struct {
 	vars map[string]interface{}
 }
 
+// Name is a convenience function to return the probe name.
 func (p *Probe) Name() string { return p.spec.Name }
 
 // Interval satisfies the scheduler.PeriodicEvent interface.
diff --git a/probes/results.go b/probes/results.go
index 80fb426f0643b04018ad1019d418eb8e37a50b1f..32be2f321732d9f9dcdd490fd167242e4c353d58 100644
--- a/probes/results.go
+++ b/probes/results.go
@@ -6,6 +6,7 @@ import (
 	"time"
 )
 
+// Result of the execution of a probe.
 type Result struct {
 	ID       string
 	Spec     SpecCommon
@@ -21,10 +22,17 @@ func (r *Result) String() string {
 	return fmt.Sprintf("%s(%s)", r.Spec.Name, r.ID)
 }
 
+// ResultStore keeps the most recent probe results in storage, and
+// allows access to them (mostly for debugging purposes, as this part
+// isn't required by the prober functionality). The results buffer has
+// a fixed size, so older results will be dropped as more recent ones
+// come in. Failures are kept in a separate buffer, with the hope of
+// keeping errors around for longer for inspection purposes, even
+// after they've recovered.
 type ResultStore interface {
 	Push(*Result)
-	DoOk(func(*Result))
-	DoErrs(func(*Result))
+	Each(func(*Result))
+	EachErrs(func(*Result))
 	Find(string) *Result
 }
 
@@ -84,13 +92,13 @@ func (r *memResultStore) Push(result *Result) {
 	r.mx.Unlock()
 }
 
-func (r *memResultStore) DoOk(f func(*Result)) {
+func (r *memResultStore) Each(f func(*Result)) {
 	r.mx.Lock()
 	r.last.Each(f)
 	r.mx.Unlock()
 }
 
-func (r *memResultStore) DoErrs(f func(*Result)) {
+func (r *memResultStore) EachErrs(f func(*Result)) {
 	r.mx.Lock()
 	r.errs.Each(f)
 	r.mx.Unlock()