mintmark 0.1.2__tar.gz → 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.
- mintmark-0.2.0/CHANGELOG.md +321 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/NOTICE +2 -2
- {mintmark-0.1.2 → mintmark-0.2.0}/PKG-INFO +13 -12
- {mintmark-0.1.2 → mintmark-0.2.0}/README.md +11 -10
- {mintmark-0.1.2 → mintmark-0.2.0}/packs/example/pack.yaml +1 -1
- {mintmark-0.1.2 → mintmark-0.2.0}/packs/example/recipes/demo.yaml +0 -2
- {mintmark-0.1.2 → mintmark-0.2.0}/pyproject.toml +6 -2
- {mintmark-0.1.2 → mintmark-0.2.0}/schemas/manifest.schema.json +66 -24
- {mintmark-0.1.2 → mintmark-0.2.0}/schemas/pack.schema.json +26 -13
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/__init__.py +3 -1
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/annotate/render.py +19 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/api.py +4 -2
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/cli.py +205 -57
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/emit/writer.py +46 -14
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/engine/draws.py +2 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/engine/templates.py +69 -5
- mintmark-0.2.0/src/mintmark/engine/version.py +5 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/lexicons/data/special_descriptors.yaml +74 -15
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/manifest/document.py +30 -11
- mintmark-0.2.0/src/mintmark/manifest/io.py +230 -0
- mintmark-0.2.0/src/mintmark/manifest/safety.py +37 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/manifest/sums.py +11 -8
- mintmark-0.2.0/src/mintmark/manifest/verify.py +778 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/mint.py +173 -31
- mintmark-0.2.0/src/mintmark/packs/digest.py +160 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/packs/loader.py +72 -4
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/packs/model.py +397 -50
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/packs/alias/pack.yaml +1 -1
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/packs/anchor/pack.yaml +1 -1
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/packs/bad-name-pattern/pack.yaml +1 -1
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/packs/duplicate-key/pack.yaml +1 -1
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/packs/float-weight/pack.yaml +1 -1
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/packs/merge-key/pack.yaml +1 -1
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/packs/missing-schema-version/pack.yaml +1 -1
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/packs/multiple-documents/pack.yaml +1 -1
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/packs/open-ended-requires-core/pack.yaml +1 -1
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/packs/unknown-field/pack.yaml +1 -1
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/packs/valid/pack.yaml +1 -1
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/packs/wrong-locale/pack.yaml +1 -1
- mintmark-0.2.0/tests/adversarial/test_numeric_resource_limits.py +147 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/test_pack_rejection.py +59 -1
- mintmark-0.2.0/tests/adversarial/test_tamper_detection.py +497 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/test_template_grammar.py +111 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/conformance/pack/pack.yaml +1 -1
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/conformance/pack/recipes/full.yaml +0 -5
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/golden/demo-run/DIGESTS.json +6 -2
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/golden/demo-run/transaction.jsonl +84 -84
- mintmark-0.2.0/tests/golden/demo-run/transaction.labels.jsonl +100 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/property/test_draws.py +18 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_cli.py +34 -0
- mintmark-0.2.0/tests/unit/test_declared_controls.py +309 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_emit.py +39 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_mint_invariants.py +82 -5
- mintmark-0.2.0/tests/unit/test_pack_digest.py +233 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_readme_mirror.py +40 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_workflows.py +59 -0
- mintmark-0.1.2/CHANGELOG.md +0 -159
- mintmark-0.1.2/src/mintmark/manifest/verify.py +0 -362
- mintmark-0.1.2/src/mintmark/packs/digest.py +0 -58
- mintmark-0.1.2/tests/adversarial/test_tamper_detection.py +0 -256
- mintmark-0.1.2/tests/golden/demo-run/transaction.labels.jsonl +0 -100
- mintmark-0.1.2/tests/unit/test_pack_digest.py +0 -112
- {mintmark-0.1.2 → mintmark-0.2.0}/.gitignore +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/LICENSE +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/assets/brand/mintmark-logo.png +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/assets/brand/mintmark-logo.svg +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/assets/denylist/institutions-tr.txt +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/assets/readme/family-topology.png +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/assets/readme/family-topology.svg +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/assets/readme/mint-pipeline.png +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/assets/readme/mint-pipeline.svg +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/assets/tables/CHECKSUMS +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/assets/tables/balances.json +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/assets/tables/txn_amounts.json +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/packs/example/README.md +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/packs/example/fields/customer.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/packs/example/fields/transaction.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/packs/example/templates/txn_descriptions/set.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/annotate/__init__.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/annotate/sidecar.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/annotate/spans.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/annotate/taxonomy.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/emit/__init__.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/emit/canonical.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/emit/csv_writer.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/engine/__init__.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/engine/fold.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/engine/prng.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/engine/records.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/engine/streams.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/engine/tables.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/identifiers/__init__.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/identifiers/email.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/identifiers/iban.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/identifiers/pan.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/identifiers/phone.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/identifiers/policy.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/identifiers/tckn.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/identifiers/vkn.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/lexicons/__init__.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/lexicons/data/given_names_tr.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/lexicons/data/occupations_tr.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/lexicons/data/provinces_tr.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/lexicons/data/street_parts_tr.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/lexicons/data/surnames_tr.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/lexicons/denylist.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/manifest/__init__.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/packs/__init__.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/packs/semver.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/src/mintmark/py.typed +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/packs/empty-file/pack.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/packs/non-mapping-root/pack.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/adversarial/packs/tab-indentation/pack.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/conformance/pack/fields/account.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/conformance/pack/fields/card.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/conformance/pack/fields/complaint_ticket.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/conformance/pack/fields/customer.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/conformance/pack/fields/kyc_note.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/conformance/pack/fields/support_transcript.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/conformance/pack/fields/transaction.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/conformance/pack/lexicons/ratings.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/conformance/pack/templates/complaints/set.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/conformance/pack/templates/kyc_notes/set.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/conformance/pack/templates/transcripts/set.yaml +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/conformance/test_contract_coverage.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/conftest.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/golden/demo-run/customer.jsonl +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/golden/prng_vectors.json +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/golden/test_golden_bytes.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/property/test_fold_and_email.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/property/test_records.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/property/test_render.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/property/test_safe_mode_purity.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/property/test_span_alignment.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_canary.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_community_mirrors.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_denylist.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_module_boundaries.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_no_libm.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_packaging.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_prng.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_prose_lint.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_repository_inventory.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_streams.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_tables.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_taxonomy.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tests/unit/test_toolchain.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tools/canary.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tools/gen_tables.py +0 -0
- {mintmark-0.1.2 → mintmark-0.2.0}/tools/mdlint.py +0 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[keep a changelog](https://keepachangelog.com/en/1.1.0/), and this project uses
|
|
5
|
+
[semantic versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
The public surface under semantic versioning is: the command-line grammar, the
|
|
8
|
+
exit codes, every `--json` payload, the library's exported functions and their
|
|
9
|
+
returned dataclasses, the pack schema, the manifest schema, and the byte-level
|
|
10
|
+
output for a fixed set of inputs. A change that alters emitted bytes for a fixed
|
|
11
|
+
seed is a major version event even when no signature changed, because it breaks
|
|
12
|
+
the reproducibility of every published manifest.
|
|
13
|
+
|
|
14
|
+
## 0.2.0 - 2026-08-23
|
|
15
|
+
|
|
16
|
+
A security and conformance review of the three sector packs found one defect
|
|
17
|
+
repeated in seven places: a field parsed, validated against the schema, asserted
|
|
18
|
+
by a test, and then read by nothing. Every item below closes one of those. Two of
|
|
19
|
+
them move emitted bytes for a fixed seed, which this project calls a major
|
|
20
|
+
version event, so the version moves rather than the golden files quietly.
|
|
21
|
+
|
|
22
|
+
### Hardened against a hostile pack and a hostile dataset
|
|
23
|
+
|
|
24
|
+
Fourteen commits landed before this release was cut and are recorded here rather
|
|
25
|
+
than left to the git log, because each one changes what the engine refuses.
|
|
26
|
+
|
|
27
|
+
- **Resource budgets on everything a pack declares.** Strict YAML parsing, pack
|
|
28
|
+
declarations, document templates, and numeric work factors all carry explicit
|
|
29
|
+
bounds now, so a pack cannot make the loader do unbounded work. Templates are
|
|
30
|
+
compiled once before any record is generated, and a nesting depth limit refuses
|
|
31
|
+
a template that recurses past what the parser supports.
|
|
32
|
+
- **Sampler bounds are checked rather than assumed.** An unsupported bound is
|
|
33
|
+
refused instead of producing a draw nobody can reason about.
|
|
34
|
+
- **Atomic staging writes are isolated**, and the pack digest streams its inputs
|
|
35
|
+
from a confined set of paths rather than reading whatever it is pointed at.
|
|
36
|
+
- **Untrusted dataset file access is hardened.** `verify` reads a dataset through
|
|
37
|
+
a reader that bounds what it will open, and the whole verification body sits
|
|
38
|
+
behind a boundary that turns a hostile input into a report rather than a
|
|
39
|
+
traceback.
|
|
40
|
+
- **Every claim in a manifest is re-derived rather than trusted.** Record counts,
|
|
41
|
+
distributions, entity coverage, the achieved counts and `met` flags on coverage
|
|
42
|
+
targets, and the fixed-contract text are all recomputed from the data and
|
|
43
|
+
compared.
|
|
44
|
+
- **Safe output and annotation invariants are enforced at mint time**, including
|
|
45
|
+
the label a field may carry for its generator, so a pack cannot declare a
|
|
46
|
+
document field or an identifier field with a label that contradicts it.
|
|
47
|
+
- **Pack compatibility is enforced deterministically.** `requires_core` is checked
|
|
48
|
+
against the running core on every load rather than only when a caller asks.
|
|
49
|
+
- **CI and release trust boundaries are sealed**, and the pack layer keeps its
|
|
50
|
+
dependency boundaries.
|
|
51
|
+
|
|
52
|
+
### Fixed, and it changes what a verifier reports
|
|
53
|
+
|
|
54
|
+
- **`verify` reported zero checksum-valid identifiers in datasets where every
|
|
55
|
+
identifier was checksum-valid.** The sweep ran only under the safe policy while
|
|
56
|
+
the counter it fills was printed under both, in the rendered report and in the
|
|
57
|
+
`--json` payload. A validator-policy dataset therefore reported
|
|
58
|
+
`checksum_valid_identifiers: 0`, and a script gating on that number let through
|
|
59
|
+
exactly the datasets it was written to stop. The sweep now runs under both
|
|
60
|
+
policies. Under safe a hit is still a problem, because safe mode is the
|
|
61
|
+
product's safety claim; under validator the count is the expected outcome and
|
|
62
|
+
is recorded as a fact.
|
|
63
|
+
|
|
64
|
+
- **A declared coverage target was recorded and never checked.** Every manifest
|
|
65
|
+
carried the target, the achieved count, and a `met` flag, and nothing read any
|
|
66
|
+
of them, so an evaluation set could ship without a whole label and still verify
|
|
67
|
+
clean. `verify` now fails on a missed target. A mint that overrode its record
|
|
68
|
+
counts is exempt: `packcheck` mini-mints twenty-five records against targets in
|
|
69
|
+
the hundreds, and a deliberately shrunken run is not a claim the recipe made.
|
|
70
|
+
|
|
71
|
+
- **The validator warning claimed more than the engines deliver.** It said the
|
|
72
|
+
values belong to no real person, account, or institution. That holds for an
|
|
73
|
+
IBAN, a PAN, and an email address, each of which sits in a range nobody can
|
|
74
|
+
hold. A TCKN and a VKN have no such reserved range, so a checksum-valid one is
|
|
75
|
+
indistinguishable from an issued number. The fixed text now says which is
|
|
76
|
+
which.
|
|
77
|
+
|
|
78
|
+
### Fixed, and it moves emitted bytes
|
|
79
|
+
|
|
80
|
+
- **Template weights were ignored.** Every template entry carries a required
|
|
81
|
+
`weight`, the schema validates it as a decimal string, and the renderer picked
|
|
82
|
+
uniformly regardless. A set declared at 0.35, 0.25, 0.25, 0.15 emitted an even
|
|
83
|
+
quarter each. Selection now uses the same weighted draw the enum generators
|
|
84
|
+
use.
|
|
85
|
+
|
|
86
|
+
- **A pack could not contribute entity surfaces.** `{entity:ORG}` drew from the
|
|
87
|
+
core's curated list and nothing else, so every pack in the family shared one
|
|
88
|
+
twelve-name organization vocabulary, and an evaluation set built on it could be
|
|
89
|
+
passed by memorizing them. `pack.yaml` gains an optional `entity_lexicons` map
|
|
90
|
+
from label to the pack's own lexicons. The core list stays the floor: pack
|
|
91
|
+
surfaces are appended, never substituted.
|
|
92
|
+
|
|
93
|
+
- **PERSON surfaces were a list of twelve full names.** The descriptor note
|
|
94
|
+
already said they came from the same common Turkish name pool the structured
|
|
95
|
+
fields draw from, so they are now composed from it: 60 given names against 50
|
|
96
|
+
surnames, 3000 surfaces, in a fixed order so the draw stays a plain index. A
|
|
97
|
+
label entry in the descriptor file may declare `compose` instead of `values`.
|
|
98
|
+
|
|
99
|
+
### Added
|
|
100
|
+
|
|
101
|
+
- **`{lex:name}` in the template grammar.** A draw from a named lexicon, emitted
|
|
102
|
+
without a label, so a template can vary its ordinary words instead of repeating
|
|
103
|
+
one carrier sentence. Domain vocabulary is not personal data and carries no
|
|
104
|
+
span.
|
|
105
|
+
|
|
106
|
+
- **Two reachability rules on pack loading.** A lexicon nothing draws from, and a
|
|
107
|
+
template set no field renders, are refused by name. Three sector packs shipped
|
|
108
|
+
eight lexicons between them that reached no generator at all: source-noted,
|
|
109
|
+
denylist-tested, guarded by their own tests, and absent from every byte those
|
|
110
|
+
packs emit.
|
|
111
|
+
|
|
112
|
+
### Changed
|
|
113
|
+
|
|
114
|
+
- **A recipe that names an identifier policy now decides it.** The field was
|
|
115
|
+
parsed into the `Recipe` dataclass and read nowhere, so a recipe pinned to
|
|
116
|
+
`safe` minted checksum-valid identifiers the moment a caller passed
|
|
117
|
+
`--identifier-policy validator`. Naming a different policy than the recipe
|
|
118
|
+
names is refused. Naming the same one is allowed, because `reproduce` replays
|
|
119
|
+
what a manifest recorded and cannot know which of the two decided it.
|
|
120
|
+
`--identifier-policy` now defaults to unset rather than to `safe`.
|
|
121
|
+
|
|
122
|
+
### Removed
|
|
123
|
+
|
|
124
|
+
- **`doc_mix` and `emit_child_outside_window` from the recipe schema.**
|
|
125
|
+
`doc_mix` restated what the record counts already fix, and nothing read it;
|
|
126
|
+
`emit_child_outside_window` carried a schema description of behaviour no code
|
|
127
|
+
implemented. The template-set existence check `doc_mix` provided is replaced by
|
|
128
|
+
the stronger reachability rule above.
|
|
129
|
+
|
|
130
|
+
## 0.1.3 - 2026-08-22
|
|
131
|
+
|
|
132
|
+
### Fixed, and it changes every manifest
|
|
133
|
+
|
|
134
|
+
- **The pack digest covered files that cannot affect what a pack emits.** It
|
|
135
|
+
enumerated the whole pack directory minus a short denylist, which meant it
|
|
136
|
+
covered README files, the changelog, the test suite, the lockfile, the vendored
|
|
137
|
+
engine wheel, compiled `__pycache__` output, and `PLAN.md`, a file the sector
|
|
138
|
+
packs deliberately keep out of git.
|
|
139
|
+
|
|
140
|
+
Three consequences, all observed rather than reasoned about. A clean clone and
|
|
141
|
+
a working checkout of the same commit produced different digests. Running the
|
|
142
|
+
suite under a different pytest version changed the digest through the `.pyc`
|
|
143
|
+
files. Editing documentation changed the digest of a pack whose declarations
|
|
144
|
+
had not moved. One pack produced three different digests for one set of
|
|
145
|
+
declarations: `9548e8fd` in a working tree, `144b703a` from a clean clone, and
|
|
146
|
+
`a9552d15` in an already published dataset.
|
|
147
|
+
|
|
148
|
+
A digest behaving that way cannot do the job it exists for, which is to let
|
|
149
|
+
somebody holding a dataset tell whether a pack they have is the pack it came
|
|
150
|
+
from. It now covers `pack.yaml` and the `fields/`, `recipes/`, `templates/`,
|
|
151
|
+
`lexicons/`, and `assets/` directories, by allowlist rather than denylist,
|
|
152
|
+
because every failure above was something nobody thought to deny.
|
|
153
|
+
|
|
154
|
+
Every manifest this engine writes now records a different `pack.digest` for the
|
|
155
|
+
same declarations. No emitted data moves: the digest seeds nothing.
|
|
156
|
+
|
|
157
|
+
- **`reproduce` could not find the pack the engine itself ships**, so the
|
|
158
|
+
quickstart's own output could not be reproduced by the command the README
|
|
159
|
+
advertises as the check that makes a manifest mean something.
|
|
160
|
+
|
|
161
|
+
- **`reproduce` reported `differs outside the excluded provenance block`**, which
|
|
162
|
+
was true and useless. It now names each field that differs with both values. A
|
|
163
|
+
difference confined to the engine version is reported as what it is rather than
|
|
164
|
+
as a mismatch, because the determinism claim covers a fixed engine version and
|
|
165
|
+
a newer engine reproducing every byte is a stronger result than the claim, not
|
|
166
|
+
a failure of it.
|
|
167
|
+
|
|
168
|
+
### Notes
|
|
169
|
+
|
|
170
|
+
Found by auditing the published product rather than the source tree: cloning the
|
|
171
|
+
packs, installing the engine from PyPI, and running the documented commands
|
|
172
|
+
against the released datasets.
|
|
173
|
+
|
|
174
|
+
## 0.1.2 - 2026-08-22
|
|
175
|
+
|
|
176
|
+
### Fixed
|
|
177
|
+
|
|
178
|
+
- The example pack shipped in the wheel and could not be reached. It is there so
|
|
179
|
+
the quickstart works without cloning anything, which is the whole reason it is
|
|
180
|
+
shipped, but `--pack packs/example` is a path that exists only in a checkout.
|
|
181
|
+
Anyone who installed 0.1.1 from PyPI and followed the README walked into
|
|
182
|
+
`pack: not-a-directory`. Found by installing the published package and running
|
|
183
|
+
the README's own first command against it.
|
|
184
|
+
|
|
185
|
+
`--pack example` now resolves to the packaged pack. A local path always wins,
|
|
186
|
+
so this cannot shadow a real directory, and an unrecognized name is returned
|
|
187
|
+
untouched so the loader still fails with the path the user typed rather than
|
|
188
|
+
rescuing a typo into some other pack.
|
|
189
|
+
|
|
190
|
+
### Changed
|
|
191
|
+
|
|
192
|
+
- Both READMEs install by package name again and the quickstart uses
|
|
193
|
+
`--pack example`. The claim that nothing was published was true until 0.1.1
|
|
194
|
+
and is not any more.
|
|
195
|
+
|
|
196
|
+
## 0.1.1 - 2026-08-22
|
|
197
|
+
|
|
198
|
+
### Added
|
|
199
|
+
|
|
200
|
+
- Publication to PyPI, over trusted publishing. The release workflow was written
|
|
201
|
+
and left disabled so its mechanics could be reviewed before they ever ran; this
|
|
202
|
+
enables it. No long-lived token is stored in this repository and none is passed
|
|
203
|
+
to a step, because PyPI verifies the workflow identity directly.
|
|
204
|
+
|
|
205
|
+
Three gates stand between a tag and a published release, and none of them is a
|
|
206
|
+
reviewer's attention. The tag must agree with the version in `pyproject.toml`
|
|
207
|
+
and with the version the package reports. The full gate runs first and
|
|
208
|
+
publication depends on it. The `pypi` environment requires the owner's approval
|
|
209
|
+
and admits only `v*` tags, so a push to main cannot reach it.
|
|
210
|
+
|
|
211
|
+
### Notes
|
|
212
|
+
|
|
213
|
+
The package is unchanged from 0.1.0. This version exists because publication is a
|
|
214
|
+
repository change that needs a tag to carry it, and moving the 0.1.0 tag would
|
|
215
|
+
have broken the immutability that repository's own tag ruleset enforces.
|
|
216
|
+
|
|
217
|
+
A version already on PyPI cannot be replaced, and deleting a release does not
|
|
218
|
+
free its number. The workflow refuses on a version mismatch rather than resolving
|
|
219
|
+
one.
|
|
220
|
+
|
|
221
|
+
## 0.1.0 - 2026-08-22
|
|
222
|
+
|
|
223
|
+
### Changed, and it moved emitted bytes
|
|
224
|
+
|
|
225
|
+
- The manifest gained a `license` block and its schema version went to 2. A
|
|
226
|
+
dataset leaves this project as a directory of files, and before this there was
|
|
227
|
+
nothing in that directory saying under what terms it could be used. An
|
|
228
|
+
attribution requirement a consumer cannot find in the artifact is not a
|
|
229
|
+
requirement. The block carries the code license, the dataset license the pack
|
|
230
|
+
declared, and a ready credit line; `verify` prints all three, and stripping the
|
|
231
|
+
block fails verification like any other tampering.
|
|
232
|
+
- `pack.yaml` requires `dataset_license`, from a closed set. The engine writes
|
|
233
|
+
this into every manifest it produces, and a free-text field would put a typo,
|
|
234
|
+
or terms nobody vetted, onto a published artifact. Declaring it changes the
|
|
235
|
+
pack digest, which changes emitted bytes for a fixed seed, which is why every
|
|
236
|
+
pack in the family took a version bump alongside it.
|
|
237
|
+
|
|
238
|
+
- The special-category descriptor lexicons moved into a curated YAML file and
|
|
239
|
+
grew to 90 entries. Expanding a lexicon changes the draw for every subsequent
|
|
240
|
+
index, so emitted bytes moved for a fixed seed. **Under this project's own rule
|
|
241
|
+
that is a major version event.** It is harmless only because nothing has been
|
|
242
|
+
published: there is no manifest this breaks. The reason is recorded in
|
|
243
|
+
`tests/golden/demo-run/DIGESTS.json` beside the regenerated goldens.
|
|
244
|
+
- `special_rate` now governs what it claimed to govern. A recipe declared it and
|
|
245
|
+
nothing read it, so template authors fixed the density with literal
|
|
246
|
+
probabilities and the recipe field was decoration. Templates now write
|
|
247
|
+
`[?special: ...]` and the rate comes from the recipe.
|
|
248
|
+
|
|
249
|
+
### Added
|
|
250
|
+
|
|
251
|
+
- Turkish mirrors of every community document: contributing, conduct,
|
|
252
|
+
governance, security, and support, each linked from its original and held in
|
|
253
|
+
step by a test. The audience for this project reads Turkish, and a README
|
|
254
|
+
mirror alone left a contributor reading the project's own rules in a second
|
|
255
|
+
language. The conduct mirror records that it is our own rendering rather than
|
|
256
|
+
the official one, because the Contributor Covenant publishes Turkish at 2.0
|
|
257
|
+
while this repository adapts 2.1.
|
|
258
|
+
- `docs/kvkk.md` and its Turkish mirror: what this project produces and what it
|
|
259
|
+
does not claim under law 6698, with a table mapping the taxonomy's
|
|
260
|
+
special-category labels to the categories the law enumerates, and naming the
|
|
261
|
+
three that no label covers.
|
|
262
|
+
- `LICENSE-DATASETS.md`, `CITATION.cff`, issue and pull request templates,
|
|
263
|
+
`CODEOWNERS`, and grouped monthly dependency updates.
|
|
264
|
+
|
|
265
|
+
- The `derived:flag_unless` rule, which turns a sentinel enum value into a
|
|
266
|
+
boolean so a row can carry both which anomaly it is and whether it is one,
|
|
267
|
+
without two independent draws that can disagree.
|
|
268
|
+
- An optional `age_years: [low, high]` parameter on `datetime_window`, which
|
|
269
|
+
draws from the span that would give a person that age at the start of the
|
|
270
|
+
recipe window. Without it a birth date is drawn from the recipe window, so
|
|
271
|
+
every person in a dataset describing one year was also born in that year. The
|
|
272
|
+
field is a valid date, the label is right, the span aligns and the manifest
|
|
273
|
+
verifies, so nothing in the suite caught it; it is only wrong to a reader. The
|
|
274
|
+
parameter is optional and a field that omits it behaves exactly as before, so
|
|
275
|
+
no existing declaration had to move. Declaring it on a field whose generator
|
|
276
|
+
cannot read it is rejected by name at pack load, because a parameter nothing
|
|
277
|
+
reads is worse than one that fails loudly.
|
|
278
|
+
|
|
279
|
+
- Deterministic generation engine: SplitMix64 over 64-bit modular arithmetic,
|
|
280
|
+
per-site stream derivation, unbiased bounded and weighted draws, and
|
|
281
|
+
continuous distributions sampled from committed fixed-point inverse-CDF tables
|
|
282
|
+
so that no transcendental function runs in the mint path.
|
|
283
|
+
- Six identifier engines, each with a `safe` default that emits provably
|
|
284
|
+
checksum-invalid values and an opt-in `validator` mode that is watermarked in
|
|
285
|
+
the manifest.
|
|
286
|
+
- A closed eighteen-label taxonomy pinned by digest, span recording that
|
|
287
|
+
survives whitespace normalization, and a label sidecar format that binds spans
|
|
288
|
+
to the exact text they index.
|
|
289
|
+
- Strict, fail-closed pack loading: duplicate keys, anchors, aliases, merge
|
|
290
|
+
keys, multi-document files, non-mapping roots, tab indentation, and unknown
|
|
291
|
+
fields are each rejected by name.
|
|
292
|
+
- Canonical JSONL and CSV emission with no float in emitted data, and atomic
|
|
293
|
+
output so an interrupted mint leaves no directory that looks like a dataset.
|
|
294
|
+
- A provenance manifest with checksums, `verify` that recomputes every claim it
|
|
295
|
+
makes, and `reproduce` that re-mints from the manifest and compares bytes.
|
|
296
|
+
- A command-line surface of seven verbs with a five-value exit-code contract and
|
|
297
|
+
stable `--json` payloads, plus a two-function library API.
|
|
298
|
+
- An example fixture pack, shipped in both the wheel and the sdist, used by the
|
|
299
|
+
quickstart and the test suite.
|
|
300
|
+
- A real-institution denylist built from a verified public registry, scanned in
|
|
301
|
+
required CI over lexicons, templates, and golden outputs.
|
|
302
|
+
- English and Turkish READMEs, kept in step by a test that compares their
|
|
303
|
+
structure and checks the quickstart's promised output against what `verify`
|
|
304
|
+
actually prints.
|
|
305
|
+
|
|
306
|
+
### Verified rather than assumed
|
|
307
|
+
|
|
308
|
+
The VKN check-digit algorithm, against two independent open implementations
|
|
309
|
+
cross-checked over 200 000 inputs. The unassigned status of IBAN bank code
|
|
310
|
+
99999, against the TCMB participant list. Turkey's permanent UTC+3 status,
|
|
311
|
+
against the IANA time zone database. The institution denylist, against the same
|
|
312
|
+
TCMB list. Each record, with its source and retrieval date, is in
|
|
313
|
+
`docs/normative-verification.md`.
|
|
314
|
+
|
|
315
|
+
### Notes
|
|
316
|
+
|
|
317
|
+
Nothing was published at the time 0.1.0 was cut: no package registry carried it
|
|
318
|
+
and the name was still provisional. Both changed later the same day, in 0.1.1 and
|
|
319
|
+
in the trademark clearance recorded in TRADEMARKS.md. This note is left as it was
|
|
320
|
+
written rather than edited, because a changelog that quietly updates itself stops
|
|
321
|
+
being a record.
|
|
@@ -6,8 +6,8 @@ This product includes software developed by the Mintmark contributors.
|
|
|
6
6
|
Mintmark is licensed under the Apache License, Version 2.0. This NOTICE is
|
|
7
7
|
informational and does not modify that license.
|
|
8
8
|
|
|
9
|
-
Mintmark is
|
|
10
|
-
the name
|
|
9
|
+
Mintmark is the project's settled name, frozen on 2026-08-22 after trademark
|
|
10
|
+
screening. See TRADEMARKS.md for what the name may and may not be used for.
|
|
11
11
|
|
|
12
12
|
Third-party code or assets incorporated into Mintmark must be recorded in
|
|
13
13
|
ORIGIN_AND_ATTRIBUTION.md, including any attribution or NOTICE text required
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: mintmark
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Deterministic, fully synthetic, Turkish-first labeled datasets with a provenance manifest.
|
|
5
5
|
Author: Mintmark contributors
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -33,9 +33,9 @@ Description-Content-Type: text/markdown
|
|
|
33
33
|
|
|
34
34
|
<p align="center">
|
|
35
35
|
<a href="https://github.com/lokomotifai/mintmark/actions/workflows/ci.yml"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/lokomotifai/mintmark/ci.yml?branch=main&style=flat-square&label=CI"></a>
|
|
36
|
-
<img alt="
|
|
36
|
+
<img alt="905 tests" src="https://img.shields.io/badge/tests-905-3C873A?style=flat-square">
|
|
37
37
|
<img alt="18 invariants, each with a named test" src="https://img.shields.io/badge/invariants-18%20tested-3C873A?style=flat-square">
|
|
38
|
-
<a href="https://github.com/lokomotifai/mintmark/releases/tag/v0.
|
|
38
|
+
<a href="https://github.com/lokomotifai/mintmark/releases/tag/v0.2.0"><img alt="Release v0.2.0" src="https://img.shields.io/badge/release-v0.2.0-3C873A?style=flat-square"></a>
|
|
39
39
|
<a href="https://pypi.org/project/mintmark/"><img alt="On PyPI" src="https://img.shields.io/pypi/v/mintmark?style=flat-square&label=PyPI&color=3C873A"></a>
|
|
40
40
|
<a href="LICENSE"><img alt="Apache-2.0 license" src="https://img.shields.io/badge/license-Apache--2.0-3B3F46?style=flat-square"></a>
|
|
41
41
|
</p>
|
|
@@ -76,11 +76,10 @@ coin to say where it was made. A Mintmark dataset carries the same thing in its
|
|
|
76
76
|
manifest, so a dataset that turns up six months later can still say what produced
|
|
77
77
|
it.
|
|
78
78
|
|
|
79
|
-
**
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
single CI run rather than asserted from one.
|
|
79
|
+
**Published as [`mintmark`](https://pypi.org/project/mintmark/) on PyPI.** 890
|
|
80
|
+
tests pass, all eighteen invariants have named tests, and the byte-level
|
|
81
|
+
determinism claim is observed on three platforms in a single CI run rather than
|
|
82
|
+
asserted from one.
|
|
84
83
|
|
|
85
84
|
> [!IMPORTANT]
|
|
86
85
|
> **What Mintmark is not.** It is not anonymization or masking of real data; it
|
|
@@ -137,10 +136,12 @@ manifest schema: valid
|
|
|
137
136
|
checksums: 3/3 match
|
|
138
137
|
identifier policy: safe (confirmed)
|
|
139
138
|
checksum-valid identifiers found: 0
|
|
139
|
+
coverage targets: 0 checked
|
|
140
140
|
taxonomy: hushmark-tr v0.1, pin af11b31e4916
|
|
141
|
-
label alignment: 100 documents,
|
|
141
|
+
label alignment: 100 documents, 89 spans
|
|
142
142
|
dataset license: CC-BY-4.0
|
|
143
143
|
attribution: mintmark-example 0.1.0 reference dataset (recipe demo, seed 42), lokomotifai, licensed CC-BY-4.0
|
|
144
|
+
authenticity: self-consistency only; no trusted manifest digest supplied
|
|
144
145
|
```
|
|
145
146
|
|
|
146
147
|
A test asserts that block against what `verify` actually prints, so this example
|
|
@@ -320,8 +321,8 @@ released on GitHub with the wheel, the source distribution, and a software bill
|
|
|
320
321
|
of materials attached. Publication runs through trusted publishing over OIDC
|
|
321
322
|
behind an approval gate, so no long-lived token exists in this repository.
|
|
322
323
|
|
|
323
|
-
The name
|
|
324
|
-
|
|
324
|
+
The name is frozen. Trademark screening cleared on 2026-08-22, and the PyPI
|
|
325
|
+
namespace is held by the project.
|
|
325
326
|
|
|
326
327
|
## Community contract
|
|
327
328
|
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
|
|
14
14
|
<p align="center">
|
|
15
15
|
<a href="https://github.com/lokomotifai/mintmark/actions/workflows/ci.yml"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/lokomotifai/mintmark/ci.yml?branch=main&style=flat-square&label=CI"></a>
|
|
16
|
-
<img alt="
|
|
16
|
+
<img alt="905 tests" src="https://img.shields.io/badge/tests-905-3C873A?style=flat-square">
|
|
17
17
|
<img alt="18 invariants, each with a named test" src="https://img.shields.io/badge/invariants-18%20tested-3C873A?style=flat-square">
|
|
18
|
-
<a href="https://github.com/lokomotifai/mintmark/releases/tag/v0.
|
|
18
|
+
<a href="https://github.com/lokomotifai/mintmark/releases/tag/v0.2.0"><img alt="Release v0.2.0" src="https://img.shields.io/badge/release-v0.2.0-3C873A?style=flat-square"></a>
|
|
19
19
|
<a href="https://pypi.org/project/mintmark/"><img alt="On PyPI" src="https://img.shields.io/pypi/v/mintmark?style=flat-square&label=PyPI&color=3C873A"></a>
|
|
20
20
|
<a href="LICENSE"><img alt="Apache-2.0 license" src="https://img.shields.io/badge/license-Apache--2.0-3B3F46?style=flat-square"></a>
|
|
21
21
|
</p>
|
|
@@ -56,11 +56,10 @@ coin to say where it was made. A Mintmark dataset carries the same thing in its
|
|
|
56
56
|
manifest, so a dataset that turns up six months later can still say what produced
|
|
57
57
|
it.
|
|
58
58
|
|
|
59
|
-
**
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
single CI run rather than asserted from one.
|
|
59
|
+
**Published as [`mintmark`](https://pypi.org/project/mintmark/) on PyPI.** 890
|
|
60
|
+
tests pass, all eighteen invariants have named tests, and the byte-level
|
|
61
|
+
determinism claim is observed on three platforms in a single CI run rather than
|
|
62
|
+
asserted from one.
|
|
64
63
|
|
|
65
64
|
> [!IMPORTANT]
|
|
66
65
|
> **What Mintmark is not.** It is not anonymization or masking of real data; it
|
|
@@ -117,10 +116,12 @@ manifest schema: valid
|
|
|
117
116
|
checksums: 3/3 match
|
|
118
117
|
identifier policy: safe (confirmed)
|
|
119
118
|
checksum-valid identifiers found: 0
|
|
119
|
+
coverage targets: 0 checked
|
|
120
120
|
taxonomy: hushmark-tr v0.1, pin af11b31e4916
|
|
121
|
-
label alignment: 100 documents,
|
|
121
|
+
label alignment: 100 documents, 89 spans
|
|
122
122
|
dataset license: CC-BY-4.0
|
|
123
123
|
attribution: mintmark-example 0.1.0 reference dataset (recipe demo, seed 42), lokomotifai, licensed CC-BY-4.0
|
|
124
|
+
authenticity: self-consistency only; no trusted manifest digest supplied
|
|
124
125
|
```
|
|
125
126
|
|
|
126
127
|
A test asserts that block against what `verify` actually prints, so this example
|
|
@@ -300,8 +301,8 @@ released on GitHub with the wheel, the source distribution, and a software bill
|
|
|
300
301
|
of materials attached. Publication runs through trusted publishing over OIDC
|
|
301
302
|
behind an approval gate, so no long-lived token exists in this repository.
|
|
302
303
|
|
|
303
|
-
The name
|
|
304
|
-
|
|
304
|
+
The name is frozen. Trademark screening cleared on 2026-08-22, and the PyPI
|
|
305
|
+
namespace is held by the project.
|
|
305
306
|
|
|
306
307
|
## Community contract
|
|
307
308
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
schema_version: 1
|
|
2
2
|
name: mintmark-example
|
|
3
3
|
version: 0.1.0
|
|
4
|
-
requires_core: ">=0.
|
|
4
|
+
requires_core: ">=0.2,<0.3"
|
|
5
5
|
locale: tr-TR
|
|
6
6
|
allowed_identifier_policies: [safe, validator]
|
|
7
7
|
description: Fixture pack for the quickstart and the test suite. Not a sector pack.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["hatchling"]
|
|
2
|
+
requires = ["hatchling==1.31.0"]
|
|
3
3
|
build-backend = "hatchling.build"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "mintmark"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.0"
|
|
8
8
|
description = "Deterministic, fully synthetic, Turkish-first labeled datasets with a provenance manifest."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12,<3.13"
|
|
@@ -30,6 +30,7 @@ mintmark = "mintmark.cli:main"
|
|
|
30
30
|
|
|
31
31
|
[dependency-groups]
|
|
32
32
|
dev = [
|
|
33
|
+
"hatchling==1.31.0",
|
|
33
34
|
"pytest>=8.3,<10",
|
|
34
35
|
"hypothesis>=6.112,<7",
|
|
35
36
|
"ruff>=0.14,<0.17",
|
|
@@ -40,6 +41,9 @@ dev = [
|
|
|
40
41
|
"types-jsonschema>=4.26.0.20260518",
|
|
41
42
|
]
|
|
42
43
|
|
|
44
|
+
[tool.uv]
|
|
45
|
+
required-version = "==0.12.3"
|
|
46
|
+
|
|
43
47
|
# Package data ships with both the sdist and the wheel. tools/ and tests/ do not.
|
|
44
48
|
[tool.hatch.build.targets.wheel]
|
|
45
49
|
packages = ["src/mintmark"]
|