SIS CLI

PDF Object & Export Reference (preview)

sis pdf-object and sis pdf-export are preview commands: output shapes and exit codes may change before 1.0. Both are PDF-only, addressed by the real object graph (not a saved report), and both refuse rather than silently misreport an encrypted or incomplete document.

sis pdf-object — raw/opaque access by object identity

Addresses one PDF object by (number, generation) and prints its parsed syntax, or — with --stream — its stream bytes.

sis pdf-object sample.pdf 45
sis pdf-object sample.pdf 45 0 --stream --decode
sis pdf-object sample.pdf 45 0 --stream --raw
sis pdf-object sample.pdf 45 0 --stream --hexdump
sis pdf-object sample.pdf 45 0 --stream --raw --extract-to streams
  • <OBJ> — the object number. [GEN] — the generation (defaults to 0).
  • --stream — treat the object as a stream and dump its bytes, instead of its parsed syntax.
  • --raw — the untouched on-disk bytes, no filter chain applied. Requires --stream.
  • --decode — the stream’s own filter chain applied (inflate etc.). Requires --stream explicitly, even though it is --stream’s own default when no mode flag is given: repeating the default without --stream is refused, not silently accepted as a no-op.
  • --hexdump — the decoded bytes, hex-formatted. Requires --stream. There is no mode that hex-dumps the untouched, undecoded bytes.
  • --extract-to <DIR> — write the full bytes to a directory instead of a bounded preview. Requires --stream.
  • --max-extract-bytes <N> — byte bound on the stream’s own decoded/raw output (default 128MiB). For --hexdump, the written file is roughly 5x this bound.

Every “Requires --stream” rule above is enforced by clap itself, before pdf-object’s own code runs: using --raw/--decode/--hexdump/--extract-to without --stream exits 2, not 1. A missing object on a complete object graph is the plain not-found error (exit 1). A missing object on an incomplete graph (cut short by the scan’s own object budget) is reported distinctly — exit 5 — because the object may exist past what was scanned. A hit on an incomplete graph still succeeds (exit 0), with a note on stderr that a later definition of the object may exist beyond the budget.

sis pdf-export — whole-shape export

Renders a derived structure of the whole document — a dependency graph, an event graph, an intermediate representation, a feature vector, or a content-stream summary — as one document.

sis pdf-export sample.pdf org
sis pdf-export sample.pdf structure --overlay
sis pdf-export sample.pdf structure --telemetry
sis pdf-export sample.pdf event
sis pdf-export sample.pdf event-stream --hops 2
sis pdf-export sample.pdf ir
sis pdf-export sample.pdf features --format csv
sis pdf-export sample.pdf events-full --format json
sis pdf-export sample.pdf stream-content --obj 8 --gen 0 --findings
sis pdf-export sample.pdf page-content --page 0
sis pdf-export sample.pdf content-graph --obj 8 --recursive
sis pdf-export sample.pdf page-content-graph --page 0 --recursive

Shapes (the <SHAPE> positional): org, structure, event, event-stream, ir, features, events-full, stream-content, page-content, content-graph, page-content-graph.

  • --format <text|json|csv> — output form. Default depends on the shape (matching each shape’s own bare spelling): json for shapes with only a JSON form; text/csv for ir/features’s own bare default; json for events-full’s own bare default.
  • --depth <N> — only for structure: caps the structure path helpers’ own recursion depth.
  • --overlay — only for structure: include the structure overlay (correlated findings projected onto the structure tree). Implied by --telemetry.
  • --telemetry — only for structure: include telemetry/signature detail in the overlay. Implies --overlay.
  • --hops <N> — only for event/event-stream: induces the hop-bounded subgraph around the graph’s own default seed nodes.
  • --recursive — only for stream-content/content-graph/page-content-graph: recurse into Form XObjects the content stream references. Refused on page-content.
  • --findings — only for stream-content/page-content: merge in correlated findings. Refused on content-graph/page-content-graph.
  • --obj <N> / --gen <N> — required for stream-content/content-graph: the object to address. --gen defaults to 0 and is refused without --obj.
  • --page <N> — required for page-content/page-content-graph: the 0-based page index.

Exit codes

Both commands share one table with scan, query and assess — the same number always means the same KIND of outcome:

CodeMeaning
0pdf-object: the object was printed. pdf-export: the shape was rendered, complete.
1A generic failure: unreadable input, a parse failure, or any other error with no distinct code. pdf-export also uses it for a shape/modifier mismatch its own grammar cannot express — a required --obj/--page missing, or a modifier refused for the shape — because that check runs at runtime, not inside clap.
2A usage/argument error rejected by clap itself, before either command’s own code ever runs: pdf-object — a missing or conflicting --stream flag, or a malformed object/generation number; pdf-export — an unknown <SHAPE> value or an unrecognised flag.
5Answered, but incomplete. pdf-object: the object was not found, and the object graph was truncated by a scan budget. pdf-export: the object graph was truncated by a scan budget, or a content stream within it could not be decoded. The object/shape may exist or be complete past what was scanned.

Exit 5 is never exit 3 — 3 is scan’s own runtime failure and query’s own execution failure, an unrelated condition this table deliberately does not reuse here.

pdf-object’s and pdf-export’s own 1/2 split differs, and it is worth stating plainly rather than papering over: pdf-object enforces every flag-combination rule through clap’s own requires/conflicts_with_all (so sis pdf-object f.pdf 1 --raw, missing --stream, exits 2), while pdf-export enforces its shape/modifier rules at runtime (so sis pdf-export f.pdf page-content, missing --page, exits 1; only an unknown <SHAPE> value or flag is clap’s own rejection, exiting 2).

Encrypted documents

sis pdf-export refuses outright on any shape when the document is encrypted (a trailer or dictionary names /Encrypt) or when encryption cannot be ruled out (no trailer was parsed, or the object scan was cut by a budget): a content-stream summary would otherwise report ciphertext as decoded content, and this command applies no decryption.

sis pdf-object is more granular, because --raw never claims to have decoded anything:

  • A plain object dump (no --stream) still prints, with a stderr note that the document is encrypted or not provably unencrypted and any string/stream bytes shown are ciphertext.
  • --stream --decode and --stream --hexdump are refused on an encrypted (or not-provably- unencrypted) document: both claim to show decoded content.
  • --stream --raw always works: it reports the stored bytes labelled as raw, never as decoded.

The incomplete marker

When a render is incomplete (exit 5), the output still carries as much as was built, plus an explicit marker so it is never mistaken for a complete, successful render:

  • JSON — the top-level object gains "incomplete": true and an "incomplete_note" string.
  • text and CSV — a leading line, # NOTE: <the same incomplete-note text>, is prepended.
  • sis docs query — the object/stream namespaces and the PDF-only REPL
  • sis docs investigate — where PDF object access fits in the wider investigation loop
  • sis docs formats — supported format coverage