From dd253f87e5122e086acf06fd35637b6aa6134176 Mon Sep 17 00:00:00 2001 From: Latte Date: Sat, 27 Jun 2026 10:44:06 +0200 Subject: [PATCH] chore: add PLAN.md and branch for local package + full coverage Co-Authored-By: Claude Opus 4.8 (1M context) --- PLAN.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 PLAN.md diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000..da0d584 --- /dev/null +++ b/PLAN.md @@ -0,0 +1,36 @@ +# PLAN — local stdio package + safe full-API coverage + +Branch: `feat/local-package-and-full-coverage` (from `dev`). All PRs target `dev`. +Flow: HEAD -> custom branch -> dev -> main. Never push directly to dev/main. + +Baseline (recorded Phase 0): 284 passed, 1 skipped, coverage 84.04%, threshold 80%. + +## Phase checklist + +- [x] Phase 0 — Branch from dev, baseline recorded, PLAN.md committed. +- [ ] Phase 1 — Extract transport-agnostic core + shared tool registry. + - Decouple `tools/raw_tools.py` from `fastapi.HTTPException` (core ToolError). + - Single `registry.py` owning name -> (handler, definition, read/write, resource-type). + - `server.py` consumes the registry. Boundary test: importing core pulls no `fastapi`. +- [ ] Phase 2 — stdio adapter (`stdio_app.py`) + packaging. + - `mcp` SDK core dep; web deps to `[server]` extra; console scripts; version 0.2.0 -> 0.3.0. + - stdio resolves PAT owner (`GET /user`), sets request_context once; policy+audit ON. + - Local audit-log fallback under user state dir. +- [ ] Phase 3 — Resource-type-aware authorization (fail-closed). + - Classify repo/user/org/admin/misc from (method, path); enforce per type. + - admin default-deny; org membership verified; user==caller; unverifiable => deny. +- [ ] Phase 4 — gitea_request classifier + full coverage by default. + - Deterministic (method, path) -> read|write with override table; unknown path => deny. +- [ ] Phase 5 — Tests: authz matrix, write-mode bypass, classifier, stdio adapter, boundary. +- [ ] Phase 6 — Docs & README (local vs server quickstart, authz model, packaging, CLAUDE.md). +- [ ] Phase 7 — `.gitea/workflows/publish.yml` (uv build + publish to Gitea registry on tag). +- [ ] Phase 8 — Verify green + coverage >= baseline, `uv build`, push, open PR into dev. + +## Key deltas found during orientation + +- No single tool registry today: definitions in `mcp_protocol.AVAILABLE_TOOLS`, + handlers in `server.TOOL_HANDLERS`. Phase 1 unifies them. +- `tools/raw_tools.py` imports `fastapi.HTTPException` — the only core->web import to break. +- Current authz is repo-only and lives in `server._verify_user_repository_access`. +- stdio mode must run with `AUTH_ENABLED=false` (config otherwise requires MCP_API_KEYS). +- `AGENTS.md` absent at root though CLAUDE.md cites it; create it from the contract.