Context
taintline detectors implement a tiny Detector Protocol (name + a pure run(trace) -> list[Finding]). Everything needed to write one is in the code, but there is no contributor-facing guide walking through it. This is the single highest-leverage doc for attracting agent-safety contributors.
What to do
Add docs/writing-a-detector.md covering:
- the
Detector Protocol and the purity/determinism contract (no LLM, no network, no clock, no RNG);
- the
Trace/Span/Finding/Verdict types a detector works with;
- a minimal worked example (e.g. flag any tool span with
status == "ERROR"), including how to register it in ALL and add a seeded fixture + test;
- how
--fail-on gates the exit code vs. what always runs.
Link it from the README and CONTRIBUTING.md.
Acceptance criteria
docs/writing-a-detector.md exists and a reader can implement + register a new detector from it alone.
- The worked example is real, runnable code (copy-pasteable).
- README and
CONTRIBUTING.md link to it.
Pointers
src/taintline/model.py:90 — the Detector Protocol; Finding/Verdict above it
src/taintline/detectors/reliability.py:123 — SwallowedErrorDetector, a compact example to model the guide on
src/taintline/detectors/__init__.py — registration in ALL
docs/CONTRACT.md — the frozen type contract to reference
Context
taintline detectors implement a tiny
DetectorProtocol (name+ a purerun(trace) -> list[Finding]). Everything needed to write one is in the code, but there is no contributor-facing guide walking through it. This is the single highest-leverage doc for attracting agent-safety contributors.What to do
Add
docs/writing-a-detector.mdcovering:DetectorProtocol and the purity/determinism contract (no LLM, no network, no clock, no RNG);Trace/Span/Finding/Verdicttypes a detector works with;status == "ERROR"), including how to register it inALLand add a seeded fixture + test;--fail-ongates the exit code vs. what always runs.Link it from the README and
CONTRIBUTING.md.Acceptance criteria
docs/writing-a-detector.mdexists and a reader can implement + register a new detector from it alone.CONTRIBUTING.mdlink to it.Pointers
src/taintline/model.py:90— theDetectorProtocol;Finding/Verdictabove itsrc/taintline/detectors/reliability.py:123—SwallowedErrorDetector, a compact example to model the guide onsrc/taintline/detectors/__init__.py— registration inALLdocs/CONTRACT.md— the frozen type contract to reference