diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..0430b74 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,39 @@ +name: Bug report +description: Something does not work, or an estimate looks wrong +labels: [bug] +body: + - type: textarea + id: what + attributes: + label: What happened? + description: What did you do, what did you expect, and what happened instead? + validations: + required: true + - type: textarea + id: repro + attributes: + label: Minimal example + description: Code that reproduces it. `graphdml.datasets` generators make good shareable data. + render: python + validations: + required: true + - type: input + id: version + attributes: + label: graphdml version + placeholder: "python -c 'import graphdml; print(graphdml.__version__)'" + validations: + required: true + - type: input + id: python + attributes: + label: Python and OS + placeholder: "3.12 on macOS 15" + validations: + required: true + - type: textarea + id: output + attributes: + label: Output or traceback + description: Paste `model.summary()` for estimation questions, or the full error. + render: text diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..080b4ae --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Documentation + url: https://github.com/Samrdreyfuss/graphdml/tree/main/docs + about: Methodology, design choices, validation results, and the Neo4j guide. + - name: Report a security issue privately + url: https://github.com/Samrdreyfuss/graphdml/security/advisories/new + about: Please do not report vulnerabilities in a public issue. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..35d3ec4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,21 @@ +name: Feature request +description: Suggest an improvement or a new capability +labels: [enhancement] +body: + - type: textarea + id: problem + attributes: + label: What are you trying to do? + description: The use case, not just the feature. + validations: + required: true + - type: textarea + id: idea + attributes: + label: What would you like graphdml to do? + validations: + required: true + - type: textarea + id: alternatives + attributes: + label: Alternatives you considered diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..0d248e0 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,11 @@ +## What and why + + + +## Checklist + +- [ ] Tests added or updated, and `pytest` passes +- [ ] `ruff check .` is clean +- [ ] User-facing changes are in `CHANGELOG.md` (under Unreleased) +- [ ] Docs or README updated if behavior changed +- [ ] Changes that affect estimates keep `docs/methodology.md` accurate diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 524d54f..237fc87 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,7 +62,9 @@ jobs: runs-on: ubuntu-latest services: neo4j: - image: neo4j:5.26-community + # Pulled through Google's Docker Hub mirror: Docker Hub rate-limits anonymous pulls + # from shared CI runners, which made this job fail at random. + image: mirror.gcr.io/library/neo4j:5.26-community env: NEO4J_AUTH: neo4j/graphdml-ci NEO4J_PLUGINS: '["graph-data-science"]' diff --git a/CHANGELOG.md b/CHANGELOG.md index 48a62a0..1133c7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,9 @@ All notable changes to graphdml are listed here. Versions follow `make_toy_graph`. ### Improved +- Repository polish: code of conduct, security policy, issue forms and a pull-request + template; `py.typed` marker so type checkers use graphdml's annotations; CI pulls the Neo4j + test image through a mirror, which fixes random failures from Docker Hub rate limits. - `load_insurance_experiment` explains where to get the data when the files are missing, and `fetch_lastfm_asia` explains what to do when the download fails. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..dda7e5a --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,86 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our community a +harassment-free experience for everyone, regardless of age, body size, visible or invisible +disability, ethnicity, sex characteristics, gender identity and expression, level of +experience, education, socio-economic status, nationality, personal appearance, race, +caste, color, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, +inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, and learning + from the experience +* Focusing on what is best not just for us as individuals, but for the overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, without + their explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of acceptable +behavior and will take appropriate and fair corrective action in response to any behavior +that they deem inappropriate, threatening, offensive, or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject comments, +commits, code, wiki edits, issues, and other contributions that are not aligned to this +Code of Conduct, and will communicate reasons for moderation decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when an +individual is officially representing the community in public spaces. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the +project maintainer, Sam Dreyfuss, privately through GitHub: open a private report under +this repository's **Security** tab ("Report a vulnerability") and say that it is a conduct +report. All complaints will be reviewed and investigated promptly and fairly. All community +leaders are obligated to respect the privacy and security of the reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining the +consequences for any action they deem in violation of this Code of Conduct: + +1. **Correction.** *Community Impact:* use of inappropriate language or other behavior + deemed unprofessional or unwelcome in the community. *Consequence:* a private, written + warning from community leaders, providing clarity around the nature of the violation and + an explanation of why the behavior was inappropriate. A public apology may be requested. +2. **Warning.** *Community Impact:* a violation through a single incident or series of + actions. *Consequence:* a warning with consequences for continued behavior. No + interaction with the people involved, including unsolicited interaction with those + enforcing the Code of Conduct, for a specified period of time. This includes avoiding + interactions in community spaces as well as external channels. Violating these terms may + lead to a temporary or permanent ban. +3. **Temporary Ban.** *Community Impact:* a serious violation of community standards, + including sustained inappropriate behavior. *Consequence:* a temporary ban from any sort + of interaction or public communication with the community for a specified period of time. + No public or private interaction with the people involved is allowed during this period. + Violating these terms may lead to a permanent ban. +4. **Permanent Ban.** *Community Impact:* demonstrating a pattern of violation of community + standards, including sustained inappropriate behavior, harassment of an individual, or + aggression toward or disparagement of classes of individuals. *Consequence:* a permanent + ban from any sort of public interaction within the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), +version 2.1, available at +. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 09a1ca0..1bfd0e0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,6 +15,9 @@ docker compose up -d GRAPHDML_NEO4J_URI=bolt://localhost:7687 GRAPHDML_NEO4J_PASSWORD=graphdml-demo pytest tests/test_neo4j.py ``` +Work happens on the `dev` branch and reaches `main` through a pull request; `main` requires +the CI checks to pass. Please read the [code of conduct](CODE_OF_CONDUCT.md) first. + Changes that affect estimates should keep [docs/methodology.md](docs/methodology.md) accurate and pass the [validation protocol](docs/validation.md). The benchmarks in `benchmarks/` and `benchmarks/report.py` regenerate [docs/validation-results.md](docs/validation-results.md). diff --git a/README.md b/README.md index 5097c2f..45e82fa 100644 --- a/README.md +++ b/README.md @@ -135,8 +135,8 @@ per-node predictions and residuals, and never modifies your data. Try it locally ## Example datasets -Six of these ship inside the package. Two need data from outside: one downloads -automatically, one you download yourself. +All of these are included in the package. Five generate their data offline; two need data +from outside: one downloads automatically, one you download yourself. | Dataset | Story | Shows | Data needed | |---|---|---|---| diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..7292756 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,22 @@ +# Security policy + +## Supported versions + +Security fixes are made to the latest release on PyPI and to `main`. + +## Reporting a vulnerability + +Please **do not open a public issue** for security problems. Use GitHub's private reporting: +go to the repository's **Security** tab and choose **Report a vulnerability**. Include what +you found, how to reproduce it, and the graphdml and Python versions. + +You can expect an acknowledgement within a week. Confirmed issues are fixed in a new +release and credited in the changelog unless you prefer otherwise. + +## Scope notes + +graphdml runs locally and makes no network requests, except when you ask it to: +`make_lastfm_promo` downloads one checksum-verified file from SNAP, and the Neo4j module +connects to the server you configure. In the Neo4j module, labels, relationship types and +property names are validated and quoted, and all values are sent as query parameters. Never +commit database credentials; pass them through environment variables. diff --git a/docs/validation.md b/docs/validation.md index 4a35fc8..cbfa45b 100644 --- a/docs/validation.md +++ b/docs/validation.md @@ -93,6 +93,9 @@ focal set is tiny. ## Layer 5: user-facing checks +`graphdml.selftest()` lets anyone re-run a signal check on their own machine: planted +effects versus a null twin, against fixed criteria (see the README). + `summary()` prints diagnostics and the identifying assumptions with every fit, and warns on small focal sets, weak overlap, collinear residuals and isolated focal nodes. The falsification checks in `graphdml.diagnostics` are tested to pass on clean data and to flag diff --git a/src/graphdml/py.typed b/src/graphdml/py.typed new file mode 100644 index 0000000..e69de29