The namespace health check (05fdcee) classified a false-ready namespace but
only returned an advisory blocks_merge_workflow flag; nothing in the merge
gate consumed it. Wire it in so a broken live namespace hard-blocks merge.
- review_merge_state_machine.assess_workflow_blockers: add live_namespace_broken
blocker (registered-in-FastMCP but not callable-through-namespace).
- assess_state_advancement: forward **blocker_kwargs so can_approve/can_merge/
workflow_status honor the full blocker set (also fixes latent drop of
mcp_reconnect_failed/stale_capability_state through those paths).
- gitea_assess_review_merge_state_machine tool: accept live_namespace_broken and
thread it through all state-machine calls.
- Tests: prove can_merge/workflow_status/tool block on live_namespace_broken even
with every review state + pre-merge gate satisfied; bridge classify verdict.
- Docs: enforcement section wiring blocks_merge_workflow -> live_namespace_broken.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
77 lines
3.0 KiB
Markdown
77 lines
3.0 KiB
Markdown
# MCP namespace EOF recovery
|
|
|
|
Gitea MCP tools can be registered in the Python FastMCP server while the IDE's
|
|
live MCP namespace is still unusable. The failure usually appears as
|
|
`client is closing: EOF`, `transport closed`, or an empty response when calling
|
|
a tool such as `gitea_whoami`.
|
|
|
|
Do not treat static tool registration as proof that review or merge workflows
|
|
can proceed. A reviewer or merger flow must have live namespace evidence that
|
|
the required tool is callable through the configured namespace.
|
|
|
|
## Required namespace probes
|
|
|
|
Run the health check after changing MCP config, switching branches that affect
|
|
server code, or seeing EOF from any Gitea namespace:
|
|
|
|
```bash
|
|
python3 test_mcp_conn.py --config ~/.gemini/config/mcp_config.json
|
|
```
|
|
|
|
By default the script checks these namespaces and required tools:
|
|
|
|
| Namespace | Required tool |
|
|
| --- | --- |
|
|
| `gitea-author` | `gitea_whoami` |
|
|
| `gitea-reviewer` | `gitea_whoami` |
|
|
| `gitea-merger` | `gitea_whoami` |
|
|
| `gitea-tools` | `gitea_list_profiles` |
|
|
|
|
Use `--namespace gitea-reviewer` to test only one namespace. A passing probe
|
|
requires:
|
|
|
|
1. The namespace exists in the MCP config.
|
|
2. JSON-RPC initialize succeeds.
|
|
3. `tools/list` returns the required tool.
|
|
4. `tools/call` successfully invokes the required tool.
|
|
|
|
## Recovery steps
|
|
|
|
When a namespace returns EOF:
|
|
|
|
1. Note the reported namespace, required tool, PID, profile, environment
|
|
summary, and config path.
|
|
2. Stop any stale MCP server process for that PID.
|
|
3. Reload or touch the MCP config so the IDE reconnects the namespace.
|
|
4. Verify the namespace command, args, profile env, and checkout path point at
|
|
the current repository.
|
|
5. Re-run `python3 test_mcp_conn.py --namespace <name>`.
|
|
6. Resume review or merge work only after the required tool call passes.
|
|
|
|
The read-only `gitea_assess_mcp_namespace_health` tool can classify probe
|
|
evidence supplied by a client. It intentionally distinguishes
|
|
`required_tool_registered=true` from `required_tool_callable=false`; the latter
|
|
must block reviewer and merger workflows until the live namespace is repaired.
|
|
|
|
## Enforcement in the review/merge state machine
|
|
|
|
The block is not advisory. Feed the `blocks_merge_workflow` verdict from
|
|
`gitea_assess_mcp_namespace_health` into
|
|
`gitea_assess_review_merge_state_machine` as `live_namespace_broken`:
|
|
|
|
```text
|
|
health = gitea_assess_mcp_namespace_health(namespace="gitea-merger", ...)
|
|
state = gitea_assess_review_merge_state_machine(
|
|
state_completion=...,
|
|
pre_merge_gates=...,
|
|
live_namespace_broken=health["blocks_merge_workflow"],
|
|
)
|
|
# state["merge"]["allowed"] is False whenever the live namespace is broken,
|
|
# even when every review state and pre-merge gate is otherwise satisfied.
|
|
```
|
|
|
|
When `live_namespace_broken=True`, `assess_workflow_blockers`,
|
|
`can_approve`, `can_merge`, and `workflow_status` all fail closed. This is the
|
|
guard that stops a merge from proceeding on a false-ready namespace, as in the
|
|
PR #418 halt that motivated this work (#543).
|