docs: def process(self, t_path, name_info, i_str):
          '''converts each :attr:`streamcorpus.StreamItem.body.clean_html` from
          `t_path` into a :class:`~dossier.fc.FeatureCollection` and saves it in
          a :class:`~dossier.store.Store` configured with the global `kvlayer`
          config.
  
          '''
          def cids_and_fcs():
              count = 0
              seen = set()
              for si in Chunk(t_path):
                  clean_html = getattr(si.body, 'clean_html', '')
                  if clean_html is None or len(clean_html.strip()) == 0:
                      logger.warn('dropping SI lacking clean_html: %r', si.abs_url)
                      continue
                  if 'other_features' in si.other_content:
                      other_features = json.loads(si.other_content['other_features'].raw)
                  else:
                      other_features = None
                  fc = html_to_fc(
                      clean_html=si.body.clean_html.decode('utf-8'),
                      clean_visible=si.body.clean_visible.decode('utf-8'),
                      encoding='utf-8',
                      url=si.abs_url,
                      timestamp=si.stream_time.epoch_ticks,
                      other_features=other_features,
                  )
                  add_sip_to_fc(fc, self.tfidf)
                  content_id = mk_content_id(str(fc.get(u'meta_url')))
                  if content_id in seen:
                      logger.warn('dropping duplicate content_id=%r', content_id)
                  else:
                      seen.add(content_id)
                      yield content_id, fc
                      count += 1
              logger.info('saved %d FCs from %d SIs', count, len(seen))
          self.store.put(cids_and_fcs())
          ## interface spec of streamcorpus_pipeline writers requires
          ## returning a list of locally generated paths.
          return []