-// Helper copied to the remote hosts to run commands and deploy configuration
+// Helper copied to the remote host to run commands and deploy configuration
 
 // Copyright (C) 2021  Simon Ruderich
 //
 
                if change.Old.Mode.Type() == fs.ModeSymlink {
                        // Some BSD systems permit changing permissions of
                        // symlinks but ignore them on traversal. To keep it
-                       // simple we don't support that and always use 0777 for
-                       // symlink permissions (the value on GNU/Linux).
+                       // simple we don't support that and always use 0777
+                       // for symlink permissions (the value on GNU/Linux).
                        //
                        // TODO: Add proper support for symlinks on BSD
                        change.Old.Mode |= 0777
                }
        }
 
-       // Directory: create new directory (also type change to directory)
+       // Directory: create new directory, also type change to directory
        if file.Mode.IsDir() && (change.Created || changeType) {
                debugf("creating directory")
                err := os.Mkdir(file.Path, 0700)
                        os.Remove(tmpPath)
                        return err
                }
-               // Permissions are irrelevant for symlinks
+               // Permissions are irrelevant for symlinks (on most systems)
 
        default:
                panic(fmt.Sprintf("invalid file type %s", file.Mode))
 
        "ruderich.org/simon/safcm/cmd/safcm-remote/run"
 )
 
+// testRunner implements run.Runner to test commands without actually running
+// them.
 type testRunner struct {
        t         *testing.T
        expCmds   []*exec.Cmd
 
        GroupRemoveSuffix     = GroupSpecialSeparator + "remove"
 )
 
-// Keep in sync with sync_info.go:infoGroupDetectedRegexp
+// Keep in sync with cmd/safcm/sync_info.go:infoGroupDetectedRegexp
 var groupNameRegexp = regexp.MustCompile(`^[a-z0-9_-]+$`)
 
 func LoadGroups(cfg *Config, hosts *Hosts) (map[string][]string, error) {
                        if x == GroupAll {
                                continue
                        }
+                       // Don't validate against groupNameRegexp because
+                       // hosts have less strict restrictions.
                        if strings.Contains(x, GroupSpecialSeparator) {
                                return nil, fmt.Errorf(
                                        "%s member %q must not contain %q",
 
                nameMap[x] = true
        }
        nameMatched := make(map[string]bool)
-       // To detect typos we must check all given names but only want to add
-       // each match once
+       // To detect typos we must check all given names but one host can be
+       // matched by multiple names (e.g. two groups with overlapping hosts)
        hostMatched := make(map[string]bool)
 
        var res []*config.Host
 
        return hostInfoRespToGroups(resp), nil
 }
 
-// Keep in sync with config/groups.go:groupNameRegexp
+// Keep in sync with cmd/safcm/config/groups.go:groupNameRegexp
 var infoGroupDetectedRegexp = regexp.MustCompile(`[^a-z0-9_-]+`)
 
 func hostInfoRespToGroups(resp safcm.MsgInfoResp) []string {
 
                return nil, nil, err
        }
 
-       // Early entries have higher priorities
+       // Early entries in "group_priority" have higher priorities
        groupPriority := make(map[string]int)
        for i, x := range s.config.GroupPriority {
                groupPriority[x] = len(s.config.GroupPriority) - i
 
 var escapeRegexp = regexp.MustCompile(`[\x00-\x08\x0B-\x1F\x7F]`)
 
 // EscapeControlCharacters escapes all ASCII control characters (except
-// newline and tab) by replacing them with their hex value.
+// newline and tab) by replacing them with their hex value. If the output is
+// to a TTY then the escaped characters are colored.
 //
 // This function must be used when displaying any input from remote hosts to
 // prevent terminal escape code injections.
 
 }
 
 // NewConn creates a new connection. Events in the returned struct must be
-// regularly read or the connection will stall. This must be done before
+// regularly read or the connection will hang. This must be done before
 // DialSSH is called to open a connection.
 func NewConn(debug bool) *Conn {
        ch := make(chan ConnEvent)
 
        //
        // The target directory must no permit other users to delete our files
        // or symlink attacks and arbitrary code execution is possible. For
-       // /tmp this is guaranteed by the sticky bit. Make sure it has the
-       // proper permissions.
+       // /tmp this is guaranteed by the sticky bit. The code verifies the
+       // directory has the proper permissions.
        //
        // We cannot use `test -f && test -O` because this is open to TOCTOU
        // attacks. `stat` gives use the full file state. If the file is owned
-       // by us and not a symlink then it's safe to use (assuming sticky or
-       // directory not writable by others).
+       // by us and not a symlink then it's safe to use (assuming sticky
+       // directory or directory not writable by others).
        //
        // `test -e` is only used to prevent error messages if the file
        // doesn't exist. It does not guard against any races.
                                c.sshRemote,
                                fmt.Sprintf("cat > %q", path))...)
                cmd.Stdin = bytes.NewReader(helper)
-               err = c.handleStderrAsEvents(cmd)
+               err = c.handleStderrAsEvents(cmd) // cmd.Stderr
                if err != nil {
                        return err
                }