   100)
 
 
-; TODO: should this be a multimethod? byte arrays can be serialized 'raw'
-; and other structures can be printed canonically.
-(defn edn-blob
-  "Returns a canonical EDN representation suitable for serializing to a blob."
+(def ^:private ^:const blob-header
+  "Magic header which must appear as the first characters in a data blob."
+  "#vault/data")
+
+
+(defn- serialize-value
+  "Returns the canonical EDN representation for the given Clojure value."
   [value]
-  (let [doc (binding [puget/*colored-output* false
-                      puget/*strict-mode* true]
-              (puget/canonize value))
-        doc (if (puget/tagged-value-doc? doc)
-              (let [[op tag sep & more] doc]
-                `[~op ~tag :line ~@more])
-              doc)]
-    (-> doc
-        (pprint-document {:width blob-width})
+  (binding [puget/*colored-output* false
+            puget/*strict-mode* true]
+    (-> value
+        (puget/pprint {:width blob-width})
         with-out-str
         string/trim)))
 
 
-; PROBLEM:
-; An indexer is given a blob to index. From just the byte content, how can the
-; indexer tell (1) whether the blob has EDN content and (2) what type of data
-; does the content represent?
-;
-; IDEAS:
-; In some cases, the blob will be EXPECTED to contain EDN data, such as if a
-; content-type header specifies "application/edn", or if the value was linked
-; by another piece of data.
-;
-; From experiments trying to read randomly-generated byte sequences as EDN, if
-; the reader either throws an exception or returns a symbol, it's not a valid
-; EDN data blob.
-
-
-; PROBLEM:
-; Inline signatures need to sign the bytes which form the "primary value" in an
-; EDN data blob.
-;
-; IDEAS:
-; Write middle-layer proxy for InputStream or PushbackReader to capture bytes
-; from the beginning of the blob to one value read from the EDN reader.
+(defn edn-blob
+  "Returns a canonical EDN representation suitable for serializing to a blob."
+  [value]
+  (let [edn (serialize-value value)
+        metadata (select-keys (meta value) [:type :vault/version])
+        lines (if (empty? metadata)
+                [blob-header edn]
+                [blob-header (str \^ (serialize-value metadata)) edn])]
+    (string/join \newline lines)))
 
 
 (def data-readers

  (:require
    [clojure.string :as string]
    [fipp.printer :refer [pprint-document]]
    [puget.printer :as puget]))


(def ^:private ^:const blob-width

   'uri puget/read-uri})


(defn read-data
  "Reads the given input stream and attempts to parse it as an EDN data
  structure. If the data is not EDN, it returns a byte array of the blob
  contents."
  [input]
  ; input > capturing proxy > InputStreamReader > PushbackReader
  ; input > PushbackInputStream > capturing proxy > InputStreamReader > PushbackReader
  ; - read first (count blob-header) bytes from the stream
  ; - if no match, unread the bytes before returning the PushbackInputStream
  ; - otherwise, read remainder of stream and parse out EDN value(s)
  ; - first value is primary value - then save the output of the capturing proxy
  ;     - ideally, disable it
  ; - read remaining values (just signatures?)
  ;     - attach as value metadata?
  nil)
