code: func (c *Corpus) permanodeAttrsOrClaims(permaNode blob.Ref,
  	at time.Time, signerID string) (m map[string][]string, claims []*camtypes.Claim) {
  
  	pm, ok := c.permanodes[permaNode]
  	if !ok {
  		return nil, nil
  	}
  
  	m, ok = pm.valuesAtSigner(at, signerID)
  	if ok {
  		return m, nil
  	}
  	return nil, pm.Claims
  }
docs: // permanodeAttrsOrClaims returns the best available source
  // to query attr values of permaNode at the given time
  // for the signerID, which is either:
  // a. m that represents attr values for the parameters, or
  // b. all claims of the permanode.
  // Only one of m or claims will be non-nil.
  //
  // (m, nil) is returned if m represents attrValues
  // valid for the specified parameters.
  //
  // (nil, claims) is returned if
  // no cached attribute map is valid for the given time,
  // because e.g. some claims are more recent than this time. In which
  // case the caller should resort to query claims directly.
  //
  // (nil, nil) is returned if the permaNode does not exist,
  // or permaNode exists and signerID is valid,
  // but permaNode has no attributes for it.
  //
  // The returned values must not be changed by the caller.