Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
4c33601
fix(ws): verify HMAC on signed_payload, dispatch from trusted source …
maltsev-dev Jun 18, 2026
5019615
Wip/working tree 2026 06 18 (#3)
maltsev-dev Jun 18, 2026
7c125a8
fix(ci): add langchain-core to [dev] so test collection passes (#4)
maltsev-dev Jun 18, 2026
c2d5606
chore(ci): fix publish.yml (correct project name, trusted-publishing …
maltsev-dev Jun 18, 2026
946719e
fix(ci): add Callable to typing imports in runtime.py (#6)
maltsev-dev Jun 18, 2026
fceae83
fix(ci): ruff ignore list for pre-existing violations (#7)
maltsev-dev Jun 18, 2026
53f5bed
Fix/ci runtime callable import (#8)
maltsev-dev Jun 18, 2026
91fa706
Fix/ci runtime callable import (#9)
maltsev-dev Jun 18, 2026
0bf5625
Fix/ci runtime callable import (#10)
maltsev-dev Jun 18, 2026
bb8b946
Fix/ws byte mismatch verify signed payload (#11)
maltsev-dev Jun 18, 2026
43072c2
fix(ci): add langchain-core to [dev] so test collection passes (#12)
maltsev-dev Jun 18, 2026
2281622
Fix/ws byte mismatch verify signed payload (#14)
maltsev-dev Jun 18, 2026
cc08b5e
chore: untrack analyze.md (keep on disk, project-local working notes)…
maltsev-dev Jun 18, 2026
bb349d5
docs: add logo and shields.io badges to README (#18)
maltsev-dev Jun 19, 2026
bbdffb9
docs: drop logo, switch badges to style=flat (#19)
maltsev-dev Jun 19, 2026
b296b40
ci: pass CODECOV_TOKEN explicitly to codecov-action (#21)
maltsev-dev Jun 19, 2026
1156eca
fix: P0 security/stability hardening bundle (#22)
maltsev-dev Jun 19, 2026
3c4b212
Fix/p0 security stability bundle (#23)
maltsev-dev Jun 19, 2026
8535ef7
Version bump/0.5.2 (#24)
maltsev-dev Jun 19, 2026
ce7f06f
Test/coverage improvements 0.5.2 (#25)
maltsev-dev Jun 19, 2026
4c7b3c8
test: bump coverage 84.52% and harden @sensitive / /track/batch / cov…
maltsev-dev Jun 20, 2026
d1c8777
Feat/0.5.2 coverage and p0 hardening (#27)
maltsev-dev Jun 21, 2026
0bc5bf2
Update README.md to left-align paragraphs (#28)
maltsev-dev Jun 22, 2026
27c5dc5
release: 0.6.0 — fail-CLOSED policy fetch, CSRF Bearer bypass, WS HMA…
maltsev-dev Jun 23, 2026
56661b1
feat(exceptions): introduce Layer-1 structured exception hierarchy (#31)
maltsev-dev Jun 24, 2026
160868e
feat(observability): Layer-2 on_error hooks, Layer-3 status() introsp…
maltsev-dev Jun 24, 2026
a349407
release: 0.6.1 — Layer-1/2/3 ('give the user a chance') (#33)
maltsev-dev Jun 24, 2026
cf725cc
release: 0.7.0 — thin-client refactor (#34)
maltsev-dev Jun 26, 2026
97f2040
Release/0.7.6 (#35)
maltsev-dev Jun 27, 2026
642b1a7
release: 0.7.7 — forward real model + tools to /gate pre-flight (T4) …
maltsev-dev Jun 27, 2026
bc9bc10
release: 0.7.8 — fail-loud on deprecated surface (#38)
maltsev-dev Jun 28, 2026
712d2be
release: 0.8.0 — SDK wire-format audit (model/provider extraction) (#39)
maltsev-dev Jun 28, 2026
fe92fb9
fix: 0.8.2 — coverage wire-shape (metadata nesting) + model fallback …
maltsev-dev Jun 29, 2026
0fc0183
release: 0.8.2 — coverage metadata nesting + model fallback (#41)
maltsev-dev Jun 29, 2026
021ae5d
fix: 0.8.3 — close silent zero-billing across langgraph + init-orderi…
maltsev-dev Jun 29, 2026
94f8879
release: 0.8.3 — langgraph model fallback + init-ordering patch + fai…
maltsev-dev Jun 29, 2026
921e917
feat(0.9.0): remove per-process coverage counters; add nullrun.shutdo…
maltsev-dev Jun 29, 2026
d0397ef
release: 0.9.0 — coverage counters removed, nullrun.shutdown() added …
maltsev-dev Jun 29, 2026
2f5f508
fix(0.9.1): unified LLM-call fingerprint collapses httpx + langchain …
maltsev-dev Jun 29, 2026
c5d2229
release(0.10.0): add nullrun.handle / guarded / init_or_die (#47)
maltsev-dev Jul 2, 2026
a9e6ab7
release(0.11.0): handle/guarded/init_or_die + v3 wire contract (#48)
maltsev-dev Jul 3, 2026
a684abc
fix(sdk): make Author field non-empty + v3 capability probe (#49)
maltsev-dev Jul 3, 2026
c0b8a5d
fix(build): align pyproject.toml version with __version__.py (0.11.0 …
maltsev-dev Jul 3, 2026
70466d5
release(0.12.1): wire server-minted execution_id through /check -> /t…
maltsev-dev Jul 4, 2026
2aab9e2
Release/0.12.2 (#52)
maltsev-dev Jul 4, 2026
399d0a1
release(0.13.0): drift-fixes — idempotency_key on /track + status_cod…
maltsev-dev Jul 5, 2026
f55691e
release(0.13.1): drift-fixes — B1 check_v3 + B3 chain_end + M3 approx…
maltsev-dev Jul 5, 2026
e5a154c
release(0.13.2): per-file mypy overrides + _singleton / _registry spl…
maltsev-dev Jul 6, 2026
2043e09
Release/0.13.1 (#57)
maltsev-dev Jul 7, 2026
dc40aec
fix(instrumentation): all 4 usage sources are 'if' not 'elif' (#59)
maltsev-dev Jul 8, 2026
9449b24
release(0.13.5): perf — cancellable flush sleep + CI hygiene (#60)
maltsev-dev Jul 8, 2026
ca04cc6
chore(release): 0.13.6 — multi-agent span attachment (parent_trace_id…
maltsev-dev Jul 11, 2026
08cd68e
fix(tests): WAL-pinning for all inline NullRunRuntime creations (#63)
maltsev-dev Jul 11, 2026
273c2d4
fix(sdk): wire parent_trace_id end-to-end on /track v3 + legacy batch…
maltsev-dev Jul 12, 2026
d4d7771
fix(sdk): parent_trace_id contextvar ALWAYS overrides caller-set (0.1…
maltsev-dev Jul 12, 2026
b9b8850
release(0.13.9): crewai 1.15 event bus + gate_cache re-capture (#67)
maltsev-dev Jul 13, 2026
0474ee1
release(0.13.10): vendor extractor edge cases (#68)
maltsev-dev Jul 14, 2026
3d72e2a
release(0.13.11): vendor-extractor fields on v3 /track (#69)
maltsev-dev Jul 14, 2026
392720a
ci: restore xdist coverage reporting (#70)
maltsev-dev Jul 20, 2026
9366c88
ci: Sprint 0 — coverage-testability + release 0.13.12 (#71)
maltsev-dev Jul 21, 2026
1fd4722
ci: isolate NULLRUN_WAL_PATH per test (CI flakefix) (#72)
maltsev-dev Jul 21, 2026
8255d7a
Coverage/sprint 0 flakefix (#73)
maltsev-dev Jul 21, 2026
566b952
fix(sdk): read approval_timeout_seconds from /gate response (Разрыв 1…
maltsev-dev Jul 21, 2026
aad4d91
chore(release): 0.13.13 — Разрыв 1c SDK sync (#75)
maltsev-dev Jul 21, 2026
b7af455
chore(release): 0.14.0 — hardening pass on the money contract (#76)
maltsev-dev Jul 24, 2026
aa87e5b
chore(release): 0.14.1 — Decimal JSON serialization patch (#77)
maltsev-dev Jul 24, 2026
34ab8ac
fix: post-0.14.1 flakefix + strict-mode init_or_die (#78)
maltsev-dev Jul 24, 2026
66ed805
chore(release): 0.14.2 - three runtime/transport hotfixes (#79)
maltsev-dev Jul 25, 2026
bc34d61
chore(release): 0.14.4 — ToolParameters Approval Rules wire contract …
maltsev-dev Jul 27, 2026
d111926
chore(release): 0.14.5 — MCP metadata and tool arguments (#81)
maltsev-dev Aug 1, 2026
d741221
chore(release): 0.14.6 — CI coverage-job flakefix + actions.cooldown …
maltsev-dev Aug 1, 2026
1ef489b
chore(release): 0.14.7 — init contract: strip whitespace from api_key…
maltsev-dev Aug 4, 2026
7108ec1
fix(test): widen release_after_ms + bump reruns on approval-timeout f…
maltsev-dev Aug 4, 2026
3109863
fix(sdk): DEF-ARFLOW-TOOLNAME-01 surface backend error_code on execut…
maltsev-dev Aug 5, 2026
29fe246
docs(sdk): align README + pyproject with current positioning
maltsev-dev Aug 5, 2026
6a3dca7
update texts
maltsev-dev Aug 6, 2026
df23134
fix(sdk): per-event idempotency_key to prevent IDEMPOTENCY_KEY_MISMAT…
maltsev-dev Aug 6, 2026
fc0fed2
feat(sdk): Execution Graph v0 - parent_execution_id forward + capabil…
maltsev-dev Aug 6, 2026
a69b57e
fix(sdk): v3.38 wire-drift close — capabilities route, API_KEY_* code…
maltsev-dev Aug 7, 2026
1e3f8ac
chore(release): 0.14.9 - v3.38 wire-drift close (capabilities route, …
maltsev-dev Aug 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Codecov configuration for nullrun-sdk-python.
#
# The SDK's Phase 7 / 0.6.0 hardening surface adds new fail-CLOSED paths
# (Policy.strict_local, _last_good_policy cache, FIX-F3 Bearer bypass,
# FIX-F4 WS_HMAC_IDENTITY_FIELD). Several of these are exercised by the
# `tests/test_integration_contract.py` contract suite, but the patch
# coverage percentage still dips below the master base coverage when the
# cumulative diff includes the large `tests/test_integration_contract.py`
# addition (675 new lines, mostly pinning contracts that don't run live
# network calls).
#
# We keep:
# - project coverage threshold at 80% (was the long-standing floor)
# - patch coverage at 70% (relaxed from the default auto-target which
# uses master base coverage as the bar — too strict for a hardening
# release whose diff is dominated by contract-pinning tests)
#
# Coverage gate at the project level is also enforced by pyproject.toml's
# `tool.coverage.report.fail_under = 80`; this file is purely about the
# GitHub-check status that Codecov posts to PRs.

coverage:
status:
project:
default:
target: 80%
threshold: 1%
if_ci_failed: error
patch:
default:
target: 70%
threshold: 5%
if_ci_failed: error
50 changes: 45 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ on:
jobs:
test:
runs-on: ubuntu-latest
permissions:
contents: read
# 2026-07-08: fail-fast on the first matrix failure instead of
# wasting runner minutes on the remaining Python versions when
# the suite is already red. Speed gain is per-run, not per-test.
strategy:
fail-fast: true
matrix:
python: ["3.10", "3.11", "3.12"]

Expand All @@ -20,14 +26,33 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
# Cache pip's download cache keyed on the lock-relevant
# surfaces of pyproject.toml. Skips the ~60-90s cold
# install on warm caches; the action also reuses the
# cache across matrix legs when the key matches.
cache: "pip"
cache-dependency-path: pyproject.toml

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
# xdist ships in the dev tree already; pin it explicitly so
# a future deps churn can't drop it without breaking CI.
# ``pytest-rerunfailures`` is used by Sprint 0 (coverage) on
# a single rare-flaky test under pytest-xdist on linux
# (thread-scheduling race in the approval-wait fixture);
# pin it for the same reason.
pip install -e ".[dev]" "pytest-xdist>=3.6" "pytest-rerunfailures>=14.0,<16.0"

- name: Run tests
run: pytest
# `-n auto` lets xdist pick a worker count from the runner's
# CPU count. With the transport cancellable-sleep fix the
# 5s-per-shutdown multiplier is gone, and xdist plus the
# existing respx-based mocking keeps the per-test wall clock
# near single-thread baseline (no shared state between
# workers — ``reset_runtime`` autouse fixture in conftest
# is per-process by construction under xdist).
run: pytest -n auto --durations=20

- name: Run ruff
run: ruff check src/
Expand All @@ -37,12 +62,27 @@ jobs:

coverage:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -e ".[dev]"
- run: coverage run -m pytest
cache: "pip"
cache-dependency-path: pyproject.toml
- run: pip install -e ".[dev]" "pytest-xdist>=3.6" "pytest-cov>=5.0" "pytest-rerunfailures>=14.0,<16.0"
# Single Python leg for coverage — multi-version coverage
# reports don't add signal and double the runner time. 3.12
# is the modern floor for typing-only changes.
# pytest-cov starts coverage in every xdist worker and combines
# the data before producing the report. ``coverage run`` only
# traced the coordinator process, so every parallel run uploaded
# 0 hits even though all tests passed.
- run: pytest -n auto --cov=src/nullrun --cov-branch --cov-report=xml:coverage.xml --cov-report=term
- uses: codecov/codecov-action@v4
if: always()
if: always()
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.xml
fail_ci_if_error: true
67 changes: 67 additions & 0 deletions .github/workflows/publish-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: publish-test

on:
workflow_dispatch:

jobs:
test:
name: Run tests
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
cache-dependency-path: pyproject.toml

- name: Install dependencies
run: pip install -e ".[dev]" "pytest-xdist>=3.6"

- name: Run tests
run: pytest tests/ -v -n auto

publish:
name: Build and publish to TestPyPI
needs: test
runs-on: ubuntu-latest
environment:
name: testpypi
url: https://test.pypi.org/project/nullrun
permissions:
id-token: write

steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Build
run: |
pip install --upgrade build
python -m build

- name: Check dist
run: |
pip install twine
twine check dist/*

- name: Publish to TestPyPI (Trusted Publishing)
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
# TestPyPI rejects re-uploads of the same wheel hash with
# HTTP 400 "File already exists". `skip-existing` makes
# re-runs of the same SHA a no-op (matching twine's
# --skip-existing behaviour). Production PyPI cannot
# overwrite anyway, so this flag is harmless there too.
skip-existing: true
40 changes: 18 additions & 22 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
name: Publish to PyPI
name: publish

on:
push:
tags:
- 'v*' # триггер только по тегу: git tag v0.1.0 && git push --tags
- "v*"
workflow_dispatch:

jobs:
test:
name: Run tests
runs-on: ubuntu-latest
permissions:
contents: read
# 2026-07-08: parallel matrix kept (PyPI publish is a one-shot
# event and the runner is already paid for) but pip cache
# brought in for parity with ci.yml.
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]
Expand All @@ -19,25 +25,24 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
cache-dependency-path: pyproject.toml

- name: Install dependencies
run: |
pip install -e ".[dev]"
run: pip install -e ".[dev]" "pytest-xdist>=3.6"

- name: Run tests
run: pytest tests/ -v
run: pytest tests/ -v -n auto

publish:
name: Build and publish
needs: test # сначала все тесты зелёные — потом публикация
needs: test
runs-on: ubuntu-latest

environment:
name: pypi
url: https://pypi.org/p/nullrun-sdk

url: https://pypi.org/p/nullrun
permissions:
id-token: write # для trusted publishing (без токена, рекомендуется PyPI)
id-token: write

steps:
- uses: actions/checkout@v4
Expand All @@ -46,24 +51,15 @@ jobs:
with:
python-version: "3.11"

- name: Build package
- name: Build
run: |
pip install hatchling build
pip install --upgrade build
python -m build

- name: Check dist contents
- name: Check dist
run: |
pip install twine
twine check dist/*

# Вариант 1: Trusted Publishing (рекомендуется, не нужен токен)
# Настроить на pypi.org: Account → Publishing → Add publisher
# Publisher: GitHub, repo: maltsev-dev/nullrun-sdk, workflow: publish.yml
- name: Publish to PyPI (Trusted Publishing)
uses: pypa/gh-action-pypi-publish@release/v1

# Вариант 2: API токен (раскомментируй если не используешь Trusted Publishing)
# - name: Publish to PyPI (API token)
# uses: pypa/gh-action-pypi-publish@release/v1
# with:
# password: ${{ secrets.PYPI_API_TOKEN }}
75 changes: 75 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# Virtual environments
.venv/
venv/
env/
ENV/
env.bak/
venv.bak/
.python-version

# Test / coverage / type / lint caches
.pytest_cache/
.coverage
.coverage.*
htmlcov/
coverage.xml
.tox/
.nox/
.mypy_cache/
.ruff_cache/
.hypothesis/

# IDE / editor
.idea/
.vscode/
*.swp
*.swo
*~
.DS_Store

# Secrets / local config
.env
.env.local
.env.*.local
*.pem
*.key
.venv-ci

# Claude Code / claude-flow project-local state
.claude/
.claude-flow/
src/**/.claude-flow/
CLAUDE.md

# Project-local working notes (kept on disk, not in VCS)
analyze.md
docs/integration-baseline-2026-06-19.md
audit.md
docs/postman/
.hermes/
Loading