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