SIS CLI

Intended-Use Assessment Guide (`sis assess`)

sis assess answers a different question from the malware verdict: is this document safe to feed to a model? It classifies a document’s AI-ingestion risk — hidden/embedded instructions, prompt-injection carriers, poisoning patterns — and emits a machine-actionable decision.

This is the AI-ingestion axis of the analyser, distinct from the malware verdict (see sis docs verdict). A file can be malware-Clean but ingestion-risky (or the reverse).

Command shape

sis assess <input> [options]
sis assess sample.docx --json
sis assess sample.pdf --deep --risk-dimensions --json

Options:

  • --json — machine-readable decision (recommended for automation)
  • --deep — deep analysis pass (same expensive detectors as sis scan --deep)
  • --risk-dimensions — include the full multi-axis risk breakdown
  • --config <path> — runtime policy / config (keep consistent with any paired scan)
  • --safe-text <dir> — emit extracted safe text to a directory
  • --safe-text-min-confidence <level> — minimum confidence for safe-text extraction

Decision shape

--json returns label, action, basis, carriers, and instruction_classes:

  • label: none | indeterminate | instruction_bearing | hidden_instruction | poisoning_likely
    • indeterminate means the analysis could not read everything — content exists that was never examined (an unreadable filter chain, an unopenable container), so neither “safe” nor “risky” has been established. It is not an all-clear: none is reserved for documents that were read and found to carry no instruction-bearing content.
  • action: the recommended disposition (e.g. allow) — adopt this as a policy decision, do not reconstruct it from labels
  • basis: the evidence the decision rests on
  • carriers: where instruction-bearing content was found
  • instruction_classes: the classes of instruction detected
sis assess sample.docx --json | jq '{label, action, instruction_classes}'

A none / allow result means no instruction-bearing or poisoning content was detected on the analysed axes. Treat anything above none as requiring review before model ingestion.

Exit codes

sis assess exits with a code matching the label, so a loader can gate on $? without parsing JSON. The ladder is ascending severity:

Exit codes collide across command families

The ladder is per-command, and two families overlap in the process-exit namespace:

Codesis assesssis sanitize / CDR release
20hidden_instructionmanual_review
30poisoning_likelyquarantine_original

A wrapper that gates a single command family can read $? directly — that is what the ladder is for. A wrapper spanning both cannot, because the same number means different things depending on which command produced it.

For that case pass --exit-code-mode generic, which projects onto shared classes:

0  completed; no requested gate blocked
1  a requested policy or assessment gate did not allow the use
2  usage or configuration error
3  analysis, query or transformation execution failure
4  input/output or persistence failure

The ranking is not lost — it stays in the structured output, which is where domain state belongs. What generic gives up is the ability to rank severity from $? alone.

codelabelmeaning
0noneread, and no instruction-bearing content found
5indeterminatecould not read everything — not an all-clear
10instruction_bearinginstructions present, human-visible too
20hidden_instructioninstructions in a concealed channel
30poisoning_likelycorroborated poisoning

A gate written as [ $? -lt 10 ] therefore keeps its existing threshold while no longer treating a document the analyser could not read as clean. Prefer adopting action over reconstructing a policy from the code or label.

Structural read-gate for MCP agents (sis.ingest_gate)

The guardian MCP server exposes a structural ingestion gate for AI agents, complementing the content-risk decision above. sis.ingest_gate { path, deny_formats } scans a file and returns an allow/deny decision based on whether the document’s asset-graph shape contains any disallowed format — e.g. deny pe/elf/js/vbs/lnk to refuse a document that nests an executable or script, however deeply.

// tool call
{ "path": "/intake/report.pdf", "deny_formats": ["pe", "elf", "js", "vbs", "lnk"] }
// result
{ "allowed": false, "shape": "pdf>zip>js",
  "denied_formats_present": ["js"],
  "reason": "document nests disallowed asset format(s): js" }

This is the containment-structure axis (from sis docs asset-graph / sis docs shape), decided on the projected shape — pair it with sis assess (the content axis) for a full ingestion posture.

When to use which surface

  • Feeding documents to a model / RAG pipeline → sis assess (content) + sis.ingest_gate (structure)
  • Classic malware triage → sis scan + sis docs investigate
  • Want the document cleaned for safe downstream use → sis docs cdr
  • sis docs verdict (the malware axis and shared data model)
  • sis docs extract (standalone textual extraction + --safe safe-text, for ingestion pipelines)
  • sis docs cdr (content disarm & reconstruction — produce a cleaned file)
  • sis docs flow (compose scan → ingest-risk → safe-text → egress as one workflow)
  • sis docs asset-graph / sis docs shape (the structural axis behind sis.ingest_gate)
  • sis docs investigate (the general triage loop)