Imports:
  - Types:
      - Config
      - BuildConfig
      - TaskExecutor
      - load_config
    From: goga/config

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

Annotations: |
  Use the `conventions` practice for development and testing.
  Use the `ralphex` practice for builds.
  Write all output to sys.stderr (click is not used).
  Run external commands via subprocess.

---

"build(plan: str, config: Config, cli_options: dict) -> exit_code:int":
  location: build.py
  annotations: |
    Orchestrates code builds through `ralphex`. The function prepares the
    execution environment and launches the build runner.

    `plan`: path to the plan file (markdown)
    `config`: loaded project configuration object
    `cli_options`: dictionary of CLI options (dry_run, worktree, skip_finalize,
                   skip_manifest_check, session_timeout, idle_timeout,
                   wait, max_iterations, review_patience)
    `exit_code`: process exit code (0 = success, 1 = failure)

    Algorithm:
    0. (pre-check) When skip_manifest_check is not set:
       - Verify all project CODEMANIFEST files are committed to git
       - Reject with exit code 1 if any uncommitted manifests are found
    1. Remove .ralphex/ directory if present (applies to all agent types)
    2. Dispatch agent-specific preconditions based on the agent field from `TaskExecutor`:
       - If agent is not in ("claude", "codex") → fail with "Unsupported agent", exit 1
       - If agent == "claude":
         a. Create or update .claude/settings.json:
            - Merge with the existing file if present
            - Inject env from `TaskExecutor` into settings["env"]
            - Set settings["attribution"] = {"commit": "", "pr": ""}
         b. Create .ralphex/claude-wrapper.sh:
            - Script body: exec env ANTHROPIC_API_KEY="$ANTHROPIC_API_TOKEN" claude "$@"
            - Apply chmod +x
         c. Update .ralphex/config:
            - Add defaults (claude_command, claude_args) if missing
            - Overwrite codex_enabled from `BuildConfig`
       - If agent == "codex":
         a. Create .ralphex/codex-wrapper.sh:
            - Script body: exec codex "$@" -m "$CODEX_MODEL"
            - Apply chmod +x
         b. Create .ralphex/config:
            - executor = codex
            - codex_command = .ralphex/codex-wrapper.sh
            - codex_sandbox = danger-full-access
            - codex_reasoning_effort = high
    3. Copy default prompts and agents from the goga package to .ralphex/,
       using the directory paths specified in `BuildConfig`
    4. Assemble the ralphex command:
       - Base command: ["ralphex", plan, "--config-dir", ".ralphex/"]
       - Apply flags with precedence: CLI options > `Config` > omit
    5. On dry_run: print the assembled command and return 0
    6. Execute `ralphex` via subprocess.call and propagate its exit code

    Requirements:
    - `ralphex` must be available on PATH; fail otherwise
    - Minimal output: log each step to sys.stderr
    - Return code: `ralphex` exit code on success, 1 on error

"main() -> exit_code:int":
  location: __main__.py
  annotations: |
    Entry point for python -m goga.build execution inside a Docker container.

    `exit_code`: process exit code (0 = success, 1 = failure)

    Algorithm:
    1. Parse CLI arguments via argparse (plan + options)
    2. Load project configuration via `load_config`
    3. Build cli_options from the parsed argparse results
    4. Invoke `build`(plan, `Config`, cli_options)
    5. Return the resulting `exit_code`

---

Author: Mikhail Trifonov
CreatedAt: 15/05/26

Description: |
  Manifest describing the code build orchestration logic through ralphex
