diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..4f0f960 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,59 @@ +name: Bug report +description: Report a bug or unexpected behavior in paperjam +labels: ["bug"] +body: + - type: textarea + id: what-happened + attributes: + label: What happened? + description: A clear description of the bug. + validations: + required: true + + - type: textarea + id: reproduction + attributes: + label: Minimal reproduction + description: The smallest possible snippet or steps that reproduces the issue. + render: python + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected behavior + description: What you expected to happen instead. + + - type: input + id: version + attributes: + label: paperjam version + description: Output of `pip show paperjam` or the crate version from `Cargo.toml`. + placeholder: e.g. 0.1.2 + validations: + required: true + + - type: dropdown + id: platform + attributes: + label: Platform + options: + - Linux + - macOS + - Windows + validations: + required: true + + - type: input + id: python-version + attributes: + label: Python version + description: Output of `python --version`. Leave blank if not using Python bindings. + placeholder: e.g. 3.12.1 + + - type: textarea + id: context + attributes: + label: Additional context + description: Logs, screenshots, related issues, anything else. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3ba13e0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..666971f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,31 @@ +name: Feature request +description: Suggest a new feature or enhancement for paperjam +labels: ["enhancement"] +body: + - type: textarea + id: problem + attributes: + label: Problem you're trying to solve + description: What's the use case or pain point driving this request? + validations: + required: true + + - type: textarea + id: solution + attributes: + label: Proposed solution + description: How would you like this to work? + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives considered + description: Other approaches you've thought about or tried. + + - type: textarea + id: context + attributes: + label: Additional context + description: Links, examples, anything else that helps explain the request. diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 0000000..a7fe379 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,50 @@ +rust: + - changed-files: + - any-glob-to-any-file: + - 'crates/**' + - '**/*.rs' + - 'Cargo.toml' + - 'Cargo.lock' + +python: + - changed-files: + - any-glob-to-any-file: + - 'py_src/**' + - 'mcp-server/**' + - '**/*.py' + - 'pyproject.toml' + +javascript: + - changed-files: + - any-glob-to-any-file: + - 'docs-site/**/*.js' + - 'docs-site/**/*.jsx' + - 'docs-site/**/*.ts' + - 'docs-site/**/*.tsx' + - 'docs-site/**/*.mjs' + - 'docs-site/**/*.cjs' + +documentation: + - changed-files: + - any-glob-to-any-file: + - 'docs-site/**' + - 'docs/**' + - '**/*.md' + - 'README*' + +github_actions: + - changed-files: + - any-glob-to-any-file: + - '.github/workflows/**' + - '.github/actions/**' + +mcp: + - changed-files: + - any-glob-to-any-file: + - 'crates/paperjam-mcp/**' + - 'mcp-server/**' + +wasm: + - changed-files: + - any-glob-to-any-file: + - 'crates/paperjam-wasm/**' diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..ac611be --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,17 @@ +## Summary + + +- + +## Test plan + + +- [ ] `cargo test` passes locally +- [ ] `pytest` passes locally +- [ ] `cargo fmt --all -- --check` and `cargo clippy` clean +- [ ] Manual check: + +## Related issue + + +N/A diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 0000000..955a2f9 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,16 @@ +name: PR Labeler + +on: + pull_request_target: + +permissions: + contents: read + pull-requests: write + +jobs: + label: + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v5 + with: + sync-labels: true diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..8ceead6 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,42 @@ +name: Stale PRs and issues + +on: + schedule: + - cron: '0 2 * * *' + workflow_dispatch: + +permissions: + issues: write + pull-requests: write + contents: read + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v9 + with: + days-before-pr-stale: 45 + days-before-pr-close: 14 + days-before-issue-stale: 90 + days-before-issue-close: 30 + exempt-pr-labels: 'dependencies,pinned,security,help wanted,good first issue' + exempt-issue-labels: 'dependencies,pinned,security,help wanted,good first issue' + remove-stale-when-updated: true + operations-per-run: 100 + stale-pr-label: 'stale' + stale-issue-label: 'stale' + stale-pr-message: > + This pull request has been inactive for 45 days and is now marked + as stale. It will be closed in 14 days unless there is new activity. + Add the `pinned` label if this should be kept open indefinitely. + stale-issue-message: > + This issue has been inactive for 90 days and is now marked as stale. + It will be closed in 30 days unless there is new activity. Add the + `pinned` label if this should be kept open indefinitely. + close-pr-message: > + Closing this pull request due to inactivity. Feel free to reopen + if you would like to continue the work. + close-issue-message: > + Closing this issue due to inactivity. Feel free to reopen with new + information if the problem persists. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..0965387 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,59 @@ +# Security Policy + +Paperjam parses untrusted document formats (PDF, DOCX, XLSX, EPUB). Parser +vulnerabilities — memory safety issues, panics on crafted input, denial of +service via pathological files, or any unexpected behavior on malicious +input — are in scope and taken seriously. + +## Reporting a vulnerability + +**Do not open a public issue for security reports.** + +Use GitHub's private vulnerability reporting: + +1. Open +2. Fill in a description and, if possible, a minimal reproducer +3. Attach any crafted input files to the advisory — **do not commit them + to the repository** + +## What to include + +- paperjam version (`pip show paperjam` or crate version from `Cargo.toml`) +- Platform, Python version, and Rust version if building from source +- A minimal file or snippet that triggers the issue +- Observed vs. expected behavior +- Any analysis you already have (stack trace, ASan output, etc.) + +## Response expectations + +Paperjam is maintained by a single person, so response times are +best-effort: + +- Initial acknowledgement: within 7 days +- Triage and severity assessment: within 14 days +- Fix or mitigation timeline: depends on severity and complexity + +## Supported versions + +Security fixes land on the latest released version only. Pin a specific +version in production and upgrade when a security release is cut. + +## Scope + +**In scope** + +- Memory safety issues (crashes, UAF, buffer overruns) in Rust parser + code reachable from the Python, WASM, or CLI frontends +- Panics or unhandled errors triggered by crafted input that should be + returned as graceful errors +- Denial of service via pathological inputs (exponential blowup, + infinite loops, quadratic behavior on small files) +- Unintended filesystem or network access from the parser + +**Out of scope** + +- Bugs in upstream dependencies — report those upstream; paperjam will + update once a fix is released +- Issues that require an attacker-controlled build environment or an + already-compromised system +- Missing hardening features that are not actual vulnerabilities