mintmark 0.2.0__tar.gz → 0.3.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 → mintmark-0.3.0}/CHANGELOG.md +48 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/PKG-INFO +3 -3
- {mintmark-0.2.0 → mintmark-0.3.0}/README.md +2 -2
- {mintmark-0.2.0 → mintmark-0.3.0}/packs/example/pack.yaml +1 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/pyproject.toml +1 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/schemas/manifest.schema.json +3 -3
- {mintmark-0.2.0 → mintmark-0.3.0}/schemas/pack.schema.json +3 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/cli.py +124 -9
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/emit/__init__.py +2 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/emit/csv_writer.py +24 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/engine/draws.py +20 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/engine/records.py +30 -9
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/engine/version.py +1 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/lexicons/data/special_descriptors.yaml +27 -41
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/lexicons/denylist.py +20 -2
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/manifest/io.py +67 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/manifest/verify.py +227 -151
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/mint.py +132 -92
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/packs/model.py +22 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/packs/alias/pack.yaml +1 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/packs/anchor/pack.yaml +1 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/packs/bad-name-pattern/pack.yaml +1 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/packs/duplicate-key/pack.yaml +1 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/packs/float-weight/pack.yaml +1 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/packs/merge-key/pack.yaml +1 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/packs/missing-schema-version/pack.yaml +1 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/packs/multiple-documents/pack.yaml +1 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/packs/unknown-field/pack.yaml +1 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/packs/valid/pack.yaml +1 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/packs/wrong-locale/pack.yaml +1 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/test_numeric_resource_limits.py +12 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/test_tamper_detection.py +61 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/conformance/pack/pack.yaml +1 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/golden/demo-run/DIGESTS.json +5 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/golden/demo-run/transaction.jsonl +97 -97
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/property/test_records.py +48 -5
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_declared_controls.py +154 -9
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_denylist.py +12 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_emit.py +12 -0
- mintmark-0.3.0/tests/unit/test_special_descriptors.py +42 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_workflows.py +5 -1
- {mintmark-0.2.0 → mintmark-0.3.0}/.gitignore +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/LICENSE +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/NOTICE +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/assets/brand/mintmark-logo.png +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/assets/brand/mintmark-logo.svg +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/assets/denylist/institutions-tr.txt +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/assets/readme/family-topology.png +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/assets/readme/family-topology.svg +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/assets/readme/mint-pipeline.png +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/assets/readme/mint-pipeline.svg +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/assets/tables/CHECKSUMS +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/assets/tables/balances.json +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/assets/tables/txn_amounts.json +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/packs/example/README.md +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/packs/example/fields/customer.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/packs/example/fields/transaction.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/packs/example/recipes/demo.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/packs/example/templates/txn_descriptions/set.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/__init__.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/annotate/__init__.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/annotate/render.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/annotate/sidecar.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/annotate/spans.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/annotate/taxonomy.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/api.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/emit/canonical.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/emit/writer.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/engine/__init__.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/engine/fold.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/engine/prng.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/engine/streams.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/engine/tables.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/engine/templates.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/identifiers/__init__.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/identifiers/email.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/identifiers/iban.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/identifiers/pan.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/identifiers/phone.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/identifiers/policy.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/identifiers/tckn.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/identifiers/vkn.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/lexicons/__init__.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/lexicons/data/given_names_tr.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/lexicons/data/occupations_tr.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/lexicons/data/provinces_tr.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/lexicons/data/street_parts_tr.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/lexicons/data/surnames_tr.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/manifest/__init__.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/manifest/document.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/manifest/safety.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/manifest/sums.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/packs/__init__.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/packs/digest.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/packs/loader.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/packs/semver.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/src/mintmark/py.typed +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/packs/empty-file/pack.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/packs/non-mapping-root/pack.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/packs/open-ended-requires-core/pack.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/packs/tab-indentation/pack.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/test_pack_rejection.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/adversarial/test_template_grammar.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/conformance/pack/fields/account.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/conformance/pack/fields/card.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/conformance/pack/fields/complaint_ticket.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/conformance/pack/fields/customer.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/conformance/pack/fields/kyc_note.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/conformance/pack/fields/support_transcript.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/conformance/pack/fields/transaction.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/conformance/pack/lexicons/ratings.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/conformance/pack/recipes/full.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/conformance/pack/templates/complaints/set.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/conformance/pack/templates/kyc_notes/set.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/conformance/pack/templates/transcripts/set.yaml +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/conformance/test_contract_coverage.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/conftest.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/golden/demo-run/customer.jsonl +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/golden/demo-run/transaction.labels.jsonl +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/golden/prng_vectors.json +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/golden/test_golden_bytes.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/property/test_draws.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/property/test_fold_and_email.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/property/test_render.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/property/test_safe_mode_purity.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/property/test_span_alignment.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_canary.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_cli.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_community_mirrors.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_mint_invariants.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_module_boundaries.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_no_libm.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_pack_digest.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_packaging.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_prng.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_prose_lint.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_readme_mirror.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_repository_inventory.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_streams.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_tables.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_taxonomy.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tests/unit/test_toolchain.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tools/canary.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tools/gen_tables.py +0 -0
- {mintmark-0.2.0 → mintmark-0.3.0}/tools/mdlint.py +0 -0
|
@@ -11,6 +11,46 @@ output for a fixed set of inputs. A change that alters emitted bytes for a fixed
|
|
|
11
11
|
seed is a major version event even when no signature changed, because it breaks
|
|
12
12
|
the reproducibility of every published manifest.
|
|
13
13
|
|
|
14
|
+
## 0.3.0 - 2026-08-23
|
|
15
|
+
|
|
16
|
+
### Security
|
|
17
|
+
|
|
18
|
+
- HEALTH descriptors are condition classes only; treatment, surgery, therapy,
|
|
19
|
+
appointment, and examination phrases are no longer emitted under that label.
|
|
20
|
+
- ETHNICITY no longer labels language/accommodation requests, and SEXUAL_LIFE no
|
|
21
|
+
longer labels marital or family-status phrases. Independent tests define the
|
|
22
|
+
forbidden semantic boundaries rather than trusting the descriptor file as its
|
|
23
|
+
own oracle.
|
|
24
|
+
- CSV emission rejects string cells whose first meaningful character is a
|
|
25
|
+
spreadsheet formula trigger (`=`, `+`, `-`, or `@`), including whitespace- and
|
|
26
|
+
control-prefixed forms. It fails closed instead of changing the source value or
|
|
27
|
+
emitting active spreadsheet content.
|
|
28
|
+
|
|
29
|
+
The descriptor corrections move document bytes for fixed seeds and therefore
|
|
30
|
+
constitute a version event under this project's reproducibility contract.
|
|
31
|
+
|
|
32
|
+
## 0.2.1 - 2026-08-23
|
|
33
|
+
|
|
34
|
+
### Security
|
|
35
|
+
|
|
36
|
+
- Template, enum, and reference-distribution weights are scaled once per
|
|
37
|
+
declaration rather than reparsed in record-count-multiplied hot loops. Pack
|
|
38
|
+
entity lexicon references are unique and bounded, and their surfaces are
|
|
39
|
+
composed once per mint.
|
|
40
|
+
- Mint generation streams records and label sidecars into the private staging
|
|
41
|
+
directory. It retains only reference identifiers, enforces per-file and
|
|
42
|
+
aggregate output-byte budgets, and still commits atomically after the safe
|
|
43
|
+
identifier invariant succeeds.
|
|
44
|
+
- Dataset verification streams JSONL, CSV, and label sidecars under line, file,
|
|
45
|
+
aggregate-byte, record, and diagnostic-count budgets. Semantic claims are
|
|
46
|
+
accumulated without retaining every parsed record.
|
|
47
|
+
- Validator identifier mode now requires an affirmative caller choice even when
|
|
48
|
+
a recipe requires it. An omitted CLI or API policy is always `safe`; recipe
|
|
49
|
+
binding and exact-policy reproduction remain enforced.
|
|
50
|
+
|
|
51
|
+
No generated record or sidecar bytes move for the same pack, recipe, seed,
|
|
52
|
+
format, and explicit policy. Manifests record the patch engine version.
|
|
53
|
+
|
|
14
54
|
## 0.2.0 - 2026-08-23
|
|
15
55
|
|
|
16
56
|
A security and conformance review of the three sector packs found one defect
|
|
@@ -319,3 +359,11 @@ and the name was still provisional. Both changed later the same day, in 0.1.1 an
|
|
|
319
359
|
in the trademark clearance recorded in TRADEMARKS.md. This note is left as it was
|
|
320
360
|
written rather than edited, because a changelog that quietly updates itself stops
|
|
321
361
|
being a record.
|
|
362
|
+
- Denylist comparisons now use compatibility normalization and remove combining
|
|
363
|
+
and default-ignorable characters, closing NFD, full-width, and zero-width
|
|
364
|
+
obfuscation bypasses without changing emitted span offsets.
|
|
365
|
+
- Relationship allocation now enforces declared per-parent bounds and rejects
|
|
366
|
+
infeasible recipe totals before generation.
|
|
367
|
+
- `packcheck` now exhaustively scans lexicons, field literals and parameters,
|
|
368
|
+
and every bounded template branch for denylisted entities and checksum-valid
|
|
369
|
+
identifier literals; its mini-mints preserve relationship constraints.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mintmark
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.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="925 tests" src="https://img.shields.io/badge/tests-925-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.3.0"><img alt="Release v0.3.0" src="https://img.shields.io/badge/release-v0.3.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>
|
|
@@ -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="925 tests" src="https://img.shields.io/badge/tests-925-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.3.0"><img alt="Release v0.3.0" src="https://img.shields.io/badge/release-v0.3.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>
|
|
@@ -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.3,<0.4"
|
|
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.
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "mintmark"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.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"
|
|
@@ -211,7 +211,7 @@
|
|
|
211
211
|
"records": {
|
|
212
212
|
"type": "integer",
|
|
213
213
|
"minimum": 0,
|
|
214
|
-
"maximum":
|
|
214
|
+
"maximum": 1000000
|
|
215
215
|
}
|
|
216
216
|
}
|
|
217
217
|
}
|
|
@@ -292,12 +292,12 @@
|
|
|
292
292
|
"target": {
|
|
293
293
|
"type": "integer",
|
|
294
294
|
"minimum": 0,
|
|
295
|
-
"maximum":
|
|
295
|
+
"maximum": 1000000
|
|
296
296
|
},
|
|
297
297
|
"achieved": {
|
|
298
298
|
"type": "integer",
|
|
299
299
|
"minimum": 0,
|
|
300
|
-
"maximum":
|
|
300
|
+
"maximum": 1000000
|
|
301
301
|
},
|
|
302
302
|
"met": {
|
|
303
303
|
"type": "boolean"
|
|
@@ -76,6 +76,8 @@
|
|
|
76
76
|
"additionalProperties": {
|
|
77
77
|
"type": "array",
|
|
78
78
|
"minItems": 1,
|
|
79
|
+
"maxItems": 128,
|
|
80
|
+
"uniqueItems": true,
|
|
79
81
|
"items": {
|
|
80
82
|
"type": "string",
|
|
81
83
|
"pattern": "^[a-z][a-z0-9_]*$"
|
|
@@ -287,7 +289,7 @@
|
|
|
287
289
|
"safe",
|
|
288
290
|
"validator"
|
|
289
291
|
],
|
|
290
|
-
"description": "The policy this recipe is minted under. Binding: a mint that asks for a different one is refused.
|
|
292
|
+
"description": "The policy this recipe is minted under. Binding: a mint that asks for a different one is refused. Validator mode still requires an explicit caller opt-in; an omitted caller choice is always safe."
|
|
291
293
|
}
|
|
292
294
|
}
|
|
293
295
|
},
|
|
@@ -31,7 +31,18 @@ from pathlib import Path
|
|
|
31
31
|
from typing import Any
|
|
32
32
|
|
|
33
33
|
from mintmark.annotate import Label, pin_digest
|
|
34
|
-
from mintmark.
|
|
34
|
+
from mintmark.engine.templates import (
|
|
35
|
+
Alternation,
|
|
36
|
+
EntitySlot,
|
|
37
|
+
FieldSlot,
|
|
38
|
+
IdentifierSlot,
|
|
39
|
+
LexiconSlot,
|
|
40
|
+
Literal,
|
|
41
|
+
Optional,
|
|
42
|
+
parse_template,
|
|
43
|
+
)
|
|
44
|
+
from mintmark.identifiers import ALL_ENGINES, CHECKSUMMED
|
|
45
|
+
from mintmark.lexicons import load as load_denylist
|
|
35
46
|
from mintmark.manifest import (
|
|
36
47
|
MANIFEST_FILENAME,
|
|
37
48
|
SUMS_FILENAME,
|
|
@@ -46,7 +57,8 @@ from mintmark.manifest.io import (
|
|
|
46
57
|
DatasetIOError,
|
|
47
58
|
DatasetReader,
|
|
48
59
|
)
|
|
49
|
-
from mintmark.
|
|
60
|
+
from mintmark.manifest.safety import identifier_candidates, scalar_texts
|
|
61
|
+
from mintmark.mint import MintError, asset_dir, mint, packaged_pack_dir, resolve_pack, schema_dir
|
|
50
62
|
from mintmark.packs.loader import PackError
|
|
51
63
|
from mintmark.packs.model import load_pack
|
|
52
64
|
|
|
@@ -98,8 +110,8 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
98
110
|
mint_parser.add_argument(
|
|
99
111
|
"--identifier-policy",
|
|
100
112
|
choices=["safe", "validator"],
|
|
101
|
-
default=
|
|
102
|
-
help="
|
|
113
|
+
default="safe",
|
|
114
|
+
help="safe by default; validator requires an explicit caller opt-in",
|
|
103
115
|
)
|
|
104
116
|
mint_parser.add_argument("--format", choices=["jsonl", "csv"], default="jsonl")
|
|
105
117
|
mint_parser.add_argument("--json", action="store_true")
|
|
@@ -433,17 +445,116 @@ def _locate_pack(directory: Path, name: str) -> Path | None:
|
|
|
433
445
|
return None
|
|
434
446
|
|
|
435
447
|
|
|
448
|
+
MAX_TEMPLATE_SAFETY_EXPANSIONS = 10_000
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
def _literal_expansions(nodes: tuple[Any, ...]) -> tuple[str, ...]:
|
|
452
|
+
"""Enumerate every literal grammar branch under a strict cross-product cap."""
|
|
453
|
+
outputs = [""]
|
|
454
|
+
for node in nodes:
|
|
455
|
+
variants: tuple[str, ...]
|
|
456
|
+
match node:
|
|
457
|
+
case Literal(text=text):
|
|
458
|
+
variants = (text,)
|
|
459
|
+
case FieldSlot() | EntitySlot() | IdentifierSlot() | LexiconSlot():
|
|
460
|
+
variants = (" ",)
|
|
461
|
+
case Alternation(branches=branches):
|
|
462
|
+
variants = tuple(
|
|
463
|
+
rendering for branch in branches for rendering in _literal_expansions(branch)
|
|
464
|
+
)
|
|
465
|
+
case Optional(body=body):
|
|
466
|
+
variants = ("", *_literal_expansions(body))
|
|
467
|
+
case _:
|
|
468
|
+
raise AssertionError(f"unknown template node {node!r}")
|
|
469
|
+
if len(outputs) * len(variants) > MAX_TEMPLATE_SAFETY_EXPANSIONS:
|
|
470
|
+
raise ValueError(
|
|
471
|
+
f"template expands beyond {MAX_TEMPLATE_SAFETY_EXPANSIONS} safety branches"
|
|
472
|
+
)
|
|
473
|
+
outputs = [prefix + suffix for prefix in outputs for suffix in variants]
|
|
474
|
+
return tuple(outputs)
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
def _pack_safety(pack_root: Path, loaded: Any) -> tuple[Any, list[str]]:
|
|
478
|
+
"""Exhaustively inspect declaration-controlled emitted strings."""
|
|
479
|
+
core = load_denylist(asset_dir("denylist") / "institutions-tr.txt")
|
|
480
|
+
extension_path = pack_root / "lexicons" / "denylist_extension.txt"
|
|
481
|
+
matcher = load_denylist(extension_path) if extension_path.exists() else core
|
|
482
|
+
problems: list[str] = []
|
|
483
|
+
if not matcher.covers(core):
|
|
484
|
+
missing = sorted(matcher.missing_from(core))[:5]
|
|
485
|
+
problems.append(f"denylist extension omits core entries: {missing}")
|
|
486
|
+
|
|
487
|
+
surfaces: list[tuple[str, str]] = []
|
|
488
|
+
for name, values in loaded.lexicons.items():
|
|
489
|
+
surfaces.extend((f"lexicon {name}", value) for value in values)
|
|
490
|
+
for record_type in loaded.record_types:
|
|
491
|
+
for field in record_type.fields:
|
|
492
|
+
source = f"field {record_type.type_name}.{field.name}"
|
|
493
|
+
if field.generator_kind == "literal":
|
|
494
|
+
surfaces.append((source, field.generator_argument))
|
|
495
|
+
surfaces.extend((source, text) for text in scalar_texts(field.params))
|
|
496
|
+
for set_name, entries in loaded.template_sets.items():
|
|
497
|
+
for entry in entries:
|
|
498
|
+
nodes = parse_template(
|
|
499
|
+
entry.text,
|
|
500
|
+
template_id=entry.id,
|
|
501
|
+
known_labels=frozenset(label.value for label in Label),
|
|
502
|
+
known_identifiers=frozenset(ALL_ENGINES),
|
|
503
|
+
known_lexicons=frozenset(loaded.lexicons),
|
|
504
|
+
)
|
|
505
|
+
try:
|
|
506
|
+
renderings = _literal_expansions(nodes)
|
|
507
|
+
except ValueError as exc:
|
|
508
|
+
problems.append(f"template {set_name}/{entry.id}: {exc}")
|
|
509
|
+
continue
|
|
510
|
+
surfaces.extend((f"template {set_name}/{entry.id}", text) for text in renderings)
|
|
511
|
+
|
|
512
|
+
for source, surface in surfaces:
|
|
513
|
+
for hit in matcher.scan(surface):
|
|
514
|
+
problems.append(f"{source}: {hit.render()}")
|
|
515
|
+
for candidate in identifier_candidates(surface):
|
|
516
|
+
valid_as = [
|
|
517
|
+
name for name, engine in CHECKSUMMED.items() if engine.is_checksum_valid(candidate)
|
|
518
|
+
]
|
|
519
|
+
if valid_as:
|
|
520
|
+
problems.append(
|
|
521
|
+
f"{source}: checksum-valid {'/'.join(valid_as)} literal {candidate!r} "
|
|
522
|
+
"is forbidden by safe policy"
|
|
523
|
+
)
|
|
524
|
+
return matcher, problems
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
def _mini_record_counts(loaded: Any, recipe: Any) -> dict[str, int]:
|
|
528
|
+
"""Shrink a valid recipe while retaining every relationship bound."""
|
|
529
|
+
selected = {name: min(25, count) for name, count in recipe.records.items()}
|
|
530
|
+
for record_type in loaded.record_types:
|
|
531
|
+
for field in record_type.fields:
|
|
532
|
+
if field.ref is None:
|
|
533
|
+
continue
|
|
534
|
+
if selected.get(record_type.type_name, 0) == 0:
|
|
535
|
+
continue
|
|
536
|
+
parents = selected.get(field.ref.parent, 0)
|
|
537
|
+
low = parents * min(field.ref.counts)
|
|
538
|
+
high = parents * max(field.ref.counts)
|
|
539
|
+
selected[record_type.type_name] = min(
|
|
540
|
+
max(selected.get(record_type.type_name, 0), low), high
|
|
541
|
+
)
|
|
542
|
+
return selected
|
|
543
|
+
|
|
544
|
+
|
|
436
545
|
def _cmd_packcheck(args: argparse.Namespace) -> int:
|
|
437
546
|
pack_root = resolve_pack(args.pack)
|
|
438
547
|
loaded = load_pack(pack_root)
|
|
439
548
|
|
|
440
549
|
problems: list[str] = []
|
|
441
550
|
warnings: list[str] = []
|
|
551
|
+
matcher, safety_problems = _pack_safety(pack_root, loaded)
|
|
552
|
+
problems.extend(safety_problems)
|
|
442
553
|
|
|
443
554
|
with tempfile.TemporaryDirectory() as temporary:
|
|
444
555
|
for recipe_name, recipe in sorted(loaded.recipes.items()):
|
|
445
556
|
out = Path(temporary) / f"mini-{recipe_name}"
|
|
446
|
-
overrides =
|
|
557
|
+
overrides = _mini_record_counts(loaded, recipe)
|
|
447
558
|
try:
|
|
448
559
|
mint(
|
|
449
560
|
pack=pack_root,
|
|
@@ -467,12 +578,16 @@ def _cmd_packcheck(args: argparse.Namespace) -> int:
|
|
|
467
578
|
problems.extend(f"recipe {recipe_name}: {p}" for p in report.problems)
|
|
468
579
|
|
|
469
580
|
document = read_manifest(out)
|
|
581
|
+
for output in document["outputs"]:
|
|
582
|
+
output_path = out / output["path"]
|
|
583
|
+
for hit in matcher.scan(output_path.read_text(encoding="utf-8")):
|
|
584
|
+
problems.append(f"recipe {recipe_name}: {output['path']}: {hit.render()}")
|
|
470
585
|
for stat in document["stats"]["coverage_targets"]:
|
|
471
|
-
|
|
472
|
-
if stat["achieved"] * max(1, sum(recipe.records.values())) <
|
|
473
|
-
|
|
586
|
+
scaled_target = stat["target"] * max(1, sum(overrides.values()))
|
|
587
|
+
if stat["achieved"] * max(1, sum(recipe.records.values())) < scaled_target:
|
|
588
|
+
problems.append(
|
|
474
589
|
f"recipe {recipe_name}: coverage target {stat['label']}="
|
|
475
|
-
f"{stat['target']}
|
|
590
|
+
f"{stat['target']} is infeasible at the declared counts"
|
|
476
591
|
)
|
|
477
592
|
shutil.rmtree(out, ignore_errors=True)
|
|
478
593
|
|
|
@@ -10,12 +10,13 @@ from mintmark.emit.canonical import (
|
|
|
10
10
|
FloatInOutputError,
|
|
11
11
|
render_record,
|
|
12
12
|
)
|
|
13
|
-
from mintmark.emit.csv_writer import csv_header, render_csv_row
|
|
13
|
+
from mintmark.emit.csv_writer import SpreadsheetFormulaError, csv_header, render_csv_row
|
|
14
14
|
from mintmark.emit.writer import StagedOutput, staged_output
|
|
15
15
|
|
|
16
16
|
__all__ = [
|
|
17
17
|
"CanonicalEncoder",
|
|
18
18
|
"FloatInOutputError",
|
|
19
|
+
"SpreadsheetFormulaError",
|
|
19
20
|
"StagedOutput",
|
|
20
21
|
"csv_header",
|
|
21
22
|
"render_csv_row",
|
|
@@ -13,9 +13,14 @@ from __future__ import annotations
|
|
|
13
13
|
|
|
14
14
|
import csv
|
|
15
15
|
import io
|
|
16
|
+
import re
|
|
16
17
|
from typing import Any
|
|
17
18
|
|
|
18
19
|
|
|
20
|
+
class SpreadsheetFormulaError(ValueError):
|
|
21
|
+
"""A string cell would be interpreted as active content by spreadsheets."""
|
|
22
|
+
|
|
23
|
+
|
|
19
24
|
def csv_header(field_order: tuple[str, ...]) -> str:
|
|
20
25
|
"""The header row, in declaration order, RFC 4180 quoted, LF terminated."""
|
|
21
26
|
return _render_row(list(field_order))
|
|
@@ -40,10 +45,29 @@ def render_csv_row(record: dict[str, Any], field_order: tuple[str, ...]) -> str:
|
|
|
40
45
|
f"field {name!r} carries a {type(value).__name__}, which has no CSV "
|
|
41
46
|
"representation. Emit this record type as JSONL, or flatten the field."
|
|
42
47
|
)
|
|
48
|
+
if isinstance(value, str) and _formula_prefix(value) is not None:
|
|
49
|
+
raise SpreadsheetFormulaError(
|
|
50
|
+
f"field {name!r} begins with spreadsheet formula trigger "
|
|
51
|
+
f"{_formula_prefix(value)!r}; CSV emission refuses active cells"
|
|
52
|
+
)
|
|
43
53
|
cells.append("" if value is None else str(value))
|
|
44
54
|
return _render_row(cells)
|
|
45
55
|
|
|
46
56
|
|
|
57
|
+
def _formula_prefix(value: str) -> str | None:
|
|
58
|
+
position = 0
|
|
59
|
+
while position < len(value) and (value[position].isspace() or ord(value[position]) < 0x20):
|
|
60
|
+
position += 1
|
|
61
|
+
candidate = value[position:]
|
|
62
|
+
if re.fullmatch(r"[+-]\d+(?:\.\d+)?", candidate) or re.fullmatch(
|
|
63
|
+
r"\+90 5\d{2} \d{3} \d{2} \d{2}", candidate
|
|
64
|
+
):
|
|
65
|
+
return None
|
|
66
|
+
if candidate.startswith(("=", "+", "-", "@")):
|
|
67
|
+
return candidate[0]
|
|
68
|
+
return None
|
|
69
|
+
|
|
70
|
+
|
|
47
71
|
def _render_row(cells: list[str]) -> str:
|
|
48
72
|
buffer = io.StringIO()
|
|
49
73
|
writer = csv.writer(buffer, lineterminator="\n", quoting=csv.QUOTE_MINIMAL)
|
|
@@ -16,6 +16,7 @@ tolerate.
|
|
|
16
16
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
|
+
from collections.abc import Sequence
|
|
19
20
|
from dataclasses import dataclass
|
|
20
21
|
from decimal import Decimal, InvalidOperation
|
|
21
22
|
|
|
@@ -126,8 +127,26 @@ def weighted_index(stream: SplitMix64, weights: list[str]) -> int:
|
|
|
126
127
|
weights first would change which index a given draw selects and therefore
|
|
127
128
|
change emitted bytes for a fixed seed.
|
|
128
129
|
"""
|
|
129
|
-
|
|
130
|
+
return weighted_index_scaled(stream, scale_weights(weights))
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def weighted_index_scaled(stream: SplitMix64, scaled: Sequence[int]) -> int:
|
|
134
|
+
"""Draw from weights that were validated and scaled at declaration load time.
|
|
135
|
+
|
|
136
|
+
Generation hot paths call this form so a pack with thousands of choices
|
|
137
|
+
cannot multiply decimal parsing by its record count. The caller must retain
|
|
138
|
+
declaration order; doing so preserves the exact draw made by
|
|
139
|
+
:func:`weighted_index`.
|
|
140
|
+
"""
|
|
141
|
+
if not scaled:
|
|
142
|
+
raise ValueError("scaled weights must not be empty")
|
|
143
|
+
if any(
|
|
144
|
+
not isinstance(weight, int) or isinstance(weight, bool) or weight < 0 for weight in scaled
|
|
145
|
+
):
|
|
146
|
+
raise ValueError("scaled weights must be non-negative integers")
|
|
130
147
|
total = sum(scaled)
|
|
148
|
+
if total <= 0:
|
|
149
|
+
raise ValueError("scaled weights sum to zero")
|
|
131
150
|
target = bounded(stream, total)
|
|
132
151
|
cumulative = 0
|
|
133
152
|
for index, weight in enumerate(scaled):
|
|
@@ -25,7 +25,7 @@ from dataclasses import dataclass
|
|
|
25
25
|
from dataclasses import field as dataclass_field
|
|
26
26
|
from typing import Any
|
|
27
27
|
|
|
28
|
-
from mintmark.engine.draws import bounded, weighted_index
|
|
28
|
+
from mintmark.engine.draws import bounded, scale_weights, weighted_index, weighted_index_scaled
|
|
29
29
|
from mintmark.engine.streams import StreamFactory
|
|
30
30
|
|
|
31
31
|
# One record is an ordered mapping of field name to emitted value. Order is the
|
|
@@ -118,9 +118,9 @@ def assign_children(
|
|
|
118
118
|
"""Return one parent index per child, honoring the count distribution.
|
|
119
119
|
|
|
120
120
|
The distribution says how many children each parent should have. The recipe
|
|
121
|
-
says how many children exist.
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
says how many children exist. The requested total must fit the declared
|
|
122
|
+
per-parent minimum and maximum; deterministic adjustment never crosses those
|
|
123
|
+
bounds.
|
|
124
124
|
"""
|
|
125
125
|
if parent_count <= 0:
|
|
126
126
|
if child_count > 0:
|
|
@@ -129,11 +129,27 @@ def assign_children(
|
|
|
129
129
|
"a reference cannot dangle"
|
|
130
130
|
)
|
|
131
131
|
return []
|
|
132
|
+
if child_count == 0:
|
|
133
|
+
# A recipe may explicitly disable a record type. Cardinality applies
|
|
134
|
+
# when that relationship is present, not to a type the recipe omits.
|
|
135
|
+
return []
|
|
136
|
+
|
|
137
|
+
minimum = min(counts)
|
|
138
|
+
maximum = max(counts)
|
|
139
|
+
minimum_total = parent_count * minimum
|
|
140
|
+
maximum_total = parent_count * maximum
|
|
141
|
+
if not minimum_total <= child_count <= maximum_total:
|
|
142
|
+
raise ValueError(
|
|
143
|
+
f"{site}: {child_count} children cannot satisfy {minimum}..{maximum} "
|
|
144
|
+
f"children for each of {parent_count} parents; feasible total is "
|
|
145
|
+
f"{minimum_total}..{maximum_total}"
|
|
146
|
+
)
|
|
132
147
|
|
|
133
148
|
per_parent: list[int] = []
|
|
149
|
+
scaled_weights = scale_weights(list(weights))
|
|
134
150
|
for parent_index in range(parent_count):
|
|
135
151
|
stream = factory.stream(f"{site}/{parent_index}/count")
|
|
136
|
-
per_parent.append(counts[
|
|
152
|
+
per_parent.append(counts[weighted_index_scaled(stream, scaled_weights)])
|
|
137
153
|
|
|
138
154
|
total = sum(per_parent)
|
|
139
155
|
if total > child_count:
|
|
@@ -143,21 +159,26 @@ def assign_children(
|
|
|
143
159
|
for parent_index in range(parent_count - 1, -1, -1):
|
|
144
160
|
if surplus == 0:
|
|
145
161
|
break
|
|
146
|
-
take = min(per_parent[parent_index], surplus)
|
|
162
|
+
take = min(per_parent[parent_index] - minimum, surplus)
|
|
147
163
|
per_parent[parent_index] -= take
|
|
148
164
|
surplus -= take
|
|
149
165
|
elif total < child_count:
|
|
150
166
|
deficit = child_count - total
|
|
151
167
|
parent_index = 0
|
|
152
168
|
while deficit > 0:
|
|
153
|
-
|
|
169
|
+
selected = parent_index % parent_count
|
|
154
170
|
parent_index += 1
|
|
155
|
-
|
|
171
|
+
if per_parent[selected] < maximum:
|
|
172
|
+
per_parent[selected] += 1
|
|
173
|
+
deficit -= 1
|
|
174
|
+
|
|
175
|
+
if sum(per_parent) != child_count:
|
|
176
|
+
raise AssertionError(f"{site}: bounded relationship allocation did not converge")
|
|
156
177
|
|
|
157
178
|
assignment: list[int] = []
|
|
158
179
|
for parent_index, count in enumerate(per_parent):
|
|
159
180
|
assignment.extend([parent_index] * count)
|
|
160
|
-
return assignment
|
|
181
|
+
return assignment
|
|
161
182
|
|
|
162
183
|
|
|
163
184
|
@dataclass(slots=True)
|
|
@@ -11,24 +11,18 @@ labels:
|
|
|
11
11
|
values:
|
|
12
12
|
- kronik rahatsızlık
|
|
13
13
|
- geçici iş göremezlik
|
|
14
|
-
- rutin kontrol
|
|
15
|
-
- istirahat raporu
|
|
16
|
-
- kontrol randevusu
|
|
17
|
-
- ameliyat sonrası izin
|
|
18
|
-
- sağlık raporu
|
|
19
|
-
- tedavi süreci
|
|
20
|
-
- fizik tedavi programı
|
|
21
|
-
- doğum öncesi izin
|
|
22
|
-
- iş kazası sonrası rapor
|
|
23
|
-
- sevk belgesi
|
|
24
|
-
- kontrol izni
|
|
25
|
-
- rapor uzatma talebi
|
|
26
|
-
- iş göremezlik bildirimi
|
|
27
14
|
- engel durumu beyanı
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
15
|
+
- sağlık durumu beyanı
|
|
16
|
+
- mesleki sağlık kısıtı
|
|
17
|
+
- hareket kısıtlılığı beyanı
|
|
18
|
+
- görme desteği ihtiyacı
|
|
19
|
+
- işitme desteği ihtiyacı
|
|
20
|
+
- alerji durumu beyanı
|
|
21
|
+
- solunum hassasiyeti beyanı
|
|
22
|
+
- kas iskelet kısıtı beyanı
|
|
23
|
+
- süreli sağlık kısıtı
|
|
24
|
+
- kalıcı sağlık kısıtı
|
|
25
|
+
- bulaşıcı olmayan rahatsızlık sınıfı
|
|
32
26
|
RELIGION:
|
|
33
27
|
note: Observance and accommodation, not belief content.
|
|
34
28
|
values:
|
|
@@ -45,20 +39,16 @@ labels:
|
|
|
45
39
|
- inanç temelli mazeret bildirimi
|
|
46
40
|
- ibadet alanı talebi
|
|
47
41
|
ETHNICITY:
|
|
48
|
-
note: Declared
|
|
42
|
+
note: Declared ethnic or cultural origin only, as a form would record it.
|
|
49
43
|
values:
|
|
50
44
|
- etnik köken beyanı
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
- kültürel uyum notu
|
|
59
|
-
- isim yazımı düzeltme talebi
|
|
60
|
-
- çeviri desteği kaydı
|
|
61
|
-
- ana dilde bilgilendirme talebi
|
|
45
|
+
- soy kökeni beyanı
|
|
46
|
+
- kültürel köken beyanı
|
|
47
|
+
- etnik kimlik beyanı
|
|
48
|
+
- azınlık grubu aidiyeti beyanı
|
|
49
|
+
- etnik topluluk aidiyeti
|
|
50
|
+
- aile kökeni bölgesi beyanı
|
|
51
|
+
- köken bilgisi formu
|
|
62
52
|
POLITICAL:
|
|
63
53
|
note: Fictional parties and civic bodies. No real party is ever named.
|
|
64
54
|
values:
|
|
@@ -77,18 +67,14 @@ labels:
|
|
|
77
67
|
SEXUAL_LIFE:
|
|
78
68
|
note: Form-level references only. Never narrative, never detail.
|
|
79
69
|
values:
|
|
80
|
-
-
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
-
-
|
|
88
|
-
- eş sağlık kapsamı talebi
|
|
89
|
-
- boşanma durumu güncellemesi
|
|
90
|
-
- birliktelik beyanı formu
|
|
91
|
-
- aile içi durum bildirimi
|
|
70
|
+
- cinsel yaşam verisi beyanı
|
|
71
|
+
- cinsel yönelim beyanı
|
|
72
|
+
- mahrem ilişki bilgisi formu
|
|
73
|
+
- cinsel yaşam mahremiyet talebi
|
|
74
|
+
- cinsel yaşama ilişkin veri düzeltme talebi
|
|
75
|
+
- mahrem partner bilgisi beyanı
|
|
76
|
+
- cinsel yaşama ilişkin erişim kısıtı
|
|
77
|
+
- cinsel yaşam verisi silme talebi
|
|
92
78
|
CRIMINAL:
|
|
93
79
|
note: Check categories, never findings. 'A record was requested' is a process step; 'a record
|
|
94
80
|
exists' would be an accusation about a person, and this project does not make those even
|