diff --git a/docs/llm-workflow-runbooks.md b/docs/llm-workflow-runbooks.md index 1b04cb3..425ce86 100644 --- a/docs/llm-workflow-runbooks.md +++ b/docs/llm-workflow-runbooks.md @@ -370,6 +370,36 @@ git branch -d fix/issue-123-example All three helpers accept `--dry-run` to print the exact commands/paths without touching anything. +### MCP-native commit path (#260) + +When the active author profile allows **`gitea.repo.commit`** and +**`gitea_commit_files`** is visible in the client, that is the **only** approved +path for committing files to the tracked repository. Do not improvise alternate +encoding or transport when MCP commit is available. + +**Required before commit:** + +1. Call `gitea_resolve_task_capability` for `commit_files` or + `gitea_commit_files` and confirm `allowed_in_current_session` is true. +2. Use `gitea_commit_files` with file payloads prepared in the author worktree. +3. Stage only issue-scoped paths; never commit throwaway `_encode_*` / + `_emit_*` / `_inline_*` helpers. + +**Explicitly forbidden workarounds** when MCP commit is reachable: + +- `WebFetch` / HTTP calls to external decode sites (for example httpbin base64 + endpoints) +- Playwright or other browser automation to bypass MCP +- Manual LLM-generated base64 pasted into ad-hoc scripts +- Delegating commit authority to a subagent while the main session has + `gitea.repo.commit` on an author profile + +**If shell encoding is unavailable** (spawn failure, hung terminal) **and** MCP +commit cannot run: **stop** with a recovery report. Mention restarting the +session, clearing hung background terminals, switching to MCP-native commit, and +the agent temp artifact cleanup checklist. Do **not** retry shell encoding in a +loop and do **not** substitute WebFetch/Playwright/manual base64. + ### Create an issue / child issues - **Profile:** issue-manager or author (any profile allowed to create issues). diff --git a/docs/safety-model.md b/docs/safety-model.md index 1f80b51..31c740a 100644 --- a/docs/safety-model.md +++ b/docs/safety-model.md @@ -28,3 +28,21 @@ Any mutating action (e.g., Gitea issue creation from GlitchTip, or Jenkins build No default profile carries trigger capability (#152 / mcp-control-plane #56). - **GlitchTip to Gitea issue filing** is a library-only orchestrator in mcp-control-plane (not on `glitchtip-mcp`). See #153 / mcp-control-plane #57. + +## 6. Agent Commit Path (no improvised fallbacks) + +When an author execution profile allows **`gitea.repo.commit`** and the +**`gitea_commit_files`** tool is visible, agents must use that MCP path for +repository commits. Fail closed instead of improvising alternate transports. + +Forbidden when MCP commit is available: + +- WebFetch or other HTTP calls to external base64/decode services +- Playwright or browser automation used to work around MCP commit +- Manual LLM-generated base64 embedded in throwaway scripts as the primary + commit transport + +If shell helpers are unavailable and MCP commit cannot run, stop with a recovery +report (restart session, clear hung terminals, use MCP-native commit). See +[`llm-workflow-runbooks.md`](llm-workflow-runbooks.md) ยง MCP-native commit path +(#260) and agent temp artifact cleanup (#261). diff --git a/tests/test_workflow_commit_path_docs.py b/tests/test_workflow_commit_path_docs.py new file mode 100644 index 0000000..7322127 --- /dev/null +++ b/tests/test_workflow_commit_path_docs.py @@ -0,0 +1,33 @@ +"""Documentation checks for MCP-native commit path rules (#260).""" +from pathlib import Path + +REPO_ROOT = Path(__file__).resolve().parent.parent +RUNBOOK = REPO_ROOT / "docs" / "llm-workflow-runbooks.md" +SAFETY = REPO_ROOT / "docs" / "safety-model.md" + + +def test_runbook_requires_mcp_native_commit_path(): + text = RUNBOOK.read_text(encoding="utf-8") + assert "MCP-native commit path" in text + assert "gitea_commit_files" in text + assert "gitea.repo.commit" in text + assert "only" in text.lower() and "approved" in text.lower() + lower = text.lower() + for forbidden in ("webfetch", "playwright", "manual llm-generated base64"): + assert forbidden in lower + + +def test_runbook_forbids_fallback_loops(): + lower = RUNBOOK.read_text(encoding="utf-8").lower() + assert "retry shell encoding" in lower + assert "loop" in lower + assert "recovery report" in lower + + +def test_safety_model_documents_commit_fallback_ban(): + text = SAFETY.read_text(encoding="utf-8") + assert "Agent Commit Path" in text + assert "gitea_commit_files" in text + assert "WebFetch" in text + assert "Playwright" in text + assert "llm-workflow-runbooks.md" in text \ No newline at end of file