Releases: ack1d/asgion
Release list
v0.6.1
Features
check:--format githubfor GitHub Actions workflow commands (annotations in PR diffs).rules RULE_ID: output now includestags,deprecatedstatus, and asuppress:line.- GitHub Action:
install-commandinput, default--format github, job summary via$GITHUB_STEP_SUMMARY.
Fixes
- Fail-fast validation across public API and CLI:
Inspector:sample_ratemust be 0.0-1.0,max_body_sizemust be positive.FileStorage: write permission checked at construction, not at firststore().- CLI:
--timeoutand--max-body-sizereject zero/negative values (exit 2). asgion init --pyproject: malformedpyproject.tomlexits 2 with a clear message.
- Config: bare strings accepted as shorthand for single-element lists (
exclude_rules = "SEM-001"). - Config: warnings on unknown rule IDs, unmatched glob patterns, and unknown categories.
- CLI:
-H ": value"(empty header name) warns instead of silently skipping. check: format dispatch refactored via_render_checkhelper.
Full changelog: CHANGELOG.md
v0.6.0
Highlights
-
CI-native workflow -
--quiet,--strict, SARIF, JUnit, GitHub Action, pre-commit hook. Everything needed to run asgion in CI pipelines with zero friction. -
Custom HTTP requests - test any endpoint with
--method,-H,-d, and method prefixes:asgion check myapp:app --path "POST:/api/users" -H "Content-Type: application/json" -d '{}' -
SARIF & JUnit output -
--format sariffor GitHub Code Scanning / VS Code,--format junitfor Jenkins / GitLab CI / Azure DevOps. -
GitHub Action - one-line CI integration:
- uses: ack1d/asgion@v0 with: app: myapp:app args: --strict --min-severity warning
-
pre-commit hook - add to
.pre-commit-config.yaml:- repo: https://github.com/ack1d/asgion rev: v0.6.0 hooks: - id: asgion args: [myapp:app, --strict]
-
asgion init- generate.asgion.tomlconfig scaffold with commented-out defaults.
Features
checkandtrace:-q/--quiet- suppress stdout, exit code only.check:--select- rule allowlist with glob support (e.g.--select "HF-*,SEM-001").check:--layerfilter (repeatable) with granular values (http.fsm,http.semantic, etc.).check:--out FILE- write output to file (strips ANSI).checkandtrace:--timeout(default 5.0s) - configurable per-scope timeout.trace:--strict- exit 1 on violations, respects--min-severity.check: wall time in summary footer.- Config
paths: define default paths in config file. CLI--pathoverrides. Violation.scope_index+Inspector.violations_by_scope- per-request violation isolation.- Public API: re-export
deserialize,TraceViolation,TraceFormatError,TraceEnvironment.
Fixes
--exclude-rulesand--select: warning on unknown rule IDs and glob patterns matching no rules.rules RULE_ID --layer/--severitynow warns that filters are ignored when a specific rule is requested.
Breaking Changes
- Rule IDs renumbered: WF-009..WF-012 are now WF-008..WF-011 (dead WF-008 removed). Update any configs referencing old IDs.
Full changelog: CHANGELOG.md
v0.5.1
CLI hardening release. Bug fixes and UX improvements.
Fixes
asgion trace: app exceptions no longer crash the CLI — errors are reported per-scope, partial traces preserved.--exclude-rulesnow supports glob patterns (e.g.SEM-*), matching config file behavior.NO_COLOR=""correctly disables colors per no-color.org spec.- Trace violation markers colored by severity instead of all-red.
asgion rulesnow displays all 164 rules (Scope, Semantic, Extensions layers were missing).
Features
asgion rules HF-002— single rule lookup by ID with summary, hint, and layer.asgion trace --min-severity— filter violation markers by severity.asgion rules --format jsonincludestotal_availablewhen filtering.
Full changelog: CHANGELOG.md
v0.5.0
Highlights
-
Trace engine - record every
receive()/send()as structured traces
with nanosecond timestamps. Enable with a single flag:inspector = Inspector(app, trace=True) # ... drive the app ... record = inspector.traces[0] record.scope.method # "GET" record.scope.path # "/api/users" record.summary.ttfb_ns # time to first byte (ns)
Pluggable storage via
TraceStorageprotocol. Built-in:MemoryStorage
(default) andFileStorage(one JSON file per trace). -
Deterministic sampling -
sample_rateparameter on Inspector.
Hash-based, same endpoint always produces the same decision for a given rate. -
asgion traceCLI command - human-readable trace output with
color-coded phases, inline violation markers with severity, and per-record
breakdown:$ asgion trace myapp:appTRACE GET / (0.070ms, TTFB 0.042ms) 0.020ms send http.response.body 4 bytes ← HF-002 (error) 0.042ms send http.response.start 200 (+0.022ms) ← SEM-002 (info) 0.059ms send http.response.body 5 bytes (+0.016ms) Events: 3 | Violations: 2 (1 error, 1 info)--format jsonfor machine-readable output,--outfor file storage.
Fixes
-
CLI
check/trace: WS runner now sends awebsocket.receivemessage
before disconnect, avoiding app crashes on frameworks that expect data
after accept (e.g. Starlette). -
CLI
check: summary line now reports application errors instead of
showing "No violations found" when a scope raised an exception.
Full changelog: CHANGELOG.md
v0.4.0
Highlights
-
Inspectorclass - stateful wrapper that accumulates violations across
all connections. Unlikeinspect()(which returns a plain callable with no
way to read results),Inspectorkeeps a.violationslist you can assert
on after driving the app:inspector = Inspector(app) # ... drive the app with httpx, TestClient, etc. ... assert inspector.violations == []
Inspectoris also directly callable as an ASGI app. -
User-defined profiles - define reusable rule presets in
pyproject.toml
or.asgion.tomland reference them by name in config or CLI:[tool.asgion.profiles.ci] min_severity = "error" categories = ["http.fsm", "ws.fsm"]
asgion check myapp:app --profile ci
-
inspect()is now a thin wrapper aroundInspector- no behavior change,
fully backward-compatible.
Breaking Changes
-
InspectedApp(internal class inasgion.pytest_plugin) is replaced by
Inspector. If you annotated the return type ofasgi_inspectexplicitly,
update it:# before app: InspectedApp = asgi_inspect(my_app) # after from asgion import Inspector app: Inspector = asgi_inspect(my_app)
Existing test code that only accesses
.violationsor callsapp(...)works
without changes.
Full changelog: CHANGELOG.md
v0.3.0
What's new in 0.3.0
This release focuses on DX and configuration: rule filtering from pyproject.toml,
built-in profiles, WebSocket support in the CLI, and a full integration test suite
across FastAPI, Litestar, and Starlette.
Highlights
- Configuration -
[tool.asgion]inpyproject.tomlor.asgion.toml:
min_severity,include_rules,exclude_rules,categories, glob patterns ("SEM-*"). - Built-in profiles -
--profile strict / recommended / minimalin CLI,
orBUILTIN_PROFILES["recommended"]in Python API. - WebSocket checking -
asgion check myapp:app --path ws:/ws/chat.
Protocol prefix (ws:,wss:,http:,https:) determines scope type. - SEM-012 - CORS misconfiguration:
Access-Control-Allow-Origin: *+
Access-Control-Allow-Credentials: true(WARNING). - SEM-013 -
text/*response missingcharsetinContent-Type(INFO). - CLI deduplication - repeated violations across multiple
--pathvalues
are grouped in text output and collapsed in JSON (count,paths,summary.unique).
Breaking Changes
Rule IDs changed. All gaps in ID sequences eliminated — if you reference
rule IDs in config files or suppression lists, update them:
| Series | Old range | New range |
|---|---|---|
HE |
005, 010–028 | 004, 005–023 |
HF |
003–015 | 002–012 |
WE |
002–023 | 001–016 |
LE |
003, 004, 006 | 002, 003, 004 |
EX-001..008 |
(extension field rules) | HE-016..023 |
Layer names renamed in categories config:
"extension"->"http.extension""semantic"->"http.semantic"
--url renamed to --path in asgion check.
v0.2.0
Features
- 162 validation rules (was 75) across 12 layers — added Scope Fields,
Extensions, and Semantic layers - Scope field validation (layers 1-3): HTTP (HS-001..HS-028), WebSocket
(WS-001..WS-025), Lifespan (LS-001..LS-004) — validates all scope dict fields
per ASGI spec - Extension validator (layer 10): gate checks for Server Push, Zero Copy Send,
Path Send, Early Hints, Debug events (EX-001..EX-011) - Semantic validator (layer 11): duplicate headers, missing Content-Type,
Content-Length mismatch, Set-Cookie security, disconnect tracking,
TTFB/lifecycle/body-size thresholds (SEM-001..SEM-011) - pytest plugin (
pip install asgion[pytest]):asgi_inspectfixture — wrap ASGI apps with validation in tests@pytest.mark.asgi_validatemarker — auto-check violations at teardown--asgi-strict/--asgi-min-severityCLI flags
- Additional FSM rules: HF-001, HF-009, HF-010, HF-012, WF-011, LF-009, LF-010
Internal
- Scope checks compiled from declarative
ProtocolSpec.scope_checks - Configurable perf thresholds (TTFB, lifecycle, body size, chunk fragmentation)
v0.1.0
Features
- 75 validation rules across 7 layers: General, HTTP Events, HTTP FSM,
WebSocket Events, WebSocket FSM, Lifespan Events, Lifespan FSM inspect()wrapper - wrap any ASGI app with zero-config protocol validation- Declarative spec engine - event schemas compiled at import time from
protocol specifications - State machine validators - HTTP, WebSocket, and Lifespan FSM enforcement
- CLI (
asgion check,asgion rules) — check apps from the command line - JSON output - machine-readable violation reports
- Real-time callbacks -
on_violationfor streaming violation detection - Rule suppression -
exclude_rulesto skip specific checks - Path exclusion -
exclude_pathsto skip validation for health checks, etc. - Strict mode -
ASGIProtocolErrorraised on any violation - Zero runtime dependencies - pure Python 3.12+