python-docs-mcp-server 0.2.0__tar.gz → 0.3.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.
- python_docs_mcp_server-0.3.0/.coderabbit.yaml +24 -0
- python_docs_mcp_server-0.3.0/.github/CODEOWNERS +49 -0
- python_docs_mcp_server-0.3.0/.github/ISSUE_TEMPLATE/autonomous-agent.yml +108 -0
- python_docs_mcp_server-0.3.0/.github/PULL_REQUEST_TEMPLATE/agent.md +42 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.github/RELEASE.md +1 -0
- python_docs_mcp_server-0.3.0/.planning/agent-context/adr-001-source-adapters.md +49 -0
- python_docs_mcp_server-0.3.0/.planning/agent-context/adr-006-serialization.md +55 -0
- python_docs_mcp_server-0.3.0/.planning/agent-context/cpython-source-sha-pin.md +78 -0
- python_docs_mcp_server-0.3.0/.planning/agent-context/pyyaml-safe-loader-audit.md +52 -0
- python_docs_mcp_server-0.3.0/.planning/agent-context/readme-glama-six-tool-refresh.md +54 -0
- python_docs_mcp_server-0.3.0/.planning/agent-context/zstd-cache-codec.md +71 -0
- python_docs_mcp_server-0.3.0/.planning/issues/v0.3.0/00-README.md +63 -0
- python_docs_mcp_server-0.3.0/.planning/issues/v0.3.0/01-zstd-cache-codec.md +83 -0
- python_docs_mcp_server-0.3.0/.planning/issues/v0.3.0/02-readme-glama-six-tool-refresh.md +59 -0
- python_docs_mcp_server-0.3.0/.planning/issues/v0.3.0/03-pyyaml-safe-loader-audit.md +50 -0
- python_docs_mcp_server-0.3.0/.planning/issues/v0.3.0/04-adr-006-serialization.md +91 -0
- python_docs_mcp_server-0.3.0/.planning/issues/v0.3.0/05-adr-001-source-adapters.md +76 -0
- python_docs_mcp_server-0.3.0/.planning/issues/v0.3.0/06-cpython-source-sha-pin.md +61 -0
- python_docs_mcp_server-0.3.0/AGENT-EXECUTION-PIPELINE.md +287 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/AGENTS.md +16 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/CHANGELOG.md +46 -0
- python_docs_mcp_server-0.3.0/OPENCLAW-FORGE-PROTOCOL.md +293 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/PKG-INFO +3 -2
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/README.md +1 -1
- python_docs_mcp_server-0.3.0/STRATEGIC-ROADMAP-2026-05-29.md +271 -0
- python_docs_mcp_server-0.3.0/docs/architecture/ADR-001-source-adapters.md +128 -0
- python_docs_mcp_server-0.3.0/docs/architecture/ADR-006-serialization.md +87 -0
- python_docs_mcp_server-0.3.0/docs/architecture/YAML-TRUST-BOUNDARY.md +23 -0
- python_docs_mcp_server-0.3.0/glama.json +7 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/pyproject.toml +2 -1
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/server.json +2 -2
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/__main__.py +35 -1
- python_docs_mcp_server-0.3.0/src/mcp_server_python_docs/cache/__init__.py +1 -0
- python_docs_mcp_server-0.3.0/src/mcp_server_python_docs/cache/codec.py +114 -0
- python_docs_mcp_server-0.3.0/src/mcp_server_python_docs/ingestion/cpython_versions.py +53 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/ingestion/sphinx_json.py +21 -1
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/services/persistent_cache.py +35 -7
- python_docs_mcp_server-0.3.0/tests/cache/__init__.py +1 -0
- python_docs_mcp_server-0.3.0/tests/cache/test_codec.py +49 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_ingestion.py +52 -1
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_mcp_get_docs_cache_smoke.py +9 -10
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_persistent_docs_cache.py +71 -1
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_stdio_smoke.py +82 -68
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_synonyms.py +44 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/uv.lock +60 -1
- python_docs_mcp_server-0.2.0/glama.json +0 -7
- python_docs_mcp_server-0.2.0/src/mcp_server_python_docs/ingestion/cpython_versions.py +0 -32
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.cursorignore +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.github/INTEGRATION-TEST.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.github/TEST-STRATEGY.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.github/dependabot.yml +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.github/workflows/ci.yml +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.github/workflows/codeql.yml +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.github/workflows/e2e.yml +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.github/workflows/release.yml +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.github/workflows/scorecard.yml +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.github/workflows/security.yml +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.gitignore +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/POSITIONING.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/ROADMAP.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/phases/09-compare-versions/09-01-data-shape-spike-PLAN.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/phases/09-compare-versions/09-01-data-shape-spike-SUMMARY.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/phases/09-compare-versions/09-02-result-models-PLAN.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/phases/09-compare-versions/09-02-result-models-SUMMARY.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/phases/09-compare-versions/09-03-compare-service-PLAN.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/phases/09-compare-versions/09-03-compare-service-SUMMARY.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/phases/09-compare-versions/09-04-mcp-tool-wiring-PLAN.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/phases/09-compare-versions/09-04-mcp-tool-wiring-SUMMARY.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/phases/09-compare-versions/09-05-user-facing-docs-PLAN.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/phases/09-compare-versions/09-05-user-facing-docs-SUMMARY.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/phases/09-compare-versions/09-CONTEXT.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/phases/09-compare-versions/09-REVIEW.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/phases/09-compare-versions/09-VERIFICATION.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/phases/10-whatsnew/10-CONTEXT.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/.planning/phases/11-detect-venv/11-CONTEXT.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/CLAUDE.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/CONTRIBUTING.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/LICENSE +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/SECURITY.md +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/__init__.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/app_context.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/data/synonyms.yaml +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/detection.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/diagnostics.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/errors.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/ingestion/__init__.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/ingestion/inventory.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/ingestion/publish.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/models.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/py.typed +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/retrieval/__init__.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/retrieval/budget.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/retrieval/query.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/retrieval/ranker.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/server.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/services/__init__.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/services/cache.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/services/compare.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/services/content.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/services/observability.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/services/package_docs.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/services/search.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/services/version.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/services/version_resolution.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/storage/__init__.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/storage/db.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/src/mcp_server_python_docs/storage/schema.sql +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/__init__.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/conftest.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/fixtures/retrieval_regression_cases.json +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/fixtures/sample_broken.fjson +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/fixtures/sample_library.fjson +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/fixtures/schema-get_docs-input.json +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/fixtures/schema-get_docs-output.json +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/fixtures/schema-list_versions-output.json +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/fixtures/schema-search_docs-input.json +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/fixtures/schema-search_docs-output.json +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_ci_workflows.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_compare_versions.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_compare_versions_spike.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_detection.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_doctor.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_multi_version.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_package_docs.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_packaging.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_phase1_integration.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_publish.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_retrieval.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_retrieval_regression.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_schema.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_schema_snapshot.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_services.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_stability.py +0 -0
- {python_docs_mcp_server-0.2.0 → python_docs_mcp_server-0.3.0}/tests/test_stdio_hygiene.py +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
|
|
2
|
+
language: "en-US"
|
|
3
|
+
|
|
4
|
+
reviews:
|
|
5
|
+
profile: "chill"
|
|
6
|
+
request_changes_workflow: false
|
|
7
|
+
high_level_summary: true
|
|
8
|
+
review_status: true
|
|
9
|
+
path_filters:
|
|
10
|
+
- "src/**"
|
|
11
|
+
- "tests/**"
|
|
12
|
+
path_instructions:
|
|
13
|
+
- path: "src/**"
|
|
14
|
+
instructions: |
|
|
15
|
+
Focus review on correctness, MCP tool behavior, runtime compatibility,
|
|
16
|
+
cache/index compatibility, packaging impact, and security boundaries.
|
|
17
|
+
Avoid comments about planning docs, release docs, or repository process
|
|
18
|
+
unless the changed source code makes those docs materially inaccurate.
|
|
19
|
+
- path: "tests/**"
|
|
20
|
+
instructions: |
|
|
21
|
+
Focus review on meaningful assertions, regression coverage, fixture
|
|
22
|
+
correctness, deterministic behavior, and avoiding network- or
|
|
23
|
+
environment-dependent tests unless the test is explicitly marked as an
|
|
24
|
+
integration smoke test.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# CODEOWNERS — requests maintainer visibility on forbidden-territory paths.
|
|
2
|
+
#
|
|
3
|
+
# Source of truth: AGENT-EXECUTION-PIPELINE.md §2 (Forbidden Territory),
|
|
4
|
+
# required by §10 (Pre-flight Checklist).
|
|
5
|
+
#
|
|
6
|
+
# For these rules to be ENFORCED, branch protection on `main` must enable
|
|
7
|
+
# "Require review from Code Owners". CODEOWNERS alone only requests review;
|
|
8
|
+
# branch protection only blocks merge when review rules are enabled.
|
|
9
|
+
#
|
|
10
|
+
# Autonomous agents may NOT modify these paths without explicit Vision approval
|
|
11
|
+
# (pipeline §2). Any agent PR touching them must add the `supervisor-review`
|
|
12
|
+
# label and stop short of self-merging (pipeline §7).
|
|
13
|
+
|
|
14
|
+
# --- Project identity, dependencies, classifiers (only `version` is agent-editable) ---
|
|
15
|
+
/pyproject.toml @ayhammouda
|
|
16
|
+
|
|
17
|
+
# --- Permanent commitments and trust posture ---
|
|
18
|
+
/LICENSE @ayhammouda
|
|
19
|
+
/SECURITY.md @ayhammouda
|
|
20
|
+
|
|
21
|
+
# --- Load-bearing brand assets ---
|
|
22
|
+
/README.md @ayhammouda
|
|
23
|
+
/.planning/POSITIONING.md @ayhammouda
|
|
24
|
+
|
|
25
|
+
# --- Release history (adding entries is fine; rewriting history is not) ---
|
|
26
|
+
/CHANGELOG.md @ayhammouda
|
|
27
|
+
|
|
28
|
+
# --- CI/CD and supply chain (release path especially) ---
|
|
29
|
+
# The single /.github/ rule covers workflows and release.yml. Last-matching-
|
|
30
|
+
# pattern wins in CODEOWNERS — adding narrower entries with the same owner
|
|
31
|
+
# below would be no-ops and would silently *override* this rule if a different
|
|
32
|
+
# owner is ever added here, so we keep ownership of /.github/ uniform.
|
|
33
|
+
/.github/ @ayhammouda
|
|
34
|
+
|
|
35
|
+
# --- Index schema and migrations (rebuilds existing user indexes) ---
|
|
36
|
+
# NOTE: the retrieved-docs *cache* table lives in
|
|
37
|
+
# src/mcp_server_python_docs/services/persistent_cache.py and is NOT covered
|
|
38
|
+
# here — it is best-effort, fingerprint-scoped, and agent-editable per
|
|
39
|
+
# decision 5.7. Only the canonical *index* schema is forbidden territory.
|
|
40
|
+
**/storage/schema.sql @ayhammouda
|
|
41
|
+
**/migrations/ @ayhammouda
|
|
42
|
+
|
|
43
|
+
# --- Archival roadmap history ---
|
|
44
|
+
/.planning/ROADMAP.md @ayhammouda
|
|
45
|
+
|
|
46
|
+
# --- Governing policy + strategy documents ---
|
|
47
|
+
/AGENT-EXECUTION-PIPELINE.md @ayhammouda
|
|
48
|
+
/OPENCLAW-FORGE-PROTOCOL.md @ayhammouda
|
|
49
|
+
/STRATEGIC-ROADMAP-2026-05-29.md @ayhammouda
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
name: Autonomous Agent Task
|
|
2
|
+
description: A task spec scoped for unattended execution by an autonomous coding agent (Claude Code or similar).
|
|
3
|
+
title: "[vX.Y.Z] <scope> — <verb> <thing>"
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
This template enforces the issue structure required by
|
|
9
|
+
`AGENT-EXECUTION-PIPELINE.md` §3 (in the repo root). An issue missing
|
|
10
|
+
any required section is **not** agent-ready and will not pass the §10
|
|
11
|
+
pre-flight checklist. Do not apply the `agent-ready` label from this
|
|
12
|
+
template; a maintainer applies it only after reading the completed
|
|
13
|
+
issue end-to-end. Read the pipeline doc and
|
|
14
|
+
`STRATEGIC-ROADMAP-2026-05-29.md` before filling this out.
|
|
15
|
+
- type: textarea
|
|
16
|
+
id: context
|
|
17
|
+
attributes:
|
|
18
|
+
label: Context (self-containment)
|
|
19
|
+
description: Link to the per-issue context file, this pipeline doc, the roadmap, any relevant ADR or `.planning/phases/0X-*` directory, and prior related issues.
|
|
20
|
+
value: |
|
|
21
|
+
- Per-issue context file: `.planning/agent-context/<issue-slug>.md` (read this first)
|
|
22
|
+
- Pipeline: `AGENT-EXECUTION-PIPELINE.md`
|
|
23
|
+
- Roadmap: `STRATEGIC-ROADMAP-2026-05-29.md` §<section>
|
|
24
|
+
- Related issues:
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
27
|
+
- type: textarea
|
|
28
|
+
id: goal
|
|
29
|
+
attributes:
|
|
30
|
+
label: Goal (one sentence)
|
|
31
|
+
description: The single outcome that counts as success.
|
|
32
|
+
validations:
|
|
33
|
+
required: true
|
|
34
|
+
- type: textarea
|
|
35
|
+
id: acceptance
|
|
36
|
+
attributes:
|
|
37
|
+
label: Acceptance criteria (testable checkbox list)
|
|
38
|
+
description: Each criterion must be testable, atomic, achievable without touching forbidden territory, and verifiable in <5 minutes (pipeline §4). Prefer exact commands and expected output.
|
|
39
|
+
value: |
|
|
40
|
+
- [ ] `<exact command>` <expected result>
|
|
41
|
+
- [ ] `<exact command>` <expected result>
|
|
42
|
+
validations:
|
|
43
|
+
required: true
|
|
44
|
+
- type: textarea
|
|
45
|
+
id: scope
|
|
46
|
+
attributes:
|
|
47
|
+
label: Scope boundaries
|
|
48
|
+
description: Explicit In scope / Out of scope. Out-of-scope work is a stop-and-comment trigger, never silent expansion.
|
|
49
|
+
value: |
|
|
50
|
+
**In scope:**
|
|
51
|
+
-
|
|
52
|
+
|
|
53
|
+
**Out of scope:**
|
|
54
|
+
-
|
|
55
|
+
validations:
|
|
56
|
+
required: true
|
|
57
|
+
- type: textarea
|
|
58
|
+
id: forbidden
|
|
59
|
+
attributes:
|
|
60
|
+
label: Forbidden-territory reminders
|
|
61
|
+
description: Repeat the AGENT-EXECUTION-PIPELINE.md §2 items relevant to THIS issue. If the task appears to require touching any of them, stop and comment.
|
|
62
|
+
validations:
|
|
63
|
+
required: true
|
|
64
|
+
- type: textarea
|
|
65
|
+
id: validation
|
|
66
|
+
attributes:
|
|
67
|
+
label: Validation commands (pipeline §5 gate)
|
|
68
|
+
description: The exact canonical gate, in order, plus any change-type-specific gates. Must pass before any PR is opened.
|
|
69
|
+
value: |
|
|
70
|
+
```bash
|
|
71
|
+
uv run ruff check src/ tests/
|
|
72
|
+
uv run pyright src/
|
|
73
|
+
uv run pytest --tb=short -q
|
|
74
|
+
uv run python-docs-mcp-server doctor
|
|
75
|
+
```
|
|
76
|
+
validations:
|
|
77
|
+
required: true
|
|
78
|
+
- type: textarea
|
|
79
|
+
id: pr-and-recovery
|
|
80
|
+
attributes:
|
|
81
|
+
label: PR requirements & recovery
|
|
82
|
+
description: What the PR description must include (pipeline §6) and where to go if blocked (pipeline §8).
|
|
83
|
+
value: |
|
|
84
|
+
- PR title matches this issue title verbatim; body uses
|
|
85
|
+
`.github/PULL_REQUEST_TEMPLATE/agent.md`.
|
|
86
|
+
- Branch: `agent/<issue-number>-<kebab-summary>`.
|
|
87
|
+
- If blocked: stop, write `WORKING-NOTES.md` on the branch, comment on
|
|
88
|
+
this issue per pipeline §8. **No PR and no silent scope expansion.**
|
|
89
|
+
validations:
|
|
90
|
+
required: true
|
|
91
|
+
- type: input
|
|
92
|
+
id: effort
|
|
93
|
+
attributes:
|
|
94
|
+
label: Effort estimate (hours)
|
|
95
|
+
description: Rough hours. Agent must bail and escalate if work exceeds 2× this estimate (pipeline §8).
|
|
96
|
+
validations:
|
|
97
|
+
required: true
|
|
98
|
+
- type: checkboxes
|
|
99
|
+
id: acknowledgements
|
|
100
|
+
attributes:
|
|
101
|
+
label: Agent acknowledgements
|
|
102
|
+
options:
|
|
103
|
+
- label: I will work on a branch, never on `main`, and will not self-merge.
|
|
104
|
+
required: true
|
|
105
|
+
- label: I will stop and comment rather than silently expand scope or touch forbidden territory.
|
|
106
|
+
required: true
|
|
107
|
+
- label: I will add `supervisor-review` if any pipeline §7 trigger fires.
|
|
108
|
+
required: true
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Autonomous-agent PR template. Enforces AGENT-EXECUTION-PIPELINE.md §6.
|
|
3
|
+
PR title MUST match the issue title verbatim. Never self-merge.
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
Closes #<issue-number>
|
|
7
|
+
|
|
8
|
+
## Acceptance criteria
|
|
9
|
+
<!-- Copy every criterion from the issue. Check the box only when satisfied,
|
|
10
|
+
and add one line of evidence (command + observed result) per item. -->
|
|
11
|
+
- [ ] <criterion 1> — <evidence>
|
|
12
|
+
- [ ] <criterion 2> — <evidence>
|
|
13
|
+
|
|
14
|
+
## Validation gate output
|
|
15
|
+
<!-- Paste the tail of each gate command. All must be green before opening this PR. -->
|
|
16
|
+
```text
|
|
17
|
+
$ uv run ruff check src/ tests/
|
|
18
|
+
$ uv run pyright src/
|
|
19
|
+
$ uv run pytest --tb=short -q
|
|
20
|
+
$ uv run python-docs-mcp-server doctor
|
|
21
|
+
```
|
|
22
|
+
<!-- Plus any change-type-specific gates from pipeline §5 (stdio smoke,
|
|
23
|
+
validate-corpus, uv lock --check) that applied to this change. -->
|
|
24
|
+
|
|
25
|
+
## CodeRabbit review
|
|
26
|
+
<!-- After CodeRabbit comments, summarize findings as:
|
|
27
|
+
- Blocking: <items or None>
|
|
28
|
+
- Follow-up: <items or None>
|
|
29
|
+
- False positive: <items or None>
|
|
30
|
+
If CodeRabbit has not run yet, write "Pending." Do not mark findings green
|
|
31
|
+
by silence. -->
|
|
32
|
+
Pending.
|
|
33
|
+
|
|
34
|
+
## Why this approach
|
|
35
|
+
<!-- One paragraph max. If the issue fully prescribed the approach, say so.
|
|
36
|
+
If you cite a design choice NOT in the issue, that is a §7 trigger. -->
|
|
37
|
+
|
|
38
|
+
## Why this triggered supervisor review
|
|
39
|
+
<!-- List any pipeline §7 triggers and explain each. If none, write "None."
|
|
40
|
+
If any fired: this PR is opened for supervisor review only; do not merge it yourself,
|
|
41
|
+
and ensure the `supervisor-review` label is applied. -->
|
|
42
|
+
None.
|
|
@@ -51,6 +51,7 @@ Replace `X.Y.Z` below with the version you are releasing (e.g. `0.1.7`). Complet
|
|
|
51
51
|
```
|
|
52
52
|
Must report `✅ server.json is valid`. If validation fails, shorten `server.json` `description` on `main` before tagging (the `pyproject.toml` description is unbounded by this constraint and can stay longer).
|
|
53
53
|
- [ ] Integration tests from `.github/INTEGRATION-TEST.md` are complete and signed off
|
|
54
|
+
- [ ] Refresh README `## Tools`, `glama.json`, and registry/version badges to match the current tool surface.
|
|
54
55
|
- [ ] `Doctor` subcommand passes:
|
|
55
56
|
```bash
|
|
56
57
|
uv run python-docs-mcp-server doctor
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Agent Context — ADR-001 (Source Adapters)
|
|
2
|
+
|
|
3
|
+
> One-read working context for issue `[v0.3.0] docs — write ADR-001 (Source Adapters)`.
|
|
4
|
+
> A **writing** task. Every claim must match the code — verify before you assert.
|
|
5
|
+
|
|
6
|
+
## 1. Roadmap excerpts (the principles you are recording)
|
|
7
|
+
|
|
8
|
+
- **Principle 2.1:** Canonical source only. CPython at a pinned tag for stdlib
|
|
9
|
+
docs; PyPI metadata API for package URLs. No scraped mirrors. No third-party indexers.
|
|
10
|
+
- **Principle 2.2:** Offline-first *runtime*. No network access at query time.
|
|
11
|
+
- **Principle 2.7:** Layered design with stable contracts; the **source
|
|
12
|
+
connector** is layer 1 of 8 and is what makes the pattern cloneable.
|
|
13
|
+
|
|
14
|
+
## 2. The two source adapters that exist today (describe these)
|
|
15
|
+
|
|
16
|
+
1. **CPython documentation source** (`src/mcp_server_python_docs/ingestion/`):
|
|
17
|
+
- `cpython_versions.py` — pinned build targets (`CPYTHON_DOCS_BUILD_CONFIG`:
|
|
18
|
+
per-version `tag` + `sphinx_pin`). Five versions: 3.10–3.14.
|
|
19
|
+
- `__main__.py` `build-index` path — `git clone --depth 1 --branch <tag>` of
|
|
20
|
+
`python/cpython`, builds docs with `sphinx-build -b json` in a dedicated venv.
|
|
21
|
+
- `sphinx_json.py` — parses the Sphinx JSON output into the index; also loads
|
|
22
|
+
`synonyms.yaml`. `inventory.py` — parses `objects.inv` for exact symbol resolution.
|
|
23
|
+
2. **PyPI metadata source** (`src/mcp_server_python_docs/services/package_docs.py`):
|
|
24
|
+
- Backs `lookup_package_docs`. A **controlled** PyPI metadata lookup
|
|
25
|
+
(`GET /pypi/<project>/json`) that returns only project/docs/homepage/source
|
|
26
|
+
URLs — not a generic web fetch, not scraped docs.
|
|
27
|
+
|
|
28
|
+
## 3. The one documented exception to "offline-first"
|
|
29
|
+
|
|
30
|
+
- `lookup_package_docs` performs a network call to PyPI's metadata API. This is
|
|
31
|
+
**not** a docs-*query*-time call against the canonical stdlib index — it is a
|
|
32
|
+
controlled, narrowly-scoped metadata lookup. The ADR must state this exception
|
|
33
|
+
explicitly so the offline-first invariant (2.2) stays honest. (See README's
|
|
34
|
+
"Why not Context7" section and `SECURITY.md` scope for the existing framing.)
|
|
35
|
+
|
|
36
|
+
## 4. Known pitfalls
|
|
37
|
+
|
|
38
|
+
- **Verify, don't assume.** Open each cited file and confirm the behavior before
|
|
39
|
+
writing it into the ADR. An ADR that misstates current behavior is worse than none.
|
|
40
|
+
- Don't document adapters that don't exist (Rust/Go) beyond a single "future
|
|
41
|
+
adopters clone this contract" sentence — that's the cloneability point, not a claim.
|
|
42
|
+
- No code, schema, or workflow changes — writing only.
|
|
43
|
+
- Keep it factual; "reference architecture" is not claimed externally (5.6).
|
|
44
|
+
|
|
45
|
+
## 5. Decision log
|
|
46
|
+
|
|
47
|
+
- File path:
|
|
48
|
+
- Claims you verified against code (file:line):
|
|
49
|
+
- Anything ambiguous about the layer contract that you flagged for the maintainer:
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Agent Context — ADR-006 (Serialization)
|
|
2
|
+
|
|
3
|
+
> One-read working context for issue `[v0.3.0] docs — write ADR-006 (Serialization)`.
|
|
4
|
+
> This is a **writing** task. You are recording locked decisions, not making new ones.
|
|
5
|
+
|
|
6
|
+
## 1. Roadmap excerpts (the decisions you are recording — verbatim)
|
|
7
|
+
|
|
8
|
+
- **Principle 2.5:** Wire format is explicit and pluggable on structured tools
|
|
9
|
+
only. Compact JSON default; TOON opt-in *if and only if* the empirical study
|
|
10
|
+
supports it. `get_docs` stays markdown. *Token economy is empirical, not architectural.*
|
|
11
|
+
- **Principle 2.7:** Layered design with stable contracts — eight layers, the
|
|
12
|
+
**serializer** being one of them.
|
|
13
|
+
- **Decision 5.3:** Storage stays SQLite + markdown. **TOON-as-storage killed.**
|
|
14
|
+
- **Decision 5.4:** Empirical Claude-tokenizer study **gates** the `format="toon"` decision.
|
|
15
|
+
- **Decision 5.5:** `format` parameter on `search_docs`, `list_versions`,
|
|
16
|
+
`compare_versions` **only**. JSON default; TOON opt-in. `get_docs` stays markdown.
|
|
17
|
+
- **Decision 5.8:** The study measures **client-side rewrap**, not just raw
|
|
18
|
+
payload tokens; reports tokens AND latency per tool family.
|
|
19
|
+
|
|
20
|
+
## 2. Code touch-points (for accuracy — describe, do NOT change)
|
|
21
|
+
|
|
22
|
+
- Tool results are Pydantic models in `src/mcp_server_python_docs/models.py`
|
|
23
|
+
(e.g. `GetDocsResult`); tools live in `server.py` and return those models,
|
|
24
|
+
which FastMCP serializes. The "serializer layer" is the conceptual seam where
|
|
25
|
+
a structured result becomes a wire string — that's what the `format` parameter
|
|
26
|
+
will eventually parameterize. You are documenting that seam, not building it.
|
|
27
|
+
- `get_docs` returns markdown content (`GetDocsResult.content`) — this is why it
|
|
28
|
+
is carved out of the `format` parameter (markdown is already the canonical body).
|
|
29
|
+
|
|
30
|
+
## 3. Pattern to follow
|
|
31
|
+
|
|
32
|
+
- There is no `docs/architecture/` ADR yet — you are establishing the house
|
|
33
|
+
style. Use the exact skeleton embedded in the issue. Keep it tight (1–2 pages).
|
|
34
|
+
- Number/name the file `docs/architecture/ADR-006-serialization.md` to match the
|
|
35
|
+
roadmap's ADR numbering (ADR-001 and ADR-006 are the first two written).
|
|
36
|
+
|
|
37
|
+
## 4. Known pitfalls
|
|
38
|
+
|
|
39
|
+
- **Do not invent.** If you find yourself making a serialization choice that is
|
|
40
|
+
not in §2 above, that's a pipeline §7 trigger ("cites a design choice not in
|
|
41
|
+
the issue") — stop and comment.
|
|
42
|
+
- **Do not implement `format`.** That is v0.3.x and is gated by the study.
|
|
43
|
+
- Don't claim a TOON token win — the study hasn't run. The ADR records that TOON
|
|
44
|
+
is *opt-in and gated*, with the bar being "win holds after client rewrap" (5.8).
|
|
45
|
+
- "Reference architecture" is **not** claimed externally (decision 5.6) — keep
|
|
46
|
+
the ADR factual, not promotional.
|
|
47
|
+
|
|
48
|
+
## 5. Decision log
|
|
49
|
+
|
|
50
|
+
- Final file path: `docs/architecture/ADR-006-serialization.md`
|
|
51
|
+
- Any wording you were unsure mapped to a locked decision (and how you resolved it):
|
|
52
|
+
none; the ADR records only roadmap principles 2.5 and 2.7 plus decisions
|
|
53
|
+
5.3, 5.4, 5.5, and 5.8.
|
|
54
|
+
- Open follow-ups: link the ADR to the v0.3.0 TOKEN-STUDY.md once that study
|
|
55
|
+
exists.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Agent Context — CPython source SHA pin
|
|
2
|
+
|
|
3
|
+
> One-read working context for issue `[v0.3.0] ingestion — pin CPython source by commit SHA`.
|
|
4
|
+
> PARTIAL issue: you do the pin + verification; Vision handles the SECURITY.md prose.
|
|
5
|
+
|
|
6
|
+
## 1. Roadmap excerpt
|
|
7
|
+
|
|
8
|
+
> **Build-time supply-chain hardening** (roadmap §4, v0.3.0): Pin CPython source
|
|
9
|
+
> by SHA, not by tag. Document the threat model in SECURITY.md (the `build-index`
|
|
10
|
+
> CPython clone is the largest non-runtime attack surface). Verify Sphinx-build
|
|
11
|
+
> environment isolation.
|
|
12
|
+
>
|
|
13
|
+
> **Decision 5.10 (locked):** Build-time supply chain (the `build-index` CPython
|
|
14
|
+
> clone) is an explicit risk area; threat model documented in SECURITY.md;
|
|
15
|
+
> CPython source pinned by SHA.
|
|
16
|
+
|
|
17
|
+
## 2. Code touch-points
|
|
18
|
+
|
|
19
|
+
- `src/mcp_server_python_docs/ingestion/cpython_versions.py`
|
|
20
|
+
- `CPythonDocsBuildConfig(TypedDict)` — add `sha: str`.
|
|
21
|
+
- `CPYTHON_DOCS_BUILD_CONFIG` — five entries, currently `{"tag": ..., "sphinx_pin": ...}`:
|
|
22
|
+
`3.10→v3.10.20`, `3.11→v3.11.15`, `3.12→v3.12.13`, `3.13→v3.13.13`, `3.14→v3.14.4`.
|
|
23
|
+
Add the resolved SHA to each. Resolve with:
|
|
24
|
+
`git ls-remote https://github.com/python/cpython.git refs/tags/<tag>`
|
|
25
|
+
(use the dereferenced commit — the `<tag>^{}` line — not the annotated-tag object).
|
|
26
|
+
- `src/mcp_server_python_docs/__main__.py:210–226` — the clone:
|
|
27
|
+
`git clone --depth 1 --branch config["tag"] https://github.com/python/cpython.git <clone_dir>`.
|
|
28
|
+
After it, add: `rev = git -C <clone_dir> rev-parse HEAD`; if `rev != config["sha"]`,
|
|
29
|
+
log a clear error and **abort this version's build** (raise / skip-with-failure —
|
|
30
|
+
match the existing error-handling style in this function; do not silently continue).
|
|
31
|
+
- `tests/test_ingestion.py:53` — existing assertion
|
|
32
|
+
`config["tag"].startswith(f"v{version}.")`. Add a sibling assertion that
|
|
33
|
+
`config["sha"]` matches `^[0-9a-f]{40}$`.
|
|
34
|
+
|
|
35
|
+
## 3. Patterns to follow
|
|
36
|
+
|
|
37
|
+
- `tests/test_ingestion.py` iterates `CPYTHON_DOCS_BUILD_CONFIG.items()` for the
|
|
38
|
+
tag assertion — extend that same loop for the SHA assertion. No new fixtures.
|
|
39
|
+
- The clone block already uses `subprocess.run([...], check=True, capture_output=True, text=True)`
|
|
40
|
+
— reuse that idiom for the `rev-parse` call.
|
|
41
|
+
|
|
42
|
+
## 4. Known pitfalls
|
|
43
|
+
|
|
44
|
+
- **`--branch <tag>` cannot take a raw SHA** on a shallow clone against GitHub by
|
|
45
|
+
default. Keep the tag-based shallow fetch; make the **SHA a post-clone
|
|
46
|
+
verification gate**, not the fetch ref. That is the integrity win: a moved/re-tagged
|
|
47
|
+
tag now fails the build instead of silently changing canonical content.
|
|
48
|
+
- Use the **dereferenced commit SHA** (peeled tag), not the annotated tag object's
|
|
49
|
+
own SHA — `rev-parse HEAD` after checkout gives the commit; match that.
|
|
50
|
+
- **Do not edit `SECURITY.md`** (forbidden). Draft the threat-model paragraph in
|
|
51
|
+
the PR body + decision log below for Vision to apply.
|
|
52
|
+
- A full `build-index` clones over the network and takes minutes — do not gate the
|
|
53
|
+
PR on it. The unit tests cover the config + verification logic offline.
|
|
54
|
+
- Don't bump any tag to a newer CPython point release; pin the SHA of the
|
|
55
|
+
**current** tag only.
|
|
56
|
+
|
|
57
|
+
## 5. Decision log
|
|
58
|
+
|
|
59
|
+
- Resolved SHAs (tag → 40-hex commit), one line each:
|
|
60
|
+
- 3.10 / v3.10.20 → 842e987df856a5d4db37933c62a3456930a19092
|
|
61
|
+
- 3.11 / v3.11.15 → 2340a037f7450e70fccfe411e6531afb4d57a312
|
|
62
|
+
- 3.12 / v3.12.13 → 3bb231a6a5dc02b95658877318bf61501a7209e9
|
|
63
|
+
- 3.13 / v3.13.13 → 01104ce1beb3135c2e0c01ec835b994c1f55a1c0
|
|
64
|
+
- 3.14 / v3.14.4 → 23116f998f6789d8c2fbe5ed5b8146854c8c2a4f
|
|
65
|
+
- Where/how the verification aborts on mismatch: after the shallow
|
|
66
|
+
tag-based clone in `build-index`, `git -C <clone_dir> rev-parse HEAD` is
|
|
67
|
+
compared to the authoritative config SHA. A mismatch logs the version, tag,
|
|
68
|
+
actual SHA, and expected SHA, then raises `SystemExit(1)` before Sphinx setup
|
|
69
|
+
or content ingestion can proceed.
|
|
70
|
+
- **Draft SECURITY.md threat-model paragraph (for Vision to apply):**
|
|
71
|
+
> The largest build-time supply-chain input is the `build-index` clone of the
|
|
72
|
+
> upstream CPython repository, which provides the source tree used to generate
|
|
73
|
+
> canonical documentation content. Each supported CPython docs release is pinned
|
|
74
|
+
> to the exact commit SHA that its human-readable release tag currently resolves
|
|
75
|
+
> to; the tag is retained for operator readability, but the SHA is the
|
|
76
|
+
> authoritative integrity anchor. If a tag is reissued, moved, or otherwise
|
|
77
|
+
> resolves to different source content, the build fails before Sphinx setup or
|
|
78
|
+
> content ingestion rather than silently publishing changed documentation.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Agent Context — PyYAML safe-loader audit
|
|
2
|
+
|
|
3
|
+
> One-read working context for issue `[v0.3.0] security — audit and document PyYAML safe-loader discipline`.
|
|
4
|
+
|
|
5
|
+
## 1. Roadmap excerpt
|
|
6
|
+
|
|
7
|
+
> **PyYAML safe-loader audit** (roadmap §4, v0.3.0): `synonyms.yaml` is loaded at
|
|
8
|
+
> startup; confirm only `yaml.safe_load` is used; document the trust boundary.
|
|
9
|
+
>
|
|
10
|
+
> **Decision 5.11 (locked):** PyYAML safe-loader-only discipline; `synonyms.yaml`
|
|
11
|
+
> is the only YAML input and is packaged with the wheel.
|
|
12
|
+
|
|
13
|
+
## 2. Code touch-points (already audited for you — verify, then lock in)
|
|
14
|
+
|
|
15
|
+
- `src/mcp_server_python_docs/server.py:54–57` — loads `data/synonyms.yaml` via
|
|
16
|
+
`importlib.resources` and `yaml.safe_load(path.read_text())`. ✅ safe.
|
|
17
|
+
- `src/mcp_server_python_docs/ingestion/sphinx_json.py:595–603` — loads the same
|
|
18
|
+
file via `importlib.resources` + `yaml.safe_load`, then type-checks it is a
|
|
19
|
+
mapping. ✅ safe.
|
|
20
|
+
- `src/mcp_server_python_docs/data/synonyms.yaml` — the only YAML data input;
|
|
21
|
+
packaged with the wheel.
|
|
22
|
+
- No other `yaml.load(` / `yaml.unsafe_load(` / custom-`Loader=` call sites were
|
|
23
|
+
found in `src/`. Your job is to **prove** this with a regression test, not just
|
|
24
|
+
assert it.
|
|
25
|
+
|
|
26
|
+
## 3. Patterns to follow
|
|
27
|
+
|
|
28
|
+
- `tests/test_synonyms.py` already exists — add the discipline test there.
|
|
29
|
+
- A clean way to assert the discipline: walk `src/` `.py` files and fail if any
|
|
30
|
+
line matches `yaml.load(` or `yaml.unsafe_load(` or `Loader=` (excluding
|
|
31
|
+
`SafeLoader`). Keep it simple and fast; no new deps.
|
|
32
|
+
- `tests/test_packaging.py` already verifies `synonyms.yaml` ships in the wheel —
|
|
33
|
+
reference it; you don't need to duplicate that.
|
|
34
|
+
|
|
35
|
+
## 4. Known pitfalls
|
|
36
|
+
|
|
37
|
+
- **Do not edit `SECURITY.md`** (forbidden). Capture the trust-boundary write-up
|
|
38
|
+
in a new `docs/architecture/YAML-TRUST-BOUNDARY.md` and recommend SECURITY.md
|
|
39
|
+
wording for Vision.
|
|
40
|
+
- The two `safe_load` sites both also exist as `.pyc` in `__pycache__`; grep
|
|
41
|
+
source dirs only (`src/`, `tests/`), not `__pycache__`.
|
|
42
|
+
- If the codebase is already clean (expected), the deliverable is the **lock-in**
|
|
43
|
+
(regression test + doc note), not a code fix. Say so plainly in the PR.
|
|
44
|
+
- A literal `yaml.load(` string inside your *test* (as a pattern to search for)
|
|
45
|
+
is fine and expected — the test asserts it does not appear in non-test `src/`.
|
|
46
|
+
|
|
47
|
+
## 5. Decision log
|
|
48
|
+
|
|
49
|
+
- Audit result (clean / findings):
|
|
50
|
+
- Regression test name + what it scans:
|
|
51
|
+
- Trust-boundary doc location:
|
|
52
|
+
- Recommended SECURITY.md wording (for Vision):
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Agent Context — README / glama 6-tool refresh
|
|
2
|
+
|
|
3
|
+
> One-read working context for issue `[v0.3.0] docs — refresh public surfaces to the 6-tool surface`.
|
|
4
|
+
|
|
5
|
+
## 1. Roadmap excerpt
|
|
6
|
+
|
|
7
|
+
> **README + PyPI + glama.json refresh** (roadmap §4, v0.3.0): Reflect the 6-tool
|
|
8
|
+
> surface including `compare_versions`. **Decision 5.9:** adopt as a release-cycle
|
|
9
|
+
> discipline going forward — every release updates the public-facing tool table.
|
|
10
|
+
> Roadmap §3 notes the surface "still lists 5 in some surfaces."
|
|
11
|
+
|
|
12
|
+
## 2. Code / file touch-points
|
|
13
|
+
|
|
14
|
+
- **Tool order of truth:** `src/mcp_server_python_docs/server.py`, the `@mcp.tool`
|
|
15
|
+
declarations in this order: `search_docs` (≈297), `get_docs` (≈318),
|
|
16
|
+
`lookup_package_docs` (≈341), `list_versions` (≈358), `detect_python_version`
|
|
17
|
+
(≈372), `compare_versions` (≈394).
|
|
18
|
+
- `README.md`:
|
|
19
|
+
- `## Tools` section at **line ~178**: already a six-row table in the correct
|
|
20
|
+
order. Verify, don't churn it.
|
|
21
|
+
- **Stale badge near the top:** `MCP%20Registry-v0.1.4`. Current published
|
|
22
|
+
registry/PyPI version is **0.2.1**. This is the concrete fix and the only
|
|
23
|
+
allowed edit above the first install code block.
|
|
24
|
+
- Hero section = everything **above the first install code block** (~line 125)
|
|
25
|
+
— FORBIDDEN except the stale registry/version badge above.
|
|
26
|
+
- `glama.json`: `description` field (prose, no tool list today).
|
|
27
|
+
- `.github/RELEASE.md`: add one checklist line for decision 5.9.
|
|
28
|
+
|
|
29
|
+
## 3. Patterns to follow
|
|
30
|
+
|
|
31
|
+
- `tests/test_packaging.py` asserts packaging consistency — run it; if you add a
|
|
32
|
+
surface, see whether a cheap assertion belongs there (optional, not required).
|
|
33
|
+
- Badge lines in `README.md` are markdown image links; match the existing style
|
|
34
|
+
when updating the version.
|
|
35
|
+
|
|
36
|
+
## 4. Known pitfalls
|
|
37
|
+
|
|
38
|
+
- **False positive — do NOT "fix":** `.github/INTEGRATION-TEST.md:139` says
|
|
39
|
+
"all five versions". That is the **five Python versions (3.10–3.14)**, not five
|
|
40
|
+
tools. Leave it alone.
|
|
41
|
+
- **PyPI short description is forbidden.** It comes from `pyproject.toml`
|
|
42
|
+
`[project].description`. If it's stale, comment — do not edit `pyproject.toml`.
|
|
43
|
+
(The README *body* you edit *is* the PyPI long description on the next release,
|
|
44
|
+
which is fine; only the hero is off-limits.)
|
|
45
|
+
- `README.md`, `.github/RELEASE.md`, and `glama.json` are all CODEOWNERS-owned.
|
|
46
|
+
Your PR will request maintainer review by design — note it, don't fight it.
|
|
47
|
+
- Don't bump `server.json` / package versions here; that's release-managed.
|
|
48
|
+
|
|
49
|
+
## 5. Decision log
|
|
50
|
+
|
|
51
|
+
- Badge: pinned to `0.2.1` vs made version-agnostic — which and why:
|
|
52
|
+
- Surfaces audited and their state (README Tools / glama / server.json):
|
|
53
|
+
- RELEASE.md checklist line added:
|
|
54
|
+
- Anything left for the maintainer (e.g. stale pyproject short description):
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Agent Context — zstd cache codec
|
|
2
|
+
|
|
3
|
+
> One-read working context for issue `[v0.3.0] cache — add zstd codec layer`.
|
|
4
|
+
> Everything you need is here; do not go fishing in `.planning/` archive material.
|
|
5
|
+
|
|
6
|
+
## 1. Roadmap excerpt (the goal — do not re-derive)
|
|
7
|
+
|
|
8
|
+
> **Workstream J — app-level zstd cache compression** (roadmap §4, v0.3.0):
|
|
9
|
+
> Targets the retrieved-docs cache *value column only*. Trained dict on a
|
|
10
|
+
> representative `get_docs` corpus. Codec column for forward-compat. Expected
|
|
11
|
+
> ratio strong because zstd's dictionary mode is especially effective on small
|
|
12
|
+
> correlated records — exactly the cache-entry shape.
|
|
13
|
+
>
|
|
14
|
+
> **Decision 5.7 (locked):** App-level zstd on retrieved-docs cache, *no gate*.
|
|
15
|
+
> Versioned codec column for forward-compat.
|
|
16
|
+
|
|
17
|
+
## 2. Code touch-points (file paths + symbols)
|
|
18
|
+
|
|
19
|
+
- `src/mcp_server_python_docs/services/persistent_cache.py`
|
|
20
|
+
- `retrieved_docs_cache` table — created inline with `CREATE TABLE IF NOT EXISTS` at **line ~47**. Columns today: `index_fingerprint, version, slug, anchor, max_chars, start_index, result_json TEXT, created_at`. PK is the first six columns.
|
|
21
|
+
- `put(...)` — **line ~118**, `INSERT OR REPLACE ... result_json` = `result.model_dump_json()`.
|
|
22
|
+
- `get(...)` — **line ~80**, `SELECT result_json ...` then `GetDocsResult.model_validate_json(row[0])`.
|
|
23
|
+
- This is **best-effort**: every read/write is wrapped in try/except and the cache disables cleanly (`self._conn = None`) on error. Preserve that posture.
|
|
24
|
+
- **New module:** `src/mcp_server_python_docs/cache/codec.py` (create the `cache/` package with `__init__.py`). Public API the pipeline §4 example expects:
|
|
25
|
+
- `list_supported() -> list[str]` → `['none', 'zstd', 'zstd-dict-v1']`
|
|
26
|
+
- `encode(text: str, codec: str, *, dictionary=None) -> bytes`, `decode(blob: bytes, codec: str, *, dictionary=None) -> str`.
|
|
27
|
+
- **Tests:** new dir `tests/cache/` with `__init__.py` and `test_codec.py`.
|
|
28
|
+
|
|
29
|
+
## 3. Existing test patterns to follow
|
|
30
|
+
|
|
31
|
+
- `tests/test_persistent_docs_cache.py` shows the established cache-test idiom:
|
|
32
|
+
the `_cache(tmp_path, marker)` helper builds an index fingerprint file +
|
|
33
|
+
`PersistentDocsCache`, and `populated_db` (a fixture from `tests/conftest.py`)
|
|
34
|
+
provides a live SQLite index. Reuse this shape for the no-regression test.
|
|
35
|
+
- The "survives restart" test (`test_cache_survives_restart_and_miss_falls_back`)
|
|
36
|
+
is the exact pattern for your "value reads back identically after restart" criterion:
|
|
37
|
+
build a `PersistentDocsCache`, write, construct a *second* instance on the same
|
|
38
|
+
files, assert `hits == 1` and equality.
|
|
39
|
+
- Tests are plain `pytest` functions, `from __future__ import annotations`, type-annotated args. Match that.
|
|
40
|
+
|
|
41
|
+
## 4. Known pitfalls
|
|
42
|
+
|
|
43
|
+
- **The cache table is NOT `storage/schema.sql`.** `schema.sql` is the canonical
|
|
44
|
+
*index* schema and is forbidden territory. The cache table is owned by
|
|
45
|
+
`persistent_cache.py` and is yours to evolve per 5.7. Do not confuse them.
|
|
46
|
+
- **Existing on-disk caches lack the new column.** `CREATE TABLE IF NOT EXISTS`
|
|
47
|
+
will *not* add a column to an existing table. Detect the column
|
|
48
|
+
(`PRAGMA table_info(retrieved_docs_cache)`) and `ALTER TABLE ... ADD COLUMN
|
|
49
|
+
compression TEXT NOT NULL DEFAULT 'none'` when missing, inside the same
|
|
50
|
+
try/except that already tolerates a broken cache.
|
|
51
|
+
- **Value column type.** `result_json` is `TEXT`. Compressed output is `bytes`.
|
|
52
|
+
Either store the blob in a new `BLOB` column and keep `result_json` for the
|
|
53
|
+
`'none'` path, or store all payloads as `BLOB` and record the codec. Simplest
|
|
54
|
+
forward-compatible design: keep `result_json` semantics for `'none'`, add a
|
|
55
|
+
`result_blob BLOB` for compressed codecs, and let `compression` select which
|
|
56
|
+
column to read. Document whichever you choose in the decision log below.
|
|
57
|
+
- **`zstandard` must already be importable** (maintainer pre-req). If
|
|
58
|
+
`import zstandard` fails, STOP and comment — do not edit `pyproject.toml`/`uv.lock`.
|
|
59
|
+
- **`zstd-dict-v1` has no production dictionary in this issue.** Make the codec
|
|
60
|
+
*work* only when an explicit dictionary object is supplied by tests. The
|
|
61
|
+
cache's default production codec is `'zstd'`. Shipping a trained dictionary
|
|
62
|
+
artifact is a separate, Vision-gated follow-up.
|
|
63
|
+
- Decode must dispatch off the stored `compression` value, never off the current
|
|
64
|
+
default — otherwise old `'none'` rows break the day the default flips.
|
|
65
|
+
|
|
66
|
+
## 5. Decision log (fill this in as you work)
|
|
67
|
+
|
|
68
|
+
- Chosen value-storage layout (`result_blob` vs reuse `result_json`):
|
|
69
|
+
- How `zstd-dict-v1` round-trips in tests (dict training approach):
|
|
70
|
+
- Default production codec wired into `put()`:
|
|
71
|
+
- Anything you deferred or escalated:
|