Skip to content

SCOUT->FORGE: 7 verified H21 tools + bridge/panel hardening#4

Merged
JosephOIbrahim merged 5 commits into
masterfrom
forge/scout-opportunities
May 29, 2026
Merged

SCOUT->FORGE: 7 verified H21 tools + bridge/panel hardening#4
JosephOIbrahim merged 5 commits into
masterfrom
forge/scout-opportunities

Conversation

@JosephOIbrahim
Copy link
Copy Markdown
Owner

@JosephOIbrahim JosephOIbrahim commented May 29, 2026

Summary

Implements all 7 opportunities surfaced by a read-only SCOUT recon of the Houdini 21.0.671 capability surface vs the SYNAPSE tool registry, plus adjacent bridge/panel robustness fixes found along the way. Every capability was V1-verified against the exact target build (21.0.671 hython) before any code was written; all changes are unit-tested standalone.

What's here

Tools / capabilities (5287006) — registry 104 → 108:

  • houdini_set_payload_loadstate — USD payload load/unload + activation
  • houdini_create_point_instancerUsdGeom.PointInstancer authoring
  • houdini_shot_render_ready — shot-template composite orchestrator
  • cops_create_copnet — modern Copernicus copnet (distinct from the legacy cop2net the 20 existing COPs tools build on)
  • houdini_reference_usd + karma_visible/purpose/kind — non-clobbering Karma-visibility metadata on import (completes the BL-008 advisory-only partial)
  • houdini_modify_usd_prim + instanceable
  • handlers_render upstream Karma-LOP walk is now branch-aware + path-keyed (C3)

Bridge / panel hardening:

  • (ea32f79) read-only tool failures now surface as JSON-RPC errors instead of success-with-isError; SynapseResponse id fix on the bridge-failure path
  • (76d8fca) SafeRender dispatch tests exercise the standalone consent tier (a real HumanGate is wired in CI) — no production-gating change
  • (bb5819a) panel Anthropic-key resolution routed through host/auth.py (hou.secure → env var) with an actionable "set it + relaunch Houdini" error message

Verification

  • New FORGE suites: 50 passing. test_cops.py: 53. test_mcp_protocol.py: 93/93 (was 91/2, and 240s → 0.4s). Full suite collects 2924 tests, 0 import errors.
  • Production consent gating provably untouchedshared/bridge.py has zero diff.

Deferred (live bridge was offline during the build)

Behavioral checks to run on a live 21.0.671 session: Karma cook of copnet, EXR landing for the render path, and USD editableStage round-trips for the metadata / load-state / instancer tools.

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Copernicus copnet network creation tool
    • Added USD payload load state, point instancer, and shot render-ready orchestration tools
    • Enhanced USD reference metadata support with visibility, purpose, and kind controls
    • Added instanceable metadata modification for USD primitives
  • Bug Fixes

    • Improved API key detection with fallback handling and clearer error messages
    • Optimized upstream render node discovery for better performance
    • Fixed error response handling in tool dispatch
  • Tests

    • Added comprehensive test coverage for new handler functionality

Review Change Stack

Joseph Ibrahim and others added 4 commits May 29, 2026 14:19
4 new MCP tools + 2 schema extensions + 1 render-walk fix, each V1-verified
on Houdini 21.0.671 and unit-tested standalone (50 new tests; behavioral
checks deferred until the live bridge is up):

- houdini_set_payload_loadstate (C2): USD payload load/unload + activation
- houdini_create_point_instancer (C5b): UsdGeom.PointInstancer authoring
- houdini_shot_render_ready (C6): shot-template composite orchestrator
- cops_create_copnet (C4): modern Copernicus copnet, distinct from legacy cop2net
- houdini_reference_usd +karma_visible/purpose/kind (C1): non-clobbering Karma
  visibility metadata on import (completes the BL-008 advisory-only partial)
- houdini_modify_usd_prim +instanceable (C5a)
- handlers_render upstream Karma-LOP walk now branch-aware + path-keyed (C3)

Registry 104 -> 108 tools. Verified: 50 FORGE + 53 cops tests green,
2924 tests collect cleanly. Produced by a SCOUT recon + FORGE MOE build run
(.scout / .forge run logs, gitignored).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…1/3 mcp_protocol tests)

Bundled bridge-layer fixes from forge-bridge-fix. CRUCIBLE cleared: no
showstopper, production consent gating preserved.

- server.py (dispatch fix): the read-only fast-path of
  MCPServer._handle_tools_call returned dispatch_tool's result directly,
  so a handler failure leaked through as a JSON-RPC success result with
  {isError:True} buried inside instead of a top-level JSON-RPC error. The
  isError->JsonRpcError conversion existed only in the non-read-only
  branch. Added the same conversion to the read-only branch and extracted
  the shared message-extraction into a module-level _isError_text() helper
  (byte-identical logic; no behavior change on the non-read-only path).
  Greens tests/test_mcp_protocol.py::TestToolsCall::
  test_tool_error_propagated_as_jsonrpc_error (synapse_ping is read_only).

- bridge_adapter.py (id fix): execute_through_bridge() omitted
  id=command.id on the failure-path SynapseResponse, so bridge-rejected
  commands returned a response with no correlation id. Added id=command.id
  to the failure branch to match the success path.

- consent finding (NO CHANGE — test-is-wrong, production gating untouched):
  TestSafeRenderMCPTools::test_safe_render_dispatch and
  ::test_render_progressively_dispatch remain red. In this repo's test env
  synapse.core.gates IS importable, so bridge.py sets _GATES_AVAILABLE=True
  and _check_consent takes Path 1 (production HumanGate). APPROVE-gated
  submit_render correctly times out to safe-default rejection because no
  artist decides -> "Bridge: Operation requires approve consent". The
  standalone auto-approve tier (Path 3) fires only when _gate is None AND
  _consent_callback is None, which is unreachable here. Any edit that
  flips these two tests green would alter Path 1 production APPROVE/CRITICAL
  gating, forbidden by the hard constraint. Bridge consent logic is correct
  as written; zero edits made to shared/bridge.py. The fix belongs in the
  test/dispatch layer (inject a consent_callback, null the bridge_adapter
  singleton, or supply a HumanGate auto-decision in the fixture) and is
  noted separately for the test owner.

Honest outcome: 1 of 3 target tests green. The 2 consent tests are
expected-red (test expectation contradicts the gating architecture), not
regressions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
test_safe_render_dispatch / test_render_progressively_dispatch verify dispatch
of non-read-only tools, which route through the LosslessExecutionBridge. In CI
synapse.core.gates is importable, so the bridge auto-wires a real HumanGate and
_check_consent takes the gate path (Path 1) before the injected callback
(Path 2) -- an unattended APPROVE-gated op then times out to safe-default
rejection (~240s).

Add an _auto_approve_bridge fixture that swaps in a process-local bridge with
the gate nulled + an auto-approving consent_callback, so the tests exercise
dispatch (their intent) rather than the production gate. Production consent
gating is untouched -- shared/bridge.py is unchanged.

test_mcp_protocol.py: 91->93 passing, 240s->0.4s.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rror

The panel's ClaudeWorker (and the panel's text-only fallback worker) read the
key straight from os.environ and failed with a cryptic "ANTHROPIC_API_KEY not
set in environment" when empty -- missing keys stored via hou.secure and
offering the user no guidance.

Resolve through host.auth.get_anthropic_api_key() (hou.secure -> env var,
whitespace-stripped, never raises) and emit an actionable message: set
ANTHROPIC_API_KEY at the SYSTEM level and relaunch Houdini (a terminal-scoped
`set` does not propagate to Houdini on Windows), or use
hou.secure.setPassword('synapse_anthropic', ...).

Root cause of the reported failure was an unset persistent key (Houdini
inherits only User/Machine env vars); this commit makes the failure
self-service rather than cryptic and honors keys stored in hou.secure.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

Warning

Review limit reached

@JosephOIbrahim, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 43 minutes and 22 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 752cc7fb-651d-43b0-ac5a-5116ebfc33b1

📥 Commits

Reviewing files that changed from the base of the PR and between bb5819a and a0453f3.

📒 Files selected for processing (3)
  • README.md
  • python/synapse/__init__.py
  • set_anthropic_key.bat
📝 Walkthrough

Walkthrough

This PR extends Synapse's FORGE command suite with four new capabilities (USD payload state management, PointInstancer creation, multi-step shot render orchestration, and modern Copernicus copnet creation), improves upstream Karma-LOP discovery via breadth-first traversal, consolidates API key retrieval across workers, enhances MCP error handling, and validates all changes through comprehensive test coverage.

Changes

FORGE Handler Suite and Infrastructure

Layer / File(s) Summary
Protocol and MCP Tool Contracts
python/synapse/core/protocol.py, mcp_tools_cops.py, mcp_tools_usd.py, python/synapse/mcp/_tool_registry.py
Adds four new CommandType enum values and registers corresponding MCP tool definitions with input schemas. Existing tools (modify_usd_prim, reference_usd) gain new optional fields (instanceable, karma_visible, purpose, kind).
Handler Registration and Routing
python/synapse/server/handlers.py
Wires the four new command handlers into _CMD_CATEGORY audit mapping and _register_handlers() dispatcher so they are recognized and routed alongside existing USD/COPs commands.
USD Handler Implementations
python/synapse/server/handlers_usd.py
Adds helper functions (_coerce_bool, _karma_visibility_pythonscript); extends _handle_modify_usd_prim with instanceable support; enhances _handle_reference_usd with optional Karma-visibility metadata authoring; introduces _handle_set_payload_loadstate, _handle_create_point_instancer, and _handle_shot_render_ready for payload management, instancing, and multi-step render orchestration.
COPs Handler and Copnet Creation
python/synapse/server/handlers_cops.py
Implements _handle_cops_create_copnet to create modern Copernicus copnet containers with optional starter COP node, returning network path, type, and starter node path.
Render Handler Improvements
python/synapse/server/handlers_render.py
Upgrades upstream Karma-LOP discovery from linear first-input walk to breadth-first traversal with cycle protection and 20-node max-visit budget, finding the first non-empty picture value at shallowest depth.
API Key Retrieval Consolidation
python/synapse/panel/claude_worker.py, houdini/python_panels/synapse_panel.pypanel
Standardizes Anthropic API key acquisition to prefer synapse.host.auth.get_anthropic_api_key() with environment fallback; both workers emit consistent, instructional error messages including Windows setx guidance.
MCP Server and Infrastructure
python/synapse/mcp/server.py, python/synapse/panel/bridge_adapter.py
Adds _isError_text() helper for extracting human-readable errors; propagates isError results as JSON-RPC errors in read-only tools/call path; fixes SynapseResponse to include command.id in bridge-failure paths.
Comprehensive Handler Testing
tests/test_forge_usd.py, tests/test_forge_copernicus.py, tests/test_forge_render.py
Introduces 983 lines of test coverage: pure-function tests for helpers (_coerce_bool, _karma_visibility_pythonscript); handler-level tests for all new/enhanced USD capabilities; copnet creation structural assertions; branch-aware render discovery including cyclic-graph termination guard.
Test Support Infrastructure and Validation Updates
tests/test_mcp_protocol.py, tests/test_cops.py
Adds _auto_approve_bridge fixture for consent-free dispatch testing; updates test_cops.py expectations from 20 to 21 COP handlers/tools to reflect the new cops_create_copnet addition.
Project Configuration
.gitignore
Excludes local SCOUT artifacts (.scout/) and FORGE build artifacts (.forge/) directories.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

A rabbit hops through FORGE so bright,
With payloads, points, and renders right,
New copnets born in Houdini's glow,
Breadth-first paths make pictures flow—
Four handlers strong, tests pass with glee! 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.40% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: introducing 7 Houdini 21 tools and bridge/panel improvements, directly aligning with the PR's primary objectives.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch forge/scout-opportunities

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
mcp_tools_cops.py (1)

8-25: 💤 Low value

Consider updating GROUP_KNOWLEDGE to distinguish cops_create_copnet from cops_create_network.

The GROUP_KNOWLEDGE currently mentions "cops_create_network creates a COP2 container" but doesn't mention the new cops_create_copnet tool. Since the tool registry describes cops_create_copnet as creating a "modern Copernicus 'copnet' network (H21 Copernicus, distinct from legacy cop2net)", agents consuming this knowledge would benefit from understanding when to use each tool.

📝 Suggested GROUP_KNOWLEDGE update
 GROUP_KNOWLEDGE = (
     "COPERNICUS (COPs) TOOLS: GPU-accelerated image processing in Houdini 21. "
-    "FOUNDATION: cops_create_network creates a COP2 container, cops_create_node "
+    "FOUNDATION: cops_create_network creates a legacy COP2 container, "
+    "cops_create_copnet creates a modern H21 copnet container, cops_create_node "
     "adds COP nodes, cops_connect wires them, cops_set_opencl sets GPU kernels, "
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@mcp_tools_cops.py` around lines 8 - 25, Update the GROUP_KNOWLEDGE string to
explicitly mention both cops_create_network and the new cops_create_copnet,
clarifying that cops_create_network creates a legacy COP2 container (cop2net)
while cops_create_copnet creates the modern Copernicus "copnet" network (H21
Copernicus) and note when to prefer each (legacy compatibility vs modern
rendering/features); keep existing mentions of other functions (e.g.,
cops_create_node, cops_connect, cops_set_opencl, cops_read_layer_info,
cops_to_materialx, cops_composite_aovs, cops_analyze_render, cops_slap_comp,
cops_create_solver, cops_procedural_texture, cops_growth_propagation,
cops_reaction_diffusion, cops_pixel_sort, cops_stylize, cops_wetmap,
cops_bake_textures, cops_temporal_analysis, cops_stamp_scatter, cops_batch_cook)
and preserve the note that all mutations wrap in hou.undos.group for safe
rollback so consumers know the transactional behavior.
houdini/python_panels/synapse_panel.pypanel (1)

208-212: 💤 Low value

Consider matching the error message from claude_worker.py.

The error message here is shorter and omits the hou.secure alternative mentioned in claude_worker.py (lines 105-106). Since both workers serve the same panel context, users would benefit from consistent, complete guidance including the hou.secure.setPassword('synapse_anthropic', 'sk-ant-...') option.

📝 Align error messages for consistency
                 self.stream_error.emit(
-                    'No Anthropic API key found. Set it at the SYSTEM level and '
-                    'relaunch Houdini:  setx ANTHROPIC_API_KEY "sk-ant-..."  '
-                    "(a terminal-scoped `set` won't carry into Houdini on Windows)."
+                    "No Anthropic API key found. Set it at the SYSTEM level so "
+                    "Houdini inherits it, then relaunch Houdini:  "
+                    'setx ANTHROPIC_API_KEY "sk-ant-..."  '
+                    "(a terminal-scoped `set` won't carry into Houdini on Windows). "
+                    "On builds exposing hou.secure you can instead run, in Houdini's "
+                    "Python shell: hou.secure.setPassword('synapse_anthropic', 'sk-ant-...')."
                 )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@houdini/python_panels/synapse_panel.pypanel` around lines 208 - 212, Update
the error string emitted by self.stream_error.emit in the SynapsePanel (the call
shown) to match the more complete guidance used in claude_worker.py: include the
hou.secure.setPassword('synapse_anthropic','sk-ant-...') option in addition to
the SYSTEM-level setx instruction and the note about Windows terminal-scoped set
not carrying into Houdini, so users get consistent, complete instructions across
workers.
tests/test_forge_usd.py (2)

265-278: ⚡ Quick win

Prefix unused unpacked variables with underscore.

The unpacked variables ref_lop and kv_lop are never used in this test method. Prefix them with _ to indicate they are intentionally unused.

♻️ Suggested fix
-        parent_node, ref_lop, kv_lop = self._setup_parent()
+        parent_node, _ref_lop, _kv_lop = self._setup_parent()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_forge_usd.py` around lines 265 - 278, In
test_payload_mode_default_karma_visible, the unpacked variables ref_lop and
kv_lop from the call to self._setup_parent() are unused; rename or prefix them
with an underscore (e.g., _ref_lop, _kv_lop) so the test signals intentional
unused variables and avoids lint warnings when running
test_payload_mode_default_karma_visible and other tests using _setup_parent.

249-264: ⚡ Quick win

Prefix unused unpacked variables with underscore.

The unpacked variables ref_lop and kv_lop are never used in this test method. Prefix them with _ to indicate they are intentionally unused.

♻️ Suggested fix
-        parent_node, ref_lop, kv_lop = self._setup_parent()
+        parent_node, _ref_lop, _kv_lop = self._setup_parent()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_forge_usd.py` around lines 249 - 264, In the test method
test_karma_visible_string_false_keeps_advisory, the unpacked variables ref_lop
and kv_lop returned from self._setup_parent() are unused; rename them to
_ref_lop and _kv_lop (i.e., change "parent_node, ref_lop, kv_lop =
self._setup_parent()" to "parent_node, _ref_lop, _kv_lop =
self._setup_parent()") to signal intentional unused variables and satisfy the
lint rule.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@python/synapse/mcp/_tool_registry.py`:
- Around line 545-557: The schema for the "houdini_create_point_instancer" /
"create_point_instancer" action marks "prototypes" and "positions" as optional
but the description implies they will be set; inspect the handler function
_handle_create_point_instancer to determine actual behavior (does it create an
empty instancer, apply protoIndices defaults, or fill positions) and then make
the schema and description consistent: either require "prototypes" and
"positions" in the schema if the handler needs them, or update the description
to state that these fields are optional and describe the
defaults/empty-instancer behavior that the handler implements (and if necessary,
modify _handle_create_point_instancer to apply sensible defaults such as empty
prototypes and zeroed protoIndices when fields are missing).

---

Nitpick comments:
In `@houdini/python_panels/synapse_panel.pypanel`:
- Around line 208-212: Update the error string emitted by self.stream_error.emit
in the SynapsePanel (the call shown) to match the more complete guidance used in
claude_worker.py: include the
hou.secure.setPassword('synapse_anthropic','sk-ant-...') option in addition to
the SYSTEM-level setx instruction and the note about Windows terminal-scoped set
not carrying into Houdini, so users get consistent, complete instructions across
workers.

In `@mcp_tools_cops.py`:
- Around line 8-25: Update the GROUP_KNOWLEDGE string to explicitly mention both
cops_create_network and the new cops_create_copnet, clarifying that
cops_create_network creates a legacy COP2 container (cop2net) while
cops_create_copnet creates the modern Copernicus "copnet" network (H21
Copernicus) and note when to prefer each (legacy compatibility vs modern
rendering/features); keep existing mentions of other functions (e.g.,
cops_create_node, cops_connect, cops_set_opencl, cops_read_layer_info,
cops_to_materialx, cops_composite_aovs, cops_analyze_render, cops_slap_comp,
cops_create_solver, cops_procedural_texture, cops_growth_propagation,
cops_reaction_diffusion, cops_pixel_sort, cops_stylize, cops_wetmap,
cops_bake_textures, cops_temporal_analysis, cops_stamp_scatter, cops_batch_cook)
and preserve the note that all mutations wrap in hou.undos.group for safe
rollback so consumers know the transactional behavior.

In `@tests/test_forge_usd.py`:
- Around line 265-278: In test_payload_mode_default_karma_visible, the unpacked
variables ref_lop and kv_lop from the call to self._setup_parent() are unused;
rename or prefix them with an underscore (e.g., _ref_lop, _kv_lop) so the test
signals intentional unused variables and avoids lint warnings when running
test_payload_mode_default_karma_visible and other tests using _setup_parent.
- Around line 249-264: In the test method
test_karma_visible_string_false_keeps_advisory, the unpacked variables ref_lop
and kv_lop returned from self._setup_parent() are unused; rename them to
_ref_lop and _kv_lop (i.e., change "parent_node, ref_lop, kv_lop =
self._setup_parent()" to "parent_node, _ref_lop, _kv_lop =
self._setup_parent()") to signal intentional unused variables and satisfy the
lint rule.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 260cd177-7514-48d9-8aa3-328b76af2edc

📥 Commits

Reviewing files that changed from the base of the PR and between 88af78d and bb5819a.

📒 Files selected for processing (18)
  • .gitignore
  • houdini/python_panels/synapse_panel.pypanel
  • mcp_tools_cops.py
  • mcp_tools_usd.py
  • python/synapse/core/protocol.py
  • python/synapse/mcp/_tool_registry.py
  • python/synapse/mcp/server.py
  • python/synapse/panel/bridge_adapter.py
  • python/synapse/panel/claude_worker.py
  • python/synapse/server/handlers.py
  • python/synapse/server/handlers_cops.py
  • python/synapse/server/handlers_render.py
  • python/synapse/server/handlers_usd.py
  • tests/test_cops.py
  • tests/test_forge_copernicus.py
  • tests/test_forge_render.py
  • tests/test_forge_usd.py
  • tests/test_mcp_protocol.py

Comment on lines +545 to +557
("houdini_create_point_instancer", "create_point_instancer", _identity,
"Author a UsdGeom.PointInstancer: scatter prototype prims across positions. "
"Minimal valid setup -- defines the instancer, sets the prototypes relationship, "
"protoIndices (defaults to zeros), and positions.",
{"type": "object", "properties": {
"node": {"type": "string", "description": "LOP node to wire after (optional)"},
"prim_path": {"type": "string", "description": "USD prim path for the PointInstancer"},
"prototypes": {"type": "array", "items": {"type": "string"},
"description": "Prototype prim paths to instance"},
"positions": {"type": "array", "items": {"type": "array", "items": {"type": "number"}},
"description": "Instance positions as [[x,y,z], ...]"},
}, "required": ["prim_path"]},
False, True, False),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Verify that optional prototypes and positions is intentional.

The description states "Minimal valid setup -- defines the instancer, sets the prototypes relationship, protoIndices (defaults to zeros), and positions", which implies these fields will be set. However, the schema makes both prototypes and positions optional (only prim_path is required).

Clarify what happens when these fields are not provided:

  • Does the handler create an empty point instancer?
  • Are there sensible defaults applied?
  • Should the description be updated to reflect that these are optional?

Run the following to verify the handler implementation:

#!/bin/bash
# Search for the create_point_instancer handler implementation
rg -n -A 20 'def _handle_create_point_instancer' --type=py
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/synapse/mcp/_tool_registry.py` around lines 545 - 557, The schema for
the "houdini_create_point_instancer" / "create_point_instancer" action marks
"prototypes" and "positions" as optional but the description implies they will
be set; inspect the handler function _handle_create_point_instancer to determine
actual behavior (does it create an empty instancer, apply protoIndices defaults,
or fill positions) and then make the schema and description consistent: either
require "prototypes" and "positions" in the schema if the handler needs them, or
update the description to state that these fields are optional and describe the
defaults/empty-instancer behavior that the handler implements (and if necessary,
modify _handle_create_point_instancer to apply sensible defaults such as empty
prototypes and zeroed protoIndices when fields are missing).

- README: registry tool count 104 -> 108; new "v5.9.0 - SCOUT -> FORGE"
  section with an on-point pipeline mermaid diagram and the 7 shipped
  capabilities; setup docs now point to the set_anthropic_key.bat helper.
- Bump __version__ 5.8.0 -> 5.9.0.
- Add set_anthropic_key.bat: prompts for the key, persists it with setx, and
  reminds you to relaunch Houdini -- removes the system-vs-shell-scope gotcha.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@JosephOIbrahim JosephOIbrahim merged commit c1926c1 into master May 29, 2026
1 of 3 checks passed
@JosephOIbrahim JosephOIbrahim deleted the forge/scout-opportunities branch May 29, 2026 19:38
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