Merge "rpc/stream/manager: Randomly select TCP connections to kill in order to not hang when the file descriptor limit of the process is reached."
diff --git a/cmd/gclogs/.api b/cmd/gclogs/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmd/gclogs/.api
diff --git a/cmd/gclogs/gclogs.go b/cmd/gclogs/gclogs.go
index 9160287..76cb946 100644
--- a/cmd/gclogs/gclogs.go
+++ b/cmd/gclogs/gclogs.go
@@ -44,6 +44,7 @@
 )
 
 func init() {
+	cmdline.HideGlobalFlagsExcept()
 	cmdGCLogs.Flags.DurationVar(&flagCutoff, "cutoff", 24*time.Hour, "The age cut-off for a log file to be considered for garbage collection.")
 	cmdGCLogs.Flags.StringVar(&flagProgname, "program", ".*", `A regular expression to apply to the program part of the log file name, e.g ".*test".`)
 	cmdGCLogs.Flags.BoolVar(&flagVerbose, "verbose", false, "If true, each deleted file is shown on stdout.")
diff --git a/cmd/mounttable/.api b/cmd/mounttable/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmd/mounttable/.api
diff --git a/cmd/mounttable/doc.go b/cmd/mounttable/doc.go
index 7d653ee..562e14d 100644
--- a/cmd/mounttable/doc.go
+++ b/cmd/mounttable/doc.go
@@ -17,9 +17,11 @@
    unmount     removes server <name> from the mount table
    resolvestep takes the next step in resolving a name.
    help        Display help for commands or topics
-Run "mounttable help [command]" for command usage.
 
 The global flags are:
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+   local namespace root; can be repeated to provided multiple roots
+
  -alsologtostderr=true
    log to standard error as well as files
  -log_backtrace_at=:0
@@ -38,8 +40,6 @@
    directory to use for storing security credentials
  -v23.i18n-catalogue=
    18n catalogue files to load, comma separated
- -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
-   local namespace root; can be repeated to provided multiple roots
  -v23.proxy=
    object name of proxy service to use to export services across network
    boundaries
@@ -59,7 +59,7 @@
  -vmodule=
    comma-separated list of pattern=N settings for file-filtered logging
 
-Mounttable Glob
+Mounttable glob
 
 returns all matching entries in the mount table
 
@@ -70,7 +70,7 @@
 <pattern> is a glob pattern that is matched against all the entries below the
 specified mount name.
 
-Mounttable Mount
+Mounttable mount
 
 Mounts a server <name> onto a mount table
 
@@ -87,7 +87,7 @@
 [M|R] are mount options. M indicates that <name> is a mounttable. R indicates
 that existing entries should be removed.
 
-Mounttable Unmount
+Mounttable unmount
 
 removes server <name> from the mount table
 
@@ -97,7 +97,7 @@
 <mount name> is a mount name on a mount table. <name> is the rooted object name
 of the server.
 
-Mounttable Resolvestep
+Mounttable resolvestep
 
 takes the next step in resolving a name.
 
@@ -106,7 +106,7 @@
 
 <mount name> is a mount name on a mount table.
 
-Mounttable Help
+Mounttable help
 
 Help with no args displays the usage of the parent command.
 
@@ -114,11 +114,10 @@
 
 "help ..." recursively displays help for all commands and topics.
 
-The output is formatted to a target width in runes.  The target width is
-determined by checking the environment variable CMDLINE_WIDTH, falling back on
-the terminal width from the OS, falling back on 80 chars.  By setting
-CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0 the width is unlimited, and
-if x == 0 or is unset one of the fallbacks is used.
+Output is formatted to a target width in runes, determined by checking the
+CMDLINE_WIDTH environment variable, falling back on the terminal width, falling
+back on 80 chars.  By setting CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0
+the width is unlimited, and if x == 0 or is unset one of the fallbacks is used.
 
 Usage:
    mounttable help [flags] [command/topic ...]
@@ -126,7 +125,11 @@
 [command/topic ...] optionally identifies a specific sub-command or help topic.
 
 The mounttable help flags are:
- -style=default
-   The formatting style for help output, either "default" or "godoc".
+ -style=compact
+   The formatting style for help output:
+      compact - Good for compact cmdline output.
+      full    - Good for cmdline output, shows all global flags.
+      godoc   - Good for godoc processing.
+   Override the default by setting the CMDLINE_STYLE environment variable.
 */
 package main
diff --git a/cmd/mounttable/impl.go b/cmd/mounttable/impl.go
index 6b851e0..8be675e 100644
--- a/cmd/mounttable/impl.go
+++ b/cmd/mounttable/impl.go
@@ -7,6 +7,7 @@
 import (
 	"errors"
 	"fmt"
+	"regexp"
 	"time"
 
 	"v.io/v23"
@@ -15,11 +16,14 @@
 	"v.io/v23/options"
 	"v.io/v23/rpc"
 	"v.io/v23/security"
-
 	"v.io/x/lib/cmdline"
 	"v.io/x/lib/vlog"
 )
 
+func init() {
+	cmdline.HideGlobalFlagsExcept(regexp.MustCompile(`^v23\.namespace\.root$`))
+}
+
 var cmdGlob = &cmdline.Command{
 	Run:      runGlob,
 	Name:     "glob",
diff --git a/cmd/namespace/.api b/cmd/namespace/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmd/namespace/.api
diff --git a/cmd/namespace/doc.go b/cmd/namespace/doc.go
index 9e25dbc..2f82af3 100644
--- a/cmd/namespace/doc.go
+++ b/cmd/namespace/doc.go
@@ -25,9 +25,11 @@
    permissions Manipulates permissions on an entry in the namespace
    delete      Deletes a name from the namespace
    help        Display help for commands or topics
-Run "namespace help [command]" for command usage.
 
 The global flags are:
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+   local namespace root; can be repeated to provided multiple roots
+
  -alsologtostderr=true
    log to standard error as well as files
  -log_backtrace_at=:0
@@ -46,8 +48,6 @@
    directory to use for storing security credentials
  -v23.i18n-catalogue=
    18n catalogue files to load, comma separated
- -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
-   local namespace root; can be repeated to provided multiple roots
  -v23.proxy=
    object name of proxy service to use to export services across network
    boundaries
@@ -67,7 +67,7 @@
  -vmodule=
    comma-separated list of pattern=N settings for file-filtered logging
 
-Namespace Glob
+Namespace glob
 
 Returns all matching entries from the namespace.
 
@@ -81,7 +81,7 @@
  -l=false
    Long listing format.
 
-Namespace Mount
+Namespace mount
 
 Adds server <server> to the namespace with name <name>.
 
@@ -93,7 +93,7 @@
 followed by a unit suffix (s, m, h). A value of 0s represents an infinite
 duration.
 
-Namespace Unmount
+Namespace unmount
 
 Removes server <server> with name <name> from the namespace.
 
@@ -103,7 +103,7 @@
 <name> is the name to remove from the namespace. <server> is the object address
 of the server to remove.
 
-Namespace Resolve
+Namespace resolve
 
 Translates a object name to its object address(es).
 
@@ -117,7 +117,7 @@
    Insecure mode: May return results from untrusted servers and invoke Resolve
    on untrusted mounttables
 
-Namespace Resolvetomt
+Namespace resolvetomt
 
 Finds the address of the mounttable that holds an object name.
 
@@ -131,7 +131,7 @@
    Insecure mode: May return results from untrusted servers and invoke Resolve
    on untrusted mounttables
 
-Namespace Permissions
+Namespace permissions
 
 Commands to get and set the permissions on a name - controlling the blessing
 names required to resolve the name.
@@ -146,7 +146,7 @@
    get         Gets permissions on a mount name
    set         Sets permissions on a mount name
 
-Namespace Permissions Get
+Namespace permissions get
 
 Get retrieves the permissions on the usage of a name.
 
@@ -158,7 +158,7 @@
 
 <name> is a name in the namespace.
 
-Namespace Permissions Set
+Namespace permissions set
 
 Set replaces the permissions controlling usage of a mount name.
 
@@ -170,7 +170,7 @@
 <permissions> is the path to a file containing a JSON-encoded Permissions object
 (defined in v.io/v23/security/access/types.vdl), or "-" for STDIN.
 
-Namespace Delete
+Namespace delete
 
 Deletes a name from the namespace.
 
@@ -183,7 +183,7 @@
  -r=false
    Delete all children of the name in addition to the name itself.
 
-Namespace Help
+Namespace help
 
 Help with no args displays the usage of the parent command.
 
@@ -191,11 +191,10 @@
 
 "help ..." recursively displays help for all commands and topics.
 
-The output is formatted to a target width in runes.  The target width is
-determined by checking the environment variable CMDLINE_WIDTH, falling back on
-the terminal width from the OS, falling back on 80 chars.  By setting
-CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0 the width is unlimited, and
-if x == 0 or is unset one of the fallbacks is used.
+Output is formatted to a target width in runes, determined by checking the
+CMDLINE_WIDTH environment variable, falling back on the terminal width, falling
+back on 80 chars.  By setting CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0
+the width is unlimited, and if x == 0 or is unset one of the fallbacks is used.
 
 Usage:
    namespace help [flags] [command/topic ...]
@@ -203,7 +202,11 @@
 [command/topic ...] optionally identifies a specific sub-command or help topic.
 
 The namespace help flags are:
- -style=default
-   The formatting style for help output, either "default" or "godoc".
+ -style=compact
+   The formatting style for help output:
+      compact - Good for compact cmdline output.
+      full    - Good for cmdline output, shows all global flags.
+      godoc   - Good for godoc processing.
+   Override the default by setting the CMDLINE_STYLE environment variable.
 */
 package main
diff --git a/cmd/namespace/impl.go b/cmd/namespace/impl.go
index 8f65e8e..9abaee2 100644
--- a/cmd/namespace/impl.go
+++ b/cmd/namespace/impl.go
@@ -8,6 +8,7 @@
 	"encoding/json"
 	"fmt"
 	"os"
+	"regexp"
 	"sort"
 	"time"
 
@@ -21,6 +22,10 @@
 	"v.io/x/lib/vlog"
 )
 
+func init() {
+	cmdline.HideGlobalFlagsExcept(regexp.MustCompile(`^v23\.namespace\.root$`))
+}
+
 var (
 	flagLongGlob            bool
 	flagInsecureResolve     bool
diff --git a/cmd/principal/.api b/cmd/principal/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmd/principal/.api
diff --git a/cmd/principal/doc.go b/cmd/principal/doc.go
index 6ce390d..84f6ef4 100644
--- a/cmd/principal/doc.go
+++ b/cmd/principal/doc.go
@@ -29,7 +29,6 @@
    addtoroots    Add to the set of identity providers recognized by this
                  principal
    help          Display help for commands or topics
-Run "principal help [command]" for command usage.
 
 The global flags are:
  -alsologtostderr=true
@@ -76,7 +75,7 @@
  -vmodule=
    comma-separated list of pattern=N settings for file-filtered logging
 
-Principal Create
+Principal create
 
 Creates a new principal with a single self-blessed blessing and writes it out to
 the provided directory. The same directory can then be used to set the
@@ -96,7 +95,7 @@
  -overwrite=false
    If true, any existing principal data in the directory will be overwritten
 
-Principal Fork
+Principal fork
 
 Creates a new principal with a blessing from the principal specified by the
 environment that this tool is running in, and writes it out to the provided
@@ -130,7 +129,7 @@
  -with=
    Path to file containing blessing to extend
 
-Principal Seekblessings
+Principal seekblessings
 
 Seeks blessings from a web-based Vanadium blesser which requires the caller to
 first authenticate with Google using OAuth. Simply run the command to see what
@@ -162,7 +161,7 @@
    If true, the blessings obtained will be set as the default blessing in the
    store
 
-Principal Recvblessings
+Principal recvblessings
 
 Allow another principal (likely a remote process) to bless this one.
 
@@ -213,7 +212,7 @@
    If true, the blessings received will be set as the default blessing in the
    store
 
-Principal Dump
+Principal dump
 
 Prints out information about the principal specified by the environment that
 this tool is running in.
@@ -225,7 +224,7 @@
  -s=false
    If true, show only the default blessing names
 
-Principal Dumpblessings
+Principal dumpblessings
 
 Prints out information about the blessings (typically obtained from this tool)
 encoded in the provided file.
@@ -236,7 +235,7 @@
 <file> is the path to a file containing blessings typically obtained from this
 tool. - is used for STDIN.
 
-Principal Blessself
+Principal blessself
 
 Returns a blessing with name <name> and self-signed by the principal specified
 by the environment that this tool is running in. Optionally, the blessing can be
@@ -256,7 +255,7 @@
  -for=0
    Duration of blessing validity (zero implies no expiration)
 
-Principal Bless
+Principal bless
 
 Bless another principal.
 
@@ -316,7 +315,7 @@
  -with=
    Path to file containing blessing to extend
 
-Principal Set
+Principal set
 
 Commands to mutate the blessings of the principal.
 
@@ -330,7 +329,7 @@
    default     Set provided blessings as default
    forpeer     Set provided blessings for peer
 
-Principal Set Default
+Principal set default
 
 Sets the provided blessings as default in the BlessingStore specified by the
 environment that this tool is running in.
@@ -349,7 +348,7 @@
    If true, the root certificate of the blessing will be added to the
    principal's set of recognized root certificates
 
-Principal Set Forpeer
+Principal set forpeer
 
 Marks the provided blessings to be shared with the provided peers on the
 BlessingStore specified by the environment that this tool is running in.
@@ -377,7 +376,7 @@
    If true, the root certificate of the blessing will be added to the
    principal's set of recognized root certificates
 
-Principal Get
+Principal get
 
 Commands to inspect the blessings of the principal.
 
@@ -394,7 +393,7 @@
    peermap         Shows the map from peer pattern to which blessing name to
                    present.
 
-Principal Get Default
+Principal get default
 
 Returns blessings that are marked as default in the BlessingStore specified by
 the environment that this tool is running in. Providing --names will print the
@@ -413,7 +412,7 @@
  -rootkey=
    Shows the value of the root key of the provided certificate chain name.
 
-Principal Get Forpeer
+Principal get forpeer
 
 Returns blessings that are marked for the provided peer in the BlessingStore
 specified by the environment that this tool is running in. Providing --names
@@ -438,7 +437,7 @@
  -rootkey=
    Shows the value of the root key of the provided certificate chain name.
 
-Principal Get Publickey
+Principal get publickey
 
 Prints out the public key of the principal specified by the environment that
 this tool is running in.
@@ -446,7 +445,7 @@
 Usage:
    principal get publickey
 
-Principal Get Recognizedroots
+Principal get recognizedroots
 
 Shows list of blessing names that the principal recognizes, and their associated
 public key. If the principal is operating as a client, contacted servers must
@@ -456,7 +455,7 @@
 Usage:
    principal get recognizedroots
 
-Principal Get Peermap
+Principal get peermap
 
 Shows the map from peer pattern to which blessing name to present. If the
 principal operates as a server, it presents its default blessing to all peers.
@@ -466,7 +465,7 @@
 Usage:
    principal get peermap
 
-Principal Addtoroots
+Principal addtoroots
 
 Adds an identity provider to the set of recognized roots public keys for this
 principal.
@@ -494,7 +493,7 @@
 
 <blessing pattern> is the blessing pattern for which <key> should be recognized.
 
-Principal Help
+Principal help
 
 Help with no args displays the usage of the parent command.
 
@@ -502,11 +501,10 @@
 
 "help ..." recursively displays help for all commands and topics.
 
-The output is formatted to a target width in runes.  The target width is
-determined by checking the environment variable CMDLINE_WIDTH, falling back on
-the terminal width from the OS, falling back on 80 chars.  By setting
-CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0 the width is unlimited, and
-if x == 0 or is unset one of the fallbacks is used.
+Output is formatted to a target width in runes, determined by checking the
+CMDLINE_WIDTH environment variable, falling back on the terminal width, falling
+back on 80 chars.  By setting CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0
+the width is unlimited, and if x == 0 or is unset one of the fallbacks is used.
 
 Usage:
    principal help [flags] [command/topic ...]
@@ -514,7 +512,11 @@
 [command/topic ...] optionally identifies a specific sub-command or help topic.
 
 The principal help flags are:
- -style=default
-   The formatting style for help output, either "default" or "godoc".
+ -style=compact
+   The formatting style for help output:
+      compact - Good for compact cmdline output.
+      full    - Good for cmdline output, shows all global flags.
+      godoc   - Good for godoc processing.
+   Override the default by setting the CMDLINE_STYLE environment variable.
 */
 package main
diff --git a/cmd/principal/main.go b/cmd/principal/main.go
index 8cdc55a..5585be0 100644
--- a/cmd/principal/main.go
+++ b/cmd/principal/main.go
@@ -873,6 +873,7 @@
 }
 
 func main() {
+	cmdline.HideGlobalFlagsExcept()
 	cmdBlessSelf.Flags.Var(&flagBlessSelfCaveats, "caveat", flagBlessSelfCaveats.usage())
 	cmdBlessSelf.Flags.DurationVar(&flagBlessSelfFor, "for", 0, "Duration of blessing validity (zero implies no expiration)")
 
diff --git a/cmd/servicerunner/.api b/cmd/servicerunner/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmd/servicerunner/.api
diff --git a/cmd/servicerunner/main.go b/cmd/servicerunner/main.go
index d141af5..397747d 100644
--- a/cmd/servicerunner/main.go
+++ b/cmd/servicerunner/main.go
@@ -21,6 +21,7 @@
 
 	"v.io/v23"
 	"v.io/v23/options"
+	"v.io/v23/rpc"
 
 	"v.io/x/ref/envvar"
 	"v.io/x/ref/lib/signals"
@@ -124,7 +125,9 @@
 	sh.SetVar(envvar.NamespacePrefix, vars["MT_NAME"])
 	v23.GetNamespace(ctx).SetRoots(vars["MT_NAME"])
 
-	proxyShutdown, proxyEndpoint, err := profiles.NewProxy(ctx, "ws", "127.0.0.1:0", "", "test/proxy")
+	lspec := v23.GetListenSpec(ctx)
+	lspec.Addrs = rpc.ListenAddrs{{"ws", "127.0.0.1:0"}}
+	proxyShutdown, proxyEndpoint, err := profiles.NewProxy(ctx, lspec, "test/proxy")
 	defer proxyShutdown()
 	vars["PROXY_NAME"] = proxyEndpoint.Name()
 
diff --git a/cmd/uniqueid/.api b/cmd/uniqueid/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmd/uniqueid/.api
diff --git a/cmd/uniqueid/doc.go b/cmd/uniqueid/doc.go
index c494452..9ad2e59 100644
--- a/cmd/uniqueid/doc.go
+++ b/cmd/uniqueid/doc.go
@@ -16,7 +16,6 @@
    generate    Generates UniqueIds
    inject      Injects UniqueIds into existing files
    help        Display help for commands or topics
-Run "uniqueid help [command]" for command usage.
 
 The global flags are:
  -alsologtostderr=true
@@ -63,14 +62,14 @@
  -vmodule=
    comma-separated list of pattern=N settings for file-filtered logging
 
-Uniqueid Generate
+Uniqueid generate
 
 Generates unique ids and outputs them to standard out.
 
 Usage:
    uniqueid generate
 
-Uniqueid Inject
+Uniqueid inject
 
 Injects UniqueIds into existing files. Strings of the form "$UNIQUEID$" will be
 replaced with generated ids.
@@ -80,7 +79,7 @@
 
 <filenames> List of files to inject unique ids into
 
-Uniqueid Help
+Uniqueid help
 
 Help with no args displays the usage of the parent command.
 
@@ -88,11 +87,10 @@
 
 "help ..." recursively displays help for all commands and topics.
 
-The output is formatted to a target width in runes.  The target width is
-determined by checking the environment variable CMDLINE_WIDTH, falling back on
-the terminal width from the OS, falling back on 80 chars.  By setting
-CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0 the width is unlimited, and
-if x == 0 or is unset one of the fallbacks is used.
+Output is formatted to a target width in runes, determined by checking the
+CMDLINE_WIDTH environment variable, falling back on the terminal width, falling
+back on 80 chars.  By setting CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0
+the width is unlimited, and if x == 0 or is unset one of the fallbacks is used.
 
 Usage:
    uniqueid help [flags] [command/topic ...]
@@ -100,7 +98,11 @@
 [command/topic ...] optionally identifies a specific sub-command or help topic.
 
 The uniqueid help flags are:
- -style=default
-   The formatting style for help output, either "default" or "godoc".
+ -style=compact
+   The formatting style for help output:
+      compact - Good for compact cmdline output.
+      full    - Good for cmdline output, shows all global flags.
+      godoc   - Good for godoc processing.
+   Override the default by setting the CMDLINE_STYLE environment variable.
 */
 package main
diff --git a/cmd/uniqueid/main.go b/cmd/uniqueid/main.go
index ca89740..9cd2737 100644
--- a/cmd/uniqueid/main.go
+++ b/cmd/uniqueid/main.go
@@ -21,6 +21,7 @@
 )
 
 func main() {
+	cmdline.HideGlobalFlagsExcept()
 	os.Exit(cmdUniqueId.Main())
 }
 
diff --git a/cmd/vdl/.api b/cmd/vdl/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmd/vdl/.api
diff --git a/cmd/vdl/arith_test.go b/cmd/vdl/arith_test.go
index 7918765..f997fda 100644
--- a/cmd/vdl/arith_test.go
+++ b/cmd/vdl/arith_test.go
@@ -23,7 +23,7 @@
 	"v.io/x/ref/lib/vdl/testdata/base"
 	"v.io/x/ref/test"
 
-	_ "v.io/x/ref/profiles/static"
+	_ "v.io/x/ref/profiles"
 )
 
 var generatedError = errors.New("generated error")
diff --git a/cmd/vdl/doc.go b/cmd/vdl/doc.go
index 7d12ec5..f51b087 100644
--- a/cmd/vdl/doc.go
+++ b/cmd/vdl/doc.go
@@ -18,14 +18,12 @@
    audit       Check if any packages are stale and need generation
    list        List package and dependency info in transitive order
    help        Display help for commands or topics
-Run "vdl help [command]" for command usage.
 
 The vdl additional help topics are:
    packages    Description of package lists
    vdlpath     Description of VDLPATH environment variable
    vdlroot     Description of VDLROOT environment variable
    vdl.config  Description of vdl.config files
-Run "vdl help [topic]" for topic details.
 
 The vdl flags are:
  -exts=.vdl
@@ -39,7 +37,7 @@
  -vdl.config=vdl.config
    Basename of the optional per-package config file.
 
-Vdl Generate
+Vdl generate
 
 Generate compiles packages and their transitive dependencies, and generates code
 in the specified languages.
@@ -93,7 +91,7 @@
  -status=true
    Show package names as they are updated
 
-Vdl Compile
+Vdl compile
 
 Compile compiles packages and their transitive dependencies, but does not
 generate code.  This is useful to sanity-check that your VDL files are valid.
@@ -108,7 +106,7 @@
  -status=true
    Show package names while we compile
 
-Vdl Audit
+Vdl audit
 
 Audit runs the same logic as generate, but doesn't write out generated files.
 Returns a 0 exit code if all packages are up-to-date, otherwise returns a non-0
@@ -163,7 +161,7 @@
  -status=true
    Show package names as they are updated
 
-Vdl List
+Vdl list
 
 List returns information about packages and their transitive dependencies, in
 transitive order.  This is the same order the generate and compile commands use
@@ -182,7 +180,7 @@
 <packages> are a list of packages to process, similar to the standard go tool.
 For more information, run "vdl help packages".
 
-Vdl Help
+Vdl help
 
 Help with no args displays the usage of the parent command.
 
@@ -190,11 +188,10 @@
 
 "help ..." recursively displays help for all commands and topics.
 
-The output is formatted to a target width in runes.  The target width is
-determined by checking the environment variable CMDLINE_WIDTH, falling back on
-the terminal width from the OS, falling back on 80 chars.  By setting
-CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0 the width is unlimited, and
-if x == 0 or is unset one of the fallbacks is used.
+Output is formatted to a target width in runes, determined by checking the
+CMDLINE_WIDTH environment variable, falling back on the terminal width, falling
+back on 80 chars.  By setting CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0
+the width is unlimited, and if x == 0 or is unset one of the fallbacks is used.
 
 Usage:
    vdl help [flags] [command/topic ...]
@@ -202,10 +199,14 @@
 [command/topic ...] optionally identifies a specific sub-command or help topic.
 
 The vdl help flags are:
- -style=default
-   The formatting style for help output, either "default" or "godoc".
+ -style=compact
+   The formatting style for help output:
+      compact - Good for compact cmdline output.
+      full    - Good for cmdline output, shows all global flags.
+      godoc   - Good for godoc processing.
+   Override the default by setting the CMDLINE_STYLE environment variable.
 
-Vdl Packages - help topic
+Vdl packages - help topic
 
 Most vdl commands apply to a list of packages:
 
@@ -233,7 +234,7 @@
  Run "vdl help vdlpath" to see docs on VDLPATH.
  Run "go help packages" to see the standard go package docs.
 
-Vdl Vdlpath - help topic
+Vdl vdlpath - help topic
 
 The VDLPATH environment variable is used to resolve import statements. It must
 be set to compile and generate vdl packages.
@@ -259,7 +260,7 @@
             baz/              (import "bar/baz" refers here)
                baz.vdl
 
-Vdl Vdlroot - help topic
+Vdl vdlroot - help topic
 
 The VDLROOT environment variable is similar to VDLPATH, but instead of pointing
 to multiple user source directories, it points at a single source directory
@@ -270,7 +271,7 @@
 If VDLROOT is empty, we try to construct it out of the V23_ROOT environment
 variable.  It is an error if both VDLROOT and V23_ROOT are empty.
 
-Vdl Vdl.Config - help topic
+Vdl vdl.config - help topic
 
 Each vdl source package P may contain an optional file "vdl.config" within the P
 directory.  This file specifies additional configuration for the vdl tool.
diff --git a/cmd/vom/.api b/cmd/vom/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmd/vom/.api
diff --git a/cmd/vom/doc.go b/cmd/vom/doc.go
index b25adef..4bdba37 100644
--- a/cmd/vom/doc.go
+++ b/cmd/vom/doc.go
@@ -15,7 +15,6 @@
    decode      Decode data encoded in the vom format
    dump        Dump data encoded in the vom format into formatted output
    help        Display help for commands or topics
-Run "vom help [command]" for command usage.
 
 The global flags are:
  -alsologtostderr=true
@@ -62,7 +61,7 @@
  -vmodule=
    comma-separated list of pattern=N settings for file-filtered logging
 
-Vom Decode
+Vom decode
 
 Decode decodes data encoded in the vom format.  If no arguments are provided,
 decode reads the data from stdin, otherwise the argument is the data.
@@ -80,7 +79,7 @@
  -data=Hex
    Data representation, one of [Hex Binary]
 
-Vom Dump
+Vom dump
 
 Dump dumps data encoded in the vom format, generating formatted output
 describing each portion of the encoding.  If no arguments are provided, dump
@@ -110,7 +109,7 @@
  -data=Hex
    Data representation, one of [Hex Binary]
 
-Vom Help
+Vom help
 
 Help with no args displays the usage of the parent command.
 
@@ -118,11 +117,10 @@
 
 "help ..." recursively displays help for all commands and topics.
 
-The output is formatted to a target width in runes.  The target width is
-determined by checking the environment variable CMDLINE_WIDTH, falling back on
-the terminal width from the OS, falling back on 80 chars.  By setting
-CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0 the width is unlimited, and
-if x == 0 or is unset one of the fallbacks is used.
+Output is formatted to a target width in runes, determined by checking the
+CMDLINE_WIDTH environment variable, falling back on the terminal width, falling
+back on 80 chars.  By setting CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0
+the width is unlimited, and if x == 0 or is unset one of the fallbacks is used.
 
 Usage:
    vom help [flags] [command/topic ...]
@@ -130,7 +128,11 @@
 [command/topic ...] optionally identifies a specific sub-command or help topic.
 
 The vom help flags are:
- -style=default
-   The formatting style for help output, either "default" or "godoc".
+ -style=compact
+   The formatting style for help output:
+      compact - Good for compact cmdline output.
+      full    - Good for cmdline output, shows all global flags.
+      godoc   - Good for godoc processing.
+   Override the default by setting the CMDLINE_STYLE environment variable.
 */
 package main
diff --git a/cmd/vom/vom.go b/cmd/vom/vom.go
index 16b5847..58d4fdc 100644
--- a/cmd/vom/vom.go
+++ b/cmd/vom/vom.go
@@ -25,6 +25,7 @@
 )
 
 func main() {
+	cmdline.HideGlobalFlagsExcept()
 	os.Exit(cmdVom.Main())
 }
 
diff --git a/cmd/vomtestgen/.api b/cmd/vomtestgen/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmd/vomtestgen/.api
diff --git a/cmd/vomtestgen/generate.go b/cmd/vomtestgen/generate.go
index cb53110..c4b67f9 100644
--- a/cmd/vomtestgen/generate.go
+++ b/cmd/vomtestgen/generate.go
@@ -62,6 +62,7 @@
 )
 
 func init() {
+	cmdline.HideGlobalFlagsExcept()
 	cmdGenerate.Flags.IntVar(&optGenMaxErrors, "max-errors", -1, "Stop processing after this many errors, or -1 for unlimited.")
 	cmdGenerate.Flags.StringVar(&optGenExts, "exts", ".vdl", "Comma-separated list of valid VDL file name extensions.")
 }
diff --git a/cmd/vrpc/.api b/cmd/vrpc/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmd/vrpc/.api
diff --git a/cmd/vrpc/doc.go b/cmd/vrpc/doc.go
index ff54449..aeaa638 100644
--- a/cmd/vrpc/doc.go
+++ b/cmd/vrpc/doc.go
@@ -17,9 +17,11 @@
    call        Call a method of a Vanadium server
    identify    Reveal blessings presented by a Vanadium server
    help        Display help for commands or topics
-Run "vrpc help [command]" for command usage.
 
 The global flags are:
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+   local namespace root; can be repeated to provided multiple roots
+
  -alsologtostderr=true
    log to standard error as well as files
  -log_backtrace_at=:0
@@ -38,8 +40,6 @@
    directory to use for storing security credentials
  -v23.i18n-catalogue=
    18n catalogue files to load, comma separated
- -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
-   local namespace root; can be repeated to provided multiple roots
  -v23.proxy=
    object name of proxy service to use to export services across network
    boundaries
@@ -59,7 +59,7 @@
  -vmodule=
    comma-separated list of pattern=N settings for file-filtered logging
 
-Vrpc Signature
+Vrpc signature
 
 Signature connects to the Vanadium server identified by <server>.
 
@@ -82,7 +82,7 @@
  -show-reserved=false
    if true, also show the signatures of reserved methods
 
-Vrpc Call
+Vrpc call
 
 Call connects to the Vanadium server identified by <server> and calls the
 <method> with the given positional [args...], returning results on stdout.
@@ -112,7 +112,7 @@
 
 [args...] are the positional input arguments, specified as VDL expressions.
 
-Vrpc Identify
+Vrpc identify
 
 Identify connects to the Vanadium server identified by <server> and dumps out
 the blessings presented by that server (and the subset of those that are
@@ -129,7 +129,7 @@
    If true, skip server authentication. This means that the client will reveal
    its blessings to servers that it may not recognize.
 
-Vrpc Help
+Vrpc help
 
 Help with no args displays the usage of the parent command.
 
@@ -137,11 +137,10 @@
 
 "help ..." recursively displays help for all commands and topics.
 
-The output is formatted to a target width in runes.  The target width is
-determined by checking the environment variable CMDLINE_WIDTH, falling back on
-the terminal width from the OS, falling back on 80 chars.  By setting
-CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0 the width is unlimited, and
-if x == 0 or is unset one of the fallbacks is used.
+Output is formatted to a target width in runes, determined by checking the
+CMDLINE_WIDTH environment variable, falling back on the terminal width, falling
+back on 80 chars.  By setting CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0
+the width is unlimited, and if x == 0 or is unset one of the fallbacks is used.
 
 Usage:
    vrpc help [flags] [command/topic ...]
@@ -149,7 +148,11 @@
 [command/topic ...] optionally identifies a specific sub-command or help topic.
 
 The vrpc help flags are:
- -style=default
-   The formatting style for help output, either "default" or "godoc".
+ -style=compact
+   The formatting style for help output:
+      compact - Good for compact cmdline output.
+      full    - Good for cmdline output, shows all global flags.
+      godoc   - Good for godoc processing.
+   Override the default by setting the CMDLINE_STYLE environment variable.
 */
 package main
diff --git a/cmd/vrpc/internal/.api b/cmd/vrpc/internal/.api
new file mode 100644
index 0000000..6801a23
--- /dev/null
+++ b/cmd/vrpc/internal/.api
@@ -0,0 +1,111 @@
+pkg internal, func TypeTesterClient(string) TypeTesterClientStub
+pkg internal, func TypeTesterServer(TypeTesterServerMethods) TypeTesterServerStub
+pkg internal, method (*TypeTesterZStreamServerCallStub) Init(rpc.StreamServerCall)
+pkg internal, method (*TypeTesterZStreamServerCallStub) SendStream() interface {  Send(item bool) error;}
+pkg internal, type Array2Int [2]int32
+pkg internal, type Struct struct
+pkg internal, type Struct struct, X int32
+pkg internal, type Struct struct, Y int32
+pkg internal, type TypeTesterClientMethods interface { EchoBool, EchoByte, EchoFloat32, EchoFloat64, EchoInt32, EchoInt64, EchoString, EchoUint32, EchoUint64, XEchoArray, XEchoMap, XEchoSet, XEchoSlice, XEchoStruct, YMultiArg, YNoArgs, ZStream }
+pkg internal, type TypeTesterClientMethods interface, EchoBool(*context.T, bool, ...rpc.CallOpt) (bool, error)
+pkg internal, type TypeTesterClientMethods interface, EchoByte(*context.T, byte, ...rpc.CallOpt) (byte, error)
+pkg internal, type TypeTesterClientMethods interface, EchoFloat32(*context.T, float32, ...rpc.CallOpt) (float32, error)
+pkg internal, type TypeTesterClientMethods interface, EchoFloat64(*context.T, float64, ...rpc.CallOpt) (float64, error)
+pkg internal, type TypeTesterClientMethods interface, EchoInt32(*context.T, int32, ...rpc.CallOpt) (int32, error)
+pkg internal, type TypeTesterClientMethods interface, EchoInt64(*context.T, int64, ...rpc.CallOpt) (int64, error)
+pkg internal, type TypeTesterClientMethods interface, EchoString(*context.T, string, ...rpc.CallOpt) (string, error)
+pkg internal, type TypeTesterClientMethods interface, EchoUint32(*context.T, uint32, ...rpc.CallOpt) (uint32, error)
+pkg internal, type TypeTesterClientMethods interface, EchoUint64(*context.T, uint64, ...rpc.CallOpt) (uint64, error)
+pkg internal, type TypeTesterClientMethods interface, XEchoArray(*context.T, Array2Int, ...rpc.CallOpt) (Array2Int, error)
+pkg internal, type TypeTesterClientMethods interface, XEchoMap(*context.T, map[int32]string, ...rpc.CallOpt) (map[int32]string, error)
+pkg internal, type TypeTesterClientMethods interface, XEchoSet(*context.T, map[int32]struct{}, ...rpc.CallOpt) (map[int32]struct{}, error)
+pkg internal, type TypeTesterClientMethods interface, XEchoSlice(*context.T, []int32, ...rpc.CallOpt) ([]int32, error)
+pkg internal, type TypeTesterClientMethods interface, XEchoStruct(*context.T, Struct, ...rpc.CallOpt) (Struct, error)
+pkg internal, type TypeTesterClientMethods interface, YMultiArg(*context.T, int32, int32, ...rpc.CallOpt) (int32, int32, error)
+pkg internal, type TypeTesterClientMethods interface, YNoArgs(*context.T, ...rpc.CallOpt) error
+pkg internal, type TypeTesterClientMethods interface, ZStream(*context.T, int32, bool, ...rpc.CallOpt) (TypeTesterZStreamClientCall, error)
+pkg internal, type TypeTesterClientStub interface, EchoBool(*context.T, bool, ...rpc.CallOpt) (bool, error)
+pkg internal, type TypeTesterClientStub interface, EchoByte(*context.T, byte, ...rpc.CallOpt) (byte, error)
+pkg internal, type TypeTesterClientStub interface, EchoFloat32(*context.T, float32, ...rpc.CallOpt) (float32, error)
+pkg internal, type TypeTesterClientStub interface, EchoFloat64(*context.T, float64, ...rpc.CallOpt) (float64, error)
+pkg internal, type TypeTesterClientStub interface, EchoInt32(*context.T, int32, ...rpc.CallOpt) (int32, error)
+pkg internal, type TypeTesterClientStub interface, EchoInt64(*context.T, int64, ...rpc.CallOpt) (int64, error)
+pkg internal, type TypeTesterClientStub interface, EchoString(*context.T, string, ...rpc.CallOpt) (string, error)
+pkg internal, type TypeTesterClientStub interface, EchoUint32(*context.T, uint32, ...rpc.CallOpt) (uint32, error)
+pkg internal, type TypeTesterClientStub interface, EchoUint64(*context.T, uint64, ...rpc.CallOpt) (uint64, error)
+pkg internal, type TypeTesterClientStub interface, XEchoArray(*context.T, Array2Int, ...rpc.CallOpt) (Array2Int, error)
+pkg internal, type TypeTesterClientStub interface, XEchoMap(*context.T, map[int32]string, ...rpc.CallOpt) (map[int32]string, error)
+pkg internal, type TypeTesterClientStub interface, XEchoSet(*context.T, map[int32]struct{}, ...rpc.CallOpt) (map[int32]struct{}, error)
+pkg internal, type TypeTesterClientStub interface, XEchoSlice(*context.T, []int32, ...rpc.CallOpt) ([]int32, error)
+pkg internal, type TypeTesterClientStub interface, XEchoStruct(*context.T, Struct, ...rpc.CallOpt) (Struct, error)
+pkg internal, type TypeTesterClientStub interface, YMultiArg(*context.T, int32, int32, ...rpc.CallOpt) (int32, int32, error)
+pkg internal, type TypeTesterClientStub interface, YNoArgs(*context.T, ...rpc.CallOpt) error
+pkg internal, type TypeTesterClientStub interface, ZStream(*context.T, int32, bool, ...rpc.CallOpt) (TypeTesterZStreamClientCall, error)
+pkg internal, type TypeTesterClientStub interface, unexported methods
+pkg internal, type TypeTesterServerMethods interface { EchoBool, EchoByte, EchoFloat32, EchoFloat64, EchoInt32, EchoInt64, EchoString, EchoUint32, EchoUint64, XEchoArray, XEchoMap, XEchoSet, XEchoSlice, XEchoStruct, YMultiArg, YNoArgs, ZStream }
+pkg internal, type TypeTesterServerMethods interface, EchoBool(*context.T, rpc.ServerCall, bool) (bool, error)
+pkg internal, type TypeTesterServerMethods interface, EchoByte(*context.T, rpc.ServerCall, byte) (byte, error)
+pkg internal, type TypeTesterServerMethods interface, EchoFloat32(*context.T, rpc.ServerCall, float32) (float32, error)
+pkg internal, type TypeTesterServerMethods interface, EchoFloat64(*context.T, rpc.ServerCall, float64) (float64, error)
+pkg internal, type TypeTesterServerMethods interface, EchoInt32(*context.T, rpc.ServerCall, int32) (int32, error)
+pkg internal, type TypeTesterServerMethods interface, EchoInt64(*context.T, rpc.ServerCall, int64) (int64, error)
+pkg internal, type TypeTesterServerMethods interface, EchoString(*context.T, rpc.ServerCall, string) (string, error)
+pkg internal, type TypeTesterServerMethods interface, EchoUint32(*context.T, rpc.ServerCall, uint32) (uint32, error)
+pkg internal, type TypeTesterServerMethods interface, EchoUint64(*context.T, rpc.ServerCall, uint64) (uint64, error)
+pkg internal, type TypeTesterServerMethods interface, XEchoArray(*context.T, rpc.ServerCall, Array2Int) (Array2Int, error)
+pkg internal, type TypeTesterServerMethods interface, XEchoMap(*context.T, rpc.ServerCall, map[int32]string) (map[int32]string, error)
+pkg internal, type TypeTesterServerMethods interface, XEchoSet(*context.T, rpc.ServerCall, map[int32]struct{}) (map[int32]struct{}, error)
+pkg internal, type TypeTesterServerMethods interface, XEchoSlice(*context.T, rpc.ServerCall, []int32) ([]int32, error)
+pkg internal, type TypeTesterServerMethods interface, XEchoStruct(*context.T, rpc.ServerCall, Struct) (Struct, error)
+pkg internal, type TypeTesterServerMethods interface, YMultiArg(*context.T, rpc.ServerCall, int32, int32) (int32, int32, error)
+pkg internal, type TypeTesterServerMethods interface, YNoArgs(*context.T, rpc.ServerCall) error
+pkg internal, type TypeTesterServerMethods interface, ZStream(*context.T, TypeTesterZStreamServerCall, int32, bool) error
+pkg internal, type TypeTesterServerStub interface { Describe__, EchoBool, EchoByte, EchoFloat32, EchoFloat64, EchoInt32, EchoInt64, EchoString, EchoUint32, EchoUint64, XEchoArray, XEchoMap, XEchoSet, XEchoSlice, XEchoStruct, YMultiArg, YNoArgs, ZStream }
+pkg internal, type TypeTesterServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg internal, type TypeTesterServerStub interface, EchoBool(*context.T, rpc.ServerCall, bool) (bool, error)
+pkg internal, type TypeTesterServerStub interface, EchoByte(*context.T, rpc.ServerCall, byte) (byte, error)
+pkg internal, type TypeTesterServerStub interface, EchoFloat32(*context.T, rpc.ServerCall, float32) (float32, error)
+pkg internal, type TypeTesterServerStub interface, EchoFloat64(*context.T, rpc.ServerCall, float64) (float64, error)
+pkg internal, type TypeTesterServerStub interface, EchoInt32(*context.T, rpc.ServerCall, int32) (int32, error)
+pkg internal, type TypeTesterServerStub interface, EchoInt64(*context.T, rpc.ServerCall, int64) (int64, error)
+pkg internal, type TypeTesterServerStub interface, EchoString(*context.T, rpc.ServerCall, string) (string, error)
+pkg internal, type TypeTesterServerStub interface, EchoUint32(*context.T, rpc.ServerCall, uint32) (uint32, error)
+pkg internal, type TypeTesterServerStub interface, EchoUint64(*context.T, rpc.ServerCall, uint64) (uint64, error)
+pkg internal, type TypeTesterServerStub interface, XEchoArray(*context.T, rpc.ServerCall, Array2Int) (Array2Int, error)
+pkg internal, type TypeTesterServerStub interface, XEchoMap(*context.T, rpc.ServerCall, map[int32]string) (map[int32]string, error)
+pkg internal, type TypeTesterServerStub interface, XEchoSet(*context.T, rpc.ServerCall, map[int32]struct{}) (map[int32]struct{}, error)
+pkg internal, type TypeTesterServerStub interface, XEchoSlice(*context.T, rpc.ServerCall, []int32) ([]int32, error)
+pkg internal, type TypeTesterServerStub interface, XEchoStruct(*context.T, rpc.ServerCall, Struct) (Struct, error)
+pkg internal, type TypeTesterServerStub interface, YMultiArg(*context.T, rpc.ServerCall, int32, int32) (int32, int32, error)
+pkg internal, type TypeTesterServerStub interface, YNoArgs(*context.T, rpc.ServerCall) error
+pkg internal, type TypeTesterServerStub interface, ZStream(*context.T, *TypeTesterZStreamServerCallStub, int32, bool) error
+pkg internal, type TypeTesterServerStubMethods interface { EchoBool, EchoByte, EchoFloat32, EchoFloat64, EchoInt32, EchoInt64, EchoString, EchoUint32, EchoUint64, XEchoArray, XEchoMap, XEchoSet, XEchoSlice, XEchoStruct, YMultiArg, YNoArgs, ZStream }
+pkg internal, type TypeTesterServerStubMethods interface, EchoBool(*context.T, rpc.ServerCall, bool) (bool, error)
+pkg internal, type TypeTesterServerStubMethods interface, EchoByte(*context.T, rpc.ServerCall, byte) (byte, error)
+pkg internal, type TypeTesterServerStubMethods interface, EchoFloat32(*context.T, rpc.ServerCall, float32) (float32, error)
+pkg internal, type TypeTesterServerStubMethods interface, EchoFloat64(*context.T, rpc.ServerCall, float64) (float64, error)
+pkg internal, type TypeTesterServerStubMethods interface, EchoInt32(*context.T, rpc.ServerCall, int32) (int32, error)
+pkg internal, type TypeTesterServerStubMethods interface, EchoInt64(*context.T, rpc.ServerCall, int64) (int64, error)
+pkg internal, type TypeTesterServerStubMethods interface, EchoString(*context.T, rpc.ServerCall, string) (string, error)
+pkg internal, type TypeTesterServerStubMethods interface, EchoUint32(*context.T, rpc.ServerCall, uint32) (uint32, error)
+pkg internal, type TypeTesterServerStubMethods interface, EchoUint64(*context.T, rpc.ServerCall, uint64) (uint64, error)
+pkg internal, type TypeTesterServerStubMethods interface, XEchoArray(*context.T, rpc.ServerCall, Array2Int) (Array2Int, error)
+pkg internal, type TypeTesterServerStubMethods interface, XEchoMap(*context.T, rpc.ServerCall, map[int32]string) (map[int32]string, error)
+pkg internal, type TypeTesterServerStubMethods interface, XEchoSet(*context.T, rpc.ServerCall, map[int32]struct{}) (map[int32]struct{}, error)
+pkg internal, type TypeTesterServerStubMethods interface, XEchoSlice(*context.T, rpc.ServerCall, []int32) ([]int32, error)
+pkg internal, type TypeTesterServerStubMethods interface, XEchoStruct(*context.T, rpc.ServerCall, Struct) (Struct, error)
+pkg internal, type TypeTesterServerStubMethods interface, YMultiArg(*context.T, rpc.ServerCall, int32, int32) (int32, int32, error)
+pkg internal, type TypeTesterServerStubMethods interface, YNoArgs(*context.T, rpc.ServerCall) error
+pkg internal, type TypeTesterServerStubMethods interface, ZStream(*context.T, *TypeTesterZStreamServerCallStub, int32, bool) error
+pkg internal, type TypeTesterZStreamClientCall interface { Finish, RecvStream }
+pkg internal, type TypeTesterZStreamClientCall interface, Finish() error
+pkg internal, type TypeTesterZStreamClientCall interface, RecvStream() interface {  Advance() bool;; Value() bool;; Err() error;}
+pkg internal, type TypeTesterZStreamClientStream interface { RecvStream }
+pkg internal, type TypeTesterZStreamClientStream interface, RecvStream() interface {  Advance() bool;; Value() bool;; Err() error;}
+pkg internal, type TypeTesterZStreamServerCall interface, SendStream() interface {  Send(item bool) error;}
+pkg internal, type TypeTesterZStreamServerCall interface, unexported methods
+pkg internal, type TypeTesterZStreamServerCallStub struct
+pkg internal, type TypeTesterZStreamServerCallStub struct, embedded rpc.StreamServerCall
+pkg internal, type TypeTesterZStreamServerStream interface { SendStream }
+pkg internal, type TypeTesterZStreamServerStream interface, SendStream() interface {  Send(item bool) error;}
+pkg internal, var TypeTesterDesc rpc.InterfaceDesc
diff --git a/cmd/vrpc/vrpc.go b/cmd/vrpc/vrpc.go
index 590e02d..e540707 100644
--- a/cmd/vrpc/vrpc.go
+++ b/cmd/vrpc/vrpc.go
@@ -11,6 +11,7 @@
 	"fmt"
 	"io"
 	"os"
+	"regexp"
 	"strings"
 	"time"
 
@@ -37,6 +38,7 @@
 )
 
 func main() {
+	cmdline.HideGlobalFlagsExcept(regexp.MustCompile(`^v23\.namespace\.root$`))
 	var shutdown v23.Shutdown
 	gctx, shutdown = v23.Init()
 	exitCode := cmdVRPC.Main()
diff --git a/cmd/vrun/.api b/cmd/vrun/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmd/vrun/.api
diff --git a/cmd/vrun/vrun.go b/cmd/vrun/vrun.go
index cdfde06..92f707f 100644
--- a/cmd/vrun/vrun.go
+++ b/cmd/vrun/vrun.go
@@ -42,6 +42,7 @@
 }
 
 func main() {
+	cmdline.HideGlobalFlagsExcept()
 	syscall.CloseOnExec(3)
 	syscall.CloseOnExec(4)
 
diff --git a/envvar/.api b/envvar/.api
new file mode 100644
index 0000000..3c58b7e
--- /dev/null
+++ b/envvar/.api
@@ -0,0 +1,7 @@
+pkg envvar, const AgentEndpoint ideal-string
+pkg envvar, const Credentials ideal-string
+pkg envvar, const I18nCatalogueFiles ideal-string
+pkg envvar, const NamespacePrefix ideal-string
+pkg envvar, const OAuthIdentityProvider ideal-string
+pkg envvar, func ClearCredentials() error
+pkg envvar, func NamespaceRoots() (map[string]string, []string)
diff --git a/examples/rps/.api b/examples/rps/.api
new file mode 100644
index 0000000..d857e0a
--- /dev/null
+++ b/examples/rps/.api
@@ -0,0 +1,158 @@
+pkg rps, const Classic GameTypeTag
+pkg rps, const Draw WinnerTag
+pkg rps, const LizardSpock GameTypeTag
+pkg rps, const Player1 WinnerTag
+pkg rps, const Player2 WinnerTag
+pkg rps, func JudgeClient(string) JudgeClientStub
+pkg rps, func JudgeServer(JudgeServerMethods) JudgeServerStub
+pkg rps, func PlayerClient(string) PlayerClientStub
+pkg rps, func PlayerServer(PlayerServerMethods) PlayerServerStub
+pkg rps, func RockPaperScissorsClient(string) RockPaperScissorsClientStub
+pkg rps, func RockPaperScissorsServer(RockPaperScissorsServerMethods) RockPaperScissorsServerStub
+pkg rps, func ScoreKeeperClient(string) ScoreKeeperClientStub
+pkg rps, func ScoreKeeperServer(ScoreKeeperServerMethods) ScoreKeeperServerStub
+pkg rps, method (*JudgePlayServerCallStub) Init(rpc.StreamServerCall)
+pkg rps, method (*JudgePlayServerCallStub) RecvStream() interface {  Advance() bool; Value() PlayerAction; Err() error;}
+pkg rps, method (*JudgePlayServerCallStub) SendStream() interface {  Send(item JudgeAction) error;}
+pkg rps, method (JudgeActionMoveOptions) Index() int
+pkg rps, method (JudgeActionMoveOptions) Interface() interface{}
+pkg rps, method (JudgeActionMoveOptions) Name() string
+pkg rps, method (JudgeActionOpponentName) Index() int
+pkg rps, method (JudgeActionOpponentName) Interface() interface{}
+pkg rps, method (JudgeActionOpponentName) Name() string
+pkg rps, method (JudgeActionPlayerNum) Index() int
+pkg rps, method (JudgeActionPlayerNum) Interface() interface{}
+pkg rps, method (JudgeActionPlayerNum) Name() string
+pkg rps, method (JudgeActionRoundResult) Index() int
+pkg rps, method (JudgeActionRoundResult) Interface() interface{}
+pkg rps, method (JudgeActionRoundResult) Name() string
+pkg rps, method (JudgeActionScore) Index() int
+pkg rps, method (JudgeActionScore) Interface() interface{}
+pkg rps, method (JudgeActionScore) Name() string
+pkg rps, method (PlayerActionMove) Index() int
+pkg rps, method (PlayerActionMove) Interface() interface{}
+pkg rps, method (PlayerActionMove) Name() string
+pkg rps, method (PlayerActionQuit) Index() int
+pkg rps, method (PlayerActionQuit) Interface() interface{}
+pkg rps, method (PlayerActionQuit) Name() string
+pkg rps, type GameId struct
+pkg rps, type GameId struct, Id string
+pkg rps, type GameOptions struct
+pkg rps, type GameOptions struct, GameType GameTypeTag
+pkg rps, type GameOptions struct, NumRounds int32
+pkg rps, type GameTypeTag byte
+pkg rps, type JudgeAction interface, Index() int
+pkg rps, type JudgeAction interface, Interface() interface{}
+pkg rps, type JudgeAction interface, Name() string
+pkg rps, type JudgeAction interface, unexported methods
+pkg rps, type JudgeActionMoveOptions struct
+pkg rps, type JudgeActionMoveOptions struct, Value []string
+pkg rps, type JudgeActionOpponentName struct
+pkg rps, type JudgeActionOpponentName struct, Value string
+pkg rps, type JudgeActionPlayerNum struct
+pkg rps, type JudgeActionPlayerNum struct, Value int32
+pkg rps, type JudgeActionRoundResult struct
+pkg rps, type JudgeActionRoundResult struct, Value Round
+pkg rps, type JudgeActionScore struct
+pkg rps, type JudgeActionScore struct, Value ScoreCard
+pkg rps, type JudgeClientMethods interface { CreateGame, Play }
+pkg rps, type JudgeClientMethods interface, CreateGame(*context.T, GameOptions, ...rpc.CallOpt) (GameId, error)
+pkg rps, type JudgeClientMethods interface, Play(*context.T, GameId, ...rpc.CallOpt) (JudgePlayClientCall, error)
+pkg rps, type JudgeClientStub interface, CreateGame(*context.T, GameOptions, ...rpc.CallOpt) (GameId, error)
+pkg rps, type JudgeClientStub interface, Play(*context.T, GameId, ...rpc.CallOpt) (JudgePlayClientCall, error)
+pkg rps, type JudgeClientStub interface, unexported methods
+pkg rps, type JudgePlayClientCall interface { Finish, RecvStream, SendStream }
+pkg rps, type JudgePlayClientCall interface, Finish() (PlayResult, error)
+pkg rps, type JudgePlayClientCall interface, RecvStream() interface {  Advance() bool;; Value() JudgeAction;; Err() error;}
+pkg rps, type JudgePlayClientCall interface, SendStream() interface {  Send(item PlayerAction) error;; Close() error;}
+pkg rps, type JudgePlayClientStream interface { RecvStream, SendStream }
+pkg rps, type JudgePlayClientStream interface, RecvStream() interface {  Advance() bool;; Value() JudgeAction;; Err() error;}
+pkg rps, type JudgePlayClientStream interface, SendStream() interface {  Send(item PlayerAction) error;; Close() error;}
+pkg rps, type JudgePlayServerCall interface, RecvStream() interface {  Advance() bool;; Value() PlayerAction;; Err() error;}
+pkg rps, type JudgePlayServerCall interface, SendStream() interface {  Send(item JudgeAction) error;}
+pkg rps, type JudgePlayServerCall interface, unexported methods
+pkg rps, type JudgePlayServerCallStub struct
+pkg rps, type JudgePlayServerCallStub struct, embedded rpc.StreamServerCall
+pkg rps, type JudgePlayServerStream interface { RecvStream, SendStream }
+pkg rps, type JudgePlayServerStream interface, RecvStream() interface {  Advance() bool;; Value() PlayerAction;; Err() error;}
+pkg rps, type JudgePlayServerStream interface, SendStream() interface {  Send(item JudgeAction) error;}
+pkg rps, type JudgeServerMethods interface { CreateGame, Play }
+pkg rps, type JudgeServerMethods interface, CreateGame(*context.T, rpc.ServerCall, GameOptions) (GameId, error)
+pkg rps, type JudgeServerMethods interface, Play(*context.T, JudgePlayServerCall, GameId) (PlayResult, error)
+pkg rps, type JudgeServerStub interface { CreateGame, Describe__, Play }
+pkg rps, type JudgeServerStub interface, CreateGame(*context.T, rpc.ServerCall, GameOptions) (GameId, error)
+pkg rps, type JudgeServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg rps, type JudgeServerStub interface, Play(*context.T, *JudgePlayServerCallStub, GameId) (PlayResult, error)
+pkg rps, type JudgeServerStubMethods interface { CreateGame, Play }
+pkg rps, type JudgeServerStubMethods interface, CreateGame(*context.T, rpc.ServerCall, GameOptions) (GameId, error)
+pkg rps, type JudgeServerStubMethods interface, Play(*context.T, *JudgePlayServerCallStub, GameId) (PlayResult, error)
+pkg rps, type PlayResult struct
+pkg rps, type PlayResult struct, YouWon bool
+pkg rps, type PlayerAction interface, Index() int
+pkg rps, type PlayerAction interface, Interface() interface{}
+pkg rps, type PlayerAction interface, Name() string
+pkg rps, type PlayerAction interface, unexported methods
+pkg rps, type PlayerActionMove struct
+pkg rps, type PlayerActionMove struct, Value string
+pkg rps, type PlayerActionQuit struct
+pkg rps, type PlayerActionQuit struct, Value unused
+pkg rps, type PlayerClientMethods interface { Challenge }
+pkg rps, type PlayerClientMethods interface, Challenge(*context.T, string, GameId, GameOptions, ...rpc.CallOpt) error
+pkg rps, type PlayerClientStub interface, Challenge(*context.T, string, GameId, GameOptions, ...rpc.CallOpt) error
+pkg rps, type PlayerClientStub interface, unexported methods
+pkg rps, type PlayerServerMethods interface { Challenge }
+pkg rps, type PlayerServerMethods interface, Challenge(*context.T, rpc.ServerCall, string, GameId, GameOptions) error
+pkg rps, type PlayerServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg rps, type PlayerServerStub interface, unexported methods
+pkg rps, type PlayerServerStubMethods PlayerServerMethods
+pkg rps, type PlayersMoves [2]string
+pkg rps, type RockPaperScissorsClientMethods interface { Challenge, CreateGame, Play, Record }
+pkg rps, type RockPaperScissorsClientMethods interface, Challenge(*context.T, string, GameId, GameOptions, ...rpc.CallOpt) error
+pkg rps, type RockPaperScissorsClientMethods interface, CreateGame(*context.T, GameOptions, ...rpc.CallOpt) (GameId, error)
+pkg rps, type RockPaperScissorsClientMethods interface, Play(*context.T, GameId, ...rpc.CallOpt) (JudgePlayClientCall, error)
+pkg rps, type RockPaperScissorsClientMethods interface, Record(*context.T, ScoreCard, ...rpc.CallOpt) error
+pkg rps, type RockPaperScissorsClientStub interface, Challenge(*context.T, string, GameId, GameOptions, ...rpc.CallOpt) error
+pkg rps, type RockPaperScissorsClientStub interface, CreateGame(*context.T, GameOptions, ...rpc.CallOpt) (GameId, error)
+pkg rps, type RockPaperScissorsClientStub interface, Play(*context.T, GameId, ...rpc.CallOpt) (JudgePlayClientCall, error)
+pkg rps, type RockPaperScissorsClientStub interface, Record(*context.T, ScoreCard, ...rpc.CallOpt) error
+pkg rps, type RockPaperScissorsClientStub interface, unexported methods
+pkg rps, type RockPaperScissorsServerMethods interface { Challenge, CreateGame, Play, Record }
+pkg rps, type RockPaperScissorsServerMethods interface, Challenge(*context.T, rpc.ServerCall, string, GameId, GameOptions) error
+pkg rps, type RockPaperScissorsServerMethods interface, CreateGame(*context.T, rpc.ServerCall, GameOptions) (GameId, error)
+pkg rps, type RockPaperScissorsServerMethods interface, Play(*context.T, JudgePlayServerCall, GameId) (PlayResult, error)
+pkg rps, type RockPaperScissorsServerMethods interface, Record(*context.T, rpc.ServerCall, ScoreCard) error
+pkg rps, type RockPaperScissorsServerStub interface, CreateGame(*context.T, rpc.ServerCall, GameOptions) (GameId, error)
+pkg rps, type RockPaperScissorsServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg rps, type RockPaperScissorsServerStub interface, Play(*context.T, *JudgePlayServerCallStub, GameId) (PlayResult, error)
+pkg rps, type RockPaperScissorsServerStub interface, unexported methods
+pkg rps, type RockPaperScissorsServerStubMethods interface, CreateGame(*context.T, rpc.ServerCall, GameOptions) (GameId, error)
+pkg rps, type RockPaperScissorsServerStubMethods interface, Play(*context.T, *JudgePlayServerCallStub, GameId) (PlayResult, error)
+pkg rps, type RockPaperScissorsServerStubMethods interface, unexported methods
+pkg rps, type Round struct
+pkg rps, type Round struct, Comment string
+pkg rps, type Round struct, EndTime time.Time
+pkg rps, type Round struct, Moves PlayersMoves
+pkg rps, type Round struct, StartTime time.Time
+pkg rps, type Round struct, Winner WinnerTag
+pkg rps, type ScoreCard struct
+pkg rps, type ScoreCard struct, EndTime time.Time
+pkg rps, type ScoreCard struct, Judge string
+pkg rps, type ScoreCard struct, Opts GameOptions
+pkg rps, type ScoreCard struct, Players []string
+pkg rps, type ScoreCard struct, Rounds []Round
+pkg rps, type ScoreCard struct, StartTime time.Time
+pkg rps, type ScoreCard struct, Winner WinnerTag
+pkg rps, type ScoreKeeperClientMethods interface { Record }
+pkg rps, type ScoreKeeperClientMethods interface, Record(*context.T, ScoreCard, ...rpc.CallOpt) error
+pkg rps, type ScoreKeeperClientStub interface, Record(*context.T, ScoreCard, ...rpc.CallOpt) error
+pkg rps, type ScoreKeeperClientStub interface, unexported methods
+pkg rps, type ScoreKeeperServerMethods interface { Record }
+pkg rps, type ScoreKeeperServerMethods interface, Record(*context.T, rpc.ServerCall, ScoreCard) error
+pkg rps, type ScoreKeeperServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg rps, type ScoreKeeperServerStub interface, unexported methods
+pkg rps, type ScoreKeeperServerStubMethods ScoreKeeperServerMethods
+pkg rps, type WinnerTag byte
+pkg rps, var JudgeDesc rpc.InterfaceDesc
+pkg rps, var PlayerDesc rpc.InterfaceDesc
+pkg rps, var RockPaperScissorsDesc rpc.InterfaceDesc
+pkg rps, var ScoreKeeperDesc rpc.InterfaceDesc
diff --git a/examples/rps/internal/.api b/examples/rps/internal/.api
new file mode 100644
index 0000000..a47f22b
--- /dev/null
+++ b/examples/rps/internal/.api
@@ -0,0 +1,6 @@
+pkg internal, func CreateName() string
+pkg internal, func FindJudge(*context.T) (string, error)
+pkg internal, func FindPlayer(*context.T) (string, error)
+pkg internal, func FindScoreKeepers(*context.T) ([]string, error)
+pkg internal, func FormatScoreCard(rps.ScoreCard) string
+pkg internal, func NewAuthorizer(string) security.Authorizer
diff --git a/examples/rps/rpsbot/.api b/examples/rps/rpsbot/.api
new file mode 100644
index 0000000..033dd6d
--- /dev/null
+++ b/examples/rps/rpsbot/.api
@@ -0,0 +1,21 @@
+pkg main, func NewJudge() *Judge
+pkg main, func NewPlayer() *Player
+pkg main, func NewRPS(*context.T) *RPS
+pkg main, func NewScoreKeeper() *ScoreKeeper
+pkg main, method (*Judge) Stats() int64
+pkg main, method (*Player) InitiateGame(*context.T) error
+pkg main, method (*Player) Stats() (int64, int64)
+pkg main, method (*Player) WaitUntilIdle()
+pkg main, method (*RPS) Challenge(*context.T, rpc.ServerCall, string, rps.GameId, rps.GameOptions) error
+pkg main, method (*RPS) CreateGame(*context.T, rpc.ServerCall, rps.GameOptions) (rps.GameId, error)
+pkg main, method (*RPS) Judge() *Judge
+pkg main, method (*RPS) Play(*context.T, rps.JudgePlayServerCall, rps.GameId) (rps.PlayResult, error)
+pkg main, method (*RPS) Player() *Player
+pkg main, method (*RPS) Record(*context.T, rpc.ServerCall, rps.ScoreCard) error
+pkg main, method (*RPS) ScoreKeeper() *ScoreKeeper
+pkg main, method (*ScoreKeeper) Record(*context.T, rpc.ServerCall, rps.ScoreCard) error
+pkg main, method (*ScoreKeeper) Stats() int64
+pkg main, type Judge struct
+pkg main, type Player struct
+pkg main, type RPS struct
+pkg main, type ScoreKeeper struct
diff --git a/examples/rps/rpsplayer/.api b/examples/rps/rpsplayer/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/examples/rps/rpsplayer/.api
diff --git a/examples/rps/rpsscorekeeper/.api b/examples/rps/rpsscorekeeper/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/examples/rps/rpsscorekeeper/.api
diff --git a/examples/tunnel/.api b/examples/tunnel/.api
new file mode 100644
index 0000000..29be5d4
--- /dev/null
+++ b/examples/tunnel/.api
@@ -0,0 +1,95 @@
+pkg tunnel, func TunnelClient(string) TunnelClientStub
+pkg tunnel, func TunnelServer(TunnelServerMethods) TunnelServerStub
+pkg tunnel, method (*TunnelForwardServerCallStub) Init(rpc.StreamServerCall)
+pkg tunnel, method (*TunnelForwardServerCallStub) RecvStream() interface {  Advance() bool; Value() []byte; Err() error;}
+pkg tunnel, method (*TunnelForwardServerCallStub) SendStream() interface {  Send(item []byte) error;}
+pkg tunnel, method (*TunnelShellServerCallStub) Init(rpc.StreamServerCall)
+pkg tunnel, method (*TunnelShellServerCallStub) RecvStream() interface {  Advance() bool; Value() ClientShellPacket; Err() error;}
+pkg tunnel, method (*TunnelShellServerCallStub) SendStream() interface {  Send(item ServerShellPacket) error;}
+pkg tunnel, method (ClientShellPacketEndOfFile) Index() int
+pkg tunnel, method (ClientShellPacketEndOfFile) Interface() interface{}
+pkg tunnel, method (ClientShellPacketEndOfFile) Name() string
+pkg tunnel, method (ClientShellPacketStdin) Index() int
+pkg tunnel, method (ClientShellPacketStdin) Interface() interface{}
+pkg tunnel, method (ClientShellPacketStdin) Name() string
+pkg tunnel, method (ClientShellPacketWinSize) Index() int
+pkg tunnel, method (ClientShellPacketWinSize) Interface() interface{}
+pkg tunnel, method (ClientShellPacketWinSize) Name() string
+pkg tunnel, method (ServerShellPacketStderr) Index() int
+pkg tunnel, method (ServerShellPacketStderr) Interface() interface{}
+pkg tunnel, method (ServerShellPacketStderr) Name() string
+pkg tunnel, method (ServerShellPacketStdout) Index() int
+pkg tunnel, method (ServerShellPacketStdout) Interface() interface{}
+pkg tunnel, method (ServerShellPacketStdout) Name() string
+pkg tunnel, type ClientShellPacket interface, Index() int
+pkg tunnel, type ClientShellPacket interface, Interface() interface{}
+pkg tunnel, type ClientShellPacket interface, Name() string
+pkg tunnel, type ClientShellPacket interface, unexported methods
+pkg tunnel, type ClientShellPacketEndOfFile struct
+pkg tunnel, type ClientShellPacketEndOfFile struct, Value unused
+pkg tunnel, type ClientShellPacketStdin struct
+pkg tunnel, type ClientShellPacketStdin struct, Value []byte
+pkg tunnel, type ClientShellPacketWinSize struct
+pkg tunnel, type ClientShellPacketWinSize struct, Value WindowSize
+pkg tunnel, type ServerShellPacket interface, Index() int
+pkg tunnel, type ServerShellPacket interface, Interface() interface{}
+pkg tunnel, type ServerShellPacket interface, Name() string
+pkg tunnel, type ServerShellPacket interface, unexported methods
+pkg tunnel, type ServerShellPacketStderr struct
+pkg tunnel, type ServerShellPacketStderr struct, Value []byte
+pkg tunnel, type ServerShellPacketStdout struct
+pkg tunnel, type ServerShellPacketStdout struct, Value []byte
+pkg tunnel, type ShellOpts struct
+pkg tunnel, type ShellOpts struct, Environment []string
+pkg tunnel, type ShellOpts struct, UsePty bool
+pkg tunnel, type ShellOpts struct, WinSize WindowSize
+pkg tunnel, type TunnelClientMethods interface { Forward, Shell }
+pkg tunnel, type TunnelClientMethods interface, Forward(*context.T, string, string, ...rpc.CallOpt) (TunnelForwardClientCall, error)
+pkg tunnel, type TunnelClientMethods interface, Shell(*context.T, string, ShellOpts, ...rpc.CallOpt) (TunnelShellClientCall, error)
+pkg tunnel, type TunnelClientStub interface, Forward(*context.T, string, string, ...rpc.CallOpt) (TunnelForwardClientCall, error)
+pkg tunnel, type TunnelClientStub interface, Shell(*context.T, string, ShellOpts, ...rpc.CallOpt) (TunnelShellClientCall, error)
+pkg tunnel, type TunnelClientStub interface, unexported methods
+pkg tunnel, type TunnelForwardClientCall interface { Finish, RecvStream, SendStream }
+pkg tunnel, type TunnelForwardClientCall interface, Finish() error
+pkg tunnel, type TunnelForwardClientCall interface, RecvStream() interface {  Advance() bool;; Value() []byte;; Err() error;}
+pkg tunnel, type TunnelForwardClientCall interface, SendStream() interface {  Send(item []byte) error;; Close() error;}
+pkg tunnel, type TunnelForwardClientStream interface { RecvStream, SendStream }
+pkg tunnel, type TunnelForwardClientStream interface, RecvStream() interface {  Advance() bool;; Value() []byte;; Err() error;}
+pkg tunnel, type TunnelForwardClientStream interface, SendStream() interface {  Send(item []byte) error;; Close() error;}
+pkg tunnel, type TunnelForwardServerCall interface, RecvStream() interface {  Advance() bool;; Value() []byte;; Err() error;}
+pkg tunnel, type TunnelForwardServerCall interface, SendStream() interface {  Send(item []byte) error;}
+pkg tunnel, type TunnelForwardServerCall interface, unexported methods
+pkg tunnel, type TunnelForwardServerCallStub struct
+pkg tunnel, type TunnelForwardServerCallStub struct, embedded rpc.StreamServerCall
+pkg tunnel, type TunnelForwardServerStream interface { RecvStream, SendStream }
+pkg tunnel, type TunnelForwardServerStream interface, RecvStream() interface {  Advance() bool;; Value() []byte;; Err() error;}
+pkg tunnel, type TunnelForwardServerStream interface, SendStream() interface {  Send(item []byte) error;}
+pkg tunnel, type TunnelServerMethods interface { Forward, Shell }
+pkg tunnel, type TunnelServerMethods interface, Forward(*context.T, TunnelForwardServerCall, string, string) error
+pkg tunnel, type TunnelServerMethods interface, Shell(*context.T, TunnelShellServerCall, string, ShellOpts) (int32, error)
+pkg tunnel, type TunnelServerStub interface { Describe__, Forward, Shell }
+pkg tunnel, type TunnelServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg tunnel, type TunnelServerStub interface, Forward(*context.T, *TunnelForwardServerCallStub, string, string) error
+pkg tunnel, type TunnelServerStub interface, Shell(*context.T, *TunnelShellServerCallStub, string, ShellOpts) (int32, error)
+pkg tunnel, type TunnelServerStubMethods interface { Forward, Shell }
+pkg tunnel, type TunnelServerStubMethods interface, Forward(*context.T, *TunnelForwardServerCallStub, string, string) error
+pkg tunnel, type TunnelServerStubMethods interface, Shell(*context.T, *TunnelShellServerCallStub, string, ShellOpts) (int32, error)
+pkg tunnel, type TunnelShellClientCall interface { Finish, RecvStream, SendStream }
+pkg tunnel, type TunnelShellClientCall interface, Finish() (int32, error)
+pkg tunnel, type TunnelShellClientCall interface, RecvStream() interface {  Advance() bool;; Value() ServerShellPacket;; Err() error;}
+pkg tunnel, type TunnelShellClientCall interface, SendStream() interface {  Send(item ClientShellPacket) error;; Close() error;}
+pkg tunnel, type TunnelShellClientStream interface { RecvStream, SendStream }
+pkg tunnel, type TunnelShellClientStream interface, RecvStream() interface {  Advance() bool;; Value() ServerShellPacket;; Err() error;}
+pkg tunnel, type TunnelShellClientStream interface, SendStream() interface {  Send(item ClientShellPacket) error;; Close() error;}
+pkg tunnel, type TunnelShellServerCall interface, RecvStream() interface {  Advance() bool;; Value() ClientShellPacket;; Err() error;}
+pkg tunnel, type TunnelShellServerCall interface, SendStream() interface {  Send(item ServerShellPacket) error;}
+pkg tunnel, type TunnelShellServerCall interface, unexported methods
+pkg tunnel, type TunnelShellServerCallStub struct
+pkg tunnel, type TunnelShellServerCallStub struct, embedded rpc.StreamServerCall
+pkg tunnel, type TunnelShellServerStream interface { RecvStream, SendStream }
+pkg tunnel, type TunnelShellServerStream interface, RecvStream() interface {  Advance() bool;; Value() ClientShellPacket;; Err() error;}
+pkg tunnel, type TunnelShellServerStream interface, SendStream() interface {  Send(item ServerShellPacket) error;}
+pkg tunnel, type WindowSize struct
+pkg tunnel, type WindowSize struct, Cols uint16
+pkg tunnel, type WindowSize struct, Rows uint16
+pkg tunnel, var TunnelDesc rpc.InterfaceDesc
diff --git a/examples/tunnel/internal/.api b/examples/tunnel/internal/.api
new file mode 100644
index 0000000..2c5268a
--- /dev/null
+++ b/examples/tunnel/internal/.api
@@ -0,0 +1,10 @@
+pkg internal, func EnterRawTerminalMode() string
+pkg internal, func Forward(net.Conn, sender, receiver) error
+pkg internal, func GetWindowSize() (*Winsize, error)
+pkg internal, func RestoreTerminalSettings(string)
+pkg internal, func SetWindowSize(uintptr, Winsize) error
+pkg internal, type Winsize struct
+pkg internal, type Winsize struct, Col uint16
+pkg internal, type Winsize struct, Row uint16
+pkg internal, type Winsize struct, Xpixel uint16
+pkg internal, type Winsize struct, Ypixel uint16
diff --git a/examples/tunnel/tunneld/.api b/examples/tunnel/tunneld/.api
new file mode 100644
index 0000000..d912224
--- /dev/null
+++ b/examples/tunnel/tunneld/.api
@@ -0,0 +1,3 @@
+pkg main, method (*T) Forward(*context.T, tunnel.TunnelForwardServerCall, string, string) error
+pkg main, method (*T) Shell(*context.T, tunnel.TunnelShellServerCall, string, tunnel.ShellOpts) (int32, error)
+pkg main, type T struct
diff --git a/examples/tunnel/vsh/.api b/examples/tunnel/vsh/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/examples/tunnel/vsh/.api
diff --git a/internal/reflectutil/.api b/internal/reflectutil/.api
new file mode 100644
index 0000000..03b663e
--- /dev/null
+++ b/internal/reflectutil/.api
@@ -0,0 +1,10 @@
+pkg reflectutil, func AreComparable(interface{}, interface{}) bool
+pkg reflectutil, func AreComparableTypes(reflect.Type, reflect.Type) bool
+pkg reflectutil, func Compare(interface{}, interface{}) int
+pkg reflectutil, func CompareValues(reflect.Value, reflect.Value) int
+pkg reflectutil, func DeepEqual(interface{}, interface{}, *DeepEqualOpts) bool
+pkg reflectutil, func Less(interface{}, interface{}) bool
+pkg reflectutil, func LessValues(reflect.Value, reflect.Value) bool
+pkg reflectutil, func TrySortValues([]reflect.Value) []reflect.Value
+pkg reflectutil, type DeepEqualOpts struct
+pkg reflectutil, type DeepEqualOpts struct, SliceEqNilEmpty bool
diff --git a/lib/exec/.api b/lib/exec/.api
new file mode 100644
index 0000000..3e3c794
--- /dev/null
+++ b/lib/exec/.api
@@ -0,0 +1,49 @@
+pkg exec, const ExecVersionVariable ideal-string
+pkg exec, const FileOffset ideal-int
+pkg exec, func GetChildHandle() (*ChildHandle, error)
+pkg exec, func Getenv([]string, string) (string, error)
+pkg exec, func Mergeenv([]string, []string) []string
+pkg exec, func NewConfig() Config
+pkg exec, func NewParentHandle(*exec.Cmd, ...ParentHandleOpt) *ParentHandle
+pkg exec, func Setenv([]string, string, string) []string
+pkg exec, method (*ChildHandle) NewExtraFile(uintptr, string) *os.File
+pkg exec, method (*ChildHandle) SetFailed(error) error
+pkg exec, method (*ChildHandle) SetReady() error
+pkg exec, method (*ParentHandle) ChildPid() int
+pkg exec, method (*ParentHandle) Clean() error
+pkg exec, method (*ParentHandle) Exists() bool
+pkg exec, method (*ParentHandle) Kill() error
+pkg exec, method (*ParentHandle) Pid() int
+pkg exec, method (*ParentHandle) Signal(syscall.Signal) error
+pkg exec, method (*ParentHandle) Start() error
+pkg exec, method (*ParentHandle) Wait(time.Duration) error
+pkg exec, method (*ParentHandle) WaitForReady(time.Duration) error
+pkg exec, method (ConfigOpt) ExecParentHandleOpt()
+pkg exec, method (SecretOpt) ExecParentHandleOpt()
+pkg exec, method (TimeKeeperOpt) ExecParentHandleOpt()
+pkg exec, method (UseExecProtocolOpt) ExecParentHandleOpt()
+pkg exec, type ChildHandle struct
+pkg exec, type ChildHandle struct, Config Config
+pkg exec, type ChildHandle struct, Secret string
+pkg exec, type Config interface { Clear, Dump, Get, MergeFrom, Serialize, Set }
+pkg exec, type Config interface, Clear(string)
+pkg exec, type Config interface, Dump() map[string]string
+pkg exec, type Config interface, Get(string) (string, error)
+pkg exec, type Config interface, MergeFrom(string) error
+pkg exec, type Config interface, Serialize() (string, error)
+pkg exec, type Config interface, Set(string, string)
+pkg exec, type ConfigOpt struct
+pkg exec, type ConfigOpt struct, embedded Config
+pkg exec, type ParentHandle struct
+pkg exec, type ParentHandleOpt interface { ExecParentHandleOpt }
+pkg exec, type ParentHandleOpt interface, ExecParentHandleOpt()
+pkg exec, type SecretOpt string
+pkg exec, type TimeKeeperOpt struct
+pkg exec, type TimeKeeperOpt struct, embedded timekeeper.TimeKeeper
+pkg exec, type UseExecProtocolOpt bool
+pkg exec, var ErrAuthTimeout unknown-type
+pkg exec, var ErrNoVersion unknown-type
+pkg exec, var ErrNotUsingProtocol unknown-type
+pkg exec, var ErrSecretTooLarge unknown-type
+pkg exec, var ErrTimeout unknown-type
+pkg exec, var ErrUnsupportedVersion unknown-type
diff --git a/lib/flags/.api b/lib/flags/.api
new file mode 100644
index 0000000..b82bdff
--- /dev/null
+++ b/lib/flags/.api
@@ -0,0 +1,52 @@
+pkg flags, const Listen FlagGroup
+pkg flags, const Permissions FlagGroup
+pkg flags, const Runtime FlagGroup
+pkg flags, func CreateAndRegister(*flag.FlagSet, ...FlagGroup) *Flags
+pkg flags, func DefaultNamespaceRoot() string
+pkg flags, func SetDefaultHostPort(string)
+pkg flags, func SetDefaultNamespaceRoot(string)
+pkg flags, func SetDefaultProtocol(string)
+pkg flags, method (*Flags) Args() []string
+pkg flags, method (*Flags) HasGroup(FlagGroup) bool
+pkg flags, method (*Flags) ListenFlags() ListenFlags
+pkg flags, method (*Flags) Parse([]string, map[string]string) error
+pkg flags, method (*Flags) PermissionsFlags() PermissionsFlags
+pkg flags, method (*Flags) RuntimeFlags() RuntimeFlags
+pkg flags, method (*IPFlag) Set(string) error
+pkg flags, method (*IPHostPortFlag) Set(string) error
+pkg flags, method (*TCPProtocolFlag) Set(string) error
+pkg flags, method (IPFlag) Get() interface{}
+pkg flags, method (IPFlag) String() string
+pkg flags, method (IPHostPortFlag) Get() interface{}
+pkg flags, method (IPHostPortFlag) String() string
+pkg flags, method (PermissionsFlags) PermissionsFile(string) string
+pkg flags, method (PermissionsFlags) PermissionsLiteral() string
+pkg flags, method (TCPProtocolFlag) Get() interface{}
+pkg flags, method (TCPProtocolFlag) String() string
+pkg flags, type FlagGroup int
+pkg flags, type Flags struct
+pkg flags, type Flags struct, FlagSet *flag.FlagSet
+pkg flags, type IPFlag struct
+pkg flags, type IPFlag struct, embedded net.IP
+pkg flags, type IPHostPortFlag struct
+pkg flags, type IPHostPortFlag struct, Address string
+pkg flags, type IPHostPortFlag struct, Host string
+pkg flags, type IPHostPortFlag struct, IP []*net.IPAddr
+pkg flags, type IPHostPortFlag struct, Port string
+pkg flags, type ListenAddrs []struct {  Protocol, Address string;}
+pkg flags, type ListenFlags struct
+pkg flags, type ListenFlags struct, Addrs ListenAddrs
+pkg flags, type ListenFlags struct, ListenProxy string
+pkg flags, type PermissionsFlags struct
+pkg flags, type RuntimeFlags struct
+pkg flags, type RuntimeFlags struct, Credentials string
+pkg flags, type RuntimeFlags struct, I18nCatalogue string
+pkg flags, type RuntimeFlags struct, NamespaceRoots []string
+pkg flags, type RuntimeFlags struct, Vtrace VtraceFlags
+pkg flags, type TCPProtocolFlag struct
+pkg flags, type TCPProtocolFlag struct, Protocol string
+pkg flags, type VtraceFlags struct
+pkg flags, type VtraceFlags struct, CacheSize int
+pkg flags, type VtraceFlags struct, CollectRegexp string
+pkg flags, type VtraceFlags struct, DumpOnShutdown bool
+pkg flags, type VtraceFlags struct, SampleRate float64
diff --git a/lib/glob/.api b/lib/glob/.api
new file mode 100644
index 0000000..380c4fe
--- /dev/null
+++ b/lib/glob/.api
@@ -0,0 +1,10 @@
+pkg glob, func Parse(string) (*Glob, error)
+pkg glob, method (*Glob) Finished() bool
+pkg glob, method (*Glob) Len() int
+pkg glob, method (*Glob) MatchInitialSegment(string) (bool, bool, *Glob)
+pkg glob, method (*Glob) PartialMatch(int, []string) (bool, bool, *Glob)
+pkg glob, method (*Glob) Restricted() bool
+pkg glob, method (*Glob) Split(int) *Glob
+pkg glob, method (*Glob) SplitFixedPrefix() ([]string, *Glob)
+pkg glob, method (*Glob) String() string
+pkg glob, type Glob struct
diff --git a/lib/mgmt/.api b/lib/mgmt/.api
new file mode 100644
index 0000000..d23ac74
--- /dev/null
+++ b/lib/mgmt/.api
@@ -0,0 +1,8 @@
+pkg mgmt, const AddressConfigKey ideal-string
+pkg mgmt, const AppCycleManagerConfigKey ideal-string
+pkg mgmt, const AppOriginConfigKey ideal-string
+pkg mgmt, const ChildNameConfigKey ideal-string
+pkg mgmt, const ParentBlessingConfigKey ideal-string
+pkg mgmt, const ParentNameConfigKey ideal-string
+pkg mgmt, const ProtocolConfigKey ideal-string
+pkg mgmt, const SecurityAgentEndpointConfigKey ideal-string
diff --git a/lib/security/.api b/lib/security/.api
new file mode 100644
index 0000000..f5b8827
--- /dev/null
+++ b/lib/security/.api
@@ -0,0 +1,21 @@
+pkg security, func CreatePersistentPrincipal(string, []byte) (security.Principal, error)
+pkg security, func InitDefaultBlessings(security.Principal, string) error
+pkg security, func LoadPEMKey(io.Reader, []byte) (interface{}, error)
+pkg security, func LoadPersistentPrincipal(string, []byte) (security.Principal, error)
+pkg security, func NewFileSerializer(string, string) *FileSerializer
+pkg security, func NewPrincipal() (security.Principal, error)
+pkg security, func NewPrincipalFromSigner(security.Signer, *PrincipalStateSerializer) (security.Principal, error)
+pkg security, func NewPrincipalKey() (security.PublicKey, *ecdsa.PrivateKey, error)
+pkg security, func NewPrincipalStateSerializer(string) (*PrincipalStateSerializer, error)
+pkg security, func SavePEMKey(io.Writer, interface{}, []byte) error
+pkg security, func SetDefaultBlessings(security.Principal, security.Blessings) error
+pkg security, method (*FileSerializer) Readers() (io.ReadCloser, io.ReadCloser, error)
+pkg security, method (*FileSerializer) Writers() (io.WriteCloser, io.WriteCloser, error)
+pkg security, type FileSerializer struct
+pkg security, type PrincipalStateSerializer struct
+pkg security, type PrincipalStateSerializer struct, BlessingRoots SerializerReaderWriter
+pkg security, type PrincipalStateSerializer struct, BlessingStore SerializerReaderWriter
+pkg security, type SerializerReaderWriter interface { Readers, Writers }
+pkg security, type SerializerReaderWriter interface, Readers() (io.ReadCloser, io.ReadCloser, error)
+pkg security, type SerializerReaderWriter interface, Writers() (io.WriteCloser, io.WriteCloser, error)
+pkg security, var ErrBadPassphrase unknown-type
diff --git a/lib/security/audit/.api b/lib/security/audit/.api
new file mode 100644
index 0000000..7643440
--- /dev/null
+++ b/lib/security/audit/.api
@@ -0,0 +1,9 @@
+pkg audit, func NewPrincipal(security.Principal, Auditor) security.Principal
+pkg audit, method (Entry) String() string
+pkg audit, type Auditor interface { Audit }
+pkg audit, type Auditor interface, Audit(Entry) error
+pkg audit, type Entry struct
+pkg audit, type Entry struct, Arguments []interface{}
+pkg audit, type Entry struct, Method string
+pkg audit, type Entry struct, Results []interface{}
+pkg audit, type Entry struct, Timestamp time.Time
diff --git a/lib/security/securityflag/.api b/lib/security/securityflag/.api
new file mode 100644
index 0000000..f10c25e
--- /dev/null
+++ b/lib/security/securityflag/.api
@@ -0,0 +1,2 @@
+pkg securityflag, func NewAuthorizerOrDie() security.Authorizer
+pkg securityflag, func PermissionsFromFlag() (access.Permissions, error)
diff --git a/lib/security/serialization/.api b/lib/security/serialization/.api
new file mode 100644
index 0000000..a41ee0e
--- /dev/null
+++ b/lib/security/serialization/.api
@@ -0,0 +1,24 @@
+pkg serialization, func NewSigningWriteCloser(io.WriteCloser, io.WriteCloser, Signer, *Options) (io.WriteCloser, error)
+pkg serialization, func NewVerifyingReader(io.Reader, io.Reader, security.PublicKey) (io.Reader, error)
+pkg serialization, method (SignedDataHash) Index() int
+pkg serialization, method (SignedDataHash) Interface() interface{}
+pkg serialization, method (SignedDataHash) Name() string
+pkg serialization, method (SignedDataSignature) Index() int
+pkg serialization, method (SignedDataSignature) Interface() interface{}
+pkg serialization, method (SignedDataSignature) Name() string
+pkg serialization, type HashCode [32]byte
+pkg serialization, type Options struct
+pkg serialization, type Options struct, ChunkSizeBytes int64
+pkg serialization, type SignedData interface, Index() int
+pkg serialization, type SignedData interface, Interface() interface{}
+pkg serialization, type SignedData interface, Name() string
+pkg serialization, type SignedData interface, unexported methods
+pkg serialization, type SignedDataHash struct
+pkg serialization, type SignedDataHash struct, Value HashCode
+pkg serialization, type SignedDataSignature struct
+pkg serialization, type SignedDataSignature struct, Value security.Signature
+pkg serialization, type SignedHeader struct
+pkg serialization, type SignedHeader struct, ChunkSizeBytes int64
+pkg serialization, type Signer interface { PublicKey, Sign }
+pkg serialization, type Signer interface, PublicKey() security.PublicKey
+pkg serialization, type Signer interface, Sign([]byte) (security.Signature, error)
diff --git a/lib/signals/.api b/lib/signals/.api
new file mode 100644
index 0000000..0ae17ce
--- /dev/null
+++ b/lib/signals/.api
@@ -0,0 +1,4 @@
+pkg signals, const DoubleStopExitCode ideal-int
+pkg signals, const STOP stopSignal
+pkg signals, func ShutdownOnSignals(*context.T, ...os.Signal) <-chan os.Signal
+pkg signals, var SameSignalTimeWindow time.Duration
diff --git a/lib/stats/.api b/lib/stats/.api
new file mode 100644
index 0000000..369d592
--- /dev/null
+++ b/lib/stats/.api
@@ -0,0 +1,43 @@
+pkg stats, func Delete(string) error
+pkg stats, func GetStatsObject(string) (StatsObject, error)
+pkg stats, func Glob(string, string, time.Time, bool) *GlobIterator
+pkg stats, func NewCounter(string) *counter.Counter
+pkg stats, func NewFloat(string) *Float
+pkg stats, func NewFloatFunc(string, func() float64) StatsObject
+pkg stats, func NewHistogram(string, histogram.Options) *histogram.Histogram
+pkg stats, func NewInteger(string) *Integer
+pkg stats, func NewIntegerFunc(string, func() int64) StatsObject
+pkg stats, func NewMap(string) *Map
+pkg stats, func NewString(string) *String
+pkg stats, func NewStringFunc(string, func() string) StatsObject
+pkg stats, func Value(string) (interface{}, error)
+pkg stats, method (*Float) Incr(float64)
+pkg stats, method (*Float) LastUpdate() time.Time
+pkg stats, method (*Float) Set(float64)
+pkg stats, method (*Float) Value() interface{}
+pkg stats, method (*GlobIterator) Advance() bool
+pkg stats, method (*Integer) Incr(int64)
+pkg stats, method (*Integer) LastUpdate() time.Time
+pkg stats, method (*Integer) Set(int64)
+pkg stats, method (*Integer) Value() interface{}
+pkg stats, method (*Map) Delete([]string)
+pkg stats, method (*Map) Keys() []string
+pkg stats, method (*Map) LastUpdate() time.Time
+pkg stats, method (*Map) Set([]KeyValue)
+pkg stats, method (*Map) Value() interface{}
+pkg stats, method (*String) LastUpdate() time.Time
+pkg stats, method (*String) Set(string)
+pkg stats, method (*String) Value() interface{}
+pkg stats, method (GlobIterator) Err() error
+pkg stats, method (GlobIterator) Value() KeyValue
+pkg stats, type Float struct
+pkg stats, type GlobIterator struct
+pkg stats, type Integer struct
+pkg stats, type KeyValue struct
+pkg stats, type KeyValue struct, Key string
+pkg stats, type KeyValue struct, Value interface{}
+pkg stats, type Map struct
+pkg stats, type StatsObject interface { LastUpdate, Value }
+pkg stats, type StatsObject interface, LastUpdate() time.Time
+pkg stats, type StatsObject interface, Value() interface{}
+pkg stats, type String struct
diff --git a/lib/stats/counter/.api b/lib/stats/counter/.api
new file mode 100644
index 0000000..fe261b1
--- /dev/null
+++ b/lib/stats/counter/.api
@@ -0,0 +1,27 @@
+pkg counter, func New() *Counter
+pkg counter, func NewTracker() *Tracker
+pkg counter, method (*Counter) Delta10m() int64
+pkg counter, method (*Counter) Delta1h() int64
+pkg counter, method (*Counter) Delta1m() int64
+pkg counter, method (*Counter) Incr(int64)
+pkg counter, method (*Counter) LastUpdate() time.Time
+pkg counter, method (*Counter) Rate10m() float64
+pkg counter, method (*Counter) Rate1h() float64
+pkg counter, method (*Counter) Rate1m() float64
+pkg counter, method (*Counter) Reset()
+pkg counter, method (*Counter) Set(int64)
+pkg counter, method (*Counter) Value() int64
+pkg counter, method (*Tracker) LastUpdate() time.Time
+pkg counter, method (*Tracker) Max() int64
+pkg counter, method (*Tracker) Max10m() int64
+pkg counter, method (*Tracker) Max1h() int64
+pkg counter, method (*Tracker) Max1m() int64
+pkg counter, method (*Tracker) Min() int64
+pkg counter, method (*Tracker) Min10m() int64
+pkg counter, method (*Tracker) Min1h() int64
+pkg counter, method (*Tracker) Min1m() int64
+pkg counter, method (*Tracker) Push(int64)
+pkg counter, method (*Tracker) Reset()
+pkg counter, type Counter struct
+pkg counter, type Tracker struct
+pkg counter, var TimeNow func() time.Time
diff --git a/lib/stats/histogram/.api b/lib/stats/histogram/.api
new file mode 100644
index 0000000..ac99368
--- /dev/null
+++ b/lib/stats/histogram/.api
@@ -0,0 +1,14 @@
+pkg histogram, func New(Options) *Histogram
+pkg histogram, method (*Histogram) Add(int64) error
+pkg histogram, method (*Histogram) Delta10m() stats.HistogramValue
+pkg histogram, method (*Histogram) Delta1h() stats.HistogramValue
+pkg histogram, method (*Histogram) Delta1m() stats.HistogramValue
+pkg histogram, method (*Histogram) LastUpdate() time.Time
+pkg histogram, method (*Histogram) Opts() Options
+pkg histogram, method (*Histogram) Value() stats.HistogramValue
+pkg histogram, type Histogram struct
+pkg histogram, type Options struct
+pkg histogram, type Options struct, GrowthFactor float64
+pkg histogram, type Options struct, MinValue int64
+pkg histogram, type Options struct, NumBuckets int
+pkg histogram, type Options struct, SmallestBucketSize float64
diff --git a/lib/stats/sysstats/.api b/lib/stats/sysstats/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/stats/sysstats/.api
diff --git a/lib/timekeeper/.api b/lib/timekeeper/.api
new file mode 100644
index 0000000..7bab5b8
--- /dev/null
+++ b/lib/timekeeper/.api
@@ -0,0 +1,4 @@
+pkg timekeeper, func RealTime() TimeKeeper
+pkg timekeeper, type TimeKeeper interface { After, Sleep }
+pkg timekeeper, type TimeKeeper interface, After(time.Duration) <-chan time.Time
+pkg timekeeper, type TimeKeeper interface, Sleep(time.Duration)
diff --git a/lib/vdl/build/.api b/lib/vdl/build/.api
new file mode 100644
index 0000000..d66ec25
--- /dev/null
+++ b/lib/vdl/build/.api
@@ -0,0 +1,27 @@
+pkg build, const UnknownPathIsError UnknownPathMode
+pkg build, const UnknownPathIsIgnored UnknownPathMode
+pkg build, func BuildConfig(string, io.Reader, *vdl.Type, []string, *compile.Env) *vdl.Value
+pkg build, func BuildConfigValue(string, io.Reader, []string, *compile.Env, interface{})
+pkg build, func BuildExprs(string, []*vdl.Type, *compile.Env) []*vdl.Value
+pkg build, func BuildPackage(*Package, *compile.Env) *compile.Package
+pkg build, func IsDirPath(string) bool
+pkg build, func IsImportPath(string) bool
+pkg build, func ParsePackage(*Package, parse.Opts, *vdlutil.Errors) []*parse.File
+pkg build, func SrcDirs(*vdlutil.Errors) []string
+pkg build, func TransitivePackages([]string, UnknownPathMode, Opts, *vdlutil.Errors) []*Package
+pkg build, func TransitivePackagesForConfig(string, io.Reader, Opts, *vdlutil.Errors) []*Package
+pkg build, method (*Package) CloseFiles() error
+pkg build, method (*Package) OpenFiles() (map[string]io.Reader, error)
+pkg build, method (UnknownPathMode) String() string
+pkg build, type Opts struct
+pkg build, type Opts struct, Extensions []string
+pkg build, type Opts struct, VDLConfigName string
+pkg build, type Package struct
+pkg build, type Package struct, BaseFileNames []string
+pkg build, type Package struct, Config vdltool.Config
+pkg build, type Package struct, Dir string
+pkg build, type Package struct, GenPath string
+pkg build, type Package struct, Name string
+pkg build, type Package struct, OpenFilesFunc func([]string) (map[string]io.ReadCloser, error)
+pkg build, type Package struct, Path string
+pkg build, type UnknownPathMode int
diff --git a/lib/vdl/codegen/.api b/lib/vdl/codegen/.api
new file mode 100644
index 0000000..9c9f12f
--- /dev/null
+++ b/lib/vdl/codegen/.api
@@ -0,0 +1,8 @@
+pkg codegen, func ImportsForFiles(...*compile.File) Imports
+pkg codegen, func ImportsForValue(*vdl.Value, string) Imports
+pkg codegen, method (Imports) LookupLocal(string) string
+pkg codegen, type Import struct
+pkg codegen, type Import struct, Local string
+pkg codegen, type Import struct, Name string
+pkg codegen, type Import struct, Path string
+pkg codegen, type Imports []Import
diff --git a/lib/vdl/codegen/golang/.api b/lib/vdl/codegen/golang/.api
new file mode 100644
index 0000000..09ce08a
--- /dev/null
+++ b/lib/vdl/codegen/golang/.api
@@ -0,0 +1 @@
+pkg golang, func Generate(*compile.File, *compile.Env) []byte
diff --git a/lib/vdl/codegen/java/.api b/lib/vdl/codegen/java/.api
new file mode 100644
index 0000000..d8a7ffc
--- /dev/null
+++ b/lib/vdl/codegen/java/.api
@@ -0,0 +1,6 @@
+pkg java, func Generate(*compile.Package, *compile.Env) []JavaFileInfo
+pkg java, func SetPkgPathXlator(func(string) string)
+pkg java, type JavaFileInfo struct
+pkg java, type JavaFileInfo struct, Data []byte
+pkg java, type JavaFileInfo struct, Dir string
+pkg java, type JavaFileInfo struct, Name string
diff --git a/lib/vdl/codegen/javascript/.api b/lib/vdl/codegen/javascript/.api
new file mode 100644
index 0000000..d557939
--- /dev/null
+++ b/lib/vdl/codegen/javascript/.api
@@ -0,0 +1 @@
+pkg javascript, func Generate(*compile.Package, *compile.Env, func(string) string, string) []byte
diff --git a/lib/vdl/codegen/vdlgen/.api b/lib/vdl/codegen/vdlgen/.api
new file mode 100644
index 0000000..fd09b5e
--- /dev/null
+++ b/lib/vdl/codegen/vdlgen/.api
@@ -0,0 +1,11 @@
+pkg vdlgen, func BaseType(*vdl.Type, string, codegen.Imports) string
+pkg vdlgen, func Imports(codegen.Imports) string
+pkg vdlgen, func PrintEmbed(io.Writer, signature.Embed)
+pkg vdlgen, func PrintInterface(io.Writer, signature.Interface, *NamedTypes)
+pkg vdlgen, func PrintMethod(io.Writer, signature.Method, *NamedTypes)
+pkg vdlgen, func Type(*vdl.Type, string, codegen.Imports) string
+pkg vdlgen, func TypedConst(*vdl.Value, string, codegen.Imports) string
+pkg vdlgen, func UntypedConst(*vdl.Value, string, codegen.Imports) string
+pkg vdlgen, method (*NamedTypes) Add(*vdl.Type)
+pkg vdlgen, method (NamedTypes) Print(io.Writer)
+pkg vdlgen, type NamedTypes struct
diff --git a/lib/vdl/compile/.api b/lib/vdl/compile/.api
new file mode 100644
index 0000000..0739783
--- /dev/null
+++ b/lib/vdl/compile/.api
@@ -0,0 +1,99 @@
+pkg compile, func CompileConfig(*vdl.Type, *parse.Config, *Env) *vdl.Value
+pkg compile, func CompileExpr(*vdl.Type, parse.ConstExpr, *Env) *vdl.Value
+pkg compile, func CompilePackage(string, string, []*parse.File, vdltool.Config, *Env) *Package
+pkg compile, func NewEnv(int) *Env
+pkg compile, func NewEnvWithErrors(*vdlutil.Errors) *Env
+pkg compile, method (*ConstDef) String() string
+pkg compile, method (*Env) DisallowPathQualifiers() *Env
+pkg compile, method (*Env) Errorf(*File, parse.Pos, string, ...interface{})
+pkg compile, method (*Env) EvalConst(string, *File) (opconst.Const, error)
+pkg compile, method (*Env) FindConstDef(*vdl.Value) *ConstDef
+pkg compile, method (*Env) FindTypeDef(*vdl.Type) *TypeDef
+pkg compile, method (*Env) ResolveConst(string, *File) (*ConstDef, string)
+pkg compile, method (*Env) ResolveInterface(string, *File) (*Interface, string)
+pkg compile, method (*Env) ResolvePackage(string) *Package
+pkg compile, method (*Env) ResolveType(string, *File) (*TypeDef, string)
+pkg compile, method (*ErrorDef) String() string
+pkg compile, method (*Field) String() string
+pkg compile, method (*File) DeclareIdent(string, string) error
+pkg compile, method (*File) LookupImportPath(string) string
+pkg compile, method (*File) String() string
+pkg compile, method (*File) ValidateImportPackagePath(string) bool
+pkg compile, method (*Interface) AllMethods() []*Method
+pkg compile, method (*Interface) String() string
+pkg compile, method (*Interface) TransitiveEmbeds() []*Interface
+pkg compile, method (*Method) String() string
+pkg compile, method (*NamePos) String() string
+pkg compile, method (*Package) QualifiedName(string) string
+pkg compile, method (*Package) ResolveConst(string) *ConstDef
+pkg compile, method (*Package) ResolveInterface(string) *Interface
+pkg compile, method (*Package) ResolveType(string) *TypeDef
+pkg compile, method (*Package) String() string
+pkg compile, method (*TypeDef) String() string
+pkg compile, type ConstDef struct
+pkg compile, type ConstDef struct, Exported bool
+pkg compile, type ConstDef struct, File *File
+pkg compile, type ConstDef struct, Value *vdl.Value
+pkg compile, type ConstDef struct, embedded NamePos
+pkg compile, type Env struct
+pkg compile, type Env struct, Errors *vdlutil.Errors
+pkg compile, type ErrorDef struct
+pkg compile, type ErrorDef struct, English string
+pkg compile, type ErrorDef struct, Exported bool
+pkg compile, type ErrorDef struct, Formats []LangFmt
+pkg compile, type ErrorDef struct, ID string
+pkg compile, type ErrorDef struct, Params []*Field
+pkg compile, type ErrorDef struct, RetryCode vdl.WireRetryCode
+pkg compile, type ErrorDef struct, embedded NamePos
+pkg compile, type Field struct
+pkg compile, type Field struct, Type *vdl.Type
+pkg compile, type Field struct, embedded NamePos
+pkg compile, type File struct
+pkg compile, type File struct, BaseName string
+pkg compile, type File struct, ConstDefs []*ConstDef
+pkg compile, type File struct, ErrorDefs []*ErrorDef
+pkg compile, type File struct, Interfaces []*Interface
+pkg compile, type File struct, Package *Package
+pkg compile, type File struct, PackageDef NamePos
+pkg compile, type File struct, PackageDeps []*Package
+pkg compile, type File struct, TypeDefs []*TypeDef
+pkg compile, type File struct, TypeDeps map[*vdl.Type]bool
+pkg compile, type Interface struct
+pkg compile, type Interface struct, Embeds []*Interface
+pkg compile, type Interface struct, Exported bool
+pkg compile, type Interface struct, File *File
+pkg compile, type Interface struct, Methods []*Method
+pkg compile, type Interface struct, embedded NamePos
+pkg compile, type LangFmt struct
+pkg compile, type LangFmt struct, Fmt string
+pkg compile, type LangFmt struct, Lang i18n.LangID
+pkg compile, type Method struct
+pkg compile, type Method struct, InArgs []*Field
+pkg compile, type Method struct, InStream *vdl.Type
+pkg compile, type Method struct, OutArgs []*Field
+pkg compile, type Method struct, OutStream *vdl.Type
+pkg compile, type Method struct, Tags []*vdl.Value
+pkg compile, type Method struct, embedded NamePos
+pkg compile, type NamePos parse.NamePos
+pkg compile, type Package struct
+pkg compile, type Package struct, Config vdltool.Config
+pkg compile, type Package struct, FileDoc string
+pkg compile, type Package struct, Files []*File
+pkg compile, type Package struct, GenPath string
+pkg compile, type Package struct, Name string
+pkg compile, type Package struct, Path string
+pkg compile, type TypeDef struct
+pkg compile, type TypeDef struct, BaseType *vdl.Type
+pkg compile, type TypeDef struct, Exported bool
+pkg compile, type TypeDef struct, FieldDoc []string
+pkg compile, type TypeDef struct, FieldDocSuffix []string
+pkg compile, type TypeDef struct, File *File
+pkg compile, type TypeDef struct, LabelDoc []string
+pkg compile, type TypeDef struct, LabelDocSuffix []string
+pkg compile, type TypeDef struct, Type *vdl.Type
+pkg compile, type TypeDef struct, embedded NamePos
+pkg compile, var BuiltInFile *File
+pkg compile, var BuiltInPackage *Package
+pkg compile, var FalseConst unknown-type
+pkg compile, var NilConst unknown-type
+pkg compile, var TrueConst unknown-type
diff --git a/lib/vdl/internal/vdltest/.api b/lib/vdl/internal/vdltest/.api
new file mode 100644
index 0000000..50c41ed
--- /dev/null
+++ b/lib/vdl/internal/vdltest/.api
@@ -0,0 +1,5 @@
+pkg vdltest, func ExpectFail(*testing.T, *vdlutil.Errors, string, ...string)
+pkg vdltest, func ExpectPass(*testing.T, *vdlutil.Errors, string)
+pkg vdltest, func ExpectResult(*testing.T, *vdlutil.Errors, string, ...string)
+pkg vdltest, func FakeBuildPackage(string, string, map[string]string) *build.Package
+pkg vdltest, func FakeOpenFiles(map[string]string) func([]string) (map[string]io.ReadCloser, error)
diff --git a/lib/vdl/opconst/.api b/lib/vdl/opconst/.api
new file mode 100644
index 0000000..8bff5b5
--- /dev/null
+++ b/lib/vdl/opconst/.api
@@ -0,0 +1,44 @@
+pkg opconst, const Add BinaryOp
+pkg opconst, const BitAnd BinaryOp
+pkg opconst, const BitNot UnaryOp
+pkg opconst, const BitOr BinaryOp
+pkg opconst, const BitXor BinaryOp
+pkg opconst, const Div BinaryOp
+pkg opconst, const EQ BinaryOp
+pkg opconst, const GE BinaryOp
+pkg opconst, const GT BinaryOp
+pkg opconst, const InvalidBinaryOp BinaryOp
+pkg opconst, const InvalidUnaryOp UnaryOp
+pkg opconst, const LE BinaryOp
+pkg opconst, const LT BinaryOp
+pkg opconst, const LeftShift BinaryOp
+pkg opconst, const LogicAnd BinaryOp
+pkg opconst, const LogicNot UnaryOp
+pkg opconst, const LogicOr BinaryOp
+pkg opconst, const Mod BinaryOp
+pkg opconst, const Mul BinaryOp
+pkg opconst, const NE BinaryOp
+pkg opconst, const Neg UnaryOp
+pkg opconst, const Pos UnaryOp
+pkg opconst, const RightShift BinaryOp
+pkg opconst, const Sub BinaryOp
+pkg opconst, func Boolean(bool) Const
+pkg opconst, func Complex(*big.Rat, *big.Rat) Const
+pkg opconst, func EvalBinary(BinaryOp, Const, Const) (Const, error)
+pkg opconst, func EvalUnary(UnaryOp, Const) (Const, error)
+pkg opconst, func FromValue(*vdl.Value) Const
+pkg opconst, func Integer(*big.Int) Const
+pkg opconst, func Rational(*big.Rat) Const
+pkg opconst, func String(string) Const
+pkg opconst, func ToBinaryOp(string) BinaryOp
+pkg opconst, func ToUnaryOp(string) UnaryOp
+pkg opconst, method (BinaryOp) String() string
+pkg opconst, method (Const) Convert(*vdl.Type) (Const, error)
+pkg opconst, method (Const) IsValid() bool
+pkg opconst, method (Const) String() string
+pkg opconst, method (Const) ToValue() (*vdl.Value, error)
+pkg opconst, method (Const) Type() *vdl.Type
+pkg opconst, method (UnaryOp) String() string
+pkg opconst, type BinaryOp uint
+pkg opconst, type Const struct
+pkg opconst, type UnaryOp uint
diff --git a/lib/vdl/parse/.api b/lib/vdl/parse/.api
new file mode 100644
index 0000000..d649b27
--- /dev/null
+++ b/lib/vdl/parse/.api
@@ -0,0 +1,193 @@
+pkg parse, func InferPackageName([]*File, *vdlutil.Errors) string
+pkg parse, func ParseConfig(string, io.Reader, Opts, *vdlutil.Errors) *Config
+pkg parse, func ParseExprs(string, *vdlutil.Errors) []ConstExpr
+pkg parse, func ParseFile(string, io.Reader, Opts, *vdlutil.Errors) *File
+pkg parse, func QuoteStripDoc(string) string
+pkg parse, method (*Config) AddImports(...string)
+pkg parse, method (*Config) HasImport(string) bool
+pkg parse, method (*ConstBinaryOp) Pos() Pos
+pkg parse, method (*ConstBinaryOp) String() string
+pkg parse, method (*ConstCompositeLit) Pos() Pos
+pkg parse, method (*ConstCompositeLit) String() string
+pkg parse, method (*ConstDef) String() string
+pkg parse, method (*ConstIndexed) Pos() Pos
+pkg parse, method (*ConstIndexed) String() string
+pkg parse, method (*ConstLit) Pos() Pos
+pkg parse, method (*ConstLit) String() string
+pkg parse, method (*ConstNamed) Pos() Pos
+pkg parse, method (*ConstNamed) String() string
+pkg parse, method (*ConstTypeConv) Pos() Pos
+pkg parse, method (*ConstTypeConv) String() string
+pkg parse, method (*ConstTypeObject) Pos() Pos
+pkg parse, method (*ConstTypeObject) String() string
+pkg parse, method (*ConstUnaryOp) Pos() Pos
+pkg parse, method (*ConstUnaryOp) String() string
+pkg parse, method (*ErrorDef) String() string
+pkg parse, method (*Field) String() string
+pkg parse, method (*File) String() string
+pkg parse, method (*Import) LocalName() string
+pkg parse, method (*Import) String() string
+pkg parse, method (*Interface) String() string
+pkg parse, method (*Method) String() string
+pkg parse, method (*NamePos) String() string
+pkg parse, method (*TypeArray) Kind() string
+pkg parse, method (*TypeArray) Pos() Pos
+pkg parse, method (*TypeArray) String() string
+pkg parse, method (*TypeDef) String() string
+pkg parse, method (*TypeEnum) Kind() string
+pkg parse, method (*TypeEnum) Pos() Pos
+pkg parse, method (*TypeEnum) String() string
+pkg parse, method (*TypeList) Kind() string
+pkg parse, method (*TypeList) Pos() Pos
+pkg parse, method (*TypeList) String() string
+pkg parse, method (*TypeMap) Kind() string
+pkg parse, method (*TypeMap) Pos() Pos
+pkg parse, method (*TypeMap) String() string
+pkg parse, method (*TypeNamed) Kind() string
+pkg parse, method (*TypeNamed) Pos() Pos
+pkg parse, method (*TypeNamed) String() string
+pkg parse, method (*TypeOptional) Kind() string
+pkg parse, method (*TypeOptional) Pos() Pos
+pkg parse, method (*TypeOptional) String() string
+pkg parse, method (*TypeSet) Kind() string
+pkg parse, method (*TypeSet) Pos() Pos
+pkg parse, method (*TypeSet) String() string
+pkg parse, method (*TypeStruct) Kind() string
+pkg parse, method (*TypeStruct) Pos() Pos
+pkg parse, method (*TypeStruct) String() string
+pkg parse, method (*TypeUnion) Kind() string
+pkg parse, method (*TypeUnion) Pos() Pos
+pkg parse, method (*TypeUnion) String() string
+pkg parse, method (LangFmt) Pos() Pos
+pkg parse, method (Pos) IsValid() bool
+pkg parse, method (Pos) String() string
+pkg parse, type BigImag big.Rat
+pkg parse, type Config struct
+pkg parse, type Config struct, Config ConstExpr
+pkg parse, type Config struct, ConfigDef NamePos
+pkg parse, type Config struct, ConstDefs []*ConstDef
+pkg parse, type Config struct, Doc string
+pkg parse, type Config struct, FileName string
+pkg parse, type Config struct, Imports []*Import
+pkg parse, type ConstBinaryOp struct
+pkg parse, type ConstBinaryOp struct, Lexpr ConstExpr
+pkg parse, type ConstBinaryOp struct, Op string
+pkg parse, type ConstBinaryOp struct, P Pos
+pkg parse, type ConstBinaryOp struct, Rexpr ConstExpr
+pkg parse, type ConstCompositeLit struct
+pkg parse, type ConstCompositeLit struct, KVList []KVLit
+pkg parse, type ConstCompositeLit struct, P Pos
+pkg parse, type ConstCompositeLit struct, Type Type
+pkg parse, type ConstDef struct
+pkg parse, type ConstDef struct, Expr ConstExpr
+pkg parse, type ConstDef struct, embedded NamePos
+pkg parse, type ConstExpr interface { Pos, String }
+pkg parse, type ConstExpr interface, Pos() Pos
+pkg parse, type ConstExpr interface, String() string
+pkg parse, type ConstIndexed struct
+pkg parse, type ConstIndexed struct, Expr *ConstNamed
+pkg parse, type ConstIndexed struct, IndexExpr ConstExpr
+pkg parse, type ConstIndexed struct, P Pos
+pkg parse, type ConstLit struct
+pkg parse, type ConstLit struct, Lit interface{}
+pkg parse, type ConstLit struct, P Pos
+pkg parse, type ConstNamed struct
+pkg parse, type ConstNamed struct, Name string
+pkg parse, type ConstNamed struct, P Pos
+pkg parse, type ConstTypeConv struct
+pkg parse, type ConstTypeConv struct, Expr ConstExpr
+pkg parse, type ConstTypeConv struct, P Pos
+pkg parse, type ConstTypeConv struct, Type Type
+pkg parse, type ConstTypeObject struct
+pkg parse, type ConstTypeObject struct, P Pos
+pkg parse, type ConstTypeObject struct, Type Type
+pkg parse, type ConstUnaryOp struct
+pkg parse, type ConstUnaryOp struct, Expr ConstExpr
+pkg parse, type ConstUnaryOp struct, Op string
+pkg parse, type ConstUnaryOp struct, P Pos
+pkg parse, type ErrorDef struct
+pkg parse, type ErrorDef struct, Actions []StringPos
+pkg parse, type ErrorDef struct, Formats []LangFmt
+pkg parse, type ErrorDef struct, Params []*Field
+pkg parse, type ErrorDef struct, embedded NamePos
+pkg parse, type Field struct
+pkg parse, type Field struct, Type Type
+pkg parse, type Field struct, embedded NamePos
+pkg parse, type File struct
+pkg parse, type File struct, BaseName string
+pkg parse, type File struct, ConstDefs []*ConstDef
+pkg parse, type File struct, Doc string
+pkg parse, type File struct, ErrorDefs []*ErrorDef
+pkg parse, type File struct, Imports []*Import
+pkg parse, type File struct, Interfaces []*Interface
+pkg parse, type File struct, PackageDef NamePos
+pkg parse, type File struct, TypeDefs []*TypeDef
+pkg parse, type Import struct
+pkg parse, type Import struct, Path string
+pkg parse, type Import struct, embedded NamePos
+pkg parse, type Interface struct
+pkg parse, type Interface struct, Embeds []*NamePos
+pkg parse, type Interface struct, Methods []*Method
+pkg parse, type Interface struct, embedded NamePos
+pkg parse, type KVLit struct
+pkg parse, type KVLit struct, Key ConstExpr
+pkg parse, type KVLit struct, Value ConstExpr
+pkg parse, type LangFmt struct
+pkg parse, type LangFmt struct, Fmt StringPos
+pkg parse, type LangFmt struct, Lang StringPos
+pkg parse, type Method struct
+pkg parse, type Method struct, InArgs []*Field
+pkg parse, type Method struct, InStream Type
+pkg parse, type Method struct, OutArgs []*Field
+pkg parse, type Method struct, OutStream Type
+pkg parse, type Method struct, Tags []ConstExpr
+pkg parse, type Method struct, embedded NamePos
+pkg parse, type NamePos struct
+pkg parse, type NamePos struct, Doc string
+pkg parse, type NamePos struct, DocSuffix string
+pkg parse, type NamePos struct, Name string
+pkg parse, type NamePos struct, Pos Pos
+pkg parse, type Opts struct
+pkg parse, type Opts struct, ImportsOnly bool
+pkg parse, type Pos struct
+pkg parse, type Pos struct, Col int
+pkg parse, type Pos struct, Line int
+pkg parse, type StringPos struct
+pkg parse, type StringPos struct, Pos Pos
+pkg parse, type StringPos struct, String string
+pkg parse, type Type interface { Kind, Pos, String }
+pkg parse, type Type interface, Kind() string
+pkg parse, type Type interface, Pos() Pos
+pkg parse, type Type interface, String() string
+pkg parse, type TypeArray struct
+pkg parse, type TypeArray struct, Elem Type
+pkg parse, type TypeArray struct, Len int
+pkg parse, type TypeArray struct, P Pos
+pkg parse, type TypeDef struct
+pkg parse, type TypeDef struct, Type Type
+pkg parse, type TypeDef struct, embedded NamePos
+pkg parse, type TypeEnum struct
+pkg parse, type TypeEnum struct, Labels []NamePos
+pkg parse, type TypeEnum struct, P Pos
+pkg parse, type TypeList struct
+pkg parse, type TypeList struct, Elem Type
+pkg parse, type TypeList struct, P Pos
+pkg parse, type TypeMap struct
+pkg parse, type TypeMap struct, Elem Type
+pkg parse, type TypeMap struct, Key Type
+pkg parse, type TypeMap struct, P Pos
+pkg parse, type TypeNamed struct
+pkg parse, type TypeNamed struct, Name string
+pkg parse, type TypeNamed struct, P Pos
+pkg parse, type TypeOptional struct
+pkg parse, type TypeOptional struct, Base Type
+pkg parse, type TypeOptional struct, P Pos
+pkg parse, type TypeSet struct
+pkg parse, type TypeSet struct, Key Type
+pkg parse, type TypeSet struct, P Pos
+pkg parse, type TypeStruct struct
+pkg parse, type TypeStruct struct, Fields []*Field
+pkg parse, type TypeStruct struct, P Pos
+pkg parse, type TypeUnion struct
+pkg parse, type TypeUnion struct, Fields []*Field
+pkg parse, type TypeUnion struct, P Pos
diff --git a/lib/vdl/testdata/arith/.api b/lib/vdl/testdata/arith/.api
new file mode 100644
index 0000000..9622783
--- /dev/null
+++ b/lib/vdl/testdata/arith/.api
@@ -0,0 +1,182 @@
+pkg arith, const FloatConst float64
+pkg arith, const Hello ideal-string
+pkg arith, const Int32Const int32
+pkg arith, const Int64Const int64
+pkg arith, const Mask uint64
+pkg arith, const No bool
+pkg arith, const Yes bool
+pkg arith, func AdvancedMathClient(string) AdvancedMathClientStub
+pkg arith, func AdvancedMathServer(AdvancedMathServerMethods) AdvancedMathServerStub
+pkg arith, func ArithClient(string) ArithClientStub
+pkg arith, func ArithServer(ArithServerMethods) ArithServerStub
+pkg arith, func CalculatorClient(string) CalculatorClientStub
+pkg arith, func CalculatorServer(CalculatorServerMethods) CalculatorServerStub
+pkg arith, func TrigonometryClient(string) TrigonometryClientStub
+pkg arith, func TrigonometryServer(TrigonometryServerMethods) TrigonometryServerStub
+pkg arith, method (*ArithCountServerCallStub) Init(rpc.StreamServerCall)
+pkg arith, method (*ArithCountServerCallStub) SendStream() interface {  Send(item int32) error;}
+pkg arith, method (*ArithStreamingAddServerCallStub) Init(rpc.StreamServerCall)
+pkg arith, method (*ArithStreamingAddServerCallStub) RecvStream() interface {  Advance() bool; Value() int32; Err() error;}
+pkg arith, method (*ArithStreamingAddServerCallStub) SendStream() interface {  Send(item int32) error;}
+pkg arith, type AdvancedMathClientMethods interface, Cosine(*context.T, float64, ...rpc.CallOpt) (float64, error)
+pkg arith, type AdvancedMathClientMethods interface, Sine(*context.T, float64, ...rpc.CallOpt) (float64, error)
+pkg arith, type AdvancedMathClientMethods interface, unexported methods
+pkg arith, type AdvancedMathClientStub interface, Cosine(*context.T, float64, ...rpc.CallOpt) (float64, error)
+pkg arith, type AdvancedMathClientStub interface, Sine(*context.T, float64, ...rpc.CallOpt) (float64, error)
+pkg arith, type AdvancedMathClientStub interface, unexported methods
+pkg arith, type AdvancedMathServerMethods interface, Cosine(*context.T, rpc.ServerCall, float64) (float64, error)
+pkg arith, type AdvancedMathServerMethods interface, Sine(*context.T, rpc.ServerCall, float64) (float64, error)
+pkg arith, type AdvancedMathServerMethods interface, unexported methods
+pkg arith, type AdvancedMathServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg arith, type AdvancedMathServerStub interface, unexported methods
+pkg arith, type AdvancedMathServerStubMethods AdvancedMathServerMethods
+pkg arith, type ArithClientMethods interface { Add, Count, DivMod, GenError, Mul, QuoteAny, StreamingAdd, Sub }
+pkg arith, type ArithClientMethods interface, Add(*context.T, int32, int32, ...rpc.CallOpt) (int32, error)
+pkg arith, type ArithClientMethods interface, Count(*context.T, int32, ...rpc.CallOpt) (ArithCountClientCall, error)
+pkg arith, type ArithClientMethods interface, DivMod(*context.T, int32, int32, ...rpc.CallOpt) (int32, int32, error)
+pkg arith, type ArithClientMethods interface, GenError(*context.T, ...rpc.CallOpt) error
+pkg arith, type ArithClientMethods interface, Mul(*context.T, base.NestedArgs, ...rpc.CallOpt) (int32, error)
+pkg arith, type ArithClientMethods interface, QuoteAny(*context.T, *vdl.Value, ...rpc.CallOpt) (*vdl.Value, error)
+pkg arith, type ArithClientMethods interface, StreamingAdd(*context.T, ...rpc.CallOpt) (ArithStreamingAddClientCall, error)
+pkg arith, type ArithClientMethods interface, Sub(*context.T, base.Args, ...rpc.CallOpt) (int32, error)
+pkg arith, type ArithClientStub interface, Add(*context.T, int32, int32, ...rpc.CallOpt) (int32, error)
+pkg arith, type ArithClientStub interface, Count(*context.T, int32, ...rpc.CallOpt) (ArithCountClientCall, error)
+pkg arith, type ArithClientStub interface, DivMod(*context.T, int32, int32, ...rpc.CallOpt) (int32, int32, error)
+pkg arith, type ArithClientStub interface, GenError(*context.T, ...rpc.CallOpt) error
+pkg arith, type ArithClientStub interface, Mul(*context.T, base.NestedArgs, ...rpc.CallOpt) (int32, error)
+pkg arith, type ArithClientStub interface, QuoteAny(*context.T, *vdl.Value, ...rpc.CallOpt) (*vdl.Value, error)
+pkg arith, type ArithClientStub interface, StreamingAdd(*context.T, ...rpc.CallOpt) (ArithStreamingAddClientCall, error)
+pkg arith, type ArithClientStub interface, Sub(*context.T, base.Args, ...rpc.CallOpt) (int32, error)
+pkg arith, type ArithClientStub interface, unexported methods
+pkg arith, type ArithCountClientCall interface { Finish, RecvStream }
+pkg arith, type ArithCountClientCall interface, Finish() error
+pkg arith, type ArithCountClientCall interface, RecvStream() interface {  Advance() bool;; Value() int32;; Err() error;}
+pkg arith, type ArithCountClientStream interface { RecvStream }
+pkg arith, type ArithCountClientStream interface, RecvStream() interface {  Advance() bool;; Value() int32;; Err() error;}
+pkg arith, type ArithCountServerCall interface, SendStream() interface {  Send(item int32) error;}
+pkg arith, type ArithCountServerCall interface, unexported methods
+pkg arith, type ArithCountServerCallStub struct
+pkg arith, type ArithCountServerCallStub struct, embedded rpc.StreamServerCall
+pkg arith, type ArithCountServerStream interface { SendStream }
+pkg arith, type ArithCountServerStream interface, SendStream() interface {  Send(item int32) error;}
+pkg arith, type ArithServerMethods interface { Add, Count, DivMod, GenError, Mul, QuoteAny, StreamingAdd, Sub }
+pkg arith, type ArithServerMethods interface, Add(*context.T, rpc.ServerCall, int32, int32) (int32, error)
+pkg arith, type ArithServerMethods interface, Count(*context.T, ArithCountServerCall, int32) error
+pkg arith, type ArithServerMethods interface, DivMod(*context.T, rpc.ServerCall, int32, int32) (int32, int32, error)
+pkg arith, type ArithServerMethods interface, GenError(*context.T, rpc.ServerCall) error
+pkg arith, type ArithServerMethods interface, Mul(*context.T, rpc.ServerCall, base.NestedArgs) (int32, error)
+pkg arith, type ArithServerMethods interface, QuoteAny(*context.T, rpc.ServerCall, *vdl.Value) (*vdl.Value, error)
+pkg arith, type ArithServerMethods interface, StreamingAdd(*context.T, ArithStreamingAddServerCall) (int32, error)
+pkg arith, type ArithServerMethods interface, Sub(*context.T, rpc.ServerCall, base.Args) (int32, error)
+pkg arith, type ArithServerStub interface { Add, Count, Describe__, DivMod, GenError, Mul, QuoteAny, StreamingAdd, Sub }
+pkg arith, type ArithServerStub interface, Add(*context.T, rpc.ServerCall, int32, int32) (int32, error)
+pkg arith, type ArithServerStub interface, Count(*context.T, *ArithCountServerCallStub, int32) error
+pkg arith, type ArithServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg arith, type ArithServerStub interface, DivMod(*context.T, rpc.ServerCall, int32, int32) (int32, int32, error)
+pkg arith, type ArithServerStub interface, GenError(*context.T, rpc.ServerCall) error
+pkg arith, type ArithServerStub interface, Mul(*context.T, rpc.ServerCall, base.NestedArgs) (int32, error)
+pkg arith, type ArithServerStub interface, QuoteAny(*context.T, rpc.ServerCall, *vdl.Value) (*vdl.Value, error)
+pkg arith, type ArithServerStub interface, StreamingAdd(*context.T, *ArithStreamingAddServerCallStub) (int32, error)
+pkg arith, type ArithServerStub interface, Sub(*context.T, rpc.ServerCall, base.Args) (int32, error)
+pkg arith, type ArithServerStubMethods interface { Add, Count, DivMod, GenError, Mul, QuoteAny, StreamingAdd, Sub }
+pkg arith, type ArithServerStubMethods interface, Add(*context.T, rpc.ServerCall, int32, int32) (int32, error)
+pkg arith, type ArithServerStubMethods interface, Count(*context.T, *ArithCountServerCallStub, int32) error
+pkg arith, type ArithServerStubMethods interface, DivMod(*context.T, rpc.ServerCall, int32, int32) (int32, int32, error)
+pkg arith, type ArithServerStubMethods interface, GenError(*context.T, rpc.ServerCall) error
+pkg arith, type ArithServerStubMethods interface, Mul(*context.T, rpc.ServerCall, base.NestedArgs) (int32, error)
+pkg arith, type ArithServerStubMethods interface, QuoteAny(*context.T, rpc.ServerCall, *vdl.Value) (*vdl.Value, error)
+pkg arith, type ArithServerStubMethods interface, StreamingAdd(*context.T, *ArithStreamingAddServerCallStub) (int32, error)
+pkg arith, type ArithServerStubMethods interface, Sub(*context.T, rpc.ServerCall, base.Args) (int32, error)
+pkg arith, type ArithStreamingAddClientCall interface { Finish, RecvStream, SendStream }
+pkg arith, type ArithStreamingAddClientCall interface, Finish() (int32, error)
+pkg arith, type ArithStreamingAddClientCall interface, RecvStream() interface {  Advance() bool;; Value() int32;; Err() error;}
+pkg arith, type ArithStreamingAddClientCall interface, SendStream() interface {  Send(item int32) error;; Close() error;}
+pkg arith, type ArithStreamingAddClientStream interface { RecvStream, SendStream }
+pkg arith, type ArithStreamingAddClientStream interface, RecvStream() interface {  Advance() bool;; Value() int32;; Err() error;}
+pkg arith, type ArithStreamingAddClientStream interface, SendStream() interface {  Send(item int32) error;; Close() error;}
+pkg arith, type ArithStreamingAddServerCall interface, RecvStream() interface {  Advance() bool;; Value() int32;; Err() error;}
+pkg arith, type ArithStreamingAddServerCall interface, SendStream() interface {  Send(item int32) error;}
+pkg arith, type ArithStreamingAddServerCall interface, unexported methods
+pkg arith, type ArithStreamingAddServerCallStub struct
+pkg arith, type ArithStreamingAddServerCallStub struct, embedded rpc.StreamServerCall
+pkg arith, type ArithStreamingAddServerStream interface { RecvStream, SendStream }
+pkg arith, type ArithStreamingAddServerStream interface, RecvStream() interface {  Advance() bool;; Value() int32;; Err() error;}
+pkg arith, type ArithStreamingAddServerStream interface, SendStream() interface {  Send(item int32) error;}
+pkg arith, type CalculatorClientMethods interface, Add(*context.T, int32, int32, ...rpc.CallOpt) (int32, error)
+pkg arith, type CalculatorClientMethods interface, Cosine(*context.T, float64, ...rpc.CallOpt) (float64, error)
+pkg arith, type CalculatorClientMethods interface, Count(*context.T, int32, ...rpc.CallOpt) (ArithCountClientCall, error)
+pkg arith, type CalculatorClientMethods interface, DivMod(*context.T, int32, int32, ...rpc.CallOpt) (int32, int32, error)
+pkg arith, type CalculatorClientMethods interface, GenError(*context.T, ...rpc.CallOpt) error
+pkg arith, type CalculatorClientMethods interface, Mul(*context.T, base.NestedArgs, ...rpc.CallOpt) (int32, error)
+pkg arith, type CalculatorClientMethods interface, Off(*context.T, ...rpc.CallOpt) error
+pkg arith, type CalculatorClientMethods interface, On(*context.T, ...rpc.CallOpt) error
+pkg arith, type CalculatorClientMethods interface, QuoteAny(*context.T, *vdl.Value, ...rpc.CallOpt) (*vdl.Value, error)
+pkg arith, type CalculatorClientMethods interface, Sine(*context.T, float64, ...rpc.CallOpt) (float64, error)
+pkg arith, type CalculatorClientMethods interface, StreamingAdd(*context.T, ...rpc.CallOpt) (ArithStreamingAddClientCall, error)
+pkg arith, type CalculatorClientMethods interface, Sub(*context.T, base.Args, ...rpc.CallOpt) (int32, error)
+pkg arith, type CalculatorClientMethods interface, unexported methods
+pkg arith, type CalculatorClientStub interface, Add(*context.T, int32, int32, ...rpc.CallOpt) (int32, error)
+pkg arith, type CalculatorClientStub interface, Cosine(*context.T, float64, ...rpc.CallOpt) (float64, error)
+pkg arith, type CalculatorClientStub interface, Count(*context.T, int32, ...rpc.CallOpt) (ArithCountClientCall, error)
+pkg arith, type CalculatorClientStub interface, DivMod(*context.T, int32, int32, ...rpc.CallOpt) (int32, int32, error)
+pkg arith, type CalculatorClientStub interface, GenError(*context.T, ...rpc.CallOpt) error
+pkg arith, type CalculatorClientStub interface, Mul(*context.T, base.NestedArgs, ...rpc.CallOpt) (int32, error)
+pkg arith, type CalculatorClientStub interface, Off(*context.T, ...rpc.CallOpt) error
+pkg arith, type CalculatorClientStub interface, On(*context.T, ...rpc.CallOpt) error
+pkg arith, type CalculatorClientStub interface, QuoteAny(*context.T, *vdl.Value, ...rpc.CallOpt) (*vdl.Value, error)
+pkg arith, type CalculatorClientStub interface, Sine(*context.T, float64, ...rpc.CallOpt) (float64, error)
+pkg arith, type CalculatorClientStub interface, StreamingAdd(*context.T, ...rpc.CallOpt) (ArithStreamingAddClientCall, error)
+pkg arith, type CalculatorClientStub interface, Sub(*context.T, base.Args, ...rpc.CallOpt) (int32, error)
+pkg arith, type CalculatorClientStub interface, unexported methods
+pkg arith, type CalculatorServerMethods interface, Add(*context.T, rpc.ServerCall, int32, int32) (int32, error)
+pkg arith, type CalculatorServerMethods interface, Cosine(*context.T, rpc.ServerCall, float64) (float64, error)
+pkg arith, type CalculatorServerMethods interface, Count(*context.T, ArithCountServerCall, int32) error
+pkg arith, type CalculatorServerMethods interface, DivMod(*context.T, rpc.ServerCall, int32, int32) (int32, int32, error)
+pkg arith, type CalculatorServerMethods interface, GenError(*context.T, rpc.ServerCall) error
+pkg arith, type CalculatorServerMethods interface, Mul(*context.T, rpc.ServerCall, base.NestedArgs) (int32, error)
+pkg arith, type CalculatorServerMethods interface, Off(*context.T, rpc.ServerCall) error
+pkg arith, type CalculatorServerMethods interface, On(*context.T, rpc.ServerCall) error
+pkg arith, type CalculatorServerMethods interface, QuoteAny(*context.T, rpc.ServerCall, *vdl.Value) (*vdl.Value, error)
+pkg arith, type CalculatorServerMethods interface, Sine(*context.T, rpc.ServerCall, float64) (float64, error)
+pkg arith, type CalculatorServerMethods interface, StreamingAdd(*context.T, ArithStreamingAddServerCall) (int32, error)
+pkg arith, type CalculatorServerMethods interface, Sub(*context.T, rpc.ServerCall, base.Args) (int32, error)
+pkg arith, type CalculatorServerMethods interface, unexported methods
+pkg arith, type CalculatorServerStub interface, Add(*context.T, rpc.ServerCall, int32, int32) (int32, error)
+pkg arith, type CalculatorServerStub interface, Count(*context.T, *ArithCountServerCallStub, int32) error
+pkg arith, type CalculatorServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg arith, type CalculatorServerStub interface, DivMod(*context.T, rpc.ServerCall, int32, int32) (int32, int32, error)
+pkg arith, type CalculatorServerStub interface, GenError(*context.T, rpc.ServerCall) error
+pkg arith, type CalculatorServerStub interface, Mul(*context.T, rpc.ServerCall, base.NestedArgs) (int32, error)
+pkg arith, type CalculatorServerStub interface, Off(*context.T, rpc.ServerCall) error
+pkg arith, type CalculatorServerStub interface, On(*context.T, rpc.ServerCall) error
+pkg arith, type CalculatorServerStub interface, QuoteAny(*context.T, rpc.ServerCall, *vdl.Value) (*vdl.Value, error)
+pkg arith, type CalculatorServerStub interface, StreamingAdd(*context.T, *ArithStreamingAddServerCallStub) (int32, error)
+pkg arith, type CalculatorServerStub interface, Sub(*context.T, rpc.ServerCall, base.Args) (int32, error)
+pkg arith, type CalculatorServerStub interface, unexported methods
+pkg arith, type CalculatorServerStubMethods interface, Add(*context.T, rpc.ServerCall, int32, int32) (int32, error)
+pkg arith, type CalculatorServerStubMethods interface, Count(*context.T, *ArithCountServerCallStub, int32) error
+pkg arith, type CalculatorServerStubMethods interface, DivMod(*context.T, rpc.ServerCall, int32, int32) (int32, int32, error)
+pkg arith, type CalculatorServerStubMethods interface, GenError(*context.T, rpc.ServerCall) error
+pkg arith, type CalculatorServerStubMethods interface, Mul(*context.T, rpc.ServerCall, base.NestedArgs) (int32, error)
+pkg arith, type CalculatorServerStubMethods interface, Off(*context.T, rpc.ServerCall) error
+pkg arith, type CalculatorServerStubMethods interface, On(*context.T, rpc.ServerCall) error
+pkg arith, type CalculatorServerStubMethods interface, QuoteAny(*context.T, rpc.ServerCall, *vdl.Value) (*vdl.Value, error)
+pkg arith, type CalculatorServerStubMethods interface, StreamingAdd(*context.T, *ArithStreamingAddServerCallStub) (int32, error)
+pkg arith, type CalculatorServerStubMethods interface, Sub(*context.T, rpc.ServerCall, base.Args) (int32, error)
+pkg arith, type CalculatorServerStubMethods interface, unexported methods
+pkg arith, type TrigonometryClientMethods interface { Cosine, Sine }
+pkg arith, type TrigonometryClientMethods interface, Cosine(*context.T, float64, ...rpc.CallOpt) (float64, error)
+pkg arith, type TrigonometryClientMethods interface, Sine(*context.T, float64, ...rpc.CallOpt) (float64, error)
+pkg arith, type TrigonometryClientStub interface, Cosine(*context.T, float64, ...rpc.CallOpt) (float64, error)
+pkg arith, type TrigonometryClientStub interface, Sine(*context.T, float64, ...rpc.CallOpt) (float64, error)
+pkg arith, type TrigonometryClientStub interface, unexported methods
+pkg arith, type TrigonometryServerMethods interface { Cosine, Sine }
+pkg arith, type TrigonometryServerMethods interface, Cosine(*context.T, rpc.ServerCall, float64) (float64, error)
+pkg arith, type TrigonometryServerMethods interface, Sine(*context.T, rpc.ServerCall, float64) (float64, error)
+pkg arith, type TrigonometryServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg arith, type TrigonometryServerStub interface, unexported methods
+pkg arith, type TrigonometryServerStubMethods TrigonometryServerMethods
+pkg arith, var AdvancedMathDesc rpc.InterfaceDesc
+pkg arith, var ArithDesc rpc.InterfaceDesc
+pkg arith, var CalculatorDesc rpc.InterfaceDesc
+pkg arith, var TrigonometryDesc rpc.InterfaceDesc
diff --git a/lib/vdl/testdata/arith/exp/.api b/lib/vdl/testdata/arith/exp/.api
new file mode 100644
index 0000000..80ad9cb
--- /dev/null
+++ b/lib/vdl/testdata/arith/exp/.api
@@ -0,0 +1,12 @@
+pkg exp, func ExpClient(string) ExpClientStub
+pkg exp, func ExpServer(ExpServerMethods) ExpServerStub
+pkg exp, type ExpClientMethods interface { Exp }
+pkg exp, type ExpClientMethods interface, Exp(*context.T, float64, ...rpc.CallOpt) (float64, error)
+pkg exp, type ExpClientStub interface, Exp(*context.T, float64, ...rpc.CallOpt) (float64, error)
+pkg exp, type ExpClientStub interface, unexported methods
+pkg exp, type ExpServerMethods interface { Exp }
+pkg exp, type ExpServerMethods interface, Exp(*context.T, rpc.ServerCall, float64) (float64, error)
+pkg exp, type ExpServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg exp, type ExpServerStub interface, unexported methods
+pkg exp, type ExpServerStubMethods ExpServerMethods
+pkg exp, var ExpDesc rpc.InterfaceDesc
diff --git a/lib/vdl/testdata/base/.api b/lib/vdl/testdata/base/.api
new file mode 100644
index 0000000..5d9efd4
--- /dev/null
+++ b/lib/vdl/testdata/base/.api
@@ -0,0 +1,272 @@
+pkg base, const CNamedBool NamedBool
+pkg base, const Cbool bool
+pkg base, const Cbyte byte
+pkg base, const Ccomplex128 complex128
+pkg base, const Ccomplex64 complex64
+pkg base, const Cenum NamedEnum
+pkg base, const Cfloat32 float32
+pkg base, const Cfloat64 float64
+pkg base, const Cint32 int32
+pkg base, const Cint64 int64
+pkg base, const Cstring ideal-string
+pkg base, const Cuint32 uint32
+pkg base, const Cuint64 uint64
+pkg base, const Five int32
+pkg base, const FiveSquared int32
+pkg base, const Foo ideal-string
+pkg base, const NamedEnumA NamedEnum
+pkg base, const NamedEnumB NamedEnum
+pkg base, const NamedEnumC NamedEnum
+pkg base, const Six uint64
+pkg base, const SixSquared uint64
+pkg base, const True bool
+pkg base, func NamedEnumFromString(string) (NamedEnum, error)
+pkg base, func NewErrNoParams1(*context.T) error
+pkg base, func NewErrNoParams2(*context.T) error
+pkg base, func NewErrWithParams1(*context.T, string, int32) error
+pkg base, func NewErrWithParams2(*context.T, string, int32) error
+pkg base, func ServiceAClient(string) ServiceAClientStub
+pkg base, func ServiceAServer(ServiceAServerMethods) ServiceAServerStub
+pkg base, func ServiceBClient(string) ServiceBClientStub
+pkg base, func ServiceBServer(ServiceBServerMethods) ServiceBServerStub
+pkg base, method (*NamedEnum) Set(string) error
+pkg base, method (*ServiceAMethodA3ServerCallStub) Init(rpc.StreamServerCall)
+pkg base, method (*ServiceAMethodA3ServerCallStub) SendStream() interface {  Send(item Scalars) error;}
+pkg base, method (*ServiceAMethodA4ServerCallStub) Init(rpc.StreamServerCall)
+pkg base, method (*ServiceAMethodA4ServerCallStub) RecvStream() interface {  Advance() bool; Value() int32; Err() error;}
+pkg base, method (*ServiceAMethodA4ServerCallStub) SendStream() interface {  Send(item string) error;}
+pkg base, method (NamedEnum) String() string
+pkg base, method (NamedUnionA) Index() int
+pkg base, method (NamedUnionA) Interface() interface{}
+pkg base, method (NamedUnionA) Name() string
+pkg base, method (NamedUnionB) Index() int
+pkg base, method (NamedUnionB) Interface() interface{}
+pkg base, method (NamedUnionB) Name() string
+pkg base, method (NamedUnionC) Index() int
+pkg base, method (NamedUnionC) Interface() interface{}
+pkg base, method (NamedUnionC) Name() string
+pkg base, type Args struct
+pkg base, type Args struct, A int32
+pkg base, type Args struct, B int32
+pkg base, type CompComp struct
+pkg base, type CompComp struct, A0 Composites
+pkg base, type CompComp struct, A1 CompositesArray
+pkg base, type CompComp struct, A2 []Composites
+pkg base, type CompComp struct, A3 map[string]Composites
+pkg base, type CompComp struct, A4 map[KeyScalars][]map[string]Composites
+pkg base, type Composites struct
+pkg base, type Composites struct, A0 Scalars
+pkg base, type Composites struct, A1 ScalarsArray
+pkg base, type Composites struct, A2 []Scalars
+pkg base, type Composites struct, A3 map[KeyScalars]struct{}
+pkg base, type Composites struct, A4 map[string]Scalars
+pkg base, type Composites struct, A5 map[KeyScalars][]map[string]complex128
+pkg base, type CompositesArray [2]Composites
+pkg base, type KeyScalars struct
+pkg base, type KeyScalars struct, A0 bool
+pkg base, type KeyScalars struct, A1 byte
+pkg base, type KeyScalars struct, A10 complex64
+pkg base, type KeyScalars struct, A11 complex128
+pkg base, type KeyScalars struct, A12 string
+pkg base, type KeyScalars struct, A2 uint16
+pkg base, type KeyScalars struct, A3 uint32
+pkg base, type KeyScalars struct, A4 uint64
+pkg base, type KeyScalars struct, A5 int16
+pkg base, type KeyScalars struct, A6 int32
+pkg base, type KeyScalars struct, A7 int64
+pkg base, type KeyScalars struct, A8 float32
+pkg base, type KeyScalars struct, A9 float64
+pkg base, type KeyScalars struct, B0 NamedBool
+pkg base, type KeyScalars struct, B1 NamedByte
+pkg base, type KeyScalars struct, B10 NamedComplex64
+pkg base, type KeyScalars struct, B11 NamedComplex128
+pkg base, type KeyScalars struct, B12 NamedString
+pkg base, type KeyScalars struct, B2 NamedUint16
+pkg base, type KeyScalars struct, B3 NamedUint32
+pkg base, type KeyScalars struct, B4 NamedUint64
+pkg base, type KeyScalars struct, B5 NamedInt16
+pkg base, type KeyScalars struct, B6 NamedInt32
+pkg base, type KeyScalars struct, B7 NamedInt64
+pkg base, type KeyScalars struct, B8 NamedFloat32
+pkg base, type KeyScalars struct, B9 NamedFloat64
+pkg base, type NamedArray [2]bool
+pkg base, type NamedBool bool
+pkg base, type NamedByte byte
+pkg base, type NamedComplex128 complex128
+pkg base, type NamedComplex64 complex64
+pkg base, type NamedEnum int
+pkg base, type NamedFloat32 float32
+pkg base, type NamedFloat64 float64
+pkg base, type NamedInt16 int16
+pkg base, type NamedInt32 int32
+pkg base, type NamedInt64 int64
+pkg base, type NamedList []uint32
+pkg base, type NamedMap map[string]float32
+pkg base, type NamedSet map[string]struct{}
+pkg base, type NamedString string
+pkg base, type NamedStruct struct
+pkg base, type NamedStruct struct, A bool
+pkg base, type NamedStruct struct, B string
+pkg base, type NamedStruct struct, C int32
+pkg base, type NamedUint16 uint16
+pkg base, type NamedUint32 uint32
+pkg base, type NamedUint64 uint64
+pkg base, type NamedUnion interface, Index() int
+pkg base, type NamedUnion interface, Interface() interface{}
+pkg base, type NamedUnion interface, Name() string
+pkg base, type NamedUnion interface, unexported methods
+pkg base, type NamedUnionA struct
+pkg base, type NamedUnionA struct, Value bool
+pkg base, type NamedUnionB struct
+pkg base, type NamedUnionB struct, Value string
+pkg base, type NamedUnionC struct
+pkg base, type NamedUnionC struct, Value int32
+pkg base, type NestedArgs struct
+pkg base, type NestedArgs struct, Args Args
+pkg base, type Scalars struct
+pkg base, type Scalars struct, A0 bool
+pkg base, type Scalars struct, A1 byte
+pkg base, type Scalars struct, A10 complex64
+pkg base, type Scalars struct, A11 complex128
+pkg base, type Scalars struct, A12 string
+pkg base, type Scalars struct, A13 error
+pkg base, type Scalars struct, A14 *vdl.Value
+pkg base, type Scalars struct, A15 *vdl.Type
+pkg base, type Scalars struct, A2 uint16
+pkg base, type Scalars struct, A3 uint32
+pkg base, type Scalars struct, A4 uint64
+pkg base, type Scalars struct, A5 int16
+pkg base, type Scalars struct, A6 int32
+pkg base, type Scalars struct, A7 int64
+pkg base, type Scalars struct, A8 float32
+pkg base, type Scalars struct, A9 float64
+pkg base, type Scalars struct, B0 NamedBool
+pkg base, type Scalars struct, B1 NamedByte
+pkg base, type Scalars struct, B10 NamedComplex64
+pkg base, type Scalars struct, B11 NamedComplex128
+pkg base, type Scalars struct, B12 NamedString
+pkg base, type Scalars struct, B13 NamedEnum
+pkg base, type Scalars struct, B14 NamedUnion
+pkg base, type Scalars struct, B2 NamedUint16
+pkg base, type Scalars struct, B3 NamedUint32
+pkg base, type Scalars struct, B4 NamedUint64
+pkg base, type Scalars struct, B5 NamedInt16
+pkg base, type Scalars struct, B6 NamedInt32
+pkg base, type Scalars struct, B7 NamedInt64
+pkg base, type Scalars struct, B8 NamedFloat32
+pkg base, type Scalars struct, B9 NamedFloat64
+pkg base, type ScalarsArray [2]Scalars
+pkg base, type ServiceAClientMethods interface { MethodA1, MethodA2, MethodA3, MethodA4 }
+pkg base, type ServiceAClientMethods interface, MethodA1(*context.T, ...rpc.CallOpt) error
+pkg base, type ServiceAClientMethods interface, MethodA2(*context.T, int32, string, ...rpc.CallOpt) (string, error)
+pkg base, type ServiceAClientMethods interface, MethodA3(*context.T, int32, ...rpc.CallOpt) (ServiceAMethodA3ClientCall, error)
+pkg base, type ServiceAClientMethods interface, MethodA4(*context.T, int32, ...rpc.CallOpt) (ServiceAMethodA4ClientCall, error)
+pkg base, type ServiceAClientStub interface, MethodA1(*context.T, ...rpc.CallOpt) error
+pkg base, type ServiceAClientStub interface, MethodA2(*context.T, int32, string, ...rpc.CallOpt) (string, error)
+pkg base, type ServiceAClientStub interface, MethodA3(*context.T, int32, ...rpc.CallOpt) (ServiceAMethodA3ClientCall, error)
+pkg base, type ServiceAClientStub interface, MethodA4(*context.T, int32, ...rpc.CallOpt) (ServiceAMethodA4ClientCall, error)
+pkg base, type ServiceAClientStub interface, unexported methods
+pkg base, type ServiceAMethodA3ClientCall interface { Finish, RecvStream }
+pkg base, type ServiceAMethodA3ClientCall interface, Finish() (string, error)
+pkg base, type ServiceAMethodA3ClientCall interface, RecvStream() interface {  Advance() bool;; Value() Scalars;; Err() error;}
+pkg base, type ServiceAMethodA3ClientStream interface { RecvStream }
+pkg base, type ServiceAMethodA3ClientStream interface, RecvStream() interface {  Advance() bool;; Value() Scalars;; Err() error;}
+pkg base, type ServiceAMethodA3ServerCall interface, SendStream() interface {  Send(item Scalars) error;}
+pkg base, type ServiceAMethodA3ServerCall interface, unexported methods
+pkg base, type ServiceAMethodA3ServerCallStub struct
+pkg base, type ServiceAMethodA3ServerCallStub struct, embedded rpc.StreamServerCall
+pkg base, type ServiceAMethodA3ServerStream interface { SendStream }
+pkg base, type ServiceAMethodA3ServerStream interface, SendStream() interface {  Send(item Scalars) error;}
+pkg base, type ServiceAMethodA4ClientCall interface { Finish, RecvStream, SendStream }
+pkg base, type ServiceAMethodA4ClientCall interface, Finish() error
+pkg base, type ServiceAMethodA4ClientCall interface, RecvStream() interface {  Advance() bool;; Value() string;; Err() error;}
+pkg base, type ServiceAMethodA4ClientCall interface, SendStream() interface {  Send(item int32) error;; Close() error;}
+pkg base, type ServiceAMethodA4ClientStream interface { RecvStream, SendStream }
+pkg base, type ServiceAMethodA4ClientStream interface, RecvStream() interface {  Advance() bool;; Value() string;; Err() error;}
+pkg base, type ServiceAMethodA4ClientStream interface, SendStream() interface {  Send(item int32) error;; Close() error;}
+pkg base, type ServiceAMethodA4ServerCall interface, RecvStream() interface {  Advance() bool;; Value() int32;; Err() error;}
+pkg base, type ServiceAMethodA4ServerCall interface, SendStream() interface {  Send(item string) error;}
+pkg base, type ServiceAMethodA4ServerCall interface, unexported methods
+pkg base, type ServiceAMethodA4ServerCallStub struct
+pkg base, type ServiceAMethodA4ServerCallStub struct, embedded rpc.StreamServerCall
+pkg base, type ServiceAMethodA4ServerStream interface { RecvStream, SendStream }
+pkg base, type ServiceAMethodA4ServerStream interface, RecvStream() interface {  Advance() bool;; Value() int32;; Err() error;}
+pkg base, type ServiceAMethodA4ServerStream interface, SendStream() interface {  Send(item string) error;}
+pkg base, type ServiceAServerMethods interface { MethodA1, MethodA2, MethodA3, MethodA4 }
+pkg base, type ServiceAServerMethods interface, MethodA1(*context.T, rpc.ServerCall) error
+pkg base, type ServiceAServerMethods interface, MethodA2(*context.T, rpc.ServerCall, int32, string) (string, error)
+pkg base, type ServiceAServerMethods interface, MethodA3(*context.T, ServiceAMethodA3ServerCall, int32) (string, error)
+pkg base, type ServiceAServerMethods interface, MethodA4(*context.T, ServiceAMethodA4ServerCall, int32) error
+pkg base, type ServiceAServerStub interface { Describe__, MethodA1, MethodA2, MethodA3, MethodA4 }
+pkg base, type ServiceAServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg base, type ServiceAServerStub interface, MethodA1(*context.T, rpc.ServerCall) error
+pkg base, type ServiceAServerStub interface, MethodA2(*context.T, rpc.ServerCall, int32, string) (string, error)
+pkg base, type ServiceAServerStub interface, MethodA3(*context.T, *ServiceAMethodA3ServerCallStub, int32) (string, error)
+pkg base, type ServiceAServerStub interface, MethodA4(*context.T, *ServiceAMethodA4ServerCallStub, int32) error
+pkg base, type ServiceAServerStubMethods interface { MethodA1, MethodA2, MethodA3, MethodA4 }
+pkg base, type ServiceAServerStubMethods interface, MethodA1(*context.T, rpc.ServerCall) error
+pkg base, type ServiceAServerStubMethods interface, MethodA2(*context.T, rpc.ServerCall, int32, string) (string, error)
+pkg base, type ServiceAServerStubMethods interface, MethodA3(*context.T, *ServiceAMethodA3ServerCallStub, int32) (string, error)
+pkg base, type ServiceAServerStubMethods interface, MethodA4(*context.T, *ServiceAMethodA4ServerCallStub, int32) error
+pkg base, type ServiceBClientMethods interface { MethodA1, MethodA2, MethodA3, MethodA4, MethodB1 }
+pkg base, type ServiceBClientMethods interface, MethodA1(*context.T, ...rpc.CallOpt) error
+pkg base, type ServiceBClientMethods interface, MethodA2(*context.T, int32, string, ...rpc.CallOpt) (string, error)
+pkg base, type ServiceBClientMethods interface, MethodA3(*context.T, int32, ...rpc.CallOpt) (ServiceAMethodA3ClientCall, error)
+pkg base, type ServiceBClientMethods interface, MethodA4(*context.T, int32, ...rpc.CallOpt) (ServiceAMethodA4ClientCall, error)
+pkg base, type ServiceBClientMethods interface, MethodB1(*context.T, Scalars, Composites, ...rpc.CallOpt) (CompComp, error)
+pkg base, type ServiceBClientStub interface, MethodA1(*context.T, ...rpc.CallOpt) error
+pkg base, type ServiceBClientStub interface, MethodA2(*context.T, int32, string, ...rpc.CallOpt) (string, error)
+pkg base, type ServiceBClientStub interface, MethodA3(*context.T, int32, ...rpc.CallOpt) (ServiceAMethodA3ClientCall, error)
+pkg base, type ServiceBClientStub interface, MethodA4(*context.T, int32, ...rpc.CallOpt) (ServiceAMethodA4ClientCall, error)
+pkg base, type ServiceBClientStub interface, MethodB1(*context.T, Scalars, Composites, ...rpc.CallOpt) (CompComp, error)
+pkg base, type ServiceBClientStub interface, unexported methods
+pkg base, type ServiceBServerMethods interface { MethodA1, MethodA2, MethodA3, MethodA4, MethodB1 }
+pkg base, type ServiceBServerMethods interface, MethodA1(*context.T, rpc.ServerCall) error
+pkg base, type ServiceBServerMethods interface, MethodA2(*context.T, rpc.ServerCall, int32, string) (string, error)
+pkg base, type ServiceBServerMethods interface, MethodA3(*context.T, ServiceAMethodA3ServerCall, int32) (string, error)
+pkg base, type ServiceBServerMethods interface, MethodA4(*context.T, ServiceAMethodA4ServerCall, int32) error
+pkg base, type ServiceBServerMethods interface, MethodB1(*context.T, rpc.ServerCall, Scalars, Composites) (CompComp, error)
+pkg base, type ServiceBServerStub interface { Describe__, MethodA1, MethodA2, MethodA3, MethodA4, MethodB1 }
+pkg base, type ServiceBServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg base, type ServiceBServerStub interface, MethodA1(*context.T, rpc.ServerCall) error
+pkg base, type ServiceBServerStub interface, MethodA2(*context.T, rpc.ServerCall, int32, string) (string, error)
+pkg base, type ServiceBServerStub interface, MethodA3(*context.T, *ServiceAMethodA3ServerCallStub, int32) (string, error)
+pkg base, type ServiceBServerStub interface, MethodA4(*context.T, *ServiceAMethodA4ServerCallStub, int32) error
+pkg base, type ServiceBServerStub interface, MethodB1(*context.T, rpc.ServerCall, Scalars, Composites) (CompComp, error)
+pkg base, type ServiceBServerStubMethods interface { MethodA1, MethodA2, MethodA3, MethodA4, MethodB1 }
+pkg base, type ServiceBServerStubMethods interface, MethodA1(*context.T, rpc.ServerCall) error
+pkg base, type ServiceBServerStubMethods interface, MethodA2(*context.T, rpc.ServerCall, int32, string) (string, error)
+pkg base, type ServiceBServerStubMethods interface, MethodA3(*context.T, *ServiceAMethodA3ServerCallStub, int32) (string, error)
+pkg base, type ServiceBServerStubMethods interface, MethodA4(*context.T, *ServiceAMethodA4ServerCallStub, int32) error
+pkg base, type ServiceBServerStubMethods interface, MethodB1(*context.T, rpc.ServerCall, Scalars, Composites) (CompComp, error)
+pkg base, var CNamedStruct NamedStruct
+pkg base, var CScalars Scalars
+pkg base, var CTypeObject_Any unknown-type
+pkg base, var CTypeObject_Array unknown-type
+pkg base, var CTypeObject_List unknown-type
+pkg base, var CTypeObject_Map unknown-type
+pkg base, var CTypeObject_Set unknown-type
+pkg base, var CTypeObject_Struct unknown-type
+pkg base, var CTypeObject_TypeObject unknown-type
+pkg base, var CTypeObject_Union unknown-type
+pkg base, var CTypeObject_bool unknown-type
+pkg base, var CTypeObject_byte unknown-type
+pkg base, var CTypeObject_bytes unknown-type
+pkg base, var CTypeObject_complex64 unknown-type
+pkg base, var CTypeObject_enum unknown-type
+pkg base, var CTypeObject_float32 unknown-type
+pkg base, var CTypeObject_int16 unknown-type
+pkg base, var CTypeObject_string unknown-type
+pkg base, var CTypeObject_uint16 unknown-type
+pkg base, var Cargs Args
+pkg base, var Carray NamedArray
+pkg base, var Clist []int32
+pkg base, var Cset map[int32]struct{}
+pkg base, var Cunion unknown-type
+pkg base, var ErrNoParams1 unknown-type
+pkg base, var ErrNoParams2 unknown-type
+pkg base, var ErrWithParams1 unknown-type
+pkg base, var ErrWithParams2 unknown-type
+pkg base, var NamedEnumAll [...]NamedEnum
+pkg base, var ServiceADesc rpc.InterfaceDesc
+pkg base, var ServiceBDesc rpc.InterfaceDesc
diff --git a/lib/vdl/testdata/nativedep/.api b/lib/vdl/testdata/nativedep/.api
new file mode 100644
index 0000000..ae0ecf6
--- /dev/null
+++ b/lib/vdl/testdata/nativedep/.api
@@ -0,0 +1,6 @@
+pkg nativedep, type All struct
+pkg nativedep, type All struct, A string
+pkg nativedep, type All struct, B map[string]int
+pkg nativedep, type All struct, C time.Time
+pkg nativedep, type All struct, D nativetest.NativeSamePkg
+pkg nativedep, type All struct, E map[nativetest.NativeSamePkg]time.Time
diff --git a/lib/vdl/testdata/nativedep2/.api b/lib/vdl/testdata/nativedep2/.api
new file mode 100644
index 0000000..423cc2f
--- /dev/null
+++ b/lib/vdl/testdata/nativedep2/.api
@@ -0,0 +1 @@
+pkg nativedep2, type MyTime time.Time
diff --git a/lib/vdl/testdata/nativetest/.api b/lib/vdl/testdata/nativetest/.api
new file mode 100644
index 0000000..a80bef3
--- /dev/null
+++ b/lib/vdl/testdata/nativetest/.api
@@ -0,0 +1,12 @@
+pkg nativetest, type NativeSamePkg string
+pkg nativetest, type WireAll struct
+pkg nativetest, type WireAll struct, A string
+pkg nativetest, type WireAll struct, B map[string]int
+pkg nativetest, type WireAll struct, C time.Time
+pkg nativetest, type WireAll struct, D nativetest.NativeSamePkg
+pkg nativetest, type WireAll struct, E map[nativetest.NativeSamePkg]time.Time
+pkg nativetest, type WireMapStringInt int32
+pkg nativetest, type WireMultiImport int32
+pkg nativetest, type WireSamePkg int32
+pkg nativetest, type WireString int32
+pkg nativetest, type WireTime int32
diff --git a/lib/vdl/testdata/testconfig/.api b/lib/vdl/testdata/testconfig/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/vdl/testdata/testconfig/.api
diff --git a/lib/vdl/vdlutil/.api b/lib/vdl/vdlutil/.api
new file mode 100644
index 0000000..3e9c4c3
--- /dev/null
+++ b/lib/vdl/vdlutil/.api
@@ -0,0 +1,17 @@
+pkg vdlutil, func FirstRuneToExportCase(string, bool) string
+pkg vdlutil, func FirstRuneToLower(string) string
+pkg vdlutil, func FirstRuneToUpper(string) string
+pkg vdlutil, func NewErrors(int) *Errors
+pkg vdlutil, func SetVerbose()
+pkg vdlutil, func ToConstCase(string) string
+pkg vdlutil, method (*Errors) Error(string) bool
+pkg vdlutil, method (*Errors) Errorf(string, ...interface{}) bool
+pkg vdlutil, method (*Errors) IsEmpty() bool
+pkg vdlutil, method (*Errors) IsFull() bool
+pkg vdlutil, method (*Errors) NumErrors() int
+pkg vdlutil, method (*Errors) Reset()
+pkg vdlutil, method (*Errors) String() string
+pkg vdlutil, method (*Errors) ToError() error
+pkg vdlutil, type Errors struct
+pkg vdlutil, type Errors struct, MaxErrors int
+pkg vdlutil, var Vlog *log.Logger
diff --git a/profiles/.api b/profiles/.api
new file mode 100644
index 0000000..ade2080
--- /dev/null
+++ b/profiles/.api
@@ -0,0 +1,2 @@
+pkg profiles, func Init(*context.T) (v23.Runtime, *context.T, v23.Shutdown, error)
+pkg profiles, func NewProxy(*context.T, string, string, string, ...string) (func(), naming.Endpoint, error)
diff --git a/profiles/chrome/.api b/profiles/chrome/.api
new file mode 100644
index 0000000..d88793b
--- /dev/null
+++ b/profiles/chrome/.api
@@ -0,0 +1 @@
+pkg chrome, func Init(*context.T) (v23.Runtime, *context.T, v23.Shutdown, error)
diff --git a/profiles/fake/.api b/profiles/fake/.api
new file mode 100644
index 0000000..430311b
--- /dev/null
+++ b/profiles/fake/.api
@@ -0,0 +1,20 @@
+pkg fake, func Init(*context.T) (v23.Runtime, *context.T, v23.Shutdown, error)
+pkg fake, func InjectRuntime(v23.Runtime, *context.T, v23.Shutdown)
+pkg fake, func SetClient(*context.T, rpc.Client) *context.T
+pkg fake, method (*Runtime) GetAppCycle(*context.T) v23.AppCycle
+pkg fake, method (*Runtime) GetBackgroundContext(*context.T) *context.T
+pkg fake, method (*Runtime) GetClient(*context.T) rpc.Client
+pkg fake, method (*Runtime) GetListenSpec(*context.T) rpc.ListenSpec
+pkg fake, method (*Runtime) GetNamespace(*context.T) namespace.T
+pkg fake, method (*Runtime) GetPrincipal(*context.T) security.Principal
+pkg fake, method (*Runtime) GetReservedNameDispatcher(*context.T) rpc.Dispatcher
+pkg fake, method (*Runtime) Init(*context.T) error
+pkg fake, method (*Runtime) NewEndpoint(string) (naming.Endpoint, error)
+pkg fake, method (*Runtime) NewServer(*context.T, ...rpc.ServerOpt) (rpc.Server, error)
+pkg fake, method (*Runtime) WithBackgroundContext(*context.T) *context.T
+pkg fake, method (*Runtime) WithNewClient(*context.T, ...rpc.ClientOpt) (*context.T, rpc.Client, error)
+pkg fake, method (*Runtime) WithNewNamespace(*context.T, ...string) (*context.T, namespace.T, error)
+pkg fake, method (*Runtime) WithNewStreamManager(*context.T) (*context.T, error)
+pkg fake, method (*Runtime) WithPrincipal(*context.T, security.Principal) (*context.T, error)
+pkg fake, method (*Runtime) WithReservedNameDispatcher(*context.T, rpc.Dispatcher) *context.T
+pkg fake, type Runtime struct
diff --git a/profiles/gce/.api b/profiles/gce/.api
new file mode 100644
index 0000000..7c93515
--- /dev/null
+++ b/profiles/gce/.api
@@ -0,0 +1 @@
+pkg gce, func Init(*context.T) (v23.Runtime, *context.T, v23.Shutdown, error)
diff --git a/profiles/gce/init.go b/profiles/gce/init.go
index 15c96d3..73a675f 100644
--- a/profiles/gce/init.go
+++ b/profiles/gce/init.go
@@ -58,8 +58,8 @@
 	if ip, err := gce.ExternalIPAddress(); err != nil {
 		return nil, nil, nil, err
 	} else {
-		listenSpec.AddressChooser = func(network string, addrs []rpc.Address) ([]rpc.Address, error) {
-			return []rpc.Address{&netstate.AddrIfc{&net.IPAddr{IP: ip}, "gce-nat", nil}}, nil
+		listenSpec.AddressChooser = func(network string, addrs []net.Addr) ([]net.Addr, error) {
+			return []net.Addr{netstate.NewNetAddr("wsh", ip.String())}, nil
 		}
 	}
 
diff --git a/profiles/internal/.api b/profiles/internal/.api
new file mode 100644
index 0000000..7b6423a
--- /dev/null
+++ b/profiles/internal/.api
@@ -0,0 +1,4 @@
+pkg internal, func GCEPublicAddress(vlog.Logger) *net.IPAddr
+pkg internal, func HasPublicIP(vlog.Logger) bool
+pkg internal, func IPAddressChooser(string, []rpc.Address) ([]rpc.Address, error)
+pkg internal, func ParseFlags(*flags.Flags) error
diff --git a/profiles/internal/gce/.api b/profiles/internal/gce/.api
new file mode 100644
index 0000000..0be300b
--- /dev/null
+++ b/profiles/internal/gce/.api
@@ -0,0 +1,2 @@
+pkg gce, func ExternalIPAddress() (net.IP, error)
+pkg gce, func RunningOnGCE() bool
diff --git a/profiles/internal/lib/appcycle/.api b/profiles/internal/lib/appcycle/.api
new file mode 100644
index 0000000..18ff7fe
--- /dev/null
+++ b/profiles/internal/lib/appcycle/.api
@@ -0,0 +1,11 @@
+pkg appcycle, func New() *AppCycle
+pkg appcycle, method (*AppCycle) AdvanceGoal(int32)
+pkg appcycle, method (*AppCycle) AdvanceProgress(int32)
+pkg appcycle, method (*AppCycle) ForceStop()
+pkg appcycle, method (*AppCycle) Remote() interface{}
+pkg appcycle, method (*AppCycle) Shutdown()
+pkg appcycle, method (*AppCycle) Stop()
+pkg appcycle, method (*AppCycle) TrackTask(chan<- v23.Task)
+pkg appcycle, method (*AppCycle) WaitForStop(chan<- string)
+pkg appcycle, type AppCycle struct
+pkg appcycle, type AppCycle struct, embedded sync.RWMutex
diff --git a/profiles/internal/lib/bqueue/.api b/profiles/internal/lib/bqueue/.api
new file mode 100644
index 0000000..3d371b5
--- /dev/null
+++ b/profiles/internal/lib/bqueue/.api
@@ -0,0 +1,24 @@
+pkg bqueue, type FlushFunc func() error
+pkg bqueue, type ID int64
+pkg bqueue, type Priority uint
+pkg bqueue, type T interface { Close, Find, Get, NewWriter, String }
+pkg bqueue, type T interface, Close()
+pkg bqueue, type T interface, Find(ID) Writer
+pkg bqueue, type T interface, Get(FlushFunc) (Writer, []*iobuf.Slice, error)
+pkg bqueue, type T interface, NewWriter(ID, Priority, int) (Writer, error)
+pkg bqueue, type T interface, String() string
+pkg bqueue, type Writer interface { Close, ID, IsClosed, IsDrained, Put, Release, Shutdown, TryPut }
+pkg bqueue, type Writer interface, Close()
+pkg bqueue, type Writer interface, ID() ID
+pkg bqueue, type Writer interface, IsClosed() bool
+pkg bqueue, type Writer interface, IsDrained() bool
+pkg bqueue, type Writer interface, Put(*iobuf.Slice, <-chan struct{}) error
+pkg bqueue, type Writer interface, Release(int) error
+pkg bqueue, type Writer interface, Shutdown(bool)
+pkg bqueue, type Writer interface, TryPut(*iobuf.Slice) error
+pkg bqueue, var ErrBQueueIsClosed error
+pkg bqueue, var ErrCancelled error
+pkg bqueue, var ErrCantToggleFlowControl error
+pkg bqueue, var ErrTryAgain error
+pkg bqueue, var ErrWriterAlreadyExists error
+pkg bqueue, var ErrWriterIsClosed error
diff --git a/profiles/internal/lib/bqueue/drrqueue/.api b/profiles/internal/lib/bqueue/drrqueue/.api
new file mode 100644
index 0000000..c983cb3
--- /dev/null
+++ b/profiles/internal/lib/bqueue/drrqueue/.api
@@ -0,0 +1,7 @@
+pkg drrqueue, func New(int) bqueue.T
+pkg drrqueue, method (*T) Close()
+pkg drrqueue, method (*T) Find(bqueue.ID) bqueue.Writer
+pkg drrqueue, method (*T) Get(bqueue.FlushFunc) (bqueue.Writer, []*iobuf.Slice, error)
+pkg drrqueue, method (*T) NewWriter(bqueue.ID, bqueue.Priority, int) (bqueue.Writer, error)
+pkg drrqueue, method (*T) String() string
+pkg drrqueue, type T struct
diff --git a/profiles/internal/lib/dependency/.api b/profiles/internal/lib/dependency/.api
new file mode 100644
index 0000000..48c7791
--- /dev/null
+++ b/profiles/internal/lib/dependency/.api
@@ -0,0 +1,6 @@
+pkg dependency, func NewGraph() *Graph
+pkg dependency, method (*Graph) CloseAndWait(interface{}) func()
+pkg dependency, method (*Graph) CloseAndWaitForAll()
+pkg dependency, method (*Graph) Depend(interface{}, ...interface{}) error
+pkg dependency, type Graph struct
+pkg dependency, var NotFoundError error
diff --git a/profiles/internal/lib/deque/.api b/profiles/internal/lib/deque/.api
new file mode 100644
index 0000000..b814b02
--- /dev/null
+++ b/profiles/internal/lib/deque/.api
@@ -0,0 +1,10 @@
+pkg deque, method (*T) Back() interface{}
+pkg deque, method (*T) Clear()
+pkg deque, method (*T) Front() interface{}
+pkg deque, method (*T) Iter(func(interface{}) bool)
+pkg deque, method (*T) PopBack() interface{}
+pkg deque, method (*T) PopFront() interface{}
+pkg deque, method (*T) PushBack(interface{})
+pkg deque, method (*T) PushFront(interface{})
+pkg deque, method (*T) Size() int
+pkg deque, type T struct
diff --git a/profiles/internal/lib/iobuf/.api b/profiles/internal/lib/iobuf/.api
new file mode 100644
index 0000000..4ed58b9
--- /dev/null
+++ b/profiles/internal/lib/iobuf/.api
@@ -0,0 +1,22 @@
+pkg iobuf, func Coalesce([]*Slice, uint) []*Slice
+pkg iobuf, func NewAllocator(*Pool, uint) *Allocator
+pkg iobuf, func NewPool(uint) *Pool
+pkg iobuf, func NewReader(*Pool, io.Reader) *Reader
+pkg iobuf, func NewSlice([]byte) *Slice
+pkg iobuf, method (*Allocator) Alloc(uint) *Slice
+pkg iobuf, method (*Allocator) Copy([]byte) *Slice
+pkg iobuf, method (*Allocator) Release()
+pkg iobuf, method (*Pool) Close()
+pkg iobuf, method (*Reader) Close()
+pkg iobuf, method (*Reader) Read(int) (*Slice, error)
+pkg iobuf, method (*Slice) ExpandFront(uint) bool
+pkg iobuf, method (*Slice) FreeEntirePrefix()
+pkg iobuf, method (*Slice) Release()
+pkg iobuf, method (*Slice) ReleasePrevious(*Slice)
+pkg iobuf, method (*Slice) Size() int
+pkg iobuf, method (*Slice) TruncateFront(uint)
+pkg iobuf, type Allocator struct
+pkg iobuf, type Pool struct
+pkg iobuf, type Reader struct
+pkg iobuf, type Slice struct
+pkg iobuf, type Slice struct, Contents []byte
diff --git a/profiles/internal/lib/pcqueue/.api b/profiles/internal/lib/pcqueue/.api
new file mode 100644
index 0000000..b850450
--- /dev/null
+++ b/profiles/internal/lib/pcqueue/.api
@@ -0,0 +1,10 @@
+pkg pcqueue, func New(int) *T
+pkg pcqueue, method (*T) Close()
+pkg pcqueue, method (*T) Get(<-chan struct{}) (interface{}, error)
+pkg pcqueue, method (*T) Put(interface{}, <-chan struct{}) error
+pkg pcqueue, method (*T) Shutdown()
+pkg pcqueue, method (*T) TryPut(interface{}) error
+pkg pcqueue, type T struct
+pkg pcqueue, var ErrCancelled error
+pkg pcqueue, var ErrQueueIsClosed error
+pkg pcqueue, var ErrTryAgain error
diff --git a/profiles/internal/lib/publisher/.api b/profiles/internal/lib/publisher/.api
new file mode 100644
index 0000000..30a7054
--- /dev/null
+++ b/profiles/internal/lib/publisher/.api
@@ -0,0 +1,10 @@
+pkg publisher, func New(*context.T, namespace.T, time.Duration) Publisher
+pkg publisher, type Publisher interface { AddName, AddServer, DebugString, RemoveName, RemoveServer, Status, Stop, WaitForStop }
+pkg publisher, type Publisher interface, AddName(string, bool, bool)
+pkg publisher, type Publisher interface, AddServer(string)
+pkg publisher, type Publisher interface, DebugString() string
+pkg publisher, type Publisher interface, RemoveName(string)
+pkg publisher, type Publisher interface, RemoveServer(string)
+pkg publisher, type Publisher interface, Status() rpc.MountState
+pkg publisher, type Publisher interface, Stop()
+pkg publisher, type Publisher interface, WaitForStop()
diff --git a/profiles/internal/lib/publisher/publisher.go b/profiles/internal/lib/publisher/publisher.go
index acdd006..6c87030 100644
--- a/profiles/internal/lib/publisher/publisher.go
+++ b/profiles/internal/lib/publisher/publisher.go
@@ -335,7 +335,7 @@
 	if status.LastUnmountErr != nil {
 		vlog.Errorf("rpc pub: couldn't unmount(%v, %v): %v", name, server, status.LastUnmountErr)
 	} else {
-		vlog.Infof("rpc pub: unmount(%v, %v)", name, server)
+		vlog.VI(1).Infof("rpc pub: unmount(%v, %v)", name, server)
 		delete(ps.mounts, mountKey{name, server})
 	}
 }
diff --git a/profiles/internal/lib/sync/.api b/profiles/internal/lib/sync/.api
new file mode 100644
index 0000000..adc91ec
--- /dev/null
+++ b/profiles/internal/lib/sync/.api
@@ -0,0 +1,20 @@
+pkg sync, func NewSemaphore() *Semaphore
+pkg sync, method (*DebugMutex) CheckLocked()
+pkg sync, method (*DebugMutex) Lock()
+pkg sync, method (*DebugMutex) Unlock()
+pkg sync, method (*Semaphore) Close()
+pkg sync, method (*Semaphore) Dec(<-chan struct{}) error
+pkg sync, method (*Semaphore) DecN(uint, <-chan struct{}) error
+pkg sync, method (*Semaphore) Inc() error
+pkg sync, method (*Semaphore) IncN(uint) error
+pkg sync, method (*Semaphore) TryDec() error
+pkg sync, method (*Semaphore) TryDecN(uint) error
+pkg sync, method (*WaitGroup) Done()
+pkg sync, method (*WaitGroup) TryAdd() bool
+pkg sync, method (*WaitGroup) Wait()
+pkg sync, type DebugMutex struct
+pkg sync, type Semaphore struct
+pkg sync, type WaitGroup struct
+pkg sync, var ErrCanceled error
+pkg sync, var ErrClosed error
+pkg sync, var ErrTryAgain error
diff --git a/profiles/internal/lib/tcputil/.api b/profiles/internal/lib/tcputil/.api
new file mode 100644
index 0000000..97a5b3f
--- /dev/null
+++ b/profiles/internal/lib/tcputil/.api
@@ -0,0 +1 @@
+pkg tcputil, func EnableTCPKeepAlive(net.Conn) error
diff --git a/profiles/internal/lib/upcqueue/.api b/profiles/internal/lib/upcqueue/.api
new file mode 100644
index 0000000..1aae0fd
--- /dev/null
+++ b/profiles/internal/lib/upcqueue/.api
@@ -0,0 +1,9 @@
+pkg upcqueue, func New() *T
+pkg upcqueue, method (*T) Close()
+pkg upcqueue, method (*T) Get(<-chan struct{}) (interface{}, error)
+pkg upcqueue, method (*T) IsClosed() bool
+pkg upcqueue, method (*T) Put(interface{}) error
+pkg upcqueue, method (*T) Shutdown() []interface{}
+pkg upcqueue, method (*T) TryGet() (interface{}, error)
+pkg upcqueue, type T struct
+pkg upcqueue, var ErrQueueIsClosed error
diff --git a/profiles/internal/lib/websocket/.api b/profiles/internal/lib/websocket/.api
new file mode 100644
index 0000000..0e441af
--- /dev/null
+++ b/profiles/internal/lib/websocket/.api
@@ -0,0 +1,5 @@
+pkg websocket, func Dial(string, string, time.Duration) (net.Conn, error)
+pkg websocket, func HybridDial(string, string, time.Duration) (net.Conn, error)
+pkg websocket, func HybridListener(string, string) (net.Listener, error)
+pkg websocket, func Listener(string, string) (net.Listener, error)
+pkg websocket, func WebsocketConn(*websocket.Conn) net.Conn
diff --git a/profiles/internal/naming/.api b/profiles/internal/naming/.api
new file mode 100644
index 0000000..2f79dcc
--- /dev/null
+++ b/profiles/internal/naming/.api
@@ -0,0 +1,21 @@
+pkg naming, const Network ideal-string
+pkg naming, func NewEndpoint(string) (*Endpoint, error)
+pkg naming, method (*Endpoint) Addr() net.Addr
+pkg naming, method (*Endpoint) BlessingNames() []string
+pkg naming, method (*Endpoint) Name() string
+pkg naming, method (*Endpoint) Network() string
+pkg naming, method (*Endpoint) RPCVersionRange() version.RPCVersionRange
+pkg naming, method (*Endpoint) RoutingID() naming.RoutingID
+pkg naming, method (*Endpoint) ServesLeaf() bool
+pkg naming, method (*Endpoint) ServesMountTable() bool
+pkg naming, method (*Endpoint) String() string
+pkg naming, method (*Endpoint) VersionedString(int) string
+pkg naming, type Endpoint struct
+pkg naming, type Endpoint struct, Address string
+pkg naming, type Endpoint struct, Blessings []string
+pkg naming, type Endpoint struct, IsLeaf bool
+pkg naming, type Endpoint struct, IsMountTable bool
+pkg naming, type Endpoint struct, MaxRPCVersion version.RPCVersion
+pkg naming, type Endpoint struct, MinRPCVersion version.RPCVersion
+pkg naming, type Endpoint struct, Protocol string
+pkg naming, type Endpoint struct, RID naming.RoutingID
diff --git a/profiles/internal/naming/namespace/.api b/profiles/internal/naming/namespace/.api
new file mode 100644
index 0000000..29e7b06
--- /dev/null
+++ b/profiles/internal/naming/namespace/.api
@@ -0,0 +1 @@
+pkg namespace, func New(...string) (*namespace, error)
diff --git a/profiles/internal/platform/.api b/profiles/internal/platform/.api
new file mode 100644
index 0000000..2d4a21c
--- /dev/null
+++ b/profiles/internal/platform/.api
@@ -0,0 +1,11 @@
+pkg platform, func GetPlatform() (*Platform, error)
+pkg platform, method (*Platform) String() string
+pkg platform, type Platform struct
+pkg platform, type Platform struct, AIKCertificate *security.Certificate
+pkg platform, type Platform struct, Machine string
+pkg platform, type Platform struct, Model string
+pkg platform, type Platform struct, Node string
+pkg platform, type Platform struct, Release string
+pkg platform, type Platform struct, System string
+pkg platform, type Platform struct, Vendor string
+pkg platform, type Platform struct, Version string
diff --git a/profiles/internal/rpc/.api b/profiles/internal/rpc/.api
new file mode 100644
index 0000000..095bdb8
--- /dev/null
+++ b/profiles/internal/rpc/.api
@@ -0,0 +1,13 @@
+pkg rpc, func InternalNewClient(stream.Manager, namespace.T, ...rpc.ClientOpt) (rpc.Client, error)
+pkg rpc, func InternalNewDischargeClient(*context.T, rpc.Client, time.Duration) vc.DischargeClient
+pkg rpc, func InternalNewServer(*context.T, stream.Manager, namespace.T, rpc.Client, security.Principal, ...rpc.ServerOpt) (rpc.Server, error)
+pkg rpc, method (NoDischarges) NSOpt()
+pkg rpc, method (NoDischarges) RPCCallOpt()
+pkg rpc, method (PreferredProtocols) RPCClientOpt()
+pkg rpc, method (PreferredServerResolveProtocols) RPCServerOpt()
+pkg rpc, method (ReservedNameDispatcher) RPCServerOpt()
+pkg rpc, type NoDischarges struct
+pkg rpc, type PreferredProtocols []string
+pkg rpc, type PreferredServerResolveProtocols []string
+pkg rpc, type ReservedNameDispatcher struct
+pkg rpc, type ReservedNameDispatcher struct, Dispatcher rpc.Dispatcher
diff --git a/profiles/internal/rpc/benchmark/.api b/profiles/internal/rpc/benchmark/.api
new file mode 100644
index 0000000..8913b34
--- /dev/null
+++ b/profiles/internal/rpc/benchmark/.api
@@ -0,0 +1,37 @@
+pkg benchmark, func BenchmarkClient(string) BenchmarkClientStub
+pkg benchmark, func BenchmarkServer(BenchmarkServerMethods) BenchmarkServerStub
+pkg benchmark, method (*BenchmarkEchoStreamServerCallStub) Init(rpc.StreamServerCall)
+pkg benchmark, method (*BenchmarkEchoStreamServerCallStub) RecvStream() interface {  Advance() bool; Value() []byte; Err() error;}
+pkg benchmark, method (*BenchmarkEchoStreamServerCallStub) SendStream() interface {  Send(item []byte) error;}
+pkg benchmark, type BenchmarkClientMethods interface { Echo, EchoStream }
+pkg benchmark, type BenchmarkClientMethods interface, Echo(*context.T, []byte, ...rpc.CallOpt) ([]byte, error)
+pkg benchmark, type BenchmarkClientMethods interface, EchoStream(*context.T, ...rpc.CallOpt) (BenchmarkEchoStreamClientCall, error)
+pkg benchmark, type BenchmarkClientStub interface, Echo(*context.T, []byte, ...rpc.CallOpt) ([]byte, error)
+pkg benchmark, type BenchmarkClientStub interface, EchoStream(*context.T, ...rpc.CallOpt) (BenchmarkEchoStreamClientCall, error)
+pkg benchmark, type BenchmarkClientStub interface, unexported methods
+pkg benchmark, type BenchmarkEchoStreamClientCall interface { Finish, RecvStream, SendStream }
+pkg benchmark, type BenchmarkEchoStreamClientCall interface, Finish() error
+pkg benchmark, type BenchmarkEchoStreamClientCall interface, RecvStream() interface {  Advance() bool;; Value() []byte;; Err() error;}
+pkg benchmark, type BenchmarkEchoStreamClientCall interface, SendStream() interface {  Send(item []byte) error;; Close() error;}
+pkg benchmark, type BenchmarkEchoStreamClientStream interface { RecvStream, SendStream }
+pkg benchmark, type BenchmarkEchoStreamClientStream interface, RecvStream() interface {  Advance() bool;; Value() []byte;; Err() error;}
+pkg benchmark, type BenchmarkEchoStreamClientStream interface, SendStream() interface {  Send(item []byte) error;; Close() error;}
+pkg benchmark, type BenchmarkEchoStreamServerCall interface, RecvStream() interface {  Advance() bool;; Value() []byte;; Err() error;}
+pkg benchmark, type BenchmarkEchoStreamServerCall interface, SendStream() interface {  Send(item []byte) error;}
+pkg benchmark, type BenchmarkEchoStreamServerCall interface, unexported methods
+pkg benchmark, type BenchmarkEchoStreamServerCallStub struct
+pkg benchmark, type BenchmarkEchoStreamServerCallStub struct, embedded rpc.StreamServerCall
+pkg benchmark, type BenchmarkEchoStreamServerStream interface { RecvStream, SendStream }
+pkg benchmark, type BenchmarkEchoStreamServerStream interface, RecvStream() interface {  Advance() bool;; Value() []byte;; Err() error;}
+pkg benchmark, type BenchmarkEchoStreamServerStream interface, SendStream() interface {  Send(item []byte) error;}
+pkg benchmark, type BenchmarkServerMethods interface { Echo, EchoStream }
+pkg benchmark, type BenchmarkServerMethods interface, Echo(*context.T, rpc.ServerCall, []byte) ([]byte, error)
+pkg benchmark, type BenchmarkServerMethods interface, EchoStream(*context.T, BenchmarkEchoStreamServerCall) error
+pkg benchmark, type BenchmarkServerStub interface { Describe__, Echo, EchoStream }
+pkg benchmark, type BenchmarkServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg benchmark, type BenchmarkServerStub interface, Echo(*context.T, rpc.ServerCall, []byte) ([]byte, error)
+pkg benchmark, type BenchmarkServerStub interface, EchoStream(*context.T, *BenchmarkEchoStreamServerCallStub) error
+pkg benchmark, type BenchmarkServerStubMethods interface { Echo, EchoStream }
+pkg benchmark, type BenchmarkServerStubMethods interface, Echo(*context.T, rpc.ServerCall, []byte) ([]byte, error)
+pkg benchmark, type BenchmarkServerStubMethods interface, EchoStream(*context.T, *BenchmarkEchoStreamServerCallStub) error
+pkg benchmark, var BenchmarkDesc rpc.InterfaceDesc
diff --git a/profiles/internal/rpc/benchmark/benchmark/.api b/profiles/internal/rpc/benchmark/benchmark/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/profiles/internal/rpc/benchmark/benchmark/.api
diff --git a/profiles/internal/rpc/benchmark/benchmarkd/.api b/profiles/internal/rpc/benchmark/benchmarkd/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/profiles/internal/rpc/benchmark/benchmarkd/.api
diff --git a/profiles/internal/rpc/benchmark/glob/.api b/profiles/internal/rpc/benchmark/glob/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/profiles/internal/rpc/benchmark/glob/.api
diff --git a/profiles/internal/rpc/benchmark/internal/.api b/profiles/internal/rpc/benchmark/internal/.api
new file mode 100644
index 0000000..ff87918
--- /dev/null
+++ b/profiles/internal/rpc/benchmark/internal/.api
@@ -0,0 +1,4 @@
+pkg internal, func CallEcho(*testing.B, *context.T, string, int, int, *tbm.Stats)
+pkg internal, func CallEchoStream(*testing.B, *context.T, string, int, int, int, *tbm.Stats)
+pkg internal, func StartEchoStream(*testing.B, *context.T, string, int, int, int, *tbm.Stats) (<-chan int, func())
+pkg internal, func StartServer(*context.T, rpc.ListenSpec) (naming.Endpoint, func())
diff --git a/profiles/internal/rpc/benchmark/main/.api b/profiles/internal/rpc/benchmark/main/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/profiles/internal/rpc/benchmark/main/.api
diff --git a/profiles/internal/rpc/client.go b/profiles/internal/rpc/client.go
index ab268dc..f963e1d 100644
--- a/profiles/internal/rpc/client.go
+++ b/profiles/internal/rpc/client.go
@@ -650,7 +650,7 @@
 				topLevelError = verror.ErrNotTrusted
 				topLevelAction = verror.NoRetry
 				onlyErrNetwork = false
-			case stream.ErrNetwork.ID:
+			case stream.ErrAborted.ID, stream.ErrNetwork.ID:
 				// do nothing
 			default:
 				onlyErrNetwork = false
diff --git a/profiles/internal/rpc/full_test.go b/profiles/internal/rpc/full_test.go
index 2e47921..e978fc0 100644
--- a/profiles/internal/rpc/full_test.go
+++ b/profiles/internal/rpc/full_test.go
@@ -1520,10 +1520,8 @@
 	sm := imanager.InternalNew(naming.FixedRoutingID(0x555555555))
 	defer sm.Shutdown()
 	ns := tnaming.NewSimpleNamespace()
-	pa := func(string, []rpc.Address) ([]rpc.Address, error) {
-		a := &net.IPAddr{}
-		a.IP = net.ParseIP("1.1.1.1")
-		return []rpc.Address{&netstate.AddrIfc{Addr: a}}, nil
+	pa := func(string, []net.Addr) ([]net.Addr, error) {
+		return []net.Addr{netstate.NewNetAddr("tcp", "1.1.1.1")}, nil
 	}
 	server, err := testInternalNewServer(ctx, sm, ns, testutil.NewPrincipal("server"))
 	if err != nil {
@@ -1565,7 +1563,7 @@
 	sm := imanager.InternalNew(naming.FixedRoutingID(0x555555555))
 	defer sm.Shutdown()
 	ns := tnaming.NewSimpleNamespace()
-	paerr := func(_ string, a []rpc.Address) ([]rpc.Address, error) {
+	paerr := func(_ string, a []net.Addr) ([]net.Addr, error) {
 		return nil, fmt.Errorf("oops")
 	}
 	server, err := testInternalNewServer(ctx, sm, ns, testutil.NewPrincipal("server"))
@@ -1578,17 +1576,16 @@
 		AddressChooser: paerr,
 	}
 	eps, err := server.Listen(spec)
-	iep := eps[0].(*inaming.Endpoint)
-	host, _, err := net.SplitHostPort(iep.Address)
-	if err != nil {
-		t.Errorf("unexpected error: %s", err)
+
+	if got, want := len(eps), 0; got != want {
+		t.Errorf("got %q, want %q", got, want)
 	}
-	ip := net.ParseIP(host)
-	if ip == nil {
-		t.Fatalf("failed to parse IP address: %q", host)
+	status := server.Status()
+	if got, want := len(status.Errors), 1; got != want {
+		t.Errorf("got %q, want %q", got, want)
 	}
-	if !ip.IsUnspecified() {
-		t.Errorf("IP: %q is not unspecified", ip)
+	if got, want := status.Errors[0].Error(), "oops"; got != want {
+		t.Errorf("got %q, want %q", got, want)
 	}
 }
 
diff --git a/profiles/internal/rpc/protocols/tcp/.api b/profiles/internal/rpc/protocols/tcp/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/profiles/internal/rpc/protocols/tcp/.api
diff --git a/profiles/internal/rpc/protocols/tcp/init.go b/profiles/internal/rpc/protocols/tcp/init.go
index a6067b9..08f95e6 100644
--- a/profiles/internal/rpc/protocols/tcp/init.go
+++ b/profiles/internal/rpc/protocols/tcp/init.go
@@ -22,6 +22,7 @@
 }
 
 func tcpDial(network, address string, timeout time.Duration) (net.Conn, error) {
+	vlog.Infof("tcp.Dial %v", address)
 	conn, err := net.DialTimeout(network, address, timeout)
 	if err != nil {
 		return nil, err
diff --git a/profiles/internal/rpc/protocols/ws/.api b/profiles/internal/rpc/protocols/ws/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/profiles/internal/rpc/protocols/ws/.api
diff --git a/profiles/internal/rpc/protocols/wsh/.api b/profiles/internal/rpc/protocols/wsh/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/profiles/internal/rpc/protocols/wsh/.api
diff --git a/profiles/internal/rpc/protocols/wsh_nacl/.api b/profiles/internal/rpc/protocols/wsh_nacl/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/profiles/internal/rpc/protocols/wsh_nacl/.api
diff --git a/profiles/internal/rpc/server.go b/profiles/internal/rpc/server.go
index 91b3a1a..d41aa64 100644
--- a/profiles/internal/rpc/server.go
+++ b/profiles/internal/rpc/server.go
@@ -14,6 +14,9 @@
 	"sync"
 	"time"
 
+	"v.io/x/lib/netstate"
+	"v.io/x/lib/vlog"
+
 	"v.io/v23/config"
 	"v.io/v23/context"
 	"v.io/v23/namespace"
@@ -26,8 +29,7 @@
 	"v.io/v23/verror"
 	"v.io/v23/vom"
 	"v.io/v23/vtrace"
-	"v.io/x/lib/netstate"
-	"v.io/x/lib/vlog"
+
 	"v.io/x/ref/lib/stats"
 	"v.io/x/ref/profiles/internal/lib/publisher"
 	inaming "v.io/x/ref/profiles/internal/naming"
@@ -316,46 +318,10 @@
 	return "", verror.New(errFailedToResolveToEndpoint, s.ctx, address)
 }
 
-// getPossbileAddrs returns an appropriate set of addresses that could be used
-// to contact the supplied protocol, host, port parameters using the supplied
-// chooser function. It returns an indication of whether the supplied address
-// was fully specified or not, returning false if the address was fully
-// specified, and true if it was not.
-func getPossibleAddrs(protocol, host, port string, chooser rpc.AddressChooser) ([]rpc.Address, bool, error) {
-
-	ip := net.ParseIP(host)
-	if ip == nil {
-		return nil, false, verror.New(errFailedToParseIP, nil, host)
-	}
-
-	addrFromIP := func(ip net.IP) rpc.Address {
-		return &netstate.AddrIfc{
-			Addr: &net.IPAddr{IP: ip},
-		}
-	}
-
-	if ip.IsUnspecified() {
-		if chooser != nil {
-			// Need to find a usable IP address since the call to listen
-			// didn't specify one.
-			if addrs, err := netstate.GetAccessibleIPs(); err == nil {
-				a, err := chooser(protocol, addrs)
-				if err == nil && len(a) > 0 {
-					return a, true, nil
-				}
-			}
-		}
-		// We don't have a chooser, so we just return the address the
-		// underlying system has chosen.
-		return []rpc.Address{addrFromIP(ip)}, true, nil
-	}
-	return []rpc.Address{addrFromIP(ip)}, false, nil
-}
-
 // createEndpoints creates appropriate inaming.Endpoint instances for
 // all of the externally accessible network addresses that can be used
 // to reach this server.
-func (s *server) createEndpoints(lep naming.Endpoint, chooser rpc.AddressChooser) ([]*inaming.Endpoint, string, bool, error) {
+func (s *server) createEndpoints(lep naming.Endpoint, chooser netstate.AddressChooser) ([]*inaming.Endpoint, string, bool, error) {
 	iep, ok := lep.(*inaming.Endpoint)
 	if !ok {
 		return nil, "", false, verror.New(errInternalTypeConversion, nil, fmt.Sprintf("%T", lep))
@@ -365,15 +331,15 @@
 		// If not tcp, ws, or wsh, just return the endpoint we were given.
 		return []*inaming.Endpoint{iep}, "", false, nil
 	}
-
 	host, port, err := net.SplitHostPort(iep.Address)
 	if err != nil {
 		return nil, "", false, err
 	}
-	addrs, unspecified, err := getPossibleAddrs(iep.Protocol, host, port, chooser)
+	addrs, unspecified, err := netstate.PossibleAddresses(iep.Protocol, host, chooser)
 	if err != nil {
 		return nil, port, false, err
 	}
+
 	ieps := make([]*inaming.Endpoint, 0, len(addrs))
 	for _, addr := range addrs {
 		n, err := inaming.NewEndpoint(lep.String())
@@ -381,7 +347,7 @@
 			return nil, port, false, err
 		}
 		n.IsMountTable = s.servesMountTable
-		n.Address = net.JoinHostPort(addr.Address().String(), port)
+		n.Address = net.JoinHostPort(addr.String(), port)
 		ieps = append(ieps, n)
 	}
 	return ieps, port, unspecified, nil
@@ -652,7 +618,7 @@
 			return
 		}
 		switch v := setting.Value().(type) {
-		case []rpc.Address:
+		case []net.Addr:
 			s.Lock()
 			if s.isStopState() {
 				s.Unlock()
@@ -687,20 +653,20 @@
 	}
 }
 
-func getHost(address rpc.Address) string {
-	host, _, err := net.SplitHostPort(address.Address().String())
+func getHost(address net.Addr) string {
+	host, _, err := net.SplitHostPort(address.String())
 	if err == nil {
 		return host
 	}
-	return address.Address().String()
+	return address.String()
 
 }
 
 // Remove all endpoints that have the same host address as the supplied
 // address parameter.
-func (s *server) removeAddresses(addresses []rpc.Address) ([]naming.Endpoint, error) {
+func (s *server) removeAddresses(addrs []net.Addr) ([]naming.Endpoint, error) {
 	var removed []naming.Endpoint
-	for _, address := range addresses {
+	for _, address := range addrs {
 		host := getHost(address)
 		for ls, _ := range s.listenState {
 			if ls != nil && ls.roaming && len(ls.ieps) > 0 {
@@ -735,13 +701,16 @@
 // externally accessible.
 // This places the onus on the dhcp/roaming code that sends us addresses
 // to ensure that those addresses are externally reachable.
-func (s *server) addAddresses(addresses []rpc.Address) []naming.Endpoint {
+func (s *server) addAddresses(addrs []net.Addr) []naming.Endpoint {
 	var added []naming.Endpoint
-	for _, address := range addresses {
+	vlog.Infof("HERE WITH %v -> %v", addrs, netstate.ConvertToAddresses(addrs))
+	for _, address := range netstate.ConvertToAddresses(addrs) {
 		if !netstate.IsAccessibleIP(address) {
+			vlog.Infof("RETURN A %v", added)
 			return added
 		}
 		host := getHost(address)
+		vlog.Infof("LISTEN ST: %v", s.listenState)
 		for ls, _ := range s.listenState {
 			if ls != nil && ls.roaming {
 				niep := ls.protoIEP
@@ -755,6 +724,7 @@
 			}
 		}
 	}
+	vlog.Infof("RETURN B %v", added)
 	return added
 }
 
diff --git a/profiles/internal/rpc/server_test.go b/profiles/internal/rpc/server_test.go
index 4e4dbe5..4e30884 100644
--- a/profiles/internal/rpc/server_test.go
+++ b/profiles/internal/rpc/server_test.go
@@ -371,7 +371,7 @@
 	return &niep
 }
 
-func getIPAddrs(eps []naming.Endpoint) []rpc.Address {
+func getIPAddrs(eps []naming.Endpoint) []net.Addr {
 	hosts := map[string]struct{}{}
 	for _, ep := range eps {
 		iep := (ep).(*inaming.Endpoint)
@@ -380,10 +380,9 @@
 			hosts[h] = struct{}{}
 		}
 	}
-	addrs := []rpc.Address{}
+	addrs := []net.Addr{}
 	for h, _ := range hosts {
-		a := &netstate.AddrIfc{Addr: &net.IPAddr{IP: net.ParseIP(h)}}
-		addrs = append(addrs, a)
+		addrs = append(addrs, netstate.NewNetAddr("ip", h))
 	}
 	return addrs
 }
@@ -439,11 +438,11 @@
 	}
 	defer func() { publisher.Shutdown(); <-stop }()
 
-	ipv4And6 := func(network string, addrs []rpc.Address) ([]rpc.Address, error) {
-		accessible := netstate.AddrList(addrs)
+	ipv4And6 := func(network string, addrs []net.Addr) ([]net.Addr, error) {
+		accessible := netstate.ConvertToAddresses(addrs)
 		ipv4 := accessible.Filter(netstate.IsUnicastIPv4)
 		ipv6 := accessible.Filter(netstate.IsUnicastIPv6)
-		return append(ipv4, ipv6...), nil
+		return append(ipv4.AsNetAddrs(), ipv6.AsNetAddrs()...), nil
 	}
 	spec := rpc.ListenSpec{
 		Addrs: rpc.ListenAddrs{
@@ -481,14 +480,14 @@
 		t.Fatalf("got %d, want %d", got, want)
 	}
 
-	n1 := &netstate.AddrIfc{Addr: &net.IPAddr{IP: net.ParseIP("1.1.1.1")}}
-	n2 := &netstate.AddrIfc{Addr: &net.IPAddr{IP: net.ParseIP("2.2.2.2")}}
+	n1 := netstate.NewNetAddr("ip", "1.1.1.1")
+	n2 := netstate.NewNetAddr("ip", "2.2.2.2")
 
 	watcher := make(chan rpc.NetworkChange, 10)
 	server.WatchNetwork(watcher)
 	defer close(watcher)
 
-	roaming <- rpc.NewAddAddrsSetting([]rpc.Address{n1, n2})
+	roaming <- rpc.NewAddAddrsSetting([]net.Addr{n1, n2})
 
 	waitForChange := func() *rpc.NetworkChange {
 		vlog.Infof("Waiting on %p", watcher)
@@ -527,7 +526,7 @@
 		t.Fatalf("got %d, want %d", got, want)
 	}
 
-	roaming <- rpc.NewRmAddrsSetting([]rpc.Address{n1})
+	roaming <- rpc.NewRmAddrsSetting([]net.Addr{n1})
 
 	// We expect 2 changes, one for each usable listen spec addr.
 	change = waitForChange()
@@ -561,7 +560,7 @@
 		t.Fatalf("got %d, want %d: %v", got, want, status.Mounts)
 	}
 
-	roaming <- rpc.NewAddAddrsSetting([]rpc.Address{n1})
+	roaming <- rpc.NewAddAddrsSetting([]net.Addr{n1})
 	// We expect 2 changes, one for each usable listen spec addr.
 	change = waitForChange()
 	if got, want := len(change.Changed), 2; got != want {
@@ -618,9 +617,9 @@
 	roaming <- rpc.NewRmAddrsSetting(getIPAddrs(eps))
 
 	// Add in two new addresses
-	n1 := &netstate.AddrIfc{Addr: &net.IPAddr{IP: net.ParseIP("1.1.1.1")}}
-	n2 := &netstate.AddrIfc{Addr: &net.IPAddr{IP: net.ParseIP("2.2.2.2")}}
-	roaming <- rpc.NewAddAddrsSetting([]rpc.Address{n1, n2})
+	n1 := netstate.NewNetAddr("ip", "1.1.1.1")
+	n2 := netstate.NewNetAddr("ip", "2.2.2.2")
+	roaming <- rpc.NewAddAddrsSetting([]net.Addr{n1, n2})
 
 	neps := make([]naming.Endpoint, 0, len(eps))
 	for _, p := range getUniqPorts(eps) {
diff --git a/profiles/internal/rpc/sort_endpoints.go b/profiles/internal/rpc/sort_endpoints.go
index 8ea0bd9..57409e7 100644
--- a/profiles/internal/rpc/sort_endpoints.go
+++ b/profiles/internal/rpc/sort_endpoints.go
@@ -200,16 +200,16 @@
 
 // ipNetworks returns the IP networks on this machine.
 func ipNetworks() []*net.IPNet {
-	ifcs, err := netstate.GetAll()
+	ifcs, err := netstate.GetAllAddresses()
 	if err != nil {
-		vlog.VI(5).Infof("netstate.GetAll failed: %v", err)
+		vlog.VI(5).Infof("netstate.GetAllAddresses failed: %v", err)
 		return nil
 	}
 	ret := make([]*net.IPNet, 0, len(ifcs))
 	for _, a := range ifcs {
-		_, ipnet, err := net.ParseCIDR(a.Address().String())
+		_, ipnet, err := net.ParseCIDR(a.String())
 		if err != nil {
-			vlog.VI(5).Infof("net.ParseCIDR(%q) failed: %v", a.Address(), err)
+			vlog.VI(5).Infof("net.ParseCIDR(%q) failed: %v", a, err)
 			continue
 		}
 		ret = append(ret, ipnet)
diff --git a/profiles/internal/rpc/stream/.api b/profiles/internal/rpc/stream/.api
new file mode 100644
index 0000000..47baafe
--- /dev/null
+++ b/profiles/internal/rpc/stream/.api
@@ -0,0 +1,53 @@
+pkg stream, func NewNetError(error, bool, bool) net.Error
+pkg stream, method (NetError) Error() string
+pkg stream, method (NetError) Temporary() bool
+pkg stream, method (NetError) Timeout() bool
+pkg stream, type Connector interface { Connect }
+pkg stream, type Connector interface, Connect(...FlowOpt) (Flow, error)
+pkg stream, type Flow interface { Cancel, Close, Closed, IsClosed, LocalBlessings, LocalDischarges, LocalEndpoint, LocalPrincipal, Read, RemoteBlessings, RemoteDischarges, RemoteEndpoint, SetDeadline, VCDataCache, Write }
+pkg stream, type Flow interface, Cancel()
+pkg stream, type Flow interface, Close() error
+pkg stream, type Flow interface, Closed() <-chan struct{}
+pkg stream, type Flow interface, IsClosed() bool
+pkg stream, type Flow interface, LocalBlessings() security.Blessings
+pkg stream, type Flow interface, LocalDischarges() map[string]security.Discharge
+pkg stream, type Flow interface, LocalEndpoint() naming.Endpoint
+pkg stream, type Flow interface, LocalPrincipal() security.Principal
+pkg stream, type Flow interface, Read([]byte) (int, error)
+pkg stream, type Flow interface, RemoteBlessings() security.Blessings
+pkg stream, type Flow interface, RemoteDischarges() map[string]security.Discharge
+pkg stream, type Flow interface, RemoteEndpoint() naming.Endpoint
+pkg stream, type Flow interface, SetDeadline(<-chan struct{})
+pkg stream, type Flow interface, VCDataCache() VCDataCache
+pkg stream, type Flow interface, Write([]byte) (int, error)
+pkg stream, type FlowOpt interface { RPCStreamFlowOpt }
+pkg stream, type FlowOpt interface, RPCStreamFlowOpt()
+pkg stream, type Listener interface { Accept, Close }
+pkg stream, type Listener interface, Accept() (Flow, error)
+pkg stream, type Listener interface, Close() error
+pkg stream, type ListenerOpt interface { RPCStreamListenerOpt }
+pkg stream, type ListenerOpt interface, RPCStreamListenerOpt()
+pkg stream, type Manager interface { Dial, Listen, RoutingID, Shutdown, ShutdownEndpoint }
+pkg stream, type Manager interface, Dial(naming.Endpoint, security.Principal, ...VCOpt) (VC, error)
+pkg stream, type Manager interface, Listen(string, string, security.Principal, security.Blessings, ...ListenerOpt) (Listener, naming.Endpoint, error)
+pkg stream, type Manager interface, RoutingID() naming.RoutingID
+pkg stream, type Manager interface, Shutdown()
+pkg stream, type Manager interface, ShutdownEndpoint(naming.Endpoint)
+pkg stream, type NetError struct
+pkg stream, type VC interface { Close, Connect, Listen }
+pkg stream, type VC interface, Close(error) error
+pkg stream, type VC interface, Connect(...FlowOpt) (Flow, error)
+pkg stream, type VC interface, Listen() (Listener, error)
+pkg stream, type VCDataCache interface { Get, GetOrInsert }
+pkg stream, type VCDataCache interface, Get(interface{}) interface{}
+pkg stream, type VCDataCache interface, GetOrInsert(interface{}, func() interface{}) interface{}
+pkg stream, type VCOpt interface { RPCStreamVCOpt }
+pkg stream, type VCOpt interface, RPCStreamVCOpt()
+pkg stream, var ErrAborted unknown-type
+pkg stream, var ErrBadArg unknown-type
+pkg stream, var ErrBadState unknown-type
+pkg stream, var ErrDialFailed unknown-type
+pkg stream, var ErrNetwork unknown-type
+pkg stream, var ErrNotTrusted unknown-type
+pkg stream, var ErrProxy unknown-type
+pkg stream, var ErrSecurity unknown-type
diff --git a/profiles/internal/rpc/stream/benchmark/.api b/profiles/internal/rpc/stream/benchmark/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/profiles/internal/rpc/stream/benchmark/.api
diff --git a/profiles/internal/rpc/stream/crypto/.api b/profiles/internal/rpc/stream/crypto/.api
new file mode 100644
index 0000000..b35c455
--- /dev/null
+++ b/profiles/internal/rpc/stream/crypto/.api
@@ -0,0 +1,34 @@
+pkg crypto, func NewBoxCrypter(BoxKeyExchanger, *iobuf.Pool) (Crypter, error)
+pkg crypto, func NewControlCipherRPC6(*BoxKey, *BoxKey, bool) ControlCipher
+pkg crypto, func NewDisabledControlCipher(ControlCipher) ControlCipher
+pkg crypto, func NewNullCrypter() Crypter
+pkg crypto, func NewTLSClient(io.ReadWriteCloser, net.Addr, net.Addr, TLSClientSessionCache, *iobuf.Pool) (Crypter, error)
+pkg crypto, func NewTLSClientSessionCache() TLSClientSessionCache
+pkg crypto, func NewTLSServer(io.ReadWriteCloser, net.Addr, net.Addr, *iobuf.Pool) (Crypter, error)
+pkg crypto, func ServerTLSConfig() *tls.Config
+pkg crypto, method (NullControlCipher) Decrypt([]byte)
+pkg crypto, method (NullControlCipher) Encrypt([]byte)
+pkg crypto, method (NullControlCipher) MACSize() int
+pkg crypto, method (NullControlCipher) Open([]byte) bool
+pkg crypto, method (NullControlCipher) Seal([]byte) error
+pkg crypto, method (TLSClientSessionCache) RPCStreamVCOpt()
+pkg crypto, type BoxKey [32]byte
+pkg crypto, type BoxKeyExchanger func(myPublicKey *BoxKey) (theirPublicKey *BoxKey, err error)
+pkg crypto, type ControlCipher interface { Decrypt, Encrypt, MACSize, Open, Seal }
+pkg crypto, type ControlCipher interface, Decrypt([]byte)
+pkg crypto, type ControlCipher interface, Encrypt([]byte)
+pkg crypto, type ControlCipher interface, MACSize() int
+pkg crypto, type ControlCipher interface, Open([]byte) bool
+pkg crypto, type ControlCipher interface, Seal([]byte) error
+pkg crypto, type Crypter interface { ChannelBinding, Decrypt, Encrypt, String }
+pkg crypto, type Crypter interface, ChannelBinding() []byte
+pkg crypto, type Crypter interface, Decrypt(*iobuf.Slice) (*iobuf.Slice, error)
+pkg crypto, type Crypter interface, Encrypt(*iobuf.Slice) (*iobuf.Slice, error)
+pkg crypto, type Crypter interface, String() string
+pkg crypto, type Decrypter interface { Decrypt }
+pkg crypto, type Decrypter interface, Decrypt(*iobuf.Slice) (*iobuf.Slice, error)
+pkg crypto, type Encrypter interface { Encrypt }
+pkg crypto, type Encrypter interface, Encrypt(*iobuf.Slice) (*iobuf.Slice, error)
+pkg crypto, type NullControlCipher struct
+pkg crypto, type TLSClientSessionCache struct
+pkg crypto, type TLSClientSessionCache struct, embedded tls.ClientSessionCache
diff --git a/profiles/internal/rpc/stream/id/.api b/profiles/internal/rpc/stream/id/.api
new file mode 100644
index 0000000..e1cb2e1
--- /dev/null
+++ b/profiles/internal/rpc/stream/id/.api
@@ -0,0 +1,2 @@
+pkg id, type Flow uint32
+pkg id, type VC uint32
diff --git a/profiles/internal/rpc/stream/manager/.api b/profiles/internal/rpc/stream/manager/.api
new file mode 100644
index 0000000..80636ef
--- /dev/null
+++ b/profiles/internal/rpc/stream/manager/.api
@@ -0,0 +1,4 @@
+pkg manager, func InternalNew(naming.RoutingID) stream.Manager
+pkg manager, method (DialTimeout) RPCClientOpt()
+pkg manager, method (DialTimeout) RPCStreamVCOpt()
+pkg manager, type DialTimeout time.Duration
diff --git a/profiles/internal/rpc/stream/message/.api b/profiles/internal/rpc/stream/message/.api
new file mode 100644
index 0000000..f9b8fcb
--- /dev/null
+++ b/profiles/internal/rpc/stream/message/.api
@@ -0,0 +1,53 @@
+pkg message, const HeaderSizeBytes ideal-int
+pkg message, func EncryptMessage([]byte, crypto.ControlCipher) error
+pkg message, func MakeCounterID(id.VC, id.Flow) CounterID
+pkg message, func NewCounters() Counters
+pkg message, func ReadFrom(*iobuf.Reader, crypto.ControlCipher) (T, error)
+pkg message, func WriteTo(io.Writer, T, crypto.ControlCipher) error
+pkg message, method (*CounterID) Flow() id.Flow
+pkg message, method (*CounterID) String() string
+pkg message, method (*CounterID) VCI() id.VC
+pkg message, method (*Data) Close() bool
+pkg message, method (*Data) PayloadSize() int
+pkg message, method (*Data) Release()
+pkg message, method (*Data) SetClose()
+pkg message, method (*Data) String() string
+pkg message, method (*Setup) NaclBox() *NaclBox
+pkg message, method (Counters) Add(id.VC, id.Flow, uint32)
+pkg message, method (Counters) String() string
+pkg message, type AddReceiveBuffers struct
+pkg message, type AddReceiveBuffers struct, Counters Counters
+pkg message, type CloseVC struct
+pkg message, type CloseVC struct, Error string
+pkg message, type CloseVC struct, VCI id.VC
+pkg message, type Control interface, unexported methods
+pkg message, type CounterID uint64
+pkg message, type Counters map[CounterID]uint32
+pkg message, type Data struct
+pkg message, type Data struct, Flow id.Flow
+pkg message, type Data struct, Payload *iobuf.Slice
+pkg message, type Data struct, VCI id.VC
+pkg message, type NaclBox struct
+pkg message, type NaclBox struct, PublicKey crypto.BoxKey
+pkg message, type OpenFlow struct
+pkg message, type OpenFlow struct, Flow id.Flow
+pkg message, type OpenFlow struct, InitialCounters uint32
+pkg message, type OpenFlow struct, VCI id.VC
+pkg message, type OpenVC struct
+pkg message, type OpenVC struct, Counters Counters
+pkg message, type OpenVC struct, DstEndpoint naming.Endpoint
+pkg message, type OpenVC struct, SrcEndpoint naming.Endpoint
+pkg message, type OpenVC struct, VCI id.VC
+pkg message, type Setup struct
+pkg message, type Setup struct, Options []SetupOption
+pkg message, type Setup struct, Versions version.Range
+pkg message, type SetupOption interface, unexported methods
+pkg message, type SetupStream struct
+pkg message, type SetupStream struct, Data []byte
+pkg message, type SetupVC struct
+pkg message, type SetupVC struct, Counters Counters
+pkg message, type SetupVC struct, LocalEndpoint naming.Endpoint
+pkg message, type SetupVC struct, RemoteEndpoint naming.Endpoint
+pkg message, type SetupVC struct, Setup Setup
+pkg message, type SetupVC struct, VCI id.VC
+pkg message, type T interface {}
diff --git a/profiles/internal/rpc/stream/proxy/.api b/profiles/internal/rpc/stream/proxy/.api
new file mode 100644
index 0000000..604aef5
--- /dev/null
+++ b/profiles/internal/rpc/stream/proxy/.api
@@ -0,0 +1,6 @@
+pkg proxy, func New(*context.T, string, string, string, ...string) (func(), naming.Endpoint, error)
+pkg proxy, type Proxy struct
+pkg proxy, type Request struct
+pkg proxy, type Response struct
+pkg proxy, type Response struct, Endpoint string
+pkg proxy, type Response struct, Error error
diff --git a/profiles/internal/rpc/stream/proxy/proxy.go b/profiles/internal/rpc/stream/proxy/proxy.go
index 09d3586..f74428b 100644
--- a/profiles/internal/rpc/stream/proxy/proxy.go
+++ b/profiles/internal/rpc/stream/proxy/proxy.go
@@ -10,6 +10,8 @@
 	"sync"
 	"time"
 
+	"v.io/x/lib/netstate"
+
 	"v.io/v23"
 	"v.io/v23/context"
 	"v.io/v23/naming"
@@ -67,6 +69,9 @@
 	errFailedToFowardOpenFlow    = reg(".errFailedToFowardOpenFlow", "failed to forward open flow{:3}")
 	errServerNotBeingProxied     = reg(".errServerNotBeingProxied", "no server with routing id {3} is being proxied")
 	errServerVanished            = reg(".errServerVanished", "server with routing id {3} vanished")
+	errAccessibleAddresses       = reg(".errAccessibleAddresses", "failed to obtain a set of accessible addresses{:3}")
+	errNoAccessibleAddresses     = reg(".errNoAccessibleAddresses", "no accessible addresses were available for {3}")
+	errEmptyListenSpec           = reg(".errEmptyListenSpec", "no addresses supplied in the listen spec")
 )
 
 // Proxy routes virtual circuit (VC) traffic between multiple underlying
@@ -90,7 +95,6 @@
 	conn         net.Conn
 	pool         *iobuf.Pool
 	reader       *iobuf.Reader
-	isSetup      bool
 	ctrlCipher   crypto.ControlCipher
 	queue        *upcqueue.T
 	mu           sync.RWMutex
@@ -182,13 +186,13 @@
 // TODO(mattr): This should take a ListenSpec instead of network, address, and
 // pubAddress.  However using a ListenSpec requires a great deal of supporting
 // code that should be refactored out of v.io/x/ref/profiles/internal/rpc/server.go.
-func New(ctx *context.T, network, address, pubAddress string, names ...string) (shutdown func(), endpoint naming.Endpoint, err error) {
+func New(ctx *context.T, spec rpc.ListenSpec, names ...string) (shutdown func(), endpoint naming.Endpoint, err error) {
 	rid, err := naming.NewRoutingID()
 	if err != nil {
 		return nil, nil, err
 	}
 
-	proxy, err := internalNew(rid, v23.GetPrincipal(ctx), network, address, pubAddress)
+	proxy, err := internalNew(rid, v23.GetPrincipal(ctx), spec)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -217,7 +221,13 @@
 	return shutdown, proxy.endpoint(), nil
 }
 
-func internalNew(rid naming.RoutingID, principal security.Principal, network, address, pubAddress string) (*Proxy, error) {
+func internalNew(rid naming.RoutingID, principal security.Principal, spec rpc.ListenSpec) (*Proxy, error) {
+	if len(spec.Addrs) == 0 {
+		return nil, verror.New(stream.ErrProxy, nil, verror.New(errEmptyListenSpec, nil))
+	}
+	laddr := spec.Addrs[0]
+	network := laddr.Protocol
+	address := laddr.Address
 	_, listenFn, _ := rpc.RegisteredProtocol(network)
 	if listenFn == nil {
 		return nil, verror.New(stream.ErrProxy, nil, verror.New(errUnknownNetwork, nil, network))
@@ -226,15 +236,23 @@
 	if err != nil {
 		return nil, verror.New(stream.ErrProxy, nil, verror.New(errListenFailed, nil, network, address, err))
 	}
-	if len(pubAddress) == 0 {
-		pubAddress = ln.Addr().String()
+	pub, _, err := netstate.PossibleAddresses(ln.Addr().Network(), ln.Addr().String(), spec.AddressChooser)
+	if err != nil {
+		ln.Close()
+		return nil, verror.New(stream.ErrProxy, nil, verror.New(errAccessibleAddresses, nil, err))
 	}
+	if len(pub) == 0 {
+		ln.Close()
+		return nil, verror.New(stream.ErrProxy, nil, verror.New(errNoAccessibleAddresses, nil, ln.Addr().String()))
+	}
+
 	proxy := &Proxy{
-		ln:         ln,
-		rid:        rid,
-		servers:    &servermap{m: make(map[naming.RoutingID]*server)},
-		processes:  make(map[*process]struct{}),
-		pubAddress: pubAddress,
+		ln:        ln,
+		rid:       rid,
+		servers:   &servermap{m: make(map[naming.RoutingID]*server)},
+		processes: make(map[*process]struct{}),
+		// TODO(cnicolaou): should use all of the available addresses
+		pubAddress: pub[0].String(),
 		principal:  principal,
 		statsName:  naming.Join("rpc", "proxy", "routing-id", rid.String(), "debug"),
 	}
@@ -261,12 +279,25 @@
 
 func (p *Proxy) acceptProcess(conn net.Conn) {
 	pool := iobuf.NewPool(0)
+	reader := iobuf.NewReader(pool, conn)
+
+	var blessings security.Blessings
+	if p.principal != nil {
+		blessings = p.principal.BlessingStore().Default()
+	}
+
+	c, err := vif.AuthenticateAsServer(conn, reader, nil, p.principal, blessings, nil)
+	if err != nil {
+		processLog().Infof("Process %v failed to authenticate: %s", p, err)
+		return
+	}
+
 	process := &process{
 		proxy:        p,
 		conn:         conn,
 		pool:         pool,
-		reader:       iobuf.NewReader(pool, conn),
-		ctrlCipher:   &crypto.NullControlCipher{},
+		reader:       reader,
+		ctrlCipher:   c,
 		queue:        upcqueue.New(),
 		routingTable: make(map[id.VC]*destination),
 		servers:      make(map[id.VC]*vc.VC),
@@ -661,26 +692,8 @@
 			dstprocess.queue.Put(m)
 			p.proxy.routeCounters(p, counters)
 
-		case *message.Setup:
-			// Set up the hop.  This takes over the process during negotiation.
-			if p.isSetup {
-				// Already performed authentication.  We don't do it again.
-				processLog().Infof("Process %v is already setup", p)
-				return
-			}
-			var blessings security.Blessings
-			if p.proxy.principal != nil {
-				blessings = p.proxy.principal.BlessingStore().Default()
-			}
-			c, err := vif.AuthenticateAsServer(p.conn, p.reader, nil, p.proxy.principal, blessings, nil, m)
-			if err != nil {
-				processLog().Infof("Process %v failed to authenticate: %s", p, err)
-				return
-			}
-			p.ctrlCipher = c
-			p.isSetup = true
 		default:
-			processLog().Infof("Closing %v because of unrecognized message %T", p, m)
+			processLog().Infof("Closing %v because of invalid message %T", p, m)
 			return
 		}
 	}
diff --git a/profiles/internal/rpc/stream/proxy/proxy_test.go b/profiles/internal/rpc/stream/proxy/proxy_test.go
index 6a08df9..c84e7cf 100644
--- a/profiles/internal/rpc/stream/proxy/proxy_test.go
+++ b/profiles/internal/rpc/stream/proxy/proxy_test.go
@@ -13,7 +13,11 @@
 	"testing"
 	"time"
 
+	"v.io/x/lib/vlog"
+
+	"v.io/v23"
 	"v.io/v23/naming"
+	"v.io/v23/verror"
 
 	_ "v.io/x/ref/profiles"
 	inaming "v.io/x/ref/profiles/internal/naming"
@@ -22,14 +26,19 @@
 	"v.io/x/ref/profiles/internal/rpc/stream/proxy"
 	"v.io/x/ref/profiles/internal/rpc/stream/vc"
 	"v.io/x/ref/profiles/internal/rpc/stream/vif"
+	"v.io/x/ref/test"
 	"v.io/x/ref/test/testutil"
 )
 
 //go:generate v23 test generate
 
 func TestProxy(t *testing.T) {
+	ctx, shutdown := test.InitForTest()
+	defer shutdown()
+
 	pproxy := testutil.NewPrincipal("proxy")
-	_, shutdown, proxyEp, err := proxy.InternalNew(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), pproxy, "tcp", "127.0.0.1:0", "")
+
+	_, shutdown, proxyEp, err := proxy.InternalNew(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), pproxy, v23.GetListenSpec(ctx))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -37,6 +46,8 @@
 	principal := testutil.NewPrincipal("test")
 	blessings := principal.BlessingStore().Default()
 
+	vlog.Infof("PROXYEP: %s", proxyEp)
+
 	// Create the stream.Manager for the server.
 	server1 := manager.InternalNew(naming.FixedRoutingID(0x1111111111111111))
 	defer server1.Shutdown()
@@ -44,6 +55,7 @@
 	// through the proxy.
 	ln1, ep1, err := server1.Listen(proxyEp.Network(), proxyEp.String(), principal, blessings)
 	if err != nil {
+		t.Logf(verror.DebugString(err))
 		t.Fatal(err)
 	}
 	defer ln1.Close()
@@ -91,8 +103,11 @@
 }
 
 func TestDuplicateRoutingID(t *testing.T) {
+	ctx, shutdown := test.InitForTest()
+	defer shutdown()
+
 	pproxy := testutil.NewPrincipal("proxy")
-	_, shutdown, proxyEp, err := proxy.InternalNew(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), pproxy, "tcp", "127.0.0.1:0", "")
+	_, shutdown, proxyEp, err := proxy.InternalNew(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), pproxy, v23.GetListenSpec(ctx))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -122,8 +137,11 @@
 }
 
 func TestProxyAuthentication(t *testing.T) {
+	ctx, shutdown := test.InitForTest()
+	defer shutdown()
+
 	pproxy := testutil.NewPrincipal("proxy")
-	_, shutdown, proxyEp, err := proxy.InternalNew(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), pproxy, "tcp", "127.0.0.1:0", "")
+	_, shutdown, proxyEp, err := proxy.InternalNew(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), pproxy, v23.GetListenSpec(ctx))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -150,13 +168,16 @@
 }
 
 func TestServerBlessings(t *testing.T) {
+	ctx, shutdown := test.InitForTest()
+	defer shutdown()
+
 	var (
 		pproxy  = testutil.NewPrincipal("proxy")
 		pserver = testutil.NewPrincipal("server")
 		pclient = testutil.NewPrincipal("client")
 	)
 
-	_, shutdown, proxyEp, err := proxy.InternalNew(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), pproxy, "tcp", "127.0.0.1:0", "")
+	_, shutdown, proxyEp, err := proxy.InternalNew(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), pproxy, v23.GetListenSpec(ctx))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -200,8 +221,11 @@
 }
 
 func TestHostPort(t *testing.T) {
+	ctx, shutdown := test.InitForTest()
+	defer shutdown()
+
 	pproxy := testutil.NewPrincipal("proxy")
-	_, shutdown, proxyEp, err := proxy.InternalNew(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), pproxy, "tcp", "127.0.0.1:0", "")
+	_, shutdown, proxyEp, err := proxy.InternalNew(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), pproxy, v23.GetListenSpec(ctx))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -220,8 +244,11 @@
 }
 
 func TestClientBecomesServer(t *testing.T) {
+	ctx, shutdown := test.InitForTest()
+	defer shutdown()
+
 	pproxy := testutil.NewPrincipal("proxy")
-	_, shutdown, proxyEp, err := proxy.InternalNew(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), pproxy, "tcp", "127.0.0.1:0", "")
+	_, shutdown, proxyEp, err := proxy.InternalNew(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), pproxy, v23.GetListenSpec(ctx))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -275,6 +302,9 @@
 }
 
 func testProxyIdleTimeout(t *testing.T, testServer bool) {
+	ctx, shutdown := test.InitForTest()
+	defer shutdown()
+
 	const (
 		idleTime = 10 * time.Millisecond
 		// We use a long wait time here since it takes some time to handle VC close
@@ -299,7 +329,7 @@
 	// Pause the idle timers.
 	triggerTimers := vif.SetFakeTimers()
 
-	Proxy, shutdown, proxyEp, err := proxy.InternalNew(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), pproxy, "tcp", "127.0.0.1:0", "")
+	Proxy, shutdown, proxyEp, err := proxy.InternalNew(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), pproxy, v23.GetListenSpec(ctx))
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/profiles/internal/rpc/stream/proxy/testutil_test.go b/profiles/internal/rpc/stream/proxy/testutil_test.go
index 1e469b2..8a1568c 100644
--- a/profiles/internal/rpc/stream/proxy/testutil_test.go
+++ b/profiles/internal/rpc/stream/proxy/testutil_test.go
@@ -6,13 +6,17 @@
 
 import (
 	"v.io/v23/naming"
+	"v.io/v23/rpc"
 	"v.io/v23/security"
 )
 
 // These are the internal functions only for use in the proxy_test package.
 
-func InternalNew(rid naming.RoutingID, p security.Principal, net, addr, pubAddr string) (*Proxy, func(), naming.Endpoint, error) {
-	proxy, err := internalNew(rid, p, net, addr, pubAddr)
+func InternalNew(rid naming.RoutingID, p security.Principal, spec rpc.ListenSpec) (*Proxy, func(), naming.Endpoint, error) {
+	proxy, err := internalNew(rid, p, spec)
+	if err != nil {
+		return nil, nil, nil, err
+	}
 	return proxy, proxy.shutdown, proxy.endpoint(), err
 }
 
diff --git a/profiles/internal/rpc/stream/vc/.api b/profiles/internal/rpc/stream/vc/.api
new file mode 100644
index 0000000..11bcfcc
--- /dev/null
+++ b/profiles/internal/rpc/stream/vc/.api
@@ -0,0 +1,80 @@
+pkg vc, const AuthFlowID ideal-int
+pkg vc, const DefaultBytesBufferedPerFlow ideal-int
+pkg vc, const DefaultServerDischargeExpiryBuffer time.Duration
+pkg vc, const HandshakeFlowID ideal-int
+pkg vc, const MaxPayloadSizeBytes ideal-int
+pkg vc, const MaxSharedBytes ideal-int
+pkg vc, const NumFlowPriorities bqueue.Priority
+pkg vc, const NumReservedFlows ideal-int
+pkg vc, const NumReservedVCs ideal-int
+pkg vc, const SharedFlowID ideal-int
+pkg vc, const TypeFlowID ideal-int
+pkg vc, func AuthenticateAsClient(io.ReadWriteCloser, crypto.Crypter, security.CallParams, *ServerAuthorizer, version.RPCVersion) (security.Blessings, security.Blessings, map[string]security.Discharge, error)
+pkg vc, func AuthenticateAsServer(io.ReadWriteCloser, security.Principal, security.Blessings, DischargeClient, crypto.Crypter, version.RPCVersion) (security.Blessings, map[string]security.Discharge, error)
+pkg vc, func InternalNew(Params) *VC
+pkg vc, method (*ServerAuthorizer) Authorize(security.CallParams) error
+pkg vc, method (*ServerAuthorizer) RPCStreamVCOpt()
+pkg vc, method (*VC) AcceptFlow(id.Flow) error
+pkg vc, method (*VC) Close(error) error
+pkg vc, method (*VC) Connect(...stream.FlowOpt) (stream.Flow, error)
+pkg vc, method (*VC) DebugString() string
+pkg vc, method (*VC) DispatchPayload(id.Flow, *iobuf.Slice) error
+pkg vc, method (*VC) Encrypt(id.Flow, *iobuf.Slice) (*iobuf.Slice, error)
+pkg vc, method (*VC) FinishHandshakeDialedVC(version.RPCVersion, *crypto.BoxKey) error
+pkg vc, method (*VC) HandshakeAcceptedVC(version.RPCVersion, security.Principal, security.Blessings, crypto.BoxKeyExchanger, ...stream.ListenerOpt) <-chan HandshakeResult
+pkg vc, method (*VC) HandshakeDialedVC(security.Principal, version.RPCVersion, func(*crypto.BoxKey) error, ...stream.VCOpt) error
+pkg vc, method (*VC) Listen() (stream.Listener, error)
+pkg vc, method (*VC) LocalBlessings() security.Blessings
+pkg vc, method (*VC) LocalDischarges() map[string]security.Discharge
+pkg vc, method (*VC) LocalEndpoint() naming.Endpoint
+pkg vc, method (*VC) LocalPrincipal() security.Principal
+pkg vc, method (*VC) ReleaseCounters(id.Flow, uint32)
+pkg vc, method (*VC) RemoteBlessings() security.Blessings
+pkg vc, method (*VC) RemoteDischarges() map[string]security.Discharge
+pkg vc, method (*VC) RemoteEndpoint() naming.Endpoint
+pkg vc, method (*VC) ShutdownFlow(id.Flow)
+pkg vc, method (*VC) String() string
+pkg vc, method (*VC) VCDataCache() stream.VCDataCache
+pkg vc, method (*VC) VCI() id.VC
+pkg vc, method (*VC) Version() version.RPCVersion
+pkg vc, method (DialContext) RPCStreamListenerOpt()
+pkg vc, method (DialContext) RPCStreamVCOpt()
+pkg vc, method (DischargeExpiryBuffer) RPCServerOpt()
+pkg vc, method (DischargeExpiryBuffer) RPCStreamListenerOpt()
+pkg vc, method (IdleTimeout) RPCStreamListenerOpt()
+pkg vc, method (IdleTimeout) RPCStreamVCOpt()
+pkg vc, method (StartTimeout) RPCStreamListenerOpt()
+pkg vc, method (StartTimeout) RPCStreamVCOpt()
+pkg vc, type DialContext struct
+pkg vc, type DialContext struct, embedded *context.T
+pkg vc, type DischargeClient interface { Invalidate, PrepareDischarges, RPCStreamListenerOpt }
+pkg vc, type DischargeClient interface, Invalidate(...security.Discharge)
+pkg vc, type DischargeClient interface, PrepareDischarges(*context.T, []security.Caveat, security.DischargeImpetus) []security.Discharge
+pkg vc, type DischargeClient interface, RPCStreamListenerOpt()
+pkg vc, type DischargeExpiryBuffer time.Duration
+pkg vc, type HandshakeResult struct
+pkg vc, type HandshakeResult struct, Error error
+pkg vc, type HandshakeResult struct, Listener stream.Listener
+pkg vc, type Helper interface { AddReceiveBuffers, NewWriter, NotifyOfNewFlow }
+pkg vc, type Helper interface, AddReceiveBuffers(id.VC, id.Flow, uint)
+pkg vc, type Helper interface, NewWriter(id.VC, id.Flow, bqueue.Priority) (bqueue.Writer, error)
+pkg vc, type Helper interface, NotifyOfNewFlow(id.VC, id.Flow, uint)
+pkg vc, type IdleTimeout struct
+pkg vc, type IdleTimeout struct, embedded time.Duration
+pkg vc, type Params struct
+pkg vc, type Params struct, Dialed bool
+pkg vc, type Params struct, Helper Helper
+pkg vc, type Params struct, LocalEP naming.Endpoint
+pkg vc, type Params struct, Pool *iobuf.Pool
+pkg vc, type Params struct, RemoteEP naming.Endpoint
+pkg vc, type Params struct, ReserveBytes uint
+pkg vc, type Params struct, VCI id.VC
+pkg vc, type ServerAuthorizer struct
+pkg vc, type ServerAuthorizer struct, Method string
+pkg vc, type ServerAuthorizer struct, Policy security.Authorizer
+pkg vc, type ServerAuthorizer struct, Suffix string
+pkg vc, type StartTimeout struct
+pkg vc, type StartTimeout struct, embedded time.Duration
+pkg vc, type TypeDecoderKey struct
+pkg vc, type TypeEncoderKey struct
+pkg vc, type VC struct
diff --git a/profiles/internal/rpc/stream/vc/auth.go b/profiles/internal/rpc/stream/vc/auth.go
index b74a351..e19d10f 100644
--- a/profiles/internal/rpc/stream/vc/auth.go
+++ b/profiles/internal/rpc/stream/vc/auth.go
@@ -110,10 +110,8 @@
 	if err := enc.Encode(b); err != nil {
 		return verror.New(stream.ErrNetwork, nil, verror.New(errVomEncodeBlessing, nil, err))
 	}
-	if v >= version.RPCVersion5 {
-		if err := enc.Encode(discharges); err != nil {
-			return verror.New(stream.ErrNetwork, nil, verror.New(errVomEncodeBlessing, nil, err))
-		}
+	if err := enc.Encode(discharges); err != nil {
+		return verror.New(stream.ErrNetwork, nil, verror.New(errVomEncodeBlessing, nil, err))
 	}
 	msg, err := crypter.Encrypt(iobuf.NewSlice(buf.Bytes()))
 	if err != nil {
@@ -161,10 +159,8 @@
 		return noBlessings, nil, verror.New(stream.ErrNetwork, nil, err)
 	}
 	var discharges []security.Discharge
-	if v >= version.RPCVersion5 {
-		if err := dec.Decode(&discharges); err != nil {
-			return noBlessings, nil, verror.New(stream.ErrNetwork, nil, err)
-		}
+	if err := dec.Decode(&discharges); err != nil {
+		return noBlessings, nil, verror.New(stream.ErrNetwork, nil, err)
 	}
 	if !sig.Verify(blessings.PublicKey(), append(tag, crypter.ChannelBinding()...)) {
 		return noBlessings, nil, verror.New(stream.ErrSecurity, nil, verror.New(errInvalidSignatureInMessage, nil))
diff --git a/profiles/internal/rpc/stream/vif/.api b/profiles/internal/rpc/stream/vif/.api
new file mode 100644
index 0000000..4ad0c30
--- /dev/null
+++ b/profiles/internal/rpc/stream/vif/.api
@@ -0,0 +1,24 @@
+pkg vif, func AuthenticateAsClient(io.Writer, *iobuf.Reader, *version.Range, security.CallParams, *vc.ServerAuthorizer) (crypto.ControlCipher, error)
+pkg vif, func AuthenticateAsServer(io.Writer, *iobuf.Reader, *version.Range, security.Principal, security.Blessings, vc.DischargeClient) (crypto.ControlCipher, error)
+pkg vif, func InternalNewAcceptedVIF(net.Conn, naming.RoutingID, security.Principal, security.Blessings, *iversion.Range, func(*VIF), ...stream.ListenerOpt) (*VIF, error)
+pkg vif, func InternalNewDialedVIF(net.Conn, naming.RoutingID, security.Principal, *iversion.Range, func(*VIF), ...stream.VCOpt) (*VIF, error)
+pkg vif, func NewSet() *Set
+pkg vif, func SetFakeTimers() func()
+pkg vif, method (*Set) Delete(*VIF)
+pkg vif, method (*Set) Find(string, string) *VIF
+pkg vif, method (*Set) Insert(*VIF)
+pkg vif, method (*Set) List() []*VIF
+pkg vif, method (*VIF) Accept() (ConnectorAndFlow, error)
+pkg vif, method (*VIF) Close()
+pkg vif, method (*VIF) DebugString() string
+pkg vif, method (*VIF) Dial(naming.Endpoint, security.Principal, ...stream.VCOpt) (stream.VC, error)
+pkg vif, method (*VIF) NumVCs() int
+pkg vif, method (*VIF) ShutdownVCs(naming.Endpoint) int
+pkg vif, method (*VIF) StartAccepting(...stream.ListenerOpt) error
+pkg vif, method (*VIF) StopAccepting()
+pkg vif, method (*VIF) String() string
+pkg vif, type ConnectorAndFlow struct
+pkg vif, type ConnectorAndFlow struct, Connector stream.Connector
+pkg vif, type ConnectorAndFlow struct, Flow stream.Flow
+pkg vif, type Set struct
+pkg vif, type VIF struct
diff --git a/profiles/internal/rpc/stream/vif/auth.go b/profiles/internal/rpc/stream/vif/auth.go
index 4f7243a..65bec0b 100644
--- a/profiles/internal/rpc/stream/vif/auth.go
+++ b/profiles/internal/rpc/stream/vif/auth.go
@@ -44,20 +44,19 @@
 //
 // The sequence is initiated by the client.
 //
-//    - If the versions include RPCVersion6 or greater, the client sends a
-//      Setup message to the server, containing the client's supported
-//      versions, and the client's crypto options.  The Setup message
+//    - The client sends a Setup message to the server, containing the client's
+//      supported versions, and the client's crypto options.  The Setup message
 //      is sent in the clear.
 //
 //    - When the server receives the Setup message, it calls
 //      AuthenticateAsServer, which constructs a response Setup containing
 //      the server's version range, and any crypto options.
 //
-//    - For RPCVersion6 and RPCVersion7, the client and server generate fresh
-//      public/private key pairs, sending the public key to the peer as a crypto
-//      option.  The remainder of the communication is encrypted as
-//      SetupStream messages using NewControlCipherRPC6, which is based on
-//      code.google.com/p/go.crypto/nacl/box.
+//    - The client and server use the public/private key pairs
+//      generated for the Setup messages to create an encrypted stream
+//      of SetupStream messages for the remainder of the authentication
+//      setup.  The encyrption uses NewControlCipherRPC6, which is based
+//      on code.google.com/p/go.crypto/nacl/box.
 //
 //    - Once the encrypted SetupStream channel is setup, the client and
 //      server authenticate using the vc.AuthenticateAs{Client,Server} protocol.
@@ -66,36 +65,23 @@
 // modification by a man-in-the-middle, which can currently force a downgrade by
 // modifying the acceptable version ranges downward.  This can be addressed by
 // including a hash of the Setup message in the encrypted stream.  It is
-// likely that this will be addressed in subsequent protocol versions (or it may
-// not be addressed at all if RPCVersion6 becomes the only supported version).
+// likely that this will be addressed in subsequent protocol versions.
 func AuthenticateAsClient(writer io.Writer, reader *iobuf.Reader, versions *version.Range, params security.CallParams, auth *vc.ServerAuthorizer) (crypto.ControlCipher, error) {
 	if versions == nil {
 		versions = version.SupportedRange
 	}
-	if params.LocalPrincipal == nil {
-		// If there is no principal, we do not support encryption/authentication.
-		// TODO(ashankar, mattr): We should still exchange version information even
-		// if we don't do encryption.
-		var err error
-		versions, err = versions.Intersect(&version.Range{Min: 0, Max: rpcversion.RPCVersion5})
-		if err != nil {
-			return nil, verror.New(stream.ErrNetwork, nil, err)
-		}
-	}
-	if versions.Max < rpcversion.RPCVersion6 {
-		return nullCipher, nil
-	}
 
-	// The client has not yet sent its public data.  Construct it and send it.
-	pvt, pub, err := makeSetup(versions)
+	// Send the client's public data.
+	pvt, pub, err := makeSetup(versions, params.LocalPrincipal != nil)
 	if err != nil {
 		return nil, verror.New(stream.ErrSecurity, nil, err)
 	}
-	if err := message.WriteTo(writer, &pub, nullCipher); err != nil {
-		return nil, verror.New(stream.ErrNetwork, nil, err)
-	}
 
-	// Read the server's public data.
+	errch := make(chan error, 1)
+	go func() {
+		errch <- message.WriteTo(writer, pub, nullCipher)
+	}()
+
 	pmsg, err := message.ReadFrom(reader, nullCipher)
 	if err != nil {
 		return nil, verror.New(stream.ErrNetwork, nil, err)
@@ -105,25 +91,28 @@
 		return nil, verror.New(stream.ErrSecurity, nil, verror.New(errVersionNegotiationFailed, nil))
 	}
 
+	// Wait for the write to succeed.
+	if err := <-errch; err != nil {
+		return nil, verror.New(stream.ErrNetwork, nil, err)
+	}
+
 	// Choose the max version in the intersection.
 	vrange, err := pub.Versions.Intersect(&ppub.Versions)
 	if err != nil {
 		return nil, verror.New(stream.ErrNetwork, nil, err)
 	}
 	v := vrange.Max
-	if v < rpcversion.RPCVersion6 {
+
+	if params.LocalPrincipal == nil {
 		return nullCipher, nil
 	}
 
 	// Perform the authentication.
-	return authenticateAsClient(writer, reader, params, auth, &pvt, &pub, ppub, v)
+	return authenticateAsClient(writer, reader, params, auth, pvt, pub, ppub, v)
 }
 
 func authenticateAsClient(writer io.Writer, reader *iobuf.Reader, params security.CallParams, auth *vc.ServerAuthorizer,
 	pvt *privateData, pub, ppub *message.Setup, version rpcversion.RPCVersion) (crypto.ControlCipher, error) {
-	if version < rpcversion.RPCVersion6 {
-		return nil, verror.New(errUnsupportedEncryptVersion, nil, version, rpcversion.RPCVersion6)
-	}
 	pbox := ppub.NaclBox()
 	if pbox == nil {
 		return nil, verror.New(errNaclBoxVersionNegotiationFailed, nil)
@@ -143,51 +132,69 @@
 //
 // See AuthenticateAsClient for a description of the negotiation.
 func AuthenticateAsServer(writer io.Writer, reader *iobuf.Reader, versions *version.Range, principal security.Principal, lBlessings security.Blessings,
-	dc vc.DischargeClient, ppub *message.Setup) (crypto.ControlCipher, error) {
+	dc vc.DischargeClient) (crypto.ControlCipher, error) {
 	var err error
 	if versions == nil {
 		versions = version.SupportedRange
 	}
 
-	if principal == nil {
-		// If we're not encrypting the connection we can just send them
-		// our version information.
-		pub := &message.Setup{
-			Versions: *versions,
-		}
-		if err := message.WriteTo(writer, &pub, nullCipher); err != nil {
-			return nil, err
-		}
-		_, err := versions.Intersect(&ppub.Versions)
-		return nullCipher, err
+	// Send server's public data.
+	pvt, pub, err := makeSetup(versions, principal != nil)
+	if err != nil {
+		return nil, err
 	}
 
-	// Create our public data and send it to the client.
-	pvt, pub, err := makeSetup(versions)
+	errch := make(chan error, 1)
+	readch := make(chan struct{})
+	go func() {
+		// TODO(mattr,ribrdb): In the case of the agent, which is
+		// currently the only user of insecure connections, we need to
+		// wait for the client to initiate the communication.  The agent
+		// sends an extra first byte to clients, which clients read before
+		// dialing their side of the vif.  If we send this message before
+		// the magic byte has been sent the client will use the first
+		// byte of this message instead rendering the remainder of the
+		// stream uninterpretable.
+		if principal == nil {
+			<-readch
+		}
+		err := message.WriteTo(writer, pub, nullCipher)
+		errch <- err
+	}()
+
+	// Read client's public data.
+	pmsg, err := message.ReadFrom(reader, nullCipher)
+	close(readch) // Note: we need to close this whether we get an error or not.
 	if err != nil {
+		return nil, verror.New(stream.ErrNetwork, nil, err)
+	}
+	ppub, ok := pmsg.(*message.Setup)
+	if !ok {
+		return nil, verror.New(stream.ErrSecurity, nil, verror.New(errVersionNegotiationFailed, nil))
+	}
+
+	// Wait for the write to succeed.
+	if err := <-errch; err != nil {
 		return nil, err
 	}
-	if err := message.WriteTo(writer, &pub, nullCipher); err != nil {
-		return nil, err
-	}
+
+	// Choose the max version in the intersection.
 	vrange, err := versions.Intersect(&ppub.Versions)
 	if err != nil {
-		return nil, err
+		return nil, verror.New(stream.ErrNetwork, nil, err)
 	}
 	v := vrange.Max
-	if v < rpcversion.RPCVersion6 {
+
+	if principal == nil {
 		return nullCipher, nil
 	}
 
 	// Perform authentication.
-	return authenticateAsServerRPC6(writer, reader, principal, lBlessings, dc, &pvt, &pub, ppub, v)
+	return authenticateAsServerRPC6(writer, reader, principal, lBlessings, dc, pvt, pub, ppub, v)
 }
 
 func authenticateAsServerRPC6(writer io.Writer, reader *iobuf.Reader, principal security.Principal, lBlessings security.Blessings, dc vc.DischargeClient,
 	pvt *privateData, pub, ppub *message.Setup, version rpcversion.RPCVersion) (crypto.ControlCipher, error) {
-	if version < rpcversion.RPCVersion6 {
-		return nil, verror.New(errUnsupportedEncryptVersion, nil, version, rpcversion.RPCVersion6)
-	}
 	box := ppub.NaclBox()
 	if box == nil {
 		return nil, verror.New(errNaclBoxVersionNegotiationFailed, nil)
@@ -215,14 +222,24 @@
 }
 
 // makeSetup constructs the options that this process can support.
-func makeSetup(versions *version.Range) (pvt privateData, pub message.Setup, err error) {
-	pub.Versions = *versions
-	var pubKey, pvtKey *[32]byte
-	pubKey, pvtKey, err = box.GenerateKey(rand.Reader)
-	if err != nil {
-		return
+func makeSetup(versions *version.Range, secure bool) (*privateData, *message.Setup, error) {
+	var options []message.SetupOption
+	var pvt *privateData
+	if secure {
+		pubKey, pvtKey, err := box.GenerateKey(rand.Reader)
+		if err != nil {
+			return nil, nil, err
+		}
+		options = []message.SetupOption{&message.NaclBox{PublicKey: *pubKey}}
+		pvt = &privateData{
+			naclBoxPrivateKey: *pvtKey,
+		}
 	}
-	pub.Options = append(pub.Options, &message.NaclBox{PublicKey: *pubKey})
-	pvt.naclBoxPrivateKey = *pvtKey
-	return
+
+	pub := &message.Setup{
+		Versions: *versions,
+		Options:  options,
+	}
+
+	return pvt, pub, nil
 }
diff --git a/profiles/internal/rpc/stream/vif/vif.go b/profiles/internal/rpc/stream/vif/vif.go
index dd647ae..e6d0e14 100644
--- a/profiles/internal/rpc/stream/vif/vif.go
+++ b/profiles/internal/rpc/stream/vif/vif.go
@@ -80,8 +80,6 @@
 	reader  *iobuf.Reader
 	localEP naming.Endpoint
 
-	// control channel encryption.
-	isSetup bool
 	// ctrlCipher is normally guarded by writeMu, however see the exception in
 	// readLoop.
 	ctrlCipher crypto.ControlCipher
@@ -183,7 +181,7 @@
 	// server and not the remote endpoint of the VIF.
 	c, err := AuthenticateAsClient(conn, reader, versions, params, nil)
 	if err != nil {
-		return nil, err
+		return nil, verror.New(stream.ErrNetwork, ctx, err)
 	}
 	var blessings security.Blessings
 
@@ -214,6 +212,14 @@
 func InternalNewAcceptedVIF(conn net.Conn, rid naming.RoutingID, principal security.Principal, blessings security.Blessings, versions *iversion.Range, onClose func(*VIF), lopts ...stream.ListenerOpt) (*VIF, error) {
 	pool := iobuf.NewPool(0)
 	reader := iobuf.NewReader(pool, conn)
+
+	dischargeClient := getDischargeClient(lopts)
+
+	c, err := AuthenticateAsServer(conn, reader, versions, principal, blessings, dischargeClient)
+	if err != nil {
+		return nil, err
+	}
+
 	var startTimeout time.Duration
 	for _, o := range lopts {
 		switch v := o.(type) {
@@ -221,7 +227,7 @@
 			startTimeout = v.Duration
 		}
 	}
-	return internalNew(conn, pool, reader, rid, id.VC(vc.NumReservedVCs)+1, versions, principal, blessings, startTimeout, onClose, upcqueue.New(), lopts, &crypto.NullControlCipher{})
+	return internalNew(conn, pool, reader, rid, id.VC(vc.NumReservedVCs)+1, versions, principal, blessings, startTimeout, onClose, upcqueue.New(), lopts, c)
 }
 
 func internalNew(conn net.Conn, pool *iobuf.Pool, reader *iobuf.Reader, rid naming.RoutingID, initialVCI id.VC, versions *iversion.Range, principal security.Principal, blessings security.Blessings, startTimeout time.Duration, onClose func(*VIF), acceptor *upcqueue.T, listenerOpts []stream.ListenerOpt, c crypto.ControlCipher) (*VIF, error) {
@@ -526,6 +532,7 @@
 	vif.muMsgCounters.Unlock()
 
 	switch m := msg.(type) {
+
 	case *message.Data:
 		_, rq, _ := vif.vcMap.Find(m.VCI)
 		if rq == nil {
@@ -537,6 +544,7 @@
 			vlog.VI(2).Infof("Failed to put message(%v) on VC queue on VIF %v: %v", m, vif, err)
 			m.Release()
 		}
+
 	case *message.OpenVC:
 		vif.muListen.Lock()
 		closed := vif.acceptor == nil || vif.acceptor.IsClosed()
@@ -575,6 +583,7 @@
 			return nil
 		}
 		go vif.acceptFlowsLoop(vc, vc.HandshakeAcceptedVC(vers, vif.principal, vif.blessings, nil, lopts...))
+
 	case *message.SetupVC:
 		// First, find the public key we need out of the message.
 		var theirPK *crypto.BoxKey
@@ -675,8 +684,10 @@
 			return nil
 		}
 		vlog.VI(2).Infof("Ignoring CloseVC(%+v) for unrecognized VCI on VIF %s", m, vif)
+
 	case *message.AddReceiveBuffers:
 		vif.distributeCounters(m.Counters)
+
 	case *message.OpenFlow:
 		if vc, _, _ := vif.vcMap.Find(m.VCI); vc != nil {
 			if err := vc.AcceptFlow(m.Flow); err != nil {
@@ -690,24 +701,10 @@
 			return nil
 		}
 		vlog.VI(2).Infof("Ignoring OpenFlow(%+v) for unrecognized VCI on VIF %s", m, m, vif)
-	case *message.Setup:
-		// Configure the VIF.  This takes over the conn during negotiation.
-		if vif.isSetup {
-			return verror.New(stream.ErrNetwork, nil, verror.New(errVIFAlreadySetup, nil))
-		}
-		vif.muListen.Lock()
-		dischargeClient := getDischargeClient(vif.listenerOpts)
-		vif.muListen.Unlock()
 
-		vif.writeMu.Lock()
-		c, err := AuthenticateAsServer(vif.conn, vif.reader, vif.versions, vif.principal, vif.blessings, dischargeClient, m)
-		if err != nil {
-			vif.writeMu.Unlock()
-			return err
-		}
-		vif.ctrlCipher = c
-		vif.writeMu.Unlock()
-		vif.isSetup = true
+	case *message.Setup:
+		vlog.Infof("Ignoring redundant Setup message %T on VIF %s", m, vif)
+
 	default:
 		vlog.Infof("Ignoring unrecognized message %T on VIF %s", m, vif)
 	}
@@ -1099,7 +1096,7 @@
 	l := make([]string, 0, len(vcs)+1)
 
 	vif.muNextVCI.Lock() // Needed for vif.nextVCI
-	l = append(l, fmt.Sprintf("VIF:[%s] -- #VCs:%d NextVCI:%d ControlChannelEncryption:%v IsClosed:%v", vif, len(vcs), vif.nextVCI, vif.isSetup, vif.isClosed))
+	l = append(l, fmt.Sprintf("VIF:[%s] -- #VCs:%d NextVCI:%d ControlChannelEncryption:%v IsClosed:%v", vif, len(vcs), vif.nextVCI, vif.ctrlCipher != nullCipher, vif.isClosed))
 	vif.muNextVCI.Unlock()
 
 	for _, vc := range vcs {
diff --git a/profiles/internal/rpc/stream/vif/vif_test.go b/profiles/internal/rpc/stream/vif/vif_test.go
index e630edc..32ccc74 100644
--- a/profiles/internal/rpc/stream/vif/vif_test.go
+++ b/profiles/internal/rpc/stream/vif/vif_test.go
@@ -650,13 +650,9 @@
 		{&iversion.Range{2, 3}, &iversion.Range{3, 5}, &iversion.Range{3, 5}, false, false},
 		{&iversion.Range{2, 3}, &iversion.Range{3, 5}, unknown, false, false},
 
-		// No VIF error because the client does not initiate authentication.
-		{&iversion.Range{2, 3}, &iversion.Range{4, 5}, &iversion.Range{4, 5}, true, false},
-		{&iversion.Range{2, 3}, &iversion.Range{4, 5}, unknown, true, false},
-
-		// VIF error because the client asks for authentication, but the server
-		// doesn't understand it.
-		{&iversion.Range{6, 6}, &iversion.Range{2, 5}, unknown, true, true},
+		// VIF error since there are no versions in common.
+		{&iversion.Range{2, 3}, &iversion.Range{4, 5}, &iversion.Range{4, 5}, true, true},
+		{&iversion.Range{2, 3}, &iversion.Range{4, 5}, unknown, true, true},
 	}
 
 	for _, tc := range tests {
diff --git a/profiles/internal/rpc/stress/.api b/profiles/internal/rpc/stress/.api
new file mode 100644
index 0000000..116e5e1
--- /dev/null
+++ b/profiles/internal/rpc/stress/.api
@@ -0,0 +1,61 @@
+pkg stress, func StressClient(string) StressClientStub
+pkg stress, func StressServer(StressServerMethods) StressServerStub
+pkg stress, method (*StressSumStreamServerCallStub) Init(rpc.StreamServerCall)
+pkg stress, method (*StressSumStreamServerCallStub) RecvStream() interface {  Advance() bool; Value() SumArg; Err() error;}
+pkg stress, method (*StressSumStreamServerCallStub) SendStream() interface {  Send(item []byte) error;}
+pkg stress, type StressClientMethods interface { Echo, GetSumStats, Stop, Sum, SumStream }
+pkg stress, type StressClientMethods interface, Echo(*context.T, []byte, ...rpc.CallOpt) ([]byte, error)
+pkg stress, type StressClientMethods interface, GetSumStats(*context.T, ...rpc.CallOpt) (SumStats, error)
+pkg stress, type StressClientMethods interface, Stop(*context.T, ...rpc.CallOpt) error
+pkg stress, type StressClientMethods interface, Sum(*context.T, SumArg, ...rpc.CallOpt) ([]byte, error)
+pkg stress, type StressClientMethods interface, SumStream(*context.T, ...rpc.CallOpt) (StressSumStreamClientCall, error)
+pkg stress, type StressClientStub interface, Echo(*context.T, []byte, ...rpc.CallOpt) ([]byte, error)
+pkg stress, type StressClientStub interface, GetSumStats(*context.T, ...rpc.CallOpt) (SumStats, error)
+pkg stress, type StressClientStub interface, Stop(*context.T, ...rpc.CallOpt) error
+pkg stress, type StressClientStub interface, Sum(*context.T, SumArg, ...rpc.CallOpt) ([]byte, error)
+pkg stress, type StressClientStub interface, SumStream(*context.T, ...rpc.CallOpt) (StressSumStreamClientCall, error)
+pkg stress, type StressClientStub interface, unexported methods
+pkg stress, type StressServerMethods interface { Echo, GetSumStats, Stop, Sum, SumStream }
+pkg stress, type StressServerMethods interface, Echo(*context.T, rpc.ServerCall, []byte) ([]byte, error)
+pkg stress, type StressServerMethods interface, GetSumStats(*context.T, rpc.ServerCall) (SumStats, error)
+pkg stress, type StressServerMethods interface, Stop(*context.T, rpc.ServerCall) error
+pkg stress, type StressServerMethods interface, Sum(*context.T, rpc.ServerCall, SumArg) ([]byte, error)
+pkg stress, type StressServerMethods interface, SumStream(*context.T, StressSumStreamServerCall) error
+pkg stress, type StressServerStub interface { Describe__, Echo, GetSumStats, Stop, Sum, SumStream }
+pkg stress, type StressServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg stress, type StressServerStub interface, Echo(*context.T, rpc.ServerCall, []byte) ([]byte, error)
+pkg stress, type StressServerStub interface, GetSumStats(*context.T, rpc.ServerCall) (SumStats, error)
+pkg stress, type StressServerStub interface, Stop(*context.T, rpc.ServerCall) error
+pkg stress, type StressServerStub interface, Sum(*context.T, rpc.ServerCall, SumArg) ([]byte, error)
+pkg stress, type StressServerStub interface, SumStream(*context.T, *StressSumStreamServerCallStub) error
+pkg stress, type StressServerStubMethods interface { Echo, GetSumStats, Stop, Sum, SumStream }
+pkg stress, type StressServerStubMethods interface, Echo(*context.T, rpc.ServerCall, []byte) ([]byte, error)
+pkg stress, type StressServerStubMethods interface, GetSumStats(*context.T, rpc.ServerCall) (SumStats, error)
+pkg stress, type StressServerStubMethods interface, Stop(*context.T, rpc.ServerCall) error
+pkg stress, type StressServerStubMethods interface, Sum(*context.T, rpc.ServerCall, SumArg) ([]byte, error)
+pkg stress, type StressServerStubMethods interface, SumStream(*context.T, *StressSumStreamServerCallStub) error
+pkg stress, type StressSumStreamClientCall interface { Finish, RecvStream, SendStream }
+pkg stress, type StressSumStreamClientCall interface, Finish() error
+pkg stress, type StressSumStreamClientCall interface, RecvStream() interface {  Advance() bool;; Value() []byte;; Err() error;}
+pkg stress, type StressSumStreamClientCall interface, SendStream() interface {  Send(item SumArg) error;; Close() error;}
+pkg stress, type StressSumStreamClientStream interface { RecvStream, SendStream }
+pkg stress, type StressSumStreamClientStream interface, RecvStream() interface {  Advance() bool;; Value() []byte;; Err() error;}
+pkg stress, type StressSumStreamClientStream interface, SendStream() interface {  Send(item SumArg) error;; Close() error;}
+pkg stress, type StressSumStreamServerCall interface, RecvStream() interface {  Advance() bool;; Value() SumArg;; Err() error;}
+pkg stress, type StressSumStreamServerCall interface, SendStream() interface {  Send(item []byte) error;}
+pkg stress, type StressSumStreamServerCall interface, unexported methods
+pkg stress, type StressSumStreamServerCallStub struct
+pkg stress, type StressSumStreamServerCallStub struct, embedded rpc.StreamServerCall
+pkg stress, type StressSumStreamServerStream interface { RecvStream, SendStream }
+pkg stress, type StressSumStreamServerStream interface, RecvStream() interface {  Advance() bool;; Value() SumArg;; Err() error;}
+pkg stress, type StressSumStreamServerStream interface, SendStream() interface {  Send(item []byte) error;}
+pkg stress, type SumArg struct
+pkg stress, type SumArg struct, ABool bool
+pkg stress, type SumArg struct, AInt64 int64
+pkg stress, type SumArg struct, AListOfBytes []byte
+pkg stress, type SumStats struct
+pkg stress, type SumStats struct, BytesRecv uint64
+pkg stress, type SumStats struct, BytesSent uint64
+pkg stress, type SumStats struct, SumCount uint64
+pkg stress, type SumStats struct, SumStreamCount uint64
+pkg stress, var StressDesc rpc.InterfaceDesc
diff --git a/profiles/internal/rpc/stress/internal/.api b/profiles/internal/rpc/stress/internal/.api
new file mode 100644
index 0000000..68b8b56
--- /dev/null
+++ b/profiles/internal/rpc/stress/internal/.api
@@ -0,0 +1,4 @@
+pkg internal, func CallEcho(*context.T, string, int, time.Duration) uint64
+pkg internal, func CallSum(*context.T, string, int, *stress.SumStats)
+pkg internal, func CallSumStream(*context.T, string, int, int, *stress.SumStats)
+pkg internal, func StartServer(*context.T, rpc.ListenSpec) (rpc.Server, naming.Endpoint, <-chan struct{})
diff --git a/profiles/internal/rpc/stress/mtstress/.api b/profiles/internal/rpc/stress/mtstress/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/profiles/internal/rpc/stress/mtstress/.api
diff --git a/profiles/internal/rpc/stress/mtstress/doc.go b/profiles/internal/rpc/stress/mtstress/doc.go
index 06d4714..f23772f 100644
--- a/profiles/internal/rpc/stress/mtstress/doc.go
+++ b/profiles/internal/rpc/stress/mtstress/doc.go
@@ -13,13 +13,18 @@
    mount       Measure latency of the Mount RPC at a fixed request rate
    resolve     Measure latency of the Resolve RPC at a fixed request rate
    help        Display help for commands or topics
-Run "mtstress help [command]" for command usage.
 
 The global flags are:
- -alsologtostderr=true
-   log to standard error as well as files
  -duration=10s
    Duration for sending test traffic and measuring latency
+ -rate=1
+   Rate, in RPCs per second, to send to the test server
+ -reauthenticate=false
+   If true, establish a new authenticated connection for each RPC, simulating
+   load from a distinct process
+
+ -alsologtostderr=true
+   log to standard error as well as files
  -log_backtrace_at=:0
    when logging hits line file:N, emit a stack trace
  -log_dir=
@@ -28,11 +33,6 @@
    log to standard error instead of files
  -max_stack_buf_size=4292608
    max size in bytes of the buffer to use for logging stack traces
- -rate=1
-   Rate, in RPCs per second, to send to the test server
- -reauthenticate=false
-   If true, establish a new authenticated connection for each RPC, simulating
-   load from a distinct process
  -stderrthreshold=2
    logs at or above this threshold go to stderr
  -v=0
@@ -62,7 +62,7 @@
  -vmodule=
    comma-separated list of pattern=N settings for file-filtered logging
 
-Mtstress Mount
+Mtstress mount
 
 Repeatedly issues a Mount request (at --rate) and measures latency
 
@@ -74,7 +74,7 @@
 <ttl> specfies the time-to-live of the mount point. For example: 5s for 5
 seconds, 1m for 1 minute etc. Valid time units are "ms", "s", "m", "h".
 
-Mtstress Resolve
+Mtstress resolve
 
 Repeatedly issues a Resolve request (at --rate) to a name and measures latency
 
@@ -83,7 +83,7 @@
 
 <name> the object name to resolve
 
-Mtstress Help
+Mtstress help
 
 Help with no args displays the usage of the parent command.
 
@@ -91,11 +91,10 @@
 
 "help ..." recursively displays help for all commands and topics.
 
-The output is formatted to a target width in runes.  The target width is
-determined by checking the environment variable CMDLINE_WIDTH, falling back on
-the terminal width from the OS, falling back on 80 chars.  By setting
-CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0 the width is unlimited, and
-if x == 0 or is unset one of the fallbacks is used.
+Output is formatted to a target width in runes, determined by checking the
+CMDLINE_WIDTH environment variable, falling back on the terminal width, falling
+back on 80 chars.  By setting CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0
+the width is unlimited, and if x == 0 or is unset one of the fallbacks is used.
 
 Usage:
    mtstress help [flags] [command/topic ...]
@@ -103,7 +102,11 @@
 [command/topic ...] optionally identifies a specific sub-command or help topic.
 
 The mtstress help flags are:
- -style=default
-   The formatting style for help output, either "default" or "godoc".
+ -style=compact
+   The formatting style for help output:
+      compact - Good for compact cmdline output.
+      full    - Good for cmdline output, shows all global flags.
+      godoc   - Good for godoc processing.
+   Override the default by setting the CMDLINE_STYLE environment variable.
 */
 package main
diff --git a/profiles/internal/rpc/stress/mtstress/main.go b/profiles/internal/rpc/stress/mtstress/main.go
index f067e93..5c0a8b9 100644
--- a/profiles/internal/rpc/stress/mtstress/main.go
+++ b/profiles/internal/rpc/stress/mtstress/main.go
@@ -11,6 +11,7 @@
 	"flag"
 	"net"
 	"os"
+	"regexp"
 	"time"
 
 	"v.io/v23"
@@ -18,11 +19,14 @@
 	"v.io/v23/naming"
 	"v.io/v23/options"
 	"v.io/v23/verror"
-
 	"v.io/x/lib/cmdline"
 	_ "v.io/x/ref/profiles"
 )
 
+func init() {
+	cmdline.HideGlobalFlagsExcept(regexp.MustCompile(`^(rate)|(duration)|(reauthenticate)$`))
+}
+
 var (
 	gctx *context.T
 
diff --git a/profiles/internal/rpc/stress/stress/.api b/profiles/internal/rpc/stress/stress/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/profiles/internal/rpc/stress/stress/.api
diff --git a/profiles/internal/rpc/stress/stressd/.api b/profiles/internal/rpc/stress/stressd/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/profiles/internal/rpc/stress/stressd/.api
diff --git a/profiles/internal/rpc/test/.api b/profiles/internal/rpc/test/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/profiles/internal/rpc/test/.api
diff --git a/profiles/internal/rpc/test/proxy_test.go b/profiles/internal/rpc/test/proxy_test.go
index ab8c7e9..bd326f5 100644
--- a/profiles/internal/rpc/test/proxy_test.go
+++ b/profiles/internal/rpc/test/proxy_test.go
@@ -14,6 +14,8 @@
 	"testing"
 	"time"
 
+	"v.io/x/lib/vlog"
+
 	"v.io/v23"
 	"v.io/v23/context"
 	"v.io/v23/namespace"
@@ -52,15 +54,14 @@
 	defer shutdown()
 
 	expected := len(args)
-	listenSpec := v23.GetListenSpec(ctx)
-	protocol := listenSpec.Addrs[0].Protocol
-	addr := listenSpec.Addrs[0].Address
-	proxyShutdown, proxyEp, err := proxy.New(ctx, protocol, addr, "")
+
+	listenSpec := rpc.ListenSpec{Addrs: rpc.ListenAddrs{{"tcp", "127.0.0.1:0"}}}
+	proxyShutdown, proxyEp, err := proxy.New(ctx, listenSpec)
 	if err != nil {
+		fmt.Fprintf(stderr, "%s\n", verror.DebugString(err))
 		return err
 	}
 	defer proxyShutdown()
-
 	fmt.Fprintf(stdout, "PID=%d\n", os.Getpid())
 	if expected > 0 {
 		pub := publisher.New(ctx, v23.GetNamespace(ctx), time.Minute)
@@ -128,6 +129,7 @@
 	p.ReadLine()
 	h.name = p.ExpectVar("PROXY_NAME")
 	if len(h.name) == 0 {
+		h.proxy.Shutdown(os.Stderr, os.Stderr)
 		t.Fatalf("failed to get PROXY_NAME from proxyd")
 	}
 	return h.ns.Mount(ctx, "proxy", h.name, time.Hour)
@@ -150,14 +152,18 @@
 }
 
 func TestProxy(t *testing.T) {
-	proxyListenSpec := rpc.ListenSpec{Addrs: rpc.ListenAddrs{{"tcp", "127.0.0.1:0"}}}
-	proxyListenSpec.Proxy = "proxy"
+	proxyListenSpec := rpc.ListenSpec{
+		Addrs: rpc.ListenAddrs{{"tcp", "127.0.0.1:0"}},
+		Proxy: "proxy",
+	}
 	testProxy(t, proxyListenSpec)
 }
 
 func TestWSProxy(t *testing.T) {
-	proxyListenSpec := rpc.ListenSpec{Addrs: rpc.ListenAddrs{{"tcp", "127.0.0.1:0"}}}
-	proxyListenSpec.Proxy = "proxy"
+	proxyListenSpec := rpc.ListenSpec{
+		Addrs: rpc.ListenAddrs{{"tcp", "127.0.0.1:0"}},
+		Proxy: "proxy",
+	}
 	// The proxy uses websockets only, but the server is using tcp.
 	testProxy(t, proxyListenSpec, "--v23.tcp.protocol=ws")
 }
@@ -165,6 +171,7 @@
 func testProxy(t *testing.T, spec rpc.ListenSpec, args ...string) {
 	ctx, shutdown := testContext()
 	defer shutdown()
+
 	var (
 		pserver   = testutil.NewPrincipal("server")
 		pclient   = testutil.NewPrincipal("client")
@@ -237,12 +244,18 @@
 		then := time.Now().Add(time.Minute)
 		for {
 			me, err := ns.Resolve(ctx, name)
+			if err != nil {
+				continue
+			}
+			for i, s := range me.Servers {
+				vlog.Infof("%d: %s", i, s)
+			}
 			if err == nil && len(me.Servers) == expect {
 				ch <- 1
 				return
 			}
 			if time.Now().After(then) {
-				t.Fatalf("timed out")
+				t.Fatalf("timed out waiting for %d servers, found %d", expect, len(me.Servers))
 			}
 			time.Sleep(100 * time.Millisecond)
 		}
diff --git a/profiles/internal/rpc/version/.api b/profiles/internal/rpc/version/.api
new file mode 100644
index 0000000..72b65cf
--- /dev/null
+++ b/profiles/internal/rpc/version/.api
@@ -0,0 +1,17 @@
+pkg version, func IsVersionError(error) bool
+pkg version, method (*Range) CheckCompatibility(naming.Endpoint) error
+pkg version, method (*Range) CommonVersion(naming.Endpoint, naming.Endpoint) (version.RPCVersion, error)
+pkg version, method (*Range) Endpoint(string, string, naming.RoutingID) *inaming.Endpoint
+pkg version, method (*Range) Intersect(*Range) (*Range, error)
+pkg version, method (*Range) ProxiedEndpoint(naming.RoutingID, naming.Endpoint) (*inaming.Endpoint, error)
+pkg version, type Range struct
+pkg version, type Range struct, Max version.RPCVersion
+pkg version, type Range struct, Min version.RPCVersion
+pkg version, var CheckCompatibility unknown-type
+pkg version, var CommonVersion unknown-type
+pkg version, var Endpoint unknown-type
+pkg version, var ErrDeprecatedVersion verror.IDAction
+pkg version, var ErrNoCompatibleVersion verror.IDAction
+pkg version, var ErrUnknownVersion verror.IDAction
+pkg version, var ProxiedEndpoint unknown-type
+pkg version, var SupportedRange *Range
diff --git a/profiles/internal/rpc/version/version.go b/profiles/internal/rpc/version/version.go
index 63be60b..157ed01 100644
--- a/profiles/internal/rpc/version/version.go
+++ b/profiles/internal/rpc/version/version.go
@@ -26,7 +26,7 @@
 	// change that's not both forward and backward compatible.
 	// Min should be incremented whenever we want to remove
 	// support for old protocol versions.
-	SupportedRange = &Range{Min: version.RPCVersion5, Max: version.RPCVersion9}
+	SupportedRange = &Range{Min: version.RPCVersion6, Max: version.RPCVersion9}
 
 	// Export the methods on supportedRange.
 	Endpoint           = SupportedRange.Endpoint
diff --git a/profiles/internal/rt/.api b/profiles/internal/rt/.api
new file mode 100644
index 0000000..95dd3dd
--- /dev/null
+++ b/profiles/internal/rt/.api
@@ -0,0 +1,18 @@
+pkg rt, func Init(*context.T, v23.AppCycle, []string, *rpc.ListenSpec, flags.RuntimeFlags, rpc.Dispatcher) (*Runtime, *context.T, v23.Shutdown, error)
+pkg rt, method (*Runtime) GetAppCycle(*context.T) v23.AppCycle
+pkg rt, method (*Runtime) GetBackgroundContext(*context.T) *context.T
+pkg rt, method (*Runtime) GetClient(*context.T) rpc.Client
+pkg rt, method (*Runtime) GetListenSpec(*context.T) rpc.ListenSpec
+pkg rt, method (*Runtime) GetNamespace(*context.T) namespace.T
+pkg rt, method (*Runtime) GetPrincipal(*context.T) security.Principal
+pkg rt, method (*Runtime) GetReservedNameDispatcher(*context.T) rpc.Dispatcher
+pkg rt, method (*Runtime) Init(*context.T) error
+pkg rt, method (*Runtime) NewEndpoint(string) (naming.Endpoint, error)
+pkg rt, method (*Runtime) NewServer(*context.T, ...rpc.ServerOpt) (rpc.Server, error)
+pkg rt, method (*Runtime) WithBackgroundContext(*context.T) *context.T
+pkg rt, method (*Runtime) WithNewClient(*context.T, ...rpc.ClientOpt) (*context.T, rpc.Client, error)
+pkg rt, method (*Runtime) WithNewNamespace(*context.T, ...string) (*context.T, namespace.T, error)
+pkg rt, method (*Runtime) WithNewStreamManager(*context.T) (*context.T, error)
+pkg rt, method (*Runtime) WithPrincipal(*context.T, security.Principal) (*context.T, error)
+pkg rt, method (*Runtime) WithReservedNameDispatcher(*context.T, rpc.Dispatcher) *context.T
+pkg rt, type Runtime struct
diff --git a/profiles/internal/testing/concurrency/.api b/profiles/internal/testing/concurrency/.api
new file mode 100644
index 0000000..8e36ffb
--- /dev/null
+++ b/profiles/internal/testing/concurrency/.api
@@ -0,0 +1,25 @@
+pkg concurrency, func Exit()
+pkg concurrency, func Finish()
+pkg concurrency, func Init(func(), func(), func()) *Tester
+pkg concurrency, func Start(func())
+pkg concurrency, func T() *Tester
+pkg concurrency, func TIDGenerator() func() TID
+pkg concurrency, method (*Tester) Explore() (int, error)
+pkg concurrency, method (*Tester) ExploreFor(time.Duration) (int, error)
+pkg concurrency, method (*Tester) ExploreN(int) (int, error)
+pkg concurrency, method (*Tester) MutexLock(*sync.Mutex)
+pkg concurrency, method (*Tester) MutexUnlock(*sync.Mutex)
+pkg concurrency, method (*Tester) RWMutexLock(*sync.RWMutex)
+pkg concurrency, method (*Tester) RWMutexRLock(*sync.RWMutex)
+pkg concurrency, method (*Tester) RWMutexRUnlock(*sync.RWMutex)
+pkg concurrency, method (*Tester) RWMutexUnlock(*sync.RWMutex)
+pkg concurrency, method (IncreasingDepth) Len() int
+pkg concurrency, method (IncreasingDepth) Less(int, int) bool
+pkg concurrency, method (IncreasingDepth) Swap(int, int)
+pkg concurrency, method (IncreasingTID) Len() int
+pkg concurrency, method (IncreasingTID) Less(int, int) bool
+pkg concurrency, method (IncreasingTID) Swap(int, int)
+pkg concurrency, type IncreasingDepth []*state
+pkg concurrency, type IncreasingTID []TID
+pkg concurrency, type TID int
+pkg concurrency, type Tester struct
diff --git a/profiles/internal/testing/concurrency/sync/.api b/profiles/internal/testing/concurrency/sync/.api
new file mode 100644
index 0000000..60e9cb2
--- /dev/null
+++ b/profiles/internal/testing/concurrency/sync/.api
@@ -0,0 +1,9 @@
+pkg sync, method (*Mutex) Lock()
+pkg sync, method (*Mutex) Unlock()
+pkg sync, method (*RWMutex) Lock()
+pkg sync, method (*RWMutex) RLock()
+pkg sync, method (*RWMutex) RLocker() sync.Locker
+pkg sync, method (*RWMutex) RUnlock()
+pkg sync, method (*RWMutex) Unlock()
+pkg sync, type Mutex struct
+pkg sync, type RWMutex struct
diff --git a/profiles/internal/testing/mocks/mocknet/.api b/profiles/internal/testing/mocks/mocknet/.api
new file mode 100644
index 0000000..b66e8d0
--- /dev/null
+++ b/profiles/internal/testing/mocks/mocknet/.api
@@ -0,0 +1,17 @@
+pkg mocknet, const Close Mode
+pkg mocknet, const Drop Mode
+pkg mocknet, const Trace Mode
+pkg mocknet, const V23CloseAtMessage Mode
+pkg mocknet, func DialerWithOpts(Opts, string, string, time.Duration) (net.Conn, error)
+pkg mocknet, func ListenerWithOpts(Opts, string, string) (net.Listener, error)
+pkg mocknet, func RewriteEndpointProtocol(string, string) (naming.Endpoint, error)
+pkg mocknet, type Mode int
+pkg mocknet, type Opts struct
+pkg mocknet, type Opts struct, Mode Mode
+pkg mocknet, type Opts struct, Rx chan int
+pkg mocknet, type Opts struct, RxCloseAt int
+pkg mocknet, type Opts struct, Tx chan int
+pkg mocknet, type Opts struct, TxCloseAt int
+pkg mocknet, type Opts struct, TxDropAfter func() int
+pkg mocknet, type Opts struct, UnderlyingProtocol string
+pkg mocknet, type Opts struct, V23MessageMatcher func(bool, message.T) bool
diff --git a/profiles/internal/testing/mocks/naming/.api b/profiles/internal/testing/mocks/naming/.api
new file mode 100644
index 0000000..96a3fb6
--- /dev/null
+++ b/profiles/internal/testing/mocks/naming/.api
@@ -0,0 +1 @@
+pkg naming, func NewSimpleNamespace() namespace.T
diff --git a/profiles/internal/util.go b/profiles/internal/util.go
index 600ff0a..a530087 100644
--- a/profiles/internal/util.go
+++ b/profiles/internal/util.go
@@ -6,10 +6,10 @@
 
 import (
 	"fmt"
+	"net"
 	"os"
 	"strings"
 
-	"v.io/v23/rpc"
 	"v.io/v23/verror"
 	"v.io/x/lib/vlog"
 
@@ -46,11 +46,11 @@
 // IPAddressChooser returns the preferred IP address, which is,
 // a public IPv4 address, then any non-loopback IPv4, then a public
 // IPv6 address and finally any non-loopback/link-local IPv6
-func IPAddressChooser(network string, addrs []rpc.Address) ([]rpc.Address, error) {
+func IPAddressChooser(network string, addrs []net.Addr) ([]net.Addr, error) {
 	if !netstate.IsIPProtocol(network) {
 		return nil, fmt.Errorf("can't support network protocol %q", network)
 	}
-	accessible := netstate.AddrList(addrs)
+	accessible := netstate.ConvertToAddresses(addrs)
 
 	// Try and find an address on a interface with a default route.
 	// We give preference to IPv4 over IPv6 for compatibility for now.
@@ -65,7 +65,7 @@
 		if addrs := accessible.Filter(predicate); len(addrs) > 0 {
 			onDefaultRoutes := addrs.Filter(netstate.IsOnDefaultRoute)
 			if len(onDefaultRoutes) > 0 {
-				return onDefaultRoutes, nil
+				return onDefaultRoutes.AsNetAddrs(), nil
 			}
 		}
 	}
@@ -74,11 +74,10 @@
 	// but without the default route requirement.
 	for _, predicate := range predicates {
 		if addrs := accessible.Filter(predicate); len(addrs) > 0 {
-			return addrs, nil
+			return addrs.AsNetAddrs(), nil
 		}
 	}
-
-	return nil, fmt.Errorf("failed to find any usable address for %q", network)
+	return []net.Addr{}, nil
 }
 
 // HasPublicIP returns true if the host has at least one public IP address.
diff --git a/profiles/internal/vtrace/.api b/profiles/internal/vtrace/.api
new file mode 100644
index 0000000..b3da14f
--- /dev/null
+++ b/profiles/internal/vtrace/.api
@@ -0,0 +1,7 @@
+pkg vtrace, func Init(*context.T, flags.VtraceFlags) (*context.T, error)
+pkg vtrace, func NewStore(flags.VtraceFlags) (*Store, error)
+pkg vtrace, method (*Store) ForceCollect(uniqueid.Id)
+pkg vtrace, method (*Store) Merge(vtrace.Response)
+pkg vtrace, method (*Store) TraceRecord(uniqueid.Id) *vtrace.TraceRecord
+pkg vtrace, method (*Store) TraceRecords() []vtrace.TraceRecord
+pkg vtrace, type Store struct
diff --git a/profiles/proxy.go b/profiles/proxy.go
index 3392743..0a12b4e 100644
--- a/profiles/proxy.go
+++ b/profiles/proxy.go
@@ -7,12 +7,13 @@
 import (
 	"v.io/v23/context"
 	"v.io/v23/naming"
+	"v.io/v23/rpc"
 
 	"v.io/x/ref/profiles/internal/rpc/stream/proxy"
 )
 
 // NewProxy creates a new Proxy that listens for network connections on the provided
 // (network, address) pair and routes VC traffic between accepted connections.
-func NewProxy(ctx *context.T, network, address, pubAddress string, names ...string) (shutdown func(), endpoint naming.Endpoint, err error) {
-	return proxy.New(ctx, network, address, pubAddress, names...)
+func NewProxy(ctx *context.T, spec rpc.ListenSpec, names ...string) (shutdown func(), endpoint naming.Endpoint, err error) {
+	return proxy.New(ctx, spec, names...)
 }
diff --git a/profiles/roaming/.api b/profiles/roaming/.api
new file mode 100644
index 0000000..df44272
--- /dev/null
+++ b/profiles/roaming/.api
@@ -0,0 +1,3 @@
+pkg roaming, const SettingsStreamName ideal-string
+pkg roaming, func Init(*context.T) (v23.Runtime, *context.T, v23.Shutdown, error)
+pkg roaming, func NewProxy(*context.T, string, string, string, ...string) (func(), naming.Endpoint, error)
diff --git a/profiles/roaming/net_watcher.go b/profiles/roaming/net_watcher.go
index 579fafb..f4880d4 100644
--- a/profiles/roaming/net_watcher.go
+++ b/profiles/roaming/net_watcher.go
@@ -8,12 +8,14 @@
 
 import (
 	"fmt"
+	"os"
 	"strings"
 
+	"v.io/x/lib/netstate"
+
 	"v.io/v23"
 	"v.io/v23/config"
 
-	"v.io/x/lib/netstate"
 	"v.io/x/ref/profiles/roaming"
 )
 
@@ -25,8 +27,26 @@
 	fmt.Println("Profile: ", profileName)
 
 	accessible, err := netstate.GetAccessibleIPs()
-	routes := netstate.GetRoutes()
-	fmt.Printf("Routes:\n%s\n", strings.Replace(routes.String(), ")", ")\n", -1))
+	interfaces, err := netstate.GetAllInterfaces()
+
+	fmt.Printf("Addresses\n")
+	for _, addr := range accessible {
+		fmt.Printf("%s\n", addr.DebugString())
+	}
+
+	fmt.Printf("\nInterfaces\n")
+	for _, ifc := range interfaces {
+		fmt.Printf("%s\n", ifc)
+	}
+
+	fmt.Printf("\nRoutes\n")
+	for _, ifc := range interfaces {
+		if ipifc, ok := ifc.(netstate.IPNetworkInterface); ok {
+			if routes := ipifc.IPRoutes(); len(routes) > 0 {
+				fmt.Printf("%s: %s\n", ifc.Name(), routes)
+			}
+		}
+	}
 
 	listenSpec := v23.GetListenSpec(ctx)
 	chooser := listenSpec.AddressChooser
@@ -36,17 +56,17 @@
 		}
 	}
 
-	if chosen, err := listenSpec.AddressChooser("tcp", accessible); err != nil {
+	if chosen, err := listenSpec.AddressChooser("tcp", accessible.AsNetAddrs()); err != nil {
 		fmt.Printf("Failed to chosen address %s\n", err)
 	} else {
-		al := netstate.AddrList(chosen)
+		al := netstate.ConvertToAddresses(chosen)
 		fmt.Printf("Chosen:\n%s\n", strings.Replace(al.String(), ") ", ")\n", -1))
 	}
 
 	ch := make(chan config.Setting, 10)
-	settings, err := v23.GetPublisher(ctx).ForkStream(roaming.SettingsStreamName, ch)
+	settings, err := listenSpec.StreamPublisher.ForkStream(roaming.SettingsStreamName, ch)
 	if err != nil {
-		r.Logger().Infof("failed to fork stream: %s", err)
+		fmt.Fprintf(os.Stderr, "failed to fork stream: %s\n", err)
 	}
 	for _, setting := range settings.Latest {
 		fmt.Println("Setting: ", setting)
diff --git a/profiles/roaming/proxy.go b/profiles/roaming/proxy.go
index ed9a6b6..845ad11 100644
--- a/profiles/roaming/proxy.go
+++ b/profiles/roaming/proxy.go
@@ -7,12 +7,13 @@
 import (
 	"v.io/v23/context"
 	"v.io/v23/naming"
+	"v.io/v23/rpc"
 
 	"v.io/x/ref/profiles/internal/rpc/stream/proxy"
 )
 
 // NewProxy creates a new Proxy that listens for network connections on the provided
 // (network, address) pair and routes VC traffic between accepted connections.
-func NewProxy(ctx *context.T, network, address, pubAddress string, names ...string) (shutdown func(), endpoint naming.Endpoint, err error) {
-	return proxy.New(ctx, network, address, pubAddress, names...)
+func NewProxy(ctx *context.T, spec rpc.ListenSpec, names ...string) (shutdown func(), endpoint naming.Endpoint, err error) {
+	return proxy.New(ctx, spec, names...)
 }
diff --git a/profiles/roaming/roaminginit.go b/profiles/roaming/roaminginit.go
index f09f1c6..4996320 100644
--- a/profiles/roaming/roaminginit.go
+++ b/profiles/roaming/roaminginit.go
@@ -15,14 +15,17 @@
 
 import (
 	"flag"
+	"net"
+
+	"v.io/x/lib/netconfig"
+	"v.io/x/lib/netstate"
+	"v.io/x/lib/vlog"
 
 	"v.io/v23"
 	"v.io/v23/config"
 	"v.io/v23/context"
 	"v.io/v23/rpc"
-	"v.io/x/lib/netconfig"
-	"v.io/x/lib/netstate"
-	"v.io/x/lib/vlog"
+
 	"v.io/x/ref/lib/flags"
 	"v.io/x/ref/lib/security/securityflag"
 	"v.io/x/ref/profiles/internal"
@@ -65,8 +68,11 @@
 	// 1:1 NAT configuration.
 	if !internal.HasPublicIP(vlog.Log) {
 		if addr := internal.GCEPublicAddress(vlog.Log); addr != nil {
-			listenSpec.AddressChooser = func(string, []rpc.Address) ([]rpc.Address, error) {
-				return []rpc.Address{&netstate.AddrIfc{addr, "nat", nil}}, nil
+			listenSpec.AddressChooser = func(string, []net.Addr) ([]net.Addr, error) {
+				// TODO(cnicolaou): the protocol at least should
+				// be configurable, or maybe there's a profile specific
+				// flag to configure both the protocol and address.
+				return []net.Addr{netstate.NewNetAddr("wsh", addr.String())}, nil
 			}
 			runtime, ctx, shutdown, err := rt.Init(ctx, ac, nil, &listenSpec, commonFlags.RuntimeFlags(), reservedDispatcher)
 			if err != nil {
@@ -146,6 +152,7 @@
 	for {
 		select {
 		case <-watcher.Channel():
+			netstate.InvalidateCache()
 			cur, err := netstate.GetAccessibleIPs()
 			if err != nil {
 				vlog.Errorf("failed to read network state: %s", err)
@@ -163,10 +170,10 @@
 			}
 			if len(removed) > 0 {
 				vlog.VI(2).Infof("Sending removed: %s", removed)
-				ch <- rpc.NewRmAddrsSetting(removed)
+				ch <- rpc.NewRmAddrsSetting(removed.AsNetAddrs())
 			}
 			// We will always send the best currently available address
-			if chosen, err := listenSpec.AddressChooser(listenSpec.Addrs[0].Protocol, cur); err == nil && chosen != nil {
+			if chosen, err := listenSpec.AddressChooser(listenSpec.Addrs[0].Protocol, cur.AsNetAddrs()); err == nil && chosen != nil {
 				vlog.VI(2).Infof("Sending added and chosen: %s", chosen)
 				ch <- rpc.NewAddAddrsSetting(chosen)
 			} else {
diff --git a/profiles/static/.api b/profiles/static/.api
new file mode 100644
index 0000000..c644a81
--- /dev/null
+++ b/profiles/static/.api
@@ -0,0 +1,2 @@
+pkg static, func Init(*context.T) (v23.Runtime, *context.T, v23.Shutdown, error)
+pkg static, func NewProxy(*context.T, string, string, string, ...string) (func(), naming.Endpoint, error)
diff --git a/profiles/static/proxy.go b/profiles/static/proxy.go
index e2617e0..a398460 100644
--- a/profiles/static/proxy.go
+++ b/profiles/static/proxy.go
@@ -7,12 +7,13 @@
 import (
 	"v.io/v23/context"
 	"v.io/v23/naming"
+	"v.io/v23/rpc"
 
 	"v.io/x/ref/profiles/internal/rpc/stream/proxy"
 )
 
 // NewProxy creates a new Proxy that listens for network connections on the provided
 // (network, address) pair and routes VC traffic between accepted connections.
-func NewProxy(ctx *context.T, network, address, pubAddress string, names ...string) (shutdown func(), endpoint naming.Endpoint, err error) {
-	return proxy.New(ctx, network, address, pubAddress, names...)
+func NewProxy(ctx *context.T, spec rpc.ListenSpec, names ...string) (shutdown func(), endpoint naming.Endpoint, err error) {
+	return proxy.New(ctx, spec, names...)
 }
diff --git a/profiles/static/staticinit.go b/profiles/static/staticinit.go
index 1908308..339e32a 100644
--- a/profiles/static/staticinit.go
+++ b/profiles/static/staticinit.go
@@ -7,12 +7,14 @@
 
 import (
 	"flag"
+	"net"
+
+	"v.io/x/lib/vlog"
 
 	"v.io/v23"
 	"v.io/v23/context"
 	"v.io/v23/rpc"
-	"v.io/x/lib/netstate"
-	"v.io/x/lib/vlog"
+
 	"v.io/x/ref/lib/flags"
 	"v.io/x/ref/lib/security/securityflag"
 	"v.io/x/ref/profiles/internal"
@@ -48,11 +50,12 @@
 	ac := appcycle.New()
 
 	// Our address is private, so we test for running on GCE and for its 1:1 NAT
-	// configuration. GCEPublicAddress returns a non-nil addr if we are running on GCE.
+	// configuration. GCEPublicAddress returns a non-nil addr if we are
+	// running on GCE.
 	if !internal.HasPublicIP(vlog.Log) {
 		if addr := internal.GCEPublicAddress(vlog.Log); addr != nil {
-			listenSpec.AddressChooser = func(string, []rpc.Address) ([]rpc.Address, error) {
-				return []rpc.Address{&netstate.AddrIfc{addr, "nat", nil}}, nil
+			listenSpec.AddressChooser = func(string, []net.Addr) ([]net.Addr, error) {
+				return []net.Addr{addr}, nil
 			}
 			runtime, ctx, shutdown, err := rt.Init(ctx, ac, nil, &listenSpec, commonFlags.RuntimeFlags(), reservedDispatcher)
 			if err != nil {
diff --git a/services/agent/.api b/services/agent/.api
new file mode 100644
index 0000000..7b709f1
--- /dev/null
+++ b/services/agent/.api
@@ -0,0 +1,112 @@
+pkg agent, func AgentClient(string) AgentClientStub
+pkg agent, func AgentServer(AgentServerMethods) AgentServerStub
+pkg agent, method (*AgentNotifyWhenChangedServerCallStub) Init(rpc.StreamServerCall)
+pkg agent, method (*AgentNotifyWhenChangedServerCallStub) SendStream() interface {  Send(item bool) error;}
+pkg agent, type AgentClientMethods interface { AddToRoots, Bless, BlessSelf, BlessingRootsAdd, BlessingRootsDebugString, BlessingRootsRecognized, BlessingStoreDebugString, BlessingStoreDefault, BlessingStoreForPeer, BlessingStorePeerBlessings, BlessingStoreSet, BlessingStoreSetDefault, BlessingsByName, BlessingsInfo, MintDischarge, NotifyWhenChanged, PublicKey, Sign }
+pkg agent, type AgentClientMethods interface, AddToRoots(*context.T, security.Blessings, ...rpc.CallOpt) error
+pkg agent, type AgentClientMethods interface, Bless(*context.T, []byte, security.Blessings, string, security.Caveat, []security.Caveat, ...rpc.CallOpt) (security.Blessings, error)
+pkg agent, type AgentClientMethods interface, BlessSelf(*context.T, string, []security.Caveat, ...rpc.CallOpt) (security.Blessings, error)
+pkg agent, type AgentClientMethods interface, BlessingRootsAdd(*context.T, []byte, security.BlessingPattern, ...rpc.CallOpt) error
+pkg agent, type AgentClientMethods interface, BlessingRootsDebugString(*context.T, ...rpc.CallOpt) (string, error)
+pkg agent, type AgentClientMethods interface, BlessingRootsRecognized(*context.T, []byte, string, ...rpc.CallOpt) error
+pkg agent, type AgentClientMethods interface, BlessingStoreDebugString(*context.T, ...rpc.CallOpt) (string, error)
+pkg agent, type AgentClientMethods interface, BlessingStoreDefault(*context.T, ...rpc.CallOpt) (security.Blessings, error)
+pkg agent, type AgentClientMethods interface, BlessingStoreForPeer(*context.T, []string, ...rpc.CallOpt) (security.Blessings, error)
+pkg agent, type AgentClientMethods interface, BlessingStorePeerBlessings(*context.T, ...rpc.CallOpt) (map[security.BlessingPattern]security.Blessings, error)
+pkg agent, type AgentClientMethods interface, BlessingStoreSet(*context.T, security.Blessings, security.BlessingPattern, ...rpc.CallOpt) (security.Blessings, error)
+pkg agent, type AgentClientMethods interface, BlessingStoreSetDefault(*context.T, security.Blessings, ...rpc.CallOpt) error
+pkg agent, type AgentClientMethods interface, BlessingsByName(*context.T, security.BlessingPattern, ...rpc.CallOpt) ([]security.Blessings, error)
+pkg agent, type AgentClientMethods interface, BlessingsInfo(*context.T, security.Blessings, ...rpc.CallOpt) (map[string][]security.Caveat, error)
+pkg agent, type AgentClientMethods interface, MintDischarge(*context.T, security.Caveat, security.Caveat, []security.Caveat, ...rpc.CallOpt) (security.Discharge, error)
+pkg agent, type AgentClientMethods interface, NotifyWhenChanged(*context.T, ...rpc.CallOpt) (AgentNotifyWhenChangedClientCall, error)
+pkg agent, type AgentClientMethods interface, PublicKey(*context.T, ...rpc.CallOpt) ([]byte, error)
+pkg agent, type AgentClientMethods interface, Sign(*context.T, []byte, ...rpc.CallOpt) (security.Signature, error)
+pkg agent, type AgentClientStub interface, AddToRoots(*context.T, security.Blessings, ...rpc.CallOpt) error
+pkg agent, type AgentClientStub interface, Bless(*context.T, []byte, security.Blessings, string, security.Caveat, []security.Caveat, ...rpc.CallOpt) (security.Blessings, error)
+pkg agent, type AgentClientStub interface, BlessSelf(*context.T, string, []security.Caveat, ...rpc.CallOpt) (security.Blessings, error)
+pkg agent, type AgentClientStub interface, BlessingRootsAdd(*context.T, []byte, security.BlessingPattern, ...rpc.CallOpt) error
+pkg agent, type AgentClientStub interface, BlessingRootsDebugString(*context.T, ...rpc.CallOpt) (string, error)
+pkg agent, type AgentClientStub interface, BlessingRootsRecognized(*context.T, []byte, string, ...rpc.CallOpt) error
+pkg agent, type AgentClientStub interface, BlessingStoreDebugString(*context.T, ...rpc.CallOpt) (string, error)
+pkg agent, type AgentClientStub interface, BlessingStoreDefault(*context.T, ...rpc.CallOpt) (security.Blessings, error)
+pkg agent, type AgentClientStub interface, BlessingStoreForPeer(*context.T, []string, ...rpc.CallOpt) (security.Blessings, error)
+pkg agent, type AgentClientStub interface, BlessingStorePeerBlessings(*context.T, ...rpc.CallOpt) (map[security.BlessingPattern]security.Blessings, error)
+pkg agent, type AgentClientStub interface, BlessingStoreSet(*context.T, security.Blessings, security.BlessingPattern, ...rpc.CallOpt) (security.Blessings, error)
+pkg agent, type AgentClientStub interface, BlessingStoreSetDefault(*context.T, security.Blessings, ...rpc.CallOpt) error
+pkg agent, type AgentClientStub interface, BlessingsByName(*context.T, security.BlessingPattern, ...rpc.CallOpt) ([]security.Blessings, error)
+pkg agent, type AgentClientStub interface, BlessingsInfo(*context.T, security.Blessings, ...rpc.CallOpt) (map[string][]security.Caveat, error)
+pkg agent, type AgentClientStub interface, MintDischarge(*context.T, security.Caveat, security.Caveat, []security.Caveat, ...rpc.CallOpt) (security.Discharge, error)
+pkg agent, type AgentClientStub interface, NotifyWhenChanged(*context.T, ...rpc.CallOpt) (AgentNotifyWhenChangedClientCall, error)
+pkg agent, type AgentClientStub interface, PublicKey(*context.T, ...rpc.CallOpt) ([]byte, error)
+pkg agent, type AgentClientStub interface, Sign(*context.T, []byte, ...rpc.CallOpt) (security.Signature, error)
+pkg agent, type AgentClientStub interface, unexported methods
+pkg agent, type AgentNotifyWhenChangedClientCall interface { Finish, RecvStream }
+pkg agent, type AgentNotifyWhenChangedClientCall interface, Finish() error
+pkg agent, type AgentNotifyWhenChangedClientCall interface, RecvStream() interface {  Advance() bool;; Value() bool;; Err() error;}
+pkg agent, type AgentNotifyWhenChangedClientStream interface { RecvStream }
+pkg agent, type AgentNotifyWhenChangedClientStream interface, RecvStream() interface {  Advance() bool;; Value() bool;; Err() error;}
+pkg agent, type AgentNotifyWhenChangedServerCall interface, SendStream() interface {  Send(item bool) error;}
+pkg agent, type AgentNotifyWhenChangedServerCall interface, unexported methods
+pkg agent, type AgentNotifyWhenChangedServerCallStub struct
+pkg agent, type AgentNotifyWhenChangedServerCallStub struct, embedded rpc.StreamServerCall
+pkg agent, type AgentNotifyWhenChangedServerStream interface { SendStream }
+pkg agent, type AgentNotifyWhenChangedServerStream interface, SendStream() interface {  Send(item bool) error;}
+pkg agent, type AgentServerMethods interface { AddToRoots, Bless, BlessSelf, BlessingRootsAdd, BlessingRootsDebugString, BlessingRootsRecognized, BlessingStoreDebugString, BlessingStoreDefault, BlessingStoreForPeer, BlessingStorePeerBlessings, BlessingStoreSet, BlessingStoreSetDefault, BlessingsByName, BlessingsInfo, MintDischarge, NotifyWhenChanged, PublicKey, Sign }
+pkg agent, type AgentServerMethods interface, AddToRoots(*context.T, rpc.ServerCall, security.Blessings) error
+pkg agent, type AgentServerMethods interface, Bless(*context.T, rpc.ServerCall, []byte, security.Blessings, string, security.Caveat, []security.Caveat) (security.Blessings, error)
+pkg agent, type AgentServerMethods interface, BlessSelf(*context.T, rpc.ServerCall, string, []security.Caveat) (security.Blessings, error)
+pkg agent, type AgentServerMethods interface, BlessingRootsAdd(*context.T, rpc.ServerCall, []byte, security.BlessingPattern) error
+pkg agent, type AgentServerMethods interface, BlessingRootsDebugString(*context.T, rpc.ServerCall) (string, error)
+pkg agent, type AgentServerMethods interface, BlessingRootsRecognized(*context.T, rpc.ServerCall, []byte, string) error
+pkg agent, type AgentServerMethods interface, BlessingStoreDebugString(*context.T, rpc.ServerCall) (string, error)
+pkg agent, type AgentServerMethods interface, BlessingStoreDefault(*context.T, rpc.ServerCall) (security.Blessings, error)
+pkg agent, type AgentServerMethods interface, BlessingStoreForPeer(*context.T, rpc.ServerCall, []string) (security.Blessings, error)
+pkg agent, type AgentServerMethods interface, BlessingStorePeerBlessings(*context.T, rpc.ServerCall) (map[security.BlessingPattern]security.Blessings, error)
+pkg agent, type AgentServerMethods interface, BlessingStoreSet(*context.T, rpc.ServerCall, security.Blessings, security.BlessingPattern) (security.Blessings, error)
+pkg agent, type AgentServerMethods interface, BlessingStoreSetDefault(*context.T, rpc.ServerCall, security.Blessings) error
+pkg agent, type AgentServerMethods interface, BlessingsByName(*context.T, rpc.ServerCall, security.BlessingPattern) ([]security.Blessings, error)
+pkg agent, type AgentServerMethods interface, BlessingsInfo(*context.T, rpc.ServerCall, security.Blessings) (map[string][]security.Caveat, error)
+pkg agent, type AgentServerMethods interface, MintDischarge(*context.T, rpc.ServerCall, security.Caveat, security.Caveat, []security.Caveat) (security.Discharge, error)
+pkg agent, type AgentServerMethods interface, NotifyWhenChanged(*context.T, AgentNotifyWhenChangedServerCall) error
+pkg agent, type AgentServerMethods interface, PublicKey(*context.T, rpc.ServerCall) ([]byte, error)
+pkg agent, type AgentServerMethods interface, Sign(*context.T, rpc.ServerCall, []byte) (security.Signature, error)
+pkg agent, type AgentServerStub interface { AddToRoots, Bless, BlessSelf, BlessingRootsAdd, BlessingRootsDebugString, BlessingRootsRecognized, BlessingStoreDebugString, BlessingStoreDefault, BlessingStoreForPeer, BlessingStorePeerBlessings, BlessingStoreSet, BlessingStoreSetDefault, BlessingsByName, BlessingsInfo, Describe__, MintDischarge, NotifyWhenChanged, PublicKey, Sign }
+pkg agent, type AgentServerStub interface, AddToRoots(*context.T, rpc.ServerCall, security.Blessings) error
+pkg agent, type AgentServerStub interface, Bless(*context.T, rpc.ServerCall, []byte, security.Blessings, string, security.Caveat, []security.Caveat) (security.Blessings, error)
+pkg agent, type AgentServerStub interface, BlessSelf(*context.T, rpc.ServerCall, string, []security.Caveat) (security.Blessings, error)
+pkg agent, type AgentServerStub interface, BlessingRootsAdd(*context.T, rpc.ServerCall, []byte, security.BlessingPattern) error
+pkg agent, type AgentServerStub interface, BlessingRootsDebugString(*context.T, rpc.ServerCall) (string, error)
+pkg agent, type AgentServerStub interface, BlessingRootsRecognized(*context.T, rpc.ServerCall, []byte, string) error
+pkg agent, type AgentServerStub interface, BlessingStoreDebugString(*context.T, rpc.ServerCall) (string, error)
+pkg agent, type AgentServerStub interface, BlessingStoreDefault(*context.T, rpc.ServerCall) (security.Blessings, error)
+pkg agent, type AgentServerStub interface, BlessingStoreForPeer(*context.T, rpc.ServerCall, []string) (security.Blessings, error)
+pkg agent, type AgentServerStub interface, BlessingStorePeerBlessings(*context.T, rpc.ServerCall) (map[security.BlessingPattern]security.Blessings, error)
+pkg agent, type AgentServerStub interface, BlessingStoreSet(*context.T, rpc.ServerCall, security.Blessings, security.BlessingPattern) (security.Blessings, error)
+pkg agent, type AgentServerStub interface, BlessingStoreSetDefault(*context.T, rpc.ServerCall, security.Blessings) error
+pkg agent, type AgentServerStub interface, BlessingsByName(*context.T, rpc.ServerCall, security.BlessingPattern) ([]security.Blessings, error)
+pkg agent, type AgentServerStub interface, BlessingsInfo(*context.T, rpc.ServerCall, security.Blessings) (map[string][]security.Caveat, error)
+pkg agent, type AgentServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg agent, type AgentServerStub interface, MintDischarge(*context.T, rpc.ServerCall, security.Caveat, security.Caveat, []security.Caveat) (security.Discharge, error)
+pkg agent, type AgentServerStub interface, NotifyWhenChanged(*context.T, *AgentNotifyWhenChangedServerCallStub) error
+pkg agent, type AgentServerStub interface, PublicKey(*context.T, rpc.ServerCall) ([]byte, error)
+pkg agent, type AgentServerStub interface, Sign(*context.T, rpc.ServerCall, []byte) (security.Signature, error)
+pkg agent, type AgentServerStubMethods interface { AddToRoots, Bless, BlessSelf, BlessingRootsAdd, BlessingRootsDebugString, BlessingRootsRecognized, BlessingStoreDebugString, BlessingStoreDefault, BlessingStoreForPeer, BlessingStorePeerBlessings, BlessingStoreSet, BlessingStoreSetDefault, BlessingsByName, BlessingsInfo, MintDischarge, NotifyWhenChanged, PublicKey, Sign }
+pkg agent, type AgentServerStubMethods interface, AddToRoots(*context.T, rpc.ServerCall, security.Blessings) error
+pkg agent, type AgentServerStubMethods interface, Bless(*context.T, rpc.ServerCall, []byte, security.Blessings, string, security.Caveat, []security.Caveat) (security.Blessings, error)
+pkg agent, type AgentServerStubMethods interface, BlessSelf(*context.T, rpc.ServerCall, string, []security.Caveat) (security.Blessings, error)
+pkg agent, type AgentServerStubMethods interface, BlessingRootsAdd(*context.T, rpc.ServerCall, []byte, security.BlessingPattern) error
+pkg agent, type AgentServerStubMethods interface, BlessingRootsDebugString(*context.T, rpc.ServerCall) (string, error)
+pkg agent, type AgentServerStubMethods interface, BlessingRootsRecognized(*context.T, rpc.ServerCall, []byte, string) error
+pkg agent, type AgentServerStubMethods interface, BlessingStoreDebugString(*context.T, rpc.ServerCall) (string, error)
+pkg agent, type AgentServerStubMethods interface, BlessingStoreDefault(*context.T, rpc.ServerCall) (security.Blessings, error)
+pkg agent, type AgentServerStubMethods interface, BlessingStoreForPeer(*context.T, rpc.ServerCall, []string) (security.Blessings, error)
+pkg agent, type AgentServerStubMethods interface, BlessingStorePeerBlessings(*context.T, rpc.ServerCall) (map[security.BlessingPattern]security.Blessings, error)
+pkg agent, type AgentServerStubMethods interface, BlessingStoreSet(*context.T, rpc.ServerCall, security.Blessings, security.BlessingPattern) (security.Blessings, error)
+pkg agent, type AgentServerStubMethods interface, BlessingStoreSetDefault(*context.T, rpc.ServerCall, security.Blessings) error
+pkg agent, type AgentServerStubMethods interface, BlessingsByName(*context.T, rpc.ServerCall, security.BlessingPattern) ([]security.Blessings, error)
+pkg agent, type AgentServerStubMethods interface, BlessingsInfo(*context.T, rpc.ServerCall, security.Blessings) (map[string][]security.Caveat, error)
+pkg agent, type AgentServerStubMethods interface, MintDischarge(*context.T, rpc.ServerCall, security.Caveat, security.Caveat, []security.Caveat) (security.Discharge, error)
+pkg agent, type AgentServerStubMethods interface, NotifyWhenChanged(*context.T, *AgentNotifyWhenChangedServerCallStub) error
+pkg agent, type AgentServerStubMethods interface, PublicKey(*context.T, rpc.ServerCall) ([]byte, error)
+pkg agent, type AgentServerStubMethods interface, Sign(*context.T, rpc.ServerCall, []byte) (security.Signature, error)
+pkg agent, var AgentDesc rpc.InterfaceDesc
diff --git a/services/agent/agentd/.api b/services/agent/agentd/.api
new file mode 100644
index 0000000..2df0f8e
--- /dev/null
+++ b/services/agent/agentd/.api
@@ -0,0 +1 @@
+pkg main, func Main() int
diff --git a/services/agent/agentlib/.api b/services/agent/agentlib/.api
new file mode 100644
index 0000000..a7e75f4
--- /dev/null
+++ b/services/agent/agentlib/.api
@@ -0,0 +1,2 @@
+pkg agentlib, func AgentEndpoint(int) string
+pkg agentlib, func NewAgentPrincipal(*context.T, naming.Endpoint, rpc.Client) (security.Principal, error)
diff --git a/services/agent/internal/cache/.api b/services/agent/internal/cache/.api
new file mode 100644
index 0000000..4c2099c
--- /dev/null
+++ b/services/agent/internal/cache/.api
@@ -0,0 +1 @@
+pkg cache, func NewCachedPrincipal(*context.T, security.Principal, rpc.ClientCall) (security.Principal, error)
diff --git a/services/agent/internal/lru/.api b/services/agent/internal/lru/.api
new file mode 100644
index 0000000..e28dbeb
--- /dev/null
+++ b/services/agent/internal/lru/.api
@@ -0,0 +1,5 @@
+pkg lru, func New(int) *Cache
+pkg lru, method (*Cache) Get(string) (interface{}, bool)
+pkg lru, method (*Cache) Put(string, interface{}) (string, interface{}, bool)
+pkg lru, method (*Cache) Size() int
+pkg lru, type Cache struct
diff --git a/services/agent/internal/pingpong/.api b/services/agent/internal/pingpong/.api
new file mode 100644
index 0000000..032710e
--- /dev/null
+++ b/services/agent/internal/pingpong/.api
@@ -0,0 +1,12 @@
+pkg main, func PingPongClient(string) PingPongClientStub
+pkg main, func PingPongServer(PingPongServerMethods) PingPongServerStub
+pkg main, type PingPongClientMethods interface { Ping }
+pkg main, type PingPongClientMethods interface, Ping(*context.T, string, ...rpc.CallOpt) (string, error)
+pkg main, type PingPongClientStub interface, Ping(*context.T, string, ...rpc.CallOpt) (string, error)
+pkg main, type PingPongClientStub interface, unexported methods
+pkg main, type PingPongServerMethods interface { Ping }
+pkg main, type PingPongServerMethods interface, Ping(*context.T, rpc.ServerCall, string) (string, error)
+pkg main, type PingPongServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg main, type PingPongServerStub interface, unexported methods
+pkg main, type PingPongServerStubMethods PingPongServerMethods
+pkg main, var PingPongDesc rpc.InterfaceDesc
diff --git a/services/agent/internal/server/.api b/services/agent/internal/server/.api
new file mode 100644
index 0000000..c1fdf13
--- /dev/null
+++ b/services/agent/internal/server/.api
@@ -0,0 +1,3 @@
+pkg server, const PrincipalHandleByteSize ideal-int
+pkg server, func RunAnonymousAgent(*context.T, security.Principal, int) (*os.File, string, error)
+pkg server, func RunKeyManager(*context.T, string, []byte) (*os.File, error)
diff --git a/services/agent/internal/test_principal/.api b/services/agent/internal/test_principal/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/agent/internal/test_principal/.api
diff --git a/services/agent/internal/unixfd/.api b/services/agent/internal/unixfd/.api
new file mode 100644
index 0000000..46fafb5
--- /dev/null
+++ b/services/agent/internal/unixfd/.api
@@ -0,0 +1,6 @@
+pkg unixfd, const Network string
+pkg unixfd, func Addr(uintptr) net.Addr
+pkg unixfd, func CloseUnixAddr(net.Addr) error
+pkg unixfd, func ReadConnection(*net.UnixConn, []byte) (net.Addr, int, func(), error)
+pkg unixfd, func SendConnection(*net.UnixConn, []byte) (net.Addr, error)
+pkg unixfd, func Socketpair() (*net.UnixConn, *os.File, error)
diff --git a/services/agent/keymgr/.api b/services/agent/keymgr/.api
new file mode 100644
index 0000000..3cf64be
--- /dev/null
+++ b/services/agent/keymgr/.api
@@ -0,0 +1,5 @@
+pkg keymgr, func NewAgent() (*Agent, error)
+pkg keymgr, func NewLocalAgent(*context.T, string, []byte) (*Agent, error)
+pkg keymgr, method (*Agent) NewConnection([]byte) (*os.File, error)
+pkg keymgr, method (*Agent) NewPrincipal(*context.T, bool) ([]byte, *os.File, error)
+pkg keymgr, type Agent struct
diff --git a/services/application/application/.api b/services/application/application/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/application/application/.api
diff --git a/services/application/application/doc.go b/services/application/application/doc.go
index 491f801..d0bca56 100644
--- a/services/application/application/doc.go
+++ b/services/application/application/doc.go
@@ -18,7 +18,6 @@
    remove      removes the application envelope for the given profile.
    edit        edits the application envelope for the given profile.
    help        Display help for commands or topics
-Run "application help [command]" for command usage.
 
 The global flags are:
  -alsologtostderr=true
@@ -60,7 +59,7 @@
  -vmodule=
    comma-separated list of pattern=N settings for file-filtered logging
 
-Application Match
+Application match
 
 Shows the first matching envelope that matches the given profiles.
 
@@ -70,7 +69,7 @@
 <application> is the full name of the application. <profiles> is a
 comma-separated list of profiles.
 
-Application Put
+Application put
 
 Add the given envelope to the application for the given profiles.
 
@@ -82,7 +81,7 @@
 JSON-encoded envelope. If this file is not provided, the user will be prompted
 to enter the data manually.
 
-Application Remove
+Application remove
 
 removes the application envelope for the given profile.
 
@@ -91,7 +90,7 @@
 
 <application> is the full name of the application. <profile> is a profile.
 
-Application Edit
+Application edit
 
 edits the application envelope for the given profile.
 
@@ -100,7 +99,7 @@
 
 <application> is the full name of the application. <profile> is a profile.
 
-Application Help
+Application help
 
 Help with no args displays the usage of the parent command.
 
@@ -108,11 +107,10 @@
 
 "help ..." recursively displays help for all commands and topics.
 
-The output is formatted to a target width in runes.  The target width is
-determined by checking the environment variable CMDLINE_WIDTH, falling back on
-the terminal width from the OS, falling back on 80 chars.  By setting
-CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0 the width is unlimited, and
-if x == 0 or is unset one of the fallbacks is used.
+Output is formatted to a target width in runes, determined by checking the
+CMDLINE_WIDTH environment variable, falling back on the terminal width, falling
+back on 80 chars.  By setting CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0
+the width is unlimited, and if x == 0 or is unset one of the fallbacks is used.
 
 Usage:
    application help [flags] [command/topic ...]
@@ -120,7 +118,11 @@
 [command/topic ...] optionally identifies a specific sub-command or help topic.
 
 The application help flags are:
- -style=default
-   The formatting style for help output, either "default" or "godoc".
+ -style=compact
+   The formatting style for help output:
+      compact - Good for compact cmdline output.
+      full    - Good for cmdline output, shows all global flags.
+      godoc   - Good for godoc processing.
+   Override the default by setting the CMDLINE_STYLE environment variable.
 */
 package main
diff --git a/services/application/application/impl.go b/services/application/application/impl.go
index de18364..448661e 100644
--- a/services/application/application/impl.go
+++ b/services/application/application/impl.go
@@ -21,6 +21,10 @@
 	"v.io/x/ref/services/repository"
 )
 
+func init() {
+	cmdline.HideGlobalFlagsExcept()
+}
+
 func getEnvelopeJSON(app repository.ApplicationClientMethods, profiles string) ([]byte, error) {
 	ctx, cancel := context.WithTimeout(gctx, time.Minute)
 	defer cancel()
diff --git a/services/application/applicationd/.api b/services/application/applicationd/.api
new file mode 100644
index 0000000..8959856
--- /dev/null
+++ b/services/application/applicationd/.api
@@ -0,0 +1,5 @@
+pkg main, func NewApplicationService(*fs.Memstore, string, string) repository.ApplicationServerMethods
+pkg main, func NewDispatcher(string) (rpc.Dispatcher, error)
+pkg main, var ErrInvalidSuffix unknown-type
+pkg main, var ErrNotAuthorized unknown-type
+pkg main, var ErrOperationFailed unknown-type
diff --git a/services/binary/binary/.api b/services/binary/binary/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/binary/binary/.api
diff --git a/services/binary/binary/doc.go b/services/binary/binary/doc.go
index be451bf..9714180 100644
--- a/services/binary/binary/doc.go
+++ b/services/binary/binary/doc.go
@@ -17,7 +17,6 @@
    upload      Upload a binary or directory archive
    url         Fetch a download URL
    help        Display help for commands or topics
-Run "binary help [command]" for command usage.
 
 The global flags are:
  -alsologtostderr=true
@@ -59,7 +58,7 @@
  -vmodule=
    comma-separated list of pattern=N settings for file-filtered logging
 
-Binary Delete
+Binary delete
 
 Delete connects to the binary repository and deletes the specified binary
 
@@ -68,7 +67,7 @@
 
 <von> is the vanadium object name of the binary to delete
 
-Binary Download
+Binary download
 
 Download connects to the binary repository, downloads the specified binary, and
 writes it to a file.
@@ -79,7 +78,7 @@
 <von> is the vanadium object name of the binary to download <filename> is the
 name of the file where the binary will be written
 
-Binary Upload
+Binary upload
 
 Upload connects to the binary repository and uploads the binary of the specified
 file or archive of the specified directory. When successful, it writes the name
@@ -91,7 +90,7 @@
 <von> is the vanadium object name of the binary to upload <filename> is the name
 of the file or directory to upload
 
-Binary Url
+Binary url
 
 Connect to the binary repository and fetch the download URL for the given
 vanadium object name.
@@ -101,7 +100,7 @@
 
 <von> is the vanadium object name of the binary repository
 
-Binary Help
+Binary help
 
 Help with no args displays the usage of the parent command.
 
@@ -109,11 +108,10 @@
 
 "help ..." recursively displays help for all commands and topics.
 
-The output is formatted to a target width in runes.  The target width is
-determined by checking the environment variable CMDLINE_WIDTH, falling back on
-the terminal width from the OS, falling back on 80 chars.  By setting
-CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0 the width is unlimited, and
-if x == 0 or is unset one of the fallbacks is used.
+Output is formatted to a target width in runes, determined by checking the
+CMDLINE_WIDTH environment variable, falling back on the terminal width, falling
+back on 80 chars.  By setting CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0
+the width is unlimited, and if x == 0 or is unset one of the fallbacks is used.
 
 Usage:
    binary help [flags] [command/topic ...]
@@ -121,7 +119,11 @@
 [command/topic ...] optionally identifies a specific sub-command or help topic.
 
 The binary help flags are:
- -style=default
-   The formatting style for help output, either "default" or "godoc".
+ -style=compact
+   The formatting style for help output:
+      compact - Good for compact cmdline output.
+      full    - Good for cmdline output, shows all global flags.
+      godoc   - Good for godoc processing.
+   Override the default by setting the CMDLINE_STYLE environment variable.
 */
 package main
diff --git a/services/binary/binary/impl.go b/services/binary/binary/impl.go
index 75e80b4..a86ede8 100644
--- a/services/binary/binary/impl.go
+++ b/services/binary/binary/impl.go
@@ -12,6 +12,10 @@
 	"v.io/x/ref/services/internal/binarylib"
 )
 
+func init() {
+	cmdline.HideGlobalFlagsExcept()
+}
+
 var cmdDelete = &cmdline.Command{
 	Run:      runDelete,
 	Name:     "delete",
diff --git a/services/binary/binaryd/.api b/services/binary/binaryd/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/binary/binaryd/.api
diff --git a/services/binary/binaryd/main.go b/services/binary/binaryd/main.go
index e5fdc80..16cd87c 100644
--- a/services/binary/binaryd/main.go
+++ b/services/binary/binaryd/main.go
@@ -32,6 +32,7 @@
 // toIPPort tries to swap in the 'best' accessible IP for the host part of the
 // address, if the provided address has an unspecified IP.
 func toIPPort(ctx *context.T, addr string) string {
+	// TODO(caprita): consider using netstate.PossibleAddresses()
 	host, port, err := net.SplitHostPort(addr)
 	if err != nil {
 		vlog.Errorf("SplitHostPort(%v) failed: %v", addr, err)
@@ -43,8 +44,8 @@
 		ips, err := netstate.GetAccessibleIPs()
 		if err == nil {
 			ls := v23.GetListenSpec(ctx)
-			if a, err := ls.AddressChooser("tcp", ips); err == nil && len(a) > 0 {
-				host = a[0].Address().String()
+			if a, err := ls.AddressChooser("tcp", ips.AsNetAddrs()); err == nil && len(a) > 0 {
+				host = a[0].String()
 			}
 		}
 	}
diff --git a/services/build/build/.api b/services/build/build/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/build/build/.api
diff --git a/services/build/build/doc.go b/services/build/build/doc.go
index 2952467..2fa4527 100644
--- a/services/build/build/doc.go
+++ b/services/build/build/doc.go
@@ -14,7 +14,6 @@
 The build commands are:
    build       Build vanadium Go packages
    help        Display help for commands or topics
-Run "build help [command]" for command usage.
 
 The global flags are:
  -alsologtostderr=true
@@ -56,7 +55,7 @@
  -vmodule=
    comma-separated list of pattern=N settings for file-filtered logging
 
-Build Build
+Build build
 
 Build vanadium Go packages using a remote build server. The command collects all
 source code files that are not part of the Go standard library that the target
@@ -78,7 +77,7 @@
  -os=<runtime.GOOS>
    Target operating system.  The default is the value of runtime.GOOS.
 
-Build Help
+Build help
 
 Help with no args displays the usage of the parent command.
 
@@ -86,11 +85,10 @@
 
 "help ..." recursively displays help for all commands and topics.
 
-The output is formatted to a target width in runes.  The target width is
-determined by checking the environment variable CMDLINE_WIDTH, falling back on
-the terminal width from the OS, falling back on 80 chars.  By setting
-CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0 the width is unlimited, and
-if x == 0 or is unset one of the fallbacks is used.
+Output is formatted to a target width in runes, determined by checking the
+CMDLINE_WIDTH environment variable, falling back on the terminal width, falling
+back on 80 chars.  By setting CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0
+the width is unlimited, and if x == 0 or is unset one of the fallbacks is used.
 
 Usage:
    build help [flags] [command/topic ...]
@@ -98,7 +96,11 @@
 [command/topic ...] optionally identifies a specific sub-command or help topic.
 
 The build help flags are:
- -style=default
-   The formatting style for help output, either "default" or "godoc".
+ -style=compact
+   The formatting style for help output:
+      compact - Good for compact cmdline output.
+      full    - Good for cmdline output, shows all global flags.
+      godoc   - Good for godoc processing.
+   Override the default by setting the CMDLINE_STYLE environment variable.
 */
 package main
diff --git a/services/build/build/impl.go b/services/build/build/impl.go
index 8f96f38..f9b6e7f 100644
--- a/services/build/build/impl.go
+++ b/services/build/build/impl.go
@@ -25,6 +25,7 @@
 )
 
 func init() {
+	cmdline.HideGlobalFlagsExcept()
 	cmdBuild.Flags.StringVar(&flagArch, "arch", runtime.GOARCH, "Target architecture.  The default is the value of runtime.GOARCH.")
 	cmdBuild.Flags.Lookup("arch").DefValue = "<runtime.GOARCH>"
 	cmdBuild.Flags.StringVar(&flagOS, "os", runtime.GOOS, "Target operating system.  The default is the value of runtime.GOOS.")
diff --git a/services/build/buildd/.api b/services/build/buildd/.api
new file mode 100644
index 0000000..3af3203
--- /dev/null
+++ b/services/build/buildd/.api
@@ -0,0 +1 @@
+pkg main, func NewBuilderService(string, string) build.BuilderServerMethods
diff --git a/services/debug/debug/.api b/services/debug/debug/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/debug/debug/.api
diff --git a/services/debug/debug/doc.go b/services/debug/debug/doc.go
index 7034069..42eaf67 100644
--- a/services/debug/debug/doc.go
+++ b/services/debug/debug/doc.go
@@ -18,7 +18,6 @@
    stats       Accesses stats
    pprof       Accesses profiling data
    help        Display help for commands or topics
-Run "debug help [command]" for command usage.
 
 The global flags are:
  -alsologtostderr=true
@@ -60,7 +59,7 @@
  -vmodule=
    comma-separated list of pattern=N settings for file-filtered logging
 
-Debug Glob
+Debug glob
 
 Returns all matching entries from the namespace.
 
@@ -69,7 +68,7 @@
 
 <pattern> is a glob pattern to match.
 
-Debug Vtrace
+Debug vtrace
 
 Returns matching vtrace traces (or all stored traces if no ids are given).
 
@@ -78,7 +77,7 @@
 
 <name> is the name of a vtrace object. [id] is a vtrace trace id.
 
-Debug Logs
+Debug logs
 
 Accesses log files
 
@@ -89,7 +88,7 @@
    read        Reads the content of a log file object.
    size        Returns the size of a log file object.
 
-Debug Logs Read
+Debug logs read
 
 Reads the content of a log file object.
 
@@ -109,7 +108,7 @@
  -v=false
    When true, read will be more verbose.
 
-Debug Logs Size
+Debug logs size
 
 Returns the size of a log file object.
 
@@ -118,7 +117,7 @@
 
 <name> is the name of the log file object.
 
-Debug Stats
+Debug stats
 
 Accesses stats
 
@@ -130,7 +129,7 @@
    watch       Returns a stream of all matching entries and their values as they
                change.
 
-Debug Stats Read
+Debug stats read
 
 Returns the value of stats objects.
 
@@ -146,7 +145,7 @@
  -type=false
    When true, the type of the values will be displayed.
 
-Debug Stats Watch
+Debug stats watch
 
 Returns a stream of all matching entries and their values as they change.
 
@@ -161,7 +160,7 @@
  -type=false
    When true, the type of the values will be displayed.
 
-Debug Pprof
+Debug pprof
 
 Accesses profiling data
 
@@ -172,7 +171,7 @@
    run         Runs the pprof tool.
    proxy       Runs an http proxy to a pprof object.
 
-Debug Pprof Run
+Debug pprof run
 
 Runs the pprof tool.
 
@@ -190,7 +189,7 @@
  -pprofcmd=v23 go tool pprof
    The pprof command to use.
 
-Debug Pprof Proxy
+Debug pprof proxy
 
 Runs an http proxy to a pprof object.
 
@@ -199,7 +198,7 @@
 
 <name> is the name of the pprof object.
 
-Debug Help
+Debug help
 
 Help with no args displays the usage of the parent command.
 
@@ -207,11 +206,10 @@
 
 "help ..." recursively displays help for all commands and topics.
 
-The output is formatted to a target width in runes.  The target width is
-determined by checking the environment variable CMDLINE_WIDTH, falling back on
-the terminal width from the OS, falling back on 80 chars.  By setting
-CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0 the width is unlimited, and
-if x == 0 or is unset one of the fallbacks is used.
+Output is formatted to a target width in runes, determined by checking the
+CMDLINE_WIDTH environment variable, falling back on the terminal width, falling
+back on 80 chars.  By setting CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0
+the width is unlimited, and if x == 0 or is unset one of the fallbacks is used.
 
 Usage:
    debug help [flags] [command/topic ...]
@@ -219,7 +217,11 @@
 [command/topic ...] optionally identifies a specific sub-command or help topic.
 
 The debug help flags are:
- -style=default
-   The formatting style for help output, either "default" or "godoc".
+ -style=compact
+   The formatting style for help output:
+      compact - Good for compact cmdline output.
+      full    - Good for cmdline output, shows all global flags.
+      godoc   - Good for godoc processing.
+   Override the default by setting the CMDLINE_STYLE environment variable.
 */
 package main
diff --git a/services/debug/debug/impl.go b/services/debug/debug/impl.go
index 14873ea..464faf9 100644
--- a/services/debug/debug/impl.go
+++ b/services/debug/debug/impl.go
@@ -42,6 +42,8 @@
 )
 
 func init() {
+	cmdline.HideGlobalFlagsExcept()
+
 	// logs read flags
 	cmdLogsRead.Flags.BoolVar(&follow, "f", false, "When true, read will wait for new log entries when it reaches the end of the file.")
 	cmdLogsRead.Flags.BoolVar(&verbose, "v", false, "When true, read will be more verbose.")
diff --git a/services/debug/debuglib/.api b/services/debug/debuglib/.api
new file mode 100644
index 0000000..d3002d4
--- /dev/null
+++ b/services/debug/debuglib/.api
@@ -0,0 +1 @@
+pkg debuglib, func NewDispatcher(func() string, security.Authorizer) rpc.Dispatcher
diff --git a/services/device/.api b/services/device/.api
new file mode 100644
index 0000000..34fc74f
--- /dev/null
+++ b/services/device/.api
@@ -0,0 +1,12 @@
+pkg device, func ConfigClient(string) ConfigClientStub
+pkg device, func ConfigServer(ConfigServerMethods) ConfigServerStub
+pkg device, type ConfigClientMethods interface { Set }
+pkg device, type ConfigClientMethods interface, Set(*context.T, string, string, ...rpc.CallOpt) error
+pkg device, type ConfigClientStub interface, Set(*context.T, string, string, ...rpc.CallOpt) error
+pkg device, type ConfigClientStub interface, unexported methods
+pkg device, type ConfigServerMethods interface { Set }
+pkg device, type ConfigServerMethods interface, Set(*context.T, rpc.ServerCall, string, string) error
+pkg device, type ConfigServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg device, type ConfigServerStub interface, unexported methods
+pkg device, type ConfigServerStubMethods ConfigServerMethods
+pkg device, var ConfigDesc rpc.InterfaceDesc
diff --git a/services/device/device/.api b/services/device/device/.api
new file mode 100644
index 0000000..4ea8c86
--- /dev/null
+++ b/services/device/device/.api
@@ -0,0 +1,2 @@
+pkg main, func Root() *cmdline.Command
+pkg main, func SetGlobalContext(*context.T)
diff --git a/services/device/device/doc.go b/services/device/device/doc.go
index fd9111e..cd1ba14 100644
--- a/services/device/device/doc.go
+++ b/services/device/device/doc.go
@@ -31,9 +31,14 @@
    acl           Tool for setting device manager Permissions
    publish       Publish the given application(s).
    help          Display help for commands or topics
-Run "device help [command]" for command usage.
 
 The global flags are:
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+   local namespace root; can be repeated to provided multiple roots
+ -v23.proxy=
+   object name of proxy service to use to export services across network
+   boundaries
+
  -alsologtostderr=true
    log to standard error as well as files
  -dryrun=false
@@ -68,16 +73,11 @@
    directory to use for storing security credentials
  -v23.i18n-catalogue=
    18n catalogue files to load, comma separated
- -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
-   local namespace root; can be repeated to provided multiple roots
  -v23.permissions.file=map[]
    specify a perms file as <name>:<permsfile>
  -v23.permissions.literal=
    explicitly specify the runtime perms as a JSON-encoded access.Permissions.
    Overrides all --v23.permissions.file flags.
- -v23.proxy=
-   object name of proxy service to use to export services across network
-   boundaries
  -v23.tcp.address=
    address to listen on
  -v23.tcp.protocol=wsh
@@ -96,7 +96,7 @@
  -workspace=
    Path to the application's workspace directory.
 
-Device Install
+Device install
 
 Install the given application and print the name of the new installation.
 
@@ -115,7 +115,7 @@
    JSON-encoded application.Packages object, of the form:
    '{"pkg1":{"File":"object name 1"},"pkg2":{"File":"object name 2"}}'
 
-Device Install-Local
+Device install-local
 
 Install the given application specified using a local path, and print the name
 of the new installation.
@@ -140,7 +140,7 @@
    JSON-encoded application.Packages object, of the form:
    '{"pkg1":{"File":"local file path1"},"pkg2":{"File":"local file path 2"}}'
 
-Device Uninstall
+Device uninstall
 
 Uninstall the given application installation.
 
@@ -150,7 +150,7 @@
 <installation> is the vanadium object name of the application installation to
 uninstall.
 
-Device Associate
+Device associate
 
 The associate tool facilitates managing blessing to system account associations.
 
@@ -162,7 +162,7 @@
    add         Add the listed blessings with the specified system account.
    remove      Removes system accounts associated with the listed blessings.
 
-Device Associate List
+Device associate list
 
 Lists all account associations.
 
@@ -171,7 +171,7 @@
 
 <devicemanager> is the name of the device manager to connect to.
 
-Device Associate Add
+Device associate add
 
 Add the listed blessings with the specified system account.
 
@@ -182,7 +182,7 @@
 the name of an account holder on the local system. <blessing>.. are the
 blessings to associate systemAccount with.
 
-Device Associate Remove
+Device associate remove
 
 Removes system accounts associated with the listed blessings.
 
@@ -192,7 +192,7 @@
 <devicemanager> is the name of the device manager to connect to. <blessing>...
 is a list of blessings.
 
-Device Describe
+Device describe
 
 Describe the device.
 
@@ -201,7 +201,7 @@
 
 <device> is the vanadium object name of the device manager's device service.
 
-Device Claim
+Device claim
 
 Claim the device.
 
@@ -219,7 +219,7 @@
 <device publickey> is the marshalled public key of the device manager we are
 claiming.
 
-Device Instantiate
+Device instantiate
 
 Create an instance of the given application, provide it with a blessing, and
 print the name of the new instance.
@@ -233,7 +233,7 @@
 <grant extension> is used to extend the default blessing of the current
 principal when blessing the app instance.
 
-Device Delete
+Device delete
 
 Delete the given application instance.
 
@@ -243,7 +243,7 @@
 <app instance> is the vanadium object name of the application instance to
 delete.
 
-Device Run
+Device run
 
 Run the given application instance.
 
@@ -252,7 +252,7 @@
 
 <app instance> is the vanadium object name of the application instance to run.
 
-Device Kill
+Device kill
 
 Kill the given application instance.
 
@@ -261,7 +261,7 @@
 
 <app instance> is the vanadium object name of the application instance to kill.
 
-Device Revert
+Device revert
 
 Revert the device manager or application to its previous version
 
@@ -271,7 +271,7 @@
 <object> is the vanadium object name of the device manager or application
 installation to revert.
 
-Device Update
+Device update
 
 Update the device manager or application
 
@@ -281,7 +281,7 @@
 <object> is the vanadium object name of the device manager or application
 installation or instance to update.
 
-Device Updateall
+Device updateall
 
 Given a name that can refer to an app instance or app installation or app or all
 apps on a device, updates all installations and instances under that name
@@ -301,7 +301,7 @@
 
 <devicename>/apps: updates all apps on the device
 
-Device Status
+Device status
 
 Get the status of an application installation or instance.
 
@@ -310,7 +310,7 @@
 
 <app name> is the vanadium object name of an app installation or instance.
 
-Device Debug
+Device debug
 
 Debug the device.
 
@@ -319,7 +319,7 @@
 
 <app name> is the vanadium object name of an app installation or instance.
 
-Device Acl
+Device acl
 
 The acl tool manages Permissions on the device manger, installations and
 instances.
@@ -331,7 +331,7 @@
    get         Get Permissions for the given target.
    set         Set Permissions for the given target.
 
-Device Acl Get
+Device acl get
 
 Get Permissions for the given target.
 
@@ -341,7 +341,7 @@
 <device manager name> can be a Vanadium name for a device manager, application
 installation or instance.
 
-Device Acl Set
+Device acl set
 
 Set Permissions for the given target
 
@@ -371,7 +371,7 @@
    Instead of making the AccessLists additive, do a complete replacement based
    on the specified settings.
 
-Device Publish
+Device publish
 
 Publishes the given application(s) to the binary and application servers. The
 binaries should be in $V23_ROOT/release/go/bin/[<GOOS>_<GOARCH>]. The binary is
@@ -395,7 +395,7 @@
    If non-empty, comma-separated blessing patterns to add to Read and Resolve
    AccessList.
 
-Device Help
+Device help
 
 Help with no args displays the usage of the parent command.
 
@@ -403,11 +403,10 @@
 
 "help ..." recursively displays help for all commands and topics.
 
-The output is formatted to a target width in runes.  The target width is
-determined by checking the environment variable CMDLINE_WIDTH, falling back on
-the terminal width from the OS, falling back on 80 chars.  By setting
-CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0 the width is unlimited, and
-if x == 0 or is unset one of the fallbacks is used.
+Output is formatted to a target width in runes, determined by checking the
+CMDLINE_WIDTH environment variable, falling back on the terminal width, falling
+back on 80 chars.  By setting CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0
+the width is unlimited, and if x == 0 or is unset one of the fallbacks is used.
 
 Usage:
    device help [flags] [command/topic ...]
@@ -415,7 +414,11 @@
 [command/topic ...] optionally identifies a specific sub-command or help topic.
 
 The device help flags are:
- -style=default
-   The formatting style for help output, either "default" or "godoc".
+ -style=compact
+   The formatting style for help output:
+      compact - Good for compact cmdline output.
+      full    - Good for cmdline output, shows all global flags.
+      godoc   - Good for godoc processing.
+   Override the default by setting the CMDLINE_STYLE environment variable.
 */
 package main
diff --git a/services/device/device/main.go b/services/device/device/main.go
index 46c85c4..b523dbc 100644
--- a/services/device/device/main.go
+++ b/services/device/device/main.go
@@ -9,13 +9,15 @@
 
 import (
 	"os"
+	"regexp"
 
 	"v.io/v23"
-
+	"v.io/x/lib/cmdline"
 	_ "v.io/x/ref/profiles/static"
 )
 
 func main() {
+	cmdline.HideGlobalFlagsExcept(regexp.MustCompile(`^(v23\.namespace\.root)|(v23\.proxy)$`))
 	gctx, shutdown := v23.Init()
 	SetGlobalContext(gctx)
 	exitCode := Root().Main()
diff --git a/services/device/deviced/.api b/services/device/deviced/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/device/deviced/.api
diff --git a/services/device/deviced/doc.go b/services/device/deviced/doc.go
new file mode 100644
index 0000000..567ed5c
--- /dev/null
+++ b/services/device/deviced/doc.go
@@ -0,0 +1,200 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command deviced is used to launch, configure and manage the deviced daemon,
+which implements the v.io/v23/services/device interfaces.
+
+Usage:
+   deviced <command>
+   deviced
+
+The deviced commands are:
+   install     Install the device manager.
+   uninstall   Uninstall the device manager.
+   start       Start the device manager.
+   stop        Stop the device manager.
+   profile     Dumps profile for the device manager.
+   help        Display help for commands or topics
+
+The global flags are:
+ -deviced-port=0
+   the port number of assign to the device manager service. The hostname/IP
+   address part of --v23.tcp.address is used along with this port. By default,
+   the port is assigned by the OS.
+ -name=
+   name to publish the device manager at
+ -neighborhood-name=
+   if provided, it will enable sharing with the local neighborhood with the
+   provided name. The address of the local mounttable will be published to the
+   neighboorhood and everything in the neighborhood will be visible on the local
+   mounttable.
+ -proxy-port=0
+   the port number to assign to the proxy service. 0 means no proxy service.
+ -restart-exit-code=0
+   exit code to return when device manager should be restarted
+ -use-pairing-token=false
+   generate a pairing token for the device manager that will need to be provided
+   when a device is claimed
+
+ -alsologtostderr=true
+   log to standard error as well as files
+ -dryrun=false
+   Elides root-requiring systemcalls.
+ -kill=false
+   Kill process ids given as command-line arguments.
+ -log_backtrace_at=:0
+   when logging hits line file:N, emit a stack trace
+ -log_dir=
+   if non-empty, write log files to this directory
+ -logdir=
+   Path to the log directory.
+ -logtostderr=false
+   log to standard error instead of files
+ -max_stack_buf_size=4292608
+   max size in bytes of the buffer to use for logging stack traces
+ -minuid=501
+   UIDs cannot be less than this number.
+ -progname=unnamed_app
+   Visible name of the application, used in argv[0]
+ -rm=false
+   Remove the file trees given as command-line arguments.
+ -run=
+   Path to the application to exec.
+ -stderrthreshold=2
+   logs at or above this threshold go to stderr
+ -username=
+   The UNIX user name used for the other functions of this tool.
+ -v=0
+   log level for V logs
+ -v23.credentials=
+   directory to use for storing security credentials
+ -v23.i18n-catalogue=
+   18n catalogue files to load, comma separated
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+   local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+   specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+   explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+   Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+   object name of proxy service to use to export services across network
+   boundaries
+ -v23.tcp.address=
+   address to listen on
+ -v23.tcp.protocol=wsh
+   protocol to listen with
+ -v23.vtrace.cache-size=1024
+   The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+   Spans and annotations that match this regular expression will trigger trace
+   collection.
+ -v23.vtrace.dump-on-shutdown=true
+   If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+   Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+   comma-separated list of pattern=N settings for file-filtered logging
+ -workspace=
+   Path to the application's workspace directory.
+
+Deviced install
+
+Performs installation of device manager into V23_DEVICE_DIR (if the env var
+set), or into the current dir otherwise
+
+Usage:
+   deviced install [flags] [-- <arguments for device manager>]
+
+Arguments to be passed to the installed device manager
+
+The deviced install flags are:
+ -agent=
+   path to security agent
+ -devuser=
+   if specified, device manager will run as this user. Provided by devicex but
+   ignored .
+ -from=
+   if specified, performs the installation from the provided application
+   envelope object name
+ -init_helper=
+   path to sysinit helper
+ -init_mode=false
+   if set, installs the device manager with the system init service manager
+ -origin=
+   if specified, self-updates will use this origin
+ -session_mode=false
+   if set, installs the device manager to run a single session. Otherwise, the
+   device manager is configured to get restarted upon exit
+ -single_user=false
+   if set, performs the installation assuming a single-user system
+ -suid_helper=
+   path to suid helper
+
+Deviced uninstall
+
+Removes the device manager installation from V23_DEVICE_DIR (if the env var
+set), or the current dir otherwise
+
+Usage:
+   deviced uninstall [flags]
+
+The deviced uninstall flags are:
+ -suid_helper=
+   path to suid helper
+
+Deviced start
+
+Starts the device manager installed under from V23_DEVICE_DIR (if the env var
+set), or the current dir otherwise
+
+Usage:
+   deviced start
+
+Deviced stop
+
+Stops the device manager installed under from V23_DEVICE_DIR (if the env var
+set), or the current dir otherwise
+
+Usage:
+   deviced stop
+
+Deviced profile
+
+Prints the internal profile description for the device manager.
+
+Usage:
+   deviced profile
+
+Deviced help
+
+Help with no args displays the usage of the parent command.
+
+Help with args displays the usage of the specified sub-command or help topic.
+
+"help ..." recursively displays help for all commands and topics.
+
+Output is formatted to a target width in runes, determined by checking the
+CMDLINE_WIDTH environment variable, falling back on the terminal width, falling
+back on 80 chars.  By setting CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0
+the width is unlimited, and if x == 0 or is unset one of the fallbacks is used.
+
+Usage:
+   deviced help [flags] [command/topic ...]
+
+[command/topic ...] optionally identifies a specific sub-command or help topic.
+
+The deviced help flags are:
+ -style=compact
+   The formatting style for help output:
+      compact - Good for compact cmdline output.
+      full    - Good for cmdline output, shows all global flags.
+      godoc   - Good for godoc processing.
+   Override the default by setting the CMDLINE_STYLE environment variable.
+*/
+package main
diff --git a/services/device/deviced/main.go b/services/device/deviced/main.go
index 1e23e55..2e824b2 100644
--- a/services/device/deviced/main.go
+++ b/services/device/deviced/main.go
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Daemon deviced implements the v.io/v23/services/device interfaces.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go .
+
 package main
 
 import (
@@ -21,9 +23,10 @@
 
 	rootCmd := cmdline.Command{
 		Name:  "deviced",
-		Short: "Vanadium device manager setup",
+		Short: "launch, configure and manage the deviced daemon",
 		Long: `
-deviced can be used to launch, configure, or manage the device manager.
+Command deviced is used to launch, configure and manage the deviced daemon,
+which implements the v.io/v23/services/device interfaces.
 `,
 		Children: []*cmdline.Command{cmdInstall, cmdUninstall, cmdStart, cmdStop, cmdProfile},
 		Run:      runServer,
diff --git a/services/device/deviced/server.go b/services/device/deviced/server.go
index 052e0fe..26e38d1 100644
--- a/services/device/deviced/server.go
+++ b/services/device/deviced/server.go
@@ -11,23 +11,22 @@
 	"net"
 	"os"
 	"path/filepath"
+	"regexp"
 	"strconv"
 	"time"
 
+	"v.io/v23"
+	"v.io/v23/context"
+	"v.io/v23/rpc"
+	"v.io/v23/verror"
 	"v.io/x/lib/cmdline"
-
+	"v.io/x/lib/vlog"
 	vexec "v.io/x/ref/lib/exec"
 	"v.io/x/ref/lib/mgmt"
 	"v.io/x/ref/lib/signals"
 	_ "v.io/x/ref/profiles/roaming"
 	"v.io/x/ref/services/device/internal/config"
 	"v.io/x/ref/services/device/internal/starter"
-
-	"v.io/v23"
-	"v.io/v23/context"
-	"v.io/v23/rpc"
-	"v.io/v23/verror"
-	"v.io/x/lib/vlog"
 )
 
 const pkgPath = "v.io/x/ref/services/device/deviced"
@@ -47,6 +46,10 @@
 	usePairingToken = flag.Bool("use-pairing-token", false, "generate a pairing token for the device manager that will need to be provided when a device is claimed")
 )
 
+func init() {
+	cmdline.HideGlobalFlagsExcept(regexp.MustCompile(`^(name)|(restart-exit-code)|(neighborhood-name)|(deviced-port)|(proxy-port)|(use-pairing-token)$`))
+}
+
 func runServer(*cmdline.Command, []string) error {
 	ctx, shutdown := v23.Init()
 	defer shutdown()
diff --git a/services/device/inithelper/.api b/services/device/inithelper/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/device/inithelper/.api
diff --git a/services/device/internal/config/.api b/services/device/internal/config/.api
new file mode 100644
index 0000000..394cdc2
--- /dev/null
+++ b/services/device/internal/config/.api
@@ -0,0 +1,18 @@
+pkg config, const CurrentLinkEnv ideal-string
+pkg config, const EnvelopeEnv ideal-string
+pkg config, const HelperEnv ideal-string
+pkg config, const OriginEnv ideal-string
+pkg config, const PreviousEnv ideal-string
+pkg config, const RootEnv ideal-string
+pkg config, func Load() (*State, error)
+pkg config, func QuoteEnv([]string) []string
+pkg config, method (*State) Save(*application.Envelope) ([]string, error)
+pkg config, method (*State) Validate() error
+pkg config, type State struct
+pkg config, type State struct, CurrentLink string
+pkg config, type State struct, Envelope *application.Envelope
+pkg config, type State struct, Helper string
+pkg config, type State struct, Name string
+pkg config, type State struct, Origin string
+pkg config, type State struct, Previous string
+pkg config, type State struct, Root string
diff --git a/services/device/internal/impl/.api b/services/device/internal/impl/.api
new file mode 100644
index 0000000..859c1fb
--- /dev/null
+++ b/services/device/internal/impl/.api
@@ -0,0 +1,41 @@
+pkg impl, func CheckCompatibility(string) error
+pkg impl, func ComputeDeviceProfile() (*profile.Specification, error)
+pkg impl, func InstallFrom(string) error
+pkg impl, func InvokeCallback(*context.T, string)
+pkg impl, func NewBlessingSystemAssociationStore(string) (BlessingSystemAssociationStore, error)
+pkg impl, func NewClaimableDispatcher(*context.T, *config.State, string) (rpc.Dispatcher, <-chan struct{})
+pkg impl, func NewDispatcher(*context.T, *config.State, string, bool, func(), *pathperms.PathStore) (rpc.Dispatcher, error)
+pkg impl, func PermsDir(*config.State) string
+pkg impl, func SaveCreatorInfo(string) error
+pkg impl, func SaveManagerInfo(string, *ManagerInfo) error
+pkg impl, func SelfInstall(string, string, string, string, string, bool, bool, bool, []string, []string, io.Writer, io.Writer) error
+pkg impl, func Shutdown(rpc.Dispatcher)
+pkg impl, func Start(string, io.Writer, io.Writer) error
+pkg impl, func Stop(*context.T, string, io.Writer, io.Writer) error
+pkg impl, func Uninstall(string, string, io.Writer, io.Writer) error
+pkg impl, func VanadiumEnvironment([]string) []string
+pkg impl, type BlessingSystemAssociationStore interface { AllBlessingSystemAssociations, AssociateSystemAccountForBlessings, DisassociateSystemAccountForBlessings, SystemAccountForBlessings }
+pkg impl, type BlessingSystemAssociationStore interface, AllBlessingSystemAssociations() ([]device.Association, error)
+pkg impl, type BlessingSystemAssociationStore interface, AssociateSystemAccountForBlessings([]string, string) error
+pkg impl, type BlessingSystemAssociationStore interface, DisassociateSystemAccountForBlessings([]string) error
+pkg impl, type BlessingSystemAssociationStore interface, SystemAccountForBlessings([]string) (string, bool)
+pkg impl, type CreatorInfo struct
+pkg impl, type CreatorInfo struct, BuildInfo string
+pkg impl, type CreatorInfo struct, Version Version
+pkg impl, type ManagerInfo struct
+pkg impl, type ManagerInfo struct, Pid int
+pkg impl, type Version struct
+pkg impl, type Version struct, Major int
+pkg impl, type Version struct, Minor int
+pkg impl, var CurrentVersion Version
+pkg impl, var Describe func() (device.Description, error)
+pkg impl, var ErrAppTitleMismatch unknown-type
+pkg impl, var ErrDeviceAlreadyClaimed unknown-type
+pkg impl, var ErrInvalidBlessing unknown-type
+pkg impl, var ErrInvalidOperation unknown-type
+pkg impl, var ErrInvalidPairingToken unknown-type
+pkg impl, var ErrInvalidSuffix unknown-type
+pkg impl, var ErrOperationFailed unknown-type
+pkg impl, var ErrOperationInProgress unknown-type
+pkg impl, var ErrUnclaimedDevice unknown-type
+pkg impl, var ErrUpdateNoOp unknown-type
diff --git a/services/device/internal/starter/.api b/services/device/internal/starter/.api
new file mode 100644
index 0000000..2d792ae
--- /dev/null
+++ b/services/device/internal/starter/.api
@@ -0,0 +1,21 @@
+pkg starter, func Start(*context.T, Args) (func(), error)
+pkg starter, type Args struct
+pkg starter, type Args struct, Device DeviceArgs
+pkg starter, type Args struct, MountGlobalNamespaceInLocalNamespace bool
+pkg starter, type Args struct, Namespace NamespaceArgs
+pkg starter, type Args struct, Proxy ProxyArgs
+pkg starter, type DeviceArgs struct
+pkg starter, type DeviceArgs struct, ConfigState *config.State
+pkg starter, type DeviceArgs struct, ListenSpec rpc.ListenSpec
+pkg starter, type DeviceArgs struct, Name string
+pkg starter, type DeviceArgs struct, PairingToken string
+pkg starter, type DeviceArgs struct, RestartCallback func()
+pkg starter, type DeviceArgs struct, TestMode bool
+pkg starter, type NamespaceArgs struct
+pkg starter, type NamespaceArgs struct, ListenSpec rpc.ListenSpec
+pkg starter, type NamespaceArgs struct, Name string
+pkg starter, type NamespaceArgs struct, Neighborhood string
+pkg starter, type NamespaceArgs struct, PermissionsFile string
+pkg starter, type NamespaceArgs struct, PersistenceDir string
+pkg starter, type ProxyArgs struct
+pkg starter, type ProxyArgs struct, Port int
diff --git a/services/device/internal/starter/starter.go b/services/device/internal/starter/starter.go
index a28fe26..654d0df 100644
--- a/services/device/internal/starter/starter.go
+++ b/services/device/internal/starter/starter.go
@@ -14,7 +14,6 @@
 	"strconv"
 	"time"
 
-	"v.io/x/lib/netstate"
 	"v.io/x/ref/profiles/roaming"
 	"v.io/x/ref/services/debug/debuglib"
 	"v.io/x/ref/services/device/internal/config"
@@ -282,17 +281,9 @@
 	protocol, addr := "tcp", net.JoinHostPort("", port)
 	// Attempt to get a publicly accessible address for the proxy to publish
 	// under.
-	var publishAddr string
 	ls := v23.GetListenSpec(ctx)
-	if addrs, err := netstate.GetAccessibleIPs(); err == nil {
-		if ac := ls.AddressChooser; ac != nil {
-			if a, err := ac(protocol, addrs); err == nil && len(a) > 0 {
-				addrs = a
-			}
-		}
-		publishAddr = net.JoinHostPort(addrs[0].Address().String(), port)
-	}
-	shutdown, ep, err := roaming.NewProxy(ctx, protocol, addr, publishAddr)
+	ls.Addrs = rpc.ListenAddrs{{protocol, addr}}
+	shutdown, ep, err := roaming.NewProxy(ctx, ls)
 	if err != nil {
 		return nil, verror.New(errCantCreateProxy, ctx, err)
 	}
diff --git a/services/device/internal/suid/.api b/services/device/internal/suid/.api
new file mode 100644
index 0000000..f18464d
--- /dev/null
+++ b/services/device/internal/suid/.api
@@ -0,0 +1,14 @@
+pkg suid, const PipeToParentFD ideal-int
+pkg suid, const SavedArgs ideal-string
+pkg suid, func Run([]string) error
+pkg suid, method (*WorkParameters) Chown() error
+pkg suid, method (*WorkParameters) Exec() error
+pkg suid, method (*WorkParameters) Kill() error
+pkg suid, method (*WorkParameters) ProcessArguments(*flag.FlagSet, []string) error
+pkg suid, method (*WorkParameters) Remove() error
+pkg suid, type ArgsSavedForTest struct
+pkg suid, type ArgsSavedForTest struct, LogDir string
+pkg suid, type ArgsSavedForTest struct, Run string
+pkg suid, type ArgsSavedForTest struct, Uname string
+pkg suid, type ArgsSavedForTest struct, Workpace string
+pkg suid, type WorkParameters struct
diff --git a/services/device/internal/sysinit/.api b/services/device/internal/sysinit/.api
new file mode 100644
index 0000000..3453948
--- /dev/null
+++ b/services/device/internal/sysinit/.api
@@ -0,0 +1,35 @@
+pkg sysinit, func InitSystem() string
+pkg sysinit, func New(string, *ServiceDescription) InstallSystemInit
+pkg sysinit, method (*DockerService) Install() error
+pkg sysinit, method (*DockerService) Print() error
+pkg sysinit, method (*DockerService) Start() error
+pkg sysinit, method (*DockerService) Stop() error
+pkg sysinit, method (*DockerService) Uninstall() error
+pkg sysinit, method (*ServiceDescription) LoadFrom(string) error
+pkg sysinit, method (*ServiceDescription) SaveTo(string) error
+pkg sysinit, method (*SystemdService) Install() error
+pkg sysinit, method (*SystemdService) Print() error
+pkg sysinit, method (*SystemdService) Start() error
+pkg sysinit, method (*SystemdService) Stop() error
+pkg sysinit, method (*SystemdService) Uninstall() error
+pkg sysinit, method (*UpstartService) Install() error
+pkg sysinit, method (*UpstartService) Print() error
+pkg sysinit, method (*UpstartService) Start() error
+pkg sysinit, method (*UpstartService) Stop() error
+pkg sysinit, method (*UpstartService) Uninstall() error
+pkg sysinit, type DockerService ServiceDescription
+pkg sysinit, type InstallSystemInit interface { Install, Print, Start, Stop, Uninstall }
+pkg sysinit, type InstallSystemInit interface, Install() error
+pkg sysinit, type InstallSystemInit interface, Print() error
+pkg sysinit, type InstallSystemInit interface, Start() error
+pkg sysinit, type InstallSystemInit interface, Stop() error
+pkg sysinit, type InstallSystemInit interface, Uninstall() error
+pkg sysinit, type ServiceDescription struct
+pkg sysinit, type ServiceDescription struct, Binary string
+pkg sysinit, type ServiceDescription struct, Command []string
+pkg sysinit, type ServiceDescription struct, Description string
+pkg sysinit, type ServiceDescription struct, Environment map[string]string
+pkg sysinit, type ServiceDescription struct, Service string
+pkg sysinit, type ServiceDescription struct, User string
+pkg sysinit, type SystemdService ServiceDescription
+pkg sysinit, type UpstartService ServiceDescription
diff --git a/services/device/suidhelper/.api b/services/device/suidhelper/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/device/suidhelper/.api
diff --git a/services/discharger/.api b/services/discharger/.api
new file mode 100644
index 0000000..6cfe4dd
--- /dev/null
+++ b/services/discharger/.api
@@ -0,0 +1,14 @@
+pkg discharger, func DischargerClient(string) DischargerClientStub
+pkg discharger, func DischargerServer(DischargerServerMethods) DischargerServerStub
+pkg discharger, func NewErrNotAThirdPartyCaveat(*context.T, security.Caveat) error
+pkg discharger, type DischargerClientMethods interface { Discharge }
+pkg discharger, type DischargerClientMethods interface, Discharge(*context.T, security.Caveat, security.DischargeImpetus, ...rpc.CallOpt) (security.Discharge, error)
+pkg discharger, type DischargerClientStub interface, Discharge(*context.T, security.Caveat, security.DischargeImpetus, ...rpc.CallOpt) (security.Discharge, error)
+pkg discharger, type DischargerClientStub interface, unexported methods
+pkg discharger, type DischargerServerMethods interface { Discharge }
+pkg discharger, type DischargerServerMethods interface, Discharge(*context.T, rpc.ServerCall, security.Caveat, security.DischargeImpetus) (security.Discharge, error)
+pkg discharger, type DischargerServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg discharger, type DischargerServerStub interface, unexported methods
+pkg discharger, type DischargerServerStubMethods DischargerServerMethods
+pkg discharger, var DischargerDesc rpc.InterfaceDesc
+pkg discharger, var ErrNotAThirdPartyCaveat unknown-type
diff --git a/services/identity/.api b/services/identity/.api
new file mode 100644
index 0000000..b0fa96f
--- /dev/null
+++ b/services/identity/.api
@@ -0,0 +1,28 @@
+pkg identity, const SeekBlessingsRoute unknown-type
+pkg identity, func MacaroonBlesserClient(string) MacaroonBlesserClientStub
+pkg identity, func MacaroonBlesserServer(MacaroonBlesserServerMethods) MacaroonBlesserServerStub
+pkg identity, func OAuthBlesserClient(string) OAuthBlesserClientStub
+pkg identity, func OAuthBlesserServer(OAuthBlesserServerMethods) OAuthBlesserServerStub
+pkg identity, type BlessingRootResponse struct
+pkg identity, type BlessingRootResponse struct, Names []string
+pkg identity, type BlessingRootResponse struct, PublicKey string
+pkg identity, type MacaroonBlesserClientMethods interface { Bless }
+pkg identity, type MacaroonBlesserClientMethods interface, Bless(*context.T, string, ...rpc.CallOpt) (security.Blessings, error)
+pkg identity, type MacaroonBlesserClientStub interface, Bless(*context.T, string, ...rpc.CallOpt) (security.Blessings, error)
+pkg identity, type MacaroonBlesserClientStub interface, unexported methods
+pkg identity, type MacaroonBlesserServerMethods interface { Bless }
+pkg identity, type MacaroonBlesserServerMethods interface, Bless(*context.T, rpc.ServerCall, string) (security.Blessings, error)
+pkg identity, type MacaroonBlesserServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg identity, type MacaroonBlesserServerStub interface, unexported methods
+pkg identity, type MacaroonBlesserServerStubMethods MacaroonBlesserServerMethods
+pkg identity, type OAuthBlesserClientMethods interface { BlessUsingAccessToken }
+pkg identity, type OAuthBlesserClientMethods interface, BlessUsingAccessToken(*context.T, string, ...rpc.CallOpt) (security.Blessings, string, error)
+pkg identity, type OAuthBlesserClientStub interface, BlessUsingAccessToken(*context.T, string, ...rpc.CallOpt) (security.Blessings, string, error)
+pkg identity, type OAuthBlesserClientStub interface, unexported methods
+pkg identity, type OAuthBlesserServerMethods interface { BlessUsingAccessToken }
+pkg identity, type OAuthBlesserServerMethods interface, BlessUsingAccessToken(*context.T, rpc.ServerCall, string) (security.Blessings, string, error)
+pkg identity, type OAuthBlesserServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg identity, type OAuthBlesserServerStub interface, unexported methods
+pkg identity, type OAuthBlesserServerStubMethods OAuthBlesserServerMethods
+pkg identity, var MacaroonBlesserDesc rpc.InterfaceDesc
+pkg identity, var OAuthBlesserDesc rpc.InterfaceDesc
diff --git a/services/identity/identityd/.api b/services/identity/identityd/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/identity/identityd/.api
diff --git a/services/identity/identitylib/.api b/services/identity/identitylib/.api
new file mode 100644
index 0000000..a796d96
--- /dev/null
+++ b/services/identity/identitylib/.api
@@ -0,0 +1 @@
+pkg identitylib, const TestIdentitydCommand ideal-string
diff --git a/services/identity/internal/auditor/.api b/services/identity/internal/auditor/.api
new file mode 100644
index 0000000..fa70f7d
--- /dev/null
+++ b/services/identity/internal/auditor/.api
@@ -0,0 +1,11 @@
+pkg auditor, func NewMockBlessingAuditor() (audit.Auditor, BlessingLogReader)
+pkg auditor, func NewSQLBlessingAuditor(*sql.DB) (audit.Auditor, BlessingLogReader, error)
+pkg auditor, type BlessingEntry struct
+pkg auditor, type BlessingEntry struct, Blessings security.Blessings
+pkg auditor, type BlessingEntry struct, Caveats []security.Caveat
+pkg auditor, type BlessingEntry struct, DecodeError error
+pkg auditor, type BlessingEntry struct, Email string
+pkg auditor, type BlessingEntry struct, RevocationCaveatID string
+pkg auditor, type BlessingEntry struct, Timestamp time.Time
+pkg auditor, type BlessingLogReader interface { Read }
+pkg auditor, type BlessingLogReader interface, Read(string) <-chan BlessingEntry
diff --git a/services/identity/internal/blesser/.api b/services/identity/internal/blesser/.api
new file mode 100644
index 0000000..64ceaf8
--- /dev/null
+++ b/services/identity/internal/blesser/.api
@@ -0,0 +1,9 @@
+pkg blesser, func NewMacaroonBlesserServer([]byte) identity.MacaroonBlesserServerStub
+pkg blesser, func NewOAuthBlesserServer(OAuthBlesserParams) identity.OAuthBlesserServerStub
+pkg blesser, type OAuthBlesserParams struct
+pkg blesser, type OAuthBlesserParams struct, AccessTokenClients []oauth.AccessTokenClient
+pkg blesser, type OAuthBlesserParams struct, BlessingDuration time.Duration
+pkg blesser, type OAuthBlesserParams struct, DischargerLocation string
+pkg blesser, type OAuthBlesserParams struct, EmailClassifier *util.EmailClassifier
+pkg blesser, type OAuthBlesserParams struct, OAuthProvider oauth.OAuthProvider
+pkg blesser, type OAuthBlesserParams struct, RevocationManager revocation.RevocationManager
diff --git a/services/identity/internal/caveats/.api b/services/identity/internal/caveats/.api
new file mode 100644
index 0000000..874b89b
--- /dev/null
+++ b/services/identity/internal/caveats/.api
@@ -0,0 +1,11 @@
+pkg caveats, func NewBrowserCaveatSelector(string, string) CaveatSelector
+pkg caveats, func NewCaveatFactory() CaveatFactory
+pkg caveats, func NewMockCaveatSelector() CaveatSelector
+pkg caveats, type CaveatFactory interface { New }
+pkg caveats, type CaveatFactory interface, New(CaveatInfo) (security.Caveat, error)
+pkg caveats, type CaveatInfo struct
+pkg caveats, type CaveatInfo struct, Args []interface{}
+pkg caveats, type CaveatInfo struct, Type string
+pkg caveats, type CaveatSelector interface { ParseSelections, Render }
+pkg caveats, type CaveatSelector interface, ParseSelections(*http.Request) ([]CaveatInfo, string, string, error)
+pkg caveats, type CaveatSelector interface, Render(string, string, string, http.ResponseWriter, *http.Request) error
diff --git a/services/identity/internal/dischargerlib/.api b/services/identity/internal/dischargerlib/.api
new file mode 100644
index 0000000..bc87a22
--- /dev/null
+++ b/services/identity/internal/dischargerlib/.api
@@ -0,0 +1 @@
+pkg dischargerlib, func NewDischarger() discharger.DischargerServerMethods
diff --git a/services/identity/internal/handlers/.api b/services/identity/internal/handlers/.api
new file mode 100644
index 0000000..d89de83
--- /dev/null
+++ b/services/identity/internal/handlers/.api
@@ -0,0 +1,3 @@
+pkg handlers, method (BlessingRoot) ServeHTTP(http.ResponseWriter, *http.Request)
+pkg handlers, type BlessingRoot struct
+pkg handlers, type BlessingRoot struct, P security.Principal
diff --git a/services/identity/internal/identityd_test/.api b/services/identity/internal/identityd_test/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/identity/internal/identityd_test/.api
diff --git a/services/identity/internal/oauth/.api b/services/identity/internal/oauth/.api
new file mode 100644
index 0000000..ec6cf46
--- /dev/null
+++ b/services/identity/internal/oauth/.api
@@ -0,0 +1,35 @@
+pkg oauth, const ExplicitApproval AuthURLApproval
+pkg oauth, const ListBlessingsRoute ideal-string
+pkg oauth, const MockClient ideal-string
+pkg oauth, const MockEmail ideal-string
+pkg oauth, const ReuseApproval AuthURLApproval
+pkg oauth, const SeekBlessingsRoute ideal-string
+pkg oauth, func ClientIDAndSecretFromJSON(io.Reader) (string, string, error)
+pkg oauth, func ClientIDFromJSON(io.Reader) (string, error)
+pkg oauth, func NewGoogleOAuth(string) (OAuthProvider, error)
+pkg oauth, func NewHandler(HandlerArgs) (http.Handler, error)
+pkg oauth, func NewMockOAuth() OAuthProvider
+pkg oauth, type AccessTokenClient struct
+pkg oauth, type AccessTokenClient struct, ClientID string
+pkg oauth, type AccessTokenClient struct, Name string
+pkg oauth, type AuthURLApproval bool
+pkg oauth, type BlessingMacaroon struct
+pkg oauth, type BlessingMacaroon struct, Caveats []security.Caveat
+pkg oauth, type BlessingMacaroon struct, Creation time.Time
+pkg oauth, type BlessingMacaroon struct, Name string
+pkg oauth, type HandlerArgs struct
+pkg oauth, type HandlerArgs struct, Addr string
+pkg oauth, type HandlerArgs struct, AssetsPrefix string
+pkg oauth, type HandlerArgs struct, BlessingLogReader auditor.BlessingLogReader
+pkg oauth, type HandlerArgs struct, CaveatSelector caveats.CaveatSelector
+pkg oauth, type HandlerArgs struct, DischargerLocation string
+pkg oauth, type HandlerArgs struct, EmailClassifier *util.EmailClassifier
+pkg oauth, type HandlerArgs struct, MacaroonBlessingService string
+pkg oauth, type HandlerArgs struct, MacaroonKey []byte
+pkg oauth, type HandlerArgs struct, OAuthProvider OAuthProvider
+pkg oauth, type HandlerArgs struct, Principal security.Principal
+pkg oauth, type HandlerArgs struct, RevocationManager revocation.RevocationManager
+pkg oauth, type OAuthProvider interface { AuthURL, ExchangeAuthCodeForEmail, GetEmailAndClientName }
+pkg oauth, type OAuthProvider interface, AuthURL(string, string, AuthURLApproval) string
+pkg oauth, type OAuthProvider interface, ExchangeAuthCodeForEmail(string, string) (string, error)
+pkg oauth, type OAuthProvider interface, GetEmailAndClientName(string, []AccessTokenClient) (string, string, error)
diff --git a/services/identity/internal/revocation/.api b/services/identity/internal/revocation/.api
new file mode 100644
index 0000000..c466140
--- /dev/null
+++ b/services/identity/internal/revocation/.api
@@ -0,0 +1,7 @@
+pkg revocation, func NewMockRevocationManager() RevocationManager
+pkg revocation, func NewRevocationManager(*sql.DB) (RevocationManager, error)
+pkg revocation, type RevocationManager interface { GetRevocationTime, NewCaveat, Revoke }
+pkg revocation, type RevocationManager interface, GetRevocationTime(string) *time.Time
+pkg revocation, type RevocationManager interface, NewCaveat(security.PublicKey, string) (security.Caveat, error)
+pkg revocation, type RevocationManager interface, Revoke(string) error
+pkg revocation, var NotRevokedCaveat security.CaveatDescriptor
diff --git a/services/identity/internal/server/.api b/services/identity/internal/server/.api
new file mode 100644
index 0000000..834f7a4
--- /dev/null
+++ b/services/identity/internal/server/.api
@@ -0,0 +1,4 @@
+pkg server, func NewIdentityServer(oauth.OAuthProvider, audit.Auditor, auditor.BlessingLogReader, revocation.RevocationManager, blesser.OAuthBlesserParams, caveats.CaveatSelector, *util.EmailClassifier, string, string) *IdentityServer
+pkg server, method (*IdentityServer) Listen(*context.T, *rpc.ListenSpec, string, string, string) (rpc.Server, []string, string)
+pkg server, method (*IdentityServer) Serve(*context.T, *rpc.ListenSpec, string, string, string)
+pkg server, type IdentityServer struct
diff --git a/services/identity/internal/templates/.api b/services/identity/internal/templates/.api
new file mode 100644
index 0000000..71f1dd1
--- /dev/null
+++ b/services/identity/internal/templates/.api
@@ -0,0 +1,3 @@
+pkg templates, var Home *template.Template
+pkg templates, var ListBlessings *template.Template
+pkg templates, var SelectCaveats *template.Template
diff --git a/services/identity/internal/util/.api b/services/identity/internal/util/.api
new file mode 100644
index 0000000..9de7ccd
--- /dev/null
+++ b/services/identity/internal/util/.api
@@ -0,0 +1,17 @@
+pkg util, func HTTPBadRequest(http.ResponseWriter, *http.Request, error)
+pkg util, func HTTPServerError(http.ResponseWriter, error)
+pkg util, func NewCSRFCop() (*CSRFCop, error)
+pkg util, func NewMacaroon([]byte, []byte) Macaroon
+pkg util, func RootCertificateDetails(security.Blessings) (string, []byte, error)
+pkg util, func WriteCertAndKey(string, time.Duration) (string, string, error)
+pkg util, method (*CSRFCop) MaybeSetCookie(http.ResponseWriter, *http.Request, string) ([]byte, error)
+pkg util, method (*CSRFCop) NewToken(http.ResponseWriter, *http.Request, string, interface{}) (string, error)
+pkg util, method (*CSRFCop) ValidateToken(string, *http.Request, string, interface{}) error
+pkg util, method (*EmailClassifier) Classify(string) string
+pkg util, method (*EmailClassifier) Get() interface{}
+pkg util, method (*EmailClassifier) Set(string) error
+pkg util, method (*EmailClassifier) String() string
+pkg util, method (Macaroon) Decode([]byte) ([]byte, error)
+pkg util, type CSRFCop struct
+pkg util, type EmailClassifier struct
+pkg util, type Macaroon string
diff --git a/services/internal/binarylib/.api b/services/internal/binarylib/.api
new file mode 100644
index 0000000..9322764
--- /dev/null
+++ b/services/internal/binarylib/.api
@@ -0,0 +1,20 @@
+pkg binarylib, const BufferLength ideal-int
+pkg binarylib, const Version ideal-string
+pkg binarylib, const VersionFile ideal-string
+pkg binarylib, func Delete(*context.T, string) error
+pkg binarylib, func Download(*context.T, string) ([]byte, repository.MediaInfo, error)
+pkg binarylib, func DownloadToFile(*context.T, string, string) error
+pkg binarylib, func DownloadUrl(*context.T, string) (string, int64, error)
+pkg binarylib, func NewDispatcher(security.Principal, *state) (rpc.Dispatcher, error)
+pkg binarylib, func NewHTTPRoot(*state) http.FileSystem
+pkg binarylib, func NewState(string, string, int) (*state, error)
+pkg binarylib, func SetupRootDir(string) (string, error)
+pkg binarylib, func Upload(*context.T, string, []byte, repository.MediaInfo) (*security.Signature, error)
+pkg binarylib, func UploadFromDir(*context.T, string, string) (*security.Signature, error)
+pkg binarylib, func UploadFromFile(*context.T, string, string) (*security.Signature, error)
+pkg binarylib, var ErrInProgress unknown-type
+pkg binarylib, var ErrInvalidPart unknown-type
+pkg binarylib, var ErrInvalidParts unknown-type
+pkg binarylib, var ErrNotAuthorized unknown-type
+pkg binarylib, var ErrOperationFailed unknown-type
+pkg binarylib, var MissingPart binary.PartInfo
diff --git a/services/internal/fs/.api b/services/internal/fs/.api
new file mode 100644
index 0000000..995b1d2
--- /dev/null
+++ b/services/internal/fs/.api
@@ -0,0 +1,24 @@
+pkg fs, func NewMemstore(string) (*Memstore, error)
+pkg fs, method (*Memstore) Abort(interface{}) error
+pkg fs, method (*Memstore) BindObject(string) *boundObject
+pkg fs, method (*Memstore) BindTransaction(string) Transaction
+pkg fs, method (*Memstore) BindTransactionRoot(string) Transaction
+pkg fs, method (*Memstore) Commit(interface{}) error
+pkg fs, method (*Memstore) CreateTransaction(interface{}) (string, error)
+pkg fs, method (*Memstore) Lock()
+pkg fs, method (*Memstore) Unlock()
+pkg fs, type Memstore struct
+pkg fs, type Memstore struct, embedded sync.Mutex
+pkg fs, type MemstoreObject interface { Exists, Remove }
+pkg fs, type MemstoreObject interface, Exists(interface{}) (bool, error)
+pkg fs, type MemstoreObject interface, Remove(interface{}) error
+pkg fs, type Transaction interface { Commit, CreateTransaction }
+pkg fs, type Transaction interface, Commit(interface{}) error
+pkg fs, type Transaction interface, CreateTransaction(interface{}) (string, error)
+pkg fs, var ErrAbortWithoutTransaction unknown-type
+pkg fs, var ErrChildrenWithoutLock unknown-type
+pkg fs, var ErrDoubleCommit unknown-type
+pkg fs, var ErrNoRecursiveCreateTransaction unknown-type
+pkg fs, var ErrNotInMemStore unknown-type
+pkg fs, var ErrUnsupportedType unknown-type
+pkg fs, var ErrWithoutTransaction unknown-type
diff --git a/services/internal/logreaderlib/.api b/services/internal/logreaderlib/.api
new file mode 100644
index 0000000..0051687
--- /dev/null
+++ b/services/internal/logreaderlib/.api
@@ -0,0 +1 @@
+pkg logreaderlib, func NewLogFileService(string, string) interface{}
diff --git a/services/internal/multipart/.api b/services/internal/multipart/.api
new file mode 100644
index 0000000..cd0b2b9
--- /dev/null
+++ b/services/internal/multipart/.api
@@ -0,0 +1 @@
+pkg multipart, func NewFile(string, []*os.File) (http.File, error)
diff --git a/services/internal/packages/.api b/services/internal/packages/.api
new file mode 100644
index 0000000..a83774d
--- /dev/null
+++ b/services/internal/packages/.api
@@ -0,0 +1,5 @@
+pkg packages, func CreateZip(string, string) error
+pkg packages, func Install(string, string) error
+pkg packages, func LoadMediaInfo(string) (repository.MediaInfo, error)
+pkg packages, func MediaInfoForFileName(string) repository.MediaInfo
+pkg packages, func SaveMediaInfo(string, repository.MediaInfo) error
diff --git a/services/internal/pathperms/.api b/services/internal/pathperms/.api
new file mode 100644
index 0000000..0ff4ab4
--- /dev/null
+++ b/services/internal/pathperms/.api
@@ -0,0 +1,14 @@
+pkg pathperms, func ComputeVersion(access.Permissions) (string, error)
+pkg pathperms, func NewHierarchicalAuthorizer(string, string, PermsGetter) (security.Authorizer, error)
+pkg pathperms, func NewPathStore(security.Principal) *PathStore
+pkg pathperms, func NilAuthPermissions(*context.T, security.Call) access.Permissions
+pkg pathperms, func PermissionsForBlessings([]string) access.Permissions
+pkg pathperms, func PrefixPatterns([]string) []security.BlessingPattern
+pkg pathperms, method (PathStore) Get(string) (access.Permissions, string, error)
+pkg pathperms, method (PathStore) PermsForPath(string) (access.Permissions, bool, error)
+pkg pathperms, method (PathStore) Set(string, access.Permissions, string) error
+pkg pathperms, method (PathStore) SetShareable(string, access.Permissions, string, bool) error
+pkg pathperms, type PathStore struct
+pkg pathperms, type PermsGetter interface { PermsForPath }
+pkg pathperms, type PermsGetter interface, PermsForPath(string) (access.Permissions, bool, error)
+pkg pathperms, var ErrOperationFailed unknown-type
diff --git a/services/internal/pproflib/.api b/services/internal/pproflib/.api
new file mode 100644
index 0000000..af095d0
--- /dev/null
+++ b/services/internal/pproflib/.api
@@ -0,0 +1,2 @@
+pkg pproflib, func NewPProfService() interface{}
+pkg pproflib, func StartProxy(*context.T, string) (net.Listener, error)
diff --git a/services/internal/servicetest/.api b/services/internal/servicetest/.api
new file mode 100644
index 0000000..74a02ff
--- /dev/null
+++ b/services/internal/servicetest/.api
@@ -0,0 +1,6 @@
+pkg servicetest, const ExpectTimeout time.Duration
+pkg servicetest, func CreateShellAndMountTable(*testing.T, *context.T, security.Principal) (*modules.Shell, func())
+pkg servicetest, func NewServer(*context.T) (rpc.Server, string)
+pkg servicetest, func ReadPID(*testing.T, modules.ExpectSession) int
+pkg servicetest, func RunCommand(*testing.T, *modules.Shell, []string, string, ...string) modules.Handle
+pkg servicetest, func SetupRootDir(*testing.T, string) (string, func())
diff --git a/services/internal/servicetest/modules.go b/services/internal/servicetest/modules.go
index 13b14a0..6cc9400 100644
--- a/services/internal/servicetest/modules.go
+++ b/services/internal/servicetest/modules.go
@@ -101,12 +101,8 @@
 	// The shell, will, by default share credentials with its children.
 	sh.ClearVar(envvar.Credentials)
 
-	mtName, mtHandle := startRootMT(t, sh)
+	mtName, _ := startRootMT(t, sh)
 	vlog.VI(1).Infof("Started shell mounttable with name %v", mtName)
-	// Make sure the root mount table is the last process to be shutdown
-	// since the others will likely want to communicate with it during
-	// their shutdown process
-	sh.Forget(mtHandle)
 
 	// TODO(caprita): Define a GetNamespaceRootsCommand in modules/core and
 	// use that?
@@ -117,15 +113,9 @@
 		vlog.VI(1).Info("---------------------------------")
 		vlog.VI(1).Info("--(cleaning up shell)------------")
 		if err := sh.Cleanup(os.Stdout, os.Stderr); err != nil {
-			t.Fatalf(testutil.FormatLogLine(2, "sh.Cleanup failed with %v", err))
+			t.Errorf(testutil.FormatLogLine(2, "sh.Cleanup failed with %v", err))
 		}
 		vlog.VI(1).Info("--(done cleaning up shell)-------")
-		vlog.VI(1).Info("--(shutting down root mt)--------")
-		if err := mtHandle.Shutdown(os.Stdout, os.Stderr); err != nil {
-			t.Fatalf(testutil.FormatLogLine(2, "mtHandle.Shutdown failed with %v", err))
-		}
-		vlog.VI(1).Info("--(done shutting down root mt)---")
-		vlog.VI(1).Info("--------- DONE CLEANUP ----------")
 		setNSRoots(t, ctx, oldNamespaceRoots...)
 	}
 	setNSRoots(t, ctx, mtName)
diff --git a/services/internal/statslib/.api b/services/internal/statslib/.api
new file mode 100644
index 0000000..b898564
--- /dev/null
+++ b/services/internal/statslib/.api
@@ -0,0 +1 @@
+pkg statslib, func NewStatsService(string, time.Duration) interface{}
diff --git a/services/internal/vtracelib/.api b/services/internal/vtracelib/.api
new file mode 100644
index 0000000..75fd45e
--- /dev/null
+++ b/services/internal/vtracelib/.api
@@ -0,0 +1 @@
+pkg vtracelib, func NewVtraceService() interface{}
diff --git a/services/mounttable/mounttabled/.api b/services/mounttable/mounttabled/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/mounttable/mounttabled/.api
diff --git a/services/mounttable/mounttablelib/.api b/services/mounttable/mounttablelib/.api
new file mode 100644
index 0000000..79958f0
--- /dev/null
+++ b/services/mounttable/mounttablelib/.api
@@ -0,0 +1,28 @@
+pkg mounttablelib, func CollectionClient(string) CollectionClientStub
+pkg mounttablelib, func CollectionServer(CollectionServerMethods) CollectionServerStub
+pkg mounttablelib, func NewLoopbackNeighborhoodDispatcher(string, ...string) (rpc.Dispatcher, error)
+pkg mounttablelib, func NewMountTableDispatcher(string, string, string) (rpc.Dispatcher, error)
+pkg mounttablelib, func NewNeighborhoodDispatcher(string, ...string) (rpc.Dispatcher, error)
+pkg mounttablelib, func NewVersionedPermissions() *VersionedPermissions
+pkg mounttablelib, func StartServers(*context.T, rpc.ListenSpec, string, string, string, string, string) (string, func(), error)
+pkg mounttablelib, method (*VersionedPermissions) AccessListForTag(string) (access.AccessList, bool)
+pkg mounttablelib, method (*VersionedPermissions) Add(security.BlessingPattern, string)
+pkg mounttablelib, method (*VersionedPermissions) Copy() *VersionedPermissions
+pkg mounttablelib, method (*VersionedPermissions) Get() (string, access.Permissions)
+pkg mounttablelib, method (*VersionedPermissions) Set(*context.T, string, access.Permissions) (*VersionedPermissions, error)
+pkg mounttablelib, type CollectionClientMethods interface { Export, Lookup }
+pkg mounttablelib, type CollectionClientMethods interface, Export(*context.T, string, bool, ...rpc.CallOpt) error
+pkg mounttablelib, type CollectionClientMethods interface, Lookup(*context.T, ...rpc.CallOpt) ([]byte, error)
+pkg mounttablelib, type CollectionClientStub interface, Export(*context.T, string, bool, ...rpc.CallOpt) error
+pkg mounttablelib, type CollectionClientStub interface, Lookup(*context.T, ...rpc.CallOpt) ([]byte, error)
+pkg mounttablelib, type CollectionClientStub interface, unexported methods
+pkg mounttablelib, type CollectionServerMethods interface { Export, Lookup }
+pkg mounttablelib, type CollectionServerMethods interface, Export(*context.T, rpc.ServerCall, string, bool) error
+pkg mounttablelib, type CollectionServerMethods interface, Lookup(*context.T, rpc.ServerCall) ([]byte, error)
+pkg mounttablelib, type CollectionServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg mounttablelib, type CollectionServerStub interface, unexported methods
+pkg mounttablelib, type CollectionServerStubMethods CollectionServerMethods
+pkg mounttablelib, type VersionedPermissions struct
+pkg mounttablelib, type VersionedPermissions struct, P access.Permissions
+pkg mounttablelib, type VersionedPermissions struct, V int32
+pkg mounttablelib, var CollectionDesc rpc.InterfaceDesc
diff --git a/services/profile/.api b/services/profile/.api
new file mode 100644
index 0000000..6d995aa
--- /dev/null
+++ b/services/profile/.api
@@ -0,0 +1,11 @@
+pkg profile, type Library struct
+pkg profile, type Library struct, MajorVersion string
+pkg profile, type Library struct, MinorVersion string
+pkg profile, type Library struct, Name string
+pkg profile, type Specification struct
+pkg profile, type Specification struct, Arch build.Architecture
+pkg profile, type Specification struct, Description string
+pkg profile, type Specification struct, Format build.Format
+pkg profile, type Specification struct, Label string
+pkg profile, type Specification struct, Libraries map[Library]struct{}
+pkg profile, type Specification struct, Os build.OperatingSystem
diff --git a/services/profile/profile/.api b/services/profile/profile/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/profile/profile/.api
diff --git a/services/profile/profile/doc.go b/services/profile/profile/doc.go
index 0b5995c..3fee387 100644
--- a/services/profile/profile/doc.go
+++ b/services/profile/profile/doc.go
@@ -18,7 +18,6 @@
    put           Sets a placeholder specification for the profile.
    remove        removes the profile specification for the profile.
    help          Display help for commands or topics
-Run "profile help [command]" for command usage.
 
 The global flags are:
  -alsologtostderr=true
@@ -60,7 +59,7 @@
  -vmodule=
    comma-separated list of pattern=N settings for file-filtered logging
 
-Profile Label
+Profile label
 
 Shows a human-readable profile key for the profile.
 
@@ -69,7 +68,7 @@
 
 <profile> is the full name of the profile.
 
-Profile Description
+Profile description
 
 Shows a human-readable profile description for the profile.
 
@@ -78,7 +77,7 @@
 
 <profile> is the full name of the profile.
 
-Profile Specification
+Profile specification
 
 Shows the specification of the profile.
 
@@ -87,7 +86,7 @@
 
 <profile> is the full name of the profile.
 
-Profile Put
+Profile put
 
 Sets a placeholder specification for the profile.
 
@@ -96,7 +95,7 @@
 
 <profile> is the full name of the profile.
 
-Profile Remove
+Profile remove
 
 removes the profile specification for the profile.
 
@@ -105,7 +104,7 @@
 
 <profile> is the full name of the profile.
 
-Profile Help
+Profile help
 
 Help with no args displays the usage of the parent command.
 
@@ -113,11 +112,10 @@
 
 "help ..." recursively displays help for all commands and topics.
 
-The output is formatted to a target width in runes.  The target width is
-determined by checking the environment variable CMDLINE_WIDTH, falling back on
-the terminal width from the OS, falling back on 80 chars.  By setting
-CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0 the width is unlimited, and
-if x == 0 or is unset one of the fallbacks is used.
+Output is formatted to a target width in runes, determined by checking the
+CMDLINE_WIDTH environment variable, falling back on the terminal width, falling
+back on 80 chars.  By setting CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0
+the width is unlimited, and if x == 0 or is unset one of the fallbacks is used.
 
 Usage:
    profile help [flags] [command/topic ...]
@@ -125,7 +123,11 @@
 [command/topic ...] optionally identifies a specific sub-command or help topic.
 
 The profile help flags are:
- -style=default
-   The formatting style for help output, either "default" or "godoc".
+ -style=compact
+   The formatting style for help output:
+      compact - Good for compact cmdline output.
+      full    - Good for cmdline output, shows all global flags.
+      godoc   - Good for godoc processing.
+   Override the default by setting the CMDLINE_STYLE environment variable.
 */
 package main
diff --git a/services/profile/profile/impl.go b/services/profile/profile/impl.go
index 1b6bbc0..1bed93e 100644
--- a/services/profile/profile/impl.go
+++ b/services/profile/profile/impl.go
@@ -10,12 +10,15 @@
 
 	"v.io/v23/context"
 	"v.io/v23/services/build"
-
 	"v.io/x/lib/cmdline"
 	"v.io/x/ref/services/profile"
 	"v.io/x/ref/services/repository"
 )
 
+func init() {
+	cmdline.HideGlobalFlagsExcept()
+}
+
 var cmdLabel = &cmdline.Command{
 	Run:      runLabel,
 	Name:     "label",
diff --git a/services/profile/profiled/.api b/services/profile/profiled/.api
new file mode 100644
index 0000000..4c50ab7
--- /dev/null
+++ b/services/profile/profiled/.api
@@ -0,0 +1,2 @@
+pkg main, func NewDispatcher(string, security.Authorizer) (rpc.Dispatcher, error)
+pkg main, func NewProfileService(*fs.Memstore, string, string) repository.ProfileServerMethods
diff --git a/services/proxy/proxyd/.api b/services/proxy/proxyd/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/proxy/proxyd/.api
diff --git a/services/proxy/proxyd/main.go b/services/proxy/proxyd/main.go
index c454b68..d9114eb 100644
--- a/services/proxy/proxyd/main.go
+++ b/services/proxy/proxyd/main.go
@@ -23,7 +23,7 @@
 )
 
 var (
-	pubAddress  = flag.String("published-address", "", "Network address the proxy publishes. If empty, the value of --address will be used")
+	pubAddress  = flag.String("published-address", "", "deprecated - the proxy now uses listenspecs and the address chooser mechanism")
 	healthzAddr = flag.String("healthz-address", "", "Network address on which the HTTP healthz server runs. It is intended to be used with a load balancer. The load balancer must be able to reach this address in order to verify that the proxy server is running")
 	name        = flag.String("name", "", "Name to mount the proxy as")
 )
@@ -39,7 +39,7 @@
 	if listenSpec.Proxy != "" {
 		vlog.Fatalf("proxyd cannot listen through another proxy")
 	}
-	proxyShutdown, proxyEndpoint, err := static.NewProxy(ctx, listenSpec.Addrs[0].Protocol, listenSpec.Addrs[0].Address, *pubAddress, *name)
+	proxyShutdown, proxyEndpoint, err := static.NewProxy(ctx, listenSpec, *name)
 	if err != nil {
 		vlog.Fatal(err)
 	}
@@ -49,6 +49,8 @@
 		// Print out a directly accessible name for the proxy table so
 		// that integration tests can reliably read it from stdout.
 		fmt.Printf("NAME=%s\n", proxyEndpoint.Name())
+	} else {
+		fmt.Printf("Proxy listening on %s\n", proxyEndpoint)
 	}
 
 	if len(*healthzAddr) != 0 {
diff --git a/services/repository/.api b/services/repository/.api
new file mode 100644
index 0000000..4ca1e1f
--- /dev/null
+++ b/services/repository/.api
@@ -0,0 +1,33 @@
+pkg repository, func ApplicationClient(string) ApplicationClientStub
+pkg repository, func ApplicationServer(ApplicationServerMethods) ApplicationServerStub
+pkg repository, func ProfileClient(string) ProfileClientStub
+pkg repository, func ProfileServer(ProfileServerMethods) ProfileServerStub
+pkg repository, type ApplicationClientMethods interface, Put(*context.T, []string, application.Envelope, ...rpc.CallOpt) error
+pkg repository, type ApplicationClientMethods interface, Remove(*context.T, string, ...rpc.CallOpt) error
+pkg repository, type ApplicationClientMethods interface, unexported methods
+pkg repository, type ApplicationClientStub interface, Put(*context.T, []string, application.Envelope, ...rpc.CallOpt) error
+pkg repository, type ApplicationClientStub interface, Remove(*context.T, string, ...rpc.CallOpt) error
+pkg repository, type ApplicationClientStub interface, unexported methods
+pkg repository, type ApplicationServerMethods interface, Put(*context.T, rpc.ServerCall, []string, application.Envelope) error
+pkg repository, type ApplicationServerMethods interface, Remove(*context.T, rpc.ServerCall, string) error
+pkg repository, type ApplicationServerMethods interface, unexported methods
+pkg repository, type ApplicationServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg repository, type ApplicationServerStub interface, unexported methods
+pkg repository, type ApplicationServerStubMethods ApplicationServerMethods
+pkg repository, type ProfileClientMethods interface, Put(*context.T, profile.Specification, ...rpc.CallOpt) error
+pkg repository, type ProfileClientMethods interface, Remove(*context.T, ...rpc.CallOpt) error
+pkg repository, type ProfileClientMethods interface, Specification(*context.T, ...rpc.CallOpt) (profile.Specification, error)
+pkg repository, type ProfileClientMethods interface, unexported methods
+pkg repository, type ProfileClientStub interface, Put(*context.T, profile.Specification, ...rpc.CallOpt) error
+pkg repository, type ProfileClientStub interface, Remove(*context.T, ...rpc.CallOpt) error
+pkg repository, type ProfileClientStub interface, Specification(*context.T, ...rpc.CallOpt) (profile.Specification, error)
+pkg repository, type ProfileClientStub interface, unexported methods
+pkg repository, type ProfileServerMethods interface, Put(*context.T, rpc.ServerCall, profile.Specification) error
+pkg repository, type ProfileServerMethods interface, Remove(*context.T, rpc.ServerCall) error
+pkg repository, type ProfileServerMethods interface, Specification(*context.T, rpc.ServerCall) (profile.Specification, error)
+pkg repository, type ProfileServerMethods interface, unexported methods
+pkg repository, type ProfileServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg repository, type ProfileServerStub interface, unexported methods
+pkg repository, type ProfileServerStubMethods ProfileServerMethods
+pkg repository, var ApplicationDesc rpc.InterfaceDesc
+pkg repository, var ProfileDesc rpc.InterfaceDesc
diff --git a/services/role/.api b/services/role/.api
new file mode 100644
index 0000000..fb230c1
--- /dev/null
+++ b/services/role/.api
@@ -0,0 +1,13 @@
+pkg role, const RoleSuffix ideal-string
+pkg role, func RoleClient(string) RoleClientStub
+pkg role, func RoleServer(RoleServerMethods) RoleServerStub
+pkg role, type RoleClientMethods interface { SeekBlessings }
+pkg role, type RoleClientMethods interface, SeekBlessings(*context.T, ...rpc.CallOpt) (security.Blessings, error)
+pkg role, type RoleClientStub interface, SeekBlessings(*context.T, ...rpc.CallOpt) (security.Blessings, error)
+pkg role, type RoleClientStub interface, unexported methods
+pkg role, type RoleServerMethods interface { SeekBlessings }
+pkg role, type RoleServerMethods interface, SeekBlessings(*context.T, rpc.ServerCall) (security.Blessings, error)
+pkg role, type RoleServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg role, type RoleServerStub interface, unexported methods
+pkg role, type RoleServerStubMethods RoleServerMethods
+pkg role, var RoleDesc rpc.InterfaceDesc
diff --git a/services/role/roled/.api b/services/role/roled/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/role/roled/.api
diff --git a/services/role/roled/internal/.api b/services/role/roled/internal/.api
new file mode 100644
index 0000000..43a97bb
--- /dev/null
+++ b/services/role/roled/internal/.api
@@ -0,0 +1,9 @@
+pkg internal, func NewDispatcher(string, string) rpc.Dispatcher
+pkg internal, type Config struct
+pkg internal, type Config struct, Audit bool
+pkg internal, type Config struct, Expiry string
+pkg internal, type Config struct, Extend bool
+pkg internal, type Config struct, ImportMembers []string
+pkg internal, type Config struct, Members []security.BlessingPattern
+pkg internal, type Config struct, Peers []security.BlessingPattern
+pkg internal, var LoggingCaveat security.CaveatDescriptor
diff --git a/services/stats/.api b/services/stats/.api
new file mode 100644
index 0000000..fd8288f
--- /dev/null
+++ b/services/stats/.api
@@ -0,0 +1,11 @@
+pkg stats, method (HistogramValue) Print(io.Writer)
+pkg stats, method (HistogramValue) String() string
+pkg stats, type HistogramBucket struct
+pkg stats, type HistogramBucket struct, Count int64
+pkg stats, type HistogramBucket struct, LowBound int64
+pkg stats, type HistogramValue struct
+pkg stats, type HistogramValue struct, Buckets []HistogramBucket
+pkg stats, type HistogramValue struct, Count int64
+pkg stats, type HistogramValue struct, Max int64
+pkg stats, type HistogramValue struct, Min int64
+pkg stats, type HistogramValue struct, Sum int64
diff --git a/services/wspr/browsprd/.api b/services/wspr/browsprd/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/wspr/browsprd/.api
diff --git a/services/wspr/internal/account/.api b/services/wspr/internal/account/.api
new file mode 100644
index 0000000..4f8af00
--- /dev/null
+++ b/services/wspr/internal/account/.api
@@ -0,0 +1,14 @@
+pkg account, func NewAccountManager(string, *principal.PrincipalManager) *AccountManager
+pkg account, method (*AccountManager) AssociateAccount(string, string, []Caveat) error
+pkg account, method (*AccountManager) CreateAccount(*context.T, string) (string, error)
+pkg account, method (*AccountManager) GetAccounts() []string
+pkg account, method (*AccountManager) LookupPrincipal(string) (security.Principal, error)
+pkg account, method (*AccountManager) OriginHasAccount(string) bool
+pkg account, method (*AccountManager) PrincipalManager() *principal.PrincipalManager
+pkg account, method (*AccountManager) SetMockBlesser(BlesserService)
+pkg account, type AccountManager struct
+pkg account, type BlesserService interface { BlessUsingAccessToken }
+pkg account, type BlesserService interface, BlessUsingAccessToken(*context.T, string, ...rpc.CallOpt) (security.Blessings, string, error)
+pkg account, type Caveat struct
+pkg account, type Caveat struct, Args string
+pkg account, type Caveat struct, Type string
diff --git a/services/wspr/internal/app/.api b/services/wspr/internal/app/.api
new file mode 100644
index 0000000..703e6ac
--- /dev/null
+++ b/services/wspr/internal/app/.api
@@ -0,0 +1,141 @@
+pkg app, const AddName ideal-int
+pkg app, const AuthResponseMessage ideal-int
+pkg app, const CancelMessage ideal-int
+pkg app, const CaveatValidationResponse ideal-int
+pkg app, const GranterResponseMessage ideal-int
+pkg app, const LookupResponseMessage ideal-int
+pkg app, const NamespaceRequestMessage ideal-int
+pkg app, const RemoteBlessings ideal-int
+pkg app, const RemoveName ideal-int
+pkg app, const ServeMessage ideal-int
+pkg app, const ServerResponseMessage ideal-int
+pkg app, const SignatureRequestMessage ideal-int
+pkg app, const StopServerMessage ideal-int
+pkg app, const StreamCloseMessage ideal-int
+pkg app, const StreamingValueMessage ideal-int
+pkg app, const UnlinkBlessingsMessage ideal-int
+pkg app, const VeyronRequestMessage MessageType
+pkg app, func ConstructOutgoingMessage(int32, lib.ResponseType, interface{}) (string, error)
+pkg app, func ControllerClient(string) ControllerClientStub
+pkg app, func ControllerServer(ControllerServerMethods) ControllerServerStub
+pkg app, func FormatAsVerror(error) error
+pkg app, func NewController(*context.T, func(int32) lib.ClientWriter, *rpc.ListenSpec, []string, security.Principal) (*Controller, error)
+pkg app, method (*Controller) AddName(*context.T, rpc.ServerCall, uint32, string) error
+pkg app, method (*Controller) AddToRoots(*context.T, rpc.ServerCall, principal.BlessingsHandle) error
+pkg app, method (*Controller) Bless(*context.T, rpc.ServerCall, string, principal.BlessingsHandle, string, []security.Caveat) (string, principal.BlessingsHandle, error)
+pkg app, method (*Controller) BlessSelf(*context.T, rpc.ServerCall, string, []security.Caveat) (string, principal.BlessingsHandle, error)
+pkg app, method (*Controller) Cleanup()
+pkg app, method (*Controller) CleanupFlow(int32)
+pkg app, method (*Controller) CloseStream(int32)
+pkg app, method (*Controller) Context() *context.T
+pkg app, method (*Controller) CreateNewFlow(interface{}, rpc.Stream) *server.Flow
+pkg app, method (*Controller) GetBlessings(principal.BlessingsHandle) security.Blessings
+pkg app, method (*Controller) GetDefaultBlessings(*context.T, rpc.ServerCall) (*principal.JsBlessings, error)
+pkg app, method (*Controller) GetOrAddBlessingsHandle(security.Blessings) principal.BlessingsHandle
+pkg app, method (*Controller) HandleAuthResponse(int32, string)
+pkg app, method (*Controller) HandleCaveatValidationResponse(int32, string)
+pkg app, method (*Controller) HandleGranterResponse(int32, string)
+pkg app, method (*Controller) HandleIncomingMessage(Message, lib.ClientWriter)
+pkg app, method (*Controller) HandleLookupResponse(int32, string)
+pkg app, method (*Controller) HandleServerResponse(int32, string)
+pkg app, method (*Controller) HandleVeyronCancellation(int32)
+pkg app, method (*Controller) HandleVeyronRequest(*context.T, int32, string, lib.ClientWriter)
+pkg app, method (*Controller) PutToBlessingStore(*context.T, rpc.ServerCall, principal.BlessingsHandle, security.BlessingPattern) (*principal.JsBlessings, error)
+pkg app, method (*Controller) RemoteBlessings(*context.T, rpc.ServerCall, string, string) ([]string, error)
+pkg app, method (*Controller) RemoveName(*context.T, rpc.ServerCall, uint32, string) error
+pkg app, method (*Controller) SendLogMessage(lib.LogLevel, string) error
+pkg app, method (*Controller) SendOnStream(int32, string, lib.ClientWriter)
+pkg app, method (*Controller) Serve(*context.T, rpc.ServerCall, string, uint32) error
+pkg app, method (*Controller) Signature(*context.T, rpc.ServerCall, string) ([]signature.Interface, error)
+pkg app, method (*Controller) Stop(*context.T, rpc.ServerCall, uint32) error
+pkg app, method (*Controller) UnlinkBlessings(*context.T, rpc.ServerCall, principal.BlessingsHandle) error
+pkg app, method (RpcCallOptionAllowedServersPolicy) Index() int
+pkg app, method (RpcCallOptionAllowedServersPolicy) Interface() interface{}
+pkg app, method (RpcCallOptionAllowedServersPolicy) Name() string
+pkg app, method (RpcCallOptionRetryTimeout) Index() int
+pkg app, method (RpcCallOptionRetryTimeout) Interface() interface{}
+pkg app, method (RpcCallOptionRetryTimeout) Name() string
+pkg app, method (RpcCallOptionUseGranter) Index() int
+pkg app, method (RpcCallOptionUseGranter) Interface() interface{}
+pkg app, method (RpcCallOptionUseGranter) Name() string
+pkg app, type Closer interface { CloseSend }
+pkg app, type Closer interface, CloseSend() error
+pkg app, type Controller struct
+pkg app, type Controller struct, embedded sync.Mutex
+pkg app, type ControllerClientMethods interface { AddName, AddToRoots, Bless, BlessSelf, GetDefaultBlessings, PutToBlessingStore, RemoteBlessings, RemoveName, Serve, Signature, Stop, UnlinkBlessings }
+pkg app, type ControllerClientMethods interface, AddName(*context.T, uint32, string, ...rpc.CallOpt) error
+pkg app, type ControllerClientMethods interface, AddToRoots(*context.T, principal.BlessingsHandle, ...rpc.CallOpt) error
+pkg app, type ControllerClientMethods interface, Bless(*context.T, string, principal.BlessingsHandle, string, []security.Caveat, ...rpc.CallOpt) (string, principal.BlessingsHandle, error)
+pkg app, type ControllerClientMethods interface, BlessSelf(*context.T, string, []security.Caveat, ...rpc.CallOpt) (string, principal.BlessingsHandle, error)
+pkg app, type ControllerClientMethods interface, GetDefaultBlessings(*context.T, ...rpc.CallOpt) (*principal.JsBlessings, error)
+pkg app, type ControllerClientMethods interface, PutToBlessingStore(*context.T, principal.BlessingsHandle, security.BlessingPattern, ...rpc.CallOpt) (*principal.JsBlessings, error)
+pkg app, type ControllerClientMethods interface, RemoteBlessings(*context.T, string, string, ...rpc.CallOpt) ([]string, error)
+pkg app, type ControllerClientMethods interface, RemoveName(*context.T, uint32, string, ...rpc.CallOpt) error
+pkg app, type ControllerClientMethods interface, Serve(*context.T, string, uint32, ...rpc.CallOpt) error
+pkg app, type ControllerClientMethods interface, Signature(*context.T, string, ...rpc.CallOpt) ([]signature.Interface, error)
+pkg app, type ControllerClientMethods interface, Stop(*context.T, uint32, ...rpc.CallOpt) error
+pkg app, type ControllerClientMethods interface, UnlinkBlessings(*context.T, principal.BlessingsHandle, ...rpc.CallOpt) error
+pkg app, type ControllerClientStub interface, AddName(*context.T, uint32, string, ...rpc.CallOpt) error
+pkg app, type ControllerClientStub interface, AddToRoots(*context.T, principal.BlessingsHandle, ...rpc.CallOpt) error
+pkg app, type ControllerClientStub interface, Bless(*context.T, string, principal.BlessingsHandle, string, []security.Caveat, ...rpc.CallOpt) (string, principal.BlessingsHandle, error)
+pkg app, type ControllerClientStub interface, BlessSelf(*context.T, string, []security.Caveat, ...rpc.CallOpt) (string, principal.BlessingsHandle, error)
+pkg app, type ControllerClientStub interface, GetDefaultBlessings(*context.T, ...rpc.CallOpt) (*principal.JsBlessings, error)
+pkg app, type ControllerClientStub interface, PutToBlessingStore(*context.T, principal.BlessingsHandle, security.BlessingPattern, ...rpc.CallOpt) (*principal.JsBlessings, error)
+pkg app, type ControllerClientStub interface, RemoteBlessings(*context.T, string, string, ...rpc.CallOpt) ([]string, error)
+pkg app, type ControllerClientStub interface, RemoveName(*context.T, uint32, string, ...rpc.CallOpt) error
+pkg app, type ControllerClientStub interface, Serve(*context.T, string, uint32, ...rpc.CallOpt) error
+pkg app, type ControllerClientStub interface, Signature(*context.T, string, ...rpc.CallOpt) ([]signature.Interface, error)
+pkg app, type ControllerClientStub interface, Stop(*context.T, uint32, ...rpc.CallOpt) error
+pkg app, type ControllerClientStub interface, UnlinkBlessings(*context.T, principal.BlessingsHandle, ...rpc.CallOpt) error
+pkg app, type ControllerClientStub interface, unexported methods
+pkg app, type ControllerServerMethods interface { AddName, AddToRoots, Bless, BlessSelf, GetDefaultBlessings, PutToBlessingStore, RemoteBlessings, RemoveName, Serve, Signature, Stop, UnlinkBlessings }
+pkg app, type ControllerServerMethods interface, AddName(*context.T, rpc.ServerCall, uint32, string) error
+pkg app, type ControllerServerMethods interface, AddToRoots(*context.T, rpc.ServerCall, principal.BlessingsHandle) error
+pkg app, type ControllerServerMethods interface, Bless(*context.T, rpc.ServerCall, string, principal.BlessingsHandle, string, []security.Caveat) (string, principal.BlessingsHandle, error)
+pkg app, type ControllerServerMethods interface, BlessSelf(*context.T, rpc.ServerCall, string, []security.Caveat) (string, principal.BlessingsHandle, error)
+pkg app, type ControllerServerMethods interface, GetDefaultBlessings(*context.T, rpc.ServerCall) (*principal.JsBlessings, error)
+pkg app, type ControllerServerMethods interface, PutToBlessingStore(*context.T, rpc.ServerCall, principal.BlessingsHandle, security.BlessingPattern) (*principal.JsBlessings, error)
+pkg app, type ControllerServerMethods interface, RemoteBlessings(*context.T, rpc.ServerCall, string, string) ([]string, error)
+pkg app, type ControllerServerMethods interface, RemoveName(*context.T, rpc.ServerCall, uint32, string) error
+pkg app, type ControllerServerMethods interface, Serve(*context.T, rpc.ServerCall, string, uint32) error
+pkg app, type ControllerServerMethods interface, Signature(*context.T, rpc.ServerCall, string) ([]signature.Interface, error)
+pkg app, type ControllerServerMethods interface, Stop(*context.T, rpc.ServerCall, uint32) error
+pkg app, type ControllerServerMethods interface, UnlinkBlessings(*context.T, rpc.ServerCall, principal.BlessingsHandle) error
+pkg app, type ControllerServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg app, type ControllerServerStub interface, unexported methods
+pkg app, type ControllerServerStubMethods ControllerServerMethods
+pkg app, type GranterHandle int32
+pkg app, type GranterRequest struct
+pkg app, type GranterRequest struct, Call server.SecurityCall
+pkg app, type GranterRequest struct, GranterHandle GranterHandle
+pkg app, type GranterResponse struct
+pkg app, type GranterResponse struct, Blessings principal.BlessingsHandle
+pkg app, type GranterResponse struct, Err error
+pkg app, type Message struct
+pkg app, type Message struct, Data string
+pkg app, type Message struct, Id int32
+pkg app, type Message struct, Type MessageType
+pkg app, type MessageType int32
+pkg app, type RpcCallOption interface, Index() int
+pkg app, type RpcCallOption interface, Interface() interface{}
+pkg app, type RpcCallOption interface, Name() string
+pkg app, type RpcCallOption interface, unexported methods
+pkg app, type RpcCallOptionAllowedServersPolicy struct
+pkg app, type RpcCallOptionAllowedServersPolicy struct, Value []security.BlessingPattern
+pkg app, type RpcCallOptionRetryTimeout struct
+pkg app, type RpcCallOptionRetryTimeout struct, Value time.Duration
+pkg app, type RpcCallOptionUseGranter struct
+pkg app, type RpcCallOptionUseGranter struct, Value GranterHandle
+pkg app, type RpcRequest struct
+pkg app, type RpcRequest struct, CallOptions []RpcCallOption
+pkg app, type RpcRequest struct, Deadline time_2.Deadline
+pkg app, type RpcRequest struct, IsStreaming bool
+pkg app, type RpcRequest struct, Method string
+pkg app, type RpcRequest struct, Name string
+pkg app, type RpcRequest struct, NumInArgs int32
+pkg app, type RpcRequest struct, NumOutArgs int32
+pkg app, type RpcRequest struct, TraceRequest vtrace.Request
+pkg app, type RpcResponse struct
+pkg app, type RpcResponse struct, OutArgs []*vdl.Value
+pkg app, type RpcResponse struct, TraceResponse vtrace.Response
+pkg app, var ControllerDesc rpc.InterfaceDesc
diff --git a/services/wspr/internal/app/app_test.go b/services/wspr/internal/app/app_test.go
index aca197c..6e14735 100644
--- a/services/wspr/internal/app/app_test.go
+++ b/services/wspr/internal/app/app_test.go
@@ -315,8 +315,8 @@
 	if err != nil {
 		return nil, fmt.Errorf("unable to start mounttable: %v", err)
 	}
-
-	proxyShutdown, proxyEndpoint, err := profiles.NewProxy(ctx, "tcp", "127.0.0.1:0", "")
+	proxySpec := rpc.ListenSpec{Addrs: rpc.ListenAddrs{{"tcp", "127.0.0.1:0"}}}
+	proxyShutdown, proxyEndpoint, err := profiles.NewProxy(ctx, proxySpec)
 	if err != nil {
 		return nil, fmt.Errorf("unable to start proxy: %v", err)
 	}
diff --git a/services/wspr/internal/browspr/.api b/services/wspr/internal/browspr/.api
new file mode 100644
index 0000000..abbd96f
--- /dev/null
+++ b/services/wspr/internal/browspr/.api
@@ -0,0 +1,33 @@
+pkg browspr, func NewBrowspr(*context.T, func(int32, string, string), *rpc.ListenSpec, string, []string) *Browspr
+pkg browspr, method (*Browspr) HandleAuthAssociateAccountRpc(*vdl.Value) (*vdl.Value, error)
+pkg browspr, method (*Browspr) HandleAuthCreateAccountRpc(*vdl.Value) (*vdl.Value, error)
+pkg browspr, method (*Browspr) HandleAuthGetAccountsRpc(*vdl.Value) (*vdl.Value, error)
+pkg browspr, method (*Browspr) HandleAuthOriginHasAccountRpc(*vdl.Value) (*vdl.Value, error)
+pkg browspr, method (*Browspr) HandleCleanupRpc(*vdl.Value) (*vdl.Value, error)
+pkg browspr, method (*Browspr) HandleCreateInstanceRpc(*vdl.Value) (*vdl.Value, error)
+pkg browspr, method (*Browspr) HandleMessage(int32, string, string) error
+pkg browspr, method (*Browspr) Shutdown()
+pkg browspr, type AssociateAccountMessage struct
+pkg browspr, type AssociateAccountMessage struct, Account string
+pkg browspr, type AssociateAccountMessage struct, Caveats []account.Caveat
+pkg browspr, type AssociateAccountMessage struct, Origin string
+pkg browspr, type Browspr struct
+pkg browspr, type CleanupMessage struct
+pkg browspr, type CleanupMessage struct, InstanceId int32
+pkg browspr, type CreateAccountMessage struct
+pkg browspr, type CreateAccountMessage struct, Token string
+pkg browspr, type CreateInstanceMessage struct
+pkg browspr, type CreateInstanceMessage struct, InstanceId int32
+pkg browspr, type CreateInstanceMessage struct, NamespaceRoots []string
+pkg browspr, type CreateInstanceMessage struct, Origin string
+pkg browspr, type CreateInstanceMessage struct, Proxy string
+pkg browspr, type GetAccountsMessage struct
+pkg browspr, type OriginHasAccountMessage struct
+pkg browspr, type OriginHasAccountMessage struct, Origin string
+pkg browspr, type StartMessage struct
+pkg browspr, type StartMessage struct, Identityd string
+pkg browspr, type StartMessage struct, IdentitydBlessingRoot identity.BlessingRootResponse
+pkg browspr, type StartMessage struct, LogLevel int32
+pkg browspr, type StartMessage struct, LogModule string
+pkg browspr, type StartMessage struct, NamespaceRoot string
+pkg browspr, type StartMessage struct, Proxy string
diff --git a/services/wspr/internal/browspr/browspr_test.go b/services/wspr/internal/browspr/browspr_test.go
index 76b6185..bbb0e0a 100644
--- a/services/wspr/internal/browspr/browspr_test.go
+++ b/services/wspr/internal/browspr/browspr_test.go
@@ -82,7 +82,8 @@
 	ctx, shutdown := test.InitForTest()
 	defer shutdown()
 
-	proxyShutdown, proxyEndpoint, err := profiles.NewProxy(ctx, "tcp", "127.0.0.1:0", "")
+	proxySpec := rpc.ListenSpec{Addrs: rpc.ListenAddrs{{"tcp", "127.0.0.1:0"}}}
+	proxyShutdown, proxyEndpoint, err := profiles.NewProxy(ctx, proxySpec)
 	if err != nil {
 		t.Fatalf("Failed to start proxy: %v", err)
 	}
diff --git a/services/wspr/internal/channel/.api b/services/wspr/internal/channel/.api
new file mode 100644
index 0000000..5a8246c
--- /dev/null
+++ b/services/wspr/internal/channel/.api
@@ -0,0 +1,29 @@
+pkg channel, func NewChannel(MessageSender) *Channel
+pkg channel, method (*Channel) HandleMessage(Message)
+pkg channel, method (*Channel) PerformRpc(string, *vdl.Value) (*vdl.Value, error)
+pkg channel, method (*Channel) RegisterRequestHandler(string, RequestHandler)
+pkg channel, method (MessageRequest) Index() int
+pkg channel, method (MessageRequest) Interface() interface{}
+pkg channel, method (MessageRequest) Name() string
+pkg channel, method (MessageResponse) Index() int
+pkg channel, method (MessageResponse) Interface() interface{}
+pkg channel, method (MessageResponse) Name() string
+pkg channel, type Channel struct
+pkg channel, type Message interface, Index() int
+pkg channel, type Message interface, Interface() interface{}
+pkg channel, type Message interface, Name() string
+pkg channel, type Message interface, unexported methods
+pkg channel, type MessageRequest struct
+pkg channel, type MessageRequest struct, Value Request
+pkg channel, type MessageResponse struct
+pkg channel, type MessageResponse struct, Value Response
+pkg channel, type MessageSender func(Message)
+pkg channel, type Request struct
+pkg channel, type Request struct, Body *vdl.Value
+pkg channel, type Request struct, Seq uint32
+pkg channel, type Request struct, Type string
+pkg channel, type RequestHandler func(*vdl.Value) (*vdl.Value, error)
+pkg channel, type Response struct
+pkg channel, type Response struct, Body *vdl.Value
+pkg channel, type Response struct, Err string
+pkg channel, type Response struct, ReqSeq uint32
diff --git a/services/wspr/internal/channel/channel_nacl/.api b/services/wspr/internal/channel/channel_nacl/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/wspr/internal/channel/channel_nacl/.api
diff --git a/services/wspr/internal/lib/.api b/services/wspr/internal/lib/.api
new file mode 100644
index 0000000..df2c51e
--- /dev/null
+++ b/services/wspr/internal/lib/.api
@@ -0,0 +1,44 @@
+pkg lib, const JSRPCNoTimeout int64
+pkg lib, const LogLevelError LogLevel
+pkg lib, const LogLevelInfo LogLevel
+pkg lib, const ResponseAuthRequest ideal-int
+pkg lib, const ResponseCancel ideal-int
+pkg lib, const ResponseDispatcherLookup ideal-int
+pkg lib, const ResponseError ideal-int
+pkg lib, const ResponseFinal ResponseType
+pkg lib, const ResponseGranterRequest ideal-int
+pkg lib, const ResponseLog ideal-int
+pkg lib, const ResponseServerRequest ideal-int
+pkg lib, const ResponseStream ideal-int
+pkg lib, const ResponseStreamClose ideal-int
+pkg lib, const ResponseValidate ideal-int
+pkg lib, func GoToJSDuration(time.Duration) int64
+pkg lib, func JSToGoDuration(int64) time.Duration
+pkg lib, func LogLevelFromString(string) (LogLevel, error)
+pkg lib, func LowercaseFirstCharacter(string) string
+pkg lib, func NewSignatureManager() SignatureManager
+pkg lib, func UppercaseFirstCharacter(string) string
+pkg lib, func VomDecode(string, interface{}) error
+pkg lib, func VomEncode(interface{}) (string, error)
+pkg lib, func VomEncodeOrDie(interface{}) string
+pkg lib, method (*LogLevel) Set(string) error
+pkg lib, method (LogLevel) String() string
+pkg lib, type ClientWriter interface { Error, Send }
+pkg lib, type ClientWriter interface, Error(error)
+pkg lib, type ClientWriter interface, Send(ResponseType, interface{}) error
+pkg lib, type LogLevel int
+pkg lib, type LogMessage struct
+pkg lib, type LogMessage struct, Level LogLevel
+pkg lib, type LogMessage struct, Message string
+pkg lib, type Response struct
+pkg lib, type Response struct, Message interface{}
+pkg lib, type Response struct, Type ResponseType
+pkg lib, type ResponseType int32
+pkg lib, type ServerRpcReply struct
+pkg lib, type ServerRpcReply struct, Err error
+pkg lib, type ServerRpcReply struct, Results []*vdl.Value
+pkg lib, type ServerRpcReply struct, TraceResponse vtrace.Response
+pkg lib, type SignatureManager interface { FlushCacheEntry, Signature }
+pkg lib, type SignatureManager interface, FlushCacheEntry(string)
+pkg lib, type SignatureManager interface, Signature(*context.T, string, ...rpc.CallOpt) ([]signature.Interface, error)
+pkg lib, var LogLevelAll [...]LogLevel
diff --git a/services/wspr/internal/lib/testwriter/.api b/services/wspr/internal/lib/testwriter/.api
new file mode 100644
index 0000000..27e1c07
--- /dev/null
+++ b/services/wspr/internal/lib/testwriter/.api
@@ -0,0 +1,10 @@
+pkg testwriter, func CheckResponses(*Writer, []lib.Response, error) error
+pkg testwriter, method (*Writer) Error(error)
+pkg testwriter, method (*Writer) ImmediatelyConsumeItem() (lib.Response, error)
+pkg testwriter, method (*Writer) Send(lib.ResponseType, interface{}) error
+pkg testwriter, method (*Writer) WaitForMessage(int) error
+pkg testwriter, type TestHarness interface { Errorf }
+pkg testwriter, type TestHarness interface, Errorf(string, ...interface{})
+pkg testwriter, type Writer struct
+pkg testwriter, type Writer struct, Stream []lib.Response
+pkg testwriter, type Writer struct, embedded sync.Mutex
diff --git a/services/wspr/internal/namespace/.api b/services/wspr/internal/namespace/.api
new file mode 100644
index 0000000..49c9ca5
--- /dev/null
+++ b/services/wspr/internal/namespace/.api
@@ -0,0 +1,96 @@
+pkg namespace, func NamespaceClient(string) NamespaceClientStub
+pkg namespace, func NamespaceServer(NamespaceServerMethods) NamespaceServerStub
+pkg namespace, func New(*context.T) *Server
+pkg namespace, method (*NamespaceGlobServerCallStub) Init(rpc.StreamServerCall)
+pkg namespace, method (*NamespaceGlobServerCallStub) SendStream() interface {  Send(item naming.GlobReply) error;}
+pkg namespace, method (*Server) Delete(*context.T, rpc.ServerCall, string, bool) error
+pkg namespace, method (*Server) DisableCache(*context.T, rpc.ServerCall, bool) error
+pkg namespace, method (*Server) FlushCacheEntry(*context.T, rpc.ServerCall, string) (bool, error)
+pkg namespace, method (*Server) GetPermissions(*context.T, rpc.ServerCall, string) (access.Permissions, string, error)
+pkg namespace, method (*Server) Glob(*context.T, *NamespaceGlobServerCallStub, string) error
+pkg namespace, method (*Server) Mount(*context.T, rpc.ServerCall, string, string, time.Duration, bool) error
+pkg namespace, method (*Server) Resolve(*context.T, rpc.ServerCall, string) ([]string, error)
+pkg namespace, method (*Server) ResolveToMountTable(*context.T, rpc.ServerCall, string) ([]string, error)
+pkg namespace, method (*Server) Roots(*context.T, rpc.ServerCall) ([]string, error)
+pkg namespace, method (*Server) SetPermissions(*context.T, rpc.ServerCall, string, access.Permissions, string) error
+pkg namespace, method (*Server) SetRoots(*context.T, rpc.ServerCall, []string) error
+pkg namespace, method (*Server) Unmount(*context.T, rpc.ServerCall, string, string) error
+pkg namespace, type NamespaceClientMethods interface { Delete, DisableCache, FlushCacheEntry, GetPermissions, Glob, Mount, Resolve, ResolveToMountTable, Roots, SetPermissions, SetRoots, Unmount }
+pkg namespace, type NamespaceClientMethods interface, Delete(*context.T, string, bool, ...rpc.CallOpt) error
+pkg namespace, type NamespaceClientMethods interface, DisableCache(*context.T, bool, ...rpc.CallOpt) error
+pkg namespace, type NamespaceClientMethods interface, FlushCacheEntry(*context.T, string, ...rpc.CallOpt) (bool, error)
+pkg namespace, type NamespaceClientMethods interface, GetPermissions(*context.T, string, ...rpc.CallOpt) (access.Permissions, string, error)
+pkg namespace, type NamespaceClientMethods interface, Glob(*context.T, string, ...rpc.CallOpt) (NamespaceGlobClientCall, error)
+pkg namespace, type NamespaceClientMethods interface, Mount(*context.T, string, string, time.Duration, bool, ...rpc.CallOpt) error
+pkg namespace, type NamespaceClientMethods interface, Resolve(*context.T, string, ...rpc.CallOpt) ([]string, error)
+pkg namespace, type NamespaceClientMethods interface, ResolveToMountTable(*context.T, string, ...rpc.CallOpt) ([]string, error)
+pkg namespace, type NamespaceClientMethods interface, Roots(*context.T, ...rpc.CallOpt) ([]string, error)
+pkg namespace, type NamespaceClientMethods interface, SetPermissions(*context.T, string, access.Permissions, string, ...rpc.CallOpt) error
+pkg namespace, type NamespaceClientMethods interface, SetRoots(*context.T, []string, ...rpc.CallOpt) error
+pkg namespace, type NamespaceClientMethods interface, Unmount(*context.T, string, string, ...rpc.CallOpt) error
+pkg namespace, type NamespaceClientStub interface, Delete(*context.T, string, bool, ...rpc.CallOpt) error
+pkg namespace, type NamespaceClientStub interface, DisableCache(*context.T, bool, ...rpc.CallOpt) error
+pkg namespace, type NamespaceClientStub interface, FlushCacheEntry(*context.T, string, ...rpc.CallOpt) (bool, error)
+pkg namespace, type NamespaceClientStub interface, GetPermissions(*context.T, string, ...rpc.CallOpt) (access.Permissions, string, error)
+pkg namespace, type NamespaceClientStub interface, Glob(*context.T, string, ...rpc.CallOpt) (NamespaceGlobClientCall, error)
+pkg namespace, type NamespaceClientStub interface, Mount(*context.T, string, string, time.Duration, bool, ...rpc.CallOpt) error
+pkg namespace, type NamespaceClientStub interface, Resolve(*context.T, string, ...rpc.CallOpt) ([]string, error)
+pkg namespace, type NamespaceClientStub interface, ResolveToMountTable(*context.T, string, ...rpc.CallOpt) ([]string, error)
+pkg namespace, type NamespaceClientStub interface, Roots(*context.T, ...rpc.CallOpt) ([]string, error)
+pkg namespace, type NamespaceClientStub interface, SetPermissions(*context.T, string, access.Permissions, string, ...rpc.CallOpt) error
+pkg namespace, type NamespaceClientStub interface, SetRoots(*context.T, []string, ...rpc.CallOpt) error
+pkg namespace, type NamespaceClientStub interface, Unmount(*context.T, string, string, ...rpc.CallOpt) error
+pkg namespace, type NamespaceClientStub interface, unexported methods
+pkg namespace, type NamespaceGlobClientCall interface { Finish, RecvStream }
+pkg namespace, type NamespaceGlobClientCall interface, Finish() error
+pkg namespace, type NamespaceGlobClientCall interface, RecvStream() interface {  Advance() bool;; Value() naming.GlobReply;; Err() error;}
+pkg namespace, type NamespaceGlobClientStream interface { RecvStream }
+pkg namespace, type NamespaceGlobClientStream interface, RecvStream() interface {  Advance() bool;; Value() naming.GlobReply;; Err() error;}
+pkg namespace, type NamespaceGlobServerCall interface, SendStream() interface {  Send(item naming.GlobReply) error;}
+pkg namespace, type NamespaceGlobServerCall interface, unexported methods
+pkg namespace, type NamespaceGlobServerCallStub struct
+pkg namespace, type NamespaceGlobServerCallStub struct, embedded rpc.StreamServerCall
+pkg namespace, type NamespaceGlobServerStream interface { SendStream }
+pkg namespace, type NamespaceGlobServerStream interface, SendStream() interface {  Send(item naming.GlobReply) error;}
+pkg namespace, type NamespaceServerMethods interface { Delete, DisableCache, FlushCacheEntry, GetPermissions, Glob, Mount, Resolve, ResolveToMountTable, Roots, SetPermissions, SetRoots, Unmount }
+pkg namespace, type NamespaceServerMethods interface, Delete(*context.T, rpc.ServerCall, string, bool) error
+pkg namespace, type NamespaceServerMethods interface, DisableCache(*context.T, rpc.ServerCall, bool) error
+pkg namespace, type NamespaceServerMethods interface, FlushCacheEntry(*context.T, rpc.ServerCall, string) (bool, error)
+pkg namespace, type NamespaceServerMethods interface, GetPermissions(*context.T, rpc.ServerCall, string) (access.Permissions, string, error)
+pkg namespace, type NamespaceServerMethods interface, Glob(*context.T, NamespaceGlobServerCall, string) error
+pkg namespace, type NamespaceServerMethods interface, Mount(*context.T, rpc.ServerCall, string, string, time.Duration, bool) error
+pkg namespace, type NamespaceServerMethods interface, Resolve(*context.T, rpc.ServerCall, string) ([]string, error)
+pkg namespace, type NamespaceServerMethods interface, ResolveToMountTable(*context.T, rpc.ServerCall, string) ([]string, error)
+pkg namespace, type NamespaceServerMethods interface, Roots(*context.T, rpc.ServerCall) ([]string, error)
+pkg namespace, type NamespaceServerMethods interface, SetPermissions(*context.T, rpc.ServerCall, string, access.Permissions, string) error
+pkg namespace, type NamespaceServerMethods interface, SetRoots(*context.T, rpc.ServerCall, []string) error
+pkg namespace, type NamespaceServerMethods interface, Unmount(*context.T, rpc.ServerCall, string, string) error
+pkg namespace, type NamespaceServerStub interface { Delete, Describe__, DisableCache, FlushCacheEntry, GetPermissions, Glob, Mount, Resolve, ResolveToMountTable, Roots, SetPermissions, SetRoots, Unmount }
+pkg namespace, type NamespaceServerStub interface, Delete(*context.T, rpc.ServerCall, string, bool) error
+pkg namespace, type NamespaceServerStub interface, Describe__() []rpc.InterfaceDesc
+pkg namespace, type NamespaceServerStub interface, DisableCache(*context.T, rpc.ServerCall, bool) error
+pkg namespace, type NamespaceServerStub interface, FlushCacheEntry(*context.T, rpc.ServerCall, string) (bool, error)
+pkg namespace, type NamespaceServerStub interface, GetPermissions(*context.T, rpc.ServerCall, string) (access.Permissions, string, error)
+pkg namespace, type NamespaceServerStub interface, Glob(*context.T, *NamespaceGlobServerCallStub, string) error
+pkg namespace, type NamespaceServerStub interface, Mount(*context.T, rpc.ServerCall, string, string, time.Duration, bool) error
+pkg namespace, type NamespaceServerStub interface, Resolve(*context.T, rpc.ServerCall, string) ([]string, error)
+pkg namespace, type NamespaceServerStub interface, ResolveToMountTable(*context.T, rpc.ServerCall, string) ([]string, error)
+pkg namespace, type NamespaceServerStub interface, Roots(*context.T, rpc.ServerCall) ([]string, error)
+pkg namespace, type NamespaceServerStub interface, SetPermissions(*context.T, rpc.ServerCall, string, access.Permissions, string) error
+pkg namespace, type NamespaceServerStub interface, SetRoots(*context.T, rpc.ServerCall, []string) error
+pkg namespace, type NamespaceServerStub interface, Unmount(*context.T, rpc.ServerCall, string, string) error
+pkg namespace, type NamespaceServerStubMethods interface { Delete, DisableCache, FlushCacheEntry, GetPermissions, Glob, Mount, Resolve, ResolveToMountTable, Roots, SetPermissions, SetRoots, Unmount }
+pkg namespace, type NamespaceServerStubMethods interface, Delete(*context.T, rpc.ServerCall, string, bool) error
+pkg namespace, type NamespaceServerStubMethods interface, DisableCache(*context.T, rpc.ServerCall, bool) error
+pkg namespace, type NamespaceServerStubMethods interface, FlushCacheEntry(*context.T, rpc.ServerCall, string) (bool, error)
+pkg namespace, type NamespaceServerStubMethods interface, GetPermissions(*context.T, rpc.ServerCall, string) (access.Permissions, string, error)
+pkg namespace, type NamespaceServerStubMethods interface, Glob(*context.T, *NamespaceGlobServerCallStub, string) error
+pkg namespace, type NamespaceServerStubMethods interface, Mount(*context.T, rpc.ServerCall, string, string, time.Duration, bool) error
+pkg namespace, type NamespaceServerStubMethods interface, Resolve(*context.T, rpc.ServerCall, string) ([]string, error)
+pkg namespace, type NamespaceServerStubMethods interface, ResolveToMountTable(*context.T, rpc.ServerCall, string) ([]string, error)
+pkg namespace, type NamespaceServerStubMethods interface, Roots(*context.T, rpc.ServerCall) ([]string, error)
+pkg namespace, type NamespaceServerStubMethods interface, SetPermissions(*context.T, rpc.ServerCall, string, access.Permissions, string) error
+pkg namespace, type NamespaceServerStubMethods interface, SetRoots(*context.T, rpc.ServerCall, []string) error
+pkg namespace, type NamespaceServerStubMethods interface, Unmount(*context.T, rpc.ServerCall, string, string) error
+pkg namespace, type Server struct
+pkg namespace, var NamespaceDesc rpc.InterfaceDesc
diff --git a/services/wspr/internal/principal/.api b/services/wspr/internal/principal/.api
new file mode 100644
index 0000000..fcf1511
--- /dev/null
+++ b/services/wspr/internal/principal/.api
@@ -0,0 +1,24 @@
+pkg principal, const ZeroHandle BlessingsHandle
+pkg principal, func ConvertBlessingsToHandle(security.Blessings, BlessingsHandle) *JsBlessings
+pkg principal, func DecodePublicKey(string) (security.PublicKey, error)
+pkg principal, func EncodePublicKey(security.PublicKey) (string, error)
+pkg principal, func NewJSBlessingsHandles() *JSBlessingsHandles
+pkg principal, func NewPrincipalManager(security.Principal, vsecurity.SerializerReaderWriter) (*PrincipalManager, error)
+pkg principal, method (*InMemorySerializer) Readers() (io.ReadCloser, io.ReadCloser, error)
+pkg principal, method (*InMemorySerializer) Writers() (io.WriteCloser, io.WriteCloser, error)
+pkg principal, method (*JSBlessingsHandles) GetBlessings(BlessingsHandle) security.Blessings
+pkg principal, method (*JSBlessingsHandles) GetOrAddHandle(security.Blessings) BlessingsHandle
+pkg principal, method (*JSBlessingsHandles) RemoveReference(BlessingsHandle) error
+pkg principal, method (*PrincipalManager) AddAccount(string, security.Blessings) error
+pkg principal, method (*PrincipalManager) AddOrigin(string, string, []security.Caveat, []time.Time) error
+pkg principal, method (*PrincipalManager) BlessingsForAccount(string) (security.Blessings, error)
+pkg principal, method (*PrincipalManager) DummyAccount() (string, error)
+pkg principal, method (*PrincipalManager) OriginHasAccount(string) bool
+pkg principal, method (*PrincipalManager) Principal(string) (security.Principal, error)
+pkg principal, type BlessingsHandle int32
+pkg principal, type InMemorySerializer struct
+pkg principal, type JSBlessingsHandles struct
+pkg principal, type JsBlessings struct
+pkg principal, type JsBlessings struct, Handle BlessingsHandle
+pkg principal, type JsBlessings struct, PublicKey string
+pkg principal, type PrincipalManager struct
diff --git a/services/wspr/internal/rpc/server/.api b/services/wspr/internal/rpc/server/.api
new file mode 100644
index 0000000..4c2a23a
--- /dev/null
+++ b/services/wspr/internal/rpc/server/.api
@@ -0,0 +1,66 @@
+pkg server, func CaveatValidation(*context.T, security.Call, [][]security.Caveat) []error
+pkg server, func ConvertSecurityCall(ServerHelper, *context.T, security.Call, bool) SecurityCall
+pkg server, func NewErrCaveatValidationTimeout(*context.T) error
+pkg server, func NewErrInvalidValidationResponseFromJavascript(*context.T) error
+pkg server, func NewErrServerStopped(*context.T) error
+pkg server, func NewServer(uint32, *rpc.ListenSpec, ServerHelper) (*Server, error)
+pkg server, method (*Server) AddName(string) error
+pkg server, method (*Server) HandleAuthResponse(int32, string)
+pkg server, method (*Server) HandleCaveatValidationResponse(int32, string)
+pkg server, method (*Server) HandleLookupResponse(int32, string)
+pkg server, method (*Server) HandleServerResponse(int32, string)
+pkg server, method (*Server) RemoveName(string)
+pkg server, method (*Server) Serve(string) error
+pkg server, method (*Server) Stop()
+pkg server, type AuthRequest struct
+pkg server, type AuthRequest struct, Call SecurityCall
+pkg server, type AuthRequest struct, Handle int32
+pkg server, type AuthRequest struct, ServerId uint32
+pkg server, type CaveatValidationRequest struct
+pkg server, type CaveatValidationRequest struct, Call SecurityCall
+pkg server, type CaveatValidationRequest struct, Cavs [][]security.Caveat
+pkg server, type CaveatValidationResponse struct
+pkg server, type CaveatValidationResponse struct, Results []error
+pkg server, type Flow struct
+pkg server, type Flow struct, ID int32
+pkg server, type Flow struct, Writer lib.ClientWriter
+pkg server, type FlowHandler interface { CleanupFlow, CreateNewFlow }
+pkg server, type FlowHandler interface, CleanupFlow(int32)
+pkg server, type FlowHandler interface, CreateNewFlow(interface{}, rpc.Stream) *Flow
+pkg server, type HandleStore interface { GetBlessings, GetOrAddBlessingsHandle }
+pkg server, type HandleStore interface, GetBlessings(principal.BlessingsHandle) security.Blessings
+pkg server, type HandleStore interface, GetOrAddBlessingsHandle(security.Blessings) principal.BlessingsHandle
+pkg server, type SecurityCall struct
+pkg server, type SecurityCall struct, LocalBlessingStrings []string
+pkg server, type SecurityCall struct, LocalBlessings principal.JsBlessings
+pkg server, type SecurityCall struct, LocalEndpoint string
+pkg server, type SecurityCall struct, Method string
+pkg server, type SecurityCall struct, MethodTags []*vdl.Value
+pkg server, type SecurityCall struct, RemoteBlessingStrings []string
+pkg server, type SecurityCall struct, RemoteBlessings principal.JsBlessings
+pkg server, type SecurityCall struct, RemoteEndpoint string
+pkg server, type SecurityCall struct, Suffix string
+pkg server, type Server struct
+pkg server, type ServerHelper interface { CleanupFlow, Context, CreateNewFlow, GetBlessings, GetOrAddBlessingsHandle, SendLogMessage }
+pkg server, type ServerHelper interface, CleanupFlow(int32)
+pkg server, type ServerHelper interface, Context() *context.T
+pkg server, type ServerHelper interface, CreateNewFlow(interface{}, rpc.Stream) *Flow
+pkg server, type ServerHelper interface, GetBlessings(principal.BlessingsHandle) security.Blessings
+pkg server, type ServerHelper interface, GetOrAddBlessingsHandle(security.Blessings) principal.BlessingsHandle
+pkg server, type ServerHelper interface, SendLogMessage(lib.LogLevel, string) error
+pkg server, type ServerRpcRequest struct
+pkg server, type ServerRpcRequest struct, Args []*vdl.Value
+pkg server, type ServerRpcRequest struct, Call ServerRpcRequestCall
+pkg server, type ServerRpcRequest struct, Handle int32
+pkg server, type ServerRpcRequest struct, Method string
+pkg server, type ServerRpcRequest struct, ServerId uint32
+pkg server, type ServerRpcRequestCall struct
+pkg server, type ServerRpcRequestCall struct, Deadline time.Deadline
+pkg server, type ServerRpcRequestCall struct, GrantedBlessings *principal.JsBlessings
+pkg server, type ServerRpcRequestCall struct, SecurityCall SecurityCall
+pkg server, type ServerRpcRequestCall struct, TraceRequest vtrace.Request
+pkg server, var ErrCaveatValidationTimeout unknown-type
+pkg server, var ErrInvalidValidationResponseFromJavascript unknown-type
+pkg server, var ErrMethodNotFoundInSignature unknown-type
+pkg server, var ErrServerStopped unknown-type
+pkg server, var ErrWrongNumberOfArgs unknown-type
diff --git a/services/wspr/wsprd/.api b/services/wspr/wsprd/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/wspr/wsprd/.api
diff --git a/services/wspr/wsprlib/.api b/services/wspr/wsprlib/.api
new file mode 100644
index 0000000..7e15162
--- /dev/null
+++ b/services/wspr/wsprlib/.api
@@ -0,0 +1,6 @@
+pkg wsprlib, func NewWSPR(*context.T, int, *rpc.ListenSpec, string, []string) *WSPR
+pkg wsprlib, method (*WSPR) CleanUpPipe(*http.Request)
+pkg wsprlib, method (*WSPR) Listen() net.Addr
+pkg wsprlib, method (*WSPR) Serve()
+pkg wsprlib, method (*WSPR) Shutdown()
+pkg wsprlib, type WSPR struct
diff --git a/test/.api b/test/.api
new file mode 100644
index 0000000..dc1c7a3
--- /dev/null
+++ b/test/.api
@@ -0,0 +1,7 @@
+pkg test, const IntegrationTestsDebugShellOnErrorFlag ideal-string
+pkg test, const IntegrationTestsFlag ideal-string
+pkg test, const TestBlessing ideal-string
+pkg test, func Init()
+pkg test, func InitForTest() (*context.T, v23.Shutdown)
+pkg test, var IntegrationTestsDebugShellOnError bool
+pkg test, var IntegrationTestsEnabled bool
diff --git a/test/benchmark/.api b/test/benchmark/.api
new file mode 100644
index 0000000..45b8fe1
--- /dev/null
+++ b/test/benchmark/.api
@@ -0,0 +1,9 @@
+pkg benchmark, func AddStats(*testing.B, int) *Stats
+pkg benchmark, func AddStatsWithName(*testing.B, string, int) *Stats
+pkg benchmark, func NewStats(int) *Stats
+pkg benchmark, func RunTestMain(*testing.M) int
+pkg benchmark, method (*Stats) Add(time.Duration)
+pkg benchmark, method (*Stats) Clear()
+pkg benchmark, method (*Stats) Print(io.Writer)
+pkg benchmark, method (*Stats) String() string
+pkg benchmark, type Stats struct
diff --git a/test/expect/.api b/test/expect/.api
new file mode 100644
index 0000000..af8ef19
--- /dev/null
+++ b/test/expect/.api
@@ -0,0 +1,22 @@
+pkg expect, func NewSession(Testing, io.Reader, time.Duration) *Session
+pkg expect, method (*Session) Error() error
+pkg expect, method (*Session) Expect(string)
+pkg expect, method (*Session) ExpectEOF() error
+pkg expect, method (*Session) ExpectRE(string, int) [][]string
+pkg expect, method (*Session) ExpectSetEventuallyRE(...string) [][]string
+pkg expect, method (*Session) ExpectSetRE(...string) [][]string
+pkg expect, method (*Session) ExpectVar(string) string
+pkg expect, method (*Session) Expectf(string, ...interface{})
+pkg expect, method (*Session) Failed() bool
+pkg expect, method (*Session) Finish(io.Writer) (string, error)
+pkg expect, method (*Session) OriginalError() error
+pkg expect, method (*Session) ReadAll() (string, error)
+pkg expect, method (*Session) ReadLine() string
+pkg expect, method (*Session) ReportError()
+pkg expect, method (*Session) SetVerbosity(bool)
+pkg expect, type Session struct
+pkg expect, type Testing interface { Error, Errorf, Log }
+pkg expect, type Testing interface, Error(...interface{})
+pkg expect, type Testing interface, Errorf(string, ...interface{})
+pkg expect, type Testing interface, Log(...interface{})
+pkg expect, var Timeout error
diff --git a/test/modules/.api b/test/modules/.api
new file mode 100644
index 0000000..08fa5b5
--- /dev/null
+++ b/test/modules/.api
@@ -0,0 +1,83 @@
+pkg modules, func DefaultStartOpts() StartOpts
+pkg modules, func Dispatch() error
+pkg modules, func DispatchAndExit()
+pkg modules, func Help(string) string
+pkg modules, func IsModulesChildProcess() bool
+pkg modules, func NewShell(*context.T, security.Principal, bool, expect.Testing) (*Shell, error)
+pkg modules, func RegisterChild(string, string, Main)
+pkg modules, func RegisterFunction(string, string, Main)
+pkg modules, func SetEntryPoint(map[string]string, string) []string
+pkg modules, func Usage(*flag.FlagSet) string
+pkg modules, func WaitForEOF(io.Reader)
+pkg modules, method (*CustomCredentials) File() (*os.File, error)
+pkg modules, method (*CustomCredentials) Principal() security.Principal
+pkg modules, method (*Shell) Cleanup(io.Writer, io.Writer) error
+pkg modules, method (*Shell) ClearConfigKey(string)
+pkg modules, method (*Shell) ClearVar(string)
+pkg modules, method (*Shell) CommandEnvelope(string, []string, ...string) ([]string, []string)
+pkg modules, method (*Shell) DefaultStartOpts() StartOpts
+pkg modules, method (*Shell) Env() []string
+pkg modules, method (*Shell) Forget(Handle)
+pkg modules, method (*Shell) GetConfigKey(string) (string, bool)
+pkg modules, method (*Shell) GetVar(string) (string, bool)
+pkg modules, method (*Shell) Help(string) string
+pkg modules, method (*Shell) NewChildCredentials(string, ...security.Caveat) (*CustomCredentials, error)
+pkg modules, method (*Shell) NewCustomCredentials() (*CustomCredentials, error)
+pkg modules, method (*Shell) SetConfigKey(string, string)
+pkg modules, method (*Shell) SetDefaultStartOpts(StartOpts)
+pkg modules, method (*Shell) SetVar(string, string)
+pkg modules, method (*Shell) Start(string, []string, ...string) (Handle, error)
+pkg modules, method (*Shell) StartWithOpts(StartOpts, []string, string, ...string) (Handle, error)
+pkg modules, method (*Shell) String() string
+pkg modules, method (StartOpts) ExternalCommand() StartOpts
+pkg modules, method (StartOpts) NoExecCommand() StartOpts
+pkg modules, method (StartOpts) WithCustomCredentials(*CustomCredentials) StartOpts
+pkg modules, method (StartOpts) WithSessions(expect.Testing, time.Duration) StartOpts
+pkg modules, method (StartOpts) WithStdin(io.Reader) StartOpts
+pkg modules, type CustomCredentials struct
+pkg modules, type ExpectSession interface { Error, Expect, ExpectEOF, ExpectRE, ExpectSetEventuallyRE, ExpectSetRE, ExpectVar, Expectf, Failed, ReadAll, ReadLine, SetVerbosity }
+pkg modules, type ExpectSession interface, Error() error
+pkg modules, type ExpectSession interface, Expect(string)
+pkg modules, type ExpectSession interface, ExpectEOF() error
+pkg modules, type ExpectSession interface, ExpectRE(string, int) [][]string
+pkg modules, type ExpectSession interface, ExpectSetEventuallyRE(...string) [][]string
+pkg modules, type ExpectSession interface, ExpectSetRE(...string) [][]string
+pkg modules, type ExpectSession interface, ExpectVar(string) string
+pkg modules, type ExpectSession interface, Expectf(string, ...interface{})
+pkg modules, type ExpectSession interface, Failed() bool
+pkg modules, type ExpectSession interface, ReadAll() (string, error)
+pkg modules, type ExpectSession interface, ReadLine() string
+pkg modules, type ExpectSession interface, SetVerbosity(bool)
+pkg modules, type Handle interface { CloseStdin, Error, Expect, ExpectEOF, ExpectRE, ExpectSetEventuallyRE, ExpectSetRE, ExpectVar, Expectf, Failed, Pid, ReadAll, ReadLine, SetVerbosity, Shutdown, Stderr, Stdin, Stdout }
+pkg modules, type Handle interface, CloseStdin()
+pkg modules, type Handle interface, Error() error
+pkg modules, type Handle interface, Expect(string)
+pkg modules, type Handle interface, ExpectEOF() error
+pkg modules, type Handle interface, ExpectRE(string, int) [][]string
+pkg modules, type Handle interface, ExpectSetEventuallyRE(...string) [][]string
+pkg modules, type Handle interface, ExpectSetRE(...string) [][]string
+pkg modules, type Handle interface, ExpectVar(string) string
+pkg modules, type Handle interface, Expectf(string, ...interface{})
+pkg modules, type Handle interface, Failed() bool
+pkg modules, type Handle interface, Pid() int
+pkg modules, type Handle interface, ReadAll() (string, error)
+pkg modules, type Handle interface, ReadLine() string
+pkg modules, type Handle interface, SetVerbosity(bool)
+pkg modules, type Handle interface, Shutdown(io.Writer, io.Writer) error
+pkg modules, type Handle interface, Stderr() io.Reader
+pkg modules, type Handle interface, Stdin() io.Writer
+pkg modules, type Handle interface, Stdout() io.Reader
+pkg modules, type Main func(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error
+pkg modules, type Shell struct
+pkg modules, type StartOpts struct
+pkg modules, type StartOpts struct, Credentials *CustomCredentials
+pkg modules, type StartOpts struct, Error error
+pkg modules, type StartOpts struct, ExecProtocol bool
+pkg modules, type StartOpts struct, ExpectTesting expect.Testing
+pkg modules, type StartOpts struct, ExpectTimeout time.Duration
+pkg modules, type StartOpts struct, External bool
+pkg modules, type StartOpts struct, ShutdownTimeout time.Duration
+pkg modules, type StartOpts struct, StartTimeout time.Duration
+pkg modules, type StartOpts struct, Stdin io.Reader
+pkg modules, var ErrNoExecAndCustomCreds error
+pkg modules, var ErrNotRegistered error
diff --git a/test/testutil/.api b/test/testutil/.api
new file mode 100644
index 0000000..d7b0df3
--- /dev/null
+++ b/test/testutil/.api
@@ -0,0 +1,24 @@
+pkg testutil, const SeedEnv ideal-string
+pkg testutil, func CallAndRecover(func()) interface{}
+pkg testutil, func DepthToExternalCaller() int
+pkg testutil, func FormatLogLine(int, string, ...interface{}) string
+pkg testutil, func GlobName(*context.T, string, string) ([]string, []naming.GlobError, error)
+pkg testutil, func InitRandGenerator()
+pkg testutil, func Int() int
+pkg testutil, func Int63() int64
+pkg testutil, func Intn(int) int
+pkg testutil, func LeafDispatcher(interface{}, security.Authorizer) rpc.Dispatcher
+pkg testutil, func NewIDProvider(string) *IDProvider
+pkg testutil, func NewPrincipal(...string) security.Principal
+pkg testutil, func NewRandGenerator() *Random
+pkg testutil, func RandomBytes(int) []byte
+pkg testutil, method (*IDProvider) Bless(security.Principal, string, ...security.Caveat) error
+pkg testutil, method (*IDProvider) NewBlessings(security.Principal, string, ...security.Caveat) (security.Blessings, error)
+pkg testutil, method (*IDProvider) PublicKey() security.PublicKey
+pkg testutil, method (*Random) Int() int
+pkg testutil, method (*Random) Int63() int64
+pkg testutil, method (*Random) Intn(int) int
+pkg testutil, method (*Random) RandomBytes(int) []byte
+pkg testutil, type IDProvider struct
+pkg testutil, type Random struct
+pkg testutil, var Rand *Random
diff --git a/test/timekeeper/.api b/test/timekeeper/.api
new file mode 100644
index 0000000..fdc3019
--- /dev/null
+++ b/test/timekeeper/.api
@@ -0,0 +1,4 @@
+pkg timekeeper, func NewManualTime() ManualTime
+pkg timekeeper, type ManualTime interface, AdvanceTime(time.Duration)
+pkg timekeeper, type ManualTime interface, Requests() <-chan time.Duration
+pkg timekeeper, type ManualTime interface, unexported methods
diff --git a/test/v23tests/.api b/test/v23tests/.api
new file mode 100644
index 0000000..b9043c1
--- /dev/null
+++ b/test/v23tests/.api
@@ -0,0 +1,59 @@
+pkg v23tests, func Caller(int) string
+pkg v23tests, func New(TB) *T
+pkg v23tests, func RunRootMT(*T, ...string) (*Binary, *Invocation)
+pkg v23tests, func RunTest(*testing.T, func(*T))
+pkg v23tests, func UseSharedBinDir() func()
+pkg v23tests, method (*Binary) Path() string
+pkg v23tests, method (*Binary) Run(...string) string
+pkg v23tests, method (*Binary) Start(...string) *Invocation
+pkg v23tests, method (*Binary) StartOpts() modules.StartOpts
+pkg v23tests, method (*Binary) WithEnv(...string) *Binary
+pkg v23tests, method (*Binary) WithStartOpts(modules.StartOpts) *Binary
+pkg v23tests, method (*Binary) WithStdin(io.Reader) *Binary
+pkg v23tests, method (*Invocation) Environment() *T
+pkg v23tests, method (*Invocation) Exists() bool
+pkg v23tests, method (*Invocation) Kill(syscall.Signal) error
+pkg v23tests, method (*Invocation) Output() string
+pkg v23tests, method (*Invocation) Path() string
+pkg v23tests, method (*Invocation) Wait(io.Writer, io.Writer) error
+pkg v23tests, method (*Invocation) WaitOrDie(io.Writer, io.Writer)
+pkg v23tests, method (*T) BinDir() string
+pkg v23tests, method (*T) BinaryFromPath(string) *Binary
+pkg v23tests, method (*T) BuildGoPkg(string, ...string) *Binary
+pkg v23tests, method (*T) BuildV23Pkg(string, ...string) *Binary
+pkg v23tests, method (*T) Caller(int) string
+pkg v23tests, method (*T) Cleanup()
+pkg v23tests, method (*T) ClearVar(string)
+pkg v23tests, method (*T) DebugSystemShell(...string)
+pkg v23tests, method (*T) GetVar(string) (string, bool)
+pkg v23tests, method (*T) NewTempDir(string) string
+pkg v23tests, method (*T) NewTempFile() *os.File
+pkg v23tests, method (*T) Popd() string
+pkg v23tests, method (*T) Principal() security.Principal
+pkg v23tests, method (*T) Pushd(string) string
+pkg v23tests, method (*T) Run(string, ...string) string
+pkg v23tests, method (*T) RunWithOpts(modules.StartOpts, string, ...string) string
+pkg v23tests, method (*T) SetVar(string, string)
+pkg v23tests, method (*T) Shell() *modules.Shell
+pkg v23tests, method (*T) WaitFor(WaitFunc, time.Duration, time.Duration) interface{}
+pkg v23tests, method (*T) WaitForAsync(WaitFunc, time.Duration, time.Duration) interface{}
+pkg v23tests, type Binary struct
+pkg v23tests, type Invocation struct
+pkg v23tests, type Invocation struct, embedded modules.Handle
+pkg v23tests, type T struct
+pkg v23tests, type T struct, embedded TB
+pkg v23tests, type TB interface { Error, Errorf, Fail, FailNow, Failed, Fatal, Fatalf, Log, Logf, Skip, SkipNow, Skipf, Skipped }
+pkg v23tests, type TB interface, Error(...interface{})
+pkg v23tests, type TB interface, Errorf(string, ...interface{})
+pkg v23tests, type TB interface, Fail()
+pkg v23tests, type TB interface, FailNow()
+pkg v23tests, type TB interface, Failed() bool
+pkg v23tests, type TB interface, Fatal(...interface{})
+pkg v23tests, type TB interface, Fatalf(string, ...interface{})
+pkg v23tests, type TB interface, Log(...interface{})
+pkg v23tests, type TB interface, Logf(string, ...interface{})
+pkg v23tests, type TB interface, Skip(...interface{})
+pkg v23tests, type TB interface, SkipNow()
+pkg v23tests, type TB interface, Skipf(string, ...interface{})
+pkg v23tests, type TB interface, Skipped() bool
+pkg v23tests, type WaitFunc func() (interface{}, error)
diff --git a/test/v23tests/internal/.api b/test/v23tests/internal/.api
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/v23tests/internal/.api