bront 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. bront-0.1.0/.dockerignore +8 -0
  2. bront-0.1.0/.env.example +9 -0
  3. bront-0.1.0/.github/workflows/ci.yml +102 -0
  4. bront-0.1.0/.gitignore +12 -0
  5. bront-0.1.0/.python-version +1 -0
  6. bront-0.1.0/Dockerfile +18 -0
  7. bront-0.1.0/LICENSE +21 -0
  8. bront-0.1.0/PKG-INFO +171 -0
  9. bront-0.1.0/README.md +149 -0
  10. bront-0.1.0/compose.scenarios.yaml +20 -0
  11. bront-0.1.0/compose.triton.yaml +37 -0
  12. bront-0.1.0/compose.yaml +65 -0
  13. bront-0.1.0/deploy/kubernetes/fallback.yaml +65 -0
  14. bront-0.1.0/deploy/kubernetes/gateway.yaml +81 -0
  15. bront-0.1.0/deploy/kubernetes/kind.yaml +5 -0
  16. bront-0.1.0/deploy/kubernetes/kustomization.yaml +19 -0
  17. bront-0.1.0/deploy/kubernetes/namespace.yaml +4 -0
  18. bront-0.1.0/deploy/kubernetes/observability/dashboards.yml +9 -0
  19. bront-0.1.0/deploy/kubernetes/observability/datasources.yml +11 -0
  20. bront-0.1.0/deploy/kubernetes/observability/gateway.json +384 -0
  21. bront-0.1.0/deploy/kubernetes/observability/grafana.yaml +62 -0
  22. bront-0.1.0/deploy/kubernetes/observability/kustomization.yaml +13 -0
  23. bront-0.1.0/deploy/kubernetes/observability/prometheus.yaml +71 -0
  24. bront-0.1.0/deploy/kubernetes/observability/prometheus.yml +23 -0
  25. bront-0.1.0/deploy/kubernetes/run-job.yaml +37 -0
  26. bront-0.1.0/deploy/kubernetes/triton.yaml +88 -0
  27. bront-0.1.0/deploy/prometheus/prometheus.yml +7 -0
  28. bront-0.1.0/deploy/toxiproxy/proxies.json +8 -0
  29. bront-0.1.0/deploy/triton/kustomization.yaml +8 -0
  30. bront-0.1.0/deploy/triton/models/double/1/model.onnx +0 -0
  31. bront-0.1.0/deploy/triton/models/double/config.pbtxt +11 -0
  32. bront-0.1.0/docs/architecture.md +68 -0
  33. bront-0.1.0/docs/comparisons.md +259 -0
  34. bront-0.1.0/docs/external-endpoints.md +206 -0
  35. bront-0.1.0/docs/kubernetes.md +229 -0
  36. bront-0.1.0/docs/observability.md +82 -0
  37. bront-0.1.0/docs/proposals/inference-reliability.md +44 -0
  38. bront-0.1.0/docs/reports.md +136 -0
  39. bront-0.1.0/docs/scenarios.md +222 -0
  40. bront-0.1.0/docs/triton.md +140 -0
  41. bront-0.1.0/examples/comparison/baseline.toml +30 -0
  42. bront-0.1.0/examples/comparison/limits.toml +12 -0
  43. bront-0.1.0/examples/gateway/cases.jsonl +1 -0
  44. bront-0.1.0/examples/gateway/suite.toml +16 -0
  45. bront-0.1.0/examples/http-json/cases.jsonl +3 -0
  46. bront-0.1.0/examples/http-json/server.py +53 -0
  47. bront-0.1.0/examples/http-json/suite.toml +16 -0
  48. bront-0.1.0/examples/kubernetes/cases.jsonl +1 -0
  49. bront-0.1.0/examples/kubernetes/suite.toml +18 -0
  50. bront-0.1.0/examples/scenarios/kubernetes-restart.toml +25 -0
  51. bront-0.1.0/examples/scenarios/kubernetes-scale-zero.toml +29 -0
  52. bront-0.1.0/examples/scenarios/proxy-delay.toml +27 -0
  53. bront-0.1.0/examples/scenarios/proxy-outage.toml +26 -0
  54. bront-0.1.0/pyproject.toml +61 -0
  55. bront-0.1.0/scripts/build_triton_model.py +31 -0
  56. bront-0.1.0/scripts/load_kind_images.py +36 -0
  57. bront-0.1.0/scripts/smoke_compose.py +81 -0
  58. bront-0.1.0/scripts/smoke_external.py +233 -0
  59. bront-0.1.0/scripts/smoke_kubernetes.py +89 -0
  60. bront-0.1.0/scripts/smoke_triton.py +102 -0
  61. bront-0.1.0/src/bront/__init__.py +1 -0
  62. bront-0.1.0/src/bront/artifacts.py +30 -0
  63. bront-0.1.0/src/bront/checks.py +104 -0
  64. bront-0.1.0/src/bront/cli.py +21 -0
  65. bront-0.1.0/src/bront/compare_cli.py +81 -0
  66. bront-0.1.0/src/bront/comparison_models.py +83 -0
  67. bront-0.1.0/src/bront/comparisons.py +231 -0
  68. bront-0.1.0/src/bront/evidence.py +297 -0
  69. bront-0.1.0/src/bront/faults.py +66 -0
  70. bront-0.1.0/src/bront/html_reports.py +474 -0
  71. bront-0.1.0/src/bront/kubernetes_scenarios.py +225 -0
  72. bront-0.1.0/src/bront/measurement.py +69 -0
  73. bront-0.1.0/src/bront/provenance.py +71 -0
  74. bront-0.1.0/src/bront/proxy_scenarios.py +81 -0
  75. bront-0.1.0/src/bront/reference/__init__.py +1 -0
  76. bront-0.1.0/src/bront/reference/adapters.py +95 -0
  77. bront-0.1.0/src/bront/reference/backends.py +99 -0
  78. bront-0.1.0/src/bront/reference/circuit_breaker.py +62 -0
  79. bront-0.1.0/src/bront/reference/config.py +17 -0
  80. bront-0.1.0/src/bront/reference/draining.py +30 -0
  81. bront-0.1.0/src/bront/reference/gateway.py +78 -0
  82. bront-0.1.0/src/bront/reference/metrics.py +78 -0
  83. bront-0.1.0/src/bront/reference/mock_backend.py +44 -0
  84. bront-0.1.0/src/bront/reference/schemas.py +21 -0
  85. bront-0.1.0/src/bront/report_cli.py +32 -0
  86. bront-0.1.0/src/bront/report_styles.py +48 -0
  87. bront-0.1.0/src/bront/results.py +81 -0
  88. bront-0.1.0/src/bront/run_cli.py +67 -0
  89. bront-0.1.0/src/bront/runs.py +224 -0
  90. bront-0.1.0/src/bront/scenario_models.py +92 -0
  91. bront-0.1.0/src/bront/scenarios.py +181 -0
  92. bront-0.1.0/src/bront/series.py +79 -0
  93. bront-0.1.0/src/bront/suites.py +223 -0
  94. bront-0.1.0/src/bront/targets.py +72 -0
  95. bront-0.1.0/src/bront/validation.py +124 -0
  96. bront-0.1.0/tests/test_circuit_breaker.py +48 -0
  97. bront-0.1.0/tests/test_cli.py +29 -0
  98. bront-0.1.0/tests/test_comparisons.py +323 -0
  99. bront-0.1.0/tests/test_external_runs.py +364 -0
  100. bront-0.1.0/tests/test_gateway.py +374 -0
  101. bront-0.1.0/tests/test_html_reports.py +238 -0
  102. bront-0.1.0/tests/test_kubernetes_scenarios.py +297 -0
  103. bront-0.1.0/tests/test_measurement.py +33 -0
  104. bront-0.1.0/tests/test_metrics.py +55 -0
  105. bront-0.1.0/tests/test_mock_backend.py +18 -0
  106. bront-0.1.0/tests/test_scenarios.py +323 -0
  107. bront-0.1.0/tests/test_series.py +183 -0
  108. bront-0.1.0/tests/test_triton_model.py +23 -0
  109. bront-0.1.0/tests/test_validation.py +58 -0
  110. bront-0.1.0/uv.lock +727 -0
@@ -0,0 +1,8 @@
1
+ .git
2
+ .venv
3
+ .env
4
+ __pycache__
5
+ .pytest_cache
6
+ .ruff_cache
7
+ tests
8
+ docs
@@ -0,0 +1,9 @@
1
+ # Copy to .env for gateway runs outside Docker Compose.
2
+ BRONT_PRIMARY_URL=http://127.0.0.1:8001
3
+ BRONT_FALLBACK_URL=http://127.0.0.1:8002
4
+ # Set to triton when running the gateway locally against a Triton primary.
5
+ # compose.triton.yaml sets this automatically for its gateway container.
6
+ BRONT_PRIMARY_PROTOCOL=mock
7
+ BRONT_REQUEST_TIMEOUT_SECONDS=1
8
+ BRONT_FAILURE_THRESHOLD=3
9
+ BRONT_RECOVERY_TIMEOUT_SECONDS=10
@@ -0,0 +1,102 @@
1
+ name: CI
2
+ on: [push, pull_request]
3
+
4
+ jobs:
5
+ check:
6
+ runs-on: ubuntu-latest
7
+ steps:
8
+ - uses: actions/checkout@v4
9
+ - uses: astral-sh/setup-uv@v6
10
+ with:
11
+ version: "0.11.21"
12
+ enable-cache: true
13
+ - run: uv sync --frozen
14
+ - run: uv run ruff check .
15
+ - run: uv run ruff format --check .
16
+ - run: uv run ty check --python-version 3.12
17
+ - run: docker compose config --quiet
18
+ - run: docker compose -f compose.triton.yaml config --quiet
19
+ - run: docker compose up --build --wait --wait-timeout 120
20
+ - run: docker compose exec -T gateway /app/.venv/bin/python --version
21
+ - run: uv run python scripts/smoke_compose.py
22
+ - name: Compose logs
23
+ if: failure()
24
+ run: docker compose logs --no-color
25
+ - name: Stop Compose services
26
+ if: always()
27
+ run: docker compose down
28
+
29
+ scenarios:
30
+ runs-on: ubuntu-latest
31
+ timeout-minutes: 10
32
+ env:
33
+ COMPOSE_FILE: compose.yaml:compose.scenarios.yaml
34
+ COMPOSE_PROJECT_NAME: bront-scenarios-ci
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+ - uses: astral-sh/setup-uv@v6
38
+ with:
39
+ version: "0.11.21"
40
+ enable-cache: true
41
+ - run: uv sync --frozen
42
+ - run: docker compose config --quiet
43
+ - name: Start scenario stack
44
+ run: docker compose up --build --wait --wait-timeout 120
45
+ - name: Run reusable proxy scenarios
46
+ run: |
47
+ uv run --frozen bront run examples/scenarios/proxy-outage.toml --output reports/scenarios/proxy-outage.json
48
+ uv run --frozen bront run examples/scenarios/proxy-delay.toml --output reports/scenarios/proxy-delay.json
49
+ - name: Render scenario HTML
50
+ if: always() && hashFiles('reports/scenarios/*.json') != ''
51
+ run: |
52
+ for source in reports/scenarios/*.json; do
53
+ uv run --frozen bront report "$source" --output "${source%.json}.html"
54
+ done
55
+ - name: Upload scenario reports
56
+ if: always() && hashFiles('reports/scenarios/*.json') != ''
57
+ uses: actions/upload-artifact@v7
58
+ with:
59
+ name: scenario-reports
60
+ path: reports/scenarios/
61
+ if-no-files-found: error
62
+ retention-days: 14
63
+ - name: Scenario Compose logs
64
+ if: failure()
65
+ run: docker compose logs --no-color
66
+ - name: Stop scenario services
67
+ if: always()
68
+ run: docker compose down
69
+
70
+ python-compatibility:
71
+ runs-on: ubuntu-latest
72
+ timeout-minutes: 10
73
+ strategy:
74
+ fail-fast: false
75
+ matrix:
76
+ python: ["3.12", "3.13", "3.14"]
77
+ env:
78
+ UV_PYTHON: ${{ matrix.python }}
79
+ steps:
80
+ - uses: actions/checkout@v4
81
+ - uses: astral-sh/setup-uv@v6
82
+ with:
83
+ version: "0.11.21"
84
+ enable-cache: true
85
+ - run: uv sync --frozen --python "${{ matrix.python }}"
86
+ - run: uv run --frozen pytest
87
+ - name: Build and install the standalone package
88
+ run: |
89
+ uv build
90
+ uv venv --python "${{ matrix.python }}" "$RUNNER_TEMP/bront-core"
91
+ uv pip install --python "$RUNNER_TEMP/bront-core/bin/python" dist/bront-*.whl
92
+ "$RUNNER_TEMP/bront-core/bin/python" -c "import importlib.util; import bront.cli; assert importlib.util.find_spec('fastapi') is None"
93
+ - name: Verify HTTP runs, comparisons, interruption handling, and HTML reports
94
+ run: '"$RUNNER_TEMP/bront-core/bin/python" scripts/smoke_external.py'
95
+ - name: Upload external endpoint reports
96
+ if: always() && hashFiles('reports/external/*.json') != ''
97
+ uses: actions/upload-artifact@v7
98
+ with:
99
+ name: external-endpoint-reports-py${{ matrix.python }}
100
+ path: reports/external/
101
+ if-no-files-found: error
102
+ retention-days: 14
bront-0.1.0/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.py[cod]
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ .coverage
7
+ htmlcov/
8
+ dist/
9
+ *.egg-info/
10
+ .env
11
+ .DS_Store
12
+ /reports/
@@ -0,0 +1 @@
1
+ 3.14
bront-0.1.0/Dockerfile ADDED
@@ -0,0 +1,18 @@
1
+ FROM python:3.14-slim AS cli
2
+
3
+ ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 UV_PYTHON_DOWNLOADS=never
4
+ WORKDIR /app
5
+ RUN pip install --no-cache-dir uv==0.11.21
6
+ COPY .python-version pyproject.toml uv.lock README.md ./
7
+ COPY src ./src
8
+ RUN uv sync --frozen --no-dev --no-editable
9
+ RUN useradd --create-home --uid 10001 app
10
+ USER app
11
+ CMD ["/app/.venv/bin/bront", "--help"]
12
+
13
+ FROM cli AS reference
14
+ USER root
15
+ RUN uv sync --frozen --no-dev --no-editable --extra reference
16
+ USER app
17
+ EXPOSE 8000
18
+ CMD ["/app/.venv/bin/uvicorn", "bront.reference.gateway:app", "--host", "0.0.0.0", "--port", "8000"]
bront-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Frank Lee
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
bront-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,171 @@
1
+ Metadata-Version: 2.5
2
+ Name: bront
3
+ Version: 0.1.0
4
+ Summary: Validate and measure inference endpoints, with a reference failover gateway
5
+ License-Expression: MIT
6
+ License-File: LICENSE
7
+ Classifier: Programming Language :: Python :: 3 :: Only
8
+ Classifier: Programming Language :: Python :: 3.12
9
+ Classifier: Programming Language :: Python :: 3.13
10
+ Classifier: Programming Language :: Python :: 3.14
11
+ Requires-Python: >=3.12
12
+ Requires-Dist: httpx<1,>=0.28
13
+ Requires-Dist: pydantic<3,>=2.10
14
+ Requires-Dist: rich<16,>=14
15
+ Requires-Dist: typer<1,>=0.20
16
+ Provides-Extra: reference
17
+ Requires-Dist: fastapi<1,>=0.115; extra == 'reference'
18
+ Requires-Dist: prometheus-client<1,>=0.21; extra == 'reference'
19
+ Requires-Dist: pydantic-settings<3,>=2.7; extra == 'reference'
20
+ Requires-Dist: uvicorn<1,>=0.34; extra == 'reference'
21
+ Description-Content-Type: text/markdown
22
+
23
+ # Bront
24
+
25
+ Repeatable reliability tests and release evidence for inference deployments.
26
+ Bront checks an existing HTTP JSON endpoint against representative inputs,
27
+ correctness assertions, and latency/error limits. Add fault or rollout scenarios,
28
+ compare repeated baseline and candidate runs, and share an offline HTML report.
29
+ Your service does not need to adopt Bront's reference gateway.
30
+
31
+ ## Quickstart
32
+
33
+ Requires Python 3.12 or newer; tested on CPython 3.12, 3.13, and 3.14. From this checkout:
34
+
35
+ ```sh
36
+ uv sync --frozen
37
+ uv run python examples/http-json/server.py
38
+ ```
39
+
40
+ In another terminal:
41
+
42
+ ```sh
43
+ uv run bront run examples/http-json/suite.toml --output reports/run.json
44
+ uv run bront report reports/run.json --output reports/review.html
45
+ ```
46
+
47
+ Open `reports/review.html` in a browser. The standalone example requires no Docker,
48
+ Kubernetes, Triton, or backend-specific status API.
49
+
50
+ For your own service, configure the URL, JSONL input cases, expected outputs,
51
+ workload, and assertions in a TOML suite. Read the
52
+ [external endpoint guide](docs/external-endpoints.md) for the supported contract.
53
+ Credentials can reference environment variables; raw payloads and credential values
54
+ are excluded from normal reports.
55
+
56
+ ## Release workflow
57
+
58
+ ```sh
59
+ uv run bront run baseline.toml --repeat 3 --output reports/baseline.json
60
+ uv run bront run candidate.toml --repeat 3 --output reports/candidate.json
61
+ uv run bront compare reports/baseline.json reports/candidate.json \
62
+ --policy limits.toml --output reports/comparison.json
63
+ uv run bront report reports/comparison.json --output reports/comparison.html
64
+ ```
65
+
66
+ Record deployment metadata and explicitly allow the intended change in the
67
+ comparison policy. Bront checks experiment compatibility before evaluating
68
+ regressions. Missing context, incomplete execution, or insufficient repeat evidence
69
+ cannot produce a passing comparison. Observed variation is not a statistical
70
+ significance test.
71
+
72
+ | Command | Purpose |
73
+ | --- | --- |
74
+ | `bront run` | Execute a suite, retain samples, and evaluate release assertions. |
75
+ | `bront compare` | Compare compatible repeated experiments against an explicit policy. |
76
+ | `bront report` | Render recorded evidence as self-contained HTML with JSON downloads. |
77
+
78
+ `run` and `compare` return 0 for passing evidence, 1 for failed checks, and 2 for
79
+ execution/configuration problems or inconclusive/incompatible comparisons.
80
+ Interrupted runs use exit 130 and retain partial evidence. `report` returns 0 when
81
+ rendering succeeds; it does not replace a release gate.
82
+
83
+ ## Guides
84
+
85
+ - [External endpoints and response validation](docs/external-endpoints.md)
86
+ - [Proxy faults and Kubernetes scenarios](docs/scenarios.md)
87
+ - [Repeated runs and release comparisons](docs/comparisons.md)
88
+ - [Offline HTML reports](docs/reports.md)
89
+ - [Architecture](docs/architecture.md)
90
+ - [Roadmap and remaining validation](docs/proposals/inference-reliability.md)
91
+
92
+ ## Optional reference deployment
93
+
94
+ The reference gateway, compatible mock fallback, Triton `double` model, fault
95
+ proxy, and monitoring stack exercise the same suite workflow. They are fixtures,
96
+ not required infrastructure for using Bront. Gateway code lives in
97
+ `bront.reference`; its server dependencies are an optional `reference` extra.
98
+
99
+ ```sh
100
+ # Build and start the mock reference stack.
101
+ docker compose up --build --wait
102
+ uv run bront run examples/gateway/suite.toml --output reports/gateway.json
103
+ uv run python scripts/smoke_compose.py
104
+ ```
105
+
106
+ For controlled outage and delay scenarios:
107
+
108
+ ```sh
109
+ docker compose -f compose.yaml -f compose.scenarios.yaml up --build --wait
110
+ uv run bront run examples/scenarios/proxy-outage.toml --output reports/outage.json
111
+ uv run bront run examples/scenarios/proxy-delay.toml --output reports/delay.json
112
+ uv run bront report reports/outage.json --output reports/outage.html
113
+ ```
114
+
115
+ Run one fault experiment at a time against a disposable reference stack. Scenarios
116
+ record control events and restore owned faults on ordinary errors and interruption.
117
+ The [scenario guide](docs/scenarios.md) explains cleanup and recovery boundaries.
118
+
119
+ See the [Triton walkthrough](docs/triton.md) for the ONNX CPU integration,
120
+ [Kubernetes guide](docs/kubernetes.md) for two independent gateway replicas, and
121
+ [observability guide](docs/observability.md) for per-pod metrics. The `double` model
122
+ is an integration fixture; a trained-model example remains on the roadmap.
123
+
124
+ For a locally launched gateway, copy `.env.example` to `.env` and install the
125
+ reference dependencies with `uv sync --extra reference`. Entry points are
126
+ `bront.reference.gateway:app` and `bront.reference.mock_backend:app`.
127
+ Reference environment variables use `BRONT_`; metrics use `bront_`.
128
+ The suite runner uses explicit TOML and process environment variables, not `.env`.
129
+
130
+ ## Development and packaging
131
+
132
+ ```sh
133
+ uv sync --frozen
134
+ uv run ruff check .
135
+ uv run ruff format --check .
136
+ uv run ty check --python-version 3.12
137
+ uv run pytest
138
+ uv run python scripts/smoke_external.py
139
+ uv build
140
+ ```
141
+
142
+ The distribution, import package, and CLI are all named `bront`. A core wheel
143
+ installation needs no FastAPI or Prometheus dependencies. Source-checkout dev
144
+ requirements include the reference dependencies to test both workflows.
145
+ No registry publication is required to install a locally built wheel.
146
+
147
+ The `.python-version` file selects Python 3.14 for default checkout development;
148
+ it is not the package's installation requirement. To work on another supported version:
149
+
150
+ ```sh
151
+ uv sync --python 3.12 --frozen
152
+ uv run --python 3.12 pytest
153
+ ```
154
+
155
+ CI tests the full suite and an isolated wheel installation on Python 3.12, 3.13,
156
+ and 3.14, including the run/compare/report smoke workflow. Ruff and type checking
157
+ target the 3.12 minimum to catch accidental use of newer syntax or APIs.
158
+ The reference Docker images continue using Python 3.14.
159
+
160
+ The Dockerfile provides a `cli` build target for the tool alone and a default
161
+ `reference` target for the fixture services:
162
+
163
+ ```sh
164
+ docker build --target cli -t bront:cli .
165
+ docker run --rm bront:cli
166
+ ```
167
+
168
+ CI runs lint, types, tests, the reference Compose smoke check, reusable proxy
169
+ scenarios, and the standalone run/compare/report workflow. It uploads JSON and
170
+ HTML artifacts, including evidence retained after failed experiments. Generated
171
+ reports belong under the ignored `reports/` directory rather than in Git.
bront-0.1.0/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # Bront
2
+
3
+ Repeatable reliability tests and release evidence for inference deployments.
4
+ Bront checks an existing HTTP JSON endpoint against representative inputs,
5
+ correctness assertions, and latency/error limits. Add fault or rollout scenarios,
6
+ compare repeated baseline and candidate runs, and share an offline HTML report.
7
+ Your service does not need to adopt Bront's reference gateway.
8
+
9
+ ## Quickstart
10
+
11
+ Requires Python 3.12 or newer; tested on CPython 3.12, 3.13, and 3.14. From this checkout:
12
+
13
+ ```sh
14
+ uv sync --frozen
15
+ uv run python examples/http-json/server.py
16
+ ```
17
+
18
+ In another terminal:
19
+
20
+ ```sh
21
+ uv run bront run examples/http-json/suite.toml --output reports/run.json
22
+ uv run bront report reports/run.json --output reports/review.html
23
+ ```
24
+
25
+ Open `reports/review.html` in a browser. The standalone example requires no Docker,
26
+ Kubernetes, Triton, or backend-specific status API.
27
+
28
+ For your own service, configure the URL, JSONL input cases, expected outputs,
29
+ workload, and assertions in a TOML suite. Read the
30
+ [external endpoint guide](docs/external-endpoints.md) for the supported contract.
31
+ Credentials can reference environment variables; raw payloads and credential values
32
+ are excluded from normal reports.
33
+
34
+ ## Release workflow
35
+
36
+ ```sh
37
+ uv run bront run baseline.toml --repeat 3 --output reports/baseline.json
38
+ uv run bront run candidate.toml --repeat 3 --output reports/candidate.json
39
+ uv run bront compare reports/baseline.json reports/candidate.json \
40
+ --policy limits.toml --output reports/comparison.json
41
+ uv run bront report reports/comparison.json --output reports/comparison.html
42
+ ```
43
+
44
+ Record deployment metadata and explicitly allow the intended change in the
45
+ comparison policy. Bront checks experiment compatibility before evaluating
46
+ regressions. Missing context, incomplete execution, or insufficient repeat evidence
47
+ cannot produce a passing comparison. Observed variation is not a statistical
48
+ significance test.
49
+
50
+ | Command | Purpose |
51
+ | --- | --- |
52
+ | `bront run` | Execute a suite, retain samples, and evaluate release assertions. |
53
+ | `bront compare` | Compare compatible repeated experiments against an explicit policy. |
54
+ | `bront report` | Render recorded evidence as self-contained HTML with JSON downloads. |
55
+
56
+ `run` and `compare` return 0 for passing evidence, 1 for failed checks, and 2 for
57
+ execution/configuration problems or inconclusive/incompatible comparisons.
58
+ Interrupted runs use exit 130 and retain partial evidence. `report` returns 0 when
59
+ rendering succeeds; it does not replace a release gate.
60
+
61
+ ## Guides
62
+
63
+ - [External endpoints and response validation](docs/external-endpoints.md)
64
+ - [Proxy faults and Kubernetes scenarios](docs/scenarios.md)
65
+ - [Repeated runs and release comparisons](docs/comparisons.md)
66
+ - [Offline HTML reports](docs/reports.md)
67
+ - [Architecture](docs/architecture.md)
68
+ - [Roadmap and remaining validation](docs/proposals/inference-reliability.md)
69
+
70
+ ## Optional reference deployment
71
+
72
+ The reference gateway, compatible mock fallback, Triton `double` model, fault
73
+ proxy, and monitoring stack exercise the same suite workflow. They are fixtures,
74
+ not required infrastructure for using Bront. Gateway code lives in
75
+ `bront.reference`; its server dependencies are an optional `reference` extra.
76
+
77
+ ```sh
78
+ # Build and start the mock reference stack.
79
+ docker compose up --build --wait
80
+ uv run bront run examples/gateway/suite.toml --output reports/gateway.json
81
+ uv run python scripts/smoke_compose.py
82
+ ```
83
+
84
+ For controlled outage and delay scenarios:
85
+
86
+ ```sh
87
+ docker compose -f compose.yaml -f compose.scenarios.yaml up --build --wait
88
+ uv run bront run examples/scenarios/proxy-outage.toml --output reports/outage.json
89
+ uv run bront run examples/scenarios/proxy-delay.toml --output reports/delay.json
90
+ uv run bront report reports/outage.json --output reports/outage.html
91
+ ```
92
+
93
+ Run one fault experiment at a time against a disposable reference stack. Scenarios
94
+ record control events and restore owned faults on ordinary errors and interruption.
95
+ The [scenario guide](docs/scenarios.md) explains cleanup and recovery boundaries.
96
+
97
+ See the [Triton walkthrough](docs/triton.md) for the ONNX CPU integration,
98
+ [Kubernetes guide](docs/kubernetes.md) for two independent gateway replicas, and
99
+ [observability guide](docs/observability.md) for per-pod metrics. The `double` model
100
+ is an integration fixture; a trained-model example remains on the roadmap.
101
+
102
+ For a locally launched gateway, copy `.env.example` to `.env` and install the
103
+ reference dependencies with `uv sync --extra reference`. Entry points are
104
+ `bront.reference.gateway:app` and `bront.reference.mock_backend:app`.
105
+ Reference environment variables use `BRONT_`; metrics use `bront_`.
106
+ The suite runner uses explicit TOML and process environment variables, not `.env`.
107
+
108
+ ## Development and packaging
109
+
110
+ ```sh
111
+ uv sync --frozen
112
+ uv run ruff check .
113
+ uv run ruff format --check .
114
+ uv run ty check --python-version 3.12
115
+ uv run pytest
116
+ uv run python scripts/smoke_external.py
117
+ uv build
118
+ ```
119
+
120
+ The distribution, import package, and CLI are all named `bront`. A core wheel
121
+ installation needs no FastAPI or Prometheus dependencies. Source-checkout dev
122
+ requirements include the reference dependencies to test both workflows.
123
+ No registry publication is required to install a locally built wheel.
124
+
125
+ The `.python-version` file selects Python 3.14 for default checkout development;
126
+ it is not the package's installation requirement. To work on another supported version:
127
+
128
+ ```sh
129
+ uv sync --python 3.12 --frozen
130
+ uv run --python 3.12 pytest
131
+ ```
132
+
133
+ CI tests the full suite and an isolated wheel installation on Python 3.12, 3.13,
134
+ and 3.14, including the run/compare/report smoke workflow. Ruff and type checking
135
+ target the 3.12 minimum to catch accidental use of newer syntax or APIs.
136
+ The reference Docker images continue using Python 3.14.
137
+
138
+ The Dockerfile provides a `cli` build target for the tool alone and a default
139
+ `reference` target for the fixture services:
140
+
141
+ ```sh
142
+ docker build --target cli -t bront:cli .
143
+ docker run --rm bront:cli
144
+ ```
145
+
146
+ CI runs lint, types, tests, the reference Compose smoke check, reusable proxy
147
+ scenarios, and the standalone run/compare/report workflow. It uploads JSON and
148
+ HTML artifacts, including evidence retained after failed experiments. Generated
149
+ reports belong under the ignored `reports/` directory rather than in Git.
@@ -0,0 +1,20 @@
1
+ # Overlay either compose.yaml or compose.triton.yaml for controlled fault scenarios.
2
+ services:
3
+ gateway:
4
+ environment:
5
+ BRONT_PRIMARY_URL: http://fault-proxy:8666
6
+ depends_on:
7
+ fault-proxy:
8
+ condition: service_healthy
9
+
10
+ fault-proxy:
11
+ image: ghcr.io/shopify/toxiproxy:2.12.0
12
+ command: ["-host=0.0.0.0", "-config=/config/proxies.json"]
13
+ ports: ["127.0.0.1:${BRONT_TOXIPROXY_PORT:-18474}:8474"]
14
+ volumes:
15
+ - ./deploy/toxiproxy/proxies.json:/config/proxies.json:ro
16
+ healthcheck:
17
+ test: ["CMD", "/toxiproxy-cli", "list"]
18
+ interval: 5s
19
+ timeout: 3s
20
+ retries: 10
@@ -0,0 +1,37 @@
1
+ name: bront
2
+ # Standalone alternative to compose.yaml: docker compose -f compose.triton.yaml up
3
+ services:
4
+ gateway:
5
+ extends:
6
+ file: compose.yaml
7
+ service: gateway
8
+ environment:
9
+ BRONT_PRIMARY_PROTOCOL: triton
10
+
11
+ primary:
12
+ image: nvcr.io/nvidia/tritonserver:26.08-py3
13
+ init: true
14
+ command:
15
+ - tritonserver
16
+ - --model-repository=/models
17
+ - --disable-auto-complete-config
18
+ - --allow-grpc=false
19
+ - --allow-gpu-metrics=false
20
+ ports: ["127.0.0.1:${BRONT_PRIMARY_PORT:-8001}:8000"]
21
+ volumes:
22
+ - ./deploy/triton/models:/models:ro
23
+ healthcheck:
24
+ test:
25
+ - CMD
26
+ - python3
27
+ - -c
28
+ - "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/v2/models/double/versions/1/ready', timeout=2)"
29
+ interval: 5s
30
+ timeout: 3s
31
+ retries: 12
32
+ start_period: 30s
33
+
34
+ fallback:
35
+ extends:
36
+ file: compose.yaml
37
+ service: fallback
@@ -0,0 +1,65 @@
1
+ name: bront
2
+ x-service: &service
3
+ build: .
4
+ init: true
5
+ healthcheck:
6
+ test:
7
+ [
8
+ "CMD",
9
+ "/app/.venv/bin/python",
10
+ "-c",
11
+ "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/healthz', timeout=2)",
12
+ ]
13
+ interval: 5s
14
+ timeout: 3s
15
+ retries: 5
16
+ start_period: 10s
17
+
18
+ services:
19
+ gateway:
20
+ <<: *service
21
+ ports: ["127.0.0.1:${BRONT_GATEWAY_PORT:-8000}:8000"]
22
+ environment:
23
+ BRONT_PRIMARY_URL: http://primary:8000
24
+ BRONT_FALLBACK_URL: http://fallback:8000
25
+ BRONT_REQUEST_TIMEOUT_SECONDS: "1"
26
+ BRONT_FAILURE_THRESHOLD: "3"
27
+ BRONT_RECOVERY_TIMEOUT_SECONDS: "10"
28
+ depends_on:
29
+ primary:
30
+ condition: service_healthy
31
+ fallback:
32
+ condition: service_healthy
33
+
34
+ primary:
35
+ <<: *service
36
+ command:
37
+ [
38
+ "/app/.venv/bin/uvicorn",
39
+ "bront.reference.mock_backend:app",
40
+ "--host",
41
+ "0.0.0.0",
42
+ "--port",
43
+ "8000",
44
+ ]
45
+ ports: ["127.0.0.1:${BRONT_PRIMARY_PORT:-8001}:8000"]
46
+
47
+ fallback:
48
+ <<: *service
49
+ command:
50
+ [
51
+ "/app/.venv/bin/uvicorn",
52
+ "bront.reference.mock_backend:app",
53
+ "--host",
54
+ "0.0.0.0",
55
+ "--port",
56
+ "8000",
57
+ ]
58
+ ports: ["127.0.0.1:${BRONT_FALLBACK_PORT:-8002}:8000"]
59
+
60
+ prometheus:
61
+ image: prom/prometheus:v3.2.1
62
+ profiles: ["observability"]
63
+ ports: ["127.0.0.1:9090:9090"]
64
+ volumes:
65
+ - ./deploy/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro