diff --git a/notary/internal/notecheck/main.go b/notary/internal/notecheck/main.go
index e0923f7..f647b6a 100644
--- a/notary/internal/notecheck/main.go
+++ b/notary/internal/notecheck/main.go
@@ -12,14 +12,21 @@
 //
 // Usage:
 //
-//	notecheck [-v] notary-key go.sum
+//	notecheck [-h H] [-k key] [-u url] [-v] go.sum
+//
+// The -h flag changes the tile height (default 8).
+//
+// The -k flag changes the go.sum database server key.
+//
+// The -u flag overrides the URL of the server.
 //
 // The -v flag enables verbose output.
+// In particular, it causes notecheck to print all URLs fetched
+// from the server and how long each took.
 //
 package main
 
 import (
-	"bytes"
 	"flag"
 	"fmt"
 	"io"
@@ -31,18 +38,20 @@
 	"sync"
 	"time"
 
-	"golang.org/x/exp/notary/internal/note"
-	"golang.org/x/exp/notary/internal/tlog"
+	"golang.org/x/exp/notary/internal/sumweb"
 )
 
 func usage() {
-	fmt.Fprintf(os.Stderr, "usage: notecheck [-u url] [-h H] [-v] notary-key go.sum...\n")
+	fmt.Fprintf(os.Stderr, "usage: notecheck [-h H] [-k notary-key] [-u url] [-v] go.sum...\n")
 	os.Exit(2)
 }
 
-var height = flag.Int("h", 8, "tile height")
-var vflag = flag.Bool("v", false, "enable verbose output")
-var url = flag.String("u", "", "url to notary (overriding name)")
+var (
+	height = flag.Int("h", 8, "tile height")
+	vkey   = flag.String("k", "rsc-goog.appspot.com+eecb1dec+AbTy1QXWdqYd1TTpuaUqsk6u7p+n4AqLiLB8SBwoB831", "notary key") // TODO: Replace with real key.
+	url    = flag.String("u", "", "url to notary (overriding name)")
+	vflag  = flag.Bool("v", false, "enable verbose output")
+)
 
 func main() {
 	log.SetPrefix("notecheck: ")
@@ -50,334 +59,123 @@
 
 	flag.Usage = usage
 	flag.Parse()
-	if flag.NArg() < 2 {
+	if flag.NArg() < 1 {
 		usage()
 	}
 
-	vkey := flag.Arg(0)
-	verifier, err := note.NewVerifier(vkey)
-	if err != nil {
-		log.Fatal(err)
-	}
-	if *url == "" {
-		*url = "https://" + verifier.Name()
-	}
-
-	// TODO(rsc): Load initial db.latest, db.latestNote from on-disk cache.
-	db := &GoSumDB{
-		url:       *url,
-		verifiers: note.VerifierList(verifier),
-	}
-	db.httpClient.Timeout = 1 * time.Minute
-	db.tileReader.db = db
-	db.tileReader.url = db.url + "/"
+	conn := sumweb.NewConn(new(client))
 
 	for _, arg := range flag.Args()[1:] {
 		data, err := ioutil.ReadFile(arg)
 		if err != nil {
 			log.Fatal(err)
 		}
-		log.SetPrefix("notecheck: " + arg + ": ")
-		checkGoSum(db, data)
-		log.SetPrefix("notecheck: ")
+		checkGoSum(conn, arg, data)
 	}
 }
 
-func checkGoSum(db *GoSumDB, data []byte) {
+func checkGoSum(conn *sumweb.Conn, name string, data []byte) {
 	lines := strings.Split(string(data), "\n")
 	if lines[len(lines)-1] != "" {
 		log.Printf("error: final line missing newline")
 		return
 	}
-	// TODO(rsc): This assumes that the /go.mod and the whole-tree hashes
-	// always appear together in a go.sum.
-	// Sometimes the /go.mod can appear alone.
-	// The code needs to be updated to handle that case.
 	lines = lines[:len(lines)-1]
-	if len(lines)%2 != 0 {
-		log.Printf("error: odd number of lines")
+
+	errs := make([]string, len(lines))
+	var wg sync.WaitGroup
+	for i, line := range lines {
+		wg.Add(1)
+		go func(i int, line string) {
+			defer wg.Done()
+			f := strings.Fields(line)
+			if len(f) != 3 {
+				errs[i] = "invalid number of fields"
+				return
+			}
+
+			dbLines, err := conn.Lookup(f[0], f[1])
+			if err != nil {
+				errs[i] = err.Error()
+				return
+			}
+			hashAlgPrefix := f[0] + " " + f[1] + " " + f[2][:strings.Index(f[2], ":")+1]
+			for _, dbLine := range dbLines {
+				if dbLine == line {
+					return
+				}
+				if strings.HasPrefix(dbLine, hashAlgPrefix) {
+					errs[i] = fmt.Sprintf("%s@%s hash mismatch: have %s, want %s", f[0], f[1], line, dbLine)
+					return
+				}
+			}
+			errs[i] = fmt.Sprintf("%s@%s hash algorithm mismatch: have %s, want one of:\n\t%s", f[0], f[1], line, strings.Join(dbLines, "\n\t"))
+		}(i, line)
 	}
-	for i := 0; i+2 <= len(lines); i += 2 {
-		f1 := strings.Fields(lines[i])
-		f2 := strings.Fields(lines[i+1])
-		if len(f1) != 3 || len(f2) != 3 || f1[0] != f2[0] || f1[1]+"/go.mod" != f2[1] {
-			log.Printf("error: bad line pair:\n\t%s\t%s", lines[i], lines[i+1])
-			continue
-		}
+	wg.Wait()
 
-		dbLines, err := db.Lookup(f1[0], f1[1])
-		if err != nil {
-			log.Printf("%s@%s: %v", f1[0], f1[1], err)
-			continue
-		}
-
-		if strings.Join(lines[i:i+2], "\n") != strings.Join(dbLines, "\n") {
-			log.Printf("%s@%s: invalid go.sum entries:\ngo.sum:\n\t%s\nsum.golang.org:\n\t%s", f1[0], f1[1], strings.Join(lines[i:i+2], "\n\t"), strings.Join(dbLines, "\n\t"))
+	for i, err := range errs {
+		if err != "" {
+			fmt.Printf("%s:%d: %s\n", name, i+1, err)
 		}
 	}
 }
 
-// A GoSumDB is a client for a go.sum database.
-type GoSumDB struct {
-	url        string         // root url of database, without trailing slash
-	verifiers  note.Verifiers // accepted verifiers for signed trees
-	tileReader tileReader     // tlog.TileReader implementation
-	httpCache  parCache
-	httpClient http.Client
+type client struct{}
 
-	// latest accepted tree head
-	mu         sync.Mutex
-	latest     tlog.Tree
-	latestNote []byte // signed note
+func (*client) ReadConfig(file string) ([]byte, error) {
+	if file == "key" {
+		return []byte(*vkey + "\n" + *url), nil
+	}
+	if strings.HasSuffix(file, "/latest") {
+		// Looking for cached latest tree head.
+		// Empty result means empty tree.
+		return []byte{}, nil
+	}
+	return nil, fmt.Errorf("unknown config %s", file)
 }
 
-// parCache is a minimal simulation of cmd/go's par.Cache.
-// When this code moves into cmd/go, it should use the real par.Cache
-type parCache struct {
+func (*client) WriteConfig(file string, old, new []byte) error {
+	// Ignore writes.
+	return nil
 }
 
-func (c *parCache) Do(key interface{}, f func() interface{}) interface{} {
-	return f()
+func (*client) ReadCache(file string) ([]byte, error) {
+	return nil, fmt.Errorf("no cache")
 }
 
-// Lookup returns the go.sum lines for the given module path and version.
-func (db *GoSumDB) Lookup(path, vers string) ([]string, error) {
-	// TODO(rsc): !-encode the path.
-	data, err := db.httpGet(db.url + "/lookup/" + path + "@" + vers)
+func (*client) WriteCache(file string, data []byte) {
+	// Ignore writes.
+}
+
+func (*client) Log(msg string) {
+	log.Print(msg)
+}
+
+func (*client) SecurityError(msg string) {
+	log.Fatal(msg)
+}
+
+func init() {
+	http.DefaultClient.Timeout = 1 * time.Minute
+}
+
+func (*client) GetURL(url string) ([]byte, error) {
+	start := time.Now()
+	resp, err := http.Get(url)
 	if err != nil {
 		return nil, err
 	}
-
-	id, text, treeMsg, err := tlog.ParseRecord(data)
+	defer resp.Body.Close()
+	if resp.StatusCode != 200 {
+		return nil, fmt.Errorf("GET %v: %v", url, resp.Status)
+	}
+	data, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
 	if err != nil {
-		return nil, fmt.Errorf("%s@%s: %v", path, vers, err)
+		return nil, err
 	}
-	if err := db.updateLatest(treeMsg); err != nil {
-		return nil, fmt.Errorf("%s@%s: %v", path, vers, err)
+	if *vflag {
+		fmt.Fprintf(os.Stderr, "%.3fs %s\n", time.Since(start).Seconds(), url)
 	}
-	if err := db.checkRecord(id, text); err != nil {
-		return nil, fmt.Errorf("%s@%s: %v", path, vers, err)
-	}
-
-	prefix := path + " " + vers + " "
-	prefixGoMod := path + " " + vers + "/go.mod "
-	var hashes []string
-	for _, line := range strings.Split(string(text), "\n") {
-		if strings.HasPrefix(line, prefix) || strings.HasPrefix(line, prefixGoMod) {
-			hashes = append(hashes, line)
-		}
-	}
-	return hashes, nil
-}
-
-// updateLatest updates db's idea of the latest tree head
-// to incorporate the signed tree head in msg.
-// If msg is before the current latest tree head,
-// updateLatest still checks that it fits into the known timeline.
-// updateLatest returns an error for non-malicious problems.
-// If it detects a fork in the tree history, it prints a detailed
-// message and calls log.Fatal.
-func (db *GoSumDB) updateLatest(msg []byte) error {
-	if len(msg) == 0 {
-		return nil
-	}
-	note, err := note.Open(msg, db.verifiers)
-	if err != nil {
-		return fmt.Errorf("reading tree note: %v\nnote:\n%s", err, msg)
-	}
-	tree, err := tlog.ParseTree([]byte(note.Text))
-	if err != nil {
-		return fmt.Errorf("reading tree: %v\ntree:\n%s", err, note.Text)
-	}
-
-Update:
-	for {
-		db.mu.Lock()
-		latest := db.latest
-		latestNote := db.latestNote
-		db.mu.Unlock()
-
-		switch {
-		case tree.N <= latest.N:
-			return db.checkTrees(tree, msg, latest, latestNote)
-
-		case tree.N > latest.N:
-			if err := db.checkTrees(latest, latestNote, tree, msg); err != nil {
-				return err
-			}
-			db.mu.Lock()
-			if db.latest != latest {
-				if db.latest.N > latest.N {
-					db.mu.Unlock()
-					continue Update
-				}
-				log.Fatalf("go.sum database changed underfoot:\n\t%v ->\n\t%v", latest, db.latest)
-			}
-			db.latest = tree
-			db.latestNote = msg
-			db.mu.Unlock()
-			return nil
-		}
-	}
-}
-
-// checkTrees checks that older (from olderNote) is contained in newer (from newerNote).
-// If an error occurs, such as malformed data or a network problem, checkTrees returns that error.
-// If on the other hand checkTrees finds evidence of misbehavior, it prepares a detailed
-// message and calls log.Fatal.
-func (db *GoSumDB) checkTrees(older tlog.Tree, olderNote []byte, newer tlog.Tree, newerNote []byte) error {
-	thr := tlog.TileHashReader(newer, &db.tileReader)
-	h, err := tlog.TreeHash(older.N, thr)
-	if err != nil {
-		return fmt.Errorf("checking tree#%d against tree#%d: %v", older.N, newer.N, err)
-	}
-	if h == older.Hash {
-		return nil
-	}
-
-	// Detected a fork in the tree timeline.
-	// Start by reporting the inconsistent signed tree notes.
-	var buf bytes.Buffer
-	fmt.Fprintf(&buf, "SECURITY ERROR\n")
-	fmt.Fprintf(&buf, "go.sum database server misbehavior detected!\n\n")
-	indent := func(b []byte) []byte {
-		return bytes.Replace(b, []byte("\n"), []byte("\n\t"), -1)
-	}
-	fmt.Fprintf(&buf, "old database:\n\t%v\n", indent(olderNote))
-	fmt.Fprintf(&buf, "new database:\n\t%v\n", indent(newerNote))
-
-	// The notes alone are not enough to prove the inconsistency.
-	// We also need to show that the newer note's tree hash for older.N
-	// does not match older.Hash. The consumer of this report could
-	// of course consult the server to try to verify the inconsistency,
-	// but we are holding all the bits we need to prove it right now,
-	// so we might as well print them and make the report not depend
-	// on the continued availability of the misbehaving server.
-	// Preparing this data only reuses the tiled hashes needed for
-	// tlog.TreeHash(older.N, thr) above, so assuming thr is caching tiles,
-	// there are no new access to the server here, and these operations cannot fail.
-	fmt.Fprintf(&buf, "proof of misbehavior:\n\t%v", h)
-	if p, err := tlog.ProveTree(newer.N, older.N, thr); err != nil {
-		fmt.Fprintf(&buf, "\tinternal error: %v\n", err)
-	} else if err := tlog.CheckTree(p, newer.N, newer.Hash, older.N, h); err != nil {
-		fmt.Fprintf(&buf, "\tinternal error: generated inconsistent proof\n")
-	} else {
-		for _, h := range p {
-			fmt.Fprintf(&buf, "\n\t%v", h)
-		}
-	}
-	log.Fatalf("%v", buf.String())
-	panic("not reached")
-}
-
-// checkRecord checks that record #id's hash matches data.
-func (db *GoSumDB) checkRecord(id int64, data []byte) error {
-	db.mu.Lock()
-	tree := db.latest
-	db.mu.Unlock()
-
-	if id >= tree.N {
-		return fmt.Errorf("cannot validate record %d in tree of size %d", id, tree.N)
-	}
-	hashes, err := tlog.TileHashReader(tree, &db.tileReader).ReadHashes([]int64{tlog.StoredHashIndex(0, id)})
-	if err != nil {
-		return err
-	}
-	if hashes[0] == tlog.RecordHash(data) {
-		return nil
-	}
-	return fmt.Errorf("cannot authenticate record data in server response")
-}
-
-type tileReader struct {
-	url     string
-	cache   map[tlog.Tile][]byte
-	cacheMu sync.Mutex
-	db      *GoSumDB
-}
-
-func (r *tileReader) Height() int {
-	return *height
-}
-
-func (r *tileReader) SaveTiles(tiles []tlog.Tile, data [][]byte) {
-	// TODO(rsc): On-disk cache in GOPATH.
-}
-
-func (r *tileReader) ReadTiles(tiles []tlog.Tile) ([][]byte, error) {
-	// TODO(rsc): Look in on-disk cache in GOPATH.
-
-	var wg sync.WaitGroup
-	out := make([][]byte, len(tiles))
-	errs := make([]error, len(tiles))
-	r.cacheMu.Lock()
-	if r.cache == nil {
-		r.cache = make(map[tlog.Tile][]byte)
-	}
-	for i, tile := range tiles {
-		if data := r.cache[tile]; data != nil {
-			out[i] = data
-			continue
-		}
-		wg.Add(1)
-		go func(i int, tile tlog.Tile) {
-			defer wg.Done()
-			data, err := r.db.httpGet(r.url + tile.Path())
-			if err != nil && tile.W != 1<<uint(tile.H) {
-				fullTile := tile
-				fullTile.W = 1 << uint(tile.H)
-				if fullData, err1 := r.db.httpGet(r.url + fullTile.Path()); err1 == nil {
-					data = fullData[:tile.W*tlog.HashSize]
-					err = nil
-				}
-			}
-			if err != nil {
-				errs[i] = err
-				return
-			}
-			r.cacheMu.Lock()
-			r.cache[tile] = data
-			r.cacheMu.Unlock()
-			out[i] = data
-		}(i, tile)
-	}
-	r.cacheMu.Unlock()
-	wg.Wait()
-
-	for _, err := range errs {
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	return out, nil
-}
-
-func (db *GoSumDB) httpGet(url string) ([]byte, error) {
-	type cached struct {
-		data []byte
-		err  error
-	}
-
-	c := db.httpCache.Do(url, func() interface{} {
-		start := time.Now()
-		resp, err := db.httpClient.Get(url)
-		if err != nil {
-			return cached{nil, err}
-		}
-		defer resp.Body.Close()
-		if resp.StatusCode != 200 {
-			return cached{nil, fmt.Errorf("GET %v: %v", url, resp.Status)}
-		}
-		data, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
-		if err != nil {
-			return cached{nil, err}
-		}
-		if *vflag {
-			fmt.Fprintf(os.Stderr, "%.3fs %s\n", time.Since(start).Seconds(), url)
-		}
-		return cached{data, nil}
-	}).(cached)
-
-	return c.data, c.err
+	return data, nil
 }
diff --git a/notary/internal/notecheck/test.sum b/notary/internal/notecheck/test.sum
index 4a8bcd7..c7105a0 100644
--- a/notary/internal/notecheck/test.sum
+++ b/notary/internal/notecheck/test.sum
@@ -2,5 +2,4 @@
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=
 rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
-rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
diff --git a/notary/internal/sumweb/client.go b/notary/internal/sumweb/client.go
index e0923f7..8c535b2 100644
--- a/notary/internal/sumweb/client.go
+++ b/notary/internal/sumweb/client.go
@@ -2,221 +2,365 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Notecheck checks a go.sum file against a notary.
-//
-// WARNING! This program is meant as a proof of concept demo and
-// should not be used in production scripts.
-// It does not set an exit status to report whether the
-// checksums matched, and it does not filter the go.sum
-// according to the $GONOVERIFY environment variable.
-//
-// Usage:
-//
-//	notecheck [-v] notary-key go.sum
-//
-// The -v flag enables verbose output.
-//
-package main
+package sumweb
 
 import (
 	"bytes"
-	"flag"
+	"errors"
 	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"net/http"
-	"os"
 	"strings"
 	"sync"
-	"time"
 
 	"golang.org/x/exp/notary/internal/note"
 	"golang.org/x/exp/notary/internal/tlog"
 )
 
-func usage() {
-	fmt.Fprintf(os.Stderr, "usage: notecheck [-u url] [-h H] [-v] notary-key go.sum...\n")
-	os.Exit(2)
+// A Client provides the external operations
+// (file caching, HTTP fetches, and so on)
+// needed to implement the HTTP client Conn.
+// The methods must be safe for concurrent use by multiple goroutines.
+type Client interface {
+	// GetURL fetches and returns the content served at the given URL.
+	// It should return an error for any non-200 HTTP response status.
+	GetURL(url string) ([]byte, error)
+
+	// ReadConfig reads and returns the content of the named configuration file.
+	// There are only a fixed set of configuration files.
+	//
+	// "key" returns a file containing the verifier key for the server.
+	// If the file has a second line, it should be the URL of the server.
+	// Otherwise the URL is "https://" + serverName (derived from key).
+	// "key" is only ever read, not written.
+	//
+	// serverName + "/latest" returns a file containing the latest known
+	// signed tree from the server. It is read and written (using WriteConfig).
+	ReadConfig(file string) ([]byte, error)
+
+	// WriteConfig updates the content of the named configuration file,
+	// changing it from the old []byte to the new []byte.
+	// If the old []byte does not match the stored configuration,
+	// WriteConfig must return ErrWriteConflict.
+	// Otherwise, WriteConfig should atomically replace old with new.
+	WriteConfig(file string, old, new []byte) error
+
+	// ReadCache reads and returns the content of the named cache file.
+	// Any returned error will be treated as equivalent to the file not existing.
+	// There can be arbitrarily many cache files, such as:
+	//	serverName/lookup/pkg@version
+	//	serverName/tile/8/1/x123/456
+	ReadCache(file string) ([]byte, error)
+
+	// WriteCache writes the named cache file.
+	WriteCache(file string, data []byte)
+
+	// Log prints the given log message (such as with log.Print)
+	Log(msg string)
+
+	// SecurityError prints the given security error log message.
+	// The Conn returns ErrSecurity from any operation that invokes SecurityError,
+	// but the return value is mainly for testing. In a real program,
+	// SecurityError should typically print the message and call log.Fatal or os.Exit.
+	SecurityError(msg string)
 }
 
-var height = flag.Int("h", 8, "tile height")
-var vflag = flag.Bool("v", false, "enable verbose output")
-var url = flag.String("u", "", "url to notary (overriding name)")
+// ErrWriteConflict signals a write conflict during Client.WriteConfig.
+var ErrWriteConflict = errors.New("write conflict")
 
-func main() {
-	log.SetPrefix("notecheck: ")
-	log.SetFlags(0)
+// ErrSecurity is returned by Conn operations that invoke Client.SecurityError.
+var ErrSecurity = errors.New("security error: misbehaving server")
 
-	flag.Usage = usage
-	flag.Parse()
-	if flag.NArg() < 2 {
-		usage()
+// A Conn is a client connection to a go.sum database.
+// All the methods are safe for simultaneous use by multiple goroutines.
+type Conn struct {
+	client Client // client-provided external world
+
+	// one-time initialized data
+	initOnce   sync.Once
+	initErr    error          // init error, if any
+	name       string         // name of accepted verifier
+	url        string         // url of server (usually https://name)
+	verifiers  note.Verifiers // accepted verifiers (just one, but Verifiers for note.Open)
+	tileReader tileReader
+	tileHeight int
+
+	record    parCache // cache of record lookup, keyed by path@vers
+	tileCache parCache // cache of tile from client.ReadCache, keyed by tile
+	tileFetch parCache // cache of tile from client.GetURL, keyed by tile
+
+	latestMu  sync.Mutex
+	latest    tlog.Tree // latest known tree head
+	latestMsg []byte    // encoded signed note for latest
+
+	tileSavedMu sync.Mutex
+	tileSaved   map[tlog.Tile]bool // which tiles have been saved using c.client.WriteCache already
+}
+
+// NewConn returns a new Conn using the given Client.
+func NewConn(client Client) *Conn {
+	return &Conn{
+		client: client,
 	}
+}
 
-	vkey := flag.Arg(0)
-	verifier, err := note.NewVerifier(vkey)
-	if err != nil {
-		log.Fatal(err)
-	}
-	if *url == "" {
-		*url = "https://" + verifier.Name()
-	}
+// init initiailzes the conn (if not already initialized)
+// and returns any initialization error.
+func (c *Conn) init() error {
+	c.initOnce.Do(c.initWork)
+	return c.initErr
+}
 
-	// TODO(rsc): Load initial db.latest, db.latestNote from on-disk cache.
-	db := &GoSumDB{
-		url:       *url,
-		verifiers: note.VerifierList(verifier),
-	}
-	db.httpClient.Timeout = 1 * time.Minute
-	db.tileReader.db = db
-	db.tileReader.url = db.url + "/"
-
-	for _, arg := range flag.Args()[1:] {
-		data, err := ioutil.ReadFile(arg)
-		if err != nil {
-			log.Fatal(err)
+// initWork does the actual initialization work.
+func (c *Conn) initWork() {
+	defer func() {
+		if c.initErr != nil {
+			c.initErr = fmt.Errorf("initializing sumweb.Conn: %v", c.initErr)
 		}
-		log.SetPrefix("notecheck: " + arg + ": ")
-		checkGoSum(db, data)
-		log.SetPrefix("notecheck: ")
-	}
-}
+	}()
 
-func checkGoSum(db *GoSumDB, data []byte) {
-	lines := strings.Split(string(data), "\n")
-	if lines[len(lines)-1] != "" {
-		log.Printf("error: final line missing newline")
+	c.tileReader.c = c
+	if c.tileHeight == 0 {
+		c.tileHeight = 8
+	}
+	c.tileSaved = make(map[tlog.Tile]bool)
+
+	vkey, err := c.client.ReadConfig("key")
+	if err != nil {
+		c.initErr = err
 		return
 	}
-	// TODO(rsc): This assumes that the /go.mod and the whole-tree hashes
-	// always appear together in a go.sum.
-	// Sometimes the /go.mod can appear alone.
-	// The code needs to be updated to handle that case.
-	lines = lines[:len(lines)-1]
-	if len(lines)%2 != 0 {
-		log.Printf("error: odd number of lines")
+	lines := strings.Split(string(vkey), "\n")
+	verifier, err := note.NewVerifier(strings.TrimSpace(lines[0]))
+	if err != nil {
+		c.initErr = err
+		return
 	}
-	for i := 0; i+2 <= len(lines); i += 2 {
-		f1 := strings.Fields(lines[i])
-		f2 := strings.Fields(lines[i+1])
-		if len(f1) != 3 || len(f2) != 3 || f1[0] != f2[0] || f1[1]+"/go.mod" != f2[1] {
-			log.Printf("error: bad line pair:\n\t%s\t%s", lines[i], lines[i+1])
-			continue
-		}
+	c.verifiers = note.VerifierList(verifier)
+	c.name = verifier.Name()
+	c.url = "https://" + c.name
+	if len(lines) >= 2 && lines[1] != "" {
+		c.url = strings.TrimRight(lines[1], "/")
+	}
 
-		dbLines, err := db.Lookup(f1[0], f1[1])
-		if err != nil {
-			log.Printf("%s@%s: %v", f1[0], f1[1], err)
-			continue
-		}
-
-		if strings.Join(lines[i:i+2], "\n") != strings.Join(dbLines, "\n") {
-			log.Printf("%s@%s: invalid go.sum entries:\ngo.sum:\n\t%s\nsum.golang.org:\n\t%s", f1[0], f1[1], strings.Join(lines[i:i+2], "\n\t"), strings.Join(dbLines, "\n\t"))
-		}
+	data, err := c.client.ReadConfig(c.name + "/latest")
+	if err != nil {
+		c.initErr = err
+		return
+	}
+	if err := c.mergeLatest(data); err != nil {
+		c.initErr = err
+		return
 	}
 }
 
-// A GoSumDB is a client for a go.sum database.
-type GoSumDB struct {
-	url        string         // root url of database, without trailing slash
-	verifiers  note.Verifiers // accepted verifiers for signed trees
-	tileReader tileReader     // tlog.TileReader implementation
-	httpCache  parCache
-	httpClient http.Client
-
-	// latest accepted tree head
-	mu         sync.Mutex
-	latest     tlog.Tree
-	latestNote []byte // signed note
-}
-
-// parCache is a minimal simulation of cmd/go's par.Cache.
-// When this code moves into cmd/go, it should use the real par.Cache
-type parCache struct {
-}
-
-func (c *parCache) Do(key interface{}, f func() interface{}) interface{} {
-	return f()
+// SetTileHeight sets the tile height for the Conn.
+// Any call to SetTileHeight must happen before the first call to Lookup.
+// If SetTileHeight is not called, the Conn defaults to tile height 8.
+func (c *Conn) SetTileHeight(height int) {
+	c.tileHeight = height
 }
 
 // Lookup returns the go.sum lines for the given module path and version.
-func (db *GoSumDB) Lookup(path, vers string) ([]string, error) {
-	// TODO(rsc): !-encode the path.
-	data, err := db.httpGet(db.url + "/lookup/" + path + "@" + vers)
-	if err != nil {
+func (c *Conn) Lookup(path, vers string) (lines []string, err error) {
+	defer func() {
+		if err != nil {
+			err = fmt.Errorf("%s@%s: %v", path, vers, err)
+		}
+	}()
+
+	if err := c.init(); err != nil {
 		return nil, err
 	}
 
-	id, text, treeMsg, err := tlog.ParseRecord(data)
+	// Prepare encoded cache filename / URL.
+	epath, err := encodePath(path)
 	if err != nil {
-		return nil, fmt.Errorf("%s@%s: %v", path, vers, err)
+		return nil, err
 	}
-	if err := db.updateLatest(treeMsg); err != nil {
-		return nil, fmt.Errorf("%s@%s: %v", path, vers, err)
+	evers, err := encodeVersion(strings.TrimSuffix(vers, "/go.mod"))
+	if err != nil {
+		return nil, err
 	}
-	if err := db.checkRecord(id, text); err != nil {
-		return nil, fmt.Errorf("%s@%s: %v", path, vers, err)
+	file := c.name + "/lookup/" + epath + "@" + evers
+	url := c.url + "/lookup/" + epath + "@" + evers
+
+	// Fetch the data.
+	// The lookupCache avoids redundant ReadCache/GetURL operations
+	// (especially since go.sum lines tend to come in pairs for a given
+	// path and version) and also avoids having multiple of the same
+	// request in flight at once.
+	type cached struct {
+		data []byte
+		err  error
+	}
+	result := c.record.Do(file, func() interface{} {
+		// Try the on-disk cache, or else get from web.
+		writeCache := false
+		data, err := c.client.ReadCache(file)
+		if err != nil {
+			data, err = c.client.GetURL(url)
+			if err != nil {
+				return cached{nil, err}
+			}
+			writeCache = true
+		}
+
+		// Validate the record before using it for anything.
+		id, text, treeMsg, err := tlog.ParseRecord(data)
+		if err != nil {
+			return cached{nil, err}
+		}
+		if err := c.mergeLatest(treeMsg); err != nil {
+			return cached{nil, err}
+		}
+		if err := c.checkRecord(id, text); err != nil {
+			return cached{nil, err}
+		}
+
+		// Now that we've validated the record,
+		// save it to the on-disk cache (unless that's where it came from).
+		if writeCache {
+			c.client.WriteCache(file, data)
+		}
+
+		return cached{data, nil}
+	}).(cached)
+	if result.err != nil {
+		return nil, result.err
 	}
 
+	// Extract the lines for the specific version we want
+	// (with or without /go.mod).
 	prefix := path + " " + vers + " "
-	prefixGoMod := path + " " + vers + "/go.mod "
 	var hashes []string
-	for _, line := range strings.Split(string(text), "\n") {
-		if strings.HasPrefix(line, prefix) || strings.HasPrefix(line, prefixGoMod) {
+	for _, line := range strings.Split(string(result.data), "\n") {
+		if strings.HasPrefix(line, prefix) {
 			hashes = append(hashes, line)
 		}
 	}
 	return hashes, nil
 }
 
-// updateLatest updates db's idea of the latest tree head
-// to incorporate the signed tree head in msg.
-// If msg is before the current latest tree head,
-// updateLatest still checks that it fits into the known timeline.
-// updateLatest returns an error for non-malicious problems.
-// If it detects a fork in the tree history, it prints a detailed
-// message and calls log.Fatal.
-func (db *GoSumDB) updateLatest(msg []byte) error {
-	if len(msg) == 0 {
+// mergeLatest merges the tree head in msg
+// with the Conn's current latest tree head,
+// ensuring the result is a consistent timeline.
+// If the result is inconsistent, mergeLatest calls c.client.Fatal
+// with a detailed security error message and then
+// (only if c.client.Fatal does not exit the program) returns ErrSecurity.
+// If the Conn's current latest tree head moves forward,
+// mergeLatest updates the underlying configuration file as well,
+// taking care to merge any independent updates to that configuration.
+func (c *Conn) mergeLatest(msg []byte) error {
+	// Merge msg into our in-memory copy of the latest tree head.
+	when, err := c.mergeLatestMem(msg)
+	if err != nil {
+		return err
+	}
+	if when <= 0 {
+		// msg matched our present or was in the past.
+		// No change to our present, so no update of config file.
 		return nil
 	}
-	note, err := note.Open(msg, db.verifiers)
+
+	// Flush our extended timeline back out to the configuration file.
+	// If the configuration file has been updated in the interim,
+	// we need to merge any updates made there as well.
+	// Note that writeConfig is an atomic compare-and-swap.
+	for {
+		msg, err := c.client.ReadConfig(c.name + "/latest")
+		if err != nil {
+			return err
+		}
+		when, err := c.mergeLatestMem(msg)
+		if err != nil {
+			return err
+		}
+		if when >= 0 {
+			// msg matched our present or was from the future,
+			// and now our in-memory copy matches.
+			return nil
+		}
+
+		// msg (== config) is in the past, so we need to update it.
+		c.latestMu.Lock()
+		latestMsg := c.latestMsg
+		c.latestMu.Unlock()
+		if err := c.client.WriteConfig(c.name+"/latest", msg, latestMsg); err != ErrWriteConflict {
+			// Success or a non-write-conflict error.
+			return err
+		}
+	}
+}
+
+// mergeLatestMem is like mergeLatest but is only concerned with
+// updating the in-memory copy of the latest tree head (c.latest)
+// not the configuration file.
+// The when result explains when msg happened relative to our
+// previous idea of c.latest:
+// when == -1 means msg was from before c.latest,
+// when == 0 means msg was exactly c.latest, and
+// when == +1 means msg was from after c.latest, which has now been updated.
+func (c *Conn) mergeLatestMem(msg []byte) (when int, err error) {
+	if len(msg) == 0 {
+		// Accept empty msg as the unsigned, empty timeline.
+		c.latestMu.Lock()
+		latest := c.latest
+		c.latestMu.Unlock()
+		if latest.N == 0 {
+			return 0, nil
+		}
+		return -1, nil
+	}
+
+	note, err := note.Open(msg, c.verifiers)
 	if err != nil {
-		return fmt.Errorf("reading tree note: %v\nnote:\n%s", err, msg)
+		return 0, fmt.Errorf("reading tree note: %v\nnote:\n%s", err, msg)
 	}
 	tree, err := tlog.ParseTree([]byte(note.Text))
 	if err != nil {
-		return fmt.Errorf("reading tree: %v\ntree:\n%s", err, note.Text)
+		return 0, fmt.Errorf("reading tree: %v\ntree:\n%s", err, note.Text)
 	}
 
-Update:
+	// Other lookups may be calling mergeLatest with other heads,
+	// so c.latest is changing underfoot. We don't want to hold the
+	// c.mu lock during tile fetches, so loop trying to update c.latest.
+	c.latestMu.Lock()
+	latest := c.latest
+	latestMsg := c.latestMsg
+	c.latestMu.Unlock()
+
 	for {
-		db.mu.Lock()
-		latest := db.latest
-		latestNote := db.latestNote
-		db.mu.Unlock()
-
-		switch {
-		case tree.N <= latest.N:
-			return db.checkTrees(tree, msg, latest, latestNote)
-
-		case tree.N > latest.N:
-			if err := db.checkTrees(latest, latestNote, tree, msg); err != nil {
-				return err
+		// If the tree head looks old, check that it is on our timeline.
+		if tree.N <= latest.N {
+			if err := c.checkTrees(tree, msg, latest, latestMsg); err != nil {
+				return 0, err
 			}
-			db.mu.Lock()
-			if db.latest != latest {
-				if db.latest.N > latest.N {
-					db.mu.Unlock()
-					continue Update
-				}
-				log.Fatalf("go.sum database changed underfoot:\n\t%v ->\n\t%v", latest, db.latest)
+			if tree.N < latest.N {
+				return -1, nil
 			}
-			db.latest = tree
-			db.latestNote = msg
-			db.mu.Unlock()
-			return nil
+			return 0, nil
+		}
+
+		// The tree head looks new. Check that we are on its timeline and try to move our timeline forward.
+		if err := c.checkTrees(latest, latestMsg, tree, msg); err != nil {
+			return 0, err
+		}
+
+		// Install our msg if possible.
+		// Otherwise we will go around again.
+		c.latestMu.Lock()
+		installed := false
+		if c.latest == latest {
+			installed = true
+			c.latest = tree
+			c.latestMsg = msg
+		} else {
+			latest = c.latest
+			latestMsg = c.latestMsg
+		}
+		c.latestMu.Unlock()
+
+		if installed {
+			return +1, nil
 		}
 	}
 }
@@ -225,10 +369,13 @@
 // If an error occurs, such as malformed data or a network problem, checkTrees returns that error.
 // If on the other hand checkTrees finds evidence of misbehavior, it prepares a detailed
 // message and calls log.Fatal.
-func (db *GoSumDB) checkTrees(older tlog.Tree, olderNote []byte, newer tlog.Tree, newerNote []byte) error {
-	thr := tlog.TileHashReader(newer, &db.tileReader)
+func (c *Conn) checkTrees(older tlog.Tree, olderNote []byte, newer tlog.Tree, newerNote []byte) error {
+	thr := tlog.TileHashReader(newer, &c.tileReader)
 	h, err := tlog.TreeHash(older.N, thr)
 	if err != nil {
+		if older.N == newer.N {
+			return fmt.Errorf("checking tree#%d: %v", older.N, err)
+		}
 		return fmt.Errorf("checking tree#%d against tree#%d: %v", older.N, newer.N, err)
 	}
 	if h == older.Hash {
@@ -243,8 +390,8 @@
 	indent := func(b []byte) []byte {
 		return bytes.Replace(b, []byte("\n"), []byte("\n\t"), -1)
 	}
-	fmt.Fprintf(&buf, "old database:\n\t%v\n", indent(olderNote))
-	fmt.Fprintf(&buf, "new database:\n\t%v\n", indent(newerNote))
+	fmt.Fprintf(&buf, "old database:\n\t%s\n", indent(olderNote))
+	fmt.Fprintf(&buf, "new database:\n\t%s\n", indent(newerNote))
 
 	// The notes alone are not enough to prove the inconsistency.
 	// We also need to show that the newer note's tree hash for older.N
@@ -266,20 +413,20 @@
 			fmt.Fprintf(&buf, "\n\t%v", h)
 		}
 	}
-	log.Fatalf("%v", buf.String())
-	panic("not reached")
+	c.client.SecurityError(buf.String())
+	return ErrSecurity
 }
 
 // checkRecord checks that record #id's hash matches data.
-func (db *GoSumDB) checkRecord(id int64, data []byte) error {
-	db.mu.Lock()
-	tree := db.latest
-	db.mu.Unlock()
+func (c *Conn) checkRecord(id int64, data []byte) error {
+	c.latestMu.Lock()
+	latest := c.latest
+	c.latestMu.Unlock()
 
-	if id >= tree.N {
-		return fmt.Errorf("cannot validate record %d in tree of size %d", id, tree.N)
+	if id >= latest.N {
+		return fmt.Errorf("cannot validate record %d in tree of size %d", id, latest.N)
 	}
-	hashes, err := tlog.TileHashReader(tree, &db.tileReader).ReadHashes([]int64{tlog.StoredHashIndex(0, id)})
+	hashes, err := tlog.TileHashReader(latest, &c.tileReader).ReadHashes([]int64{tlog.StoredHashIndex(0, id)})
 	if err != nil {
 		return err
 	}
@@ -289,59 +436,31 @@
 	return fmt.Errorf("cannot authenticate record data in server response")
 }
 
+// tileReader is a *Conn wrapper that implements tlog.TileReader.
+// The separate type avoids exposing the ReadTiles and SaveTiles
+// methods on Conn itself.
 type tileReader struct {
-	url     string
-	cache   map[tlog.Tile][]byte
-	cacheMu sync.Mutex
-	db      *GoSumDB
+	c *Conn
 }
 
 func (r *tileReader) Height() int {
-	return *height
+	return r.c.tileHeight
 }
 
-func (r *tileReader) SaveTiles(tiles []tlog.Tile, data [][]byte) {
-	// TODO(rsc): On-disk cache in GOPATH.
-}
-
+// ReadTiles reads and returns the requested tiles,
+// either from the on-disk cache or the server.
 func (r *tileReader) ReadTiles(tiles []tlog.Tile) ([][]byte, error) {
-	// TODO(rsc): Look in on-disk cache in GOPATH.
-
-	var wg sync.WaitGroup
-	out := make([][]byte, len(tiles))
+	// Read all the tiles in parallel.
+	data := make([][]byte, len(tiles))
 	errs := make([]error, len(tiles))
-	r.cacheMu.Lock()
-	if r.cache == nil {
-		r.cache = make(map[tlog.Tile][]byte)
-	}
+	var wg sync.WaitGroup
 	for i, tile := range tiles {
-		if data := r.cache[tile]; data != nil {
-			out[i] = data
-			continue
-		}
 		wg.Add(1)
 		go func(i int, tile tlog.Tile) {
 			defer wg.Done()
-			data, err := r.db.httpGet(r.url + tile.Path())
-			if err != nil && tile.W != 1<<uint(tile.H) {
-				fullTile := tile
-				fullTile.W = 1 << uint(tile.H)
-				if fullData, err1 := r.db.httpGet(r.url + fullTile.Path()); err1 == nil {
-					data = fullData[:tile.W*tlog.HashSize]
-					err = nil
-				}
-			}
-			if err != nil {
-				errs[i] = err
-				return
-			}
-			r.cacheMu.Lock()
-			r.cache[tile] = data
-			r.cacheMu.Unlock()
-			out[i] = data
+			data[i], errs[i] = r.c.readTile(tile)
 		}(i, tile)
 	}
-	r.cacheMu.Unlock()
 	wg.Wait()
 
 	for _, err := range errs {
@@ -350,34 +469,112 @@
 		}
 	}
 
-	return out, nil
+	return data, nil
 }
 
-func (db *GoSumDB) httpGet(url string) ([]byte, error) {
+// tileCacheKey returns the cache key for the tile.
+func (c *Conn) tileCacheKey(tile tlog.Tile) string {
+	return c.name + "/" + tile.Path()
+}
+
+// tileURL returns the URL for the tile.
+func (c *Conn) tileURL(tile tlog.Tile) string {
+	return c.url + "/" + tile.Path()
+}
+
+// readTile reads a single tile, either from the on-disk cache or the server.
+func (c *Conn) readTile(tile tlog.Tile) ([]byte, error) {
 	type cached struct {
 		data []byte
 		err  error
 	}
 
-	c := db.httpCache.Do(url, func() interface{} {
-		start := time.Now()
-		resp, err := db.httpClient.Get(url)
-		if err != nil {
-			return cached{nil, err}
-		}
-		defer resp.Body.Close()
-		if resp.StatusCode != 200 {
-			return cached{nil, fmt.Errorf("GET %v: %v", url, resp.Status)}
-		}
-		data, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
-		if err != nil {
-			return cached{nil, err}
-		}
-		if *vflag {
-			fmt.Fprintf(os.Stderr, "%.3fs %s\n", time.Since(start).Seconds(), url)
-		}
-		return cached{data, nil}
+	// Try the requested tile in on-disk cache.
+	result := c.tileCache.Do(tile, func() interface{} {
+		data, err := c.client.ReadCache(c.tileCacheKey(tile))
+		return cached{data, err}
 	}).(cached)
+	if result.err == nil {
+		c.markTileSaved(tile)
+		return result.data, nil
+	}
 
-	return c.data, c.err
+	// Try the full tile in on-disk cache (if requested tile not already full).
+	// We only save authenticated tiles to the on-disk cache,
+	// so rederiving the prefix is not going to cause spurious validation errors.
+	full := tile
+	full.W = 1 << tile.H
+	if tile != full {
+		result := c.tileCache.Do(full, func() interface{} {
+			data, err := c.client.ReadCache(c.tileCacheKey(full))
+			return cached{data, err}
+		}).(cached)
+		if result.err == nil {
+			c.markTileSaved(tile) // don't save tile later; we already have full
+			return result.data[:len(result.data)/full.W*tile.W], nil
+		}
+	}
+
+	// Try requested tile from server.
+	result = c.tileFetch.Do(tile, func() interface{} {
+		data, err := c.client.GetURL(c.tileURL(tile))
+		return cached{data, err}
+	}).(cached)
+	if result.err == nil {
+		return result.data, nil
+	}
+
+	// Try full tile on server.
+	// If the partial tile does not exist, it should be because
+	// the tile has been completed and only the complete one
+	// is available.
+	if tile != full {
+		result := c.tileFetch.Do(tile, func() interface{} {
+			data, err := c.client.GetURL(c.tileURL(full))
+			return cached{data, err}
+		}).(cached)
+		if result.err == nil {
+			// Note: We could save the full tile in the on-disk cache here,
+			// but we don't know if it is valid yet, and we will only find out
+			// about the partial data, not the full data. So let SaveTiles
+			// save the partial tile, and we'll just refetch the full tile later
+			// once we can validate more (or all) of it.
+			return result.data[:len(result.data)/full.W*tile.W], nil
+		}
+	}
+
+	// Nothing worked.
+	// Return the error from the server fetch for the requested (not full) tile.
+	return nil, result.err
+}
+
+// markTileSaved records that tile is already present in the on-disk cache,
+// so that a future SaveTiles for that tile can be ignored.
+func (c *Conn) markTileSaved(tile tlog.Tile) {
+	c.tileSavedMu.Lock()
+	c.tileSaved[tile] = true
+	c.tileSavedMu.Unlock()
+}
+
+// SaveTiles saves the now validated tiles.
+func (r *tileReader) SaveTiles(tiles []tlog.Tile, data [][]byte) {
+	c := r.c
+
+	// Determine which tiles need saving.
+	// (Tiles that came from the cache need not be saved back.)
+	save := make([]bool, len(tiles))
+	c.tileSavedMu.Lock()
+	for i, tile := range tiles {
+		if !c.tileSaved[tile] {
+			save[i] = true
+			c.tileSaved[tile] = true
+		}
+	}
+	c.tileSavedMu.Unlock()
+
+	for i, tile := range tiles {
+		if save[i] {
+			c.client.WriteCache(c.name+"/"+tile.Path(), data[i])
+		}
+	}
 }
diff --git a/notary/internal/sumweb/client_test.go b/notary/internal/sumweb/client_test.go
new file mode 100644
index 0000000..47bc2f5
--- /dev/null
+++ b/notary/internal/sumweb/client_test.go
@@ -0,0 +1,426 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sumweb
+
+import (
+	"bytes"
+	"fmt"
+	"strings"
+	"sync"
+	"testing"
+
+	"golang.org/x/exp/notary/internal/note"
+	"golang.org/x/exp/notary/internal/tlog"
+)
+
+const (
+	testName        = "localhost.localdev/sumdb"
+	testVerifierKey = "localhost.localdev/sumdb+00000c67+AcTrnkbUA+TU4heY3hkjiSES/DSQniBqIeQ/YppAUtK6"
+	testSignerKey   = "PRIVATE+KEY+localhost.localdev/sumdb+00000c67+AXu6+oaVaOYuQOFrf1V59JK1owcFlJcHwwXHDfDGxSPk"
+)
+
+func TestConnLookup(t *testing.T) {
+	tc := newTestClient(t)
+	tc.mustHaveLatest(1)
+
+	// Basic lookup.
+	tc.mustLookup("rsc.io/sampler", "v1.3.0", "rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=")
+	tc.mustHaveLatest(3)
+
+	// Everything should now be cached, both for the original package and its /go.mod.
+	tc.getOK = false
+	tc.mustLookup("rsc.io/sampler", "v1.3.0", "rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=")
+	tc.mustLookup("rsc.io/sampler", "v1.3.0/go.mod", "rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=")
+	tc.mustHaveLatest(3)
+	tc.getOK = true
+	tc.getTileOK = false // the cache has what we need
+
+	// Lookup with multiple returned lines.
+	tc.mustLookup("rsc.io/quote", "v1.5.2", "rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=\nrsc.io/quote v1.5.2 h2:xyzzy")
+	tc.mustHaveLatest(3)
+
+	// Lookup with need for !-encoding.
+	// rsc.io/Quote is the only record written after rsc.io/samper,
+	// so it is the only one that should need more tiles.
+	tc.getTileOK = true
+	tc.mustLookup("rsc.io/Quote", "v1.5.2", "rsc.io/Quote v1.5.2 h1:uppercase!=")
+	tc.mustHaveLatest(4)
+}
+
+func TestConnBadTiles(t *testing.T) {
+	tc := newTestClient(t)
+
+	flipBits := func() {
+		for url, data := range tc.get {
+			if strings.Contains(url, "/tile/") {
+				for i := range data {
+					data[i] ^= 0x80
+				}
+			}
+		}
+	}
+
+	// Bad tiles in initial download.
+	tc.mustHaveLatest(1)
+	flipBits()
+	_, err := tc.conn.Lookup("rsc.io/sampler", "v1.3.0")
+	tc.mustError(err, "rsc.io/sampler@v1.3.0: initializing sumweb.Conn: checking tree#1: downloaded inconsistent tile")
+	flipBits()
+	tc.newConn()
+	tc.mustLookup("rsc.io/sampler", "v1.3.0", "rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=")
+
+	// Bad tiles after initial download.
+	flipBits()
+	_, err = tc.conn.Lookup("rsc.io/Quote", "v1.5.2")
+	tc.mustError(err, "rsc.io/Quote@v1.5.2: checking tree#3 against tree#4: downloaded inconsistent tile")
+	flipBits()
+	tc.newConn()
+	tc.mustLookup("rsc.io/Quote", "v1.5.2", "rsc.io/Quote v1.5.2 h1:uppercase!=")
+
+	// Bad starting tree hash looks like bad tiles.
+	tc.newConn()
+	text := tlog.FormatTree(tlog.Tree{N: 1, Hash: tlog.Hash{}})
+	data, err := note.Sign(&note.Note{Text: string(text)}, tc.signer)
+	if err != nil {
+		tc.t.Fatal(err)
+	}
+	tc.config[testName+"/latest"] = data
+	_, err = tc.conn.Lookup("rsc.io/sampler", "v1.3.0")
+	tc.mustError(err, "rsc.io/sampler@v1.3.0: initializing sumweb.Conn: checking tree#1: downloaded inconsistent tile")
+}
+
+func TestConnFork(t *testing.T) {
+	tc := newTestClient(t)
+	tc2 := tc.fork()
+
+	tc.addRecord("rsc.io/pkg1@v1.5.2", `rsc.io/pkg1 v1.5.2 h1:hash!=
+`)
+	tc.addRecord("rsc.io/pkg1@v1.5.4", `rsc.io/pkg1 v1.5.4 h1:hash!=
+`)
+	tc.mustLookup("rsc.io/pkg1", "v1.5.2", "rsc.io/pkg1 v1.5.2 h1:hash!=")
+
+	tc2.addRecord("rsc.io/pkg1@v1.5.3", `rsc.io/pkg1 v1.5.3 h1:hash!=
+`)
+	tc2.addRecord("rsc.io/pkg1@v1.5.4", `rsc.io/pkg1 v1.5.4 h1:hash!=
+`)
+	tc2.mustLookup("rsc.io/pkg1", "v1.5.4", "rsc.io/pkg1 v1.5.4 h1:hash!=")
+
+	key := "https://" + testName + "/lookup/rsc.io/pkg1@v1.5.2"
+	tc2.get[key] = tc.get[key]
+	_, err := tc2.conn.Lookup("rsc.io/pkg1", "v1.5.2")
+	tc2.mustError(err, ErrSecurity.Error())
+
+	/*
+	   SECURITY ERROR
+	   go.sum database server misbehavior detected!
+
+	   old database:
+	   	go.sum database tree!
+	   	5
+	   	nWzN20+pwMt62p7jbv1/NlN95ePTlHijabv5zO/s36w=
+
+	   	— localhost.localdev/sumdb AAAMZ5/2FVAdMH58kmnz/0h299pwyskEbzDzoa2/YaPdhvLya4YWDFQQxu2TQb5GpwAH4NdWnTwuhILafisyf3CNbgg=
+
+	   new database:
+	   	go.sum database tree
+	   	6
+	   	wc4SkQt52o5W2nQ8To2ARs+mWuUJjss+sdleoiqxMmM=
+
+	   	— localhost.localdev/sumdb AAAMZ6oRNswlEZ6ZZhxrCvgl1MBy+nusq4JU+TG6Fe2NihWLqOzb+y2c2kzRLoCr4tvw9o36ucQEnhc20e4nA4Qc/wc=
+
+	   proof of misbehavior:
+	   	T7i+H/8ER4nXOiw4Bj0koZOkGjkxoNvlI34GpvhHhQg=
+	   	Nsuejv72de9hYNM5bqFv8rv3gm3zJQwv/DT/WNbLDLA=
+	   	mOmqqZ1aI/lzS94oq/JSbj7pD8Rv9S+xDyi12BtVSHo=
+	   	/7Aw5jVSMM9sFjQhaMg+iiDYPMk6decH7QLOGrL9Lx0=
+	*/
+
+	wants := []string{
+		"SECURITY ERROR",
+		"go.sum database server misbehavior detected!",
+		"old database:\n\tgo.sum database tree\n\t5\n",
+		"— localhost.localdev/sumdb AAAMZ5/2FVAd",
+		"new database:\n\tgo.sum database tree\n\t6\n",
+		"— localhost.localdev/sumdb AAAMZ6oRNswl",
+		"proof of misbehavior:\n\tT7i+H/8ER4nXOiw4Bj0k",
+	}
+	text := tc2.security.String()
+	for _, want := range wants {
+		if !strings.Contains(text, want) {
+			t.Fatalf("cannot find %q in security text:\n%s", want, text)
+		}
+	}
+}
+
+// A testClient is a self-contained client-side testing environment.
+type testClient struct {
+	t          *testing.T // active test
+	conn       *Conn      // conn being tested
+	tileHeight int        // tile height to use (default 2)
+	getOK      bool       // should tc.GetURL succeed?
+	getTileOK  bool       // should tc.GetURL of tiles succeed?
+	treeSize   int64
+	hashes     []tlog.Hash
+	get        map[string][]byte
+	signer     note.Signer
+
+	// mu protects config, cache, log, security
+	// during concurrent use of the exported methods
+	// by the conn itself (testClient is the Conn's Client,
+	// and the Client methods can both read and write these fields).
+	// Unexported methods invoked directly by the test
+	// (for example, addRecord) need not hold the mutex:
+	// for proper test execution those methods should only
+	// be called when the Conn is idle and not using its Client.
+	// Not holding the mutex in those methods ensures
+	// that if a mistake is made, go test -race will report it.
+	// (Holding the mutex would eliminate the race report but
+	// not the underlying problem.)
+	// Similarly, the get map is not protected by the mutex,
+	// because the Client methods only read it.
+	mu       sync.Mutex // prot
+	config   map[string][]byte
+	cache    map[string][]byte
+	security bytes.Buffer
+}
+
+// newTestClient returns a new testClient that will call t.Fatal on error
+// and has a few records already available on the remote server.
+func newTestClient(t *testing.T) *testClient {
+	tc := &testClient{
+		t:          t,
+		tileHeight: 2,
+		getOK:      true,
+		getTileOK:  true,
+		config:     make(map[string][]byte),
+		cache:      make(map[string][]byte),
+		get:        make(map[string][]byte),
+	}
+
+	tc.config["key"] = []byte(testVerifierKey + "\n")
+	var err error
+	tc.signer, err = note.NewSigner(testSignerKey)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	tc.newConn()
+
+	tc.addRecord("rsc.io/quote@v1.5.2", `rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=
+rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
+rsc.io/quote v1.5.2 h2:xyzzy
+`)
+
+	tc.addRecord("golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c", `golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8=
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+`)
+	tc.addRecord("rsc.io/sampler@v1.3.0", `rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
+`)
+	tc.config[testName+"/latest"] = tc.signTree(1)
+
+	tc.addRecord("rsc.io/!quote@v1.5.2", `rsc.io/Quote v1.5.2 h1:uppercase!=
+`)
+	return tc
+}
+
+// newConn resets the Conn associated with tc.
+// This clears any in-memory cache from the Conn
+// but not tc's on-disk cache.
+func (tc *testClient) newConn() {
+	tc.conn = NewConn(tc)
+	tc.conn.SetTileHeight(tc.tileHeight)
+}
+
+// mustLookup does a lookup for path@vers and checks that the lines that come back match want.
+func (tc *testClient) mustLookup(path, vers, want string) {
+	tc.t.Helper()
+	lines, err := tc.conn.Lookup(path, vers)
+	if err != nil {
+		tc.t.Fatal(err)
+	}
+	if strings.Join(lines, "\n") != want {
+		tc.t.Fatalf("Lookup(%q, %q):\n\t%s\nwant:\n\t%s", path, vers, strings.Join(lines, "\n\t"), strings.Replace(want, "\n", "\n\t", -1))
+	}
+}
+
+// mustHaveLatest checks that the on-disk configuration
+// for latest is a tree of size n.
+func (tc *testClient) mustHaveLatest(n int64) {
+	tc.t.Helper()
+
+	latest := tc.config[testName+"/latest"]
+	lines := strings.Split(string(latest), "\n")
+	if len(lines) < 2 || lines[1] != fmt.Sprint(n) {
+		tc.t.Fatalf("/latest should have tree %d, but has:\n%s", n, latest)
+	}
+}
+
+// mustError checks that err's error string contains the text.
+func (tc *testClient) mustError(err error, text string) {
+	tc.t.Helper()
+	if err == nil || !strings.Contains(err.Error(), text) {
+		tc.t.Fatalf("err = %v, want %q", err, text)
+	}
+}
+
+// fork returns a copy of tc.
+// Changes made to the new copy or to tc are not reflected in the other.
+func (tc *testClient) fork() *testClient {
+	tc2 := &testClient{
+		t:          tc.t,
+		getOK:      tc.getOK,
+		getTileOK:  tc.getTileOK,
+		tileHeight: tc.tileHeight,
+		treeSize:   tc.treeSize,
+		hashes:     append([]tlog.Hash{}, tc.hashes...),
+		signer:     tc.signer,
+		config:     copyMap(tc.config),
+		cache:      copyMap(tc.cache),
+		get:        copyMap(tc.get),
+	}
+	tc2.newConn()
+	return tc2
+}
+
+func copyMap(m map[string][]byte) map[string][]byte {
+	m2 := make(map[string][]byte)
+	for k, v := range m {
+		m2[k] = v
+	}
+	return m2
+}
+
+// ReadHashes is tc's implementation of tlog.HashReader, for use with
+// tlog.TreeHash and so on.
+func (tc *testClient) ReadHashes(indexes []int64) ([]tlog.Hash, error) {
+	var list []tlog.Hash
+	for _, id := range indexes {
+		list = append(list, tc.hashes[id])
+	}
+	return list, nil
+}
+
+// addRecord adds a log record using the given (!-encoded) key and data.
+func (tc *testClient) addRecord(key, data string) {
+	tc.t.Helper()
+
+	// Create record, add hashes to log tree.
+	id := tc.treeSize
+	tc.treeSize++
+	rec, err := tlog.FormatRecord(id, []byte(data))
+	if err != nil {
+		tc.t.Fatal(err)
+	}
+	hashes, err := tlog.StoredHashesForRecordHash(id, tlog.RecordHash([]byte(data)), tc)
+	if err != nil {
+		tc.t.Fatal(err)
+	}
+	tc.hashes = append(tc.hashes, hashes...)
+
+	// Create lookup result.
+	tc.get["https://"+testName+"/lookup/"+key] = append(rec, tc.signTree(tc.treeSize)...)
+
+	// Create new tiles.
+	tiles := tlog.NewTiles(tc.tileHeight, id, tc.treeSize)
+	for _, tile := range tiles {
+		data, err := tlog.ReadTileData(tile, tc)
+		if err != nil {
+			tc.t.Fatal(err)
+		}
+		tc.get["https://"+testName+"/"+tile.Path()] = data
+		// TODO delete old partial tiles
+	}
+}
+
+// signTree returns the signed head for the tree of the given size.
+func (tc *testClient) signTree(size int64) []byte {
+	h, err := tlog.TreeHash(size, tc)
+	if err != nil {
+		tc.t.Fatal(err)
+	}
+	text := tlog.FormatTree(tlog.Tree{N: size, Hash: h})
+	data, err := note.Sign(&note.Note{Text: string(text)}, tc.signer)
+	if err != nil {
+		tc.t.Fatal(err)
+	}
+	return data
+}
+
+// GetURL is for tc's implementation of Client.
+func (tc *testClient) GetURL(url string) ([]byte, error) {
+	// No mutex here because only the Client should be running
+	// and the Client cannot change tc.get.
+	if !tc.getOK {
+		return nil, fmt.Errorf("disallowed URL %s", url)
+	}
+	if strings.Contains(url, "/tile/") && !tc.getTileOK {
+		return nil, fmt.Errorf("disallowed Tile URL %s", url)
+	}
+
+	data, ok := tc.get[url]
+	if !ok {
+		return nil, fmt.Errorf("no URL %s", url)
+	}
+	return data, nil
+}
+
+// ReadConfig is for tc's implementation of Client.
+func (tc *testClient) ReadConfig(file string) ([]byte, error) {
+	tc.mu.Lock()
+	defer tc.mu.Unlock()
+
+	data, ok := tc.config[file]
+	if !ok {
+		return nil, fmt.Errorf("no config %s", file)
+	}
+	return data, nil
+}
+
+// WriteConfig is for tc's implementation of Client.
+func (tc *testClient) WriteConfig(file string, old, new []byte) error {
+	tc.mu.Lock()
+	defer tc.mu.Unlock()
+
+	data := tc.config[file]
+	if !bytes.Equal(old, data) {
+		return ErrWriteConflict
+	}
+	tc.config[file] = new
+	return nil
+}
+
+// ReadCache is for tc's implementation of Client.
+func (tc *testClient) ReadCache(file string) ([]byte, error) {
+	tc.mu.Lock()
+	defer tc.mu.Unlock()
+
+	data, ok := tc.cache[file]
+	if !ok {
+		return nil, fmt.Errorf("no cache %s", file)
+	}
+	return data, nil
+}
+
+// WriteCache is for tc's implementation of Client.
+func (tc *testClient) WriteCache(file string, data []byte) {
+	tc.mu.Lock()
+	defer tc.mu.Unlock()
+
+	tc.cache[file] = data
+}
+
+// Log is for tc's implementation of Client.
+func (tc *testClient) Log(msg string) {
+	tc.t.Log(msg)
+}
+
+// SecurityError is for tc's implementation of Client.
+func (tc *testClient) SecurityError(msg string) {
+	tc.mu.Lock()
+	defer tc.mu.Unlock()
+
+	fmt.Fprintf(&tc.security, "%s\n", strings.TrimRight(msg, "\n"))
+}
diff --git a/notary/internal/sumweb/server.go b/notary/internal/sumweb/server.go
index 2474b76..b529c55 100644
--- a/notary/internal/sumweb/server.go
+++ b/notary/internal/sumweb/server.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package sumweb implements the HTTP protocols for serving a go.sum database.
+// Package sumweb implements the HTTP protocols for serving or accessing a go.sum database.
 package sumweb
 
 import (
@@ -15,7 +15,9 @@
 	"golang.org/x/exp/notary/internal/tlog"
 )
 
-// Server is a connection to a go.sum database server.
+// A Server provides the external operations
+// (underlying database access and so on)
+// needed to implement the HTTP server Handler.
 type Server interface {
 	// NewContext returns the context to use for the request r.
 	NewContext(r *http.Request) (context.Context, error)
@@ -35,9 +37,9 @@
 	ReadTileData(ctx context.Context, t tlog.Tile) ([]byte, error)
 }
 
-// Handler is the go.sum database server handler,
+// A Handler is the go.sum database server handler,
 // which should be invoked to serve the paths listed in Paths.
-// The client is responsible for initializing Server.
+// The calling code is responsible for initializing Server.
 type Handler struct {
 	Server Server
 }
