finelint 0.2.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.
finelint-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 FineLint 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.
@@ -0,0 +1,227 @@
1
+ Metadata-Version: 2.4
2
+ Name: finelint
3
+ Version: 0.2.0
4
+ Summary: Facts for fine-tuning data. No models, no verdicts.
5
+ Author: FineLint contributors
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/denizaslan36/FineLint
8
+ Project-URL: Repository, https://github.com/denizaslan36/FineLint
9
+ Project-URL: Issues, https://github.com/denizaslan36/FineLint/issues
10
+ Keywords: fine-tuning,dataset,data-quality,llm,cli
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Software Development :: Quality Assurance
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Dynamic: license-file
25
+
26
+ <div align="center">
27
+
28
+ # FineLint
29
+
30
+ **Facts for fine-tuning data. No models, no verdicts.**
31
+
32
+ [![Test](https://github.com/denizaslan36/FineLint/actions/workflows/test.yml/badge.svg)](https://github.com/denizaslan36/FineLint/actions/workflows/test.yml)
33
+ [![Python 3.10+](https://img.shields.io/badge/Python-3.10%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/)
34
+ [![AI free](https://img.shields.io/badge/AI-free-2ea44f)](#what-finelint-reports)
35
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
36
+
37
+ Terminal only · Deterministic · Local · Vendor neutral
38
+
39
+ </div>
40
+
41
+ FineLint inspects text datasets before fine-tuning. It identifies malformed chat
42
+ records, duplicate examples, suspicious conversation flows, conflicting targets,
43
+ and leakage between train, validation, and test splits.
44
+
45
+ FineLint does **not** call a model, create embeddings, use an API, change your source
46
+ files, or label a dataset as good or bad. Every result points back to concrete rows,
47
+ lines, turns, and deterministic evidence.
48
+
49
+ ## Install
50
+
51
+ ```bash
52
+ pipx install finelint
53
+ ```
54
+
55
+ Or install the current source version:
56
+
57
+ ```bash
58
+ git clone https://github.com/denizaslan36/FineLint.git
59
+ cd FineLint
60
+ pipx install .
61
+ ```
62
+
63
+ FineLint has no runtime dependencies and supports Python 3.10 through 3.14.
64
+
65
+ ## Inspect one dataset
66
+
67
+ ```bash
68
+ finelint inspect conversations.jsonl
69
+ ```
70
+
71
+ FineLint detects these chat schemas automatically:
72
+
73
+ | Schema | Recognized shape |
74
+ | --- | --- |
75
+ | OpenAI chat | `messages` with `role`, `content`, and optional tool calls |
76
+ | ShareGPT | `conversations` with `from` and `value` |
77
+ | Alpaca | `instruction`, optional `input`, and `output` |
78
+ | Generic text | Top-level string fields in CSV or JSONL |
79
+
80
+ Choose a schema explicitly when needed:
81
+
82
+ ```bash
83
+ finelint inspect conversations.jsonl --schema openai
84
+ finelint inspect sharegpt.jsonl --schema sharegpt
85
+ finelint inspect alpaca.jsonl --schema alpaca
86
+ finelint inspect custom.csv --schema generic --fields prompt --fields response
87
+ ```
88
+
89
+ If a file contains conflicting chat shapes, auto-detection stops and asks for an
90
+ explicit schema instead of guessing.
91
+
92
+ ## Compare dataset splits
93
+
94
+ ```bash
95
+ finelint compare \
96
+ --split train=train.jsonl \
97
+ --split validation=validation.jsonl \
98
+ --split test=test.jsonl
99
+ ```
100
+
101
+ `compare` finds cross-split overlap at two levels:
102
+
103
+ - whole examples: exact, normalized, and highly similar conversations;
104
+ - training contexts: repeated prompts or histories, including contexts paired with
105
+ different assistant targets.
106
+
107
+ Each split is adapted independently, so an OpenAI-formatted train file can be
108
+ compared with a ShareGPT validation file. Override one split when auto-detection is
109
+ not enough:
110
+
111
+ ```bash
112
+ finelint compare \
113
+ --split train=train.jsonl \
114
+ --split validation=validation.jsonl \
115
+ --schema train=openai \
116
+ --schema validation=sharegpt
117
+ ```
118
+
119
+ ## What FineLint reports
120
+
121
+ | Area | Examples |
122
+ | --- | --- |
123
+ | File structure | Malformed JSONL, non-object rows, empty lines, malformed CSV, wrong row widths |
124
+ | Chat schema | Missing messages, invalid roles or content, empty turns, missing assistant targets |
125
+ | Tool calling | Invalid tool definitions, malformed arguments JSON, undefined tools, orphaned results |
126
+ | Conversation flow | Consecutive roles, late system messages, repeated turns |
127
+ | Duplication | Exact copies, Unicode/case/whitespace-hidden copies, near duplicates |
128
+ | Split leakage | Repeated examples or contexts across named splits, conflicting targets |
129
+
130
+ Definite schema violations are `error` findings. Patterns that may be intentional are
131
+ `warning` findings. Neither severity is an overall dataset score or verdict.
132
+
133
+ Near-duplicate candidates come from a bounded deterministic MinHash/LSH index and
134
+ are verified with character 5-gram Jaccard similarity. Adjust the conservative
135
+ default threshold when needed:
136
+
137
+ ```bash
138
+ finelint inspect data.jsonl --similarity-threshold 0.92 --min-text-length 60
139
+ ```
140
+
141
+ ## Outputs
142
+
143
+ Every successful command writes two JSON files:
144
+
145
+ ```text
146
+ conversations.finelint-report.json
147
+ conversations.finelint-affected.json
148
+ ```
149
+
150
+ The report contains metadata, the effective configuration, counts, and complete
151
+ findings. Every finding has a deterministic ID such as `FL-a62db0194f2e9c11`.
152
+
153
+ The affected-records file is a compact index of every referenced record and its
154
+ reason codes. It deliberately contains no `keep`, `delete`, or `fix` decision.
155
+
156
+ ```json
157
+ {
158
+ "report_schema_version": 2,
159
+ "records": [
160
+ {
161
+ "split": "validation",
162
+ "dataset": "/data/validation.jsonl",
163
+ "row": 204,
164
+ "line": 204,
165
+ "turn": 1,
166
+ "reasons": [
167
+ {
168
+ "finding_id": "FL-a62db0194f2e9c11",
169
+ "code": "CROSS_SPLIT_EXACT_CONTEXT",
170
+ "category": "split_leakage",
171
+ "severity": "warning"
172
+ }
173
+ ]
174
+ }
175
+ ]
176
+ }
177
+ ```
178
+
179
+ Use custom output paths with `--report` and `--affected-records`. FineLint refuses
180
+ to overwrite an input dataset.
181
+
182
+ A completed scan exits with code `0`, even when it reports findings. Invalid input,
183
+ configuration problems, and fatal processing errors return a nonzero code.
184
+
185
+ ## Generic datasets
186
+
187
+ The original CSV/JSONL field inspector remains available:
188
+
189
+ ```bash
190
+ finelint inspect data.jsonl \
191
+ --schema generic \
192
+ --fields instruction \
193
+ --fields response \
194
+ --input-fields instruction \
195
+ --output-fields response \
196
+ --required-fields instruction \
197
+ --id-field id
198
+ ```
199
+
200
+ Field options are repeatable. `--input-fields` and `--output-fields` must be supplied
201
+ together.
202
+
203
+ ## Development
204
+
205
+ ```bash
206
+ git clone https://github.com/denizaslan36/FineLint.git
207
+ cd FineLint
208
+
209
+ PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src \
210
+ python3 -m unittest discover -s tests -v
211
+
212
+ PYTHONPATH=src python3 -m finelint --help
213
+ ```
214
+
215
+ The runtime uses only the Python standard library. Pull requests should preserve
216
+ deterministic output, source-file safety, and the no-model/no-verdict boundary.
217
+
218
+ ## Roadmap
219
+
220
+ - dataset facts: length, role, source, Unicode script, and template distributions;
221
+ - reproducible project rules through `.finelint.toml` and report diffs;
222
+ - DPO, evaluation, and deterministic PII/secret checks;
223
+ - a stable adapter and rule extension interface.
224
+
225
+ ## License
226
+
227
+ [MIT](LICENSE)
@@ -0,0 +1,202 @@
1
+ <div align="center">
2
+
3
+ # FineLint
4
+
5
+ **Facts for fine-tuning data. No models, no verdicts.**
6
+
7
+ [![Test](https://github.com/denizaslan36/FineLint/actions/workflows/test.yml/badge.svg)](https://github.com/denizaslan36/FineLint/actions/workflows/test.yml)
8
+ [![Python 3.10+](https://img.shields.io/badge/Python-3.10%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/)
9
+ [![AI free](https://img.shields.io/badge/AI-free-2ea44f)](#what-finelint-reports)
10
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
11
+
12
+ Terminal only · Deterministic · Local · Vendor neutral
13
+
14
+ </div>
15
+
16
+ FineLint inspects text datasets before fine-tuning. It identifies malformed chat
17
+ records, duplicate examples, suspicious conversation flows, conflicting targets,
18
+ and leakage between train, validation, and test splits.
19
+
20
+ FineLint does **not** call a model, create embeddings, use an API, change your source
21
+ files, or label a dataset as good or bad. Every result points back to concrete rows,
22
+ lines, turns, and deterministic evidence.
23
+
24
+ ## Install
25
+
26
+ ```bash
27
+ pipx install finelint
28
+ ```
29
+
30
+ Or install the current source version:
31
+
32
+ ```bash
33
+ git clone https://github.com/denizaslan36/FineLint.git
34
+ cd FineLint
35
+ pipx install .
36
+ ```
37
+
38
+ FineLint has no runtime dependencies and supports Python 3.10 through 3.14.
39
+
40
+ ## Inspect one dataset
41
+
42
+ ```bash
43
+ finelint inspect conversations.jsonl
44
+ ```
45
+
46
+ FineLint detects these chat schemas automatically:
47
+
48
+ | Schema | Recognized shape |
49
+ | --- | --- |
50
+ | OpenAI chat | `messages` with `role`, `content`, and optional tool calls |
51
+ | ShareGPT | `conversations` with `from` and `value` |
52
+ | Alpaca | `instruction`, optional `input`, and `output` |
53
+ | Generic text | Top-level string fields in CSV or JSONL |
54
+
55
+ Choose a schema explicitly when needed:
56
+
57
+ ```bash
58
+ finelint inspect conversations.jsonl --schema openai
59
+ finelint inspect sharegpt.jsonl --schema sharegpt
60
+ finelint inspect alpaca.jsonl --schema alpaca
61
+ finelint inspect custom.csv --schema generic --fields prompt --fields response
62
+ ```
63
+
64
+ If a file contains conflicting chat shapes, auto-detection stops and asks for an
65
+ explicit schema instead of guessing.
66
+
67
+ ## Compare dataset splits
68
+
69
+ ```bash
70
+ finelint compare \
71
+ --split train=train.jsonl \
72
+ --split validation=validation.jsonl \
73
+ --split test=test.jsonl
74
+ ```
75
+
76
+ `compare` finds cross-split overlap at two levels:
77
+
78
+ - whole examples: exact, normalized, and highly similar conversations;
79
+ - training contexts: repeated prompts or histories, including contexts paired with
80
+ different assistant targets.
81
+
82
+ Each split is adapted independently, so an OpenAI-formatted train file can be
83
+ compared with a ShareGPT validation file. Override one split when auto-detection is
84
+ not enough:
85
+
86
+ ```bash
87
+ finelint compare \
88
+ --split train=train.jsonl \
89
+ --split validation=validation.jsonl \
90
+ --schema train=openai \
91
+ --schema validation=sharegpt
92
+ ```
93
+
94
+ ## What FineLint reports
95
+
96
+ | Area | Examples |
97
+ | --- | --- |
98
+ | File structure | Malformed JSONL, non-object rows, empty lines, malformed CSV, wrong row widths |
99
+ | Chat schema | Missing messages, invalid roles or content, empty turns, missing assistant targets |
100
+ | Tool calling | Invalid tool definitions, malformed arguments JSON, undefined tools, orphaned results |
101
+ | Conversation flow | Consecutive roles, late system messages, repeated turns |
102
+ | Duplication | Exact copies, Unicode/case/whitespace-hidden copies, near duplicates |
103
+ | Split leakage | Repeated examples or contexts across named splits, conflicting targets |
104
+
105
+ Definite schema violations are `error` findings. Patterns that may be intentional are
106
+ `warning` findings. Neither severity is an overall dataset score or verdict.
107
+
108
+ Near-duplicate candidates come from a bounded deterministic MinHash/LSH index and
109
+ are verified with character 5-gram Jaccard similarity. Adjust the conservative
110
+ default threshold when needed:
111
+
112
+ ```bash
113
+ finelint inspect data.jsonl --similarity-threshold 0.92 --min-text-length 60
114
+ ```
115
+
116
+ ## Outputs
117
+
118
+ Every successful command writes two JSON files:
119
+
120
+ ```text
121
+ conversations.finelint-report.json
122
+ conversations.finelint-affected.json
123
+ ```
124
+
125
+ The report contains metadata, the effective configuration, counts, and complete
126
+ findings. Every finding has a deterministic ID such as `FL-a62db0194f2e9c11`.
127
+
128
+ The affected-records file is a compact index of every referenced record and its
129
+ reason codes. It deliberately contains no `keep`, `delete`, or `fix` decision.
130
+
131
+ ```json
132
+ {
133
+ "report_schema_version": 2,
134
+ "records": [
135
+ {
136
+ "split": "validation",
137
+ "dataset": "/data/validation.jsonl",
138
+ "row": 204,
139
+ "line": 204,
140
+ "turn": 1,
141
+ "reasons": [
142
+ {
143
+ "finding_id": "FL-a62db0194f2e9c11",
144
+ "code": "CROSS_SPLIT_EXACT_CONTEXT",
145
+ "category": "split_leakage",
146
+ "severity": "warning"
147
+ }
148
+ ]
149
+ }
150
+ ]
151
+ }
152
+ ```
153
+
154
+ Use custom output paths with `--report` and `--affected-records`. FineLint refuses
155
+ to overwrite an input dataset.
156
+
157
+ A completed scan exits with code `0`, even when it reports findings. Invalid input,
158
+ configuration problems, and fatal processing errors return a nonzero code.
159
+
160
+ ## Generic datasets
161
+
162
+ The original CSV/JSONL field inspector remains available:
163
+
164
+ ```bash
165
+ finelint inspect data.jsonl \
166
+ --schema generic \
167
+ --fields instruction \
168
+ --fields response \
169
+ --input-fields instruction \
170
+ --output-fields response \
171
+ --required-fields instruction \
172
+ --id-field id
173
+ ```
174
+
175
+ Field options are repeatable. `--input-fields` and `--output-fields` must be supplied
176
+ together.
177
+
178
+ ## Development
179
+
180
+ ```bash
181
+ git clone https://github.com/denizaslan36/FineLint.git
182
+ cd FineLint
183
+
184
+ PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src \
185
+ python3 -m unittest discover -s tests -v
186
+
187
+ PYTHONPATH=src python3 -m finelint --help
188
+ ```
189
+
190
+ The runtime uses only the Python standard library. Pull requests should preserve
191
+ deterministic output, source-file safety, and the no-model/no-verdict boundary.
192
+
193
+ ## Roadmap
194
+
195
+ - dataset facts: length, role, source, Unicode script, and template distributions;
196
+ - reproducible project rules through `.finelint.toml` and report diffs;
197
+ - DPO, evaluation, and deterministic PII/secret checks;
198
+ - a stable adapter and rule extension interface.
199
+
200
+ ## License
201
+
202
+ [MIT](LICENSE)
@@ -0,0 +1,37 @@
1
+ [build-system]
2
+ requires = ["setuptools>=69"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "finelint"
7
+ version = "0.2.0"
8
+ description = "Facts for fine-tuning data. No models, no verdicts."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ authors = [{ name = "FineLint contributors" }]
13
+ dependencies = []
14
+ keywords = ["fine-tuning", "dataset", "data-quality", "llm", "cli"]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Environment :: Console",
18
+ "Intended Audience :: Developers",
19
+ "Programming Language :: Python :: 3 :: Only",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Programming Language :: Python :: 3.14",
25
+ "Topic :: Software Development :: Quality Assurance",
26
+ ]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/denizaslan36/FineLint"
30
+ Repository = "https://github.com/denizaslan36/FineLint"
31
+ Issues = "https://github.com/denizaslan36/FineLint/issues"
32
+
33
+ [project.scripts]
34
+ finelint = "finelint.cli:main"
35
+
36
+ [tool.setuptools.packages.find]
37
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """FineLint: deterministic facts for fine-tuning datasets."""
2
+
3
+ __version__ = "0.2.0"
@@ -0,0 +1,4 @@
1
+ from .cli import main
2
+
3
+ if __name__ == "__main__":
4
+ main()