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 assis 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_likelyindeterminatemeans 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:noneis 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 labelsbasis: the evidence the decision rests oncarriers: where instruction-bearing content was foundinstruction_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:
| Code | sis assess | sis sanitize / CDR release |
|---|---|---|
| 20 | hidden_instruction | manual_review |
| 30 | poisoning_likely | quarantine_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.
| code | label | meaning |
|---|---|---|
| 0 | none | read, and no instruction-bearing content found |
| 5 | indeterminate | could not read everything — not an all-clear |
| 10 | instruction_bearing | instructions present, human-visible too |
| 20 | hidden_instruction | instructions in a concealed channel |
| 30 | poisoning_likely | corroborated 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
Related guides
sis docs verdict(the malware axis and shared data model)sis docs extract(standalone textual extraction +--safesafe-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 behindsis.ingest_gate)sis docs investigate(the general triage loop)