Skip to content

Relay 0.2.0 — Semantic recovery and polyglot review

Choose a tag to compare

@devkyato devkyato released this 29 Jul 10:59
98a812f

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=None is 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
    requires safety_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 .gitignore rules 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 5s

Relay 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.