phase 3
This commit is contained in:
@@ -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-id>/SKILL.md`
|
||||||
|
- `docs/skills/<skill-id>/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.
|
||||||
Reference in New Issue
Block a user