{"id":50930180,"url":"https://github.com/foundryside-dev/wardline","last_synced_at":"2026-06-17T03:05:26.019Z","repository":{"id":350899210,"uuid":"1208460695","full_name":"foundryside-dev/wardline","owner":"foundryside-dev","description":"Generic semantic-tainting static analyzer for Python — enterprise-class trust-boundary analysis at small-team weight.","archived":false,"fork":false,"pushed_at":"2026-06-15T14:12:09.000Z","size":4875,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-15T14:25:37.972Z","etag":null,"topics":["security","static-analysis","taint-analysis","trust-boundaries"],"latest_commit_sha":null,"homepage":"https://foundryside-dev.github.io/wardline/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/foundryside-dev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":"AUDIT.md","citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-12T10:09:13.000Z","updated_at":"2026-06-07T08:23:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/foundryside-dev/wardline","commit_stats":null,"previous_names":["foundryside-dev/wardline"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/foundryside-dev/wardline","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foundryside-dev%2Fwardline","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foundryside-dev%2Fwardline/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foundryside-dev%2Fwardline/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foundryside-dev%2Fwardline/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/foundryside-dev","download_url":"https://codeload.github.com/foundryside-dev/wardline/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foundryside-dev%2Fwardline/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34431810,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-17T02:00:05.408Z","response_time":127,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["security","static-analysis","taint-analysis","trust-boundaries"],"created_at":"2026-06-17T03:05:25.136Z","updated_at":"2026-06-17T03:05:26.010Z","avatar_url":"https://github.com/foundryside-dev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Wardline\n\nGeneric, lightweight semantic-tainting static analyzer for trust boundaries. Wardline's full analyzer targets\nPython; its Rust preview catches command-injection defects over crate-aware identity. The base package has zero\nruntime dependencies, and scanner/front-end functionality stays behind opt-in extras.\n\n[![CI](https://github.com/foundryside-dev/wardline/actions/workflows/ci.yml/badge.svg)](https://github.com/foundryside-dev/wardline/actions/workflows/ci.yml)\n[![PyPI](https://img.shields.io/pypi/v/wardline)](https://pypi.org/project/wardline/)\n[![Python 3.12+](https://img.shields.io/pypi/pyversions/wardline)](https://pypi.org/project/wardline/)\n[![License: MIT](https://img.shields.io/pypi/l/wardline)](https://github.com/foundryside-dev/wardline/blob/main/LICENSE)\n\n```python\n# demo.py\nfrom weft_markers import trusted, external_boundary\n\n@external_boundary\ndef read_request(req):\n    return req.body            # raw, untrusted (EXTERNAL_RAW)\n\n@trusted(level=\"ASSURED\")\ndef build_record(req):\n    return read_request(req)   # claims ASSURED, returns raw — no validation\n```\n\n```console\n$ wardline scan . --fail-on ERROR\nscanned 1 file(s); 3 finding(s) — 0 suppressed (0 baseline / 0 waiver / 0 judged), 1 active -\u003e findings.jsonl\n$ echo $?\n1\n```\n\nThe gate trips (exit 1) and the findings land in `findings.jsonl` (JSON Lines;\n`--format sarif` for GitHub code scanning). Wardline is agent-first — you don't\nread that file by hand. Your coding agent does: ask it *\"why did the scan fail?\"*\nand it surfaces the one active defect (the other two findings are `NONE`-severity\nengine facts):\n\n\u003e **`demo.build_record`** declares return trust `ASSURED` but actually returns\n\u003e `EXTERNAL_RAW` (less trusted) — untrusted data reaches a trusted producer.\n\u003e \u0026nbsp;\u0026nbsp;`demo.py:8` · `PY-WL-101`\n\n## What is Wardline?\n\nWardline reads your code statically — it never runs it — and asks one question\nof every trust-annotated boundary: **is the data this function works with as\ntrusted as it claims?** For Python, it tracks a *taint* (a trust level) for\nvalues through function bodies and the project call graph, flagging places where\nuntrusted data reaches a trusted producer with no validation in between. For\nRust, the preview frontend currently focuses on command-injection sinks around\n`std::process::Command`.\n\nWardline is part of **Weft** — an agent-first suite of small, local-first\ndeveloper tools, each driven by a coding agent as much as a person, giving small\nteams capable tooling without enterprise weight. The authoritative federation\nhub, roster, and composition doctrine live at `~/weft` (see\n`~/weft/doctrine.md`); rather than restate membership here, refer to the hub for\nthe current roster and the enrich-only axiom that governs how the tools compose.\n\n**Opt-in by design.** Wardline is silent until you opt in. Undecorated code sits\nin the developer-freedom zone — unknown-trust, no findings. You declare trust on\nthe functions that matter, and only then does Wardline enforce it. That is what\nlets it scan a large untouched codebase (including its own) with zero noise.\n\n## Key Features\n\n- **Deterministic Python taint analysis** — function-, variable-, and\n  project-level analysis over an inter-module call graph; no runtime\n  instrumentation.\n- **Rust command-injection preview** — `wardline scan --lang rust` finds\n  `RS-WL-108`/`RS-WL-112` over `.rs` trees with crate-prefixed, baseline-eligible\n  finding identity.\n- **Opt-in trust model** — Python decorators (`@external_boundary`,\n  `@trust_boundary`, `@trusted`) and Rust doc-comment markers declare the\n  boundary surface; undecorated code stays quiet.\n- **Trust-boundary and sink rules** — boundary-integrity rules, exception-flow\n  rules, and expanded sink families for command execution, dynamic code/imports,\n  deserialization, path traversal, SSRF, SQL injection, XML parsing, templates,\n  native library loads, logging format strings, and SMTP sends.\n- **Zero-dependency base** — `pip install wardline` pulls nothing; scanner,\n  Loomweave, Rust, and docs functionality live behind small extras.\n- **Structured output** — JSONL, SARIF, agent-summary JSON, signed legis scan\n  artifacts, and native Filigree emission for finding lifecycle work.\n- **MCP-primary agent surface** — `wardline mcp` is a dependency-free\n  MCP-over-stdio server with structured tool output, schema declarations, and\n  tools for scan, explain, fix, judge, doctor, rekey, assurance, attestation,\n  dossier, and finding lifecycle work.\n- **Reproducible evidence and migrations** — `assure`, `attest`, and `rekey`\n  report trust-surface coverage, sign reproducible posture bundles, and migrate\n  fingerprint-keyed stores across scheme changes.\n- **Opt-in LLM triage** — `wardline judge` labels findings TRUE/FALSE positive\n  (dependency-free; never runs automatically).\n- **Light-touch suppression** — baselines, time-boxed waivers, and judged\n  findings with explicit gate semantics.\n- **Loomweave integration** — persist per-entity taint facts to a Loomweave store.\n\n## Quick Start\n\n```bash\npip install 'wardline[scanner]'   # quote the extras for zsh\n```\n\n```python\n# app.py\nfrom weft_markers import trusted, external_boundary\n\n@external_boundary\ndef read_request(req):\n    return req.body\n\n@trusted(level=\"ASSURED\")\ndef build_record(req):\n    return read_request(req)\n```\n\n```bash\nwardline scan . --fail-on ERROR   # exit 0 = clean, 1 = gate tripped, 2 = wardline error\n```\n\nFix findings at the **boundary** (validate before returning), not at the sink.\n\n## Installation\n\n```bash\npip install weft-markers          # tiny runtime marker package for application code\npip install wardline              # zero-dependency base (library + decorators)\npip install 'wardline[scanner]'   # the scan/judge/baseline CLI + MCP server (quote for zsh)\npip install 'wardline[rust]'      # Rust command-injection preview frontend\n```\n\nPrefer `weft_markers` in application code. Wardline still recognizes\n`wardline.decorators` for backward compatibility and direct Wardline users, but\n`weft-markers` is the neutral marker-only runtime dependency.\n\n| Extra | Pulls | Enables |\n|-------|-------|---------|\n| `scanner` | pyyaml, jsonschema, click | the `wardline` CLI and `wardline mcp` server |\n| `loomweave` | blake3 | persisting taint facts to a Loomweave store |\n| `rust` | scanner extra, tree-sitter, tree-sitter-rust | `wardline scan --lang rust` |\n| `docs` | mkdocs, mkdocs-material | building the documentation site |\n\nThe LLM triage judge (`wardline judge`) is dependency-free (stdlib `urllib` →\nOpenRouter) and needs no extra.\n\n## Use Wardline with your coding agent\n\n```bash\nwardline install\n```\n\nThis injects a hash-fenced instruction block into `CLAUDE.md`/`AGENTS.md`,\ninstalls the `wardline-gate` skill, merges a `wardline` entry into `.mcp.json`,\nand writes Codex's `~/.codex/config.toml` MCP entry. Agents then run the scan →\nexplain → fix-at-boundary → rescan loop natively. The `wardline mcp` server\nexposes the primary tool surface over JSON-RPC with no SDK, including scan,\nfiltered findings, explain-taint, fix, judge, baseline/waiver, doctor, rekey,\nassure, attest, dossier, and Filigree filing tools.\n\n`wardline install` also reminds application projects to install `weft-markers`\nand import from `weft_markers` when they want runtime-importable trust markers\nwithout depending on the full Wardline scanner package.\n\nRun `wardline doctor` to check those artifacts later, or `wardline doctor\n--repair` to refresh stale/missing wiring after moving tools or starting a\nFiligree dashboard.\n\n## Configuration and state\n\nWardline reads operator configuration from the `[wardline]` table in\n`weft.toml`. Machine-written state lives under `.weft/wardline/`: baselines,\nwaivers, judged findings, and cache data stay out of the authored config file.\n\nSibling URLs are resolved at runtime from flags, environment variables, or\npublished local Weft port files. `wardline install` and `wardline doctor` detect\nsibling tools such as Filigree and Loomweave, but they do not persist endpoint\nbindings into project config.\n\n## Where Wardline fits\n\nUse Wardline when you want a deterministic, opt-in trust-boundary gate you can\nrun in CI and hand to an agent — lightweight, Python-native, no external service.\n\nIt is **not** the right tool when you need:\n\n- **Full interprocedural everything.** Wardline is precise at the function and\n  project-call-graph level (L1–L2 with an L3 fixed point), not an exhaustive,\n  path-sensitive whole-program prover.\n- **A broad SAST suite.** Wardline checks trust boundaries and a small set of\n  exception-handling rules; it is not a replacement for a general-purpose\n  scanner that covers dozens of vulnerability classes.\n- **Full non-Python coverage.** Wardline's Rust frontend is a preview for\n  command-injection findings only; it is not a general Rust SAST engine.\n- **Zero-config coverage.** Wardline is silent until you declare trust — that is\n  the point, but it means it finds nothing meaningful on an un-annotated\n  codebase.\n\n## Documentation\n\nFull documentation lives at **\u003chttps://foundryside-dev.github.io/wardline/\u003e**.\n\n| Document | Description |\n|----------|-------------|\n| [Getting Started](https://foundryside-dev.github.io/wardline/getting-started/) | Install, decorate, first scan |\n| [Taint \u0026 Trust Model](https://foundryside-dev.github.io/wardline/concepts/model/) | The lattice, decorators, and propagation |\n| [Rules](https://foundryside-dev.github.io/wardline/concepts/rules/) | The boundary, exception-flow, and sink rules |\n| [Configuration](https://foundryside-dev.github.io/wardline/guides/configuration/) | `weft.toml` `[wardline]`: rules, severity, excludes |\n| [Suppression](https://foundryside-dev.github.io/wardline/guides/suppression/) | Baselines and waivers |\n| [LLM Triage Judge](https://foundryside-dev.github.io/wardline/guides/judge/) | Opt-in TRUE/FALSE-positive labelling |\n| [Rust Support](https://foundryside-dev.github.io/wardline/guides/rust-preview/) | Preview Rust command-injection frontend |\n| [Weft Integration](https://foundryside-dev.github.io/wardline/guides/weft/) | SARIF, Filigree, Loomweave, and sibling URL resolution |\n| [Assurance Posture](https://foundryside-dev.github.io/wardline/guides/assurance-posture/) | Coverage posture, attestations, and trust-surface evidence |\n| [Loomweave Taint Store](https://foundryside-dev.github.io/wardline/guides/loomweave-taint-store/) | Persisting taint facts |\n| [CLI Reference](https://foundryside-dev.github.io/wardline/reference/cli/) | Every command and flag |\n| [Trust Vocabulary](https://foundryside-dev.github.io/wardline/reference/vocabulary/) | The decorators and their arguments |\n| [Agent Integration](https://foundryside-dev.github.io/wardline/guides/agents/) | Using Wardline from a coding agent |\n\n## Development\n\nRequires Python ≥3.12. Developed on 3.13 with [uv](https://docs.astral.sh/uv/).\n\n```bash\ngit clone https://github.com/foundryside-dev/wardline\ncd wardline\nuv sync --all-extras --group dev\n\nmake ci          # ruff check + format check + mypy strict + pytest (90% coverage floor)\nmake lint        # ruff check + format --check\nmake format      # auto-format and fix\nmake typecheck   # mypy strict\nmake test        # pytest\nmake scan-self   # dogfood: scan wardline's own source\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the full workflow and\n[CLAUDE.md](CLAUDE.md) for the developer architecture guide.\n\n## Acknowledgements\n\nWardline is one of the **Weft** tools (with Loomweave and Filigree) — an\nagent-first, local-first developer tooling suite for small teams.\n\n## License\n\n[MIT](LICENSE) — Copyright (c) 2026 John Morrissey\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffoundryside-dev%2Fwardline","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffoundryside-dev%2Fwardline","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffoundryside-dev%2Fwardline/lists"}