Is json_decode parse-ability proof of a safe string? Do I need to use check_plain (or something else) when displaying a user supplied JSON string, when I have previously checked it successfully parses with json_decode?
TL;DR: You should check_plain it.

Because the json-enoded string itself can contain insecure code. 

This is our example. $data[1] and $data[2] should not be executed.

$data = array(
  'Hukana Matata',
  '&lt;script&gt;alert("Oh no!")&lt;/script&gt;',
  '&lt;a href="#" onclick="javascript:alert(\"Oh no!\')"&gt;CLick here&lt;/a&gt;',
);


You encode this with json_encode. If you json_decode($data_str), and it's a perfectly valid JSON.

$data_str = json_encode($data);


Now, if you print this:

print $data_str;


Now, you will see that the forward slash is escaped.

["Hukana Matata","&lt;script&gt;alert(\"Oh no!\")&lt;\/script&gt;","&lt;a href=\"#\" onclick=\"javascript:alert(\\\"Oh no!')\"&gt;CLick here&lt;\/a&gt;"]


json_encode encodes strings for JSON notation. In the example above, we encoded using json_encode from PHP's implementation. But depending on the flags, you can prevent PHP from doing do. 

$data = array(
      'Hukana Matata',
      '&lt;script&gt;alert(document.title)&lt;/script&gt;',
      '&lt;a href="#" onclick="javascript:alert(\"Oh no!\')"&gt;CLick here&lt;/a&gt;',
    );
$data_str = json_encode($data, JSON_UNESCAPED_SLASHES);
print $data_str;


Notice how the script tag sneaked in:

["Hukana Matata","&lt;script&gt;alert(document.title)&lt;/script&gt;","&lt;a href=\"#\" onclick=\"javascript:alert(\\\"Oh no!')\"&gt;CLick here&lt;/a&gt;"]