---
phase: 01-installer-and-setup-architecture-simplification
plan: 02
type: execute
wave: 2
depends_on:
  - 01
files_modified:
  - ../shared-client-python/src/fivemghost_shared_client/registration/cli_registry.py
  - ../shared-client-python/src/fivemghost_shared_client/registration/claude_internal.py
  - ../shared-client-python/src/fivemghost_shared_client/registration/codex_internal.py
  - ../shared-client-python/src/fivemghost_shared_client/registration/gemini_internal.py
  - ../shared-client-python/src/fivemghost_shared_client/registration/openclaw.py
  - ../shared-client-python/tests/test_registration_configs.py
autonomous: true
requirements:
  - REG-01
  - REG-02
  - REG-03
  - VER-01
must_haves:
  truths:
    - "Supported AI clients are auto-detected and registered to the same canonical runtime command rather than per-client `python3` + launcher variants."
    - "Registration fails clearly when no supported client is detected or when detected-client registration fails."
    - "Registration output contains AI-actionable remediation information instead of vague best-effort warnings."
  artifacts:
    - path: "../shared-client-python/src/fivemghost_shared_client/registration/cli_registry.py"
      provides: "Single registration orchestration path and failure semantics"
    - path: "../shared-client-python/tests/test_registration_configs.py"
      provides: "Regression coverage for canonical command serialization across supported clients"
  key_links:
    - from: "../shared-client-python/src/fivemghost_shared_client/registration/cli_registry.py"
      to: "../shared-client-python/src/fivemghost_shared_client/registration/codex_internal.py"
      via: "serialized runtime command"
      pattern: "reddit-mcp|serve"
    - from: "../shared-client-python/src/fivemghost_shared_client/registration/cli_registry.py"
      to: "../shared-client-python/src/fivemghost_shared_client/registration/openclaw.py"
      via: "JSON/TOML config emission"
      pattern: "reddit-mcp|serve"
---

<objective>
Refactor shared registration so every supported AI client receives the same canonical `reddit-mcp serve` invocation and the registration layer enforces hard-failure semantics.

Purpose: The CLI contract from Plan 01 is not enough unless the shared registration layer stops serializing `python3`/launcher assumptions and stops reporting best-effort success. This plan makes registration behavior match the new product contract.
Output: Simplified registration APIs, canonical runtime serialization across clients, AI-actionable registration failure output, and regression tests that reject stale runtime assumptions.
</objective>

<execution_context>
@/Users/yimingwang/.codex/get-shit-done/workflows/execute-plan.md
@/Users/yimingwang/.codex/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/REQUIREMENTS.md
@.planning/ROADMAP.md
@.planning/phases/01-installer-and-setup-architecture-simplification/01-CONTEXT.md
@src/reddit_mcp/cli.py
@../shared-client-python/src/fivemghost_shared_client/registration/cli_registry.py
@../shared-client-python/src/fivemghost_shared_client/registration/claude_internal.py
@../shared-client-python/src/fivemghost_shared_client/registration/codex_internal.py
@../shared-client-python/src/fivemghost_shared_client/registration/gemini_internal.py
@../shared-client-python/src/fivemghost_shared_client/registration/openclaw.py
@../shared-client-python/tests/test_registration_configs.py
</context>

<tasks>

<task type="auto">
  <name>Task 1: Replace runtime-plus-launcher registration with canonical command serialization</name>
  <read_first>.planning/phases/01-installer-and-setup-architecture-simplification/01-CONTEXT.md, src/reddit_mcp/cli.py, ../shared-client-python/src/fivemghost_shared_client/registration/cli_registry.py, ../shared-client-python/src/fivemghost_shared_client/registration/codex_internal.py, ../shared-client-python/tests/test_registration_configs.py</read_first>
  <files>../shared-client-python/src/fivemghost_shared_client/registration/cli_registry.py, ../shared-client-python/src/fivemghost_shared_client/registration/claude_internal.py, ../shared-client-python/src/fivemghost_shared_client/registration/codex_internal.py, ../shared-client-python/src/fivemghost_shared_client/registration/gemini_internal.py, ../shared-client-python/src/fivemghost_shared_client/registration/openclaw.py</files>
  <action>Refactor the shared registration API so it no longer accepts or serializes a guessed runtime plus `launcher_path` pair. Update the supported client writers to persist the canonical command contract centered on `reddit-mcp serve`, using the exact command/args shape decided by Plan 01 for Claude, Codex, Gemini, and OpenClaw. Remove `python3`, launcher script paths, and other retired runtime assumptions from emitted configs. Preserve direct config writes and CLI-driven registration where needed, but make every path target the same canonical runtime command.</action>
  <verify>
    <automated>py -3 -m pytest ../shared-client-python/tests/test_registration_configs.py -q</automated>
  </verify>
  <acceptance_criteria>
    - `../shared-client-python/src/fivemghost_shared_client/registration/cli_registry.py` does not require a `launcher_path` argument.
    - Registration writers in `claude_internal.py`, `codex_internal.py`, `gemini_internal.py`, and `openclaw.py` emit configs containing `reddit-mcp` and `serve`.
    - None of those registration files emits the exact string `python3` for reddit-mcp registration.
    - `py -3 -m pytest ../shared-client-python/tests/test_registration_configs.py -q` exits 0.
  </acceptance_criteria>
  <done>The registration layer has one runtime contract across all supported clients, with no launcher-based escape hatch remaining in the shared serializer API.</done>
</task>

<task type="auto">
  <name>Task 2: Enforce hard registration failure semantics and AI-actionable remediation</name>
  <read_first>.planning/phases/01-installer-and-setup-architecture-simplification/01-CONTEXT.md, ../shared-client-python/src/fivemghost_shared_client/registration/cli_registry.py, ../shared-client-python/tests/test_registration_configs.py, src/reddit_mcp/cli.py</read_first>
  <files>../shared-client-python/src/fivemghost_shared_client/registration/cli_registry.py, ../shared-client-python/tests/test_registration_configs.py</files>
  <action>Change `cli_registry.py` so registration stops being best-effort success. If no supported client is detected, raise a failure that upstream `register` and `setup` can treat as fatal. If a detected client registration fails, surface that failure as fatal too, and include machine-readable or at least AI-actionable remediation data naming the target client, config location, and canonical command to write. Expand tests to cover no-client and failed-detected-client behavior, not just config serialization.</action>
  <verify>
    <automated>py -3 -m pytest ../shared-client-python/tests/test_registration_configs.py -q</automated>
  </verify>
  <acceptance_criteria>
    - `../shared-client-python/src/fivemghost_shared_client/registration/cli_registry.py` raises or returns a fatal failure when zero supported clients are detected.
    - `../shared-client-python/src/fivemghost_shared_client/registration/cli_registry.py` raises or returns a fatal failure when a detected client registration attempt fails.
    - Failure output in `cli_registry.py` contains a client identifier and the canonical command text `reddit-mcp serve`.
    - `../shared-client-python/tests/test_registration_configs.py` contains coverage for no-client and detected-client-failure cases.
    - `py -3 -m pytest ../shared-client-python/tests/test_registration_configs.py -q` exits 0.
  </acceptance_criteria>
  <done>The registration layer now behaves like a required setup phase instead of a warning-only side effect, and AI operators get explicit repair instructions when it fails.</done>
</task>

</tasks>

<threat_model>
## Trust Boundaries

| Boundary | Description |
|----------|-------------|
| local machine -> supported AI client configs | Incorrect serialization can poison client config and make MCP unusable |
| CLI detection -> registration result | False success here causes setup to report usable state when no client can launch the server |

## STRIDE Threat Register

| Threat ID | Category | Component | Disposition | Mitigation Plan |
|-----------|----------|-----------|-------------|-----------------|
| T-01-04 | T | serialized MCP command | mitigate | Serialize one canonical command path and remove per-client runtime guessing |
| T-01-05 | I | failure reporting | mitigate | Include exact target client/config and canonical command in remediation output |
| T-01-06 | D | no-client / failed-client registration | mitigate | Treat these as fatal registration outcomes rather than warnings |
</threat_model>

<verification>
Run `py -3 -m pytest ../shared-client-python/tests/test_registration_configs.py -q` and inspect emitted config fixtures if needed to confirm every client uses the canonical command and registration failures are fatal.
</verification>

<success_criteria>
Any supported client registration produced by shared-client-python points at the same canonical runtime command, and registration can no longer silently succeed while leaving the user with no usable MCP client.
</success_criteria>

<output>
After completion, create `.planning/phases/01-installer-and-setup-architecture-simplification/01-installer-and-setup-architecture-simplification-02-SUMMARY.md`
</output>
