{"repo": "berabuddies/semia", "files": {"README.md": {"379bc25fe99833eb185efe56a38fe15f0235799c": {"t": 1785674031.9539313, "n": 8545, "h": "fb2680e370fb9209", "c": "# Semia\n\n> **Security audit for AI agent skills.** Know what a skill *can* do\n> before you trust it.\n\n[![CI](https://github.com/berabuddies/Semia/actions/workflows/ci.yml/badge.svg)](https://github.com/berabuddies/Semia/actions/workflows/ci.yml)\n[![Lint](https://github.com/berabuddies/Semia/actions/workflows/lint.yml/badge.svg)](https://github.com/berabuddies/Semia/actions/workflows/lint.yml)\n[![codecov](https://codecov.io/gh/berabuddies/Semia/graph/badge.svg)](https://codecov.io/gh/berabuddies/Semia)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](pyproject.toml)\n\nAgent skills are markdown files with embedded shell commands, network calls,\nand tool invocations. They run with **your credentials, on your machine,\nwith your data**. Semia reads a skill as data — never executes it — and\nproduces an evidence-backed report of every capability it may exercise.\n\nIt is the difference between\n\n> *\"I trust this skill because the README looks fine.\"*\n\nand\n\n> *\"I trust this skill because Semia extracted 14 actions, 6 effects,\n> and 2 secret reads — and every one is grounded in a specific source line.\"*\n\n---\n\n## Quick example\n\nPick whichever fits how you already work.\n\n### As a CLI\n\n```bash\npip install semia-audit\nsemia scan ./some-skill\n```\n\n`scan` does prepare → synthesize (via your configured LLM provider) →\ndetect → report in one shot. Output lands under\n`.semia/runs//` by default — pass `--out ` to override.\nYou'll need an LLM provider configured first — see\n[Set up an LLM provider](#set-up-an-llm-provider) below.\n\n### Inside Codex, Claude Code, or OpenClaw\n\nInstall the plugin once. Each host has its own flow.\n\n**Codex** — pick either path:\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add berabuddies/Semia\n```\n\nThen enable the plugin by appending to `~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia@semia\"]\nenabled = true\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, toggle `semia` on from the\n newly-added marketplace.\n\n**Claude Code** — pick either path:\n\n*Shell (one-liner):*\n\n```bash\nclaude plugin marketplace add berabuddies/Semia\nclaude plugin install semia@semia\n```\n\n*Interactive plugin manager inside the Claude Code CLI:*\n\n1. Launch `claude`.\n2. Inside Claude Code, input `/plugins` (plural — opens the plugin panel).\n3. Press **→** (Right) twice and select **Add Marketplace**.\n4. Enter `berabuddies/Semia`.\n\nEither path registers the marketplace; finish installing `semia` from\nthe panel or with `claude plugin install semia@semia`.\n\n**OpenClaw** — one shell command registers the marketplace and installs:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nThen in any chat with the host agent just ask:\n\n> Run Semia audit on ./some-skill\n\nThe host agent itself acts as the synthesize step — **no API key needed**.\nThe bundled `semia.pyz` handles prepare / detect / report deterministically.\n\n### Fix what Semia finds\n\n```bash\nsemia repair .semia/runs/some-skill --from-scan\n```\n\n`repair` reads the findings and synthesized facts from an existing scan,\ntraces each violation back through the Datalog rules to identify the root\ncause, then calls an LLM to generate a SKILL.md patch — either fixing\nthe problematic content directly or adding specific security constraints.\n\n```bash\n# Or scan + repair in one shot:\nsemia repair ./some-skill\n```\n\n### Outputs\n\nYou get `report.md` — findings ranked by severity, every one tied to a\nspecific source line. Need [SARIF 2.1.0](https://sarifweb.azurewebsites.net/)\nfor GitHub Code Scanning, or structured JSON for downstream tooling? One\nmore command:\n\n```bash\nsemia report .semia/runs/some-skill --format sarif # for GitHub Code Scanning\nsemia report .semia/runs/some-skill --format json # structured payload\n```\n\n## Set up an LLM provider\n\n`semia scan` needs an LLM for the **synthesize** step (the other three\nstages are deterministic, no key required). If you run Semia via a host\nplugin (Codex / Claude Code / OpenClaw) skip this — the host agent already\ndoes synthesize for you.\n\nFour providers are supported. Pick one and export its credentials:\n\n```bash\n# OpenAI Responses API — default; also works for DeepSeek / OpenRouter / vLLM\nexport OPENAI_API_KEY=sk-...\n# optional: export OPENAI_BASE_URL=https://api.deepseek.com/v1\n\n# Anthropic Messages API\nexport SEMIA_LLM_PROVIDER=anthropic\nexport ANTHROPIC_API_KEY=sk-ant-...\n# optional: export ANTHROPIC_BASE_URL=https://api.anthropic.com\n\n# Locally-installed Claude Code CLI (uses your Claude Code login)\nexport SEMIA_LLM_PROVIDER=claude\n\n# Locally-installed Codex CLI (uses your Codex login)\nexport SEMIA_LLM_PROVIDER=codex\n```\n\nOverride the model with `--model ` on any `semia scan` invocation, or\npersist it via `SEMIA_LLM_MODEL`. Models are free-form strings — anything\nthe endpoint accepts (`gpt-5.5`, `deepseek-v4`, `claude-opus-4-7`, …).\n\nSee [Configuration](ADVANCED_USAGE.md#configuration) for the full provider\nmatrix, base-URL support, timeout/retry knobs, and synthesis-loop tuning.\n\n## What you get\n\nA run writes everything under `.semia/runs//`. **Most users only\never open the reports**:\n\n| Report | When |\n| ------------------- | --------------------------------------------------------- |\n| `report.md` | always produced by `semia scan` — read this first |\n| `report.sarif.json` | on demand via `semia report --format sarif` — feed to GitHub Code Scanning |\n| `report.json` | on demand via `semia report --format json` — structured payload (check + evidence + detector) for programmatic consumers |\n\nBecause every finding traces back to a source line, the SARIF drops cleanly\ninto GitHub Code Scanning and reviewers see annotations directly on the\nskill PR.\n\n
\nOther artifacts in the run directory (internal — for tooling, debugging, or re-querying)\n\n| Artifact | Purpose |\n| ------------------------- | -------------------------------------------------- |\n| `synthesized_facts.dl` | the behavior map (Datalog facts) — re-queryable |\n| `detection_findings.dl` | findings derived by rule evaluation |\n| `prepared_skill.md` | normalized skill text with stable line anchors |\n| `prepare_units.json` | reference units the evidence text aligns against |\n| `synthesis_metadata.json` | provider, model, retries, score, stop reason |\n| `run_manifest.json` | end-to-end manifest of the run |\n| `repair_result.json` | repair outcomes (when `semia repair` is run) |\n| `patched/SKILL.md` | the repaired SKILL.md (when `semia repair` is run) |\n\n
\n\n## More docs\n\n- [Advanced usage](ADVANCED_USAGE.md) covers the worked example, trust\n model, installation, configuration, and common workflows.\n- [Development](DEVELOPMENT.md) covers the repository layout and local\n development workflow.\n\n## Project background\n\nThe technique behind Semia is described in the Semia paper\n([arXiv:2605.00314](https://arxiv.org/abs/2605.00314) ·\n[PDF](https://arxiv.org/pdf/2605.00314)). Semia is the\n**deterministic acceptance boundary** around behavior mapping: agents may\nextract facts, but only checked, evidence-grounded facts make it into a\nreport.\n\n## Security\n\nTo report a security vulnerability, see [SECURITY.md](SECURITY.md). Please\ndo **not** file public GitHub issues for security problems.\n\n## Contributing\n\nContributions are welcome — bug reports, documentation fixes, detector\nrules, and code. See [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow\nand the DCO sign-off requirement.\n\n## License\n\nSemia is released under the [Apache License 2.0](LICENSE).\nCopyright 2026 RiemaLabs.\n\n## Citation\n\nIf you use this tool, please cite our paper:\n\n```bibtex\n@misc{wen2026semia,\n title = {Semia: Auditing Agent Skills via Constraint-Guided Representation Synthesis},\n author = {Wen, Hongbo and Li, Ying and Liu, Hanzhi and Shou, Chaofan and Chen, Yanju and Tian, Yuan and Feng, Yu},\n year = {2026},\n eprint = {2605.00314},\n archivePrefix = {arXiv},\n primaryClass = {cs.CR},\n doi = {10.48550/arXiv.2605.00314},\n url = {https://arxiv.org/abs/2605.00314}\n}\n```\n"}, "0ea9ebf04da0745d7525c8357251e8c990ba47e7": {"t": 1785762596.3031366, "n": 8545, "h": "fb2680e370fb9209", "c": "# Semia\n\n> **Security audit for AI agent skills.** Know what a skill *can* do\n> before you trust it.\n\n[![CI](https://github.com/berabuddies/Semia/actions/workflows/ci.yml/badge.svg)](https://github.com/berabuddies/Semia/actions/workflows/ci.yml)\n[![Lint](https://github.com/berabuddies/Semia/actions/workflows/lint.yml/badge.svg)](https://github.com/berabuddies/Semia/actions/workflows/lint.yml)\n[![codecov](https://codecov.io/gh/berabuddies/Semia/graph/badge.svg)](https://codecov.io/gh/berabuddies/Semia)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](pyproject.toml)\n\nAgent skills are markdown files with embedded shell commands, network calls,\nand tool invocations. They run with **your credentials, on your machine,\nwith your data**. Semia reads a skill as data — never executes it — and\nproduces an evidence-backed report of every capability it may exercise.\n\nIt is the difference between\n\n> *\"I trust this skill because the README looks fine.\"*\n\nand\n\n> *\"I trust this skill because Semia extracted 14 actions, 6 effects,\n> and 2 secret reads — and every one is grounded in a specific source line.\"*\n\n---\n\n## Quick example\n\nPick whichever fits how you already work.\n\n### As a CLI\n\n```bash\npip install semia-audit\nsemia scan ./some-skill\n```\n\n`scan` does prepare → synthesize (via your configured LLM provider) →\ndetect → report in one shot. Output lands under\n`.semia/runs//` by default — pass `--out ` to override.\nYou'll need an LLM provider configured first — see\n[Set up an LLM provider](#set-up-an-llm-provider) below.\n\n### Inside Codex, Claude Code, or OpenClaw\n\nInstall the plugin once. Each host has its own flow.\n\n**Codex** — pick either path:\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add berabuddies/Semia\n```\n\nThen enable the plugin by appending to `~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia@semia\"]\nenabled = true\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, toggle `semia` on from the\n newly-added marketplace.\n\n**Claude Code** — pick either path:\n\n*Shell (one-liner):*\n\n```bash\nclaude plugin marketplace add berabuddies/Semia\nclaude plugin install semia@semia\n```\n\n*Interactive plugin manager inside the Claude Code CLI:*\n\n1. Launch `claude`.\n2. Inside Claude Code, input `/plugins` (plural — opens the plugin panel).\n3. Press **→** (Right) twice and select **Add Marketplace**.\n4. Enter `berabuddies/Semia`.\n\nEither path registers the marketplace; finish installing `semia` from\nthe panel or with `claude plugin install semia@semia`.\n\n**OpenClaw** — one shell command registers the marketplace and installs:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nThen in any chat with the host agent just ask:\n\n> Run Semia audit on ./some-skill\n\nThe host agent itself acts as the synthesize step — **no API key needed**.\nThe bundled `semia.pyz` handles prepare / detect / report deterministically.\n\n### Fix what Semia finds\n\n```bash\nsemia repair .semia/runs/some-skill --from-scan\n```\n\n`repair` reads the findings and synthesized facts from an existing scan,\ntraces each violation back through the Datalog rules to identify the root\ncause, then calls an LLM to generate a SKILL.md patch — either fixing\nthe problematic content directly or adding specific security constraints.\n\n```bash\n# Or scan + repair in one shot:\nsemia repair ./some-skill\n```\n\n### Outputs\n\nYou get `report.md` — findings ranked by severity, every one tied to a\nspecific source line. Need [SARIF 2.1.0](https://sarifweb.azurewebsites.net/)\nfor GitHub Code Scanning, or structured JSON for downstream tooling? One\nmore command:\n\n```bash\nsemia report .semia/runs/some-skill --format sarif # for GitHub Code Scanning\nsemia report .semia/runs/some-skill --format json # structured payload\n```\n\n## Set up an LLM provider\n\n`semia scan` needs an LLM for the **synthesize** step (the other three\nstages are deterministic, no key required). If you run Semia via a host\nplugin (Codex / Claude Code / OpenClaw) skip this — the host agent already\ndoes synthesize for you.\n\nFour providers are supported. Pick one and export its credentials:\n\n```bash\n# OpenAI Responses API — default; also works for DeepSeek / OpenRouter / vLLM\nexport OPENAI_API_KEY=sk-...\n# optional: export OPENAI_BASE_URL=https://api.deepseek.com/v1\n\n# Anthropic Messages API\nexport SEMIA_LLM_PROVIDER=anthropic\nexport ANTHROPIC_API_KEY=sk-ant-...\n# optional: export ANTHROPIC_BASE_URL=https://api.anthropic.com\n\n# Locally-installed Claude Code CLI (uses your Claude Code login)\nexport SEMIA_LLM_PROVIDER=claude\n\n# Locally-installed Codex CLI (uses your Codex login)\nexport SEMIA_LLM_PROVIDER=codex\n```\n\nOverride the model with `--model ` on any `semia scan` invocation, or\npersist it via `SEMIA_LLM_MODEL`. Models are free-form strings — anything\nthe endpoint accepts (`gpt-5.5`, `deepseek-v4`, `claude-opus-4-7`, …).\n\nSee [Configuration](ADVANCED_USAGE.md#configuration) for the full provider\nmatrix, base-URL support, timeout/retry knobs, and synthesis-loop tuning.\n\n## What you get\n\nA run writes everything under `.semia/runs//`. **Most users only\never open the reports**:\n\n| Report | When |\n| ------------------- | --------------------------------------------------------- |\n| `report.md` | always produced by `semia scan` — read this first |\n| `report.sarif.json` | on demand via `semia report --format sarif` — feed to GitHub Code Scanning |\n| `report.json` | on demand via `semia report --format json` — structured payload (check + evidence + detector) for programmatic consumers |\n\nBecause every finding traces back to a source line, the SARIF drops cleanly\ninto GitHub Code Scanning and reviewers see annotations directly on the\nskill PR.\n\n
\nOther artifacts in the run directory (internal — for tooling, debugging, or re-querying)\n\n| Artifact | Purpose |\n| ------------------------- | -------------------------------------------------- |\n| `synthesized_facts.dl` | the behavior map (Datalog facts) — re-queryable |\n| `detection_findings.dl` | findings derived by rule evaluation |\n| `prepared_skill.md` | normalized skill text with stable line anchors |\n| `prepare_units.json` | reference units the evidence text aligns against |\n| `synthesis_metadata.json` | provider, model, retries, score, stop reason |\n| `run_manifest.json` | end-to-end manifest of the run |\n| `repair_result.json` | repair outcomes (when `semia repair` is run) |\n| `patched/SKILL.md` | the repaired SKILL.md (when `semia repair` is run) |\n\n
\n\n## More docs\n\n- [Advanced usage](ADVANCED_USAGE.md) covers the worked example, trust\n model, installation, configuration, and common workflows.\n- [Development](DEVELOPMENT.md) covers the repository layout and local\n development workflow.\n\n## Project background\n\nThe technique behind Semia is described in the Semia paper\n([arXiv:2605.00314](https://arxiv.org/abs/2605.00314) ·\n[PDF](https://arxiv.org/pdf/2605.00314)). Semia is the\n**deterministic acceptance boundary** around behavior mapping: agents may\nextract facts, but only checked, evidence-grounded facts make it into a\nreport.\n\n## Security\n\nTo report a security vulnerability, see [SECURITY.md](SECURITY.md). Please\ndo **not** file public GitHub issues for security problems.\n\n## Contributing\n\nContributions are welcome — bug reports, documentation fixes, detector\nrules, and code. See [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow\nand the DCO sign-off requirement.\n\n## License\n\nSemia is released under the [Apache License 2.0](LICENSE).\nCopyright 2026 RiemaLabs.\n\n## Citation\n\nIf you use this tool, please cite our paper:\n\n```bibtex\n@misc{wen2026semia,\n title = {Semia: Auditing Agent Skills via Constraint-Guided Representation Synthesis},\n author = {Wen, Hongbo and Li, Ying and Liu, Hanzhi and Shou, Chaofan and Chen, Yanju and Tian, Yuan and Feng, Yu},\n year = {2026},\n eprint = {2605.00314},\n archivePrefix = {arXiv},\n primaryClass = {cs.CR},\n doi = {10.48550/arXiv.2605.00314},\n url = {https://arxiv.org/abs/2605.00314}\n}\n```\n"}, "1976791cb20ddc608f55613008e81a366c122117": {"t": 1785762597.784606, "n": 21011, "h": "29a60b0dfaed1b7b", "c": "# Semia\n\n> **Security audit for AI agent skills.** Know what a skill *can* do\n> before you trust it.\n\n[![CI](https://github.com/berabuddies/Semia/actions/workflows/ci.yml/badge.svg)](https://github.com/berabuddies/Semia/actions/workflows/ci.yml)\n[![Lint](https://github.com/berabuddies/Semia/actions/workflows/lint.yml/badge.svg)](https://github.com/berabuddies/Semia/actions/workflows/lint.yml)\n[![codecov](https://codecov.io/gh/berabuddies/Semia/graph/badge.svg)](https://codecov.io/gh/berabuddies/Semia)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](pyproject.toml)\n\nAgent skills are markdown files with embedded shell commands, network calls,\nand tool invocations. They run with **your credentials, on your machine,\nwith your data**. Semia reads a skill as data — never executes it — and\nproduces an evidence-backed report of every capability it may exercise.\n\nIt is the difference between\n\n> *\"I trust this skill because the README looks fine.\"*\n\nand\n\n> *\"I trust this skill because Semia extracted 14 actions, 6 effects,\n> and 2 secret reads — and every one is grounded in a specific source line.\"*\n\n---\n\n## Quick example\n\nPick whichever fits how you already work.\n\n### As a CLI\n\n```bash\npip install semia-audit\nsemia scan ./some-skill\n```\n\n`scan` does prepare → synthesize (via your configured LLM provider) →\ndetect → report in one shot. Output lands under\n`.semia/runs//` by default — pass `--out ` to override.\nYou'll need an LLM provider configured first — see\n[Set up an LLM provider](#set-up-an-llm-provider) below.\n\n### Inside Codex, Claude Code, or OpenClaw\n\nInstall the plugin once. Each host has its own flow.\n\n**Codex** — pick either path:\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add berabuddies/Semia\n```\n\nThen enable the plugin by appending to `~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia@semia\"]\nenabled = true\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, toggle `semia` on from the\n newly-added marketplace.\n\n**Claude Code** — pick either path:\n\n*Shell (one-liner):*\n\n```bash\nclaude plugin marketplace add berabuddies/Semia\nclaude plugin install semia@semia\n```\n\n*Interactive plugin manager inside the Claude Code CLI:*\n\n1. Launch `claude`.\n2. Inside Claude Code, input `/plugins` (plural — opens the plugin panel).\n3. Press **→** (Right) twice and select **Add Marketplace**.\n4. Enter `berabuddies/Semia`.\n\nEither path registers the marketplace; finish installing `semia` from\nthe panel or with `claude plugin install semia@semia`.\n\n**OpenClaw** — one shell command registers the marketplace and installs:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nThen in any chat with the host agent just ask:\n\n> Run Semia audit on ./some-skill\n\nThe host agent itself acts as the synthesize step — **no API key needed**.\nThe bundled `semia.pyz` handles prepare / detect / report deterministically.\n\n### Fix what Semia finds\n\n```bash\nsemia repair .semia/runs/some-skill --from-scan\n```\n\n`repair` reads the findings and synthesized facts from an existing scan,\ntraces each violation back through the Datalog rules to identify the root\ncause, then calls an LLM to generate a SKILL.md patch — either fixing\nthe problematic content directly or adding specific security constraints.\n\n```bash\n# Or scan + repair in one shot:\nsemia repair ./some-skill\n```\n\n### Outputs\n\nYou get `report.md` — findings ranked by severity, every one tied to a\nspecific source line. Need [SARIF 2.1.0](https://sarifweb.azurewebsites.net/)\nfor GitHub Code Scanning, or structured JSON for downstream tooling? One\nmore command:\n\n```bash\nsemia report .semia/runs/some-skill --format sarif # for GitHub Code Scanning\nsemia report .semia/runs/some-skill --format json # structured payload\n```\n\n## Set up an LLM provider\n\n`semia scan` needs an LLM for the **synthesize** step (the other three\nstages are deterministic, no key required). If you run Semia via a host\nplugin (Codex / Claude Code / OpenClaw) skip this — the host agent already\ndoes synthesize for you.\n\nFour providers are supported. Pick one and export its credentials:\n\n```bash\n# OpenAI Responses API — default; also works for DeepSeek / OpenRouter / vLLM\nexport OPENAI_API_KEY=sk-...\n# optional: export OPENAI_BASE_URL=https://api.deepseek.com/v1\n\n# Anthropic Messages API\nexport SEMIA_LLM_PROVIDER=anthropic\nexport ANTHROPIC_API_KEY=sk-ant-...\n# optional: export ANTHROPIC_BASE_URL=https://api.anthropic.com\n\n# Locally-installed Claude Code CLI (uses your Claude Code login)\nexport SEMIA_LLM_PROVIDER=claude\n\n# Locally-installed Codex CLI (uses your Codex login)\nexport SEMIA_LLM_PROVIDER=codex\n```\n\nOverride the model with `--model ` on any `semia scan` invocation, or\npersist it via `SEMIA_LLM_MODEL`. Models are free-form strings — anything\nthe endpoint accepts (`gpt-5.5`, `deepseek-v4`, `claude-opus-4-7`, …).\n\nSee [Configuration](#configuration) for the full provider matrix, base-URL\nsupport, timeout/retry knobs, and synthesis-loop tuning.\n\n## What you get\n\nA run writes everything under `.semia/runs//`. **Most users only\never open the reports**:\n\n| Report | When |\n| ------------------- | --------------------------------------------------------- |\n| `report.md` | always produced by `semia scan` — read this first |\n| `report.sarif.json` | on demand via `semia report --format sarif` — feed to GitHub Code Scanning |\n| `report.json` | on demand via `semia report --format json` — structured payload (check + evidence + detector) for programmatic consumers |\n\nBecause every finding traces back to a source line, the SARIF drops cleanly\ninto GitHub Code Scanning and reviewers see annotations directly on the\nskill PR.\n\n
\nOther artifacts in the run directory (internal — for tooling, debugging, or re-querying)\n\n| Artifact | Purpose |\n| ------------------------- | -------------------------------------------------- |\n| `synthesized_facts.dl` | the behavior map (Datalog facts) — re-queryable |\n| `detection_findings.dl` | findings derived by rule evaluation |\n| `prepared_skill.md` | normalized skill text with stable line anchors |\n| `prepare_units.json` | reference units the evidence text aligns against |\n| `synthesis_metadata.json` | provider, model, retries, score, stop reason |\n| `run_manifest.json` | end-to-end manifest of the run |\n| `repair_result.json` | repair outcomes (when `semia repair` is run) |\n| `patched/SKILL.md` | the repaired SKILL.md (when `semia repair` is run) |\n\n
\n\n## Worked example\n\nPicture a skill that promises to \"summarize your inbox every day\". It\ninstalls a browser automation tool, opens your real Chrome (with every\nsaved login), reads Gmail, pipes the messages to an LLM that controls\nthe browser, and sets up a launchd job to repeat daily — forever. One\nemail from an attacker turns that skill into a remote control for every\nsite you are logged into.\n\n[See **EXAMPLE.md** for the full walkthrough →](EXAMPLE.md) — the skill\nsource, the attack, why it works, and the exact capabilities Semia\nsurfaces before you install.\n\n## How it works\n\n```text\n ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌────────┐\n │ Prepare │ ──▶ │ Synthesize │ ──▶ │ Detect │ ──▶ │ Report │\n │ (det.) │ │ (LLM) │ │ (det.) │ │ (det.) │\n └──────────┘ └────────────┘ └──────────┘ └────────┘\n```\n\n1. **Prepare** — read skill markdown + adjacent source, inline references,\n assign stable evidence handles. Pure stdlib. No LLM.\n2. **Synthesize** — an LLM (or the host agent's own session) extracts a\n *behavior map* as Datalog facts (`action`, `call`, `call_effect`, …)\n with `_evidence_text` sidecars citing the original source. The loop\n retries invalid candidates with checker feedback and keeps the best one.\n3. **Detect** — a Datalog evaluator runs the bundled SDL rules over the\n facts to flag risky combinations (e.g. *secret read → network write*).\n4. **Report** — render Markdown for humans and SARIF for CI.\n5. **Repair** *(optional)* — trace each finding back through the Datalog\n rules to identify which facts caused it, then call an LLM to generate\n a SKILL.md patch. The patch either fixes the problematic content\n (e.g. replacing a hardcoded IP) or adds specific security constraints\n (e.g. \"Never execute `blockchain.send_transaction()` without user\n confirmation\"). The tracer and prompt builder are deterministic; only\n the patch generation step calls the LLM.\n\nDetection runs through a built-in pure-Python Datalog evaluator by default,\nso **no external binary is required**. If [Soufflé](https://souffle-lang.github.io/)\nis on `PATH` (or `SEMIA_SOUFFLE_BIN`) it is preferred as a faster backend.\nOverride with `SEMIA_DETECTOR_BACKEND=auto|souffle|builtin`.\n\n[Read the full architecture →](docs/architecture.md)\n\n## Trust model\n\nSemia is a security tool for analyzing untrusted content. The trust\nboundary is explicit:\n\n| Surface | Treatment |\n| ------------------------- | -------------------------------------------------------------------------------- |\n| Audited skill | **untrusted data** — never executed, hooks/installers ignored |\n| Skill-declared URLs | **never fetched** during a scan |\n| Prompt-injection in skill | **recorded as evidence**, not followed as instructions |\n| Prepare / Detect / Report | deterministic, stdlib-friendly, runs locally |\n| Synthesize | the only LLM-mediated step; output must pass structural and evidence checks |\n| Network | LLM provider only |\n| Filesystem | reads the skill directory; writes only `.semia/runs//` |\n\nSee [docs/plugin-protocol.md#hostile-input-rules](docs/plugin-protocol.md)\nfor the full host-integration contract, and\n[SECURITY.md](SECURITY.md) for vulnerability reporting.\n\n## Install\n\nFrom source (current):\n\n```bash\ngit clone https://github.com/berabuddies/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\n```\n\nPython 3.11+ required. The project has **zero runtime dependencies** — both\nthe `responses` and `anthropic` providers talk to their APIs over raw HTTP\nusing the standard library.\n\n## Configuration\n\nSettings come from CLI flags, environment variables, or a repo-local\n`.env`. Copy [`.env.example`](.env.example) to `.env` and fill in your\ncredentials — `.env` is gitignored, and the pre-commit `gitleaks` hook\nruns locally against staged changes so secrets do not reach the history.\n\n### Providers\n\nSemia routes synthesis through one of four providers — two HTTP wire\nformats and two local CLI shell-outs. The default is `responses` with\nmodel `gpt-5.5`, authenticated via `OPENAI_API_KEY`.\n\n| Provider | Transport | Default model | Honors `--base-url` | Auth |\n| ------------ | ---------------------------------- | ------------------- | ------------------- | ----------------------------------------------------------------- |\n| `responses` | OpenAI Responses API (raw HTTP) | `gpt-5.5` | yes | `OPENAI_API_KEY`; `OPENAI_BASE_URL` (defaults to api.openai.com) |\n| `anthropic` | Anthropic Messages API (raw HTTP) | `claude-opus-4-7` | yes | `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`; `ANTHROPIC_BASE_URL` |\n| `codex` | shells out to `codex exec` | Codex CLI's own | no | inherits Codex CLI config |\n| `claude` | shells out to `claude --print` | `claude-opus-4-7` | no | inherits Claude Code env (`ANTHROPIC_*`) |\n\n`openai` is accepted as a synonym for `responses`. The **model** is free-form\n— any string the endpoint accepts works (`gpt-5.5`, `gpt-5.4`,\n`gpt-5.3-codex`, `deepseek-v4`, `claude-opus-4-7`, `claude-opus-4-6`, …).\n\nSwitch with flags:\n\n```bash\n# Default: OpenAI Responses against api.openai.com\nsemia scan ./some-skill\n\n# Anthropic Messages against api.anthropic.com\nsemia scan ./some-skill --provider anthropic\n\n# Point the responses format at a different endpoint (DeepSeek, OpenRouter, vLLM, …)\nsemia scan ./some-skill \\\n --provider responses --model deepseek-v4 \\\n --base-url https://api.deepseek.com/v1\n\n# Use the locally-installed Claude Code CLI (model is the only knob)\nsemia scan ./some-skill --provider claude --model claude-opus-4-7\n```\n\nEach of these lands output under `.semia/runs/some-skill/`. Pass\n`--out ` if you want a custom run directory.\n\n### Most common environment variables\n\n| Variable | Purpose |\n| --------------------------- | -------------------------------------------------------------------- |\n| `SEMIA_LLM_PROVIDER` | `responses` (default) / `anthropic` / `codex` / `claude` |\n| `SEMIA_LLM_MODEL` | free-form model name passed to the provider |\n| `SEMIA_LLM_TIMEOUT` | request timeout in seconds |\n| `SEMIA_LLM_MAX_RETRIES` | retry budget for transient provider errors |\n| `OPENAI_BASE_URL` | base URL for the `responses` provider |\n| `ANTHROPIC_BASE_URL` | base URL for the `anthropic` provider |\n| `SEMIA_DETECTOR_BACKEND` | `auto` (default), `souffle`, `builtin` |\n| `SEMIA_SOUFFLE_BIN` | path to `souffle` if not on `PATH` |\n\nFor full synthesis tuning (`SEMIA_SYNTHESIS_*`), see the rest of\n[`.env.example`](.env.example) and\n[docs/plugin-protocol.md](docs/plugin-protocol.md).\n\n## Common workflows\n\n**Stop after deterministic preparation:**\n```bash\nsemia scan ./some-skill --prepare-only\n```\n\n**Reuse facts from a prior run or an agent session:**\n```bash\nsemia scan ./some-skill --facts synthesized_facts.dl\nsemia report .semia/runs/some-skill --format sarif\n```\n\n**CI smoke test (no LLM call):**\n```bash\nsemia scan ./some-skill --offline-baseline\n```\n> `--offline-baseline` is a conservative non-LLM fallback for offline demos\n> and CI smoke tests. It is **not** a substitute for real synthesis.\n\n**Repair a scanned skill (generate SKILL.md patch):**\n```bash\n# From an existing scan run:\nsemia repair .semia/runs/some-skill --from-scan\n\n# Scan + repair in one shot:\nsemia repair ./some-skill\n\n# Trace only (see what to fix, without generating patches):\nsemia repair .semia/runs/some-skill --from-scan --trace-only\n```\n\n## Install as a host plugin\n\nThe Codex and Claude Code plugin bundles under `packages/semia-plugins//`\nship with a self-contained `bin/semia.pyz` zipapp, so they work out of the\nbox without a separate `pip install semia-audit`. The OpenClaw skill\nrelies on the published `semia` CLI on `PATH` (ClawHub provisions it via\n`uv tool install`). Installing the Python package as well is recommended if\nyou want `semia` available as a normal shell command alongside the in-host\nworkflow.\n\n**Codex** — pick either path.\n\n> `codex plugin` only exposes a `marketplace` subcommand (`add` /\n> `upgrade` / `remove`) — there is **no `codex plugin install`**.\n> \"Installing\" a plugin means enabling the\n> `[plugins.\"@\"]` toggle in `~/.codex/config.toml`,\n> either via the `/plugins` TUI panel or by editing the file directly.\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add berabuddies/Semia\n```\n\nThen append the plugin toggle to `~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia@semia\"]\nenabled = true\n```\n\nThe second `semia` is the marketplace identifier (the top-level\n`name` in this repo's `.agents/plugins/marketplace.json`); the first\n`semia` is the plugin entry under it. For a one-shot non-persistent\nrun you can use `codex -c 'plugins.\"semia@semia\".enabled=true'`\ninstead of editing the file.\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, toggle `semia` on from the newly-added\n marketplace (the panel writes the same `[plugins.\"semia@semia\"]`\n block into `~/.codex/config.toml` for you).\n\n**Claude Code** — pick either path.\n\n*Shell (scripts and CI):*\n\n```bash\nclaude plugin marketplace add berabuddies/Semia\nclaude plugin install semia@semia\n```\n\n*Interactive plugin manager inside the Claude Code CLI:*\n\n1. Launch `claude`.\n2. Inside Claude Code, input `/plugins` (plural — opens the plugin panel).\n3. Press **→** (Right) twice and select **Add Marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, install `semia` from the newly-added marketplace.\n\nThe `name@marketplace` form on `install` is required — the second `semia`\nis the marketplace identifier from the project's `marketplace.json`.\nUse `--scope user|project|local` on the shell form to control where the\nplugin is recorded (default is `user`):\n\n```bash\nclaude plugin install semia@semia --scope project\n```\n\nSee [Discover and install plugins](https://code.claude.com/docs/en/discover-plugins)\nfor the full UX and [Plugins reference](https://code.claude.com/docs/en/plugins-reference#cli-commands-reference)\nfor the complete list of `claude plugin ...` subcommands.\n\n**OpenClaw** — install from ClawHub:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nClawHub will install the `semia` CLI on demand via `uv tool install\nsemia-audit` (declared in the skill's `install` block). If you prefer to\npre-provision it yourself:\n\n```bash\nuv tool install semia-audit # or: pip install semia-audit\nopenclaw plugins install clawhub:semia\n```\n\n## Repository layout\n\n```text\npackages/\n semia-core/ # deterministic analysis library (prepare, check, detect, report)\n semia-cli/ # `semia` command surface\n semia-plugins/ # Codex / Claude Code / OpenClaw integrations\ndocs/\n architecture.md\n plugin-protocol.md\n release.md\n supply-chain.md\ntests/\n\n```\n\n## Development\n\n```bash\ngit clone https://github.com/berabuddies/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\npython -m pip install pre-commit\npre-commit install\npre-commit run --all-files # establish a clean baseline\n\nmake help # list targets\nmake check # compile + tests + manifest validation\nmake build # package metadata check\nmake release-check # full pre-release gate\n```\n\nThe root quality gates stay stdlib-friendly: `compileall`, `unittest`\ndiscovery, and stdlib-only validators. Pre-commit adds `ruff` lint/format\nand `gitleaks` secret scanning. CI mirrors `ruff` via\n[`lint.yml`](.github/workflows/lint.yml); `gitleaks` stays local-only\nbecause the upstream GitHub Action now requires a paid license for\norganization repositories.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow and the DCO\nsign-off requirement.\n\n## Project background\n\nThe technique behind Semia is described in the Semia paper\n([arXiv:2605.00314](https://arxiv.org/abs/2605.00314) ·\n[PDF](https://arxiv.org/pdf/2605.00314)). Semia is the\n**deterministic acceptance boundary** around behavior mapping: agents may\nextract facts, but only checked, evidence-grounded facts make it into a\nreport.\n\n## Security\n\nTo report a security vulnerability, see [SECURITY.md](SECURITY.md). Please\ndo **not** file public GitHub issues for security problems.\n\n## Contributing\n\nContributions are welcome — bug reports, documentation fixes, detector\nrules, and code. See [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow\nand the DCO sign-off requirement.\n\n## License & trademarks\n\nSemia is released under the [Apache License 2.0](LICENSE). You\nmay use, modify, and redistribute it freely, including for commercial\npurposes, subject to the terms of the license. See [NOTICE](NOTICE) for\nattribution.\n\nThe names **\"Semia\"**, **\"Semia\"**, **\"Semia\"**, and\n**\"berabuddies\"** are trademarks of berabuddies and are **not** licensed under\nApache-2.0. See [TRADEMARKS.md](TRADEMARKS.md) for the trademark policy.\n"}, "317e213a5816881d0908a4c3b3d49771b7ce6423": {"t": 1785762603.1701272, "n": 19600, "h": "41d9060ba71df1b9", "c": "# Semia\n\n> **Security audit for AI agent skills.** Know what a skill *can* do\n> before you trust it.\n\n[![CI](https://github.com/berabuddies/Semia/actions/workflows/ci.yml/badge.svg)](https://github.com/berabuddies/Semia/actions/workflows/ci.yml)\n[![Lint](https://github.com/berabuddies/Semia/actions/workflows/lint.yml/badge.svg)](https://github.com/berabuddies/Semia/actions/workflows/lint.yml)\n[![codecov](https://codecov.io/gh/berabuddies/Semia/graph/badge.svg)](https://codecov.io/gh/berabuddies/Semia)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](pyproject.toml)\n\nAgent skills are markdown files with embedded shell commands, network calls,\nand tool invocations. They run with **your credentials, on your machine,\nwith your data**. Semia reads a skill as data — never executes it — and\nproduces an evidence-backed report of every capability it may exercise.\n\nIt is the difference between\n\n> *\"I trust this skill because the README looks fine.\"*\n\nand\n\n> *\"I trust this skill because Semia extracted 14 actions, 6 effects,\n> and 2 secret reads — and every one is grounded in a specific source line.\"*\n\n---\n\n## Quick example\n\nPick whichever fits how you already work.\n\n### As a CLI\n\n```bash\npip install semia-audit\nsemia scan ./some-skill\n```\n\n`scan` does prepare → synthesize (via your configured LLM provider) →\ndetect → report in one shot. Output lands under\n`.semia/runs//` by default — pass `--out ` to override.\nYou'll need an LLM provider configured first — see\n[Set up an LLM provider](#set-up-an-llm-provider) below.\n\n### Inside Codex, Claude Code, or OpenClaw\n\nInstall the plugin once. Each host has its own flow.\n\n**Codex** — pick either path:\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add berabuddies/Semia\n```\n\nThen enable the plugin by appending to `~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia@semia\"]\nenabled = true\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, toggle `semia` on from the\n newly-added marketplace.\n\n**Claude Code** — pick either path:\n\n*Shell (one-liner):*\n\n```bash\nclaude plugin marketplace add berabuddies/Semia\nclaude plugin install semia@semia\n```\n\n*Interactive plugin manager inside the Claude Code CLI:*\n\n1. Launch `claude`.\n2. Inside Claude Code, input `/plugins` (plural — opens the plugin panel).\n3. Press **→** (Right) twice and select **Add Marketplace**.\n4. Enter `berabuddies/Semia`.\n\nEither path registers the marketplace; finish installing `semia` from\nthe panel or with `claude plugin install semia@semia`.\n\n**OpenClaw** — one shell command registers the marketplace and installs:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nThen in any chat with the host agent just ask:\n\n> Run Semia audit on ./some-skill\n\nThe host agent itself acts as the synthesize step — **no API key needed**.\nThe bundled `semia.pyz` handles prepare / detect / report deterministically.\n\n### Outputs\n\nYou get `report.md` — findings ranked by severity, every one tied to a\nspecific source line. Need [SARIF 2.1.0](https://sarifweb.azurewebsites.net/)\nfor GitHub Code Scanning, or structured JSON for downstream tooling? One\nmore command:\n\n```bash\nsemia report .semia/runs/some-skill --format sarif # for GitHub Code Scanning\nsemia report .semia/runs/some-skill --format json # structured payload\n```\n\n## Set up an LLM provider\n\n`semia scan` needs an LLM for the **synthesize** step (the other three\nstages are deterministic, no key required). If you run Semia via a host\nplugin (Codex / Claude Code / OpenClaw) skip this — the host agent already\ndoes synthesize for you.\n\nFour providers are supported. Pick one and export its credentials:\n\n```bash\n# OpenAI Responses API — default; also works for DeepSeek / OpenRouter / vLLM\nexport OPENAI_API_KEY=sk-...\n# optional: export OPENAI_BASE_URL=https://api.deepseek.com/v1\n\n# Anthropic Messages API\nexport SEMIA_LLM_PROVIDER=anthropic\nexport ANTHROPIC_API_KEY=sk-ant-...\n# optional: export ANTHROPIC_BASE_URL=https://api.anthropic.com\n\n# Locally-installed Claude Code CLI (uses your Claude Code login)\nexport SEMIA_LLM_PROVIDER=claude\n\n# Locally-installed Codex CLI (uses your Codex login)\nexport SEMIA_LLM_PROVIDER=codex\n```\n\nOverride the model with `--model ` on any `semia scan` invocation, or\npersist it via `SEMIA_LLM_MODEL`. Models are free-form strings — anything\nthe endpoint accepts (`gpt-5.5`, `deepseek-v4`, `claude-opus-4-7`, …).\n\nSee [Configuration](#configuration) for the full provider matrix, base-URL\nsupport, timeout/retry knobs, and synthesis-loop tuning.\n\n## What you get\n\nA run writes everything under `.semia/runs//`. **Most users only\never open the reports**:\n\n| Report | When |\n| ------------------- | --------------------------------------------------------- |\n| `report.md` | always produced by `semia scan` — read this first |\n| `report.sarif.json` | on demand via `semia report --format sarif` — feed to GitHub Code Scanning |\n| `report.json` | on demand via `semia report --format json` — structured payload (check + evidence + detector) for programmatic consumers |\n\nBecause every finding traces back to a source line, the SARIF drops cleanly\ninto GitHub Code Scanning and reviewers see annotations directly on the\nskill PR.\n\n
\nOther artifacts in the run directory (internal — for tooling, debugging, or re-querying)\n\n| Artifact | Purpose |\n| ------------------------- | -------------------------------------------------- |\n| `synthesized_facts.dl` | the behavior map (Datalog facts) — re-queryable |\n| `detection_findings.dl` | findings derived by rule evaluation |\n| `prepared_skill.md` | normalized skill text with stable line anchors |\n| `prepare_units.json` | reference units the evidence text aligns against |\n| `synthesis_metadata.json` | provider, model, retries, score, stop reason |\n| `run_manifest.json` | end-to-end manifest of the run |\n\n
\n\n## Worked example\n\nPicture a skill that promises to \"summarize your inbox every day\". It\ninstalls a browser automation tool, opens your real Chrome (with every\nsaved login), reads Gmail, pipes the messages to an LLM that controls\nthe browser, and sets up a launchd job to repeat daily — forever. One\nemail from an attacker turns that skill into a remote control for every\nsite you are logged into.\n\n[See **EXAMPLE.md** for the full walkthrough →](EXAMPLE.md) — the skill\nsource, the attack, why it works, and the exact capabilities Semia\nsurfaces before you install.\n\n## How it works\n\n```text\n ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌────────┐\n │ Prepare │ ──▶ │ Synthesize │ ──▶ │ Detect │ ──▶ │ Report │\n │ (det.) │ │ (LLM) │ │ (det.) │ │ (det.) │\n └──────────┘ └────────────┘ └──────────┘ └────────┘\n```\n\n1. **Prepare** — read skill markdown + adjacent source, inline references,\n assign stable evidence handles. Pure stdlib. No LLM.\n2. **Synthesize** — an LLM (or the host agent's own session) extracts a\n *behavior map* as Datalog facts (`action`, `call`, `call_effect`, …)\n with `_evidence_text` sidecars citing the original source. The loop\n retries invalid candidates with checker feedback and keeps the best one.\n3. **Detect** — a Datalog evaluator runs the bundled SDL rules over the\n facts to flag risky combinations (e.g. *secret read → network write*).\n4. **Report** — render Markdown for humans and SARIF for CI.\n\nDetection runs through a built-in pure-Python Datalog evaluator by default,\nso **no external binary is required**. If [Soufflé](https://souffle-lang.github.io/)\nis on `PATH` (or `SEMIA_SOUFFLE_BIN`) it is preferred as a faster backend.\nOverride with `SEMIA_DETECTOR_BACKEND=auto|souffle|builtin`.\n\n[Read the full architecture →](docs/architecture.md)\n\n## Trust model\n\nSemia is a security tool for analyzing untrusted content. The trust\nboundary is explicit:\n\n| Surface | Treatment |\n| ------------------------- | -------------------------------------------------------------------------------- |\n| Audited skill | **untrusted data** — never executed, hooks/installers ignored |\n| Skill-declared URLs | **never fetched** during a scan |\n| Prompt-injection in skill | **recorded as evidence**, not followed as instructions |\n| Prepare / Detect / Report | deterministic, stdlib-friendly, runs locally |\n| Synthesize | the only LLM-mediated step; output must pass structural and evidence checks |\n| Network | LLM provider only |\n| Filesystem | reads the skill directory; writes only `.semia/runs//` |\n\nSee [docs/plugin-protocol.md#hostile-input-rules](docs/plugin-protocol.md)\nfor the full host-integration contract, and\n[SECURITY.md](SECURITY.md) for vulnerability reporting.\n\n## Install\n\nFrom source (current):\n\n```bash\ngit clone https://github.com/berabuddies/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\n```\n\nPython 3.11+ required. The project has **zero runtime dependencies** — both\nthe `responses` and `anthropic` providers talk to their APIs over raw HTTP\nusing the standard library.\n\n## Configuration\n\nSettings come from CLI flags, environment variables, or a repo-local\n`.env`. Copy [`.env.example`](.env.example) to `.env` and fill in your\ncredentials — `.env` is gitignored, and the pre-commit `gitleaks` hook\nruns locally against staged changes so secrets do not reach the history.\n\n### Providers\n\nSemia routes synthesis through one of four providers — two HTTP wire\nformats and two local CLI shell-outs. The default is `responses` with\nmodel `gpt-5.5`, authenticated via `OPENAI_API_KEY`.\n\n| Provider | Transport | Default model | Honors `--base-url` | Auth |\n| ------------ | ---------------------------------- | ------------------- | ------------------- | ----------------------------------------------------------------- |\n| `responses` | OpenAI Responses API (raw HTTP) | `gpt-5.5` | yes | `OPENAI_API_KEY`; `OPENAI_BASE_URL` (defaults to api.openai.com) |\n| `anthropic` | Anthropic Messages API (raw HTTP) | `claude-opus-4-7` | yes | `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`; `ANTHROPIC_BASE_URL` |\n| `codex` | shells out to `codex exec` | Codex CLI's own | no | inherits Codex CLI config |\n| `claude` | shells out to `claude --print` | `claude-opus-4-7` | no | inherits Claude Code env (`ANTHROPIC_*`) |\n\n`openai` is accepted as a synonym for `responses`. The **model** is free-form\n— any string the endpoint accepts works (`gpt-5.5`, `gpt-5.4`,\n`gpt-5.3-codex`, `deepseek-v4`, `claude-opus-4-7`, `claude-opus-4-6`, …).\n\nSwitch with flags:\n\n```bash\n# Default: OpenAI Responses against api.openai.com\nsemia scan ./some-skill\n\n# Anthropic Messages against api.anthropic.com\nsemia scan ./some-skill --provider anthropic\n\n# Point the responses format at a different endpoint (DeepSeek, OpenRouter, vLLM, …)\nsemia scan ./some-skill \\\n --provider responses --model deepseek-v4 \\\n --base-url https://api.deepseek.com/v1\n\n# Use the locally-installed Claude Code CLI (model is the only knob)\nsemia scan ./some-skill --provider claude --model claude-opus-4-7\n```\n\nEach of these lands output under `.semia/runs/some-skill/`. Pass\n`--out ` if you want a custom run directory.\n\n### Most common environment variables\n\n| Variable | Purpose |\n| --------------------------- | -------------------------------------------------------------------- |\n| `SEMIA_LLM_PROVIDER` | `responses` (default) / `anthropic` / `codex` / `claude` |\n| `SEMIA_LLM_MODEL` | free-form model name passed to the provider |\n| `SEMIA_LLM_TIMEOUT` | request timeout in seconds |\n| `SEMIA_LLM_MAX_RETRIES` | retry budget for transient provider errors |\n| `OPENAI_BASE_URL` | base URL for the `responses` provider |\n| `ANTHROPIC_BASE_URL` | base URL for the `anthropic` provider |\n| `SEMIA_DETECTOR_BACKEND` | `auto` (default), `souffle`, `builtin` |\n| `SEMIA_SOUFFLE_BIN` | path to `souffle` if not on `PATH` |\n\nFor full synthesis tuning (`SEMIA_SYNTHESIS_*`), see the rest of\n[`.env.example`](.env.example) and\n[docs/plugin-protocol.md](docs/plugin-protocol.md).\n\n## Common workflows\n\n**Stop after deterministic preparation:**\n```bash\nsemia scan ./some-skill --prepare-only\n```\n\n**Reuse facts from a prior run or an agent session:**\n```bash\nsemia scan ./some-skill --facts synthesized_facts.dl\nsemia report .semia/runs/some-skill --format sarif\n```\n\n**CI smoke test (no LLM call):**\n```bash\nsemia scan ./some-skill --offline-baseline\n```\n> `--offline-baseline` is a conservative non-LLM fallback for offline demos\n> and CI smoke tests. It is **not** a substitute for real synthesis.\n\n## Install as a host plugin\n\nThe Codex and Claude Code plugin bundles under `packages/semia-plugins//`\nship with a self-contained `bin/semia.pyz` zipapp, so they work out of the\nbox without a separate `pip install semia-audit`. The OpenClaw skill\nrelies on the published `semia` CLI on `PATH` (ClawHub provisions it via\n`uv tool install`). Installing the Python package as well is recommended if\nyou want `semia` available as a normal shell command alongside the in-host\nworkflow.\n\n**Codex** — pick either path.\n\n> `codex plugin` only exposes a `marketplace` subcommand (`add` /\n> `upgrade` / `remove`) — there is **no `codex plugin install`**.\n> \"Installing\" a plugin means enabling the\n> `[plugins.\"@\"]` toggle in `~/.codex/config.toml`,\n> either via the `/plugins` TUI panel or by editing the file directly.\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add berabuddies/Semia\n```\n\nThen append the plugin toggle to `~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia@semia\"]\nenabled = true\n```\n\nThe second `semia` is the marketplace identifier (the top-level\n`name` in this repo's `.agents/plugins/marketplace.json`); the first\n`semia` is the plugin entry under it. For a one-shot non-persistent\nrun you can use `codex -c 'plugins.\"semia@semia\".enabled=true'`\ninstead of editing the file.\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, toggle `semia` on from the newly-added\n marketplace (the panel writes the same `[plugins.\"semia@semia\"]`\n block into `~/.codex/config.toml` for you).\n\n**Claude Code** — pick either path.\n\n*Shell (scripts and CI):*\n\n```bash\nclaude plugin marketplace add berabuddies/Semia\nclaude plugin install semia@semia\n```\n\n*Interactive plugin manager inside the Claude Code CLI:*\n\n1. Launch `claude`.\n2. Inside Claude Code, input `/plugins` (plural — opens the plugin panel).\n3. Press **→** (Right) twice and select **Add Marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, install `semia` from the newly-added marketplace.\n\nThe `name@marketplace` form on `install` is required — the second `semia`\nis the marketplace identifier from the project's `marketplace.json`.\nUse `--scope user|project|local` on the shell form to control where the\nplugin is recorded (default is `user`):\n\n```bash\nclaude plugin install semia@semia --scope project\n```\n\nSee [Discover and install plugins](https://code.claude.com/docs/en/discover-plugins)\nfor the full UX and [Plugins reference](https://code.claude.com/docs/en/plugins-reference#cli-commands-reference)\nfor the complete list of `claude plugin ...` subcommands.\n\n**OpenClaw** — install from ClawHub:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nClawHub will install the `semia` CLI on demand via `uv tool install\nsemia-audit` (declared in the skill's `install` block). If you prefer to\npre-provision it yourself:\n\n```bash\nuv tool install semia-audit # or: pip install semia-audit\nopenclaw plugins install clawhub:semia\n```\n\n## Repository layout\n\n```text\npackages/\n semia-core/ # deterministic analysis library (prepare, check, detect, report)\n semia-cli/ # `semia` command surface\n semia-plugins/ # Codex / Claude Code / OpenClaw integrations\ndocs/\n architecture.md\n plugin-protocol.md\n release.md\n supply-chain.md\ntests/\n\n```\n\n## Development\n\n```bash\ngit clone https://github.com/berabuddies/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\npython -m pip install pre-commit\npre-commit install\npre-commit run --all-files # establish a clean baseline\n\nmake help # list targets\nmake check # compile + tests + manifest validation\nmake build # package metadata check\nmake release-check # full pre-release gate\n```\n\nThe root quality gates stay stdlib-friendly: `compileall`, `unittest`\ndiscovery, and stdlib-only validators. Pre-commit adds `ruff` lint/format\nand `gitleaks` secret scanning. CI mirrors `ruff` via\n[`lint.yml`](.github/workflows/lint.yml); `gitleaks` stays local-only\nbecause the upstream GitHub Action now requires a paid license for\norganization repositories.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow and the DCO\nsign-off requirement.\n\n## Project background\n\nThe technique behind Semia is described in the Semia paper\n([arXiv:2605.00314](https://arxiv.org/abs/2605.00314) ·\n[PDF](https://arxiv.org/pdf/2605.00314)). Semia is the\n**deterministic acceptance boundary** around behavior mapping: agents may\nextract facts, but only checked, evidence-grounded facts make it into a\nreport.\n\n## Security\n\nTo report a security vulnerability, see [SECURITY.md](SECURITY.md). Please\ndo **not** file public GitHub issues for security problems.\n\n## Contributing\n\nContributions are welcome — bug reports, documentation fixes, detector\nrules, and code. See [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow\nand the DCO sign-off requirement.\n\n## License & trademarks\n\nSemia is released under the [Apache License 2.0](LICENSE). You\nmay use, modify, and redistribute it freely, including for commercial\npurposes, subject to the terms of the license. See [NOTICE](NOTICE) for\nattribution.\n\nThe names **\"Semia\"**, **\"Semia\"**, **\"Semia\"**, and\n**\"berabuddies\"** are trademarks of berabuddies and are **not** licensed under\nApache-2.0. See [TRADEMARKS.md](TRADEMARKS.md) for the trademark policy.\n"}, "3e15a7f087dc88646614728fd816d10b9a36f66f": {"t": 1785762604.9289076, "n": 19570, "h": "2c956c7bf3034a8c", "c": "# Semia\n\n> **Security audit for AI agent skills.** Know what a skill *can* do\n> before you trust it.\n\n[![CI](https://github.com/berabuddies/Semia/actions/workflows/ci.yml/badge.svg)](https://github.com/berabuddies/Semia/actions/workflows/ci.yml)\n[![Lint](https://github.com/berabuddies/Semia/actions/workflows/lint.yml/badge.svg)](https://github.com/berabuddies/Semia/actions/workflows/lint.yml)\n[![codecov](https://codecov.io/gh/berabuddies/Semia/graph/badge.svg)](https://codecov.io/gh/berabuddies/Semia)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](pyproject.toml)\n\nAgent skills are markdown files with embedded shell commands, network calls,\nand tool invocations. They run with **your credentials, on your machine,\nwith your data**. Semia reads a skill as data — never executes it — and\nproduces an evidence-backed report of every capability it may exercise.\n\nIt is the difference between\n\n> *\"I trust this skill because the README looks fine.\"*\n\nand\n\n> *\"I trust this skill because Semia extracted 14 actions, 6 effects,\n> and 2 secret reads — and every one is grounded in a specific source line.\"*\n\n---\n\n## Quick example\n\nPick whichever fits how you already work.\n\n### As a CLI\n\n```bash\npip install semia\nsemia scan ./some-skill\n```\n\n`scan` does prepare → synthesize (via your configured LLM provider) →\ndetect → report in one shot. Output lands under\n`.semia/runs//` by default — pass `--out ` to override.\nYou'll need an LLM provider configured first — see\n[Set up an LLM provider](#set-up-an-llm-provider) below.\n\n### Inside Codex, Claude Code, or OpenClaw\n\nInstall the plugin once. Each host has its own flow.\n\n**Codex** — pick either path:\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add berabuddies/Semia\n```\n\nThen enable the plugin by appending to `~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia@semia\"]\nenabled = true\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, toggle `semia` on from the\n newly-added marketplace.\n\n**Claude Code** — pick either path:\n\n*Shell (one-liner):*\n\n```bash\nclaude plugin marketplace add berabuddies/Semia\nclaude plugin install semia@semia\n```\n\n*Interactive plugin manager inside the Claude Code CLI:*\n\n1. Launch `claude`.\n2. Inside Claude Code, input `/plugins` (plural — opens the plugin panel).\n3. Press **→** (Right) twice and select **Add Marketplace**.\n4. Enter `berabuddies/Semia`.\n\nEither path registers the marketplace; finish installing `semia` from\nthe panel or with `claude plugin install semia@semia`.\n\n**OpenClaw** — one shell command registers the marketplace and installs:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nThen in any chat with the host agent just ask:\n\n> Run Semia audit on ./some-skill\n\nThe host agent itself acts as the synthesize step — **no API key needed**.\nThe bundled `semia.pyz` handles prepare / detect / report deterministically.\n\n### Outputs\n\nYou get `report.md` — findings ranked by severity, every one tied to a\nspecific source line. Need [SARIF 2.1.0](https://sarifweb.azurewebsites.net/)\nfor GitHub Code Scanning, or structured JSON for downstream tooling? One\nmore command:\n\n```bash\nsemia report .semia/runs/some-skill --format sarif # for GitHub Code Scanning\nsemia report .semia/runs/some-skill --format json # structured payload\n```\n\n## Set up an LLM provider\n\n`semia scan` needs an LLM for the **synthesize** step (the other three\nstages are deterministic, no key required). If you run Semia via a host\nplugin (Codex / Claude Code / OpenClaw) skip this — the host agent already\ndoes synthesize for you.\n\nFour providers are supported. Pick one and export its credentials:\n\n```bash\n# OpenAI Responses API — default; also works for DeepSeek / OpenRouter / vLLM\nexport OPENAI_API_KEY=sk-...\n# optional: export OPENAI_BASE_URL=https://api.deepseek.com/v1\n\n# Anthropic Messages API\nexport SEMIA_LLM_PROVIDER=anthropic\nexport ANTHROPIC_API_KEY=sk-ant-...\n# optional: export ANTHROPIC_BASE_URL=https://api.anthropic.com\n\n# Locally-installed Claude Code CLI (uses your Claude Code login)\nexport SEMIA_LLM_PROVIDER=claude\n\n# Locally-installed Codex CLI (uses your Codex login)\nexport SEMIA_LLM_PROVIDER=codex\n```\n\nOverride the model with `--model ` on any `semia scan` invocation, or\npersist it via `SEMIA_LLM_MODEL`. Models are free-form strings — anything\nthe endpoint accepts (`gpt-5.5`, `deepseek-v4`, `claude-opus-4-7`, …).\n\nSee [Configuration](#configuration) for the full provider matrix, base-URL\nsupport, timeout/retry knobs, and synthesis-loop tuning.\n\n## What you get\n\nA run writes everything under `.semia/runs//`. **Most users only\never open the reports**:\n\n| Report | When |\n| ------------------- | --------------------------------------------------------- |\n| `report.md` | always produced by `semia scan` — read this first |\n| `report.sarif.json` | on demand via `semia report --format sarif` — feed to GitHub Code Scanning |\n| `report.json` | on demand via `semia report --format json` — structured payload (check + evidence + detector) for programmatic consumers |\n\nBecause every finding traces back to a source line, the SARIF drops cleanly\ninto GitHub Code Scanning and reviewers see annotations directly on the\nskill PR.\n\n
\nOther artifacts in the run directory (internal — for tooling, debugging, or re-querying)\n\n| Artifact | Purpose |\n| ------------------------- | -------------------------------------------------- |\n| `synthesized_facts.dl` | the behavior map (Datalog facts) — re-queryable |\n| `detection_findings.dl` | findings derived by rule evaluation |\n| `prepared_skill.md` | normalized skill text with stable line anchors |\n| `prepare_units.json` | reference units the evidence text aligns against |\n| `synthesis_metadata.json` | provider, model, retries, score, stop reason |\n| `run_manifest.json` | end-to-end manifest of the run |\n\n
\n\n## Worked example\n\nPicture a skill that promises to \"summarize your inbox every day\". It\ninstalls a browser automation tool, opens your real Chrome (with every\nsaved login), reads Gmail, pipes the messages to an LLM that controls\nthe browser, and sets up a launchd job to repeat daily — forever. One\nemail from an attacker turns that skill into a remote control for every\nsite you are logged into.\n\n[See **EXAMPLE.md** for the full walkthrough →](EXAMPLE.md) — the skill\nsource, the attack, why it works, and the exact capabilities Semia\nsurfaces before you install.\n\n## How it works\n\n```text\n ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌────────┐\n │ Prepare │ ──▶ │ Synthesize │ ──▶ │ Detect │ ──▶ │ Report │\n │ (det.) │ │ (LLM) │ │ (det.) │ │ (det.) │\n └──────────┘ └────────────┘ └──────────┘ └────────┘\n```\n\n1. **Prepare** — read skill markdown + adjacent source, inline references,\n assign stable evidence handles. Pure stdlib. No LLM.\n2. **Synthesize** — an LLM (or the host agent's own session) extracts a\n *behavior map* as Datalog facts (`action`, `call`, `call_effect`, …)\n with `_evidence_text` sidecars citing the original source. The loop\n retries invalid candidates with checker feedback and keeps the best one.\n3. **Detect** — a Datalog evaluator runs the bundled SDL rules over the\n facts to flag risky combinations (e.g. *secret read → network write*).\n4. **Report** — render Markdown for humans and SARIF for CI.\n\nDetection runs through a built-in pure-Python Datalog evaluator by default,\nso **no external binary is required**. If [Soufflé](https://souffle-lang.github.io/)\nis on `PATH` (or `SEMIA_SOUFFLE_BIN`) it is preferred as a faster backend.\nOverride with `SEMIA_DETECTOR_BACKEND=auto|souffle|builtin`.\n\n[Read the full architecture →](docs/architecture.md)\n\n## Trust model\n\nSemia is a security tool for analyzing untrusted content. The trust\nboundary is explicit:\n\n| Surface | Treatment |\n| ------------------------- | -------------------------------------------------------------------------------- |\n| Audited skill | **untrusted data** — never executed, hooks/installers ignored |\n| Skill-declared URLs | **never fetched** during a scan |\n| Prompt-injection in skill | **recorded as evidence**, not followed as instructions |\n| Prepare / Detect / Report | deterministic, stdlib-friendly, runs locally |\n| Synthesize | the only LLM-mediated step; output must pass structural and evidence checks |\n| Network | LLM provider only |\n| Filesystem | reads the skill directory; writes only `.semia/runs//` |\n\nSee [docs/plugin-protocol.md#hostile-input-rules](docs/plugin-protocol.md)\nfor the full host-integration contract, and\n[SECURITY.md](SECURITY.md) for vulnerability reporting.\n\n## Install\n\nFrom source (current):\n\n```bash\ngit clone https://github.com/berabuddies/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\n```\n\nPython 3.11+ required. The project has **zero runtime dependencies** — both\nthe `responses` and `anthropic` providers talk to their APIs over raw HTTP\nusing the standard library.\n\n## Configuration\n\nSettings come from CLI flags, environment variables, or a repo-local\n`.env`. Copy [`.env.example`](.env.example) to `.env` and fill in your\ncredentials — `.env` is gitignored, and the pre-commit `gitleaks` hook\nruns locally against staged changes so secrets do not reach the history.\n\n### Providers\n\nSemia routes synthesis through one of four providers — two HTTP wire\nformats and two local CLI shell-outs. The default is `responses` with\nmodel `gpt-5.5`, authenticated via `OPENAI_API_KEY`.\n\n| Provider | Transport | Default model | Honors `--base-url` | Auth |\n| ------------ | ---------------------------------- | ------------------- | ------------------- | ----------------------------------------------------------------- |\n| `responses` | OpenAI Responses API (raw HTTP) | `gpt-5.5` | yes | `OPENAI_API_KEY`; `OPENAI_BASE_URL` (defaults to api.openai.com) |\n| `anthropic` | Anthropic Messages API (raw HTTP) | `claude-opus-4-7` | yes | `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`; `ANTHROPIC_BASE_URL` |\n| `codex` | shells out to `codex exec` | Codex CLI's own | no | inherits Codex CLI config |\n| `claude` | shells out to `claude --print` | `claude-opus-4-7` | no | inherits Claude Code env (`ANTHROPIC_*`) |\n\n`openai` is accepted as a synonym for `responses`. The **model** is free-form\n— any string the endpoint accepts works (`gpt-5.5`, `gpt-5.4`,\n`gpt-5.3-codex`, `deepseek-v4`, `claude-opus-4-7`, `claude-opus-4-6`, …).\n\nSwitch with flags:\n\n```bash\n# Default: OpenAI Responses against api.openai.com\nsemia scan ./some-skill\n\n# Anthropic Messages against api.anthropic.com\nsemia scan ./some-skill --provider anthropic\n\n# Point the responses format at a different endpoint (DeepSeek, OpenRouter, vLLM, …)\nsemia scan ./some-skill \\\n --provider responses --model deepseek-v4 \\\n --base-url https://api.deepseek.com/v1\n\n# Use the locally-installed Claude Code CLI (model is the only knob)\nsemia scan ./some-skill --provider claude --model claude-opus-4-7\n```\n\nEach of these lands output under `.semia/runs/some-skill/`. Pass\n`--out ` if you want a custom run directory.\n\n### Most common environment variables\n\n| Variable | Purpose |\n| --------------------------- | -------------------------------------------------------------------- |\n| `SEMIA_LLM_PROVIDER` | `responses` (default) / `anthropic` / `codex` / `claude` |\n| `SEMIA_LLM_MODEL` | free-form model name passed to the provider |\n| `SEMIA_LLM_TIMEOUT` | request timeout in seconds |\n| `SEMIA_LLM_MAX_RETRIES` | retry budget for transient provider errors |\n| `OPENAI_BASE_URL` | base URL for the `responses` provider |\n| `ANTHROPIC_BASE_URL` | base URL for the `anthropic` provider |\n| `SEMIA_DETECTOR_BACKEND` | `auto` (default), `souffle`, `builtin` |\n| `SEMIA_SOUFFLE_BIN` | path to `souffle` if not on `PATH` |\n\nFor full synthesis tuning (`SEMIA_SYNTHESIS_*`), see the rest of\n[`.env.example`](.env.example) and\n[docs/plugin-protocol.md](docs/plugin-protocol.md).\n\n## Common workflows\n\n**Stop after deterministic preparation:**\n```bash\nsemia scan ./some-skill --prepare-only\n```\n\n**Reuse facts from a prior run or an agent session:**\n```bash\nsemia scan ./some-skill --facts synthesized_facts.dl\nsemia report .semia/runs/some-skill --format sarif\n```\n\n**CI smoke test (no LLM call):**\n```bash\nsemia scan ./some-skill --offline-baseline\n```\n> `--offline-baseline` is a conservative non-LLM fallback for offline demos\n> and CI smoke tests. It is **not** a substitute for real synthesis.\n\n## Install as a host plugin\n\nThe Codex and Claude Code plugin bundles under `packages/semia-plugins//`\nship with a self-contained `bin/semia.pyz` zipapp, so they work out of the\nbox without a separate `pip install semia`. The OpenClaw skill\nrelies on the published `semia` CLI on `PATH` (ClawHub provisions it via\n`uv tool install`). Installing the Python package as well is recommended if\nyou want `semia` available as a normal shell command alongside the in-host\nworkflow.\n\n**Codex** — pick either path.\n\n> `codex plugin` only exposes a `marketplace` subcommand (`add` /\n> `upgrade` / `remove`) — there is **no `codex plugin install`**.\n> \"Installing\" a plugin means enabling the\n> `[plugins.\"@\"]` toggle in `~/.codex/config.toml`,\n> either via the `/plugins` TUI panel or by editing the file directly.\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add berabuddies/Semia\n```\n\nThen append the plugin toggle to `~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia@semia\"]\nenabled = true\n```\n\nThe second `semia` is the marketplace identifier (the top-level\n`name` in this repo's `.agents/plugins/marketplace.json`); the first\n`semia` is the plugin entry under it. For a one-shot non-persistent\nrun you can use `codex -c 'plugins.\"semia@semia\".enabled=true'`\ninstead of editing the file.\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, toggle `semia` on from the newly-added\n marketplace (the panel writes the same `[plugins.\"semia@semia\"]`\n block into `~/.codex/config.toml` for you).\n\n**Claude Code** — pick either path.\n\n*Shell (scripts and CI):*\n\n```bash\nclaude plugin marketplace add berabuddies/Semia\nclaude plugin install semia@semia\n```\n\n*Interactive plugin manager inside the Claude Code CLI:*\n\n1. Launch `claude`.\n2. Inside Claude Code, input `/plugins` (plural — opens the plugin panel).\n3. Press **→** (Right) twice and select **Add Marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, install `semia` from the newly-added marketplace.\n\nThe `name@marketplace` form on `install` is required — the second `semia`\nis the marketplace identifier from the project's `marketplace.json`.\nUse `--scope user|project|local` on the shell form to control where the\nplugin is recorded (default is `user`):\n\n```bash\nclaude plugin install semia@semia --scope project\n```\n\nSee [Discover and install plugins](https://code.claude.com/docs/en/discover-plugins)\nfor the full UX and [Plugins reference](https://code.claude.com/docs/en/plugins-reference#cli-commands-reference)\nfor the complete list of `claude plugin ...` subcommands.\n\n**OpenClaw** — install from ClawHub:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nClawHub will install the `semia` CLI on demand via `uv tool install\nsemia` (declared in the skill's `install` block). If you prefer to\npre-provision it yourself:\n\n```bash\nuv tool install semia # or: pip install semia\nopenclaw plugins install clawhub:semia\n```\n\n## Repository layout\n\n```text\npackages/\n semia-core/ # deterministic analysis library (prepare, check, detect, report)\n semia-cli/ # `semia` command surface\n semia-plugins/ # Codex / Claude Code / OpenClaw integrations\ndocs/\n architecture.md\n plugin-protocol.md\n release.md\n supply-chain.md\ntests/\n\n```\n\n## Development\n\n```bash\ngit clone https://github.com/berabuddies/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\npython -m pip install pre-commit\npre-commit install\npre-commit run --all-files # establish a clean baseline\n\nmake help # list targets\nmake check # compile + tests + manifest validation\nmake build # package metadata check\nmake release-check # full pre-release gate\n```\n\nThe root quality gates stay stdlib-friendly: `compileall`, `unittest`\ndiscovery, and stdlib-only validators. Pre-commit adds `ruff` lint/format\nand `gitleaks` secret scanning. CI mirrors `ruff` via\n[`lint.yml`](.github/workflows/lint.yml); `gitleaks` stays local-only\nbecause the upstream GitHub Action now requires a paid license for\norganization repositories.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow and the DCO\nsign-off requirement.\n\n## Project background\n\nThe technique behind Semia is described in the Semia paper\n([arXiv:2605.00314](https://arxiv.org/abs/2605.00314) ·\n[PDF](https://arxiv.org/pdf/2605.00314)). Semia is the\n**deterministic acceptance boundary** around behavior mapping: agents may\nextract facts, but only checked, evidence-grounded facts make it into a\nreport.\n\n## Security\n\nTo report a security vulnerability, see [SECURITY.md](SECURITY.md). Please\ndo **not** file public GitHub issues for security problems.\n\n## Contributing\n\nContributions are welcome — bug reports, documentation fixes, detector\nrules, and code. See [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow\nand the DCO sign-off requirement.\n\n## License & trademarks\n\nSemia is released under the [Apache License 2.0](LICENSE). You\nmay use, modify, and redistribute it freely, including for commercial\npurposes, subject to the terms of the license. See [NOTICE](NOTICE) for\nattribution.\n\nThe names **\"Semia\"**, **\"Semia\"**, **\"Semia\"**, and\n**\"berabuddies\"** are trademarks of berabuddies and are **not** licensed under\nApache-2.0. See [TRADEMARKS.md](TRADEMARKS.md) for the trademark policy.\n"}, "628398d563d28af93774244293a0ed3424b9e8a9": {"t": 1785762609.6321423, "n": 19536, "h": "1f534e6fe47ec543", "c": "# Semia\n\n> **Security audit for AI agent skills.** Know what a skill *can* do\n> before you trust it.\n\n[![CI](https://github.com/berabuddies/Semia/actions/workflows/ci.yml/badge.svg)](https://github.com/berabuddies/Semia/actions/workflows/ci.yml)\n[![Lint](https://github.com/berabuddies/Semia/actions/workflows/lint.yml/badge.svg)](https://github.com/berabuddies/Semia/actions/workflows/lint.yml)\n[![codecov](https://codecov.io/gh/berabuddies/Semia/graph/badge.svg)](https://codecov.io/gh/berabuddies/Semia)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](pyproject.toml)\n\nAgent skills are markdown files with embedded shell commands, network calls,\nand tool invocations. They run with **your credentials, on your machine,\nwith your data**. Semia reads a skill as data — never executes it — and\nproduces an evidence-backed report of every capability it may exercise.\n\nIt is the difference between\n\n> *\"I trust this skill because the README looks fine.\"*\n\nand\n\n> *\"I trust this skill because Semia extracted 14 actions, 6 effects,\n> and 2 secret reads — and every one is grounded in a specific source line.\"*\n\n---\n\n## Quick example\n\nPick whichever fits how you already work.\n\n### As a CLI\n\n```bash\npip install semia\nsemia scan ./some-skill\n```\n\n`scan` does prepare → synthesize (via your configured LLM provider) →\ndetect → report in one shot. Output lands under\n`.semia/runs//` by default — pass `--out ` to override.\nYou'll need an LLM provider configured first — see\n[Set up an LLM provider](#set-up-an-llm-provider) below.\n\n### Inside Codex, Claude Code, or OpenClaw\n\nInstall the plugin once. Each host has its own flow.\n\n**Codex** — pick either path:\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add berabuddies/Semia\n```\n\nThen enable the plugin by appending to `~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia@semia\"]\nenabled = true\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, toggle `semia` on from the\n newly-added marketplace.\n\n**Claude Code** — pick either path:\n\n*Shell (one-liner):*\n\n```bash\nclaude plugin marketplace add berabuddies/Semia\n```\n\n*Interactive plugin manager inside the Claude Code CLI:*\n\n1. Launch `claude`.\n2. Inside Claude Code, input `/plugins` (plural — opens the plugin panel).\n3. Press **→** (Right) twice and select **Add Marketplace**.\n4. Enter `berabuddies/Semia`.\n\nEither path registers the marketplace; finish installing `semia` from\nthe panel or with `claude plugin install semia@semia`.\n\n**OpenClaw** — one shell command registers the marketplace and installs:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nThen in any chat with the host agent just ask:\n\n> Run Semia audit on ./some-skill\n\nThe host agent itself acts as the synthesize step — **no API key needed**.\nThe bundled `semia.pyz` handles prepare / detect / report deterministically.\n\n### Outputs\n\nYou get `report.md` — findings ranked by severity, every one tied to a\nspecific source line. Need [SARIF 2.1.0](https://sarifweb.azurewebsites.net/)\nfor GitHub Code Scanning, or structured JSON for downstream tooling? One\nmore command:\n\n```bash\nsemia report .semia/runs/some-skill --format sarif # for GitHub Code Scanning\nsemia report .semia/runs/some-skill --format json # structured payload\n```\n\n## Set up an LLM provider\n\n`semia scan` needs an LLM for the **synthesize** step (the other three\nstages are deterministic, no key required). If you run Semia via a host\nplugin (Codex / Claude Code / OpenClaw) skip this — the host agent already\ndoes synthesize for you.\n\nFour providers are supported. Pick one and export its credentials:\n\n```bash\n# OpenAI Responses API — default; also works for DeepSeek / OpenRouter / vLLM\nexport OPENAI_API_KEY=sk-...\n# optional: export OPENAI_BASE_URL=https://api.deepseek.com/v1\n\n# Anthropic Messages API\nexport SEMIA_LLM_PROVIDER=anthropic\nexport ANTHROPIC_API_KEY=sk-ant-...\n# optional: export ANTHROPIC_BASE_URL=https://api.anthropic.com\n\n# Locally-installed Claude Code CLI (uses your Claude Code login)\nexport SEMIA_LLM_PROVIDER=claude\n\n# Locally-installed Codex CLI (uses your Codex login)\nexport SEMIA_LLM_PROVIDER=codex\n```\n\nOverride the model with `--model ` on any `semia scan` invocation, or\npersist it via `SEMIA_LLM_MODEL`. Models are free-form strings — anything\nthe endpoint accepts (`gpt-5.5`, `deepseek-v4`, `claude-opus-4-7`, …).\n\nSee [Configuration](#configuration) for the full provider matrix, base-URL\nsupport, timeout/retry knobs, and synthesis-loop tuning.\n\n## What you get\n\nA run writes everything under `.semia/runs//`. **Most users only\never open the reports**:\n\n| Report | When |\n| ------------------- | --------------------------------------------------------- |\n| `report.md` | always produced by `semia scan` — read this first |\n| `report.sarif.json` | on demand via `semia report --format sarif` — feed to GitHub Code Scanning |\n| `report.json` | on demand via `semia report --format json` — structured payload (check + evidence + detector) for programmatic consumers |\n\nBecause every finding traces back to a source line, the SARIF drops cleanly\ninto GitHub Code Scanning and reviewers see annotations directly on the\nskill PR.\n\n
\nOther artifacts in the run directory (internal — for tooling, debugging, or re-querying)\n\n| Artifact | Purpose |\n| ------------------------- | -------------------------------------------------- |\n| `synthesized_facts.dl` | the behavior map (Datalog facts) — re-queryable |\n| `detection_findings.dl` | findings derived by rule evaluation |\n| `prepared_skill.md` | normalized skill text with stable line anchors |\n| `prepare_units.json` | reference units the evidence text aligns against |\n| `synthesis_metadata.json` | provider, model, retries, score, stop reason |\n| `run_manifest.json` | end-to-end manifest of the run |\n\n
\n\n## Worked example\n\nPicture a skill that promises to \"summarize your inbox every day\". It\ninstalls a browser automation tool, opens your real Chrome (with every\nsaved login), reads Gmail, pipes the messages to an LLM that controls\nthe browser, and sets up a launchd job to repeat daily — forever. One\nemail from an attacker turns that skill into a remote control for every\nsite you are logged into.\n\n[See **EXAMPLE.md** for the full walkthrough →](EXAMPLE.md) — the skill\nsource, the attack, why it works, and the exact capabilities Semia\nsurfaces before you install.\n\n## How it works\n\n```text\n ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌────────┐\n │ Prepare │ ──▶ │ Synthesize │ ──▶ │ Detect │ ──▶ │ Report │\n │ (det.) │ │ (LLM) │ │ (det.) │ │ (det.) │\n └──────────┘ └────────────┘ └──────────┘ └────────┘\n```\n\n1. **Prepare** — read skill markdown + adjacent source, inline references,\n assign stable evidence handles. Pure stdlib. No LLM.\n2. **Synthesize** — an LLM (or the host agent's own session) extracts a\n *behavior map* as Datalog facts (`action`, `call`, `call_effect`, …)\n with `_evidence_text` sidecars citing the original source. The loop\n retries invalid candidates with checker feedback and keeps the best one.\n3. **Detect** — a Datalog evaluator runs the bundled SDL rules over the\n facts to flag risky combinations (e.g. *secret read → network write*).\n4. **Report** — render Markdown for humans and SARIF for CI.\n\nDetection runs through a built-in pure-Python Datalog evaluator by default,\nso **no external binary is required**. If [Soufflé](https://souffle-lang.github.io/)\nis on `PATH` (or `SEMIA_SOUFFLE_BIN`) it is preferred as a faster backend.\nOverride with `SEMIA_DETECTOR_BACKEND=auto|souffle|builtin`.\n\n[Read the full architecture →](docs/architecture.md)\n\n## Trust model\n\nSemia is a security tool for analyzing untrusted content. The trust\nboundary is explicit:\n\n| Surface | Treatment |\n| ------------------------- | -------------------------------------------------------------------------------- |\n| Audited skill | **untrusted data** — never executed, hooks/installers ignored |\n| Skill-declared URLs | **never fetched** during a scan |\n| Prompt-injection in skill | **recorded as evidence**, not followed as instructions |\n| Prepare / Detect / Report | deterministic, stdlib-friendly, runs locally |\n| Synthesize | the only LLM-mediated step; output must pass structural and evidence checks |\n| Network | LLM provider only |\n| Filesystem | reads the skill directory; writes only `.semia/runs//` |\n\nSee [docs/plugin-protocol.md#hostile-input-rules](docs/plugin-protocol.md)\nfor the full host-integration contract, and\n[SECURITY.md](SECURITY.md) for vulnerability reporting.\n\n## Install\n\nFrom source (current):\n\n```bash\ngit clone https://github.com/berabuddies/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\n```\n\nPython 3.11+ required. The project has **zero runtime dependencies** — both\nthe `responses` and `anthropic` providers talk to their APIs over raw HTTP\nusing the standard library.\n\n## Configuration\n\nSettings come from CLI flags, environment variables, or a repo-local\n`.env`. Copy [`.env.example`](.env.example) to `.env` and fill in your\ncredentials — `.env` is gitignored, and the pre-commit `gitleaks` hook\nruns locally against staged changes so secrets do not reach the history.\n\n### Providers\n\nSemia routes synthesis through one of four providers — two HTTP wire\nformats and two local CLI shell-outs. The default is `responses` with\nmodel `gpt-5.5`, authenticated via `OPENAI_API_KEY`.\n\n| Provider | Transport | Default model | Honors `--base-url` | Auth |\n| ------------ | ---------------------------------- | ------------------- | ------------------- | ----------------------------------------------------------------- |\n| `responses` | OpenAI Responses API (raw HTTP) | `gpt-5.5` | yes | `OPENAI_API_KEY`; `OPENAI_BASE_URL` (defaults to api.openai.com) |\n| `anthropic` | Anthropic Messages API (raw HTTP) | `claude-opus-4-7` | yes | `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`; `ANTHROPIC_BASE_URL` |\n| `codex` | shells out to `codex exec` | Codex CLI's own | no | inherits Codex CLI config |\n| `claude` | shells out to `claude --print` | `claude-opus-4-7` | no | inherits Claude Code env (`ANTHROPIC_*`) |\n\n`openai` is accepted as a synonym for `responses`. The **model** is free-form\n— any string the endpoint accepts works (`gpt-5.5`, `gpt-5.4`,\n`gpt-5.3-codex`, `deepseek-v4`, `claude-opus-4-7`, `claude-opus-4-6`, …).\n\nSwitch with flags:\n\n```bash\n# Default: OpenAI Responses against api.openai.com\nsemia scan ./some-skill\n\n# Anthropic Messages against api.anthropic.com\nsemia scan ./some-skill --provider anthropic\n\n# Point the responses format at a different endpoint (DeepSeek, OpenRouter, vLLM, …)\nsemia scan ./some-skill \\\n --provider responses --model deepseek-v4 \\\n --base-url https://api.deepseek.com/v1\n\n# Use the locally-installed Claude Code CLI (model is the only knob)\nsemia scan ./some-skill --provider claude --model claude-opus-4-7\n```\n\nEach of these lands output under `.semia/runs/some-skill/`. Pass\n`--out ` if you want a custom run directory.\n\n### Most common environment variables\n\n| Variable | Purpose |\n| --------------------------- | -------------------------------------------------------------------- |\n| `SEMIA_LLM_PROVIDER` | `responses` (default) / `anthropic` / `codex` / `claude` |\n| `SEMIA_LLM_MODEL` | free-form model name passed to the provider |\n| `SEMIA_LLM_TIMEOUT` | request timeout in seconds |\n| `SEMIA_LLM_MAX_RETRIES` | retry budget for transient provider errors |\n| `OPENAI_BASE_URL` | base URL for the `responses` provider |\n| `ANTHROPIC_BASE_URL` | base URL for the `anthropic` provider |\n| `SEMIA_DETECTOR_BACKEND` | `auto` (default), `souffle`, `builtin` |\n| `SEMIA_SOUFFLE_BIN` | path to `souffle` if not on `PATH` |\n\nFor full synthesis tuning (`SEMIA_SYNTHESIS_*`), see the rest of\n[`.env.example`](.env.example) and\n[docs/plugin-protocol.md](docs/plugin-protocol.md).\n\n## Common workflows\n\n**Stop after deterministic preparation:**\n```bash\nsemia scan ./some-skill --prepare-only\n```\n\n**Reuse facts from a prior run or an agent session:**\n```bash\nsemia scan ./some-skill --facts synthesized_facts.dl\nsemia report .semia/runs/some-skill --format sarif\n```\n\n**CI smoke test (no LLM call):**\n```bash\nsemia scan ./some-skill --offline-baseline\n```\n> `--offline-baseline` is a conservative non-LLM fallback for offline demos\n> and CI smoke tests. It is **not** a substitute for real synthesis.\n\n## Install as a host plugin\n\nThe Codex and Claude Code plugin bundles under `packages/semia-plugins//`\nship with a self-contained `bin/semia.pyz` zipapp, so they work out of the\nbox without a separate `pip install semia`. The OpenClaw skill\nrelies on the published `semia` CLI on `PATH` (ClawHub provisions it via\n`uv tool install`). Installing the Python package as well is recommended if\nyou want `semia` available as a normal shell command alongside the in-host\nworkflow.\n\n**Codex** — pick either path.\n\n> `codex plugin` only exposes a `marketplace` subcommand (`add` /\n> `upgrade` / `remove`) — there is **no `codex plugin install`**.\n> \"Installing\" a plugin means enabling the\n> `[plugins.\"@\"]` toggle in `~/.codex/config.toml`,\n> either via the `/plugins` TUI panel or by editing the file directly.\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add berabuddies/Semia\n```\n\nThen append the plugin toggle to `~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia@semia\"]\nenabled = true\n```\n\nThe second `semia` is the marketplace identifier (the top-level\n`name` in this repo's `.agents/plugins/marketplace.json`); the first\n`semia` is the plugin entry under it. For a one-shot non-persistent\nrun you can use `codex -c 'plugins.\"semia@semia\".enabled=true'`\ninstead of editing the file.\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, toggle `semia` on from the newly-added\n marketplace (the panel writes the same `[plugins.\"semia@semia\"]`\n block into `~/.codex/config.toml` for you).\n\n**Claude Code** — pick either path.\n\n*Shell (scripts and CI):*\n\n```bash\nclaude plugin marketplace add berabuddies/Semia\nclaude plugin install semia@semia\n```\n\n*Interactive plugin manager inside the Claude Code CLI:*\n\n1. Launch `claude`.\n2. Inside Claude Code, input `/plugins` (plural — opens the plugin panel).\n3. Press **→** (Right) twice and select **Add Marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, install `semia` from the newly-added marketplace.\n\nThe `name@marketplace` form on `install` is required — the second `semia`\nis the marketplace identifier from the project's `marketplace.json`.\nUse `--scope user|project|local` on the shell form to control where the\nplugin is recorded (default is `user`):\n\n```bash\nclaude plugin install semia@semia --scope project\n```\n\nSee [Discover and install plugins](https://code.claude.com/docs/en/discover-plugins)\nfor the full UX and [Plugins reference](https://code.claude.com/docs/en/plugins-reference#cli-commands-reference)\nfor the complete list of `claude plugin ...` subcommands.\n\n**OpenClaw** — install from ClawHub:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nClawHub will install the `semia` CLI on demand via `uv tool install\nsemia` (declared in the skill's `install` block). If you prefer to\npre-provision it yourself:\n\n```bash\nuv tool install semia # or: pip install semia\nopenclaw plugins install clawhub:semia\n```\n\n## Repository layout\n\n```text\npackages/\n semia-core/ # deterministic analysis library (prepare, check, detect, report)\n semia-cli/ # `semia` command surface\n semia-plugins/ # Codex / Claude Code / OpenClaw integrations\ndocs/\n architecture.md\n plugin-protocol.md\n release.md\n supply-chain.md\ntests/\n\n```\n\n## Development\n\n```bash\ngit clone https://github.com/berabuddies/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\npython -m pip install pre-commit\npre-commit install\npre-commit run --all-files # establish a clean baseline\n\nmake help # list targets\nmake check # compile + tests + manifest validation\nmake build # package metadata check\nmake release-check # full pre-release gate\n```\n\nThe root quality gates stay stdlib-friendly: `compileall`, `unittest`\ndiscovery, and stdlib-only validators. Pre-commit adds `ruff` lint/format\nand `gitleaks` secret scanning. CI mirrors `ruff` via\n[`lint.yml`](.github/workflows/lint.yml); `gitleaks` stays local-only\nbecause the upstream GitHub Action now requires a paid license for\norganization repositories.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow and the DCO\nsign-off requirement.\n\n## Project background\n\nThe technique behind Semia is described in the Semia paper\n([arXiv:2605.00314](https://arxiv.org/abs/2605.00314) ·\n[PDF](https://arxiv.org/pdf/2605.00314)). Semia is the\n**deterministic acceptance boundary** around behavior mapping: agents may\nextract facts, but only checked, evidence-grounded facts make it into a\nreport.\n\n## Security\n\nTo report a security vulnerability, see [SECURITY.md](SECURITY.md). Please\ndo **not** file public GitHub issues for security problems.\n\n## Contributing\n\nContributions are welcome — bug reports, documentation fixes, detector\nrules, and code. See [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow\nand the DCO sign-off requirement.\n\n## License & trademarks\n\nSemia is released under the [Apache License 2.0](LICENSE). You\nmay use, modify, and redistribute it freely, including for commercial\npurposes, subject to the terms of the license. See [NOTICE](NOTICE) for\nattribution.\n\nThe names **\"Semia\"**, **\"Semia\"**, **\"Semia\"**, and\n**\"berabuddies\"** are trademarks of berabuddies and are **not** licensed under\nApache-2.0. See [TRADEMARKS.md](TRADEMARKS.md) for the trademark policy.\n"}, "c423872b81fe988ec428bc3cc8c1e4dee7414529": {"t": 1785762612.6617265, "n": 19558, "h": "2bb85f6fa03448d8", "c": "# Semia\n\n> **Security audit for AI agent skills.** Know what a skill *can* do\n> before you trust it.\n\n[![CI](https://github.com/berabuddies/Semia/actions/workflows/ci.yml/badge.svg)](https://github.com/berabuddies/Semia/actions/workflows/ci.yml)\n[![Lint](https://github.com/berabuddies/Semia/actions/workflows/lint.yml/badge.svg)](https://github.com/berabuddies/Semia/actions/workflows/lint.yml)\n[![codecov](https://codecov.io/gh/berabuddies/Semia/graph/badge.svg)](https://codecov.io/gh/berabuddies/Semia)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](pyproject.toml)\n\nAgent skills are markdown files with embedded shell commands, network calls,\nand tool invocations. They run with **your credentials, on your machine,\nwith your data**. Semia reads a skill as data — never executes it — and\nproduces an evidence-backed report of every capability it may exercise.\n\nIt is the difference between\n\n> *\"I trust this skill because the README looks fine.\"*\n\nand\n\n> *\"I trust this skill because Semia extracted 14 actions, 6 effects,\n> and 2 secret reads — and every one is grounded in a specific source line.\"*\n\n---\n\n## Quick example\n\nPick whichever fits how you already work.\n\n### As a CLI\n\n```bash\npip install semia\nsemia scan ./some-skill --out .semia/runs/some-skill\n```\n\n`scan` does prepare → synthesize (via your configured LLM provider) →\ndetect → report in one shot. You'll need an LLM provider configured first —\nsee [Set up an LLM provider](#set-up-an-llm-provider) below.\n\n### Inside Codex, Claude Code, or OpenClaw\n\nInstall the plugin once. Each host has its own flow.\n\n**Codex** — pick either path:\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add berabuddies/Semia\n```\n\nThen enable the plugin by appending to `~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia@semia\"]\nenabled = true\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, toggle `semia` on from the\n newly-added marketplace.\n\n**Claude Code** — pick either path:\n\n*Shell (one-liner):*\n\n```bash\nclaude plugin marketplace add berabuddies/Semia\n```\n\n*Interactive plugin manager inside the Claude Code CLI:*\n\n1. Launch `claude`.\n2. Inside Claude Code, input `/plugins` (plural — opens the plugin panel).\n3. Press **→** (Right) twice and select **Add Marketplace**.\n4. Enter `berabuddies/Semia`.\n\nEither path registers the marketplace; finish installing `semia` from\nthe panel or with `claude plugin install semia@semia`.\n\n**OpenClaw** — one shell command registers the marketplace and installs:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nThen in any chat with the host agent just ask:\n\n> Run Semia audit on ./some-skill\n\nThe host agent itself acts as the synthesize step — **no API key needed**.\nThe bundled `semia.pyz` handles prepare / detect / report deterministically.\n\n### Outputs\n\nYou get `report.md` — findings ranked by severity, every one tied to a\nspecific source line. Need [SARIF 2.1.0](https://sarifweb.azurewebsites.net/)\nfor GitHub Code Scanning, or structured JSON for downstream tooling? One\nmore command:\n\n```bash\nsemia report .semia/runs/some-skill --format sarif # for GitHub Code Scanning\nsemia report .semia/runs/some-skill --format json # structured payload\n```\n\n## Set up an LLM provider\n\n`semia scan` needs an LLM for the **synthesize** step (the other three\nstages are deterministic, no key required). If you run Semia via a host\nplugin (Codex / Claude Code / OpenClaw) skip this — the host agent already\ndoes synthesize for you.\n\nFour providers are supported. Pick one and export its credentials:\n\n```bash\n# OpenAI Responses API — default; also works for DeepSeek / OpenRouter / vLLM\nexport OPENAI_API_KEY=sk-...\n# optional: export OPENAI_BASE_URL=https://api.deepseek.com/v1\n\n# Anthropic Messages API\nexport SEMIA_LLM_PROVIDER=anthropic\nexport ANTHROPIC_API_KEY=sk-ant-...\n# optional: export ANTHROPIC_BASE_URL=https://api.anthropic.com\n\n# Locally-installed Claude Code CLI (uses your Claude Code login)\nexport SEMIA_LLM_PROVIDER=claude\n\n# Locally-installed Codex CLI (uses your Codex login)\nexport SEMIA_LLM_PROVIDER=codex\n```\n\nOverride the model with `--model ` on any `semia scan` invocation, or\npersist it via `SEMIA_LLM_MODEL`. Models are free-form strings — anything\nthe endpoint accepts (`gpt-5.5`, `deepseek-v4`, `claude-opus-4-7`, …).\n\nSee [Configuration](#configuration) for the full provider matrix, base-URL\nsupport, timeout/retry knobs, and synthesis-loop tuning.\n\n## What you get\n\nA run writes everything under `.semia/runs//`. **Most users only\never open the reports**:\n\n| Report | When |\n| ------------------- | --------------------------------------------------------- |\n| `report.md` | always produced by `semia scan` — read this first |\n| `report.sarif.json` | on demand via `semia report --format sarif` — feed to GitHub Code Scanning |\n| `report.json` | on demand via `semia report --format json` — structured payload (check + evidence + detector) for programmatic consumers |\n\nBecause every finding traces back to a source line, the SARIF drops cleanly\ninto GitHub Code Scanning and reviewers see annotations directly on the\nskill PR.\n\n
\nOther artifacts in the run directory (internal — for tooling, debugging, or re-querying)\n\n| Artifact | Purpose |\n| ------------------------- | -------------------------------------------------- |\n| `synthesized_facts.dl` | the behavior map (Datalog facts) — re-queryable |\n| `detection_findings.dl` | findings derived by rule evaluation |\n| `prepared_skill.md` | normalized skill text with stable line anchors |\n| `prepare_units.json` | reference units the evidence text aligns against |\n| `synthesis_metadata.json` | provider, model, retries, score, stop reason |\n| `run_manifest.json` | end-to-end manifest of the run |\n\n
\n\n## Worked example\n\nPicture a skill that promises to \"summarize your inbox every day\". It\ninstalls a browser automation tool, opens your real Chrome (with every\nsaved login), reads Gmail, pipes the messages to an LLM that controls\nthe browser, and sets up a launchd job to repeat daily — forever. One\nemail from an attacker turns that skill into a remote control for every\nsite you are logged into.\n\n[See **EXAMPLE.md** for the full walkthrough →](EXAMPLE.md) — the skill\nsource, the attack, why it works, and the exact capabilities Semia\nsurfaces before you install.\n\n## How it works\n\n```text\n ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌────────┐\n │ Prepare │ ──▶ │ Synthesize │ ──▶ │ Detect │ ──▶ │ Report │\n │ (det.) │ │ (LLM) │ │ (det.) │ │ (det.) │\n └──────────┘ └────────────┘ └──────────┘ └────────┘\n```\n\n1. **Prepare** — read skill markdown + adjacent source, inline references,\n assign stable evidence handles. Pure stdlib. No LLM.\n2. **Synthesize** — an LLM (or the host agent's own session) extracts a\n *behavior map* as Datalog facts (`action`, `call`, `call_effect`, …)\n with `_evidence_text` sidecars citing the original source. The loop\n retries invalid candidates with checker feedback and keeps the best one.\n3. **Detect** — a Datalog evaluator runs the bundled SDL rules over the\n facts to flag risky combinations (e.g. *secret read → network write*).\n4. **Report** — render Markdown for humans and SARIF for CI.\n\nDetection runs through a built-in pure-Python Datalog evaluator by default,\nso **no external binary is required**. If [Soufflé](https://souffle-lang.github.io/)\nis on `PATH` (or `SEMIA_SOUFFLE_BIN`) it is preferred as a faster backend.\nOverride with `SEMIA_DETECTOR_BACKEND=auto|souffle|builtin`.\n\n[Read the full architecture →](docs/architecture.md)\n\n## Trust model\n\nSemia is a security tool for analyzing untrusted content. The trust\nboundary is explicit:\n\n| Surface | Treatment |\n| ------------------------- | -------------------------------------------------------------------------------- |\n| Audited skill | **untrusted data** — never executed, hooks/installers ignored |\n| Skill-declared URLs | **never fetched** during a scan |\n| Prompt-injection in skill | **recorded as evidence**, not followed as instructions |\n| Prepare / Detect / Report | deterministic, stdlib-friendly, runs locally |\n| Synthesize | the only LLM-mediated step; output must pass structural and evidence checks |\n| Network | LLM provider only |\n| Filesystem | reads the skill directory; writes only `.semia/runs//` |\n\nSee [docs/plugin-protocol.md#hostile-input-rules](docs/plugin-protocol.md)\nfor the full host-integration contract, and\n[SECURITY.md](SECURITY.md) for vulnerability reporting.\n\n## Install\n\nFrom source (current):\n\n```bash\ngit clone https://github.com/berabuddies/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\n```\n\nPython 3.11+ required. The project has **zero runtime dependencies** — both\nthe `responses` and `anthropic` providers talk to their APIs over raw HTTP\nusing the standard library.\n\n## Configuration\n\nSettings come from CLI flags, environment variables, or a repo-local\n`.env`. Copy [`.env.example`](.env.example) to `.env` and fill in your\ncredentials — `.env` is gitignored, and the pre-commit `gitleaks` hook\nruns locally against staged changes so secrets do not reach the history.\n\n### Providers\n\nSemia routes synthesis through one of four providers — two HTTP wire\nformats and two local CLI shell-outs. The default is `responses` with\nmodel `gpt-5.5`, authenticated via `OPENAI_API_KEY`.\n\n| Provider | Transport | Default model | Honors `--base-url` | Auth |\n| ------------ | ---------------------------------- | ------------------- | ------------------- | ----------------------------------------------------------------- |\n| `responses` | OpenAI Responses API (raw HTTP) | `gpt-5.5` | yes | `OPENAI_API_KEY`; `OPENAI_BASE_URL` (defaults to api.openai.com) |\n| `anthropic` | Anthropic Messages API (raw HTTP) | `claude-opus-4-7` | yes | `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`; `ANTHROPIC_BASE_URL` |\n| `codex` | shells out to `codex exec` | Codex CLI's own | no | inherits Codex CLI config |\n| `claude` | shells out to `claude --print` | `claude-opus-4-7` | no | inherits Claude Code env (`ANTHROPIC_*`) |\n\n`openai` is accepted as a synonym for `responses`. The **model** is free-form\n— any string the endpoint accepts works (`gpt-5.5`, `gpt-5.4`,\n`gpt-5.3-codex`, `deepseek-v4`, `claude-opus-4-7`, `claude-opus-4-6`, …).\n\nSwitch with flags:\n\n```bash\n# Default: OpenAI Responses against api.openai.com\nsemia scan ./some-skill --out .semia/runs/some-skill\n\n# Anthropic Messages against api.anthropic.com\nsemia scan ./some-skill --out .semia/runs/some-skill --provider anthropic\n\n# Point the responses format at a different endpoint (DeepSeek, OpenRouter, vLLM, …)\nsemia scan ./some-skill --out .semia/runs/some-skill \\\n --provider responses --model deepseek-v4 \\\n --base-url https://api.deepseek.com/v1\n\n# Use the locally-installed Claude Code CLI (model is the only knob)\nsemia scan ./some-skill --out .semia/runs/some-skill --provider claude --model claude-opus-4-7\n```\n\n### Most common environment variables\n\n| Variable | Purpose |\n| --------------------------- | -------------------------------------------------------------------- |\n| `SEMIA_LLM_PROVIDER` | `responses` (default) / `anthropic` / `codex` / `claude` |\n| `SEMIA_LLM_MODEL` | free-form model name passed to the provider |\n| `SEMIA_LLM_TIMEOUT` | request timeout in seconds |\n| `SEMIA_LLM_MAX_RETRIES` | retry budget for transient provider errors |\n| `OPENAI_BASE_URL` | base URL for the `responses` provider |\n| `ANTHROPIC_BASE_URL` | base URL for the `anthropic` provider |\n| `SEMIA_DETECTOR_BACKEND` | `auto` (default), `souffle`, `builtin` |\n| `SEMIA_SOUFFLE_BIN` | path to `souffle` if not on `PATH` |\n\nFor full synthesis tuning (`SEMIA_SYNTHESIS_*`), see the rest of\n[`.env.example`](.env.example) and\n[docs/plugin-protocol.md](docs/plugin-protocol.md).\n\n## Common workflows\n\n**Stop after deterministic preparation:**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --prepare-only\n```\n\n**Reuse facts from a prior run or an agent session:**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --facts synthesized_facts.dl\nsemia report .semia/runs/some-skill --format sarif\n```\n\n**CI smoke test (no LLM call):**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --offline-baseline\n```\n> `--offline-baseline` is a conservative non-LLM fallback for offline demos\n> and CI smoke tests. It is **not** a substitute for real synthesis.\n\n## Install as a host plugin\n\nThe Codex and Claude Code plugin bundles under `packages/semia-plugins//`\nship with a self-contained `bin/semia.pyz` zipapp, so they work out of the\nbox without a separate `pip install semia`. The OpenClaw skill\nrelies on the published `semia` CLI on `PATH` (ClawHub provisions it via\n`uv tool install`). Installing the Python package as well is recommended if\nyou want `semia` available as a normal shell command alongside the in-host\nworkflow.\n\n**Codex** — pick either path.\n\n> `codex plugin` only exposes a `marketplace` subcommand (`add` /\n> `upgrade` / `remove`) — there is **no `codex plugin install`**.\n> \"Installing\" a plugin means enabling the\n> `[plugins.\"@\"]` toggle in `~/.codex/config.toml`,\n> either via the `/plugins` TUI panel or by editing the file directly.\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add berabuddies/Semia\n```\n\nThen append the plugin toggle to `~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia@semia\"]\nenabled = true\n```\n\nThe second `semia` is the marketplace identifier (the top-level\n`name` in this repo's `.agents/plugins/marketplace.json`); the first\n`semia` is the plugin entry under it. For a one-shot non-persistent\nrun you can use `codex -c 'plugins.\"semia@semia\".enabled=true'`\ninstead of editing the file.\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, toggle `semia` on from the newly-added\n marketplace (the panel writes the same `[plugins.\"semia@semia\"]`\n block into `~/.codex/config.toml` for you).\n\n**Claude Code** — pick either path.\n\n*Shell (scripts and CI):*\n\n```bash\nclaude plugin marketplace add berabuddies/Semia\nclaude plugin install semia@semia\n```\n\n*Interactive plugin manager inside the Claude Code CLI:*\n\n1. Launch `claude`.\n2. Inside Claude Code, input `/plugins` (plural — opens the plugin panel).\n3. Press **→** (Right) twice and select **Add Marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, install `semia` from the newly-added marketplace.\n\nThe `name@marketplace` form on `install` is required — the second `semia`\nis the marketplace identifier from the project's `marketplace.json`.\nUse `--scope user|project|local` on the shell form to control where the\nplugin is recorded (default is `user`):\n\n```bash\nclaude plugin install semia@semia --scope project\n```\n\nSee [Discover and install plugins](https://code.claude.com/docs/en/discover-plugins)\nfor the full UX and [Plugins reference](https://code.claude.com/docs/en/plugins-reference#cli-commands-reference)\nfor the complete list of `claude plugin ...` subcommands.\n\n**OpenClaw** — install from ClawHub:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nClawHub will install the `semia` CLI on demand via `uv tool install\nsemia` (declared in the skill's `install` block). If you prefer to\npre-provision it yourself:\n\n```bash\nuv tool install semia # or: pip install semia\nopenclaw plugins install clawhub:semia\n```\n\n## Repository layout\n\n```text\npackages/\n semia-core/ # deterministic analysis library (prepare, check, detect, report)\n semia-cli/ # `semia` command surface\n semia-plugins/ # Codex / Claude Code / OpenClaw integrations\ndocs/\n architecture.md\n plugin-protocol.md\n release.md\n supply-chain.md\ntests/\n\n```\n\n## Development\n\n```bash\ngit clone https://github.com/berabuddies/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\npython -m pip install pre-commit\npre-commit install\npre-commit run --all-files # establish a clean baseline\n\nmake help # list targets\nmake check # compile + tests + manifest validation\nmake build # package metadata check\nmake release-check # full pre-release gate\n```\n\nThe root quality gates stay stdlib-friendly: `compileall`, `unittest`\ndiscovery, and stdlib-only validators. Pre-commit adds `ruff` lint/format\nand `gitleaks` secret scanning. CI mirrors `ruff` via\n[`lint.yml`](.github/workflows/lint.yml); `gitleaks` stays local-only\nbecause the upstream GitHub Action now requires a paid license for\norganization repositories.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow and the DCO\nsign-off requirement.\n\n## Project background\n\nThe technique behind Semia is described in the Semia paper\n([arXiv:2605.00314](https://arxiv.org/abs/2605.00314) ·\n[PDF](https://arxiv.org/pdf/2605.00314)). Semia is the\n**deterministic acceptance boundary** around behavior mapping: agents may\nextract facts, but only checked, evidence-grounded facts make it into a\nreport.\n\n## Security\n\nTo report a security vulnerability, see [SECURITY.md](SECURITY.md). Please\ndo **not** file public GitHub issues for security problems.\n\n## Contributing\n\nContributions are welcome — bug reports, documentation fixes, detector\nrules, and code. See [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow\nand the DCO sign-off requirement.\n\n## License & trademarks\n\nSemia is released under the [Apache License 2.0](LICENSE). You\nmay use, modify, and redistribute it freely, including for commercial\npurposes, subject to the terms of the license. See [NOTICE](NOTICE) for\nattribution.\n\nThe names **\"Semia\"**, **\"Semia\"**, **\"Semia\"**, and\n**\"berabuddies\"** are trademarks of berabuddies and are **not** licensed under\nApache-2.0. See [TRADEMARKS.md](TRADEMARKS.md) for the trademark policy.\n"}, "44a85a55d0223c473d1d80f909039c6d531387f9": {"t": 1785762614.1028404, "n": 18806, "h": "6d779cf76bbe6615", "c": "# Semia\n\n> **Security audit for AI agent skills.** Know what a skill *can* do\n> before you trust it.\n\n[![CI](https://github.com/berabuddies/Semia/actions/workflows/ci.yml/badge.svg)](https://github.com/berabuddies/Semia/actions/workflows/ci.yml)\n[![Lint](https://github.com/berabuddies/Semia/actions/workflows/lint.yml/badge.svg)](https://github.com/berabuddies/Semia/actions/workflows/lint.yml)\n[![codecov](https://codecov.io/gh/berabuddies/Semia/graph/badge.svg)](https://codecov.io/gh/berabuddies/Semia)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](pyproject.toml)\n\nAgent skills are markdown files with embedded shell commands, network calls,\nand tool invocations. They run with **your credentials, on your machine,\nwith your data**. Semia reads a skill as data — never executes it — and\nproduces an evidence-backed report of every capability it may exercise.\n\nIt is the difference between\n\n> *\"I trust this skill because the README looks fine.\"*\n\nand\n\n> *\"I trust this skill because Semia extracted 14 actions, 6 effects,\n> and 2 secret reads — and every one is grounded in a specific source line.\"*\n\n---\n\n## Quick example\n\nPick whichever fits how you already work.\n\n### As a CLI\n\n```bash\npip install semia\nsemia scan ./some-skill --out .semia/runs/some-skill\n```\n\n`scan` does prepare → synthesize (via your configured LLM provider) →\ndetect → report in one shot. You'll need an LLM provider configured first —\nsee [Set up an LLM provider](#set-up-an-llm-provider) below.\n\n### Inside Codex, Claude Code, or OpenClaw\n\nInstall the plugin once. Each host has its own flow.\n\n**Codex** — pick either path:\n\n*Shell (one-liner):*\n\n```bash\ncodex plugin marketplace add berabuddies/Semia\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `berabuddies/Semia`.\n\nEither path leaves the marketplace registered; install `semia`\nfrom the panel or by re-running the relevant install command.\n\n**Claude Code** — pick either path:\n\n*Shell (one-liner):*\n\n```bash\nclaude plugin marketplace add berabuddies/Semia\n```\n\n*Interactive plugin manager inside the Claude Code CLI:*\n\n1. Launch `claude`.\n2. Inside Claude Code, input `/plugins` (plural — opens the plugin panel).\n3. Press **→** (Right) twice and select **Add Marketplace**.\n4. Enter `berabuddies/Semia`.\n\nEither path registers the marketplace; finish installing `semia` from\nthe panel or with `claude plugin install semia@semia`.\n\n**OpenClaw** — one shell command registers the marketplace and installs:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nThen in any chat with the host agent just ask:\n\n> Run Semia audit on ./some-skill\n\nThe host agent itself acts as the synthesize step — **no API key needed**.\nThe bundled `semia.pyz` handles prepare / detect / report deterministically.\n\n### Outputs\n\nYou get `report.md` — findings ranked by severity, every one tied to a\nspecific source line. Need [SARIF 2.1.0](https://sarifweb.azurewebsites.net/)\nfor GitHub Code Scanning, or structured JSON for downstream tooling? One\nmore command:\n\n```bash\nsemia report .semia/runs/some-skill --format sarif # for GitHub Code Scanning\nsemia report .semia/runs/some-skill --format json # structured payload\n```\n\n## Set up an LLM provider\n\n`semia scan` needs an LLM for the **synthesize** step (the other three\nstages are deterministic, no key required). If you run Semia via a host\nplugin (Codex / Claude Code / OpenClaw) skip this — the host agent already\ndoes synthesize for you.\n\nFour providers are supported. Pick one and export its credentials:\n\n```bash\n# OpenAI Responses API — default; also works for DeepSeek / OpenRouter / vLLM\nexport OPENAI_API_KEY=sk-...\n# optional: export OPENAI_BASE_URL=https://api.deepseek.com/v1\n\n# Anthropic Messages API\nexport SEMIA_LLM_PROVIDER=anthropic\nexport ANTHROPIC_API_KEY=sk-ant-...\n# optional: export ANTHROPIC_BASE_URL=https://api.anthropic.com\n\n# Locally-installed Claude Code CLI (uses your Claude Code login)\nexport SEMIA_LLM_PROVIDER=claude\n\n# Locally-installed Codex CLI (uses your Codex login)\nexport SEMIA_LLM_PROVIDER=codex\n```\n\nOverride the model with `--model ` on any `semia scan` invocation, or\npersist it via `SEMIA_LLM_MODEL`. Models are free-form strings — anything\nthe endpoint accepts (`gpt-5.5`, `deepseek-v4`, `claude-opus-4-7`, …).\n\nSee [Configuration](#configuration) for the full provider matrix, base-URL\nsupport, timeout/retry knobs, and synthesis-loop tuning.\n\n## What you get\n\nA run writes everything under `.semia/runs//`. **Most users only\never open the reports**:\n\n| Report | When |\n| ------------------- | --------------------------------------------------------- |\n| `report.md` | always produced by `semia scan` — read this first |\n| `report.sarif.json` | on demand via `semia report --format sarif` — feed to GitHub Code Scanning |\n| `report.json` | on demand via `semia report --format json` — structured payload (check + evidence + detector) for programmatic consumers |\n\nBecause every finding traces back to a source line, the SARIF drops cleanly\ninto GitHub Code Scanning and reviewers see annotations directly on the\nskill PR.\n\n
\nOther artifacts in the run directory (internal — for tooling, debugging, or re-querying)\n\n| Artifact | Purpose |\n| ------------------------- | -------------------------------------------------- |\n| `synthesized_facts.dl` | the behavior map (Datalog facts) — re-queryable |\n| `detection_findings.dl` | findings derived by rule evaluation |\n| `prepared_skill.md` | normalized skill text with stable line anchors |\n| `prepare_units.json` | reference units the evidence text aligns against |\n| `synthesis_metadata.json` | provider, model, retries, score, stop reason |\n| `run_manifest.json` | end-to-end manifest of the run |\n\n
\n\n## Worked example\n\nPicture a skill that promises to \"summarize your inbox every day\". It\ninstalls a browser automation tool, opens your real Chrome (with every\nsaved login), reads Gmail, pipes the messages to an LLM that controls\nthe browser, and sets up a launchd job to repeat daily — forever. One\nemail from an attacker turns that skill into a remote control for every\nsite you are logged into.\n\n[See **EXAMPLE.md** for the full walkthrough →](EXAMPLE.md) — the skill\nsource, the attack, why it works, and the exact capabilities Semia\nsurfaces before you install.\n\n## How it works\n\n```text\n ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌────────┐\n │ Prepare │ ──▶ │ Synthesize │ ──▶ │ Detect │ ──▶ │ Report │\n │ (det.) │ │ (LLM) │ │ (det.) │ │ (det.) │\n └──────────┘ └────────────┘ └──────────┘ └────────┘\n```\n\n1. **Prepare** — read skill markdown + adjacent source, inline references,\n assign stable evidence handles. Pure stdlib. No LLM.\n2. **Synthesize** — an LLM (or the host agent's own session) extracts a\n *behavior map* as Datalog facts (`action`, `call`, `call_effect`, …)\n with `_evidence_text` sidecars citing the original source. The loop\n retries invalid candidates with checker feedback and keeps the best one.\n3. **Detect** — a Datalog evaluator runs the bundled SDL rules over the\n facts to flag risky combinations (e.g. *secret read → network write*).\n4. **Report** — render Markdown for humans and SARIF for CI.\n\nDetection runs through a built-in pure-Python Datalog evaluator by default,\nso **no external binary is required**. If [Soufflé](https://souffle-lang.github.io/)\nis on `PATH` (or `SEMIA_SOUFFLE_BIN`) it is preferred as a faster backend.\nOverride with `SEMIA_DETECTOR_BACKEND=auto|souffle|builtin`.\n\n[Read the full architecture →](docs/architecture.md)\n\n## Trust model\n\nSemia is a security tool for analyzing untrusted content. The trust\nboundary is explicit:\n\n| Surface | Treatment |\n| ------------------------- | -------------------------------------------------------------------------------- |\n| Audited skill | **untrusted data** — never executed, hooks/installers ignored |\n| Skill-declared URLs | **never fetched** during a scan |\n| Prompt-injection in skill | **recorded as evidence**, not followed as instructions |\n| Prepare / Detect / Report | deterministic, stdlib-friendly, runs locally |\n| Synthesize | the only LLM-mediated step; output must pass structural and evidence checks |\n| Network | LLM provider only |\n| Filesystem | reads the skill directory; writes only `.semia/runs//` |\n\nSee [docs/plugin-protocol.md#hostile-input-rules](docs/plugin-protocol.md)\nfor the full host-integration contract, and\n[SECURITY.md](SECURITY.md) for vulnerability reporting.\n\n## Install\n\nFrom source (current):\n\n```bash\ngit clone https://github.com/berabuddies/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\n```\n\nPython 3.11+ required. The project has **zero runtime dependencies** — both\nthe `responses` and `anthropic` providers talk to their APIs over raw HTTP\nusing the standard library.\n\n## Configuration\n\nSettings come from CLI flags, environment variables, or a repo-local\n`.env`. Copy [`.env.example`](.env.example) to `.env` and fill in your\ncredentials — `.env` is gitignored, and the pre-commit `gitleaks` hook\nruns locally against staged changes so secrets do not reach the history.\n\n### Providers\n\nSemia routes synthesis through one of four providers — two HTTP wire\nformats and two local CLI shell-outs. The default is `responses` with\nmodel `gpt-5.5`, authenticated via `OPENAI_API_KEY`.\n\n| Provider | Transport | Default model | Honors `--base-url` | Auth |\n| ------------ | ---------------------------------- | ------------------- | ------------------- | ----------------------------------------------------------------- |\n| `responses` | OpenAI Responses API (raw HTTP) | `gpt-5.5` | yes | `OPENAI_API_KEY`; `OPENAI_BASE_URL` (defaults to api.openai.com) |\n| `anthropic` | Anthropic Messages API (raw HTTP) | `claude-opus-4-7` | yes | `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`; `ANTHROPIC_BASE_URL` |\n| `codex` | shells out to `codex exec` | Codex CLI's own | no | inherits Codex CLI config |\n| `claude` | shells out to `claude --print` | `claude-opus-4-7` | no | inherits Claude Code env (`ANTHROPIC_*`) |\n\n`openai` is accepted as a synonym for `responses`. The **model** is free-form\n— any string the endpoint accepts works (`gpt-5.5`, `gpt-5.4`,\n`gpt-5.3-codex`, `deepseek-v4`, `claude-opus-4-7`, `claude-opus-4-6`, …).\n\nSwitch with flags:\n\n```bash\n# Default: OpenAI Responses against api.openai.com\nsemia scan ./some-skill --out .semia/runs/some-skill\n\n# Anthropic Messages against api.anthropic.com\nsemia scan ./some-skill --out .semia/runs/some-skill --provider anthropic\n\n# Point the responses format at a different endpoint (DeepSeek, OpenRouter, vLLM, …)\nsemia scan ./some-skill --out .semia/runs/some-skill \\\n --provider responses --model deepseek-v4 \\\n --base-url https://api.deepseek.com/v1\n\n# Use the locally-installed Claude Code CLI (model is the only knob)\nsemia scan ./some-skill --out .semia/runs/some-skill --provider claude --model claude-opus-4-7\n```\n\n### Most common environment variables\n\n| Variable | Purpose |\n| --------------------------- | -------------------------------------------------------------------- |\n| `SEMIA_LLM_PROVIDER` | `responses` (default) / `anthropic` / `codex` / `claude` |\n| `SEMIA_LLM_MODEL` | free-form model name passed to the provider |\n| `SEMIA_LLM_TIMEOUT` | request timeout in seconds |\n| `SEMIA_LLM_MAX_RETRIES` | retry budget for transient provider errors |\n| `OPENAI_BASE_URL` | base URL for the `responses` provider |\n| `ANTHROPIC_BASE_URL` | base URL for the `anthropic` provider |\n| `SEMIA_DETECTOR_BACKEND` | `auto` (default), `souffle`, `builtin` |\n| `SEMIA_SOUFFLE_BIN` | path to `souffle` if not on `PATH` |\n\nFor full synthesis tuning (`SEMIA_SYNTHESIS_*`), see the rest of\n[`.env.example`](.env.example) and\n[docs/plugin-protocol.md](docs/plugin-protocol.md).\n\n## Common workflows\n\n**Stop after deterministic preparation:**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --prepare-only\n```\n\n**Reuse facts from a prior run or an agent session:**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --facts synthesized_facts.dl\nsemia report .semia/runs/some-skill --format sarif\n```\n\n**CI smoke test (no LLM call):**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --offline-baseline\n```\n> `--offline-baseline` is a conservative non-LLM fallback for offline demos\n> and CI smoke tests. It is **not** a substitute for real synthesis.\n\n## Install as a host plugin\n\nThe Codex and Claude Code plugin bundles under `packages/semia-plugins//`\nship with a self-contained `bin/semia.pyz` zipapp, so they work out of the\nbox without a separate `pip install semia`. The OpenClaw skill\nrelies on the published `semia` CLI on `PATH` (ClawHub provisions it via\n`uv tool install`). Installing the Python package as well is recommended if\nyou want `semia` available as a normal shell command alongside the in-host\nworkflow.\n\n**Codex** — pick either path.\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add berabuddies/Semia\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, install `semia` from the newly-added\n marketplace.\n\nHeadless setups can enable the plugin directly by adding the following to\n`~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia@semia\"]\nenabled = true\n```\n\n**Claude Code** — pick either path.\n\n*Shell (scripts and CI):*\n\n```bash\nclaude plugin marketplace add berabuddies/Semia\nclaude plugin install semia@semia\n```\n\n*Interactive plugin manager inside the Claude Code CLI:*\n\n1. Launch `claude`.\n2. Inside Claude Code, input `/plugins` (plural — opens the plugin panel).\n3. Press **→** (Right) twice and select **Add Marketplace**.\n4. Enter `berabuddies/Semia`.\n5. Back in the plugin panel, install `semia` from the newly-added marketplace.\n\nThe `name@marketplace` form on `install` is required — the second `semia`\nis the marketplace identifier from the project's `marketplace.json`.\nUse `--scope user|project|local` on the shell form to control where the\nplugin is recorded (default is `user`):\n\n```bash\nclaude plugin install semia@semia --scope project\n```\n\nSee [Discover and install plugins](https://code.claude.com/docs/en/discover-plugins)\nfor the full UX and [Plugins reference](https://code.claude.com/docs/en/plugins-reference#cli-commands-reference)\nfor the complete list of `claude plugin ...` subcommands.\n\n**OpenClaw** — install from ClawHub:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nClawHub will install the `semia` CLI on demand via `uv tool install\nsemia` (declared in the skill's `install` block). If you prefer to\npre-provision it yourself:\n\n```bash\nuv tool install semia # or: pip install semia\nopenclaw plugins install clawhub:semia\n```\n\n## Repository layout\n\n```text\npackages/\n semia-core/ # deterministic analysis library (prepare, check, detect, report)\n semia-cli/ # `semia` command surface\n semia-plugins/ # Codex / Claude Code / OpenClaw integrations\ndocs/\n architecture.md\n plugin-protocol.md\n release.md\n supply-chain.md\ntests/\n\n```\n\n## Development\n\n```bash\ngit clone https://github.com/berabuddies/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\npython -m pip install pre-commit\npre-commit install\npre-commit run --all-files # establish a clean baseline\n\nmake help # list targets\nmake check # compile + tests + manifest validation\nmake build # package metadata check\nmake release-check # full pre-release gate\n```\n\nThe root quality gates stay stdlib-friendly: `compileall`, `unittest`\ndiscovery, and stdlib-only validators. Pre-commit adds `ruff` lint/format\nand `gitleaks` secret scanning. CI mirrors `ruff` via\n[`lint.yml`](.github/workflows/lint.yml); `gitleaks` stays local-only\nbecause the upstream GitHub Action now requires a paid license for\norganization repositories.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow and the DCO\nsign-off requirement.\n\n## Project background\n\nThe technique behind Semia is described in the Semia paper\n([arXiv:2605.00314](https://arxiv.org/abs/2605.00314) ·\n[PDF](https://arxiv.org/pdf/2605.00314)). Semia is the\n**deterministic acceptance boundary** around behavior mapping: agents may\nextract facts, but only checked, evidence-grounded facts make it into a\nreport.\n\n## Security\n\nTo report a security vulnerability, see [SECURITY.md](SECURITY.md). Please\ndo **not** file public GitHub issues for security problems.\n\n## Contributing\n\nContributions are welcome — bug reports, documentation fixes, detector\nrules, and code. See [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow\nand the DCO sign-off requirement.\n\n## License & trademarks\n\nSemia is released under the [Apache License 2.0](LICENSE). You\nmay use, modify, and redistribute it freely, including for commercial\npurposes, subject to the terms of the license. See [NOTICE](NOTICE) for\nattribution.\n\nThe names **\"Semia\"**, **\"Semia\"**, **\"Semia\"**, and\n**\"berabuddies\"** are trademarks of berabuddies and are **not** licensed under\nApache-2.0. See [TRADEMARKS.md](TRADEMARKS.md) for the trademark policy.\n"}, "e385a41730ad3e0e7f3e5b7c51be07e731d40656": {"t": 1785762616.8762903, "n": 18770, "h": "e65c410ed89fe968", "c": "# Semia\n\n> **Security audit for AI agent skills.** Know what a skill *can* do\n> before you trust it.\n\n[![CI](https://github.com/RiemaLabs/Semia/actions/workflows/ci.yml/badge.svg)](https://github.com/RiemaLabs/Semia/actions/workflows/ci.yml)\n[![Lint](https://github.com/RiemaLabs/Semia/actions/workflows/lint.yml/badge.svg)](https://github.com/RiemaLabs/Semia/actions/workflows/lint.yml)\n[![codecov](https://codecov.io/gh/RiemaLabs/Semia/graph/badge.svg)](https://codecov.io/gh/RiemaLabs/Semia)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](pyproject.toml)\n\nAgent skills are markdown files with embedded shell commands, network calls,\nand tool invocations. They run with **your credentials, on your machine,\nwith your data**. Semia reads a skill as data — never executes it — and\nproduces an evidence-backed report of every capability it may exercise.\n\nIt is the difference between\n\n> *\"I trust this skill because the README looks fine.\"*\n\nand\n\n> *\"I trust this skill because Semia extracted 14 actions, 6 effects,\n> and 2 secret reads — and every one is grounded in a specific source line.\"*\n\n---\n\n## Quick example\n\nPick whichever fits how you already work.\n\n### As a CLI\n\n```bash\npip install semia\nsemia scan ./some-skill --out .semia/runs/some-skill\n```\n\n`scan` does prepare → synthesize (via your configured LLM provider) →\ndetect → report in one shot. You'll need an LLM provider configured first —\nsee [Set up an LLM provider](#set-up-an-llm-provider) below.\n\n### Inside Codex, Claude Code, or OpenClaw\n\nInstall the plugin once. Each host has its own flow.\n\n**Codex** — pick either path:\n\n*Shell (one-liner):*\n\n```bash\ncodex plugin marketplace add RiemaLabs/Semia\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `RiemaLabs/Semia`.\n\nEither path leaves the marketplace registered; install `semia`\nfrom the panel or by re-running the relevant install command.\n\n**Claude Code** — pick either path:\n\n*Shell (one-liner):*\n\n```bash\nclaude plugin marketplace add RiemaLabs/Semia\n```\n\n*Interactive plugin manager inside the Claude Code CLI:*\n\n1. Launch `claude`.\n2. Inside Claude Code, input `/plugins` (plural — opens the plugin panel).\n3. Press **→** (Right) twice and select **Add Marketplace**.\n4. Enter `RiemaLabs/Semia`.\n\nEither path registers the marketplace; finish installing `semia` from\nthe panel or with `claude plugin install semia@semia`.\n\n**OpenClaw** — one shell command registers the marketplace and installs:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nThen in any chat with the host agent just ask:\n\n> Run Semia audit on ./some-skill\n\nThe host agent itself acts as the synthesize step — **no API key needed**.\nThe bundled `semia.pyz` handles prepare / detect / report deterministically.\n\n### Outputs\n\nYou get `report.md` — findings ranked by severity, every one tied to a\nspecific source line. Need [SARIF 2.1.0](https://sarifweb.azurewebsites.net/)\nfor GitHub Code Scanning, or structured JSON for downstream tooling? One\nmore command:\n\n```bash\nsemia report .semia/runs/some-skill --format sarif # for GitHub Code Scanning\nsemia report .semia/runs/some-skill --format json # structured payload\n```\n\n## Set up an LLM provider\n\n`semia scan` needs an LLM for the **synthesize** step (the other three\nstages are deterministic, no key required). If you run Semia via a host\nplugin (Codex / Claude Code / OpenClaw) skip this — the host agent already\ndoes synthesize for you.\n\nFour providers are supported. Pick one and export its credentials:\n\n```bash\n# OpenAI Responses API — default; also works for DeepSeek / OpenRouter / vLLM\nexport OPENAI_API_KEY=sk-...\n# optional: export OPENAI_BASE_URL=https://api.deepseek.com/v1\n\n# Anthropic Messages API\nexport SEMIA_LLM_PROVIDER=anthropic\nexport ANTHROPIC_API_KEY=sk-ant-...\n# optional: export ANTHROPIC_BASE_URL=https://api.anthropic.com\n\n# Locally-installed Claude Code CLI (uses your Claude Code login)\nexport SEMIA_LLM_PROVIDER=claude\n\n# Locally-installed Codex CLI (uses your Codex login)\nexport SEMIA_LLM_PROVIDER=codex\n```\n\nOverride the model with `--model ` on any `semia scan` invocation, or\npersist it via `SEMIA_LLM_MODEL`. Models are free-form strings — anything\nthe endpoint accepts (`gpt-5.5`, `deepseek-v4`, `claude-opus-4-7`, …).\n\nSee [Configuration](#configuration) for the full provider matrix, base-URL\nsupport, timeout/retry knobs, and synthesis-loop tuning.\n\n## What you get\n\nA run writes everything under `.semia/runs//`. **Most users only\never open the reports**:\n\n| Report | When |\n| ------------------- | --------------------------------------------------------- |\n| `report.md` | always produced by `semia scan` — read this first |\n| `report.sarif.json` | on demand via `semia report --format sarif` — feed to GitHub Code Scanning |\n| `report.json` | on demand via `semia report --format json` — structured payload (check + evidence + detector) for programmatic consumers |\n\nBecause every finding traces back to a source line, the SARIF drops cleanly\ninto GitHub Code Scanning and reviewers see annotations directly on the\nskill PR.\n\n
\nOther artifacts in the run directory (internal — for tooling, debugging, or re-querying)\n\n| Artifact | Purpose |\n| ------------------------- | -------------------------------------------------- |\n| `synthesized_facts.dl` | the behavior map (Datalog facts) — re-queryable |\n| `detection_findings.dl` | findings derived by rule evaluation |\n| `prepared_skill.md` | normalized skill text with stable line anchors |\n| `prepare_units.json` | reference units the evidence text aligns against |\n| `synthesis_metadata.json` | provider, model, retries, score, stop reason |\n| `run_manifest.json` | end-to-end manifest of the run |\n\n
\n\n## Worked example\n\nPicture a skill that promises to \"summarize your inbox every day\". It\ninstalls a browser automation tool, opens your real Chrome (with every\nsaved login), reads Gmail, pipes the messages to an LLM that controls\nthe browser, and sets up a launchd job to repeat daily — forever. One\nemail from an attacker turns that skill into a remote control for every\nsite you are logged into.\n\n[See **EXAMPLE.md** for the full walkthrough →](EXAMPLE.md) — the skill\nsource, the attack, why it works, and the exact capabilities Semia\nsurfaces before you install.\n\n## How it works\n\n```text\n ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌────────┐\n │ Prepare │ ──▶ │ Synthesize │ ──▶ │ Detect │ ──▶ │ Report │\n │ (det.) │ │ (LLM) │ │ (det.) │ │ (det.) │\n └──────────┘ └────────────┘ └──────────┘ └────────┘\n```\n\n1. **Prepare** — read skill markdown + adjacent source, inline references,\n assign stable evidence handles. Pure stdlib. No LLM.\n2. **Synthesize** — an LLM (or the host agent's own session) extracts a\n *behavior map* as Datalog facts (`action`, `call`, `call_effect`, …)\n with `_evidence_text` sidecars citing the original source. The loop\n retries invalid candidates with checker feedback and keeps the best one.\n3. **Detect** — a Datalog evaluator runs the bundled SDL rules over the\n facts to flag risky combinations (e.g. *secret read → network write*).\n4. **Report** — render Markdown for humans and SARIF for CI.\n\nDetection runs through a built-in pure-Python Datalog evaluator by default,\nso **no external binary is required**. If [Soufflé](https://souffle-lang.github.io/)\nis on `PATH` (or `SEMIA_SOUFFLE_BIN`) it is preferred as a faster backend.\nOverride with `SEMIA_DETECTOR_BACKEND=auto|souffle|builtin`.\n\n[Read the full architecture →](docs/architecture.md)\n\n## Trust model\n\nSemia is a security tool for analyzing untrusted content. The trust\nboundary is explicit:\n\n| Surface | Treatment |\n| ------------------------- | -------------------------------------------------------------------------------- |\n| Audited skill | **untrusted data** — never executed, hooks/installers ignored |\n| Skill-declared URLs | **never fetched** during a scan |\n| Prompt-injection in skill | **recorded as evidence**, not followed as instructions |\n| Prepare / Detect / Report | deterministic, stdlib-friendly, runs locally |\n| Synthesize | the only LLM-mediated step; output must pass structural and evidence checks |\n| Network | LLM provider only |\n| Filesystem | reads the skill directory; writes only `.semia/runs//` |\n\nSee [docs/plugin-protocol.md#hostile-input-rules](docs/plugin-protocol.md)\nfor the full host-integration contract, and\n[SECURITY.md](SECURITY.md) for vulnerability reporting.\n\n## Install\n\nFrom source (current):\n\n```bash\ngit clone https://github.com/RiemaLabs/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\n```\n\nPython 3.11+ required. The project has **zero runtime dependencies** — both\nthe `responses` and `anthropic` providers talk to their APIs over raw HTTP\nusing the standard library.\n\n## Configuration\n\nSettings come from CLI flags, environment variables, or a repo-local\n`.env`. Copy [`.env.example`](.env.example) to `.env` and fill in your\ncredentials — `.env` is gitignored, and the pre-commit `gitleaks` hook\nruns locally against staged changes so secrets do not reach the history.\n\n### Providers\n\nSemia routes synthesis through one of four providers — two HTTP wire\nformats and two local CLI shell-outs. The default is `responses` with\nmodel `gpt-5.5`, authenticated via `OPENAI_API_KEY`.\n\n| Provider | Transport | Default model | Honors `--base-url` | Auth |\n| ------------ | ---------------------------------- | ------------------- | ------------------- | ----------------------------------------------------------------- |\n| `responses` | OpenAI Responses API (raw HTTP) | `gpt-5.5` | yes | `OPENAI_API_KEY`; `OPENAI_BASE_URL` (defaults to api.openai.com) |\n| `anthropic` | Anthropic Messages API (raw HTTP) | `claude-opus-4-7` | yes | `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`; `ANTHROPIC_BASE_URL` |\n| `codex` | shells out to `codex exec` | Codex CLI's own | no | inherits Codex CLI config |\n| `claude` | shells out to `claude --print` | `claude-opus-4-7` | no | inherits Claude Code env (`ANTHROPIC_*`) |\n\n`openai` is accepted as a synonym for `responses`. The **model** is free-form\n— any string the endpoint accepts works (`gpt-5.5`, `gpt-5.4`,\n`gpt-5.3-codex`, `deepseek-v4`, `claude-opus-4-7`, `claude-opus-4-6`, …).\n\nSwitch with flags:\n\n```bash\n# Default: OpenAI Responses against api.openai.com\nsemia scan ./some-skill --out .semia/runs/some-skill\n\n# Anthropic Messages against api.anthropic.com\nsemia scan ./some-skill --out .semia/runs/some-skill --provider anthropic\n\n# Point the responses format at a different endpoint (DeepSeek, OpenRouter, vLLM, …)\nsemia scan ./some-skill --out .semia/runs/some-skill \\\n --provider responses --model deepseek-v4 \\\n --base-url https://api.deepseek.com/v1\n\n# Use the locally-installed Claude Code CLI (model is the only knob)\nsemia scan ./some-skill --out .semia/runs/some-skill --provider claude --model claude-opus-4-7\n```\n\n### Most common environment variables\n\n| Variable | Purpose |\n| --------------------------- | -------------------------------------------------------------------- |\n| `SEMIA_LLM_PROVIDER` | `responses` (default) / `anthropic` / `codex` / `claude` |\n| `SEMIA_LLM_MODEL` | free-form model name passed to the provider |\n| `SEMIA_LLM_TIMEOUT` | request timeout in seconds |\n| `SEMIA_LLM_MAX_RETRIES` | retry budget for transient provider errors |\n| `OPENAI_BASE_URL` | base URL for the `responses` provider |\n| `ANTHROPIC_BASE_URL` | base URL for the `anthropic` provider |\n| `SEMIA_DETECTOR_BACKEND` | `auto` (default), `souffle`, `builtin` |\n| `SEMIA_SOUFFLE_BIN` | path to `souffle` if not on `PATH` |\n\nFor full synthesis tuning (`SEMIA_SYNTHESIS_*`), see the rest of\n[`.env.example`](.env.example) and\n[docs/plugin-protocol.md](docs/plugin-protocol.md).\n\n## Common workflows\n\n**Stop after deterministic preparation:**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --prepare-only\n```\n\n**Reuse facts from a prior run or an agent session:**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --facts synthesized_facts.dl\nsemia report .semia/runs/some-skill --format sarif\n```\n\n**CI smoke test (no LLM call):**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --offline-baseline\n```\n> `--offline-baseline` is a conservative non-LLM fallback for offline demos\n> and CI smoke tests. It is **not** a substitute for real synthesis.\n\n## Install as a host plugin\n\nThe Codex and Claude Code plugin bundles under `packages/semia-plugins//`\nship with a self-contained `bin/semia.pyz` zipapp, so they work out of the\nbox without a separate `pip install semia`. The OpenClaw skill\nrelies on the published `semia` CLI on `PATH` (ClawHub provisions it via\n`uv tool install`). Installing the Python package as well is recommended if\nyou want `semia` available as a normal shell command alongside the in-host\nworkflow.\n\n**Codex** — pick either path.\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add RiemaLabs/Semia\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `RiemaLabs/Semia`.\n5. Back in the plugin panel, install `semia` from the newly-added\n marketplace.\n\nHeadless setups can enable the plugin directly by adding the following to\n`~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia@semia\"]\nenabled = true\n```\n\n**Claude Code** — pick either path.\n\n*Shell (scripts and CI):*\n\n```bash\nclaude plugin marketplace add RiemaLabs/Semia\nclaude plugin install semia@semia\n```\n\n*Interactive plugin manager inside the Claude Code CLI:*\n\n1. Launch `claude`.\n2. Inside Claude Code, input `/plugins` (plural — opens the plugin panel).\n3. Press **→** (Right) twice and select **Add Marketplace**.\n4. Enter `RiemaLabs/Semia`.\n5. Back in the plugin panel, install `semia` from the newly-added marketplace.\n\nThe `name@marketplace` form on `install` is required — the second `semia`\nis the marketplace identifier from the project's `marketplace.json`.\nUse `--scope user|project|local` on the shell form to control where the\nplugin is recorded (default is `user`):\n\n```bash\nclaude plugin install semia@semia --scope project\n```\n\nSee [Discover and install plugins](https://code.claude.com/docs/en/discover-plugins)\nfor the full UX and [Plugins reference](https://code.claude.com/docs/en/plugins-reference#cli-commands-reference)\nfor the complete list of `claude plugin ...` subcommands.\n\n**OpenClaw** — install from ClawHub:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nClawHub will install the `semia` CLI on demand via `uv tool install\nsemia` (declared in the skill's `install` block). If you prefer to\npre-provision it yourself:\n\n```bash\nuv tool install semia # or: pip install semia\nopenclaw plugins install clawhub:semia\n```\n\n## Repository layout\n\n```text\npackages/\n semia-core/ # deterministic analysis library (prepare, check, detect, report)\n semia-cli/ # `semia` command surface\n semia-plugins/ # Codex / Claude Code / OpenClaw integrations\ndocs/\n architecture.md\n plugin-protocol.md\n release.md\n supply-chain.md\ntests/\n\n```\n\n## Development\n\n```bash\ngit clone https://github.com/RiemaLabs/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\npython -m pip install pre-commit\npre-commit install\npre-commit run --all-files # establish a clean baseline\n\nmake help # list targets\nmake check # compile + tests + manifest validation\nmake build # package metadata check\nmake release-check # full pre-release gate\n```\n\nThe root quality gates stay stdlib-friendly: `compileall`, `unittest`\ndiscovery, and stdlib-only validators. Pre-commit adds `ruff` lint/format\nand `gitleaks` secret scanning. CI mirrors `ruff` via\n[`lint.yml`](.github/workflows/lint.yml); `gitleaks` stays local-only\nbecause the upstream GitHub Action now requires a paid license for\norganization repositories.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow and the DCO\nsign-off requirement.\n\n## Project background\n\nThe technique behind Semia is described in the Semia paper\n([arXiv:2605.00314](https://arxiv.org/abs/2605.00314) ·\n[PDF](https://arxiv.org/pdf/2605.00314)). Semia is the\n**deterministic acceptance boundary** around behavior mapping: agents may\nextract facts, but only checked, evidence-grounded facts make it into a\nreport.\n\n## Security\n\nTo report a security vulnerability, see [SECURITY.md](SECURITY.md). Please\ndo **not** file public GitHub issues for security problems.\n\n## Contributing\n\nContributions are welcome — bug reports, documentation fixes, detector\nrules, and code. See [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow\nand the DCO sign-off requirement.\n\n## License & trademarks\n\nSemia is released under the [Apache License 2.0](LICENSE). You\nmay use, modify, and redistribute it freely, including for commercial\npurposes, subject to the terms of the license. See [NOTICE](NOTICE) for\nattribution.\n\nThe names **\"Semia\"**, **\"Semia\"**, **\"Semia\"**, and\n**\"RiemaLabs\"** are trademarks of RiemaLabs and are **not** licensed under\nApache-2.0. See [TRADEMARKS.md](TRADEMARKS.md) for the trademark policy.\n"}, "147af551080a93799c0814f9cec0a43c81c96937": {"t": 1785762619.1445227, "n": 18473, "h": "ee973acab317bae3", "c": "# Semia\n\n> **Security audit for AI agent skills.** Know what a skill *can* do\n> before you trust it.\n\n[![CI](https://github.com/RiemaLabs/Semia/actions/workflows/ci.yml/badge.svg)](https://github.com/RiemaLabs/Semia/actions/workflows/ci.yml)\n[![Lint](https://github.com/RiemaLabs/Semia/actions/workflows/lint.yml/badge.svg)](https://github.com/RiemaLabs/Semia/actions/workflows/lint.yml)\n[![codecov](https://codecov.io/gh/RiemaLabs/Semia/graph/badge.svg)](https://codecov.io/gh/RiemaLabs/Semia)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](pyproject.toml)\n\nAgent skills are markdown files with embedded shell commands, network calls,\nand tool invocations. They run with **your credentials, on your machine,\nwith your data**. Semia reads a skill as data — never executes it — and\nproduces an evidence-backed report of every capability it may exercise.\n\nIt is the difference between\n\n> *\"I trust this skill because the README looks fine.\"*\n\nand\n\n> *\"I trust this skill because Semia extracted 14 actions, 6 effects,\n> and 2 secret reads — and every one is grounded in a specific source line.\"*\n\n---\n\n## Quick example\n\nPick whichever fits how you already work.\n\n### As a CLI\n\n```bash\npip install semia\nsemia scan ./some-skill --out .semia/runs/some-skill\n```\n\n`scan` does prepare → synthesize (via your configured LLM provider) →\ndetect → report in one shot. You'll need an LLM provider configured first —\nsee [Set up an LLM provider](#set-up-an-llm-provider) below.\n\n### Inside Codex, Claude Code, or OpenClaw\n\nInstall the plugin once. Each host has its own flow.\n\n**Codex** — pick either path:\n\n*Shell (one-liner):*\n\n```bash\ncodex plugin marketplace add RiemaLabs/Semia\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `RiemaLabs/Semia`.\n\nEither path leaves the marketplace registered; install `semia`\nfrom the panel or by re-running the relevant install command.\n\n**Claude Code** — pick either path:\n\n*Shell (one-liner):*\n\n```bash\nclaude plugin marketplace add RiemaLabs/Semia\n```\n\n*Slash commands inside the Claude Code CLI:*\n\n```text\n/plugin marketplace add RiemaLabs/Semia\n/plugin install semia@semia\n```\n\nEither path registers the marketplace; finish installing `semia` from\nthe slash command above or with `claude plugin install semia@semia`.\n\n**OpenClaw** — one shell command registers the marketplace and installs:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nThen in any chat with the host agent just ask:\n\n> Run Semia audit on ./some-skill\n\nThe host agent itself acts as the synthesize step — **no API key needed**.\nThe bundled `semia.pyz` handles prepare / detect / report deterministically.\n\n### Outputs\n\nYou get `report.md` — findings ranked by severity, every one tied to a\nspecific source line. Need [SARIF 2.1.0](https://sarifweb.azurewebsites.net/)\nfor GitHub Code Scanning, or structured JSON for downstream tooling? One\nmore command:\n\n```bash\nsemia report .semia/runs/some-skill --format sarif # for GitHub Code Scanning\nsemia report .semia/runs/some-skill --format json # structured payload\n```\n\n## Set up an LLM provider\n\n`semia scan` needs an LLM for the **synthesize** step (the other three\nstages are deterministic, no key required). If you run Semia via a host\nplugin (Codex / Claude Code / OpenClaw) skip this — the host agent already\ndoes synthesize for you.\n\nFour providers are supported. Pick one and export its credentials:\n\n```bash\n# OpenAI Responses API — default; also works for DeepSeek / OpenRouter / vLLM\nexport OPENAI_API_KEY=sk-...\n# optional: export OPENAI_BASE_URL=https://api.deepseek.com/v1\n\n# Anthropic Messages API\nexport SEMIA_LLM_PROVIDER=anthropic\nexport ANTHROPIC_API_KEY=sk-ant-...\n# optional: export ANTHROPIC_BASE_URL=https://api.anthropic.com\n\n# Locally-installed Claude Code CLI (uses your Claude Code login)\nexport SEMIA_LLM_PROVIDER=claude\n\n# Locally-installed Codex CLI (uses your Codex login)\nexport SEMIA_LLM_PROVIDER=codex\n```\n\nOverride the model with `--model ` on any `semia scan` invocation, or\npersist it via `SEMIA_LLM_MODEL`. Models are free-form strings — anything\nthe endpoint accepts (`gpt-5.5`, `deepseek-v4`, `claude-opus-4-7`, …).\n\nSee [Configuration](#configuration) for the full provider matrix, base-URL\nsupport, timeout/retry knobs, and synthesis-loop tuning.\n\n## What you get\n\nA run writes everything under `.semia/runs//`. **Most users only\never open the reports**:\n\n| Report | When |\n| ------------------- | --------------------------------------------------------- |\n| `report.md` | always produced by `semia scan` — read this first |\n| `report.sarif.json` | on demand via `semia report --format sarif` — feed to GitHub Code Scanning |\n| `report.json` | on demand via `semia report --format json` — structured payload (check + evidence + detector) for programmatic consumers |\n\nBecause every finding traces back to a source line, the SARIF drops cleanly\ninto GitHub Code Scanning and reviewers see annotations directly on the\nskill PR.\n\n
\nOther artifacts in the run directory (internal — for tooling, debugging, or re-querying)\n\n| Artifact | Purpose |\n| ------------------------- | -------------------------------------------------- |\n| `synthesized_facts.dl` | the behavior map (Datalog facts) — re-queryable |\n| `detection_findings.dl` | findings derived by rule evaluation |\n| `prepared_skill.md` | normalized skill text with stable line anchors |\n| `prepare_units.json` | reference units the evidence text aligns against |\n| `synthesis_metadata.json` | provider, model, retries, score, stop reason |\n| `run_manifest.json` | end-to-end manifest of the run |\n\n
\n\n## Worked example\n\nPicture a skill that promises to \"summarize your inbox every day\". It\ninstalls a browser automation tool, opens your real Chrome (with every\nsaved login), reads Gmail, pipes the messages to an LLM that controls\nthe browser, and sets up a launchd job to repeat daily — forever. One\nemail from an attacker turns that skill into a remote control for every\nsite you are logged into.\n\n[See **EXAMPLE.md** for the full walkthrough →](EXAMPLE.md) — the skill\nsource, the attack, why it works, and the exact capabilities Semia\nsurfaces before you install.\n\n## How it works\n\n```text\n ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌────────┐\n │ Prepare │ ──▶ │ Synthesize │ ──▶ │ Detect │ ──▶ │ Report │\n │ (det.) │ │ (LLM) │ │ (det.) │ │ (det.) │\n └──────────┘ └────────────┘ └──────────┘ └────────┘\n```\n\n1. **Prepare** — read skill markdown + adjacent source, inline references,\n assign stable evidence handles. Pure stdlib. No LLM.\n2. **Synthesize** — an LLM (or the host agent's own session) extracts a\n *behavior map* as Datalog facts (`action`, `call`, `call_effect`, …)\n with `_evidence_text` sidecars citing the original source. The loop\n retries invalid candidates with checker feedback and keeps the best one.\n3. **Detect** — a Datalog evaluator runs the bundled SDL rules over the\n facts to flag risky combinations (e.g. *secret read → network write*).\n4. **Report** — render Markdown for humans and SARIF for CI.\n\nDetection runs through a built-in pure-Python Datalog evaluator by default,\nso **no external binary is required**. If [Soufflé](https://souffle-lang.github.io/)\nis on `PATH` (or `SEMIA_SOUFFLE_BIN`) it is preferred as a faster backend.\nOverride with `SEMIA_DETECTOR_BACKEND=auto|souffle|builtin`.\n\n[Read the full architecture →](docs/architecture.md)\n\n## Trust model\n\nSemia is a security tool for analyzing untrusted content. The trust\nboundary is explicit:\n\n| Surface | Treatment |\n| ------------------------- | -------------------------------------------------------------------------------- |\n| Audited skill | **untrusted data** — never executed, hooks/installers ignored |\n| Skill-declared URLs | **never fetched** during a scan |\n| Prompt-injection in skill | **recorded as evidence**, not followed as instructions |\n| Prepare / Detect / Report | deterministic, stdlib-friendly, runs locally |\n| Synthesize | the only LLM-mediated step; output must pass structural and evidence checks |\n| Network | LLM provider only |\n| Filesystem | reads the skill directory; writes only `.semia/runs//` |\n\nSee [docs/plugin-protocol.md#hostile-input-rules](docs/plugin-protocol.md)\nfor the full host-integration contract, and\n[SECURITY.md](SECURITY.md) for vulnerability reporting.\n\n## Install\n\nFrom source (current):\n\n```bash\ngit clone https://github.com/RiemaLabs/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\n```\n\nPython 3.11+ required. The project has **zero runtime dependencies** — both\nthe `responses` and `anthropic` providers talk to their APIs over raw HTTP\nusing the standard library.\n\n## Configuration\n\nSettings come from CLI flags, environment variables, or a repo-local\n`.env`. Copy [`.env.example`](.env.example) to `.env` and fill in your\ncredentials — `.env` is gitignored, and the pre-commit `gitleaks` hook\nruns locally against staged changes so secrets do not reach the history.\n\n### Providers\n\nSemia routes synthesis through one of four providers — two HTTP wire\nformats and two local CLI shell-outs. The default is `responses` with\nmodel `gpt-5.5`, authenticated via `OPENAI_API_KEY`.\n\n| Provider | Transport | Default model | Honors `--base-url` | Auth |\n| ------------ | ---------------------------------- | ------------------- | ------------------- | ----------------------------------------------------------------- |\n| `responses` | OpenAI Responses API (raw HTTP) | `gpt-5.5` | yes | `OPENAI_API_KEY`; `OPENAI_BASE_URL` (defaults to api.openai.com) |\n| `anthropic` | Anthropic Messages API (raw HTTP) | `claude-opus-4-7` | yes | `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`; `ANTHROPIC_BASE_URL` |\n| `codex` | shells out to `codex exec` | Codex CLI's own | no | inherits Codex CLI config |\n| `claude` | shells out to `claude --print` | `claude-opus-4-7` | no | inherits Claude Code env (`ANTHROPIC_*`) |\n\n`openai` is accepted as a synonym for `responses`. The **model** is free-form\n— any string the endpoint accepts works (`gpt-5.5`, `gpt-5.4`,\n`gpt-5.3-codex`, `deepseek-v4`, `claude-opus-4-7`, `claude-opus-4-6`, …).\n\nSwitch with flags:\n\n```bash\n# Default: OpenAI Responses against api.openai.com\nsemia scan ./some-skill --out .semia/runs/some-skill\n\n# Anthropic Messages against api.anthropic.com\nsemia scan ./some-skill --out .semia/runs/some-skill --provider anthropic\n\n# Point the responses format at a different endpoint (DeepSeek, OpenRouter, vLLM, …)\nsemia scan ./some-skill --out .semia/runs/some-skill \\\n --provider responses --model deepseek-v4 \\\n --base-url https://api.deepseek.com/v1\n\n# Use the locally-installed Claude Code CLI (model is the only knob)\nsemia scan ./some-skill --out .semia/runs/some-skill --provider claude --model claude-opus-4-7\n```\n\n### Most common environment variables\n\n| Variable | Purpose |\n| --------------------------- | -------------------------------------------------------------------- |\n| `SEMIA_LLM_PROVIDER` | `responses` (default) / `anthropic` / `codex` / `claude` |\n| `SEMIA_LLM_MODEL` | free-form model name passed to the provider |\n| `SEMIA_LLM_TIMEOUT` | request timeout in seconds |\n| `SEMIA_LLM_MAX_RETRIES` | retry budget for transient provider errors |\n| `OPENAI_BASE_URL` | base URL for the `responses` provider |\n| `ANTHROPIC_BASE_URL` | base URL for the `anthropic` provider |\n| `SEMIA_DETECTOR_BACKEND` | `auto` (default), `souffle`, `builtin` |\n| `SEMIA_SOUFFLE_BIN` | path to `souffle` if not on `PATH` |\n\nFor full synthesis tuning (`SEMIA_SYNTHESIS_*`), see the rest of\n[`.env.example`](.env.example) and\n[docs/plugin-protocol.md](docs/plugin-protocol.md).\n\n## Common workflows\n\n**Stop after deterministic preparation:**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --prepare-only\n```\n\n**Reuse facts from a prior run or an agent session:**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --facts synthesized_facts.dl\nsemia report .semia/runs/some-skill --format sarif\n```\n\n**CI smoke test (no LLM call):**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --offline-baseline\n```\n> `--offline-baseline` is a conservative non-LLM fallback for offline demos\n> and CI smoke tests. It is **not** a substitute for real synthesis.\n\n## Install as a host plugin\n\nThe Codex and Claude Code plugin bundles under `packages/semia-plugins//`\nship with a self-contained `bin/semia.pyz` zipapp, so they work out of the\nbox without a separate `pip install semia`. The OpenClaw skill\nrelies on the published `semia` CLI on `PATH` (ClawHub provisions it via\n`uv tool install`). Installing the Python package as well is recommended if\nyou want `semia` available as a normal shell command alongside the in-host\nworkflow.\n\n**Codex** — pick either path.\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add RiemaLabs/Semia\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `RiemaLabs/Semia`.\n5. Back in the plugin panel, install `semia` from the newly-added\n marketplace.\n\nHeadless setups can enable the plugin directly by adding the following to\n`~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia@semia\"]\nenabled = true\n```\n\n**Claude Code** — pick either path.\n\n*Shell (scripts and CI):*\n\n```bash\nclaude plugin marketplace add RiemaLabs/Semia\nclaude plugin install semia@semia\n```\n\n*Slash commands inside the Claude Code CLI:*\n\n```text\n/plugin marketplace add RiemaLabs/Semia\n/plugin install semia@semia\n```\n\nThe `name@marketplace` form on `install` is required — the second `semia`\nis the marketplace identifier from the project's `marketplace.json`.\nUse `--scope user|project|local` on the shell form to control where the\nplugin is recorded (default is `user`):\n\n```bash\nclaude plugin install semia@semia --scope project\n```\n\nSee [Discover and install plugins](https://code.claude.com/docs/en/discover-plugins)\nfor the full UX and [Plugins reference](https://code.claude.com/docs/en/plugins-reference#cli-commands-reference)\nfor the complete list of `claude plugin ...` subcommands.\n\n**OpenClaw** — install from ClawHub:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nClawHub will install the `semia` CLI on demand via `uv tool install\nsemia` (declared in the skill's `install` block). If you prefer to\npre-provision it yourself:\n\n```bash\nuv tool install semia # or: pip install semia\nopenclaw plugins install clawhub:semia\n```\n\n## Repository layout\n\n```text\npackages/\n semia-core/ # deterministic analysis library (prepare, check, detect, report)\n semia-cli/ # `semia` command surface\n semia-plugins/ # Codex / Claude Code / OpenClaw integrations\ndocs/\n architecture.md\n plugin-protocol.md\n release.md\n supply-chain.md\ntests/\n\n```\n\n## Development\n\n```bash\ngit clone https://github.com/RiemaLabs/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\npython -m pip install pre-commit\npre-commit install\npre-commit run --all-files # establish a clean baseline\n\nmake help # list targets\nmake check # compile + tests + manifest validation\nmake build # package metadata check\nmake release-check # full pre-release gate\n```\n\nThe root quality gates stay stdlib-friendly: `compileall`, `unittest`\ndiscovery, and stdlib-only validators. Pre-commit adds `ruff` lint/format\nand `gitleaks` secret scanning. CI mirrors `ruff` via\n[`lint.yml`](.github/workflows/lint.yml); `gitleaks` stays local-only\nbecause the upstream GitHub Action now requires a paid license for\norganization repositories.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow and the DCO\nsign-off requirement.\n\n## Project background\n\nThe technique behind Semia is described in the Semia paper\n([arXiv:2605.00314](https://arxiv.org/abs/2605.00314) ·\n[PDF](https://arxiv.org/pdf/2605.00314)). Semia is the\n**deterministic acceptance boundary** around behavior mapping: agents may\nextract facts, but only checked, evidence-grounded facts make it into a\nreport.\n\n## Security\n\nTo report a security vulnerability, see [SECURITY.md](SECURITY.md). Please\ndo **not** file public GitHub issues for security problems.\n\n## Contributing\n\nContributions are welcome — bug reports, documentation fixes, detector\nrules, and code. See [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow\nand the DCO sign-off requirement.\n\n## License & trademarks\n\nSemia is released under the [Apache License 2.0](LICENSE). You\nmay use, modify, and redistribute it freely, including for commercial\npurposes, subject to the terms of the license. See [NOTICE](NOTICE) for\nattribution.\n\nThe names **\"Semia\"**, **\"Semia\"**, **\"Semia\"**, and\n**\"RiemaLabs\"** are trademarks of RiemaLabs and are **not** licensed under\nApache-2.0. See [TRADEMARKS.md](TRADEMARKS.md) for the trademark policy.\n"}, "d44f400cf55839d2a7f1d1cf8bc6c0ca266d81aa": {"t": 1785762621.3784304, "n": 18303, "h": "e97f35587ab7e1fb", "c": "# Semia\n\n> **Security audit for AI agent skills.** Know what a skill *can* do\n> before you trust it.\n\n[![CI](https://github.com/RiemaLabs/Semia/actions/workflows/ci.yml/badge.svg)](https://github.com/RiemaLabs/Semia/actions/workflows/ci.yml)\n[![Lint](https://github.com/RiemaLabs/Semia/actions/workflows/lint.yml/badge.svg)](https://github.com/RiemaLabs/Semia/actions/workflows/lint.yml)\n[![codecov](https://codecov.io/gh/RiemaLabs/Semia/graph/badge.svg)](https://codecov.io/gh/RiemaLabs/Semia)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](pyproject.toml)\n\nAgent skills are markdown files with embedded shell commands, network calls,\nand tool invocations. They run with **your credentials, on your machine,\nwith your data**. Semia reads a skill as data — never executes it — and\nproduces an evidence-backed report of every capability it may exercise.\n\nIt is the difference between\n\n> *\"I trust this skill because the README looks fine.\"*\n\nand\n\n> *\"I trust this skill because Semia extracted 14 actions, 6 effects,\n> and 2 secret reads — and every one is grounded in a specific source line.\"*\n\n---\n\n## Quick example\n\nPick whichever fits how you already work.\n\n### As a CLI\n\n```bash\npip install semia\nsemia scan ./some-skill --out .semia/runs/some-skill\n```\n\n`scan` does prepare → synthesize (via your configured LLM provider) →\ndetect → report in one shot. You'll need an LLM provider configured first —\nsee [Set up an LLM provider](#set-up-an-llm-provider) below.\n\n### Inside Codex, Claude Code, or OpenClaw\n\nInstall the plugin once. Each host has its own flow.\n\n**Codex** — pick either path:\n\n*Shell (one-liner):*\n\n```bash\ncodex plugin marketplace add RiemaLabs/Semia\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `RiemaLabs/Semia`.\n\nEither path leaves the marketplace registered; install `semia`\nfrom the panel or by re-running the relevant install command.\n\n**Claude Code** — slash commands inside the Claude Code CLI (not a separate shell):\n\n```text\n/plugin marketplace add RiemaLabs/Semia\n/plugin install semia@semia\n```\n\n**OpenClaw** — one shell command registers the marketplace and installs:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nThen in any chat with the host agent just ask:\n\n> Run Semia audit on ./some-skill\n\nThe host agent itself acts as the synthesize step — **no API key needed**.\nThe bundled `semia.pyz` handles prepare / detect / report deterministically.\n\n### Outputs\n\nYou get `report.md` — findings ranked by severity, every one tied to a\nspecific source line. Need [SARIF 2.1.0](https://sarifweb.azurewebsites.net/)\nfor GitHub Code Scanning, or structured JSON for downstream tooling? One\nmore command:\n\n```bash\nsemia report .semia/runs/some-skill --format sarif # for GitHub Code Scanning\nsemia report .semia/runs/some-skill --format json # structured payload\n```\n\n## Set up an LLM provider\n\n`semia scan` needs an LLM for the **synthesize** step (the other three\nstages are deterministic, no key required). If you run Semia via a host\nplugin (Codex / Claude Code / OpenClaw) skip this — the host agent already\ndoes synthesize for you.\n\nFour providers are supported. Pick one and export its credentials:\n\n```bash\n# OpenAI Responses API — default; also works for DeepSeek / OpenRouter / vLLM\nexport OPENAI_API_KEY=sk-...\n# optional: export OPENAI_BASE_URL=https://api.deepseek.com/v1\n\n# Anthropic Messages API\nexport SEMIA_LLM_PROVIDER=anthropic\nexport ANTHROPIC_API_KEY=sk-ant-...\n# optional: export ANTHROPIC_BASE_URL=https://api.anthropic.com\n\n# Locally-installed Claude Code CLI (uses your Claude Code login)\nexport SEMIA_LLM_PROVIDER=claude\n\n# Locally-installed Codex CLI (uses your Codex login)\nexport SEMIA_LLM_PROVIDER=codex\n```\n\nOverride the model with `--model ` on any `semia scan` invocation, or\npersist it via `SEMIA_LLM_MODEL`. Models are free-form strings — anything\nthe endpoint accepts (`gpt-5.5`, `deepseek-v4`, `claude-opus-4-7`, …).\n\nSee [Configuration](#configuration) for the full provider matrix, base-URL\nsupport, timeout/retry knobs, and synthesis-loop tuning.\n\n## What you get\n\nA run writes everything under `.semia/runs//`. **Most users only\never open the reports**:\n\n| Report | When |\n| ------------------- | --------------------------------------------------------- |\n| `report.md` | always produced by `semia scan` — read this first |\n| `report.sarif.json` | on demand via `semia report --format sarif` — feed to GitHub Code Scanning |\n| `report.json` | on demand via `semia report --format json` — structured payload (check + evidence + detector) for programmatic consumers |\n\nBecause every finding traces back to a source line, the SARIF drops cleanly\ninto GitHub Code Scanning and reviewers see annotations directly on the\nskill PR.\n\n
\nOther artifacts in the run directory (internal — for tooling, debugging, or re-querying)\n\n| Artifact | Purpose |\n| ------------------------- | -------------------------------------------------- |\n| `synthesized_facts.dl` | the behavior map (Datalog facts) — re-queryable |\n| `detection_findings.dl` | findings derived by rule evaluation |\n| `prepared_skill.md` | normalized skill text with stable line anchors |\n| `prepare_units.json` | reference units the evidence text aligns against |\n| `synthesis_metadata.json` | provider, model, retries, score, stop reason |\n| `run_manifest.json` | end-to-end manifest of the run |\n\n
\n\n## Worked example\n\nPicture a skill that promises to \"summarize your inbox every day\". It\ninstalls a browser automation tool, opens your real Chrome (with every\nsaved login), reads Gmail, pipes the messages to an LLM that controls\nthe browser, and sets up a launchd job to repeat daily — forever. One\nemail from an attacker turns that skill into a remote control for every\nsite you are logged into.\n\n[See **EXAMPLE.md** for the full walkthrough →](EXAMPLE.md) — the skill\nsource, the attack, why it works, and the exact capabilities Semia\nsurfaces before you install.\n\n## How it works\n\n```text\n ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌────────┐\n │ Prepare │ ──▶ │ Synthesize │ ──▶ │ Detect │ ──▶ │ Report │\n │ (det.) │ │ (LLM) │ │ (det.) │ │ (det.) │\n └──────────┘ └────────────┘ └──────────┘ └────────┘\n```\n\n1. **Prepare** — read skill markdown + adjacent source, inline references,\n assign stable evidence handles. Pure stdlib. No LLM.\n2. **Synthesize** — an LLM (or the host agent's own session) extracts a\n *behavior map* as Datalog facts (`action`, `call`, `call_effect`, …)\n with `_evidence_text` sidecars citing the original source. The loop\n retries invalid candidates with checker feedback and keeps the best one.\n3. **Detect** — a Datalog evaluator runs the bundled SDL rules over the\n facts to flag risky combinations (e.g. *secret read → network write*).\n4. **Report** — render Markdown for humans and SARIF for CI.\n\nDetection runs through a built-in pure-Python Datalog evaluator by default,\nso **no external binary is required**. If [Soufflé](https://souffle-lang.github.io/)\nis on `PATH` (or `SEMIA_SOUFFLE_BIN`) it is preferred as a faster backend.\nOverride with `SEMIA_DETECTOR_BACKEND=auto|souffle|builtin`.\n\n[Read the full architecture →](docs/architecture.md)\n\n## Trust model\n\nSemia is a security tool for analyzing untrusted content. The trust\nboundary is explicit:\n\n| Surface | Treatment |\n| ------------------------- | -------------------------------------------------------------------------------- |\n| Audited skill | **untrusted data** — never executed, hooks/installers ignored |\n| Skill-declared URLs | **never fetched** during a scan |\n| Prompt-injection in skill | **recorded as evidence**, not followed as instructions |\n| Prepare / Detect / Report | deterministic, stdlib-friendly, runs locally |\n| Synthesize | the only LLM-mediated step; output must pass structural and evidence checks |\n| Network | LLM provider only |\n| Filesystem | reads the skill directory; writes only `.semia/runs//` |\n\nSee [docs/plugin-protocol.md#hostile-input-rules](docs/plugin-protocol.md)\nfor the full host-integration contract, and\n[SECURITY.md](SECURITY.md) for vulnerability reporting.\n\n## Install\n\nFrom source (current):\n\n```bash\ngit clone https://github.com/RiemaLabs/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\n```\n\nPython 3.11+ required. The project has **zero runtime dependencies** — both\nthe `responses` and `anthropic` providers talk to their APIs over raw HTTP\nusing the standard library.\n\n## Configuration\n\nSettings come from CLI flags, environment variables, or a repo-local\n`.env`. Copy [`.env.example`](.env.example) to `.env` and fill in your\ncredentials — `.env` is gitignored, and the pre-commit `gitleaks` hook\nruns locally against staged changes so secrets do not reach the history.\n\n### Providers\n\nSemia routes synthesis through one of four providers — two HTTP wire\nformats and two local CLI shell-outs. The default is `responses` with\nmodel `gpt-5.5`, authenticated via `OPENAI_API_KEY`.\n\n| Provider | Transport | Default model | Honors `--base-url` | Auth |\n| ------------ | ---------------------------------- | ------------------- | ------------------- | ----------------------------------------------------------------- |\n| `responses` | OpenAI Responses API (raw HTTP) | `gpt-5.5` | yes | `OPENAI_API_KEY`; `OPENAI_BASE_URL` (defaults to api.openai.com) |\n| `anthropic` | Anthropic Messages API (raw HTTP) | `claude-opus-4-7` | yes | `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`; `ANTHROPIC_BASE_URL` |\n| `codex` | shells out to `codex exec` | Codex CLI's own | no | inherits Codex CLI config |\n| `claude` | shells out to `claude --print` | `claude-opus-4-7` | no | inherits Claude Code env (`ANTHROPIC_*`) |\n\n`openai` is accepted as a synonym for `responses`. The **model** is free-form\n— any string the endpoint accepts works (`gpt-5.5`, `gpt-5.4`,\n`gpt-5.3-codex`, `deepseek-v4`, `claude-opus-4-7`, `claude-opus-4-6`, …).\n\nSwitch with flags:\n\n```bash\n# Default: OpenAI Responses against api.openai.com\nsemia scan ./some-skill --out .semia/runs/some-skill\n\n# Anthropic Messages against api.anthropic.com\nsemia scan ./some-skill --out .semia/runs/some-skill --provider anthropic\n\n# Point the responses format at a different endpoint (DeepSeek, OpenRouter, vLLM, …)\nsemia scan ./some-skill --out .semia/runs/some-skill \\\n --provider responses --model deepseek-v4 \\\n --base-url https://api.deepseek.com/v1\n\n# Use the locally-installed Claude Code CLI (model is the only knob)\nsemia scan ./some-skill --out .semia/runs/some-skill --provider claude --model claude-opus-4-7\n```\n\n### Most common environment variables\n\n| Variable | Purpose |\n| --------------------------- | -------------------------------------------------------------------- |\n| `SEMIA_LLM_PROVIDER` | `responses` (default) / `anthropic` / `codex` / `claude` |\n| `SEMIA_LLM_MODEL` | free-form model name passed to the provider |\n| `SEMIA_LLM_TIMEOUT` | request timeout in seconds |\n| `SEMIA_LLM_MAX_RETRIES` | retry budget for transient provider errors |\n| `OPENAI_BASE_URL` | base URL for the `responses` provider |\n| `ANTHROPIC_BASE_URL` | base URL for the `anthropic` provider |\n| `SEMIA_DETECTOR_BACKEND` | `auto` (default), `souffle`, `builtin` |\n| `SEMIA_SOUFFLE_BIN` | path to `souffle` if not on `PATH` |\n\nFor full synthesis tuning (`SEMIA_SYNTHESIS_*`), see the rest of\n[`.env.example`](.env.example) and\n[docs/plugin-protocol.md](docs/plugin-protocol.md).\n\n## Common workflows\n\n**Stop after deterministic preparation:**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --prepare-only\n```\n\n**Reuse facts from a prior run or an agent session:**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --facts synthesized_facts.dl\nsemia report .semia/runs/some-skill --format sarif\n```\n\n**CI smoke test (no LLM call):**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --offline-baseline\n```\n> `--offline-baseline` is a conservative non-LLM fallback for offline demos\n> and CI smoke tests. It is **not** a substitute for real synthesis.\n\n## Install as a host plugin\n\nThe Codex and Claude Code plugin bundles under `packages/semia-plugins//`\nship with a self-contained `bin/semia.pyz` zipapp, so they work out of the\nbox without a separate `pip install semia`. The OpenClaw skill\nrelies on the published `semia` CLI on `PATH` (ClawHub provisions it via\n`uv tool install`). Installing the Python package as well is recommended if\nyou want `semia` available as a normal shell command alongside the in-host\nworkflow.\n\n**Codex** — pick either path.\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add RiemaLabs/Semia\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `RiemaLabs/Semia`.\n5. Back in the plugin panel, install `semia` from the newly-added\n marketplace.\n\nHeadless setups can enable the plugin directly by adding the following to\n`~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia@semia\"]\nenabled = true\n```\n\n**Claude Code** — slash commands run inside the Claude Code CLI (not a separate shell):\n\n```text\n/plugin marketplace add RiemaLabs/Semia\n/plugin install semia@semia\n```\n\nThe `name@marketplace` form on `/plugin install` is required — the second\n`semia` is the marketplace identifier from the project's\n`marketplace.json`. The marketplace registration step (`/plugin marketplace\nadd ...`) is only available as a slash command inside the CLI; there is no\n`claude plugin marketplace add` shell equivalent in the official\n[plugins reference](https://code.claude.com/docs/en/plugins-reference#cli-commands-reference).\nOnce installed, the management subcommands (`install`, `uninstall`,\n`enable`, `disable`, `list`, …) are also exposed as shell commands —\ne.g. `claude plugin install semia@semia --scope project`.\nSee [Discover and install plugins](https://code.claude.com/docs/en/discover-plugins)\nfor the full UX.\n\n**OpenClaw** — install from ClawHub:\n\n```bash\nopenclaw plugins install clawhub:semia\n```\n\nClawHub will install the `semia` CLI on demand via `uv tool install\nsemia` (declared in the skill's `install` block). If you prefer to\npre-provision it yourself:\n\n```bash\nuv tool install semia # or: pip install semia\nopenclaw plugins install clawhub:semia\n```\n\n## Repository layout\n\n```text\npackages/\n semia-core/ # deterministic analysis library (prepare, check, detect, report)\n semia-cli/ # `semia` command surface\n semia-plugins/ # Codex / Claude Code / OpenClaw integrations\ndocs/\n architecture.md\n plugin-protocol.md\n release.md\n supply-chain.md\ntests/\n\n```\n\n## Development\n\n```bash\ngit clone https://github.com/RiemaLabs/Semia\ncd semia\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\npython -m pip install pre-commit\npre-commit install\npre-commit run --all-files # establish a clean baseline\n\nmake help # list targets\nmake check # compile + tests + manifest validation\nmake build # package metadata check\nmake release-check # full pre-release gate\n```\n\nThe root quality gates stay stdlib-friendly: `compileall`, `unittest`\ndiscovery, and stdlib-only validators. Pre-commit adds `ruff` lint/format\nand `gitleaks` secret scanning. CI mirrors `ruff` via\n[`lint.yml`](.github/workflows/lint.yml); `gitleaks` stays local-only\nbecause the upstream GitHub Action now requires a paid license for\norganization repositories.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow and the DCO\nsign-off requirement.\n\n## Project background\n\nThe technique behind Semia is described in the Semia paper\n([arXiv:2605.00314](https://arxiv.org/abs/2605.00314) ·\n[PDF](https://arxiv.org/pdf/2605.00314)). Semia is the\n**deterministic acceptance boundary** around behavior mapping: agents may\nextract facts, but only checked, evidence-grounded facts make it into a\nreport.\n\n## Security\n\nTo report a security vulnerability, see [SECURITY.md](SECURITY.md). Please\ndo **not** file public GitHub issues for security problems.\n\n## Contributing\n\nContributions are welcome — bug reports, documentation fixes, detector\nrules, and code. See [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow\nand the DCO sign-off requirement.\n\n## License & trademarks\n\nSemia is released under the [Apache License 2.0](LICENSE). You\nmay use, modify, and redistribute it freely, including for commercial\npurposes, subject to the terms of the license. See [NOTICE](NOTICE) for\nattribution.\n\nThe names **\"Semia\"**, **\"Semia\"**, **\"Semia\"**, and\n**\"RiemaLabs\"** are trademarks of RiemaLabs and are **not** licensed under\nApache-2.0. See [TRADEMARKS.md](TRADEMARKS.md) for the trademark policy.\n"}, "711cb135d8c62531036efe730d11cec0f52b3dd0": {"t": 1785762622.743444, "n": 18703, "h": "9d046220bcccaf30", "c": "# Semia\n\n> **Security audit for AI agent skills.** Know what a skill *can* do\n> before you trust it.\n\n[![CI](https://github.com/RiemaLabs/semia-skillscan/actions/workflows/ci.yml/badge.svg)](https://github.com/RiemaLabs/semia-skillscan/actions/workflows/ci.yml)\n[![Lint](https://github.com/RiemaLabs/semia-skillscan/actions/workflows/lint.yml/badge.svg)](https://github.com/RiemaLabs/semia-skillscan/actions/workflows/lint.yml)\n[![codecov](https://codecov.io/gh/RiemaLabs/semia-skillscan/graph/badge.svg)](https://codecov.io/gh/RiemaLabs/semia-skillscan)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](pyproject.toml)\n\nAgent skills are markdown files with embedded shell commands, network calls,\nand tool invocations. They run with **your credentials, on your machine,\nwith your data**. Semia reads a skill as data — never executes it — and\nproduces an evidence-backed report of every capability it may exercise.\n\nIt is the difference between\n\n> *\"I trust this skill because the README looks fine.\"*\n\nand\n\n> *\"I trust this skill because Semia extracted 14 actions, 6 effects,\n> and 2 secret reads — and every one is grounded in a specific source line.\"*\n\n---\n\n## Quick example\n\nPick whichever fits how you already work.\n\n### As a CLI\n\n```bash\npip install semia-skillscan\nsemia scan ./some-skill --out .semia/runs/some-skill\n```\n\n`scan` does prepare → synthesize (via your configured LLM provider) →\ndetect → report in one shot. You'll need an LLM provider configured first —\nsee [Set up an LLM provider](#set-up-an-llm-provider) below.\n\n### Inside Codex, Claude Code, or OpenClaw\n\nInstall the plugin once. Each host has its own flow.\n\n**Codex** — pick either path:\n\n*Shell (one-liner):*\n\n```bash\ncodex plugin marketplace add RiemaLabs/semia-skillscan\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `RiemaLabs/semia-skillscan`.\n\nEither path leaves the marketplace registered; install `semia-skillscan`\nfrom the panel or by re-running the relevant install command.\n\n**Claude Code** — slash commands inside the Claude Code CLI (not a separate shell):\n\n```text\n/plugin marketplace add RiemaLabs/semia-skillscan\n/plugin install semia-skillscan@semia-skillscan\n```\n\n**OpenClaw** — one shell command registers the marketplace and installs:\n\n```bash\nopenclaw plugins install clawhub:semia-skillscan\n```\n\nThen in any chat with the host agent just ask:\n\n> Run Semia audit on ./some-skill\n\nThe host agent itself acts as the synthesize step — **no API key needed**.\nThe bundled `semia.pyz` handles prepare / detect / report deterministically.\n\n### Outputs\n\nYou get `report.md` — findings ranked by severity, every one tied to a\nspecific source line. Need [SARIF 2.1.0](https://sarifweb.azurewebsites.net/)\nfor GitHub Code Scanning, or structured JSON for downstream tooling? One\nmore command:\n\n```bash\nsemia report .semia/runs/some-skill --format sarif # for GitHub Code Scanning\nsemia report .semia/runs/some-skill --format json # structured payload\n```\n\n## Set up an LLM provider\n\n`semia scan` needs an LLM for the **synthesize** step (the other three\nstages are deterministic, no key required). If you run Semia via a host\nplugin (Codex / Claude Code / OpenClaw) skip this — the host agent already\ndoes synthesize for you.\n\nFour providers are supported. Pick one and export its credentials:\n\n```bash\n# OpenAI Responses API — default; also works for DeepSeek / OpenRouter / vLLM\nexport OPENAI_API_KEY=sk-...\n# optional: export OPENAI_BASE_URL=https://api.deepseek.com/v1\n\n# Anthropic Messages API\nexport SEMIA_LLM_PROVIDER=anthropic\nexport ANTHROPIC_API_KEY=sk-ant-...\n# optional: export ANTHROPIC_BASE_URL=https://api.anthropic.com\n\n# Locally-installed Claude Code CLI (uses your Claude Code login)\nexport SEMIA_LLM_PROVIDER=claude\n\n# Locally-installed Codex CLI (uses your Codex login)\nexport SEMIA_LLM_PROVIDER=codex\n```\n\nOverride the model with `--model ` on any `semia scan` invocation, or\npersist it via `SEMIA_LLM_MODEL`. Models are free-form strings — anything\nthe endpoint accepts (`gpt-5.5`, `deepseek-v4`, `claude-opus-4-7`, …).\n\nSee [Configuration](#configuration) for the full provider matrix, base-URL\nsupport, timeout/retry knobs, and synthesis-loop tuning.\n\n## What you get\n\nA run writes everything under `.semia/runs//`. **Most users only\never open the reports**:\n\n| Report | When |\n| ------------------- | --------------------------------------------------------- |\n| `report.md` | always produced by `semia scan` — read this first |\n| `report.sarif.json` | on demand via `semia report --format sarif` — feed to GitHub Code Scanning |\n| `report.json` | on demand via `semia report --format json` — structured payload (check + evidence + detector) for programmatic consumers |\n\nBecause every finding traces back to a source line, the SARIF drops cleanly\ninto GitHub Code Scanning and reviewers see annotations directly on the\nskill PR.\n\n
\nOther artifacts in the run directory (internal — for tooling, debugging, or re-querying)\n\n| Artifact | Purpose |\n| ------------------------- | -------------------------------------------------- |\n| `synthesized_facts.dl` | the behavior map (Datalog facts) — re-queryable |\n| `detection_findings.dl` | findings derived by rule evaluation |\n| `prepared_skill.md` | normalized skill text with stable line anchors |\n| `prepare_units.json` | reference units the evidence text aligns against |\n| `synthesis_metadata.json` | provider, model, retries, score, stop reason |\n| `run_manifest.json` | end-to-end manifest of the run |\n\n
\n\n## Worked example\n\nPicture a skill that promises to \"summarize your inbox every day\". It\ninstalls a browser automation tool, opens your real Chrome (with every\nsaved login), reads Gmail, pipes the messages to an LLM that controls\nthe browser, and sets up a launchd job to repeat daily — forever. One\nemail from an attacker turns that skill into a remote control for every\nsite you are logged into.\n\n[See **EXAMPLE.md** for the full walkthrough →](EXAMPLE.md) — the skill\nsource, the attack, why it works, and the exact capabilities Skillscan\nsurfaces before you install.\n\n## How it works\n\n```text\n ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌────────┐\n │ Prepare │ ──▶ │ Synthesize │ ──▶ │ Detect │ ──▶ │ Report │\n │ (det.) │ │ (LLM) │ │ (det.) │ │ (det.) │\n └──────────┘ └────────────┘ └──────────┘ └────────┘\n```\n\n1. **Prepare** — read skill markdown + adjacent source, inline references,\n assign stable evidence handles. Pure stdlib. No LLM.\n2. **Synthesize** — an LLM (or the host agent's own session) extracts a\n *behavior map* as Datalog facts (`action`, `call`, `call_effect`, …)\n with `_evidence_text` sidecars citing the original source. The loop\n retries invalid candidates with checker feedback and keeps the best one.\n3. **Detect** — a Datalog evaluator runs the bundled SDL rules over the\n facts to flag risky combinations (e.g. *secret read → network write*).\n4. **Report** — render Markdown for humans and SARIF for CI.\n\nDetection runs through a built-in pure-Python Datalog evaluator by default,\nso **no external binary is required**. If [Soufflé](https://souffle-lang.github.io/)\nis on `PATH` (or `SEMIA_SOUFFLE_BIN`) it is preferred as a faster backend.\nOverride with `SEMIA_DETECTOR_BACKEND=auto|souffle|builtin`.\n\n[Read the full architecture →](docs/architecture.md)\n\n## Trust model\n\nSkillscan is a security tool for analyzing untrusted content. The trust\nboundary is explicit:\n\n| Surface | Treatment |\n| ------------------------- | -------------------------------------------------------------------------------- |\n| Audited skill | **untrusted data** — never executed, hooks/installers ignored |\n| Skill-declared URLs | **never fetched** during a scan |\n| Prompt-injection in skill | **recorded as evidence**, not followed as instructions |\n| Prepare / Detect / Report | deterministic, stdlib-friendly, runs locally |\n| Synthesize | the only LLM-mediated step; output must pass structural and evidence checks |\n| Network | LLM provider only |\n| Filesystem | reads the skill directory; writes only `.semia/runs//` |\n\nSee [docs/plugin-protocol.md#hostile-input-rules](docs/plugin-protocol.md)\nfor the full host-integration contract, and\n[SECURITY.md](SECURITY.md) for vulnerability reporting.\n\n## Install\n\nFrom source (current):\n\n```bash\ngit clone https://github.com/RiemaLabs/semia-skillscan\ncd semia-skillscan\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\n```\n\nPython 3.11+ required. The project has **zero runtime dependencies** — both\nthe `responses` and `anthropic` providers talk to their APIs over raw HTTP\nusing the standard library.\n\n## Configuration\n\nSettings come from CLI flags, environment variables, or a repo-local\n`.env`. Copy [`.env.example`](.env.example) to `.env` and fill in your\ncredentials — `.env` is gitignored, and the pre-commit `gitleaks` hook\nruns locally against staged changes so secrets do not reach the history.\n\n### Providers\n\nSkillscan routes synthesis through one of four providers — two HTTP wire\nformats and two local CLI shell-outs. The default is `responses` with\nmodel `gpt-5.5`, authenticated via `OPENAI_API_KEY`.\n\n| Provider | Transport | Default model | Honors `--base-url` | Auth |\n| ------------ | ---------------------------------- | ------------------- | ------------------- | ----------------------------------------------------------------- |\n| `responses` | OpenAI Responses API (raw HTTP) | `gpt-5.5` | yes | `OPENAI_API_KEY`; `OPENAI_BASE_URL` (defaults to api.openai.com) |\n| `anthropic` | Anthropic Messages API (raw HTTP) | `claude-opus-4-7` | yes | `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`; `ANTHROPIC_BASE_URL` |\n| `codex` | shells out to `codex exec` | Codex CLI's own | no | inherits Codex CLI config |\n| `claude` | shells out to `claude --print` | `claude-opus-4-7` | no | inherits Claude Code env (`ANTHROPIC_*`) |\n\n`openai` is accepted as a synonym for `responses`. The **model** is free-form\n— any string the endpoint accepts works (`gpt-5.5`, `gpt-5.4`,\n`gpt-5.3-codex`, `deepseek-v4`, `claude-opus-4-7`, `claude-opus-4-6`, …).\n\nSwitch with flags:\n\n```bash\n# Default: OpenAI Responses against api.openai.com\nsemia scan ./some-skill --out .semia/runs/some-skill\n\n# Anthropic Messages against api.anthropic.com\nsemia scan ./some-skill --out .semia/runs/some-skill --provider anthropic\n\n# Point the responses format at a different endpoint (DeepSeek, OpenRouter, vLLM, …)\nsemia scan ./some-skill --out .semia/runs/some-skill \\\n --provider responses --model deepseek-v4 \\\n --base-url https://api.deepseek.com/v1\n\n# Use the locally-installed Claude Code CLI (model is the only knob)\nsemia scan ./some-skill --out .semia/runs/some-skill --provider claude --model claude-opus-4-7\n```\n\n### Most common environment variables\n\n| Variable | Purpose |\n| --------------------------- | -------------------------------------------------------------------- |\n| `SEMIA_LLM_PROVIDER` | `responses` (default) / `anthropic` / `codex` / `claude` |\n| `SEMIA_LLM_MODEL` | free-form model name passed to the provider |\n| `SEMIA_LLM_TIMEOUT` | request timeout in seconds |\n| `SEMIA_LLM_MAX_RETRIES` | retry budget for transient provider errors |\n| `OPENAI_BASE_URL` | base URL for the `responses` provider |\n| `ANTHROPIC_BASE_URL` | base URL for the `anthropic` provider |\n| `SEMIA_DETECTOR_BACKEND` | `auto` (default), `souffle`, `builtin` |\n| `SEMIA_SOUFFLE_BIN` | path to `souffle` if not on `PATH` |\n\nFor full synthesis tuning (`SEMIA_SYNTHESIS_*`), see the rest of\n[`.env.example`](.env.example) and\n[docs/plugin-protocol.md](docs/plugin-protocol.md).\n\n## Common workflows\n\n**Stop after deterministic preparation:**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --prepare-only\n```\n\n**Reuse facts from a prior run or an agent session:**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --facts synthesized_facts.dl\nsemia report .semia/runs/some-skill --format sarif\n```\n\n**CI smoke test (no LLM call):**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --offline-baseline\n```\n> `--offline-baseline` is a conservative non-LLM fallback for offline demos\n> and CI smoke tests. It is **not** a substitute for real synthesis.\n\n## Install as a host plugin\n\nThe Codex and Claude Code plugin bundles under `packages/semia-plugins//`\nship with a self-contained `bin/semia.pyz` zipapp, so they work out of the\nbox without a separate `pip install semia-skillscan`. The OpenClaw skill\nrelies on the published `semia` CLI on `PATH` (ClawHub provisions it via\n`uv tool install`). Installing the Python package as well is recommended if\nyou want `semia` available as a normal shell command alongside the in-host\nworkflow.\n\n**Codex** — pick either path.\n\n*Shell (scripts and CI):*\n\n```bash\ncodex plugin marketplace add RiemaLabs/semia-skillscan\n```\n\n*Interactive plugin manager inside the Codex CLI:*\n\n1. Launch `codex`.\n2. Inside Codex, input `/plugins` (plural — opens the plugin panel).\n3. Press **←** (Left) to enter **Add marketplace**.\n4. Enter `RiemaLabs/semia-skillscan`.\n5. Back in the plugin panel, install `semia-skillscan` from the newly-added\n marketplace.\n\nHeadless setups can enable the plugin directly by adding the following to\n`~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia-skillscan@semia-skillscan\"]\nenabled = true\n```\n\n**Claude Code** — slash commands run inside the Claude Code CLI (not a separate shell):\n\n```text\n/plugin marketplace add RiemaLabs/semia-skillscan\n/plugin install semia-skillscan@semia-skillscan\n```\n\nThe `name@marketplace` form on `/plugin install` is required — the second\n`semia-skillscan` is the marketplace identifier from the project's\n`marketplace.json`. The marketplace registration step (`/plugin marketplace\nadd ...`) is only available as a slash command inside the CLI; there is no\n`claude plugin marketplace add` shell equivalent in the official\n[plugins reference](https://code.claude.com/docs/en/plugins-reference#cli-commands-reference).\nOnce installed, the management subcommands (`install`, `uninstall`,\n`enable`, `disable`, `list`, …) are also exposed as shell commands —\ne.g. `claude plugin install semia-skillscan@semia-skillscan --scope project`.\nSee [Discover and install plugins](https://code.claude.com/docs/en/discover-plugins)\nfor the full UX.\n\n**OpenClaw** — install from ClawHub:\n\n```bash\nopenclaw plugins install clawhub:semia-skillscan\n```\n\nClawHub will install the `semia` CLI on demand via `uv tool install\nsemia-skillscan` (declared in the skill's `install` block). If you prefer to\npre-provision it yourself:\n\n```bash\nuv tool install semia-skillscan # or: pip install semia-skillscan\nopenclaw plugins install clawhub:semia-skillscan\n```\n\n## Repository layout\n\n```text\npackages/\n semia-core/ # deterministic analysis library (prepare, check, detect, report)\n semia-cli/ # `semia` command surface\n semia-plugins/ # Codex / Claude Code / OpenClaw integrations\ndocs/\n architecture.md\n plugin-protocol.md\n release.md\n supply-chain.md\ntests/\n\n```\n\n## Development\n\n```bash\ngit clone https://github.com/RiemaLabs/semia-skillscan\ncd semia-skillscan\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\npython -m pip install pre-commit\npre-commit install\npre-commit run --all-files # establish a clean baseline\n\nmake help # list targets\nmake check # compile + tests + manifest validation\nmake build # package metadata check\nmake release-check # full pre-release gate\n```\n\nThe root quality gates stay stdlib-friendly: `compileall`, `unittest`\ndiscovery, and stdlib-only validators. Pre-commit adds `ruff` lint/format\nand `gitleaks` secret scanning. CI mirrors `ruff` via\n[`lint.yml`](.github/workflows/lint.yml); `gitleaks` stays local-only\nbecause the upstream GitHub Action now requires a paid license for\norganization repositories.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow and the DCO\nsign-off requirement.\n\n## Project background\n\nThe technique behind Semia Skillscan is described in the Semia paper\n([arXiv:2605.00314](https://arxiv.org/abs/2605.00314) ·\n[PDF](https://arxiv.org/pdf/2605.00314)). Skillscan is the\n**deterministic acceptance boundary** around behavior mapping: agents may\nextract facts, but only checked, evidence-grounded facts make it into a\nreport.\n\n## Security\n\nTo report a security vulnerability, see [SECURITY.md](SECURITY.md). Please\ndo **not** file public GitHub issues for security problems.\n\n## Contributing\n\nContributions are welcome — bug reports, documentation fixes, detector\nrules, and code. See [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow\nand the DCO sign-off requirement.\n\n## License & trademarks\n\nSemia Skillscan is released under the [Apache License 2.0](LICENSE). You\nmay use, modify, and redistribute it freely, including for commercial\npurposes, subject to the terms of the license. See [NOTICE](NOTICE) for\nattribution.\n\nThe names **\"Semia\"**, **\"Skillscan\"**, **\"Semia Skillscan\"**, and\n**\"RiemaLabs\"** are trademarks of RiemaLabs and are **not** licensed under\nApache-2.0. See [TRADEMARKS.md](TRADEMARKS.md) for the trademark policy.\n"}, "a616f9536070b5393f9449073ea9bdfaba0aa86b": {"t": 1785762655.0793147, "n": 18090, "h": "9af4078addf3ffd2", "c": "# Semia Skillscan\n\n> **Static security audit for AI agent skills.** Know what a skill *can* do\n> before you trust it.\n\n[![CI](https://github.com/RiemaLabs/semia-skillscan/actions/workflows/ci.yml/badge.svg)](https://github.com/RiemaLabs/semia-skillscan/actions/workflows/ci.yml)\n[![Lint](https://github.com/RiemaLabs/semia-skillscan/actions/workflows/lint.yml/badge.svg)](https://github.com/RiemaLabs/semia-skillscan/actions/workflows/lint.yml)\n[![codecov](https://codecov.io/gh/RiemaLabs/semia-skillscan/graph/badge.svg)](https://codecov.io/gh/RiemaLabs/semia-skillscan)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](pyproject.toml)\n\nAgent skills are markdown files with embedded shell commands, network calls,\nand tool invocations. They run with **your credentials, on your machine,\nwith your data**. Skillscan reads a skill as data — never executes it — and\nproduces an evidence-backed report of every capability it may exercise.\n\nIt is the difference between\n\n> *\"I trust this skill because the README looks fine.\"*\n\nand\n\n> *\"I trust this skill because Skillscan extracted 14 actions, 6 effects,\n> and 2 secret reads — and every one is grounded in a specific source line.\"*\n\n---\n\n## Quick example\n\nPick whichever fits how you already work.\n\n### As a CLI\n\n```bash\npip install semia-skillscan\nsemia scan ./some-skill --out .semia/runs/some-skill\n```\n\n`scan` does prepare → synthesize (via your configured LLM provider) →\ndetect → report in one shot. You'll need an LLM provider configured first —\nsee [Set up an LLM provider](#set-up-an-llm-provider) below.\n\n### Inside Codex, Claude Code, or OpenClaw\n\nInstall the plugin once:\n\n```bash\n# Codex (slash command, run inside the Codex CLI — not a separate shell)\n/plugin marketplace add RiemaLabs/semia-skillscan\n/plugin install semia-skillscan@semia-skillscan\n\n# Claude Code (slash command, run inside the Claude Code CLI — not a separate shell)\n/plugin marketplace add RiemaLabs/semia-skillscan\n/plugin install semia-skillscan@semia-skillscan\n\n# OpenClaw (shell command — one step registers and installs)\nopenclaw plugins install clawhub:semia-skillscan\n```\n\nThen in any chat with the host agent just ask:\n\n> Run Semia audit on ./some-skill\n\nThe host agent itself acts as the synthesize step — **no API key needed**.\nThe bundled `semia.pyz` handles prepare / detect / report deterministically.\n\n### Outputs\n\nYou get `report.md` — findings ranked by severity, every one tied to a\nspecific source line. Need [SARIF 2.1.0](https://sarifweb.azurewebsites.net/)\nfor GitHub Code Scanning, or structured JSON for downstream tooling? One\nmore command:\n\n```bash\nsemia report .semia/runs/some-skill --format sarif # for GitHub Code Scanning\nsemia report .semia/runs/some-skill --format json # structured payload\n```\n\n## Set up an LLM provider\n\n`semia scan` needs an LLM for the **synthesize** step (the other three\nstages are deterministic, no key required). If you run Semia via a host\nplugin (Codex / Claude Code / OpenClaw) skip this — the host agent already\ndoes synthesize for you.\n\nFour providers are supported. Pick one and export its credentials:\n\n```bash\n# OpenAI Responses API — default; also works for DeepSeek / OpenRouter / vLLM\nexport OPENAI_API_KEY=sk-...\n# optional: export OPENAI_BASE_URL=https://api.deepseek.com/v1\n\n# Anthropic Messages API\nexport SEMIA_LLM_PROVIDER=anthropic\nexport ANTHROPIC_API_KEY=sk-ant-...\n# optional: export ANTHROPIC_BASE_URL=https://api.anthropic.com\n\n# Locally-installed Claude Code CLI (uses your Claude Code login)\nexport SEMIA_LLM_PROVIDER=claude\n\n# Locally-installed Codex CLI (uses your Codex login)\nexport SEMIA_LLM_PROVIDER=codex\n```\n\nOverride the model with `--model ` on any `semia scan` invocation, or\npersist it via `SEMIA_LLM_MODEL`. Models are free-form strings — anything\nthe endpoint accepts (`gpt-5.5`, `deepseek-v4`, `claude-opus-4-7`, …).\n\nSee [Configuration](#configuration) for the full provider matrix, base-URL\nsupport, timeout/retry knobs, and synthesis-loop tuning.\n\n## What you get\n\nA run writes everything under `.semia/runs//`. **Most users only\never open the reports**:\n\n| Report | When |\n| ------------------- | --------------------------------------------------------- |\n| `report.md` | always produced by `semia scan` — read this first |\n| `report.sarif.json` | on demand via `semia report --format sarif` — feed to GitHub Code Scanning |\n| `report.json` | on demand via `semia report --format json` — structured payload (check + evidence + detector) for programmatic consumers |\n\nBecause every finding traces back to a source line, the SARIF drops cleanly\ninto GitHub Code Scanning and reviewers see annotations directly on the\nskill PR.\n\n
\nOther artifacts in the run directory (internal — for tooling, debugging, or re-querying)\n\n| Artifact | Purpose |\n| ------------------------- | -------------------------------------------------- |\n| `synthesized_facts.dl` | the behavior map (Datalog facts) — re-queryable |\n| `detection_findings.dl` | findings derived by rule evaluation |\n| `prepared_skill.md` | normalized skill text with stable line anchors |\n| `prepare_units.json` | reference units the evidence text aligns against |\n| `synthesis_metadata.json` | provider, model, retries, score, stop reason |\n| `run_manifest.json` | end-to-end manifest of the run |\n\n
\n\n## Worked example\n\nPicture a skill that promises to \"summarize your inbox every day\". It\ninstalls a browser automation tool, opens your real Chrome (with every\nsaved login), reads Gmail, pipes the messages to an LLM that controls\nthe browser, and sets up a launchd job to repeat daily — forever. One\nemail from an attacker turns that skill into a remote control for every\nsite you are logged into.\n\n[See **EXAMPLE.md** for the full walkthrough →](EXAMPLE.md) — the skill\nsource, the attack, why it works, and the exact capabilities Skillscan\nsurfaces before you install.\n\n## How it works\n\n```text\n ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌────────┐\n │ Prepare │ ──▶ │ Synthesize │ ──▶ │ Detect │ ──▶ │ Report │\n │ (det.) │ │ (LLM) │ │ (det.) │ │ (det.) │\n └──────────┘ └────────────┘ └──────────┘ └────────┘\n```\n\n1. **Prepare** — read skill markdown + adjacent source, inline references,\n assign stable evidence handles. Pure stdlib. No LLM.\n2. **Synthesize** — an LLM (or the host agent's own session) extracts a\n *behavior map* as Datalog facts (`action`, `call`, `call_effect`, …)\n with `_evidence_text` sidecars citing the original source. The loop\n retries invalid candidates with checker feedback and keeps the best one.\n3. **Detect** — a Datalog evaluator runs the bundled SDL rules over the\n facts to flag risky combinations (e.g. *secret read → network write*).\n4. **Report** — render Markdown for humans and SARIF for CI.\n\nDetection runs through a built-in pure-Python Datalog evaluator by default,\nso **no external binary is required**. If [Soufflé](https://souffle-lang.github.io/)\nis on `PATH` (or `SEMIA_SOUFFLE_BIN`) it is preferred as a faster backend.\nOverride with `SEMIA_DETECTOR_BACKEND=auto|souffle|builtin`.\n\n[Read the full architecture →](docs/architecture.md)\n\n## Trust model\n\nSkillscan is a security tool for analyzing untrusted content. The trust\nboundary is explicit:\n\n| Surface | Treatment |\n| ------------------------- | -------------------------------------------------------------------------------- |\n| Audited skill | **untrusted data** — never executed, hooks/installers ignored |\n| Skill-declared URLs | **never fetched** during a scan |\n| Prompt-injection in skill | **recorded as evidence**, not followed as instructions |\n| Prepare / Detect / Report | deterministic, stdlib-friendly, runs locally |\n| Synthesize | the only LLM-mediated step; output must pass structural and evidence checks |\n| Network | LLM provider only |\n| Filesystem | reads the skill directory; writes only `.semia/runs//` |\n\nSee [docs/plugin-protocol.md#hostile-input-rules](docs/plugin-protocol.md)\nfor the full host-integration contract, and\n[SECURITY.md](SECURITY.md) for vulnerability reporting.\n\n## Install\n\nFrom source (current):\n\n```bash\ngit clone https://github.com/RiemaLabs/semia-skillscan\ncd semia-skillscan\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\n```\n\nPython 3.11+ required. The project has **zero runtime dependencies** — both\nthe `responses` and `anthropic` providers talk to their APIs over raw HTTP\nusing the standard library.\n\n## Configuration\n\nSettings come from CLI flags, environment variables, or a repo-local\n`.env`. Copy [`.env.example`](.env.example) to `.env` and fill in your\ncredentials — `.env` is gitignored, and the pre-commit `gitleaks` hook\nruns locally against staged changes so secrets do not reach the history.\n\n### Providers\n\nSkillscan routes synthesis through one of four providers — two HTTP wire\nformats and two local CLI shell-outs. The default is `responses` with\nmodel `gpt-5.5`, authenticated via `OPENAI_API_KEY`.\n\n| Provider | Transport | Default model | Honors `--base-url` | Auth |\n| ------------ | ---------------------------------- | ------------------- | ------------------- | ----------------------------------------------------------------- |\n| `responses` | OpenAI Responses API (raw HTTP) | `gpt-5.5` | yes | `OPENAI_API_KEY`; `OPENAI_BASE_URL` (defaults to api.openai.com) |\n| `anthropic` | Anthropic Messages API (raw HTTP) | `claude-opus-4-7` | yes | `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`; `ANTHROPIC_BASE_URL` |\n| `codex` | shells out to `codex exec` | Codex CLI's own | no | inherits Codex CLI config |\n| `claude` | shells out to `claude --print` | `claude-opus-4-7` | no | inherits Claude Code env (`ANTHROPIC_*`) |\n\n`openai` is accepted as a synonym for `responses`. The **model** is free-form\n— any string the endpoint accepts works (`gpt-5.5`, `gpt-5.4`,\n`gpt-5.3-codex`, `deepseek-v4`, `claude-opus-4-7`, `claude-opus-4-6`, …).\n\nSwitch with flags:\n\n```bash\n# Default: OpenAI Responses against api.openai.com\nsemia scan ./some-skill --out .semia/runs/some-skill\n\n# Anthropic Messages against api.anthropic.com\nsemia scan ./some-skill --out .semia/runs/some-skill --provider anthropic\n\n# Point the responses format at a different endpoint (DeepSeek, OpenRouter, vLLM, …)\nsemia scan ./some-skill --out .semia/runs/some-skill \\\n --provider responses --model deepseek-v4 \\\n --base-url https://api.deepseek.com/v1\n\n# Use the locally-installed Claude Code CLI (model is the only knob)\nsemia scan ./some-skill --out .semia/runs/some-skill --provider claude --model claude-opus-4-7\n```\n\n### Most common environment variables\n\n| Variable | Purpose |\n| --------------------------- | -------------------------------------------------------------------- |\n| `SEMIA_LLM_PROVIDER` | `responses` (default) / `anthropic` / `codex` / `claude` |\n| `SEMIA_LLM_MODEL` | free-form model name passed to the provider |\n| `SEMIA_LLM_TIMEOUT` | request timeout in seconds |\n| `SEMIA_LLM_MAX_RETRIES` | retry budget for transient provider errors |\n| `OPENAI_BASE_URL` | base URL for the `responses` provider |\n| `ANTHROPIC_BASE_URL` | base URL for the `anthropic` provider |\n| `SEMIA_DETECTOR_BACKEND` | `auto` (default), `souffle`, `builtin` |\n| `SEMIA_SOUFFLE_BIN` | path to `souffle` if not on `PATH` |\n\nFor full synthesis tuning (`SEMIA_SYNTHESIS_*`), see the rest of\n[`.env.example`](.env.example) and\n[docs/plugin-protocol.md](docs/plugin-protocol.md).\n\n## Common workflows\n\n**Stop after deterministic preparation:**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --prepare-only\n```\n\n**Reuse facts from a prior run or an agent session:**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --facts synthesized_facts.dl\nsemia report .semia/runs/some-skill --format sarif\n```\n\n**CI smoke test (no LLM call):**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --offline-baseline\n```\n> `--offline-baseline` is a conservative non-LLM fallback for offline demos\n> and CI smoke tests. It is **not** a substitute for real synthesis.\n\n## Install as a host plugin\n\nThe Codex and Claude Code plugin bundles under `packages/semia-plugins//`\nship with a self-contained `bin/semia.pyz` zipapp, so they work out of the\nbox without a separate `pip install semia-skillscan`. The OpenClaw skill\nrelies on the published `semia` CLI on `PATH` (ClawHub provisions it via\n`uv tool install`). Installing the Python package as well is recommended if\nyou want `semia` available as a normal shell command alongside the in-host\nworkflow.\n\n**Codex** — slash commands run inside the Codex CLI (not a separate shell):\n\n```text\n/plugin marketplace add RiemaLabs/semia-skillscan\n/plugin install semia-skillscan@semia-skillscan\n```\n\nHeadless setups can enable it directly by adding the following to\n`~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia-skillscan@semia-skillscan\"]\nenabled = true\n```\n\n**Claude Code** — slash commands run inside the Claude Code CLI (not a separate shell):\n\n```text\n/plugin marketplace add RiemaLabs/semia-skillscan\n/plugin install semia-skillscan@semia-skillscan\n```\n\nThe `name@marketplace` form on `/plugin install` is required — the second\n`semia-skillscan` is the marketplace identifier from the project's\n`marketplace.json`. The marketplace registration step (`/plugin marketplace\nadd ...`) is only available as a slash command inside the CLI; there is no\n`claude plugin marketplace add` shell equivalent in the official\n[plugins reference](https://code.claude.com/docs/en/plugins-reference#cli-commands-reference).\nOnce installed, the management subcommands (`install`, `uninstall`,\n`enable`, `disable`, `list`, …) are also exposed as shell commands —\ne.g. `claude plugin install semia-skillscan@semia-skillscan --scope project`.\nSee [Discover and install plugins](https://code.claude.com/docs/en/discover-plugins)\nfor the full UX.\n\n**OpenClaw** — install from ClawHub:\n\n```bash\nopenclaw plugins install clawhub:semia-skillscan\n```\n\nClawHub will install the `semia` CLI on demand via `uv tool install\nsemia-skillscan` (declared in the skill's `install` block). If you prefer to\npre-provision it yourself:\n\n```bash\nuv tool install semia-skillscan # or: pip install semia-skillscan\nopenclaw plugins install clawhub:semia-skillscan\n```\n\n## Repository layout\n\n```text\npackages/\n semia-core/ # deterministic analysis library (prepare, check, detect, report)\n semia-cli/ # `semia` command surface\n semia-plugins/ # Codex / Claude Code / OpenClaw integrations\ndocs/\n architecture.md\n plugin-protocol.md\n release.md\n supply-chain.md\ntests/\n\n```\n\n## Development\n\n```bash\ngit clone https://github.com/RiemaLabs/semia-skillscan\ncd semia-skillscan\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\npython -m pip install pre-commit\npre-commit install\npre-commit run --all-files # establish a clean baseline\n\nmake help # list targets\nmake check # compile + tests + manifest validation\nmake build # package metadata check\nmake release-check # full pre-release gate\n```\n\nThe root quality gates stay stdlib-friendly: `compileall`, `unittest`\ndiscovery, and stdlib-only validators. Pre-commit adds `ruff` lint/format\nand `gitleaks` secret scanning. CI mirrors `ruff` via\n[`lint.yml`](.github/workflows/lint.yml); `gitleaks` stays local-only\nbecause the upstream GitHub Action now requires a paid license for\norganization repositories.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow and the DCO\nsign-off requirement.\n\n## Project background\n\nThe technique behind Semia Skillscan is described in the Semia paper\n([arXiv:2605.00314](https://arxiv.org/abs/2605.00314) ·\n[PDF](https://arxiv.org/pdf/2605.00314)). Skillscan is the\n**deterministic acceptance boundary** around behavior mapping: agents may\nextract facts, but only checked, evidence-grounded facts make it into a\nreport.\n\n## Security\n\nTo report a security vulnerability, see [SECURITY.md](SECURITY.md). Please\ndo **not** file public GitHub issues for security problems.\n\n## Contributing\n\nContributions are welcome — bug reports, documentation fixes, detector\nrules, and code. See [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow\nand the DCO sign-off requirement.\n\n## License & trademarks\n\nSemia Skillscan is released under the [Apache License 2.0](LICENSE). You\nmay use, modify, and redistribute it freely, including for commercial\npurposes, subject to the terms of the license. See [NOTICE](NOTICE) for\nattribution.\n\nThe names **\"Semia\"**, **\"Skillscan\"**, **\"Semia Skillscan\"**, and\n**\"RiemaLabs\"** are trademarks of RiemaLabs and are **not** licensed under\nApache-2.0. See [TRADEMARKS.md](TRADEMARKS.md) for the trademark policy.\n"}, "390b9984784e07527f4ee8ec7febf4eaddf04674": {"t": 1785762656.901792, "n": 17979, "h": "53266675635d8945", "c": "# Semia Skillscan\n\n> **Static security audit for AI agent skills.** Know what a skill *can* do\n> before you trust it.\n\n[![CI](https://github.com/RiemaLabs/semia-skillscan/actions/workflows/ci.yml/badge.svg)](https://github.com/RiemaLabs/semia-skillscan/actions/workflows/ci.yml)\n[![Lint](https://github.com/RiemaLabs/semia-skillscan/actions/workflows/lint.yml/badge.svg)](https://github.com/RiemaLabs/semia-skillscan/actions/workflows/lint.yml)\n[![codecov](https://codecov.io/gh/RiemaLabs/semia-skillscan/graph/badge.svg)](https://codecov.io/gh/RiemaLabs/semia-skillscan)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](pyproject.toml)\n\nAgent skills are markdown files with embedded shell commands, network calls,\nand tool invocations. They run with **your credentials, on your machine,\nwith your data**. Skillscan reads a skill as data — never executes it — and\nproduces an evidence-backed report of every capability it may exercise.\n\nIt is the difference between\n\n> *\"I trust this skill because the README looks fine.\"*\n\nand\n\n> *\"I trust this skill because Skillscan extracted 14 actions, 6 effects,\n> and 2 secret reads — and every one is grounded in a specific source line.\"*\n\n---\n\n## Quick example\n\nPick whichever fits how you already work.\n\n### As a CLI\n\n```bash\npip install semia-skillscan\nsemia scan ./some-skill --out .semia/runs/some-skill\n```\n\n`scan` does prepare → synthesize (via your configured LLM provider) →\ndetect → report in one shot. You'll need an LLM provider configured first —\nsee [Set up an LLM provider](#set-up-an-llm-provider) below.\n\n### Inside Codex, Claude Code, or OpenClaw\n\nInstall the plugin once:\n\n```bash\n# Codex (slash command, run inside the Codex CLI — not a separate shell)\n/plugin marketplace add RiemaLabs/semia-skillscan\n/plugin install semia-skillscan@semia-skillscan\n\n# Claude Code (slash command, run inside the Claude Code CLI — not a separate shell)\n/plugin marketplace add RiemaLabs/semia-skillscan\n/plugin install semia-skillscan@semia-skillscan\n\n# OpenClaw (shell command — one step registers and installs)\nopenclaw plugins install clawhub:semia-skillscan\n```\n\nThen in any chat with the host agent just ask:\n\n> Run Semia audit on ./some-skill\n\nThe host agent itself acts as the synthesize step — **no API key needed**.\nThe bundled `semia.pyz` handles prepare / detect / report deterministically.\n\n### Outputs\n\nYou get `report.md` — findings ranked by severity, every one tied to a\nspecific source line. Need [SARIF 2.1.0](https://sarifweb.azurewebsites.net/)\nfor GitHub Code Scanning, or structured JSON for downstream tooling? One\nmore command:\n\n```bash\nsemia report .semia/runs/some-skill --format sarif # for GitHub Code Scanning\nsemia report .semia/runs/some-skill --format json # structured payload\n```\n\n## Set up an LLM provider\n\n`semia scan` needs an LLM for the **synthesize** step (the other three\nstages are deterministic, no key required). If you run Semia via a host\nplugin (Codex / Claude Code / OpenClaw) skip this — the host agent already\ndoes synthesize for you.\n\nFour providers are supported. Pick one and export its credentials:\n\n```bash\n# OpenAI Responses API — default; also works for DeepSeek / OpenRouter / vLLM\nexport OPENAI_API_KEY=sk-...\n# optional: export OPENAI_BASE_URL=https://api.deepseek.com/v1\n\n# Anthropic Messages API\nexport SEMIA_LLM_PROVIDER=anthropic\nexport ANTHROPIC_API_KEY=sk-ant-...\n# optional: export ANTHROPIC_BASE_URL=https://api.anthropic.com\n\n# Locally-installed Claude Code CLI (uses your Claude Code login)\nexport SEMIA_LLM_PROVIDER=claude\n\n# Locally-installed Codex CLI (uses your Codex login)\nexport SEMIA_LLM_PROVIDER=codex\n```\n\nOverride the model with `--model ` on any `semia scan` invocation, or\npersist it via `SEMIA_LLM_MODEL`. Models are free-form strings — anything\nthe endpoint accepts (`gpt-5.5`, `deepseek-v4`, `claude-opus-4-7`, …).\n\nSee [Configuration](#configuration) for the full provider matrix, base-URL\nsupport, timeout/retry knobs, and synthesis-loop tuning.\n\n## What you get\n\nA run writes everything under `.semia/runs//`. **Most users only\never open the reports**:\n\n| Report | When |\n| ------------------- | --------------------------------------------------------- |\n| `report.md` | always produced by `semia scan` — read this first |\n| `report.sarif.json` | on demand via `semia report --format sarif` — feed to GitHub Code Scanning |\n| `report.json` | on demand via `semia report --format json` — structured payload (check + evidence + detector) for programmatic consumers |\n\nBecause every finding traces back to a source line, the SARIF drops cleanly\ninto GitHub Code Scanning and reviewers see annotations directly on the\nskill PR.\n\n
\nOther artifacts in the run directory (internal — for tooling, debugging, or re-querying)\n\n| Artifact | Purpose |\n| ------------------------- | -------------------------------------------------- |\n| `synthesized_facts.dl` | the behavior map (Datalog facts) — re-queryable |\n| `detection_findings.dl` | findings derived by rule evaluation |\n| `prepared_skill.md` | normalized skill text with stable line anchors |\n| `prepare_units.json` | reference units the evidence text aligns against |\n| `synthesis_metadata.json` | provider, model, retries, score, stop reason |\n| `run_manifest.json` | end-to-end manifest of the run |\n\n
\n\n## Worked example\n\nPicture a skill that promises to \"summarize your inbox every day\". It\ninstalls a browser automation tool, opens your real Chrome (with every\nsaved login), reads Gmail, pipes the messages to an LLM that controls\nthe browser, and sets up a launchd job to repeat daily — forever. One\nemail from an attacker turns that skill into a remote control for every\nsite you are logged into.\n\n[See **EXAMPLE.md** for the full walkthrough →](EXAMPLE.md) — the skill\nsource, the attack, why it works, and the exact capabilities Skillscan\nsurfaces before you install.\n\n## How it works\n\n```text\n ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌────────┐\n │ Prepare │ ──▶ │ Synthesize │ ──▶ │ Detect │ ──▶ │ Report │\n │ (det.) │ │ (LLM) │ │ (det.) │ │ (det.) │\n └──────────┘ └────────────┘ └──────────┘ └────────┘\n```\n\n1. **Prepare** — read skill markdown + adjacent source, inline references,\n assign stable evidence handles. Pure stdlib. No LLM.\n2. **Synthesize** — an LLM (or the host agent's own session) extracts a\n *behavior map* as Datalog facts (`action`, `call`, `call_effect`, …)\n with `_evidence_text` sidecars citing the original source. The loop\n retries invalid candidates with checker feedback and keeps the best one.\n3. **Detect** — a Datalog evaluator runs the bundled SDL rules over the\n facts to flag risky combinations (e.g. *secret read → network write*).\n4. **Report** — render Markdown for humans and SARIF for CI.\n\nDetection runs through a built-in pure-Python Datalog evaluator by default,\nso **no external binary is required**. If [Soufflé](https://souffle-lang.github.io/)\nis on `PATH` (or `SEMIA_SOUFFLE_BIN`) it is preferred as a faster backend.\nOverride with `SEMIA_DETECTOR_BACKEND=auto|souffle|builtin`.\n\n[Read the full architecture →](docs/architecture.md)\n\n## Trust model\n\nSkillscan is a security tool for analyzing untrusted content. The trust\nboundary is explicit:\n\n| Surface | Treatment |\n| ------------------------- | -------------------------------------------------------------------------------- |\n| Audited skill | **untrusted data** — never executed, hooks/installers ignored |\n| Skill-declared URLs | **never fetched** during a scan |\n| Prompt-injection in skill | **recorded as evidence**, not followed as instructions |\n| Prepare / Detect / Report | deterministic, stdlib-friendly, runs locally |\n| Synthesize | the only LLM-mediated step; output must pass structural and evidence checks |\n| Network | LLM provider only |\n| Filesystem | reads the skill directory; writes only `.semia/runs//` |\n\nSee [docs/plugin-protocol.md#hostile-input-rules](docs/plugin-protocol.md)\nfor the full host-integration contract, and\n[SECURITY.md](SECURITY.md) for vulnerability reporting.\n\n## Install\n\nFrom source (current):\n\n```bash\ngit clone https://github.com/RiemaLabs/semia-skillscan\ncd semia-skillscan\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\n```\n\nPython 3.11+ required. The project has **zero runtime dependencies** — both\nthe `responses` and `anthropic` providers talk to their APIs over raw HTTP\nusing the standard library.\n\n## Configuration\n\nSettings come from CLI flags, environment variables, or a repo-local\n`.env`. Copy [`.env.example`](.env.example) to `.env` and fill in your\ncredentials — `.env` is gitignored, and CI runs `gitleaks` to make sure\nnothing leaks into the history.\n\n### Providers\n\nSkillscan routes synthesis through one of four providers — two HTTP wire\nformats and two local CLI shell-outs. The default is `responses` with\nmodel `gpt-5.5`, authenticated via `OPENAI_API_KEY`.\n\n| Provider | Transport | Default model | Honors `--base-url` | Auth |\n| ------------ | ---------------------------------- | ------------------- | ------------------- | ----------------------------------------------------------------- |\n| `responses` | OpenAI Responses API (raw HTTP) | `gpt-5.5` | yes | `OPENAI_API_KEY`; `OPENAI_BASE_URL` (defaults to api.openai.com) |\n| `anthropic` | Anthropic Messages API (raw HTTP) | `claude-opus-4-7` | yes | `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`; `ANTHROPIC_BASE_URL` |\n| `codex` | shells out to `codex exec` | Codex CLI's own | no | inherits Codex CLI config |\n| `claude` | shells out to `claude --print` | `claude-opus-4-7` | no | inherits Claude Code env (`ANTHROPIC_*`) |\n\n`openai` is accepted as a synonym for `responses`. The **model** is free-form\n— any string the endpoint accepts works (`gpt-5.5`, `gpt-5.4`,\n`gpt-5.3-codex`, `deepseek-v4`, `claude-opus-4-7`, `claude-opus-4-6`, …).\n\nSwitch with flags:\n\n```bash\n# Default: OpenAI Responses against api.openai.com\nsemia scan ./some-skill --out .semia/runs/some-skill\n\n# Anthropic Messages against api.anthropic.com\nsemia scan ./some-skill --out .semia/runs/some-skill --provider anthropic\n\n# Point the responses format at a different endpoint (DeepSeek, OpenRouter, vLLM, …)\nsemia scan ./some-skill --out .semia/runs/some-skill \\\n --provider responses --model deepseek-v4 \\\n --base-url https://api.deepseek.com/v1\n\n# Use the locally-installed Claude Code CLI (model is the only knob)\nsemia scan ./some-skill --out .semia/runs/some-skill --provider claude --model claude-opus-4-7\n```\n\n### Most common environment variables\n\n| Variable | Purpose |\n| --------------------------- | -------------------------------------------------------------------- |\n| `SEMIA_LLM_PROVIDER` | `responses` (default) / `anthropic` / `codex` / `claude` |\n| `SEMIA_LLM_MODEL` | free-form model name passed to the provider |\n| `SEMIA_LLM_TIMEOUT` | request timeout in seconds |\n| `SEMIA_LLM_MAX_RETRIES` | retry budget for transient provider errors |\n| `OPENAI_BASE_URL` | base URL for the `responses` provider |\n| `ANTHROPIC_BASE_URL` | base URL for the `anthropic` provider |\n| `SEMIA_DETECTOR_BACKEND` | `auto` (default), `souffle`, `builtin` |\n| `SEMIA_SOUFFLE_BIN` | path to `souffle` if not on `PATH` |\n\nFor full synthesis tuning (`SEMIA_SYNTHESIS_*`), see the rest of\n[`.env.example`](.env.example) and\n[docs/plugin-protocol.md](docs/plugin-protocol.md).\n\n## Common workflows\n\n**Stop after deterministic preparation:**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --prepare-only\n```\n\n**Reuse facts from a prior run or an agent session:**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --facts synthesized_facts.dl\nsemia report .semia/runs/some-skill --format sarif\n```\n\n**CI smoke test (no LLM call):**\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --offline-baseline\n```\n> `--offline-baseline` is a conservative non-LLM fallback for offline demos\n> and CI smoke tests. It is **not** a substitute for real synthesis.\n\n## Install as a host plugin\n\nThe Codex and Claude Code plugin bundles under `packages/semia-plugins//`\nship with a self-contained `bin/semia.pyz` zipapp, so they work out of the\nbox without a separate `pip install semia-skillscan`. The OpenClaw skill\nrelies on the published `semia` CLI on `PATH` (ClawHub provisions it via\n`uv tool install`). Installing the Python package as well is recommended if\nyou want `semia` available as a normal shell command alongside the in-host\nworkflow.\n\n**Codex** — slash commands run inside the Codex CLI (not a separate shell):\n\n```text\n/plugin marketplace add RiemaLabs/semia-skillscan\n/plugin install semia-skillscan@semia-skillscan\n```\n\nHeadless setups can enable it directly by adding the following to\n`~/.codex/config.toml`:\n\n```toml\n[plugins.\"semia-skillscan@semia-skillscan\"]\nenabled = true\n```\n\n**Claude Code** — slash commands run inside the Claude Code CLI (not a separate shell):\n\n```text\n/plugin marketplace add RiemaLabs/semia-skillscan\n/plugin install semia-skillscan@semia-skillscan\n```\n\nThe `name@marketplace` form on `/plugin install` is required — the second\n`semia-skillscan` is the marketplace identifier from the project's\n`marketplace.json`. The marketplace registration step (`/plugin marketplace\nadd ...`) is only available as a slash command inside the CLI; there is no\n`claude plugin marketplace add` shell equivalent in the official\n[plugins reference](https://code.claude.com/docs/en/plugins-reference#cli-commands-reference).\nOnce installed, the management subcommands (`install`, `uninstall`,\n`enable`, `disable`, `list`, …) are also exposed as shell commands —\ne.g. `claude plugin install semia-skillscan@semia-skillscan --scope project`.\nSee [Discover and install plugins](https://code.claude.com/docs/en/discover-plugins)\nfor the full UX.\n\n**OpenClaw** — install from ClawHub:\n\n```bash\nopenclaw plugins install clawhub:semia-skillscan\n```\n\nClawHub will install the `semia` CLI on demand via `uv tool install\nsemia-skillscan` (declared in the skill's `install` block). If you prefer to\npre-provision it yourself:\n\n```bash\nuv tool install semia-skillscan # or: pip install semia-skillscan\nopenclaw plugins install clawhub:semia-skillscan\n```\n\n## Repository layout\n\n```text\npackages/\n semia-core/ # deterministic analysis library (prepare, check, detect, report)\n semia-cli/ # `semia` command surface\n semia-plugins/ # Codex / Claude Code / OpenClaw integrations\ndocs/\n architecture.md\n plugin-protocol.md\n release.md\n supply-chain.md\ntests/\n\n```\n\n## Development\n\n```bash\ngit clone https://github.com/RiemaLabs/semia-skillscan\ncd semia-skillscan\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\npython -m pip install pre-commit\npre-commit install\npre-commit run --all-files # establish a clean baseline\n\nmake help # list targets\nmake check # compile + tests + manifest validation\nmake build # package metadata check\nmake release-check # full pre-release gate\n```\n\nThe root quality gates stay stdlib-friendly: `compileall`, `unittest`\ndiscovery, and stdlib-only validators. Pre-commit adds `ruff` lint/format\nand `gitleaks` secret scanning; CI mirrors both via\n[`lint.yml`](.github/workflows/lint.yml) and\n[`gitleaks.yml`](.github/workflows/gitleaks.yml).\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow and the DCO\nsign-off requirement.\n\n## Project background\n\nThe technique behind Semia Skillscan is described in the Semia paper\n([arXiv:2605.00314](https://arxiv.org/abs/2605.00314) ·\n[PDF](https://arxiv.org/pdf/2605.00314)). Skillscan is the\n**deterministic acceptance boundary** around behavior mapping: agents may\nextract facts, but only checked, evidence-grounded facts make it into a\nreport.\n\n## Security\n\nTo report a security vulnerability, see [SECURITY.md](SECURITY.md). Please\ndo **not** file public GitHub issues for security problems.\n\n## Contributing\n\nContributions are welcome — bug reports, documentation fixes, detector\nrules, and code. See [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow\nand the DCO sign-off requirement.\n\n## License & trademarks\n\nSemia Skillscan is released under the [Apache License 2.0](LICENSE). You\nmay use, modify, and redistribute it freely, including for commercial\npurposes, subject to the terms of the license. See [NOTICE](NOTICE) for\nattribution.\n\nThe names **\"Semia\"**, **\"Skillscan\"**, **\"Semia Skillscan\"**, and\n**\"RiemaLabs\"** are trademarks of RiemaLabs and are **not** licensed under\nApache-2.0. See [TRADEMARKS.md](TRADEMARKS.md) for the trademark policy.\n"}, "173430f50c68fc8e281c35c611479a56a44a610d": {"t": 1785762658.3861492, "n": 5469, "h": "393955371fb68568", "c": "# Semia Skillscan\n\nSemia Skillscan builds a behavior map for AI agent skills. It turns\nnatural-language skill instructions and adjacent source into grounded facts\nabout what the skill may do, then runs deterministic checks over those facts.\nIt is maintained by RiemaLabs and follows the license used by the Semia paper:\n[arXiv:2605.00314](https://arxiv.org/abs/2605.00314).\n\nThe product shape is:\n\n```text\nsemia scan ./some-skill\nRun Semia audit on this skill\n```\n\nThe scanner is designed around a narrow trust boundary. Host agents such as\nCodex, Claude Code, and OpenClaw can use their own session to synthesize the\nbehavior map, while Semia provides deterministic preparation, fact checking,\nevidence grounding, Souffle-backed detection, and reporting.\nThe standalone CLI defaults to OpenAI for synthesis with `gpt-5.5`, using\n`OPENAI_API_KEY`. Users can override the provider or model with flags or\nenvironment variables.\n\n## Quick start\n\nIn an installed plugin host, ask:\n\n```text\nRun Semia audit on this skill\n```\n\nFrom a shell, run a full local audit:\n\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill\n```\n\nBy default, this runs `prepare`, calls the configured LLM provider for\n`synthesize`, then runs `detect` and `report`. The default provider is `openai`\nand the default model is `gpt-5.5`. Use `--provider anthropic` for direct\nAnthropic SDK calls, `--provider codex` or `--provider claude` to route\nsynthesis through a local agent CLI, or `--model` to pass an explicit model\nname to the selected provider.\n\nConfiguration knobs:\n\n```bash\nexport OPENAI_API_KEY=...\nexport SEMIA_LLM_PROVIDER=openai\nexport SEMIA_LLM_MODEL=gpt-5.5\nsemia scan ./some-skill --out .semia/runs/some-skill\n```\n\nProvider defaults:\n\n- `openai`: reads `OPENAI_API_KEY`, optional `OPENAI_BASE_URL`, and streams the\n Responses API by default.\n- `anthropic`: uses the Python Anthropic SDK when installed. It reads\n `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`, optional\n `ANTHROPIC_BASE_URL`, and `ANTHROPIC_MODEL`.\n- `claude`: shells out to Claude Code and inherits Claude Code environment such\n as `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_BASE_URL`, and\n `ANTHROPIC_MODEL`.\n- `codex`: shells out to Codex CLI and inherits the user's Codex CLI\n configuration.\n\nShared Semia overrides:\n\n- `SEMIA_LLM_PROVIDER`\n- `SEMIA_LLM_MODEL`\n- `SEMIA_LLM_TIMEOUT`\n- `SEMIA_LLM_MAX_RETRIES`\n- `SEMIA_SYNTHESIS_N_ITERATIONS`\n- `SEMIA_SYNTHESIS_MAX_RETRIES`\n- `SEMIA_SYNTHESIS_PLATEAU_MIN_IMPROVEMENT`\n- `SEMIA_SYNTHESIS_PLATEAU_PATIENCE`\n- `SEMIA_SYNTHESIS_RESUME_FROM`\n- `SEMIA_SYNTHESIS_MAX_DOC_BYTES`\n\nSynthesize writes production audit artifacts as it runs:\n\n- `synthesized_facts.dl`: selected winning behavior map\n- `synthesized_facts_.dl`: accepted candidate per iteration\n- `synthesis_attempt__.dl`: raw extracted attempt facts\n- `synthesis_patch__.dl`: incremental review diff, when used\n- `synthesis_response__.txt`: raw provider response\n- `synthesis_metadata.json`: provider, model, retry, score, candidate chain,\n selected iteration, and stop reason\n\nFor local development, simulate a fresh user install:\n\n```bash\npython3 -m venv --clear .venv\nsource .venv/bin/activate\npython -m pip install -e .\nsemia --help\nsemia scan ./some-skill --out .semia/runs/some-skill\n```\n\nFor direct Anthropic SDK synthesis, install the optional extra:\n\n```bash\npython -m pip install -e \".[anthropic]\"\nsemia scan ./some-skill --out .semia/runs/some-skill --provider anthropic\n```\n\nIf the virtual environment was created by a broken Python runtime, recreate it\nwith `python3 -m venv --clear .venv` before installing.\n\nIf you already have agent-generated synthesized facts, provide them explicitly:\n\n```bash\nsemia scan ./some-skill --out .semia/runs/some-skill --facts synthesized_facts.dl\nsemia report .semia/runs/some-skill --format sarif\n```\n\nFor CI smoke tests or offline demos only, `--offline-baseline` uses a\nconservative non-LLM fallback. It is not a substitute for real synthesis. Use\n`--prepare-only` only when you intentionally want to stop after prepare.\n\n## Repository shape\n\n```text\npackages/\n semia-core/ # deterministic analysis library\n semia-cli/ # local and CI command surface\n semia-plugins/ # Codex, Claude Code, and OpenClaw integrations\ndocs/\n release.md\n supply-chain.md\ntests/\n```\n\nThis scaffold intentionally keeps runtime dependencies at zero. Package lanes\ncan add their own dependencies when they land, but the root quality gates stay\nstdlib-friendly.\n\n## Development\n\nInstall `uv`, then run:\n\n```bash\nmake help\nmake check\nmake build\nmake release-check\n```\n\nThe root checks currently cover:\n\n- Python byte-compilation via `compileall`\n- stdlib `unittest` discovery\n- integration manifest JSON validation\n- package metadata and package-data checks\n\n## Behavior Map Contract\n\nThe target skill is untrusted data. A host agent may read skill contents to\nsynthesize behavior facts, but deterministic Semia tooling is the acceptance\nboundary: generated facts must pass parsing, schema checks, evidence alignment,\nand detector execution before a report is trusted.\n\n## License\n\nSemia Skillscan uses `CC-BY-NC-ND-4.0`, matching the Semia paper\n([arXiv:2605.00314](https://arxiv.org/abs/2605.00314)). This is a\nsource-available research/software release, not an OSI open source software\nlicense. Commercial use and distribution of modified versions require explicit\npermission from RiemaLabs. See [LICENSE](LICENSE).\n"}}}}