Relay 0.2.0 — Semantic recovery and polyglot review
Relay 0.2.0
This release started with a hard critique: Relay looked like a static analyser, but too many of
its conclusions came from names and structural patterns. I thought about that point carefully,
and the right response was not to soften the wording around the edges. The model itself needed to
be more honest and more useful.
The important correction
Relay 0.2.0 is a conservative source-review tool. Python uses its standard AST with file-local,
qualified symbols. C/C++, Arduino, JavaScript, TypeScript, Java, C#, Go, Rust, Kotlin, Swift,
Ruby, and PHP use explicitly labelled structural models. Those models are useful for direct
blocking patterns and local structure, but they are not compilers and their findings are capped
accordingly.
Every text, Markdown, JSON, and SARIF report now names the analysis model. Ambiguous method calls
are left unresolved instead of being collapsed into a convenient but potentially false path.
What now works differently
await asyncio.sleep()is recognised as cooperative and is not reported as blocking.- Python classes and nested functions keep qualified identities.
- C-family class and namespace methods no longer collapse solely because their basenames match.
- Known blocking waits are reviewed across the supported language profiles.
- Timeout checking uses actual Python keyword and positional argument structure.
timeout=Noneis still missing; an unrelated argument containing the word “timeout” is not
accepted. - Durations can include arithmetic, signed values, common numeric suffixes,
min/max, Go time
units, and common duration constructors. - A maximum-latency task is not automatically called emergency logic. Critical reachability
requiressafety_critical = true. - Timing consequences are attached only to a task that can reach the wait. Execution contexts are
recorded as user-supplied provenance.
Oh—and the old timeline name was too authoritative. relay summary now lists declared periods
and reachable waits without pretending to simulate release times, priorities, execution costs,
pre-emption, interrupts, cores, or deadline response time. The old command remains as a deprecated
alias for this release.
Operational hardening
- Symlink analysis roots are refused before resolution.
- Discovery has a 50 MB aggregate default in addition to per-file and file-count limits.
- Root
.gitignorerules use Git wildmatch ordering, negation, rooted patterns, and directory
semantics. - Reports use atomic same-directory replacement and refuse source or symlink targets.
- Reproducibility verification builds the wheel and source archive twice and compares SHA-256
digests. - JSON schema 2.0 includes analysis models; SARIF includes stable finding fingerprints.
Compatibility
- Relay runtime: Python 3.9–3.14
- Analysed languages: Python, C, C++, Arduino, JavaScript, TypeScript, Java, C#, Go, Rust,
Kotlin, Swift, Ruby, and PHP - Operation: local and offline after installation
- Breaking report change: JSON schema version is now
2.0 - Configuration now rejects unknown keys and rule IDs
Install
python -m pip install relay_lint-0.2.0-py3-none-any.whl
relay --version
relay check .
relay summary . --duration 5sRelay still cannot prove real-time or physical-machine safety. It is designed to make review
questions sharper—and to make the limits behind those questions impossible to miss.