8000 feat(cli): 0012 DeterministicCliSidecar — gimp-agent doctor/probe/exit codes by Ryan-AI-Studios · Pull Request #37 · gimp-mcp/gimp-mcp · GitHub
[go: up one dir, main page]

Skip to content

feat(cli): 0012 DeterministicCliSidecar — gimp-agent doctor/probe/exit codes - #37

Closed
Ryan-AI-Studios wants to merge 23 commits into
gimp-mcp:mainfrom
Ryan-AI-Studios:feature/0012-deterministic-cli-sidecar
Closed

Ryan-AI-Studios wants to merge 23 commits into
gimp-mcp:mainfrom
Ryan-AI-Studios:feature/0012-deterministic-cli-sidecar

Conversation

@Ryan-AI-Studios
@Ryan-AI-Studios Ryan-AI-Studios commented Aug 3, 2026 •
Copy link
Copy Markdown

Summary

Implements conductor track 0012-DeterministicCliSidecar: product gimp-agent CLI sidecar with deterministic exit codes, JSON envelopes, doctor/probe diagnostics, and path discovery.

Deliverables

  • Host package gimp_agent/ (argparse only; no click/typer)
  • Commands: doctor [--json] [--strict], probe [--json] [--timeout], version, codes
  • Exit map CODE_* → 0–12 (+ CLI-local CLI_USAGE/GIMP_NOT_FOUND/PLUGIN_NOT_FOUND; generic exit 1)
  • Packaging: packages = [\"gimp_agent\"] + existing py-modules; gimp-agent script; ruff/basedpyright coverage
  • Probe always JSON-auth + get_gimp_info; doctor TCP is connect-only; full EXPECTED_PLUGIN_FILES (7 files)
  • Docs: README CLI section; protocol exit table; parent bin/ shim note

Review

  • Internal review clean after low fixes
  • Codex FAIL → fixes (global --json, probe success require, version rc, env JSON, NaN JSON) → Codex final PASS

Test plan

  • uv run ruff check .
  • uv run basedpyright
  • uv run pytest tests/test_gimp_agent_cli.py -q (38)
  • uv run pytest -m \"not integration and not slow\"
  • uv run gimp-agent codes --json / --json codes / GIMP_AGENT_JSON=1
  • CI green on this PR

Out of scope (later tracks)

BatchProcedure (0019), recipes (0015), atomic save (0013), install scripts (0018)

Summary by CodeRabbit

  • New Features

    • Added authenticated sessions, secure workspace restrictions, audit logging, and structured error reporting.
    • Added high-level tools for image selection, orientation, snapshots, checkpoints, layer protection, and visible composites.
    • Added the gimp-agent command-line utility for diagnostics, connectivity checks, version information, and standardized exit codes.
    • Added stable image and layer references for safer workflows.
  • Improvements

    • Exports now support alpha preservation and verification.
    • Added coordinate mapping and orientation metadata to snapshots.
  • Documentation

    • Expanded setup, security, workflow, export, and architecture guidance.
  • Tests

    • Added broad offline coverage for security, exports, snapshots, state, CLI, and editing workflows.

Ryan and others added 23 commits August 2, 2026 08:17
Add uv dev toolchain (ruff, basedpyright, pytest), project CI with
Node-24-ready Actions, gitignore for local agent/conductor governance,
offline smoke tests, and docs/planner-handoff.md for cold-start planners.
Includes small gimp_mcp_server typing/format fixes for the new gate.
Document 0001 bootstrap complete, 0002 quality stabilization as next,
and the full path through 0028 final product polish.
Full product ruff/format green; scripts layout; setup-uv@v9.0.0; lint.yml retired; planner-handoff policy.

Ledger: 83598dee-78b5-4c0a-8975-96a7b5cd15c4
…th jail

Track 0003: Class A/B exec gates, AF_INET 127.0.0.1, session auth, path jail, audit. CI green. Codex final PASS WITH DEFERRED P3.
…mapping

Visible composite snapshots (dup+merge), image_index, ToolResult structuredContent mapping, temp policy, fail-closed selection/PNG validation. Codex final PASS WITH DEFERRED P3.
* feat(export): add gimp_mcp_export host module + offline alpha tests

* fix(export): alpha-preserving merge-on-dup + file-*-export + verify tool

* docs: Issue 16 alpha export defaults, install gimp_mcp_export.py

* fix(export): recursive alpha preflight + structured MCP errors

IR1-01: walk layer groups recursively in preflight/verify_alpha
IR1-02: return structured export error dicts from MCP export_image
IR1-04: fail-closed when preserve_alpha and drawable unset
IR1-05: greps, type-4 PNG fixture, structured-error source tests

* fix(export): codex P1/P2 — no silent format fallback, fail-closed RGBA8, batch metadata

* fix(export): format README; drop accidental conductor review from tree

Keep conductor/ gitignored local-only. Ruff-format README code fences for CI.

* docs(0005): mark AlphaExportCorrectness complete in planner handoff

Issue 16 closed: merge-on-dup export, IHDR ALPHA_LOST, verify_alpha_channel.
Next product track: 0006 StateManifestOrientation (placeholder plan).

---------

Co-authored-by: Ryan <rbourgoin@gmail.com>
Schema-versioned orient_workspace state-manifest v1; host finalize; recursive layers; provisional handles; image_index metadata hygiene. Codex engineering PASS WITH DEFERRED P3 (live matrix).
Ledger: f13ebc80-dc77-4722-831e-68b1858c6a0f
…select_* (#6)

Stable handle registry: gimp_mcp_handles, process-unique session_epoch, generation tombstones, structural bumps, select_image/select_layers. Codex PASS WITH DEFERRED P3.
Next product track is 0008-CoordinateModelAndExif (placeholder).
PR #6 / main@33df2b5 delivered generation registry, STALE_HANDLE, select_*.

Ledger: 211b63de-c672-4bfe-9143-007559ba8877

Co-authored-by: Ryan <rbourgoin@gmail.com>
…#8)

* feat(0008): CoordinateModelAndExif — coords, mapping, normalize, map_*

Ship gimp_mcp_coords as 7th plug-in file (preview/layer math, ordered
ORIENTATION_OPS, declaration validate, half-even rounding). Enrich mapping
metadata on three paths (build_mapping_metadata + plugin bitmap flatten +
server ToolResult pass-through). Add normalize_image_orientation (default
assume_pixels_upright; trust_tag opt-in; direct rotate/flip; both EXIF tags;
METADATA_WRITE_FAILED; self gen-bump). Session _orientation_normalized synced
with gen prune. Host map_* x4. Capability coordinate_exif_normalized true.

Ledger: a184eb50-f0d4-42c6-b069-1061eef57ad3

* fix(0008): undo pixel ops when normalize set_metadata fails

Call image.undo() after the undo group ends if metadata write fails and
trust_tag pixel ops ran, so the canvas is not left rotated with a stale tag.

Ledger: a184eb50-f0d4-42c6-b069-1061eef57ad3

* fix(0008): undo on mid-op normalize exceptions (ops_started)

Ensure trust_tag pixel ops that raise after partial transform call
image.undo() after undo_group_end, not only the metadata-false path.

Ledger: a184eb50-f0d4-42c6-b069-1061eef57ad3

* fix(0008): fail-closed gboolean ops, invalid EXIF honesty, plan tests

- Check image.flip/rotate and undo_group_* for explicit False
- Keep present-but-invalid orientation for honesty; clamp for manifest
- plan_normalize_ops offline behavioral tests; README install count

Ledger: a184eb50-f0d4-42c6-b069-1061eef57ad3

* fix(0008): fail-closed undo_group_end (no success on False)

Do not swallow undo_group_end gboolean False; re-raise body errors after
end so generation is never bumped on group-close failure.

Ledger: a184eb50-f0d4-42c6-b069-1061eef57ad3

---------

Co-authored-by: Ryan <rbourgoin@gmail.com>
PR #8 / main@8970ad2; Codex PASS WITH DEFERRED P3; next=0009.

Co-authored-by: Ryan <rbourgoin@gmail.com>
…kpoints, confirm_destructive (#10)

* feat(0009): gimp_mcp_policy + codes + tests + install

Ship 8th plug-in file for labels/paths/sidecar/integrity hash;
POLICY_DENIED/CONFIRM_REQUIRED/CHECKPOINT_* codes; offline tests;
pyproject + README install lists.

Ledger: 3a04bc4b-8616-4512-9529-40c0f0c9f4d4

* feat(0009): Source_Immutable, confirm_destructive, checkpoints

- ensure_source_immutable with parasite group + central mutable resolve
- confirm_destructive on live flatten/merge/rotate free-angle/resize fill
- checkpoint_create/restore with jailed paths + integrity sidecar
- orient tattoo/protected; capabilities source_immutable_policy + checkpoints
- MCP tools + protocol/README agent intake order

Ledger: 3a04bc4b-8616-4512-9529-40c0f0c9f4d4

* fix(0009): tighten confirm-scope wiring tests and orient-snapshot honesty

Pin free-angle / will_flatten branch structure for confirm_destructive.
Document include_orient_snapshot=true as note-only (no embedded dump).

Ledger: 3a04bc4b-8616-4512-9529-40c0f0c9f4d4

* fix(0009): address Codex P1/P2 — bool coerce, idempotent ensure, XCF partial

- Use export.coerce_bool for confirm_destructive / allow_source_mutation / overwrite
- Skip working copies on re-ensure (session set + name suffix); no gen bump on no-op
- Save checkpoint XCF via .partial then os.replace; check PDB status + non-empty
- Document allow_source_mutation as raw-TCP recovery only (not MCP mutators)

Ledger: 3a04bc4b-8616-4512-9529-40c0f0c9f4d4

* fix(0009): strict coerce_bool + safer working-name skip + restore bools

- coerce_bool fail-closed for non-scalar JSON (list/dict → default)
- Name-based working skip only when policy group already has children
- checkpoint_restore close_prior/verify_hash use coerce_bool

Ledger: 3a04bc4b-8616-4512-9529-40c0f0c9f4d4

* fix(0009): durable Source_Immutable deny via group ancestry + hydrate

_assert_mutable also denies descendants of parasite-marked group.
Hydrate protected set on ensure, open_image, orient, checkpoint_restore.
Strict coerce_bool non-scalar fail-closed already in export.

Ledger: 3a04bc4b-8616-4512-9529-40c0f0c9f4d4

---------

Co-authored-by: Ryan <rbourgoin@gmail.com>
#11)

Record PR #10 / main@25e93ba completion notes; next track 0010.

Co-authored-by: Ryan <rbourgoin@gmail.com>
…stMCP (#12)

* 0010: high-level MCP surface (~18 tools) on real FastMCP

Migrate from mcp.server.fastmcp shim to real fastmcp.FastMCP with include_tags + ToolAnnotations. Default surface is 18 HL tools; GIMP_MCP_ADVANCED_TOOLS=1 exposes full advanced surface.

Ledger: 5272272a-d519-4e72-9635-d27e3267c1fb

* fix(0010): handle-first save/export/verify/close + by_color layer_id

Wire plugin mutators through _resolve_image_from_params so HL handle
params cannot silently target image 0. Fail closed on explicit layer_id
for select_by_color. Strengthen offline handle tests; PROTOCOL design names.

Ledger: 5272272a-d519-4e72-9635-d27e3267c1fb

* fix(0010): fail-closed prior handle on restore; honest composite index

checkpoint_restore close_prior with invalid handle returns STALE/FOREIGN
instead of silent skip. Derive open-list image_index after handle resolve
for composite mapping. Align create_selection layer_handle docs; tests.

Ledger: 5272272a-d519-4e72-9635-d27e3267c1fb

---------

Co-authored-by: Ryan <rbourgoin@gmail.com>
Ledger: 5272272a-d519-4e72-9635-d27e3267c1fb

Co-authored-by: Ryan <rbourgoin@gmail.com>
…st_id audit (#14)

* feat(0011): structured error envelope v1 + request_id audit correlation

Implement product error envelope, single-line ToolError wire, CODE matrix (PARTIAL_MUTATION, CONNECTION_FAILED), host/plugin split audit files, and request_id correlation (contextvars host, threading.local plugin).

- export_image raises ToolError on ALPHA_LOST (H1; details preserved)

- _jail_path_or_raise re-raises SecurityError (H5)

- send_command params copy + _request_id; CONNECTION_FAILED on transport

- @with_structured_error on all MCP tools; structured_errors capability

- docs: PROTOCOL recovery table, SECURITY audit/traceback policy, README

Ledger: 6dc55b22-8287-44cf-a6d3-1fbbfb37327a

* fix(0011): call_api ToolError path + affected_handles on INTERNAL (M5)

Ledger: 6dc55b22-8287-44cf-a6d3-1fbbfb37327a

* fix(0011): parse_tool_error_text handles message containing ' | '

Codex P1: rfind alone selected the pipe inside JSON error.message when the
human message also contained the delimiter. Try every ' | ' candidate from
the right until a valid envelope parses. Regression test added.

Ledger: 6dc55b22-8287-44cf-a6d3-1fbbfb37327a

---------

Co-authored-by: Ryan <rbourgoin@gmail.com>
…#15)

Ledger: 6dc55b22-8287-44cf-a6d3-1fbbfb37327a

Co-authored-by: Ryan <rbourgoin@gmail.com>
Ship host package gimp_agent/ with entrypoint gimp-agent:
- argparse CLI: doctor [--strict], probe [--timeout], version, codes
- CODE_* / CLI-local → exit 0-12 map + reverse table
- path discovery (env/PATH/App Paths/install dirs + GIMP 3.* semver)
- doctor ordered checks; probe auth JSON get_gimp_info
- JSON envelope (--json / GIMP_AGENT_JSON); offline tests
- docs: README CLI section; protocol full exit table
Document non-strict doctor (exit 0 + ok:false) and probe TIMEOUT→9.
Add offline tests for non-strict doctor and TimeoutError path.
Remove dead stderr branch in jsonio.emit (human mode stays stdout).
@Ryan-AI-Studios
Copy link
Copy Markdown
Author

Opened against upstream by mistake; product PR belongs on Ryan-AI-Studios/gimp-mcp.

@coderabbitai
coderabbitai Bot commented Aug 3, 2026 •
Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7a8e016a-d028-40b9-97e3-8816c1131dd5

📥 Commits

Reviewing files that changed from the base of the PR and between 09bfb2d and 28bd903.

⛔ Files ignored due to path filters (3)
  • scripts/continuous_edit_test/files/bg_night_2048.png is excluded by !**/*.png
  • scripts/continuous_edit_test/files/winry_joy.png is excluded by !**/*.png
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (49)
  • .github/workflows/ci.yml
  • .github/workflows/lint.yml
  • .gitignore
  • .pre-commit-config.yaml
  • CLAUDE.md
  • GIMP_MCP_PROTOCOL.md
  • README.md
  • SECURITY.md
  • agent_edit_demo.py
  • bg_remove.py
  • bg_remove_iterative.py
  • docs/best_practices.md
  • docs/iterative_workflow.md
  • docs/planner-handoff.md
  • gimp-mcp-plugin.py
  • gimp_agent/__init__.py
  • gimp_agent/__main__.py
  • gimp_agent/cli.py
  • gimp_agent/doctor.py
  • gimp_agent/exit_codes.py
  • gimp_agent/jsonio.py
  • gimp_agent/paths.py
  • gimp_agent/probe.py
  • gimp_mcp_coords.py
  • gimp_mcp_export.py
  • gimp_mcp_handles.py
  • gimp_mcp_policy.py
  • gimp_mcp_security.py
  • gimp_mcp_server.py
  • gimp_mcp_snapshot.py
  • gimp_mcp_state.py
  • gimp_mcp_surface.py
  • pyproject.toml
  • run_tests.py
  • schemas/state-manifest.v1.json
  • scripts/add_text_metadata.py
  • scripts/continuous_edit_test/continuous_edit_test.py
  • tests/test_coords.py
  • tests/test_export_alpha.py
  • tests/test_gimp_agent_cli.py
  • tests/test_handles.py
  • tests/test_high_level_surface.py
  • tests/test_layer_policy.py
  • tests/test_quality_smoke.py
  • tests/test_security_policy.py
  • tests/test_snapshot_composite.py
  • tests/test_snapshot_mapping.py
  • tests/test_state_manifest.py
  • tests/test_structured_errors.py

Walkthrough

The change adds secure authenticated MCP transport, workspace and export safeguards, stable handles, state manifests, visible-composite snapshots, a diagnostic CLI, updated tooling, documentation, and offline tests.

Changes

GIMP MCP platform

Layer / File(s) Summary
Repository tooling and contracts
.github/workflows/ci.yml, .gitignore, .pre-commit-config.yaml, pyproject.toml, schemas/*, README.md, GIMP_MCP_PROTOCOL.md, SECURITY.md, docs/*
Adds CI, packaging, lint/type/test configuration, protocol contracts, security documentation, planner handoff, and workflow guidance.
Security and runtime hardening
gimp_mcp_security.py, gimp-mcp-plugin.py, gimp_mcp_server.py
Adds token authentication, loopback binding, path jailing, audit logs, structured errors, gated execution, request IDs, stable handles, generations, protected layers, checkpoints, and hardened exports.
Image data and tool contracts
gimp_mcp_state.py, gimp_mcp_handles.py, gimp_mcp_coords.py, gimp_mcp_snapshot.py, gimp_mcp_export.py, gimp_mcp_policy.py, gimp_mcp_surface.py
Adds manifest validation, coordinate conversion, orientation handling, visible-composite snapshots, alpha-aware export policies, checkpoint sidecars, and high-level tool selection.
Diagnostic CLI
gimp_agent/*
Adds gimp-agent commands for diagnostics, authenticated probing, version discovery, exit-code lookup, and JSON or human-readable output.
Client workflow updates
agent_edit_demo.py, bg_remove.py, bg_remove_iterative.py, run_tests.py, scripts/*
Updates scripts to use configurable endpoints, session tokens, authenticated requests, timeout handling, and disabled-execution reporting.
Offline validation
tests/*
Adds coverage for security, structured errors, handles, manifests, coordinates, snapshots, exports, CLI behavior, layer policy, high-level tools, and repository smoke checks.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested labels: documentation

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0