pasr-mcp 0.2.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 (88) hide show
  1. pasr_mcp-0.2.0/.gitignore +226 -0
  2. pasr_mcp-0.2.0/CHANGELOG.md +78 -0
  3. pasr_mcp-0.2.0/CITATION.cff +28 -0
  4. pasr_mcp-0.2.0/CODE_OF_CONDUCT.md +133 -0
  5. pasr_mcp-0.2.0/CONTRIBUTING.md +62 -0
  6. pasr_mcp-0.2.0/LICENSE +201 -0
  7. pasr_mcp-0.2.0/NOTICE +8 -0
  8. pasr_mcp-0.2.0/PKG-INFO +263 -0
  9. pasr_mcp-0.2.0/README.md +222 -0
  10. pasr_mcp-0.2.0/SECURITY.md +43 -0
  11. pasr_mcp-0.2.0/pyproject.toml +87 -0
  12. pasr_mcp-0.2.0/server.json +30 -0
  13. pasr_mcp-0.2.0/src/pasr/__init__.py +13 -0
  14. pasr_mcp-0.2.0/src/pasr/_tokenize.py +38 -0
  15. pasr_mcp-0.2.0/src/pasr/candidates.py +229 -0
  16. pasr_mcp-0.2.0/src/pasr/chunker.py +121 -0
  17. pasr_mcp-0.2.0/src/pasr/cli.py +333 -0
  18. pasr_mcp-0.2.0/src/pasr/context_order.py +130 -0
  19. pasr_mcp-0.2.0/src/pasr/controller.py +100 -0
  20. pasr_mcp-0.2.0/src/pasr/evidence.py +211 -0
  21. pasr_mcp-0.2.0/src/pasr/file_discovery.py +256 -0
  22. pasr_mcp-0.2.0/src/pasr/ledger.py +156 -0
  23. pasr_mcp-0.2.0/src/pasr/mcp/__init__.py +2 -0
  24. pasr_mcp-0.2.0/src/pasr/mcp/server.py +207 -0
  25. pasr_mcp-0.2.0/src/pasr/packing.py +279 -0
  26. pasr_mcp-0.2.0/src/pasr/packs.py +111 -0
  27. pasr_mcp-0.2.0/src/pasr/pipeline.py +252 -0
  28. pasr_mcp-0.2.0/src/pasr/receipt.py +157 -0
  29. pasr_mcp-0.2.0/src/pasr/redaction.py +17 -0
  30. pasr_mcp-0.2.0/src/pasr/retrieval/__init__.py +46 -0
  31. pasr_mcp-0.2.0/src/pasr/retrieval/bm25.py +105 -0
  32. pasr_mcp-0.2.0/src/pasr/retrieval/lexical.py +46 -0
  33. pasr_mcp-0.2.0/src/pasr/retrieval/semantic.py +128 -0
  34. pasr_mcp-0.2.0/src/pasr/review.py +201 -0
  35. pasr_mcp-0.2.0/src/pasr/routing.py +151 -0
  36. pasr_mcp-0.2.0/src/pasr/schema.py +217 -0
  37. pasr_mcp-0.2.0/src/pasr/select.py +334 -0
  38. pasr_mcp-0.2.0/src/pasr/symbols/__init__.py +24 -0
  39. pasr_mcp-0.2.0/src/pasr/symbols/base.py +84 -0
  40. pasr_mcp-0.2.0/src/pasr/symbols/candidates.py +87 -0
  41. pasr_mcp-0.2.0/src/pasr/symbols/python_provider.py +129 -0
  42. pasr_mcp-0.2.0/src/pasr/symbols/python_symbols.py +142 -0
  43. pasr_mcp-0.2.0/src/pasr/symbols/registry.py +50 -0
  44. pasr_mcp-0.2.0/src/pasr/symbols/treesitter_provider.py +219 -0
  45. pasr_mcp-0.2.0/src/pasr/tokenize.py +108 -0
  46. pasr_mcp-0.2.0/src/pasr/trace.py +193 -0
  47. pasr_mcp-0.2.0/src/pasr/window.py +80 -0
  48. pasr_mcp-0.2.0/tests/_helpers.py +7 -0
  49. pasr_mcp-0.2.0/tests/conftest.py +29 -0
  50. pasr_mcp-0.2.0/tests/fixtures/mini_repo/api/ratelimit.py +36 -0
  51. pasr_mcp-0.2.0/tests/fixtures/mini_repo/auth/session.py +37 -0
  52. pasr_mcp-0.2.0/tests/fixtures/mini_repo/billing/invoice.py +25 -0
  53. pasr_mcp-0.2.0/tests/fixtures/mini_repo/docs/deployment.md +24 -0
  54. pasr_mcp-0.2.0/tests/fixtures/mini_repo/search/index.py +44 -0
  55. pasr_mcp-0.2.0/tests/fixtures/mini_repo_needles.json +22 -0
  56. pasr_mcp-0.2.0/tests/fixtures/paraphrase/auth.py +22 -0
  57. pasr_mcp-0.2.0/tests/fixtures/paraphrase/jobs.py +31 -0
  58. pasr_mcp-0.2.0/tests/fixtures/paraphrase/store.py +37 -0
  59. pasr_mcp-0.2.0/tests/fixtures/paraphrase/text.py +21 -0
  60. pasr_mcp-0.2.0/tests/fixtures/paraphrase_needles.json +18 -0
  61. pasr_mcp-0.2.0/tests/fixtures/queries.jsonl +22 -0
  62. pasr_mcp-0.2.0/tests/fixtures/trace_repo/app/pipeline.py +56 -0
  63. pasr_mcp-0.2.0/tests/fixtures/trace_repo/web/util.js +36 -0
  64. pasr_mcp-0.2.0/tests/test_assemble.py +147 -0
  65. pasr_mcp-0.2.0/tests/test_bm25.py +83 -0
  66. pasr_mcp-0.2.0/tests/test_candidates.py +95 -0
  67. pasr_mcp-0.2.0/tests/test_chunker.py +72 -0
  68. pasr_mcp-0.2.0/tests/test_cli.py +215 -0
  69. pasr_mcp-0.2.0/tests/test_context_order.py +60 -0
  70. pasr_mcp-0.2.0/tests/test_controller.py +39 -0
  71. pasr_mcp-0.2.0/tests/test_evidence.py +101 -0
  72. pasr_mcp-0.2.0/tests/test_file_discovery.py +135 -0
  73. pasr_mcp-0.2.0/tests/test_ledger.py +90 -0
  74. pasr_mcp-0.2.0/tests/test_mcp_server.py +218 -0
  75. pasr_mcp-0.2.0/tests/test_packing.py +173 -0
  76. pasr_mcp-0.2.0/tests/test_packs.py +76 -0
  77. pasr_mcp-0.2.0/tests/test_pipeline.py +120 -0
  78. pasr_mcp-0.2.0/tests/test_python_symbols.py +82 -0
  79. pasr_mcp-0.2.0/tests/test_receipt.py +125 -0
  80. pasr_mcp-0.2.0/tests/test_review.py +87 -0
  81. pasr_mcp-0.2.0/tests/test_routing.py +75 -0
  82. pasr_mcp-0.2.0/tests/test_schema.py +70 -0
  83. pasr_mcp-0.2.0/tests/test_select.py +224 -0
  84. pasr_mcp-0.2.0/tests/test_semantic.py +105 -0
  85. pasr_mcp-0.2.0/tests/test_symbols.py +100 -0
  86. pasr_mcp-0.2.0/tests/test_tokenize.py +59 -0
  87. pasr_mcp-0.2.0/tests/test_trace.py +99 -0
  88. pasr_mcp-0.2.0/tests/test_window.py +86 -0
@@ -0,0 +1,226 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ # Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ # poetry.lock
109
+ # poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ # pdm.lock
116
+ # pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ # pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # Redis
135
+ *.rdb
136
+ *.aof
137
+ *.pid
138
+
139
+ # RabbitMQ
140
+ mnesia/
141
+ rabbitmq/
142
+ rabbitmq-data/
143
+
144
+ # ActiveMQ
145
+ activemq-data/
146
+
147
+ # SageMath parsed files
148
+ *.sage.py
149
+
150
+ # Environments
151
+ .env
152
+ .envrc
153
+ .venv
154
+ env/
155
+ venv/
156
+ ENV/
157
+ env.bak/
158
+ venv.bak/
159
+
160
+ # Spyder project settings
161
+ .spyderproject
162
+ .spyproject
163
+
164
+ # Rope project settings
165
+ .ropeproject
166
+
167
+ # mkdocs documentation
168
+ /site
169
+
170
+ # mypy
171
+ .mypy_cache/
172
+ .dmypy.json
173
+ dmypy.json
174
+
175
+ # Pyre type checker
176
+ .pyre/
177
+
178
+ # pytype static type analyzer
179
+ .pytype/
180
+
181
+ # Cython debug symbols
182
+ cython_debug/
183
+
184
+ # PyCharm
185
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
186
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
187
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
188
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
189
+ # .idea/
190
+
191
+ # Abstra
192
+ # Abstra is an AI-powered process automation framework.
193
+ # Ignore directories containing user credentials, local state, and settings.
194
+ # Learn more at https://abstra.io/docs
195
+ .abstra/
196
+
197
+ # Visual Studio Code
198
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
199
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
200
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
201
+ # you could uncomment the following to ignore the entire vscode folder
202
+ # .vscode/
203
+ # Temporary file for partial code execution
204
+ tempCodeRunnerFile.py
205
+
206
+ # Ruff stuff:
207
+ .ruff_cache/
208
+
209
+ # PyPI configuration file
210
+ .pypirc
211
+
212
+ # Marimo
213
+ marimo/_static/
214
+ marimo/_lsp/
215
+ __marimo__/
216
+
217
+ # Streamlit
218
+ .streamlit/secrets.toml
219
+
220
+ # PASR local artifacts — receipts are ignored, Context Packs are committable
221
+ .pasr/*
222
+ !.pasr/packs/
223
+ eval/runs/
224
+ eval/pasr_eval/runs/
225
+ pasr-bench-runs/
226
+ .eval-checkouts/
@@ -0,0 +1,78 @@
1
+ # Changelog
2
+
3
+ All notable changes to PASR. Format follows [Keep a Changelog](https://keepachangelog.com/);
4
+ this project uses [Semantic Versioning](https://semver.org/).
5
+
6
+ ## [Unreleased]
7
+
8
+ ## [0.2.0] — 2026-09-07
9
+
10
+ First public release. A zero-setup, offline, deterministic context-broker MCP for
11
+ coding and document agents. (0.1.x was the internal M0–M12 build; it was never
12
+ published.)
13
+
14
+ ### MCP tools (stdio)
15
+
16
+ - **`select_context`** — a budgeted, provenance-tracked slice of the workspace for a
17
+ query. BM25 + lexical coverage + tree-sitter symbol candidates, optionally an
18
+ in-process sub-word or MiniLM semantic scorer, fused by reciprocal-rank fusion, then
19
+ line-aligned active-window assembly under a hard `budget_tokens` cap. Returns the
20
+ assembled `context`, a `spans` list with `file:line` + token count + reason per span,
21
+ a `route` (`lossless` when the whole input already fit, else `selected`), full token
22
+ accounting, and a `query_class` / `confidence` / `advice` triple that tells the agent
23
+ when PASR is the wrong tool (e.g. aggregation-style questions).
24
+ - **`map_tokens=N`** — prepend a query-ranked `file:line kind name` symbol index of
25
+ up to `N` tokens, carved out of `budget_tokens` (never additive), skipped on a
26
+ `lossless` route. Repo-map-style pointer coverage of the whole file set without
27
+ giving up the bodies in the slice; in the offline bake-off it lifts `retrieval_ok`
28
+ from 0.70 to 0.90 (ties a full repo-map) at perfect critical-file coverage.
29
+ Recorded under `diagnostics.symbol_map`.
30
+ - **`trace="<symbol>"`** — fold that symbol's dependency closure into the slice as a
31
+ `# dependency closure` header, also carved out of `budget_tokens`. A one-call
32
+ "slice + closure" for trace-style questions; recorded under `diagnostics.trace`.
33
+ - **`trace_dependencies`** — deterministic transitive definition closure for a symbol
34
+ (Python, JS/TS), in source order, with `file:line` provenance and `defines` /
35
+ `dependencies` per span. An undefined symbol returns `found: false`, not an error.
36
+ - **`direction="callers"`** — reverse the edges: the closure of every definition that
37
+ transitively *references* the symbol. Impact analysis — "what breaks if I change
38
+ this."
39
+ - **`explain_selection`** — the stored receipt for a prior selection: kept spans,
40
+ dropped candidates with ranks, and the budget accounting.
41
+ - **`expand_context`** — re-run a prior selection once with a larger budget.
42
+
43
+ Every real `select_context` call (MCP, and `pasr explain` unless `--no-ledger`)
44
+ appends a row to `.pasr/ledger.jsonl` (gitignored): tokens in vs. out, round trips
45
+ saved, route.
46
+
47
+ ### CLI
48
+
49
+ - `pasr explain` / `pasr trace` (`--callers`) / `pasr pack` / `pasr context` /
50
+ `pasr review` / `pasr report`.
51
+ - **`pasr review`** — diff-aware context. From a unified diff (`git diff`, `--staged`,
52
+ `--range A..B`, or `--diff FILE`) it returns the definitions the change *touches*
53
+ (innermost def per hunk, not the whole enclosing class) plus the definitions that
54
+ *call* them (a one-level reverse closure), packed under `--budget` with `file:line`
55
+ provenance. `--json` / `--context-file` for machines.
56
+ - **`pasr report`** — summarise `.pasr/ledger.jsonl`: "PASR handed the model N fewer
57
+ tokens across M calls, R round trips saved", with `--since` and an optional
58
+ `--price-per-mtok` dollar estimate.
59
+ - **`pasr context`** — headless slice for CI / autonomous agents, `--format
60
+ text|json`, `--metrics-file`, `--context-file`; a composite GitHub Action at
61
+ `.github/actions/pasr-context/`.
62
+
63
+ ### Other
64
+
65
+ - **Receipts** — byte-stable `.pasr/receipts/<id>.{json,md}` audit records (gitignored).
66
+ - **Context Packs** — committable `.pasr/packs/<name>.json` warm-start slices, loadable
67
+ with `select_context(pack=…)`, with `source_fingerprint` staleness detection.
68
+ - **Routing** — `classify_query` + `assess` produce the confidence and ordered advice.
69
+ - Torch-free, `mcp`-SDK-free core; `tiktoken` + `pathspec` + `tree-sitter` runtime.
70
+ - **PASR-Bench** — the evaluation harness is a standalone distribution (`pip install
71
+ ./eval`, package `pasr-bench`, console script `pasr-bench {run,bakeoff,plans}`).
72
+ Pre-registered 4-arm protocol, paired non-inferiority vs a whole-repo dump,
73
+ `validate_matrix` (no synthetic rows, no leak, matched matrix). "Bring your own
74
+ retriever" — add an arm and measure it against the same 50 tasks. Results:
75
+ `eval/RESULTS.md`, `docs/competitors-benchmark.md`.
76
+
77
+ [Unreleased]: https://github.com/Apheironn/pasr/compare/v0.2.0...HEAD
78
+ [0.2.0]: https://github.com/Apheironn/pasr/releases/tag/v0.2.0
@@ -0,0 +1,28 @@
1
+ cff-version: 1.2.0
2
+ message: "If you use PASR in your work, please cite it as below."
3
+ title: "PASR — Provenance-Aware Span Recall"
4
+ abstract: >-
5
+ A zero-setup context-broker MCP server for coding and document agents. Given a query
6
+ and a workspace it returns a small, hard-budgeted, fully-traceable slice: every span
7
+ carries its file:line, token count, retrieval score, and the reason it was kept. It
8
+ classifies each query and signals when it is the wrong tool. Deterministic and offline
9
+ by default.
10
+ type: software
11
+ authors:
12
+ - family-names: Catak
13
+ given-names: Mertcan
14
+ alias: Apheironn
15
+ repository-code: "https://github.com/Apheironn/pasr"
16
+ url: "https://github.com/Apheironn/pasr"
17
+ license: Apache-2.0
18
+ version: 0.2.0
19
+ date-released: 2026-09-07
20
+ keywords:
21
+ - model-context-protocol
22
+ - mcp
23
+ - retrieval
24
+ - context-engineering
25
+ - coding-agent
26
+ - code-search
27
+ - token-budget
28
+ - provenance
@@ -0,0 +1,133 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, caste, color, religion, or sexual
10
+ identity and orientation.
11
+
12
+ We pledge to act and interact in ways that contribute to an open, welcoming,
13
+ diverse, inclusive, and healthy community.
14
+
15
+ ## Our Standards
16
+
17
+ Examples of behavior that contributes to a positive environment for our
18
+ community include:
19
+
20
+ * Demonstrating empathy and kindness toward other people
21
+ * Being respectful of differing opinions, viewpoints, and experiences
22
+ * Giving and gracefully accepting constructive feedback
23
+ * Accepting responsibility and apologizing to those affected by our mistakes,
24
+ and learning from the experience
25
+ * Focusing on what is best not just for us as individuals, but for the overall
26
+ community
27
+
28
+ Examples of unacceptable behavior include:
29
+
30
+ * The use of sexualized language or imagery, and sexual attention or advances of
31
+ any kind
32
+ * Trolling, insulting or derogatory comments, and personal or political attacks
33
+ * Public or private harassment
34
+ * Publishing others' private information, such as a physical or email address,
35
+ without their explicit permission
36
+ * Other conduct which could reasonably be considered inappropriate in a
37
+ professional setting
38
+
39
+ ## Enforcement Responsibilities
40
+
41
+ Community leaders are responsible for clarifying and enforcing our standards of
42
+ acceptable behavior and will take appropriate and fair corrective action in
43
+ response to any behavior that they deem inappropriate, threatening, offensive,
44
+ or harmful.
45
+
46
+ Community leaders have the right and responsibility to remove, edit, or reject
47
+ comments, commits, code, wiki edits, issues, and other contributions that are
48
+ not aligned to this Code of Conduct, and will communicate reasons for moderation
49
+ decisions when appropriate.
50
+
51
+ ## Scope
52
+
53
+ This Code of Conduct applies within all community spaces, and also applies when
54
+ an individual is officially representing the community in public spaces.
55
+ Examples of representing our community include using an official email address,
56
+ posting via an official social media account, or acting as an appointed
57
+ representative at an online or offline event.
58
+
59
+ ## Enforcement
60
+
61
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
62
+ reported to the project maintainer through a private report on the repository's
63
+ [Security tab](https://github.com/Apheironn/pasr/security/advisories/new) or by
64
+ contacting [@Apheironn](https://github.com/Apheironn) on GitHub. All complaints
65
+ will be reviewed and investigated promptly and fairly.
66
+
67
+ All community leaders are obligated to respect the privacy and security of the
68
+ reporter of any incident.
69
+
70
+ ## Enforcement Guidelines
71
+
72
+ Community leaders will follow these Community Impact Guidelines in determining
73
+ the consequences for any action they deem in violation of this Code of Conduct:
74
+
75
+ ### 1. Correction
76
+
77
+ **Community Impact**: Use of inappropriate language or other behavior deemed
78
+ unprofessional or unwelcome in the community.
79
+
80
+ **Consequence**: A private, written warning from community leaders, providing
81
+ clarity around the nature of the violation and an explanation of why the
82
+ behavior was inappropriate. A public apology may be requested.
83
+
84
+ ### 2. Warning
85
+
86
+ **Community Impact**: A violation through a single incident or series of
87
+ actions.
88
+
89
+ **Consequence**: A warning with consequences for continued behavior. No
90
+ interaction with the people involved, including unsolicited interaction with
91
+ those enforcing the Code of Conduct, for a specified period of time. This
92
+ includes avoiding interactions in community spaces as well as external channels
93
+ like social media. Violating these terms may lead to a temporary or permanent
94
+ ban.
95
+
96
+ ### 3. Temporary Ban
97
+
98
+ **Community Impact**: A serious violation of community standards, including
99
+ sustained inappropriate behavior.
100
+
101
+ **Consequence**: A temporary ban from any sort of interaction or public
102
+ communication with the community for a specified period of time. No public or
103
+ private interaction with the people involved, including unsolicited interaction
104
+ with those enforcing the Code of Conduct, is allowed during this period.
105
+ Violating these terms may lead to a permanent ban.
106
+
107
+ ### 4. Permanent Ban
108
+
109
+ **Community Impact**: Demonstrating a pattern of violation of community
110
+ standards, including sustained inappropriate behavior, harassment of an
111
+ individual, or aggression toward or disparagement of classes of individuals.
112
+
113
+ **Consequence**: A permanent ban from any sort of public interaction within the
114
+ community.
115
+
116
+ ## Attribution
117
+
118
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
119
+ version 2.1, available at
120
+ [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
121
+
122
+ Community Impact Guidelines were inspired by
123
+ [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
124
+
125
+ For answers to common questions about this code of conduct, see the FAQ at
126
+ [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
127
+ [https://www.contributor-covenant.org/translations][translations].
128
+
129
+ [homepage]: https://www.contributor-covenant.org
130
+ [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
131
+ [Mozilla CoC]: https://github.com/mozilla/diversity
132
+ [FAQ]: https://www.contributor-covenant.org/faq
133
+ [translations]: https://www.contributor-covenant.org/translations
@@ -0,0 +1,62 @@
1
+ # Contributing to PASR
2
+
3
+ Thanks for looking. PASR is small on purpose; the bar for changes is "does it keep the
4
+ invariants and pay for its own complexity".
5
+
6
+ ## Setup
7
+
8
+ ```bash
9
+ python -m venv .venv && . .venv/bin/activate # or .venv\Scripts\Activate.ps1
10
+ pip install -e ".[dev]"
11
+ pytest -q
12
+ ```
13
+
14
+ ## Before you open a PR
15
+
16
+ All three must be green:
17
+
18
+ ```bash
19
+ ruff check src tests eval
20
+ ruff format --check src tests eval
21
+ pytest -q
22
+ ```
23
+
24
+ CI runs the same on Python 3.10 and 3.12, plus a torch-free / mcp-free import check on
25
+ the core and a headless `pasr context` smoke.
26
+
27
+ ## Invariants (do not regress)
28
+
29
+ 1. The pure-logic core imports **no** `torch` / `transformers`, and no `mcp` SDK
30
+ outside `pasr.mcp`. Runtime deps stay minimal.
31
+ 2. `budget_tokens` is a hard cap — never return more.
32
+ 3. Lossless under budget: if the full context already fits, return it unchanged.
33
+ 4. Deterministic: same repo + query + config ⇒ identical bytes. No wall-clock, no
34
+ salted `hash()`, LF-normalized content hashes.
35
+ 5. Offline by default: no network, no daemon, no vector DB. External scorers are opt-in
36
+ extras.
37
+ 6. Every returned span carries `file:line` provenance, a token count, and a reason.
38
+
39
+ A change that touches retrieval or assembly needs a test that pins the new behaviour,
40
+ and the `examples/` transcripts regenerated (`bash scripts/gen_examples.sh`) if their
41
+ output moves.
42
+
43
+ ## Scope
44
+
45
+ New capability proposals should open an issue first describing the user-visible
46
+ behaviour and which invariant budget it spends; `docs/roadmap.md` has the current
47
+ scope. Model-internal ideas belong in the research line, not here — PASR stays
48
+ model-external.
49
+
50
+ ## Style
51
+
52
+ Line length 120. English for code and docs. Match the file you are in. `unittest`-style
53
+ classes and plain `pytest` functions both exist; follow the neighbouring test file.
54
+
55
+ ## Commits
56
+
57
+ Conventional-ish subject lines (`area: what changed`). One logical change per commit.
58
+
59
+ ## Conduct and security
60
+
61
+ By participating you agree to the [Code of Conduct](CODE_OF_CONDUCT.md). Security
62
+ issues go through [SECURITY.md](SECURITY.md) — a private report, not a public issue.