ckdn 1.0.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.
Files changed (77) hide show
  1. ckdn-1.0.0/.editorconfig +21 -0
  2. ckdn-1.0.0/.github/CODEOWNERS +5 -0
  3. ckdn-1.0.0/.github/ISSUE_TEMPLATE/bug.yml +62 -0
  4. ckdn-1.0.0/.github/ISSUE_TEMPLATE/config.yml +10 -0
  5. ckdn-1.0.0/.github/ISSUE_TEMPLATE/feature.yml +37 -0
  6. ckdn-1.0.0/.github/PULL_REQUEST_TEMPLATE.md +20 -0
  7. ckdn-1.0.0/.github/dependabot.yml +20 -0
  8. ckdn-1.0.0/.github/workflows/ci.yml +56 -0
  9. ckdn-1.0.0/.github/workflows/publish.yml +113 -0
  10. ckdn-1.0.0/.gitignore +16 -0
  11. ckdn-1.0.0/.pre-commit-config.yaml +72 -0
  12. ckdn-1.0.0/CHANGELOG.md +33 -0
  13. ckdn-1.0.0/CODE_OF_CONDUCT.md +77 -0
  14. ckdn-1.0.0/CONTRIBUTING.md +49 -0
  15. ckdn-1.0.0/LICENSE +24 -0
  16. ckdn-1.0.0/PKG-INFO +620 -0
  17. ckdn-1.0.0/README.md +580 -0
  18. ckdn-1.0.0/REUSE.toml +15 -0
  19. ckdn-1.0.0/SECURITY.md +54 -0
  20. ckdn-1.0.0/assets/ckdn-pipeline-dark.svg +61 -0
  21. ckdn-1.0.0/assets/ckdn-pipeline.svg +61 -0
  22. ckdn-1.0.0/assets/ckdn-wordmark-dark.svg +36 -0
  23. ckdn-1.0.0/assets/ckdn-wordmark.svg +36 -0
  24. ckdn-1.0.0/assets/ckdn.svg +32 -0
  25. ckdn-1.0.0/ckdn.toml +134 -0
  26. ckdn-1.0.0/codeclone.baseline.json +4916 -0
  27. ckdn-1.0.0/examples/ckdn.toml +134 -0
  28. ckdn-1.0.0/examples/claude/skills/verified-fix-loop/SKILL.md +79 -0
  29. ckdn-1.0.0/pyproject.toml +132 -0
  30. ckdn-1.0.0/src/ckdn/__init__.py +16 -0
  31. ckdn-1.0.0/src/ckdn/__main__.py +7 -0
  32. ckdn-1.0.0/src/ckdn/app/__init__.py +53 -0
  33. ckdn-1.0.0/src/ckdn/app/errors.py +45 -0
  34. ckdn-1.0.0/src/ckdn/app/queries.py +270 -0
  35. ckdn-1.0.0/src/ckdn/app/run.py +177 -0
  36. ckdn-1.0.0/src/ckdn/app/types.py +28 -0
  37. ckdn-1.0.0/src/ckdn/cli.py +211 -0
  38. ckdn-1.0.0/src/ckdn/config.py +327 -0
  39. ckdn-1.0.0/src/ckdn/digest.py +191 -0
  40. ckdn-1.0.0/src/ckdn/mcp/__init__.py +15 -0
  41. ckdn-1.0.0/src/ckdn/mcp/context.py +37 -0
  42. ckdn-1.0.0/src/ckdn/mcp/register.py +37 -0
  43. ckdn-1.0.0/src/ckdn/mcp/server.py +64 -0
  44. ckdn-1.0.0/src/ckdn/mcp/tools/__init__.py +3 -0
  45. ckdn-1.0.0/src/ckdn/mcp/tools/get_digest.py +29 -0
  46. ckdn-1.0.0/src/ckdn/mcp/tools/get_evidence.py +49 -0
  47. ckdn-1.0.0/src/ckdn/mcp/tools/list_checks.py +27 -0
  48. ckdn-1.0.0/src/ckdn/mcp/tools/list_runs.py +26 -0
  49. ckdn-1.0.0/src/ckdn/mcp/tools/run_check.py +48 -0
  50. ckdn-1.0.0/src/ckdn/mcp/tools/run_group.py +39 -0
  51. ckdn-1.0.0/src/ckdn/parsers/__init__.py +46 -0
  52. ckdn-1.0.0/src/ckdn/parsers/bandit_json.py +138 -0
  53. ckdn-1.0.0/src/ckdn/parsers/base.py +204 -0
  54. ckdn-1.0.0/src/ckdn/parsers/coverage_xml.py +165 -0
  55. ckdn-1.0.0/src/ckdn/parsers/generic.py +25 -0
  56. ckdn-1.0.0/src/ckdn/parsers/mypy.py +246 -0
  57. ckdn-1.0.0/src/ckdn/parsers/pip_audit_json.py +112 -0
  58. ckdn-1.0.0/src/ckdn/parsers/pylint_json.py +155 -0
  59. ckdn-1.0.0/src/ckdn/parsers/pyright_json.py +130 -0
  60. ckdn-1.0.0/src/ckdn/parsers/pytest_junit.py +105 -0
  61. ckdn-1.0.0/src/ckdn/parsers/reformat_text.py +89 -0
  62. ckdn-1.0.0/src/ckdn/parsers/ruff_json.py +78 -0
  63. ckdn-1.0.0/src/ckdn/parsers/sarif.py +160 -0
  64. ckdn-1.0.0/src/ckdn/parsers/ty_text.py +186 -0
  65. ckdn-1.0.0/src/ckdn/py.typed +0 -0
  66. ckdn-1.0.0/src/ckdn/reconcile.py +72 -0
  67. ckdn-1.0.0/src/ckdn/runner.py +179 -0
  68. ckdn-1.0.0/tests/test_app.py +429 -0
  69. ckdn-1.0.0/tests/test_cli.py +240 -0
  70. ckdn-1.0.0/tests/test_cli_alias.py +222 -0
  71. ckdn-1.0.0/tests/test_config.py +235 -0
  72. ckdn-1.0.0/tests/test_digest.py +218 -0
  73. ckdn-1.0.0/tests/test_mcp.py +231 -0
  74. ckdn-1.0.0/tests/test_parsers.py +754 -0
  75. ckdn-1.0.0/tests/test_reconcile.py +61 -0
  76. ckdn-1.0.0/tests/test_runner.py +181 -0
  77. ckdn-1.0.0/uv.lock +2157 -0
@@ -0,0 +1,21 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2026 Den Rozhnovskiy <rozhnovskiydenis@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ root = true
5
+
6
+ [*]
7
+ charset = utf-8
8
+ end_of_line = lf
9
+ insert_final_newline = true
10
+ trim_trailing_whitespace = true
11
+ indent_style = space
12
+ indent_size = 4
13
+
14
+ [*.{yml,yaml,toml,md,svg}]
15
+ indent_size = 2
16
+
17
+ [*.py]
18
+ indent_size = 4
19
+
20
+ [Makefile]
21
+ indent_style = tab
@@ -0,0 +1,5 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2026 Den Rozhnovskiy <rozhnovskiydenis@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ # Default owner for the whole repository.
5
+ * @orenlab
@@ -0,0 +1,62 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2026 Den Rozhnovskiy <rozhnovskiydenis@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+ name: Bug report
4
+ description: Something is broken or a digest/status looks wrong
5
+ title: "[bug] "
6
+ labels: ["bug"]
7
+ body:
8
+ - type: markdown
9
+ attributes:
10
+ value: |
11
+ Thanks for filing a bug. For security issues use
12
+ [Security Advisories](https://github.com/orenlab/ckdn/security/advisories/new)
13
+ instead.
14
+ - type: textarea
15
+ id: summary
16
+ attributes:
17
+ label: Summary
18
+ description: What went wrong in one or two sentences?
19
+ validations:
20
+ required: true
21
+ - type: textarea
22
+ id: reproduce
23
+ attributes:
24
+ label: Steps to reproduce
25
+ description: Minimal commands / ckdn.toml snippets.
26
+ placeholder: |
27
+ ckdn init
28
+ ckdn run lint
29
+ validations:
30
+ required: true
31
+ - type: textarea
32
+ id: expected
33
+ attributes:
34
+ label: Expected behavior
35
+ validations:
36
+ required: true
37
+ - type: textarea
38
+ id: actual
39
+ attributes:
40
+ label: Actual behavior
41
+ description: Paste the compact digest JSON if relevant (redact secrets).
42
+ validations:
43
+ required: true
44
+ - type: input
45
+ id: version
46
+ attributes:
47
+ label: ckdn version
48
+ placeholder: "ckdn --version"
49
+ validations:
50
+ required: true
51
+ - type: input
52
+ id: python
53
+ attributes:
54
+ label: Python version
55
+ placeholder: "python --version"
56
+ validations:
57
+ required: true
58
+ - type: textarea
59
+ id: env
60
+ attributes:
61
+ label: Environment
62
+ description: OS, how ckdn was installed (uv tool / path / PYTHONPATH).
@@ -0,0 +1,10 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2026 Den Rozhnovskiy <rozhnovskiydenis@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+ blank_issues_enabled: false
4
+ contact_links:
5
+ - name: Security report
6
+ url: https://github.com/orenlab/ckdn/security/advisories/new
7
+ about: Report a vulnerability privately (do not file a public issue).
8
+ - name: Discussions
9
+ url: https://github.com/orenlab/ckdn/discussions
10
+ about: Questions and ideas that are not bugs or feature requests.
@@ -0,0 +1,37 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2026 Den Rozhnovskiy <rozhnovskiydenis@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+ name: Feature request
4
+ description: Propose a parser, alias behavior, or CLI improvement
5
+ title: "[feat] "
6
+ labels: ["enhancement"]
7
+ body:
8
+ - type: textarea
9
+ id: problem
10
+ attributes:
11
+ label: Problem
12
+ description: What gap does this fill for agent / CI loops?
13
+ validations:
14
+ required: true
15
+ - type: textarea
16
+ id: proposal
17
+ attributes:
18
+ label: Proposal
19
+ description: Desired behavior, config shape, and non-goals if any.
20
+ validations:
21
+ required: true
22
+ - type: textarea
23
+ id: alternatives
24
+ attributes:
25
+ label: Alternatives considered
26
+ description: Workarounds today (generic parser, external script, …).
27
+ - type: checkboxes
28
+ id: constraints
29
+ attributes:
30
+ label: Constraints you accept
31
+ options:
32
+ - label: Stdlib-only runtime (no new published dependencies)
33
+ required: true
34
+ - label: Digests stay sparse (ckdn.digest/2 omit-empty rules)
35
+ required: true
36
+ - label: Parsers report facts; reconcile owns status
37
+ required: true
@@ -0,0 +1,20 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: Copyright (c) 2026 Den Rozhnovskiy <rozhnovskiydenis@gmail.com>
3
+ SPDX-License-Identifier: MIT
4
+ -->
5
+ ## Summary
6
+
7
+ <!-- What and why (1–3 bullets). -->
8
+
9
+ -
10
+
11
+ ## Test plan
12
+
13
+ - [ ] `uv run pytest`
14
+ - [ ] `uv run ruff check src tests`
15
+ - [ ] `uv run mypy src/ckdn`
16
+ - [ ] Manual: `ckdn run <relevant-check>` digest looks correct (sparse on pass)
17
+
18
+ ## Notes
19
+
20
+ <!-- Breaking digest/schema changes? Update DIGEST_SCHEMA and README. -->
@@ -0,0 +1,20 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2026 Den Rozhnovskiy <rozhnovskiydenis@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ version: 2
5
+ updates:
6
+ - package-ecosystem: github-actions
7
+ directory: /
8
+ schedule:
9
+ interval: weekly
10
+ open-pull-requests-limit: 5
11
+
12
+ - package-ecosystem: uv
13
+ directory: /
14
+ schedule:
15
+ interval: weekly
16
+ open-pull-requests-limit: 5
17
+ groups:
18
+ dev-python:
19
+ patterns:
20
+ - "*"
@@ -0,0 +1,56 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2026 Den Rozhnovskiy <rozhnovskiydenis@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+ name: CI
4
+
5
+ on:
6
+ push:
7
+ branches: [main]
8
+ pull_request:
9
+ branches: [main]
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ jobs:
15
+ test:
16
+ runs-on: ubuntu-latest
17
+ strategy:
18
+ fail-fast: false
19
+ matrix:
20
+ python-version: ["3.11", "3.12", "3.13", "3.14"]
21
+ steps:
22
+ - uses: actions/checkout@v7
23
+ - name: Install uv
24
+ uses: astral-sh/setup-uv@v8.3.2
25
+ with:
26
+ enable-cache: true
27
+ python-version: ${{ matrix.python-version }}
28
+ - name: Sync
29
+ run: uv sync --extra dev --extra mcp
30
+ - name: Ruff
31
+ run: uv run ruff check src tests
32
+ - name: Mypy
33
+ run: uv run mypy src/ckdn
34
+ - name: Ty
35
+ run: uv run ty check src/ckdn
36
+ - name: Pytest
37
+ run: uv run pytest -q
38
+
39
+ codeclone:
40
+ runs-on: ubuntu-latest
41
+ permissions:
42
+ contents: read
43
+ security-events: write
44
+ pull-requests: write
45
+ steps:
46
+ - name: Checkout
47
+ uses: actions/checkout@v7
48
+ with:
49
+ fetch-depth: 0
50
+
51
+ - name: Run CodeClone
52
+ uses: orenlab/codeclone/.github/actions/codeclone@v2.1.0a1
53
+ with:
54
+ fail-on-new: "true"
55
+ sarif: "true"
56
+ pr-comment: "true"
@@ -0,0 +1,113 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2026 Den Rozhnovskiy <rozhnovskiydenis@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+ name: publish
4
+ run-name: >-
5
+ publish • ${{ github.event_name }} •
6
+ ${{ github.event.release.tag_name || inputs.repository || github.ref_name }}
7
+
8
+ on:
9
+ release:
10
+ types: [published]
11
+ workflow_dispatch:
12
+ inputs:
13
+ repository:
14
+ description: Target package index
15
+ required: true
16
+ default: testpypi
17
+ type: choice
18
+ options:
19
+ - testpypi
20
+ - pypi
21
+
22
+ permissions:
23
+ contents: read
24
+
25
+ concurrency:
26
+ group: publish-${{ github.event.release.tag_name || github.ref }}
27
+ cancel-in-progress: false
28
+
29
+ jobs:
30
+ build:
31
+ runs-on: ubuntu-latest
32
+ steps:
33
+ - name: Checkout
34
+ uses: actions/checkout@v7
35
+
36
+ - name: Set up uv
37
+ uses: astral-sh/setup-uv@v8.3.2
38
+ with:
39
+ enable-cache: true
40
+ python-version: "3.13"
41
+
42
+ - name: Verify release tag matches project version
43
+ if: ${{ github.event_name == 'release' }}
44
+ shell: bash
45
+ run: |
46
+ set -euo pipefail
47
+ project_version="$(python - <<'PY'
48
+ import pathlib, tomllib
49
+ payload = tomllib.loads(pathlib.Path("pyproject.toml").read_text(encoding="utf-8"))
50
+ print(payload["project"]["version"])
51
+ PY
52
+ )"
53
+ release_tag="${{ github.event.release.tag_name }}"
54
+ normalized_tag="${release_tag#v}"
55
+ if [ "$normalized_tag" != "$project_version" ]; then
56
+ echo "release tag $release_tag does not match project version $project_version" >&2
57
+ exit 1
58
+ fi
59
+
60
+ - name: Build distributions
61
+ run: uv build
62
+
63
+ - name: Validate distributions
64
+ run: uv run --with twine twine check dist/*
65
+
66
+ - name: Upload distributions
67
+ uses: actions/upload-artifact@v7
68
+ with:
69
+ name: python-package-distributions
70
+ path: dist/
71
+ if-no-files-found: error
72
+
73
+ publish-testpypi:
74
+ if: ${{ github.event_name == 'workflow_dispatch' && inputs.repository == 'testpypi' }}
75
+ needs: build
76
+ runs-on: ubuntu-latest
77
+ environment: testpypi
78
+ permissions:
79
+ contents: read
80
+ id-token: write
81
+ steps:
82
+ - name: Download distributions
83
+ uses: actions/download-artifact@v8
84
+ with:
85
+ name: python-package-distributions
86
+ path: dist/
87
+
88
+ - name: Publish to TestPyPI
89
+ uses: pypa/gh-action-pypi-publish@release/v1
90
+ with:
91
+ repository-url: https://test.pypi.org/legacy/
92
+
93
+ publish-pypi:
94
+ if: >-
95
+ ${{
96
+ github.event_name == 'release' ||
97
+ (github.event_name == 'workflow_dispatch' && inputs.repository == 'pypi')
98
+ }}
99
+ needs: build
100
+ runs-on: ubuntu-latest
101
+ environment: pypi
102
+ permissions:
103
+ contents: read
104
+ id-token: write
105
+ steps:
106
+ - name: Download distributions
107
+ uses: actions/download-artifact@v8
108
+ with:
109
+ name: python-package-distributions
110
+ path: dist/
111
+
112
+ - name: Publish to PyPI
113
+ uses: pypa/gh-action-pypi-publish@release/v1
ckdn-1.0.0/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ .agent-runs/
2
+ __pycache__/
3
+ *.pyc
4
+ dist/
5
+ .venv/
6
+ .codeclone/
7
+ .idea/
8
+ *.egg-info/
9
+ .pytest_cache/
10
+ .mypy_cache/
11
+ .ruff_cache/
12
+ .DS_Store
13
+ .coverage
14
+ htmlcov/
15
+ build/
16
+ *.whl
@@ -0,0 +1,72 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2026 Den Rozhnovskiy <rozhnovskiydenis@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+ default_install_hook_types: [pre-commit, pre-push]
4
+
5
+ repos:
6
+ - repo: https://github.com/pre-commit/pre-commit-hooks
7
+ rev: v6.0.0
8
+ hooks:
9
+ - id: check-merge-conflict
10
+ - id: end-of-file-fixer
11
+ - id: trailing-whitespace
12
+ - id: check-toml
13
+ - id: check-yaml
14
+ - id: check-json
15
+ - id: check-ast
16
+ - id: debug-statements
17
+ - id: check-case-conflict
18
+ - id: check-symlinks
19
+ - id: destroyed-symlinks
20
+ - id: detect-private-key
21
+ - id: mixed-line-ending
22
+ args: [--fix=lf]
23
+ - id: forbid-submodules
24
+
25
+ - repo: local
26
+ hooks:
27
+ - id: ruff-format
28
+ name: Ruff (format)
29
+ entry: uv run ruff format .
30
+ language: system
31
+ pass_filenames: false
32
+ stages: [pre-commit]
33
+
34
+ - id: ruff-check
35
+ name: Ruff (lint)
36
+ entry: uv run ruff check .
37
+ language: system
38
+ pass_filenames: false
39
+ stages: [pre-commit]
40
+
41
+ - id: mypy
42
+ name: Mypy
43
+ entry: uv run mypy
44
+ language: system
45
+ pass_filenames: false
46
+ always_run: true
47
+ stages: [pre-commit]
48
+
49
+ - id: ty
50
+ name: Ty
51
+ entry: uv run ty check .
52
+ language: system
53
+ pass_filenames: false
54
+ always_run: true
55
+ stages: [pre-commit]
56
+
57
+ - id: codeclone
58
+ name: CodeClone
59
+ entry: uv run codeclone
60
+ language: system
61
+ pass_filenames: false
62
+ args: [".", "--ci"]
63
+ always_run: true
64
+ stages: [pre-commit]
65
+
66
+ - id: pytest
67
+ name: Pytest
68
+ entry: uv run pytest -q
69
+ language: system
70
+ pass_filenames: false
71
+ always_run: true
72
+ stages: [pre-push]
@@ -0,0 +1,33 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: Copyright (c) 2026 Den Rozhnovskiy <rozhnovskiydenis@gmail.com>
3
+ SPDX-License-Identifier: MIT
4
+ -->
5
+ # Changelog
6
+
7
+ All notable changes to this project will be documented in this file.
8
+
9
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
10
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
11
+
12
+ ## [1.0.0] - 2026-07-11
13
+
14
+ ### Added
15
+
16
+ - Initial public release of **ckdn** (checkdown): deterministic check runner
17
+ and bounded log digester for AI-assisted development loops
18
+ - Atomic checks and configurable aliases (`members`, optional `fail_fast`)
19
+ - Tier-1 parsers: pytest, ruff, coverage, ty, mypy, pyright, pylint, bandit,
20
+ pip-audit, SARIF, reformat text, generic
21
+ - Sparse schemas: digest `ckdn.digest/2`, alias aggregate `ckdn.aggregate/1`,
22
+ meta `ckdn.meta/1`
23
+ - CLI: `run`, `show`, `list`, `checks`, `gc`, `init` (writes a starter
24
+ `ckdn.toml`)
25
+ - Stdlib-only core runtime; MIT license; security and contribution docs
26
+ - Optional FastMCP stdio server (`ckdn[mcp]` / `ckdn-mcp`) exposing
27
+ `list_checks`, `run_check`, `run_group`, `get_digest`, `list_runs`,
28
+ `get_evidence`
29
+ - Application facade (`ckdn.app`) shared by CLI and MCP so reconcile/digest
30
+ semantics stay single-sourced
31
+
32
+ [Unreleased]: https://github.com/orenlab/ckdn/compare/v1.0.0...HEAD
33
+ [1.0.0]: https://github.com/orenlab/ckdn/releases/tag/v1.0.0
@@ -0,0 +1,77 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: Copyright (c) 2026 Den Rozhnovskiy <rozhnovskiydenis@gmail.com>
3
+ SPDX-License-Identifier: MIT
4
+ -->
5
+ # Contributor Covenant Code of Conduct
6
+
7
+ ## Our Pledge
8
+
9
+ We as members, contributors, and leaders pledge to make participation in our
10
+ community a harassment-free experience for everyone, regardless of age, body
11
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
12
+ identity and expression, level of experience, education, socio-economic status,
13
+ nationality, personal appearance, race, caste, color, religion, or sexual
14
+ identity and orientation.
15
+
16
+ We pledge to act and interact in ways that contribute to an open, welcoming,
17
+ diverse, inclusive, and healthy community.
18
+
19
+ ## Our Standards
20
+
21
+ Examples of behavior that contributes to a positive environment:
22
+
23
+ - Demonstrating empathy and kindness toward other people
24
+ - Being respectful of differing opinions, viewpoints, and experiences
25
+ - Giving and gracefully accepting constructive feedback
26
+ - Accepting responsibility and apologizing to those affected by our mistakes,
27
+ and learning from the experience
28
+ - Focusing on what is best not just for us as individuals, but for the overall
29
+ community
30
+
31
+ Examples of unacceptable behavior:
32
+
33
+ - The use of sexualized language or imagery, and sexual attention or advances of
34
+ any kind
35
+ - Trolling, insulting or derogatory comments, and personal or political attacks
36
+ - Public or private harassment
37
+ - Publishing others' private information, such as a physical or email address,
38
+ without their explicit permission
39
+ - Other conduct which could reasonably be considered inappropriate in a
40
+ professional setting
41
+
42
+ ## Enforcement Responsibilities
43
+
44
+ Community leaders are responsible for clarifying and enforcing our standards of
45
+ acceptable behavior and will take appropriate and fair corrective action in
46
+ response to any behavior that they deem inappropriate, threatening, offensive,
47
+ or harmful.
48
+
49
+ ## Scope
50
+
51
+ This Code of Conduct applies within all community spaces, and also applies when
52
+ an individual is officially representing the community in public spaces.
53
+
54
+ ## Enforcement
55
+
56
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
57
+ reported to the community leaders responsible for enforcement at
58
+ **rozhnovskiydenis@gmail.com**.
59
+
60
+ All complaints will be reviewed and investigated promptly and fairly.
61
+
62
+ ## Enforcement Guidelines
63
+
64
+ Community leaders will follow these Community Impact Guidelines in determining
65
+ the consequences for any action they deem in violation of this Code of Conduct:
66
+
67
+ 1. **Correction** — private warning and clarification of expectations.
68
+ 2. **Warning** — consequences for continued behavior.
69
+ 3. **Temporary ban** — no interaction for a specified period.
70
+ 4. **Permanent ban** — permanent ban from community spaces.
71
+
72
+ ## Attribution
73
+
74
+ This Code of Conduct is adapted from the
75
+ [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1,
76
+ available at
77
+ https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
@@ -0,0 +1,49 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: Copyright (c) 2026 Den Rozhnovskiy <rozhnovskiydenis@gmail.com>
3
+ SPDX-License-Identifier: MIT
4
+ -->
5
+ # Contributing
6
+
7
+ Thanks for helping with **ckdn** (checkdown).
8
+
9
+ ## Development setup
10
+
11
+ ```bash
12
+ uv sync --extra dev --extra mcp
13
+ uv run pre-commit install # if you use pre-commit
14
+ uv run pytest
15
+ uv run ruff check src tests
16
+ uv run mypy src/ckdn
17
+ uv run ty check src/ckdn
18
+ # coverage check needs pytest-cov (in the dev extra):
19
+ # uv run ckdn run coverage
20
+ ```
21
+
22
+ Core package stays **stdlib only** (`dependencies = []`). The MCP server is the optional
23
+ `mcp` extra (`fastmcp`); sync it for MCP tests and local `ckdn-mcp`.
24
+
25
+ ## Pull requests
26
+
27
+ 1. Keep changes focused; prefer small PRs.
28
+ 2. Add or update tests for behavior changes (especially reconcile /
29
+ parser guards and digest shape).
30
+ 3. Update [CHANGELOG.md](CHANGELOG.md) under `[Unreleased]` for user-facing changes.
31
+ 4. Do not commit `.agent-runs/`, `.venv/`, or CodeClone state
32
+ (`.codeclone/`, baseline updates unless explicitly requested).
33
+ 5. Fill in the PR template.
34
+
35
+ ## Coding norms
36
+
37
+ - Python ≥ 3.11, **stdlib only** in the published package (`dependencies = []`).
38
+ - Parsers report facts; they never decide final status (`ckdn.reconcile` does).
39
+ - Digests stay sparse (`ckdn.digest/2`): omit empty / zero / false defaults.
40
+ - Prefer machine-readable artifacts under `{run_dir}` over terminal scraping.
41
+
42
+ ## Security
43
+
44
+ See [SECURITY.md](SECURITY.md). Do not file public issues for vulnerabilities.
45
+
46
+ ## License
47
+
48
+ By contributing, you agree that your contributions are licensed under the
49
+ [MIT License](LICENSE).
ckdn-1.0.0/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ SPDX-FileCopyrightText: Copyright (c) 2026 Den Rozhnovskiy <rozhnovskiydenis@gmail.com>
2
+ SPDX-License-Identifier: MIT
3
+
4
+ MIT License
5
+
6
+ Copyright (c) 2026 Den Rozhnovskiy <rozhnovskiydenis@gmail.com>
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ of this software and associated documentation files (the "Software"), to deal
10
+ in the Software without restriction, including without limitation the rights
11
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ copies of the Software, and to permit persons to whom the Software is
13
+ furnished to do so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in all
16
+ copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.