diff --git a/edosl0util/cli/rdr2l0.py b/edosl0util/cli/rdr2l0.py
index 061f69532566115b01d41959c1197466b44cacb2..e8a883f8766de8b4316c643dd3e3d62f50034508 100644
--- a/edosl0util/cli/rdr2l0.py
+++ b/edosl0util/cli/rdr2l0.py
@@ -32,7 +32,8 @@ def remove_files(files):
     [os.remove(f) for f in files]
 
 
-def _do_dump(filepat, product, rdrs, start, end):
+def _do_dump(filepat, satellite, product, rdrs, start, end):
+    product = 'P{}{}'.format(satellite_to_scid[satellite], product)
     for filepath in rdrs:
         LOG.info('dumping %s', filepath)
         jpssrdr.write_rdr_datasets(filepath)
@@ -49,38 +50,57 @@ def _do_dump(filepat, product, rdrs, start, end):
 
 
 def cris_hsk(satellite, rdrs, start, end):
-    product = 'P{}1280CRISHSK'.format(satellite_to_scid[satellite])
-    return _do_dump('*.telemetry.pkts', product, rdrs, start, end)
+    product = '1280CRISHSK'
+    return _do_dump('*.telemetry.pkts', satellite, product, rdrs, start, end)
 
 
 def cris_dwell(satellite, rdrs, start, end):
-    product = 'P{}1291CRISDWELL'.format(satellite_to_scid[satellite])
-    return _do_dump('*.dwell.pkts', product, rdrs, start, end)
+    product = '1291CRISDWELL'
+    return _do_dump('*.dwell.pkts', satellite, product, rdrs, start, end)
 
 
 def cris_sci(satellite, rdrs, start, end):
-    product = 'P{}1289CRISSCIENCE'.format(satellite_to_scid[satellite])
-    return _do_dump('*.science.pkts', product, rdrs, start, end)
+    product = '1289CRISSCIENCE'
+    return _do_dump('*.science.pkts', satellite, product, rdrs, start, end)
 
 
 def atms_hsk(satellite, rdrs, start, end):
-    product = 'P{}0518ATMSHSK'.format(satellite_to_scid[satellite])
-    return _do_dump('*.telemetry.pkts', product, rdrs, start, end)
+    product = '0518ATMSHSK'
+    return _do_dump('*.telemetry.pkts', satellite, product, rdrs, start, end)
 
 
 def atms_dwell(satellite, rdrs, start, end):
-    product = 'P{}0517ATMSDWELL'.format(satellite_to_scid[satellite])
-    return _do_dump('*.dwell.pkts', product, rdrs, start, end)
+    product = '0517ATMSDWELL'
+    return _do_dump('*.dwell.pkts', satellite, product, rdrs, start, end)
 
 
 def atms_sci(satellite, rdrs, start, end):
-    product = 'P{}0515ATMSSCIENCE'.format(satellite_to_scid[satellite])
-    return _do_dump('*.science.pkts', product, rdrs, start, end)
+    product = '0515ATMSSCIENCE'
+    return _do_dump('*.science.pkts', satellite, product, rdrs, start, end)
 
 
-def viirs_sci(satellite, sci, start, end):
-    product = 'P{}0826VIIRSSCIENCE'.format(satellite_to_scid[satellite])
-    return _do_dump('*.science.pkts', product, rdrs, start, end)
+def viirs_sci(satellite, rdrs, start, end):
+    product = '0826VIIRSSCIENCE'
+    return _do_dump('*.science.pkts', satellite, product, rdrs, start, end)
+
+
+def spacecraft(satellite, rdrs, start, end):
+    product = 'SPACECRAFT'
+    for filepath in rdrs:
+        LOG.info('dumping %s', filepath)
+        jpssrdr.write_rdr_datasets(filepath, ancillary=True)
+
+    scid = satellite_to_scid[satellite]
+    for apid in (0, 8, 11):
+        # alphanumeric sorting to bootstrap final sort
+        inputs = sorted(glob.glob('*.ancillary{}.pkts'.format(apid)))
+        streams = [stream.jpss_packet_stream(open(f, 'rb')) for f in inputs]
+
+        product = 'P{}{:04d}'.format(scid, apid)
+        pdsname = pdsfilename(product, start)
+        LOG.info('merging to %s', pdsname)
+        with open(pdsname, 'wb') as dest:
+            merge.merge(streams, output=dest, trunc_to=[start, end])
 
 
 def main():
@@ -108,7 +128,7 @@ def main():
               'end will default to start + 2 hours. Format '
               'is YYYY-mm-dd HH:MM:SS.'),
     )
-    subs = parser.add_subparsers(title='Destination level 0 data type')
+    subs = parser.add_subparsers(title='Destination level 0 data type sub-commands')
 
     def cmd_cris_hsk(args):
         cris_hsk(args.satellite, args.rcrit, args.start, args.end)
@@ -158,6 +178,12 @@ def main():
     subp.add_argument('rvirs', nargs='+')
     subp.set_defaults(func=cmd_viirs_sci)
 
+    def cmd_spacecraft(args):
+        return spacecraft(args.satellite, args.rnsca, args.start, args.end)
+    subp = subs.add_parser('SPACECRAFT')
+    subp.add_argument('rnsca', nargs='+')
+    subp.set_defaults(func=cmd_spacecraft)
+
     args = parser.parse_args()
 
     if not args.end:
diff --git a/edosl0util/jpssrdr.py b/edosl0util/jpssrdr.py
index 20da569eb0ff79e82058dca0d670ada447f2bfce..bdb941b38325c298b77a046ce439e8c1118eba1a 100644
--- a/edosl0util/jpssrdr.py
+++ b/edosl0util/jpssrdr.py
@@ -185,7 +185,7 @@ def _find_telemetry_group(fobj):
 
 
 def _find_spacecraft_group(fobj):
-    return _find_data_group(fobj, 'SPACESCRAFT', sensors=['cris', 'atms'])
+    return _find_data_group(fobj, 'SPACECRAFT', sensors=['cris', 'atms'])
 
 
 def _rdrs_for_packet_dataset(group):
@@ -251,19 +251,32 @@ def _write_packets(pkts, dest, skipfill):
         dest.write(pkt.packet)
 
 
-def write_rdr_datasets(filepath, skipfill=False):
+def write_rdr_datasets(filepath, ancillary=False, skipfill=False):
     rdrname = os.path.basename(filepath)
     rdrs = rdr_datasets(filepath)
 
     for typekey in rdrs:
         if not rdrs[typekey]:
             continue
-        pktfile = '{}.{}.pkts'.format(rdrname, typekey)
-        LOG.debug('writing %s', pktfile)
-        with open(pktfile, 'wb') as dest:
-            for idx, rdr in enumerate(rdrs[typekey]):
-                LOG.debug(
-                    '... %s gran %d %s-%s-%s', typekey,
-                    idx, rdr.header.satellite, rdr.header.sensor, rdr.header.type_id)
-                _write_packets(rdr.packets(), dest, skipfill)
+        if ancillary and typekey == 'ancillary':
+            for idx, rdr in enumerate(rdrs['ancillary']):
+                packets = {a.value: rdr.packets_for_apid(a)
+                           for a in rdr.apids}
+                for apid, pkts in packets.items():
+                    LOG.debug(
+                        'writing ancillary gran %d %s-%s-%s %d',
+                        idx, rdr.header.satellite, rdr.header.sensor,
+                        rdr.header.type_id, apid)
+                    pktfile = '{}.{}{}.pkts'.format(rdrname, typekey, apid)
+                    with open(pktfile, 'ab') as dest:
+                        _write_packets(pkts, dest, skipfill)
+        else:
+            pktfile = '{}.{}.pkts'.format(rdrname, typekey)
+            LOG.debug('writing %s', pktfile)
+            with open(pktfile, 'wb') as dest:
+                for idx, rdr in enumerate(rdrs[typekey]):
+                    LOG.debug(
+                        '... %s gran %d %s-%s-%s', typekey,
+                        idx, rdr.header.satellite, rdr.header.sensor, rdr.header.type_id)
+                    _write_packets(rdr.packets(), dest, skipfill)
     return rdrs