diff --git a/.github/prompts/plan-phase3.prompt.md b/.github/prompts/plan-phase3.prompt.md new file mode 100644 index 0000000..0293a16 --- /dev/null +++ b/.github/prompts/plan-phase3.prompt.md @@ -0,0 +1,169 @@ +**Phase 3 Results: Packaging Contract and Surface Decoupling (Wheel/sdist Resources + Docs-Only Authoring)** + +This section finalizes Phase 3 by defining how authored docs are packaged as runtime resources, how runtime loading avoids filesystem assumptions, and how website and MCP distribution surfaces are decoupled while sharing one authored source. + +### Greenfield Framing (Normative) + +This Phase 3 design assumes a full refactor with intentional break-and-replace behavior: + +1. No compatibility shims, aliases, adapter layers, or dual-read runtime paths. +2. No runtime dependency on repository checkout layout. +3. Runtime docs access is package-resource-only. +4. Canonical authoring remains in `docs/` in source control. + +### Research Baseline (Packaging + Runtime) + +Authoritative references used for this phase: + +1. Python `importlib.resources` docs (`files`, `Traversable`, and zip-safe behavior) +2. Python packaging guidance for wheel/sdist data inclusion +3. Hatchling build target configuration guidance for including non-code files +4. Existing repository constraints from Steps 4-5 (registry-first, deterministic startup, resource-first discovery) + +Best-practice conclusions applied to this design: + +1. Package docs as build artifacts so runtime reads work from installed wheels. +2. Keep docs source-of-truth in one place (`docs/`) and project into package resource space at build time. +3. Avoid `Path(__file__)`/repo-root probing in runtime paths. +4. Enforce parity across wheel and sdist so local/dev/prod behavior does not drift. + +### Phase 3 Responsibilities (Normative) + +Phase 3 MUST: + +1. Ensure authored markdown under `docs/` is included in wheel and sdist artifacts. +2. Ensure runtime docs registry/document reads use `importlib.resources` only. +3. Ensure MCP runtime behavior is independent of current working directory or checkout structure. +4. Ensure website docs build continues to consume source `docs/` directly. +5. Remove materialization/path-probing coupling from runtime loader code. +6. Preserve deterministic packaged docs layout for registry/resource URI generation. + +### Packaging Contract (Wheel + sdist) + +Canonical packaging behavior: + +1. Source-authored docs remain at repository root: `docs/`. +2. Build projects docs into package resource space under `personal_mcp/docs/` inside artifacts. +3. Runtime anchor for docs loading is `importlib.resources.files("personal_mcp").joinpath("docs")`. +4. Build artifacts MUST include: + - top-level docs pages used by discovery/overview + - `docs/skills//SKILL.md` + - `docs/skills//references/**` + +Parity requirements: + +1. Wheel and sdist contain equivalent docs content for runtime use. +2. Missing docs resources in either artifact is a hard validation failure. + +### Build-System Plan (pyproject + build) + +Primary target file: + +1. `pyproject.toml` + +Configuration goals: + +1. Add explicit build inclusion rules so docs resources are shipped in wheel artifacts. +2. Add explicit sdist inclusion rules so docs are present for source builds. +3. Keep inclusion deterministic and auditable (no implicit glob side effects beyond intended docs content). +4. Ensure packaged destination path matches runtime anchor (`personal_mcp/docs`). + +Implementation note: + +1. Use Hatchling-native inclusion mapping (for example force-include or equivalent target-level include mapping) to project `docs/` into package resource space. +2. Prefer one clear packaging path over multiple fallback packaging mechanisms. + +### Runtime Loader Contract (No Filesystem Assumptions) + +Primary target file: + +1. `src/personal_mcp/skills/document_loader.py` + +Required runtime behavior: + +1. Remove repository-root discovery helpers and path-probing candidates. +2. Remove metadata-based document path overrides that bypass canonical skill layout. +3. Resolve SKILL and reference documents via package-resource-relative paths only. +4. Keep reads UTF-8 and deterministic. +5. Raise explicit errors for missing packaged resources; no fallback probing. + +Prohibited runtime behavior: + +1. No `Path(__file__).resolve().parents[...]` lookup for docs. +2. No implicit fallback to source-tree `docs/` during runtime reads. +3. No slug-guessing or namespace substitution for path recovery. + +### Surface Decoupling Contract (Website vs MCP) + +Website surface: + +1. Website build pipeline consumes source `docs/` directly (`uv run zensical build`). +2. Static output (`site/`) remains a build artifact served by web mounting logic. + +MCP surface: + +1. MCP runtime serves docs from packaged resources loaded by registry/resource handlers. +2. MCP does not read `site/` and does not depend on website build artifacts. + +Decoupling guarantees: + +1. One authored source (`docs/`), two distribution surfaces (website + MCP runtime). +2. Changes to website serving do not alter MCP resource loading semantics. +3. Changes to MCP runtime loader do not require website materialization logic. + +### Integration Plan for Existing Modules + +Primary integration targets: + +1. `pyproject.toml`: add wheel/sdist docs inclusion mapping. +2. `src/personal_mcp/skills/document_loader.py`: replace filesystem probing with package-resource loading. +3. `src/personal_mcp/main.py`: keep startup composition deterministic once registry/resource registration is in place. +4. `src/personal_mcp/mcp.py`: maintain registry-driven resource composition as canonical runtime surface. +5. `src/personal_mcp/web/docs_mount.py`: continue static-site mount behavior without coupling to MCP runtime docs loading. + +Cleanup targets: + +1. Remove obsolete references to materialization-only modules if no longer present/used. +2. Remove dead code paths that attempt source-tree fallback loading. + +### Validation and Test Plan (Phase 3 Scope) + +Build/package validation: + +1. Build wheel and sdist in CI/local. +2. Inspect artifacts to confirm `personal_mcp/docs/**` exists and includes representative skill/reference files. +3. Install built wheel in isolated environment and verify resource reads via `importlib.resources.files(...)`. + +Runtime validation: + +1. Run MCP in an environment where repo-root docs paths are unavailable and confirm reads still succeed. +2. Verify representative URIs resolve (skill document and reference document). +3. Confirm startup fails clearly if required packaged docs resources are missing. + +Decoupling validation: + +1. Run `uv run zensical build` to verify website pipeline still consumes source `docs/`. +2. Confirm MCP runtime does not require `site/` presence. +3. Confirm web static serving behavior is unchanged when docs are built. + +Expected command path in this repo: + +1. `uv run pytest -q` +2. `uv run zensical build` + +### Acceptance Criteria for Phase 3 Completion + +Phase 3 is complete when all are true: + +1. Wheel and sdist include docs resources in deterministic package paths. +2. Runtime docs loading works from installed artifacts using `importlib.resources` only. +3. Runtime docs loading has no checkout-path dependency and no fallback probing. +4. Website docs build remains source-docs-driven and independent of MCP runtime loading. +5. No compatibility shims, aliases, or dual runtime loader paths exist. + +### Non-goals for Phase 3 + +1. No Step 6 discovery-tool fallback implementation details. +2. No URI aliasing or backward-compat transition mechanics. +3. No redesign of skill frontmatter/schema contracts already finalized in earlier steps. +4. No web UI visual redesign or docs IA overhaul.