Usages:
  conventions: .goga/usages/conventions.md
  ralphex: .goga/usages/cooks/ralphex.md

Annotations: |
  The `conventions` practice is used for:
  - Working with the codebase
  - Organizing the REPL development cycle
  - Debugging and testing
  - Organizing the test infrastructure
  - Understanding the general principles and rules of development and testing in the project

  This cell is a thin launcher over the external `ralphex` binary — its sole responsibility
  is to invoke ralphex with the resolved plan and ralphex options, then propagate the
  subprocess exit code. Config generation (.ralphex/config), ralphex option resolution
  (CLI > ProjectConfig > omit), and agent-wrapper resolution live in the caller
  (goga/build): this cell performs none of them.

  Use the `ralphex` practice to interact with the external ralphex binary (CLI contract,
  invocation shape, flag set, PATH-resolved invocation, exit-code propagation).

  The launcher inherits the process environment for the ralphex subprocess; an
  optional env layer (dict of strings), supplied by the caller, is applied on
  top of the inherited environment for that subprocess only. The layer is never
  logged and never printed on dry-run (secret-safe). The standard library
  subprocess and shutil modules are used for invoking the binary and the PATH
  check. All output goes to sys.stderr (click is not used).

---

"run_ralphex(plan: str, options: dict[str, str | int | bool], dry_run: bool, env: dict[str, str] | None = None) -> exit_code: int":
  location: run_ralphex.py
  annotations: |
    Launch the external `ralphex` binary to execute the given build plan with the resolved
    ralphex options. goga-side entry point to ralphex; performs no config generation,
    option resolution, or wrapper resolution — those live in goga/build.

    `plan`: path to the plan file (markdown), resolved by the caller (goga/build). Passed
           to ralphex as the positional argument.
    `options`: resolved ralphex options — the caller (goga/build) has already applied
              precedence and stage binding. Keys are ralphex option names; each key maps
              to exactly one ralphex CLI flag:
              - tasks_only (bool)             → --tasks-only          (bare flag)
              - review (bool)                 → --review              (bare flag)
              - external_only (bool)          → -e                    (bare flag)
              - session_timeout (str)         → --session-timeout     (value flag)
              - idle_timeout (str)            → --idle-timeout        (value flag)
              - wait (str)                    → --wait                (value flag)
              - max_iterations (int)          → --max-iterations      (value flag)
              - review_patience (int)         → --review-patience     (value flag)
              - max_external_iterations (int) → --max-external-iterations (value flag)
              - base_ref (str)                → --base-ref            (value flag)
    `dry_run`: when True, print the assembled ralphex command to sys.stderr and return 0
              without launching.
    `env`: optional environment layer applied on top of the inherited process
           environment for the ralphex subprocess only. Never logged, never printed.
    `exit_code`: 0 on success, 1 when ralphex is missing from PATH or the launch is
                rejected before the exec, otherwise ralphex's own exit code

    Algorithm:
    1. Receive `plan`, `options`, `dry_run`, and `env` from the caller
    2. Invoke ralphex via the `ralphex` practice with `plan` as the positional argument,
       --config-dir .ralphex/, and the flags mapped from `options`
    3. On `dry_run`: print the assembled command to sys.stderr and return 0 — never print
       the `env` layer values
    4. Verify `ralphex` is on PATH; when absent — return 1
    5. Execute ralphex via subprocess with the composed environment and propagate its
       exit code; a pre-exec rejection surfaces as a clean one-line message and exit
       code 1 — never a traceback, never the `env` contents

    Requirements:
    - Map `options` to ralphex CLI flags per the table: a bool key that is True emits a
      bare flag (False or absent → omit); a scalar key emits --<flag> <value> and is
      omitted when the value is None or an empty string — EXCEPT the zero-valued
      external flags: review_patience 0 and max_external_iterations 0 are meaningful
      (disabled / ralphex auto) and ARE passed as 0
    - The pass-mode bare flags (tasks_only, review, external_only) are mutually
      exclusive per invocation — the caller guarantees it; this launcher does not check
    - Apply the `ralphex` practice's exit-code rules verbatim

    Constraints:
    - Do not generate .ralphex/config, resolve options, or resolve wrappers — caller's
      responsibility
    - Do not check flag exclusivity — the caller owns pass composition
    - Do not log or otherwise expose the `env` layer contents

---

Author: Goga
CreatedAt: 26/07/26
Description: |
  Thin launcher over the external `ralphex` binary. Invokes ralphex with the resolved
  plan and ralphex options (resolved by the caller), then propagates the subprocess exit
  code. Config generation, option resolution, and wrapper resolution live in goga/build.
