---
name: sketchup-bounded-op
description: Turn one approved modelling instruction into a SketchUp Ruby script that creates candidate geometry inside a new, named group, never touching existing geometry, and verifies the result. Use when the designer has approved a specific element to model (a box, a cabinet carcass, a wall opening study) and wants it as editable candidate geometry in SketchUp.
version: 0.1.0
---

# SketchUp bounded operation

No plugin, no network, no server. You write a Ruby script from an **approved instruction**; the
designer pastes it into SketchUp's Ruby Console (Window → Ruby Console) or runs it with
`load "path/to/script.rb"`. The script works only inside a new group it creates.

## Inputs
- The approved instruction, in writing, with every dimension in millimetres and a name for the
  candidate. Example: "Candidate K-03: carcass 600 × 580 × 720 mm, 18 mm panels, open front,
  origin at the model origin." If a dimension is missing, stop and ask. Do not assume.
- The register ID or approved-memory line that authorises it (see `brief-register`, `context-pack`).

## Outputs (write only inside `candidates/`)
- `candidates/<name>.rb` — the script, built from `candidate_box.rb` as the pattern
- `candidates/<name>.md` — the instruction, the dimensions used, the verification result the
  designer pastes back, and the ledger reference
- Ledger entry (`../_shared/run-ledger.md`). Gate: "Designer approves the result before it is kept".

## The script must
1. Start with `model.start_operation("Candidate <name>", true)` so one Undo removes everything.
2. Create **one new group** named `candidate-<name>-<date>` at the model root and build only
   inside `group.entities`. Never call methods on `model.active_entities` or any existing group.
3. Use millimetres explicitly (`x.mm`), never raw numbers.
4. Verify programmatically at the end and print the result:
   - bounding box width, depth, height in mm, compared with the instruction;
   - face and edge counts;
   - for any cut or subtraction: check with geometry (`faces.loops.count > 1` for an opening in a
     face), never trust that `subtract` returned non-nil.
5. End with `model.commit_operation` and a single printed line:
   `CANDIDATE <name>: OK` or `CANDIDATE <name>: MISMATCH <what>`.
6. Contain no `Net::HTTP`, no file writes, no `require` of anything outside SketchUp's API, no
   `Sketchup.send_action`, no model save. Blocking network calls inside SketchUp freeze it.

## Procedure
1. Restate the instruction as a dimension table. Ask for anything missing.
2. Write the script from `candidate_box.rb`. Keep the dimension table at the top as constants.
3. Write `candidates/<name>.md` with the table and an empty "Verification output" section.
4. Tell the designer how to run it and ask them to paste the printed verification line back.
5. Record the pasted line in the `.md` and the ledger. The designer decides whether to keep,
   rename or delete the group. You never delete anything in the model.

## Permissions and gate
- Read: the instruction and its source. Write: `candidates/` and `runs/ledger.md`.
- The script writes to the SketchUp model only inside its own new group, under one undo step.
- Gate: approval of the instruction before the script exists; approval of the result before it is
  kept.

## Anti-patterns
- Editing geometry outside the candidate group 'just to make it fit'.
- Taking a dimension from a screenshot, a photo or a hand sketch.
- Reporting OK without the printed verification line.

## Never
- Never modify, move or delete existing geometry, layers, materials or components.
- Never infer a dimension from a photo, a sketch or a "typical" size.
- Never claim the geometry is correct from the script alone; the verification line is the evidence.
