isitright 0.1.0.dev0__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.
- isitright-0.1.0.dev0/.github/workflows/ci.yml +33 -0
- isitright-0.1.0.dev0/.github/workflows/publish.yml +97 -0
- isitright-0.1.0.dev0/.gitignore +13 -0
- isitright-0.1.0.dev0/LICENSE +22 -0
- isitright-0.1.0.dev0/PKG-INFO +105 -0
- isitright-0.1.0.dev0/README.md +56 -0
- isitright-0.1.0.dev0/docs/contracts.md +78 -0
- isitright-0.1.0.dev0/docs/releasing.md +44 -0
- isitright-0.1.0.dev0/pyproject.toml +73 -0
- isitright-0.1.0.dev0/src/isitright/__about__.py +4 -0
- isitright-0.1.0.dev0/src/isitright/__init__.py +34 -0
- isitright-0.1.0.dev0/src/isitright/api.py +46 -0
- isitright-0.1.0.dev0/src/isitright/cli.py +105 -0
- isitright-0.1.0.dev0/src/isitright/models.py +269 -0
- isitright-0.1.0.dev0/src/isitright/suite.py +43 -0
- isitright-0.1.0.dev0/tests/__init__.py +1 -0
- isitright-0.1.0.dev0/tests/factories.py +41 -0
- isitright-0.1.0.dev0/tests/fixtures/proposals/README.md +32 -0
- isitright-0.1.0.dev0/tests/fixtures/proposals/constraints.yaml +22 -0
- isitright-0.1.0.dev0/tests/fixtures/proposals/expected_semantics.yaml +36 -0
- isitright-0.1.0.dev0/tests/fixtures/proposals/roman_tribute.sql +37 -0
- isitright-0.1.0.dev0/tests/fixtures/proposals/roman_tribute_minimal_counterexample.sql +15 -0
- isitright-0.1.0.dev0/tests/fixtures/proposals/synthetic_22.jsonl +23 -0
- isitright-0.1.0.dev0/tests/snapshots/case_report.json +51 -0
- isitright-0.1.0.dev0/tests/snapshots/suite_report.json +17 -0
- isitright-0.1.0.dev0/tests/test_api.py +16 -0
- isitright-0.1.0.dev0/tests/test_cli.py +69 -0
- isitright-0.1.0.dev0/tests/test_contract_snapshots.py +40 -0
- isitright-0.1.0.dev0/tests/test_models.py +87 -0
- isitright-0.1.0.dev0/tests/test_packaging.py +17 -0
- isitright-0.1.0.dev0/tests/test_suite.py +81 -0
- isitright-0.1.0.dev0/uv.lock +1381 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
test:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
- uses: astral-sh/setup-uv@v6
|
|
20
|
+
with:
|
|
21
|
+
python-version: ${{ matrix.python-version }}
|
|
22
|
+
enable-cache: true
|
|
23
|
+
- run: uv sync --extra dev
|
|
24
|
+
- run: uv run ruff check .
|
|
25
|
+
- run: uv run mypy src
|
|
26
|
+
- run: uv run pytest
|
|
27
|
+
- run: uv build
|
|
28
|
+
- name: Verify wheel imports without network
|
|
29
|
+
shell: bash
|
|
30
|
+
run: |
|
|
31
|
+
uv pip install --reinstall --no-deps dist/*.whl
|
|
32
|
+
.venv/bin/python -c "import isitright; print(isitright.__version__)"
|
|
33
|
+
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
name: Publish distributions
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
if: github.ref == 'refs/heads/main'
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: astral-sh/setup-uv@v6
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.11"
|
|
18
|
+
enable-cache: true
|
|
19
|
+
- run: uv sync --extra dev
|
|
20
|
+
- run: uv run ruff check .
|
|
21
|
+
- run: uv run mypy src
|
|
22
|
+
- run: uv run pytest
|
|
23
|
+
- run: uv build
|
|
24
|
+
- run: uv run python -m twine check dist/*
|
|
25
|
+
- uses: actions/upload-artifact@v4
|
|
26
|
+
with:
|
|
27
|
+
name: python-distributions
|
|
28
|
+
path: dist/
|
|
29
|
+
if-no-files-found: error
|
|
30
|
+
retention-days: 7
|
|
31
|
+
|
|
32
|
+
publish-testpypi:
|
|
33
|
+
needs: build
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
environment: testpypi
|
|
36
|
+
permissions:
|
|
37
|
+
id-token: write
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/download-artifact@v4
|
|
40
|
+
with:
|
|
41
|
+
name: python-distributions
|
|
42
|
+
path: dist/
|
|
43
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
44
|
+
with:
|
|
45
|
+
repository-url: https://test.pypi.org/legacy/
|
|
46
|
+
|
|
47
|
+
verify-testpypi:
|
|
48
|
+
needs: publish-testpypi
|
|
49
|
+
runs-on: ubuntu-latest
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/setup-python@v5
|
|
52
|
+
with:
|
|
53
|
+
python-version: "3.11"
|
|
54
|
+
- uses: actions/download-artifact@v4
|
|
55
|
+
with:
|
|
56
|
+
name: python-distributions
|
|
57
|
+
path: dist/
|
|
58
|
+
- name: Read the package version from the built wheel
|
|
59
|
+
shell: bash
|
|
60
|
+
run: |
|
|
61
|
+
wheel=$(find dist -name 'isitright-*.whl' -print -quit)
|
|
62
|
+
version=${wheel##*/isitright-}
|
|
63
|
+
version=${version%-py3-none-any.whl}
|
|
64
|
+
echo "PACKAGE_VERSION=$version" >> "$GITHUB_ENV"
|
|
65
|
+
- name: Install runtime dependencies from PyPI
|
|
66
|
+
run: >-
|
|
67
|
+
python -m pip install
|
|
68
|
+
"pydantic>=2.10,<3"
|
|
69
|
+
"pyyaml>=6.0.2,<7"
|
|
70
|
+
"sqlglot>=27,<29"
|
|
71
|
+
"typer>=0.15,<1"
|
|
72
|
+
- name: Install the exact TestPyPI release
|
|
73
|
+
shell: bash
|
|
74
|
+
run: |
|
|
75
|
+
for attempt in 1 2 3 4 5; do
|
|
76
|
+
python -m pip install \
|
|
77
|
+
--index-url https://test.pypi.org/simple/ \
|
|
78
|
+
--no-deps "isitright==$PACKAGE_VERSION" && break
|
|
79
|
+
if [ "$attempt" = 5 ]; then exit 1; fi
|
|
80
|
+
sleep 15
|
|
81
|
+
done
|
|
82
|
+
- run: python -c "import isitright, os; assert isitright.__version__ == os.environ['PACKAGE_VERSION']"
|
|
83
|
+
- run: isitright --version
|
|
84
|
+
|
|
85
|
+
publish-pypi:
|
|
86
|
+
needs: verify-testpypi
|
|
87
|
+
runs-on: ubuntu-latest
|
|
88
|
+
environment: pypi
|
|
89
|
+
permissions:
|
|
90
|
+
id-token: write
|
|
91
|
+
steps:
|
|
92
|
+
- uses: actions/download-artifact@v4
|
|
93
|
+
with:
|
|
94
|
+
name: python-distributions
|
|
95
|
+
path: dist/
|
|
96
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
97
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 isitright contributors
|
|
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.
|
|
22
|
+
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: isitright
|
|
3
|
+
Version: 0.1.0.dev0
|
|
4
|
+
Summary: Evidence-first stress testing for text-to-SQL evaluations
|
|
5
|
+
Project-URL: Repository, https://github.com/isitright-ai/isitright
|
|
6
|
+
Author: isitright contributors
|
|
7
|
+
License: MIT License
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2026 isitright contributors
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
31
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
32
|
+
Classifier: Programming Language :: Python :: 3
|
|
33
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
36
|
+
Requires-Python: >=3.11
|
|
37
|
+
Requires-Dist: pydantic<3,>=2.10
|
|
38
|
+
Requires-Dist: pyyaml<7,>=6.0.2
|
|
39
|
+
Requires-Dist: sqlglot<29,>=27
|
|
40
|
+
Requires-Dist: typer<1,>=0.15
|
|
41
|
+
Provides-Extra: dev
|
|
42
|
+
Requires-Dist: build<2,>=1.2.2; extra == 'dev'
|
|
43
|
+
Requires-Dist: mypy<2,>=1.14; extra == 'dev'
|
|
44
|
+
Requires-Dist: pytest-cov<8,>=6; extra == 'dev'
|
|
45
|
+
Requires-Dist: pytest<9,>=8.3; extra == 'dev'
|
|
46
|
+
Requires-Dist: ruff<1,>=0.9; extra == 'dev'
|
|
47
|
+
Requires-Dist: twine<7,>=6.1; extra == 'dev'
|
|
48
|
+
Description-Content-Type: text/markdown
|
|
49
|
+
|
|
50
|
+
# isitright
|
|
51
|
+
|
|
52
|
+
`isitright` is an evidence-first tool for stress-testing text-to-SQL evaluations.
|
|
53
|
+
Given reference and candidate SQL, the eventual v0.1 engine will search for a valid
|
|
54
|
+
database state on which their outputs differ and emit a minimized, replayable
|
|
55
|
+
counterexample. A disagreement is evidence, not automatic attribution of fault.
|
|
56
|
+
|
|
57
|
+
## Current status: Stage 0 review gate
|
|
58
|
+
|
|
59
|
+
This repository currently contains package scaffolding and specification contracts
|
|
60
|
+
only. SQL execution, database mutation, constraint validation, search, comparison,
|
|
61
|
+
and minimization are deliberately not implemented. The proposed fixtures under
|
|
62
|
+
`tests/fixtures/proposals` require owner approval before Stage 1 begins.
|
|
63
|
+
|
|
64
|
+
## Development
|
|
65
|
+
|
|
66
|
+
Python 3.11 or newer is required. With `uv` installed:
|
|
67
|
+
|
|
68
|
+
```console
|
|
69
|
+
uv sync --extra dev
|
|
70
|
+
uv run ruff check .
|
|
71
|
+
uv run mypy src
|
|
72
|
+
uv run pytest
|
|
73
|
+
uv build
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The package exposes the future command surface now:
|
|
77
|
+
|
|
78
|
+
```console
|
|
79
|
+
isitright --version
|
|
80
|
+
isitright check --help
|
|
81
|
+
isitright suite --help
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Calling `check` or `suite` during Stage 0 exits with the internal/not-implemented
|
|
85
|
+
code because no analysis engine exists yet.
|
|
86
|
+
|
|
87
|
+
The Stage 0 preview is versioned `0.1.0.dev0`. It is intentionally a development
|
|
88
|
+
release and must not be presented as an implemented analysis engine.
|
|
89
|
+
|
|
90
|
+
## Contract highlights
|
|
91
|
+
|
|
92
|
+
- Result statuses keep observed equivalence, state validity, and attribution separate.
|
|
93
|
+
- Unordered query results will be compared as multisets, preserving duplicates.
|
|
94
|
+
- Automatic ordering will honor a top-level `ORDER BY`; otherwise results are unordered.
|
|
95
|
+
- SQLite values are represented with explicit storage classes.
|
|
96
|
+
- Reports use schema version `0.1`; package versioning remains pre-release until an
|
|
97
|
+
engine is implemented.
|
|
98
|
+
|
|
99
|
+
See [the contract reference](docs/contracts.md) and
|
|
100
|
+
[the fixture proposal](tests/fixtures/proposals/README.md).
|
|
101
|
+
|
|
102
|
+
## License
|
|
103
|
+
|
|
104
|
+
MIT
|
|
105
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# isitright
|
|
2
|
+
|
|
3
|
+
`isitright` is an evidence-first tool for stress-testing text-to-SQL evaluations.
|
|
4
|
+
Given reference and candidate SQL, the eventual v0.1 engine will search for a valid
|
|
5
|
+
database state on which their outputs differ and emit a minimized, replayable
|
|
6
|
+
counterexample. A disagreement is evidence, not automatic attribution of fault.
|
|
7
|
+
|
|
8
|
+
## Current status: Stage 0 review gate
|
|
9
|
+
|
|
10
|
+
This repository currently contains package scaffolding and specification contracts
|
|
11
|
+
only. SQL execution, database mutation, constraint validation, search, comparison,
|
|
12
|
+
and minimization are deliberately not implemented. The proposed fixtures under
|
|
13
|
+
`tests/fixtures/proposals` require owner approval before Stage 1 begins.
|
|
14
|
+
|
|
15
|
+
## Development
|
|
16
|
+
|
|
17
|
+
Python 3.11 or newer is required. With `uv` installed:
|
|
18
|
+
|
|
19
|
+
```console
|
|
20
|
+
uv sync --extra dev
|
|
21
|
+
uv run ruff check .
|
|
22
|
+
uv run mypy src
|
|
23
|
+
uv run pytest
|
|
24
|
+
uv build
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The package exposes the future command surface now:
|
|
28
|
+
|
|
29
|
+
```console
|
|
30
|
+
isitright --version
|
|
31
|
+
isitright check --help
|
|
32
|
+
isitright suite --help
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Calling `check` or `suite` during Stage 0 exits with the internal/not-implemented
|
|
36
|
+
code because no analysis engine exists yet.
|
|
37
|
+
|
|
38
|
+
The Stage 0 preview is versioned `0.1.0.dev0`. It is intentionally a development
|
|
39
|
+
release and must not be presented as an implemented analysis engine.
|
|
40
|
+
|
|
41
|
+
## Contract highlights
|
|
42
|
+
|
|
43
|
+
- Result statuses keep observed equivalence, state validity, and attribution separate.
|
|
44
|
+
- Unordered query results will be compared as multisets, preserving duplicates.
|
|
45
|
+
- Automatic ordering will honor a top-level `ORDER BY`; otherwise results are unordered.
|
|
46
|
+
- SQLite values are represented with explicit storage classes.
|
|
47
|
+
- Reports use schema version `0.1`; package versioning remains pre-release until an
|
|
48
|
+
engine is implemented.
|
|
49
|
+
|
|
50
|
+
See [the contract reference](docs/contracts.md) and
|
|
51
|
+
[the fixture proposal](tests/fixtures/proposals/README.md).
|
|
52
|
+
|
|
53
|
+
## License
|
|
54
|
+
|
|
55
|
+
MIT
|
|
56
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Stage 0 contract reference
|
|
2
|
+
|
|
3
|
+
This document freezes the interfaces proposed for schema version `0.1`. It does
|
|
4
|
+
not claim that the analysis engine is implemented.
|
|
5
|
+
|
|
6
|
+
## Public API
|
|
7
|
+
|
|
8
|
+
`check(...)` accepts a concrete SQLite database, two SQL strings, an optional
|
|
9
|
+
question, an optional constraints file, a `CheckConfig`, and an optional trusted
|
|
10
|
+
validator callback. `check_suite(...)` accepts the same shared inputs plus a JSONL
|
|
11
|
+
case file. During Stage 0 both functions raise `StageNotImplementedError`.
|
|
12
|
+
|
|
13
|
+
`CheckConfig` defaults to seed `0`, 100 attempts, a 30-second query budget,
|
|
14
|
+
positional column comparison, automatic ordering, and a `1e-9` relative float
|
|
15
|
+
tolerance.
|
|
16
|
+
|
|
17
|
+
## Status fields
|
|
18
|
+
|
|
19
|
+
The three result axes are deliberately independent:
|
|
20
|
+
|
|
21
|
+
- `equivalence_status`: `COUNTEREXAMPLE_FOUND`, `NOT_FOUND_WITHIN_BUDGET`,
|
|
22
|
+
`INCONCLUSIVE`, or `UNSUPPORTED`.
|
|
23
|
+
- `validity_status`: `DOMAIN_VALIDATED`, `SCHEMA_VALID_ONLY`, `INVALID`, or
|
|
24
|
+
`UNKNOWN`.
|
|
25
|
+
- `attribution_status`: `UNDETERMINED` in core v0.1. Values reserved for future
|
|
26
|
+
adjudication are `AGENT_DEFECT`, `REFERENCE_DEFECT`, `BOTH_DEFECTIVE`, and
|
|
27
|
+
`AMBIGUOUS_TASK`.
|
|
28
|
+
|
|
29
|
+
Headlines summarize evidence and may not contain the standalone words “pass,”
|
|
30
|
+
“fail,” “correct,” or “wrong.”
|
|
31
|
+
|
|
32
|
+
## Comparison contract
|
|
33
|
+
|
|
34
|
+
- Unordered rows are a multiset. Duplicate multiplicity is significant.
|
|
35
|
+
- `auto` ordering treats a top-level `ORDER BY` as ordered and all other queries
|
|
36
|
+
as unordered. `ordered` and `unordered` override this.
|
|
37
|
+
- Column comparison is `positional`, `by_name`, or `strict`.
|
|
38
|
+
- Values are tagged as SQLite `null`, `integer`, `real`, `text`, or `blob`.
|
|
39
|
+
Blobs are base64 strings in JSON. Types are significant; only real values use
|
|
40
|
+
the configured relative tolerance.
|
|
41
|
+
|
|
42
|
+
## Suite input
|
|
43
|
+
|
|
44
|
+
Each nonblank JSONL line requires `case_id`, `reference_sql`, and
|
|
45
|
+
`candidate_sql`. `question` is optional. All other properties are moved into the
|
|
46
|
+
record's `metadata` mapping. Case IDs must be unique within a suite.
|
|
47
|
+
|
|
48
|
+
## Reports and reproducer
|
|
49
|
+
|
|
50
|
+
A case report contains the version, status axes, evidence-only headline, inputs
|
|
51
|
+
and SHA-256 hashes, active comparison policy, original-state result, search
|
|
52
|
+
accounting, checked rules, assumptions, evidence, errors, timing, and carried
|
|
53
|
+
metadata. Suite reports contain all cases, status totals, mutator-family totals,
|
|
54
|
+
timing, and metadata.
|
|
55
|
+
|
|
56
|
+
When later stages find a counterexample, `counterexample.sql` will contain only
|
|
57
|
+
deterministic DDL and minimized inserts needed to rebuild the state. The report
|
|
58
|
+
retains both queries, both typed outputs, the original injected change, and the
|
|
59
|
+
exact replay command. This separation keeps the SQL fixture independently
|
|
60
|
+
inspectable without embedding shell-specific behavior.
|
|
61
|
+
|
|
62
|
+
Suite ranking is stable within four priority groups:
|
|
63
|
+
|
|
64
|
+
1. Counterexamples on domain-validated states.
|
|
65
|
+
2. Counterexamples on schema-valid-only states.
|
|
66
|
+
3. Inconclusive or unsupported cases, plus counterexamples of unknown validity.
|
|
67
|
+
4. Cases with no divergence found within budget.
|
|
68
|
+
|
|
69
|
+
## CLI exit codes
|
|
70
|
+
|
|
71
|
+
- `0`: analysis completed, including unsupported and not-found outcomes.
|
|
72
|
+
- `1`: internal failure or a Stage 0 unimplemented command.
|
|
73
|
+
- `2`: invalid invocation or input.
|
|
74
|
+
- `3`: an explicit `--fail-on` policy matched.
|
|
75
|
+
|
|
76
|
+
`--fail-on` accepts `none`, `domain-validated`, or `any-counterexample` and never
|
|
77
|
+
changes attribution.
|
|
78
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Releasing
|
|
2
|
+
|
|
3
|
+
`isitright` uses Hatchling as its PEP 517 build backend and `uv build` as the
|
|
4
|
+
build frontend. The version has one source of truth in
|
|
5
|
+
`src/isitright/__about__.py`.
|
|
6
|
+
|
|
7
|
+
Hatchling is temporarily capped below 1.32 so distributions use Core Metadata
|
|
8
|
+
2.4, which the current Twine release can validate. Remove the cap when the
|
|
9
|
+
publishing toolchain supports Hatchling's newer default metadata version.
|
|
10
|
+
|
|
11
|
+
## Release invariants
|
|
12
|
+
|
|
13
|
+
- Publish only from the `main` branch after CI passes.
|
|
14
|
+
- Build the source distribution and wheel exactly once.
|
|
15
|
+
- Run `twine check` before either upload.
|
|
16
|
+
- Publish to TestPyPI and smoke-test the indexed wheel before approving PyPI.
|
|
17
|
+
- Promote the exact same downloaded GitHub artifact to PyPI; never rebuild it.
|
|
18
|
+
- Never reuse a version. PyPI files are immutable even if a release is deleted.
|
|
19
|
+
- Configure separate `testpypi` and `pypi` GitHub environments with required
|
|
20
|
+
reviewers for the production environment.
|
|
21
|
+
|
|
22
|
+
## One-time registry setup
|
|
23
|
+
|
|
24
|
+
Create pending Trusted Publishers on both registries with:
|
|
25
|
+
|
|
26
|
+
- Owner: `isitright-ai`
|
|
27
|
+
- Repository: `isitright`
|
|
28
|
+
- Workflow: `publish.yml`
|
|
29
|
+
- Environment: `testpypi` on TestPyPI and `pypi` on PyPI
|
|
30
|
+
|
|
31
|
+
The repository must exist on GitHub before the workflow can run. No long-lived
|
|
32
|
+
API token is stored in GitHub; the publish jobs request short-lived OIDC
|
|
33
|
+
credentials.
|
|
34
|
+
|
|
35
|
+
## Release
|
|
36
|
+
|
|
37
|
+
1. Confirm the version in `src/isitright/__about__.py` is new.
|
|
38
|
+
2. Push the reviewed commit to `main`.
|
|
39
|
+
3. Run the **Publish distributions** workflow manually.
|
|
40
|
+
4. Approve the `testpypi` environment deployment.
|
|
41
|
+
5. Wait for the TestPyPI installation smoke test to pass.
|
|
42
|
+
6. Approve the `pypi` environment deployment.
|
|
43
|
+
7. Verify the project page and install the exact version in a clean environment.
|
|
44
|
+
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.27,<1.32"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "isitright"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Evidence-first stress testing for text-to-SQL evaluations"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = { file = "LICENSE" }
|
|
12
|
+
authors = [{ name = "isitright contributors" }]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 2 - Pre-Alpha",
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.11",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Programming Language :: Python :: 3.13",
|
|
20
|
+
]
|
|
21
|
+
dependencies = [
|
|
22
|
+
"pydantic>=2.10,<3",
|
|
23
|
+
"pyyaml>=6.0.2,<7",
|
|
24
|
+
"sqlglot>=27,<29",
|
|
25
|
+
"typer>=0.15,<1",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[project.optional-dependencies]
|
|
29
|
+
dev = [
|
|
30
|
+
"build>=1.2.2,<2",
|
|
31
|
+
"mypy>=1.14,<2",
|
|
32
|
+
"pytest>=8.3,<9",
|
|
33
|
+
"pytest-cov>=6,<8",
|
|
34
|
+
"ruff>=0.9,<1",
|
|
35
|
+
"twine>=6.1,<7",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[project.scripts]
|
|
39
|
+
isitright = "isitright.cli:app"
|
|
40
|
+
|
|
41
|
+
[project.urls]
|
|
42
|
+
Repository = "https://github.com/isitright-ai/isitright"
|
|
43
|
+
|
|
44
|
+
[tool.hatch.build.targets.wheel]
|
|
45
|
+
packages = ["src/isitright"]
|
|
46
|
+
|
|
47
|
+
[tool.hatch.version]
|
|
48
|
+
path = "src/isitright/__about__.py"
|
|
49
|
+
|
|
50
|
+
[tool.pytest.ini_options]
|
|
51
|
+
addopts = "--strict-config --strict-markers --cov=isitright --cov-report=term-missing"
|
|
52
|
+
testpaths = ["tests"]
|
|
53
|
+
|
|
54
|
+
[tool.coverage.run]
|
|
55
|
+
branch = true
|
|
56
|
+
source = ["isitright"]
|
|
57
|
+
|
|
58
|
+
[tool.coverage.report]
|
|
59
|
+
fail_under = 90
|
|
60
|
+
show_missing = true
|
|
61
|
+
|
|
62
|
+
[tool.ruff]
|
|
63
|
+
line-length = 100
|
|
64
|
+
target-version = "py311"
|
|
65
|
+
|
|
66
|
+
[tool.ruff.lint]
|
|
67
|
+
select = ["E", "F", "I", "UP", "B", "SIM", "RUF"]
|
|
68
|
+
|
|
69
|
+
[tool.mypy]
|
|
70
|
+
python_version = "3.11"
|
|
71
|
+
strict = true
|
|
72
|
+
packages = ["isitright"]
|
|
73
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Public package interface for isitright."""
|
|
2
|
+
|
|
3
|
+
from isitright.__about__ import __version__
|
|
4
|
+
from isitright.api import StageNotImplementedError, check, check_suite
|
|
5
|
+
from isitright.models import (
|
|
6
|
+
AttributionStatus,
|
|
7
|
+
CaseResult,
|
|
8
|
+
CheckConfig,
|
|
9
|
+
ColumnComparisonPolicy,
|
|
10
|
+
EquivalenceStatus,
|
|
11
|
+
FailOnPolicy,
|
|
12
|
+
OrderingPolicy,
|
|
13
|
+
SuiteCase,
|
|
14
|
+
SuiteResult,
|
|
15
|
+
ValidityStatus,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
"AttributionStatus",
|
|
20
|
+
"CaseResult",
|
|
21
|
+
"CheckConfig",
|
|
22
|
+
"ColumnComparisonPolicy",
|
|
23
|
+
"EquivalenceStatus",
|
|
24
|
+
"FailOnPolicy",
|
|
25
|
+
"OrderingPolicy",
|
|
26
|
+
"StageNotImplementedError",
|
|
27
|
+
"SuiteCase",
|
|
28
|
+
"SuiteResult",
|
|
29
|
+
"ValidityStatus",
|
|
30
|
+
"__version__",
|
|
31
|
+
"check",
|
|
32
|
+
"check_suite",
|
|
33
|
+
]
|
|
34
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""Reserved public API for the future analysis engine."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Callable
|
|
6
|
+
from os import PathLike
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from isitright.models import CaseResult, CheckConfig, SuiteResult
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class StageNotImplementedError(RuntimeError):
|
|
13
|
+
"""Raised when a post-Stage-0 capability is invoked."""
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def check(
|
|
17
|
+
*,
|
|
18
|
+
database: str | PathLike[str],
|
|
19
|
+
reference_sql: str,
|
|
20
|
+
candidate_sql: str,
|
|
21
|
+
question: str | None = None,
|
|
22
|
+
constraints_file: str | PathLike[str] | None = None,
|
|
23
|
+
config: CheckConfig | None = None,
|
|
24
|
+
validator: Callable[[Path], bool] | None = None,
|
|
25
|
+
) -> CaseResult:
|
|
26
|
+
"""Compare one SQL pair once the Stage 1+ engine is implemented."""
|
|
27
|
+
del database, reference_sql, candidate_sql, question, constraints_file, config, validator
|
|
28
|
+
raise StageNotImplementedError(
|
|
29
|
+
"check() is a Stage 1+ capability; Stage 0 defines its contract only"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def check_suite(
|
|
34
|
+
*,
|
|
35
|
+
database: str | PathLike[str],
|
|
36
|
+
cases: str | PathLike[str],
|
|
37
|
+
constraints_file: str | PathLike[str] | None = None,
|
|
38
|
+
config: CheckConfig | None = None,
|
|
39
|
+
validator: Callable[[Path], bool] | None = None,
|
|
40
|
+
) -> SuiteResult:
|
|
41
|
+
"""Compare a JSONL suite once the Stage 3 engine is implemented."""
|
|
42
|
+
del database, cases, constraints_file, config, validator
|
|
43
|
+
raise StageNotImplementedError(
|
|
44
|
+
"check_suite() is a Stage 3 capability; Stage 0 defines its contract only"
|
|
45
|
+
)
|
|
46
|
+
|