diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..70754be --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,30 @@ +## Summary + +Describe the geospatial failure mode or repository problem and the smallest coherent change that +addresses it. + +## Contract + +- Behavior changed: +- Behavior intentionally unchanged: +- Compatibility or schema impact: + +## Verification + +List commands, fixtures, or checks actually run and their outcomes. + +For diagnostic-rule changes, include the relevant `PASS / FAIL / UNKNOWN / NOT_APPLICABLE` +coverage and any `must_not_report` cases. + +## Risk + +Describe remaining correctness, geospatial-semantic, security, compatibility, performance, or +operational risk. + +## Scope check + +- [ ] The change has one coherent purpose. +- [ ] Unrelated cleanup is excluded. +- [ ] Tests or integration fixtures cover changed behavior where practical. +- [ ] Public rule, schema, CLI, or Python API documentation is updated when its contract changes. +- [ ] Expensive scans remain explicit rather than becoming an accidental default. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..113a5ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,91 @@ +# Contributing + +Contributions should make GeoDebug more correct, more explicit, or easier to verify without +turning the project into a catalog of generic GIS advice. + +## Principles + +- Start from a concrete geospatial failure mode. +- Prefer deterministic evidence over model judgment. +- Keep adapters observational: adapters emit facts, not diagnostics. +- Keep rules pure: rules evaluate normalized facts and do not perform I/O. +- Preserve `UNKNOWN != PASS`. +- Avoid universal thresholds when the correct value depends on spatial context. +- Keep expensive scans explicit. +- Do not add automatic repair when the transformation can change scientific meaning. +- Keep public rule IDs, report schemas, and config schemas stable once released. + +## Development + +Requires Python 3.12 or newer. + +```bash +python -m venv .venv +source .venv/bin/activate +pip install -e '.[dev,all]' + +ruff check . +mypy src/geodebug +pytest +``` + +Before opening a change: + +1. run the focused tests for the behavior you changed, +2. run Ruff and strict Mypy, +3. run the relevant integration tests when an adapter or format changes, +4. inspect the complete diff, +5. update rule docs, schemas, or golden fixtures when the public contract changes. + +## Adding a diagnostic rule + +A rule should answer: + +- What concrete spatial failure does it detect? +- What evidence makes the conclusion deterministic, inferred, or heuristic? +- When does it apply? +- When must it return `UNKNOWN`? +- When is it `NOT_APPLICABLE`? +- What false positive would be most damaging? + +Every released rule must: + +1. use a stable `GEOxxx` identifier, +2. document its scope, default severity, certainty, and semantics, +3. exercise `PASS`, `FAIL`, `UNKNOWN`, and `NOT_APPLICABLE`, +4. add or update golden cases when cross-rule behavior changes, +5. include `must_not_report` coverage where adjacent rules could cascade. + +Do not create a rule merely because a GIS practice is common. Encode an invariant or a +well-bounded diagnostic condition. + +## Adding or changing an adapter + +Adapters normalize source-specific observations into GeoDebug facts. + +They must not: + +- choose diagnostic severity, +- emit `GEOxxx` findings, +- infer a missing CRS from plausible coordinates, +- silently trigger an expensive full scan in the metadata path. + +When changing an adapter, include an integration fixture that exercises the real dependency when +practical. + +## Changing public contracts + +Treat these as versioned interfaces: + +- released rule IDs and meanings, +- canonical report schema, +- project config schema, +- CLI exit behavior, +- documented Python API. + +Compatibility changes require documentation and a versioning decision. + +## Releases + +Follow [docs/releasing.md](docs/releasing.md). Do not move published tags. A release must keep the +package version, changelog, schemas, built artifacts, and eventual `v` tag consistent. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..97d1119 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 GeoGeekLab + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index db9d752..88886b0 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,12 @@ Deterministic diagnostics for geospatial data and workflows. [![CI](https://github.com/GeoGeekLab/geodebug/actions/workflows/ci.yml/badge.svg)](https://github.com/GeoGeekLab/geodebug/actions/workflows/ci.yml) -[![Release](https://img.shields.io/github/v/release/GeoGeekLab/geodebug?display_name=tag&sort=semver)](https://github.com/GeoGeekLab/geodebug/releases/latest) -[![Python](https://img.shields.io/badge/python-3.12%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/) -[![Typed](https://img.shields.io/badge/typing-strict-2F81F7)](pyproject.toml) +[![Release](https://img.shields.io/github/v/release/GeoGeekLab/geodebug?display_name=tag&sort=semver&style=flat-square)](https://github.com/GeoGeekLab/geodebug/releases/latest) +[![License: MIT](https://img.shields.io/badge/license-MIT-2ea44f?style=flat-square)](LICENSE) +[![Python](https://img.shields.io/badge/python-3.12%2B-3776AB?style=flat-square&logo=python&logoColor=white)](https://www.python.org/) +[![Typed](https://img.shields.io/badge/typing-strict-2F81F7?style=flat-square)](pyproject.toml) -[Architecture](docs/architecture.md) · [Rule catalog](docs/rules.md) · [Changelog](CHANGELOG.md) · [v0.1.0](https://github.com/GeoGeekLab/geodebug/releases/tag/v0.1.0) +[Architecture](docs/architecture.md) · [Rule catalog](docs/rules.md) · [Contributing](CONTRIBUTING.md) · [Security](SECURITY.md) · [Changelog](CHANGELOG.md) · [v0.1.0](https://github.com/GeoGeekLab/geodebug/releases/tag/v0.1.0) @@ -224,6 +225,26 @@ tests, and installation from a freshly built wheel. See [Architecture](docs/architecture.md), [Diagnostic rules](docs/rules.md), and [Releasing](docs/releasing.md) for the deeper contracts. +## Contributing + +Contributions should start from a concrete geospatial failure mode or a clearly bounded +engineering improvement. New diagnostics must preserve the four-state rule contract and include +false-positive coverage where adjacent rules can cascade. + +See [CONTRIBUTING.md](CONTRIBUTING.md). + +## Security + +Please report vulnerabilities privately through GitHub's security reporting features when +available. Do not publish exploit details in a public issue before a fix or mitigation is +available. + +See [SECURITY.md](SECURITY.md). + +## License + +[MIT](LICENSE) + ---
diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..f428693 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,32 @@ +# Security policy + +## Reporting a vulnerability + +Please report security issues privately through GitHub's security reporting features when +available. Do not publish exploit details in a public issue before a fix or mitigation is +available. + +A useful report includes the affected file, adapter, workflow, or data format; concrete impact; +reproduction steps; required preconditions; and suggested mitigation if known. + +## Scope + +GeoDebug reads geospatial files and metadata through Python geospatial libraries and can perform +explicit deep scans. Security reports are especially relevant when crafted or untrusted input can: + +- access files or paths outside the user-supplied target, +- cause unintended command execution, +- expose sensitive local data or configuration, +- trigger disproportionate CPU or memory consumption, +- bypass an explicit metadata-only or `--deep` boundary, +- corrupt or misrepresent the canonical diagnostic report, +- turn an unsafe operation into a misleadingly safe diagnostic result. + +GeoDebug does not automatically repair datasets and does not execute arbitrary fixes from +diagnostic output. + +## Dependency issues + +If the issue originates in GDAL, PROJ, GEOS, Rasterio, Pyogrio, PyArrow, GeoPandas, Shapely, or +another dependency, report it upstream when appropriate. GeoDebug reports are still useful when +its own adapter or policy layer makes the upstream issue exploitable or materially worse. diff --git a/pyproject.toml b/pyproject.toml index 90f012c..d4a9671 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,12 +8,15 @@ dynamic = ["version"] description = "Deterministic diagnostics for geospatial data and workflows." keywords = ["gis", "geospatial", "crs", "raster", "vector", "diagnostics"] readme = "README.md" +license = "MIT" +license-files = ["LICENSE"] requires-python = ">=3.12" authors = [{ name = "GeoGeekLab" }] classifiers = [ "Development Status :: 3 - Alpha", "Environment :: Console", "Operating System :: OS Independent", + "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13",