docs(settings): track E shipped — CLAUDE.md sections 18-20, README, changelog with the live COM smoke record

CLAUDE.md gains items 18-20 (styles, page setup & templates, environment),
the grown drawing_settings facade on item 11, lean 55 / 52 and
TOOL_PACKS=all|core,pid,settings, and three conventions: layer states are
ours (ACADMCP_LAYERSTATES XRECORD, mode "xrecord"), page-setup evidence is
the PDF's own /MediaBox, nothing interprets coordinates in UCS.

README token table re-measured on this tree with benchmarks/token_suite.py
(ratio/v1 estimates): full 199 tools / 59,315 tokens, core,settings 190 /
55,593, core 168 / 48,825, lean 55 / 16,360, search 2 / 356; corpus
re-derived from discovery.aliases: 186 AutoCAD command names, 933 synonym
phrases, 204 tools. Styles & standards row, page setup & templates row,
final environment wording, and "Known limitations of the settings track".

CHANGELOG Unreleased: the track E intro, Added (styles, page setup &
templates, environment, drawing_settings growth, benchmark evidence),
Fixed (the Track A hardening list), Changed (three groups, packs, measured
idle cost, release snapshot 204 · 8 · 5 · 3284). Spec status: implemented.

Where the plan's text and the tree disagreed, the tree wins:
mleaderstyle_create is implemented on both engines through the
ACAD_MLEADERSTYLE dictionary and no `mleaderstyle` capability key exists
(spec §4, capability maps), so the docs say so instead of calling it
ezdxf-only; the Task 7 fix (tolerant ACADMCP_PID payloads, crossings
tested against the arc) joins the hardening list the plan left it out of.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
Umut CAN
2026-09-22 13:38:14 +03:00
co-authored by Claude Opus 5
parent 18c7c69da6
commit 39e6e2f9e4
4 changed files with 132 additions and 28 deletions
+100 -12
View File
@@ -13,8 +13,68 @@ implements, six critique focuses that join `drawing_finalize`, and a
`TOOL_PACKS` gate so a mechanical-only client never pays for the P&ID `TOOL_PACKS` gate so a mechanical-only client never pays for the P&ID
surface. Spec: `docs/superpowers/specs/2026-09-15-v1.6-pid-design.md`. surface. Spec: `docs/superpowers/specs/2026-09-15-v1.6-pid-design.md`.
Track E of 1.6: the environment a drawing lives in. 38 tools in three new
sections — styles (18), page setup and templates (19), environment (20) —
the `drawing_settings` facade grown, a system-variable catalog, five bundled
templates, several open documents headlessly, portable layer states, named
views and UCS, and the live-only group (launch, preferences, document
properties, operator prompts) refused honestly headlessly. Spec:
`docs/superpowers/specs/2026-09-16-v1.6-settings-design.md`.
### Added ### Added
- **Styles — 10 tools, pack `core`.** `dimstyle_list/create/modify/set_current`,
`textstyle_list/create/set_current`, `mleaderstyle_list/create`,
`drawing_apply_standard`. ISO-25 and ANSI (metric) presets are authored data
pinned by `tests/test_standards_presets.py` against ISO 129-1 / ASME Y14.2
(DIMTXT 2.5 / 3.0, DIMASZ 2.5 / 3.0, DIMEXO 0.625 / 1.5, DIMDSEP `,` / `.`,
DIMTAD 1 / 0 …). `dimstyle_modify` accepts the 33-name whitelist only (the
17 preset variables plus 16 more — `DIM_VARIABLE_WHITELIST`) and
refuses an out-of-range value by name before writing; `changed` lists what
moved. A font neither bundled nor on the engine's font path is written and
reported `font_resolved: false`, never refused. `mleaderstyle_create` works
on both engines: ActiveX exposes no MLeaderStyle *collection*, but the
`ACAD_MLEADERSTYLE` dictionary holds full `IAcadMLeaderStyle` objects, so
the live engine creates the style through `AddObject` and the property
writes — no `mleaderstyle` capability key exists.
- **Page setup & templates — 6 tools, pack `core`.** `page_setup_list/apply`
(`PAPER_SIZES` ISO A0–A4 / ANSI A–E, `CTB_CATALOG`, `SCALES`), `plot_style_list`
(catalog + installed), `batch_plot` — `mediabox_mm` parsed from each PDF's
`/MediaBox`, so `ISO_A3` landscape is 420 × 297 because the file says so —
`drawing_template_list`, `drawing_template_save` (`.dwt` refused headlessly,
capability `dwt_write`). Five bundled templates built by
`scripts/build_templates.py` through the server's own methods (`--check`
proves the DXFs byte-reproducible); their `.dwt` twins were built once on
AutoCAD 2026 by the smoke. `drawing_new(template="iso_a3_mech")` resolves the
bundled file and reports `{name, source}`.
- **Environment — 22 tools, pack `settings`.** `document_list/activate/close`
on both engines (the headless backend keeps a document registry;
`drawing_close` is the active-document case); `layer_state_save/restore/
list/delete` as portable XRECORD snapshots — restore applies only the
requested `properties`, reports `missing_layers` (skipped, never created)
and `new_layers` (untouched), and the state survives save/reopen;
`view_named_save/restore/list`; `ucs_list/set/restore` (non-orthogonal axes
refused with the measured angle; tool coordinates stay WCS);
`system_variable_describe` over a 90-entry catalog (`known: false` + nearest
names on a miss); `drawing_properties_get/set` (custom properties on both
engines, summary fields COM-only: `dwgprops`); `system_launch`
(`live_application`), `system_preferences_get/set` (whitelisted keys with
ranges, read-only keys refused by name, `old`/`new` reported:
`preferences`), `user_pick_point/select` and `system_prompt_message`
(`interactive_prompt`; a cancelled pick is `{cancelled: true}`, a
`COM_CALL_TIMEOUT` overrun is `timed_out`).
- **`drawing_settings` grows** by `limits`, `grid`/`grid_spacing`,
`snap`/`snap_spacing`, `ortho`, `polar`/`polar_angle`, `psltscale`,
`annotation_scale`, `linear_units`, `angular_units`, `dimstyle`,
`textstyle`; `system_set_variable` refuses an out-of-range value for a
catalogued name before writing.
- **Benchmark evidence.** `benchmarks/tasks_v4.py` adds `page_setup_truth`;
the correctness suite grows to 32 with `settings_dimstyle_iso25_values`,
`settings_layer_state_roundtrip`, `settings_pdf_mediabox_a3`. A/B against
`v1.5.1`: **26 / 32 → 32 / 32, six `miss → pass`, zero regressed**.
`scripts/smoke_settings_com.py` runs the track once against the live seat
(record below).
- **P&ID — 9 tools, pack `pid`.** - **P&ID — 9 tools, pack `pid`.**
- `pid_symbol_list` / `pid_symbol_insert`: a 43-symbol ISO 10628-2 / - `pid_symbol_list` / `pid_symbol_insert`: a 43-symbol ISO 10628-2 /
ISA-5.1 catalogue authored in code (11 valve bodies × 6 actuators, 6 ISA-5.1 catalogue authored in code (11 valve bodies × 6 actuators, 6
@@ -93,6 +153,26 @@ surface. Spec: `docs/superpowers/specs/2026-09-15-v1.6-pid-design.md`.
### Fixed ### Fixed
- **Track A hardening** (`tests/test_track_a_hardening.py`; the remaining
review findings are filed with a disposition each in
`docs/analysis/track-a-review-backlog.md`):
- `entity_create_block_ref` of an undefined block name is refused before
writing (it returned a handle to a dangling INSERT).
- `block_explode` keeps ATTRIB text: each ATTRIB becomes a TEXT entity on
both engines instead of being dropped.
- `pid_from_spec` refuses a NaN coordinate before the transaction opens and
rolls back on `BaseException`, not only `Exception`.
- A signal line no longer receives a fabricated line number and label; the
reader reports `line_number: null` for it.
- A bubble's exit point honours the first waypoint instead of the port
direction.
- A foreign or hand-edited `ACADMCP_PID` payload is read tolerantly, and an
existing polyline with a bulge is tested as its arc, not its chord, so a
line through a crossing jump counts as a crossing.
- `block_insert` attribute values are validated as strings; an int or None
is a `TypeError` naming the tag, not `str()`-coerced.
- `block_define` refuses a NaN base point and a layer that does not exist
in the drawing (it wrote both and `drawing_audit` repaired them later).
- **Headless `block_insert(attributes=…)` lost its ATTRIBs.** The ezdxf path - **Headless `block_insert(attributes=…)` lost its ATTRIBs.** The ezdxf path
used `add_auto_blockref`, which wraps the INSERT in an anonymous `*U` used `add_auto_blockref`, which wraps the INSERT in an anonymous `*U`
block: the handle it returned reported `block_name` `*U1`, and block: the handle it returned reported `block_name` `*U1`, and
@@ -119,13 +199,21 @@ surface. Spec: `docs/superpowers/specs/2026-09-15-v1.6-pid-design.md`.
### Changed ### Changed
- **`TOOL_PACKS=all|core,pid`** (default `all`) advertises only the vertical - Three tool groups appear in `system_about` and `docs/tool-inventory.json`:
packs a client uses; `core` is always on and unknown names are ignored `styles` (10), `page_setup` (6), `environment` (22) — 204 tools in 23 groups;
with a warning. It composes with `TOOL_PROFILE=lean` (which now carries `LEAN_TOOL_NAMES` 55; capability keys `dwgprops`, `dwt_write`,
`pid_symbol_insert`, `pid_line_draw` and `pid_graph`: 50 tools, 47 with `live_application`, `preferences`, `interactive_prompt`, `registry_sysvar`
`TOOL_PACKS=core`) and `ENABLE_3D`; `system_about` reports `tool_packs`. and the `documents`, `named_views`, `ucs` and `layer_states`
Measured idle cost: 161 tools / 44,930 tokens by default, 152 / 41,420 (`mode: "xrecord"`) features in both maps.
with `TOOL_PACKS=core`. - **`TOOL_PACKS=all|core,pid,settings`** (default `all`) advertises only the
vertical packs a client uses; `core` is always on and unknown names are
ignored with a warning. It composes with `TOOL_PROFILE=lean` (which now
carries `pid_symbol_insert`, `pid_line_draw` and `pid_graph`, and the five
settings essentials: 55 tools, 52 with `TOOL_PACKS=core`) and `ENABLE_3D`;
`system_about` reports `tool_packs`. Measured idle cost: 199 tools /
59,315 tokens by default, 190 / 55,593 with `TOOL_PACKS=core,settings`,
168 / 48,825 with `TOOL_PACKS=core`, 55 / 16,360 lean, 2 / 356 in
discovery mode.
- `PID_LAYERS` (`drawing_apply_iso_layers("pid")`) gains `PROCESS-LINE-TEXT`; - `PID_LAYERS` (`drawing_apply_iso_layers("pid")`) gains `PROCESS-LINE-TEXT`;
`drawing_plan` / `drawing_preflight` report `LAYER_SET_INTENT_MISMATCH` `drawing_plan` / `drawing_preflight` report `LAYER_SET_INTENT_MISMATCH`
when a P&ID intent is planned onto a non-`pid` layer set. when a P&ID intent is planned onto a non-`pid` layer set.
@@ -134,11 +222,11 @@ surface. Spec: `docs/superpowers/specs/2026-09-15-v1.6-pid-design.md`.
primitives. primitives.
- `CritiqueFocus` grows by the six `pid_*` values; benchmark matrix v4 - `CritiqueFocus` grows by the six `pid_*` values; benchmark matrix v4
(`--matrix v3` / `v2` reproduce the earlier sets); correctness suite 29. (`--matrix v3` / `v2` reproduce the earlier sets); correctness suite 29.
- README release snapshot: 166 tools · 8 resources · 5 prompts · 2423 - README release snapshot: 204 tools · 8 resources · 5 prompts · 3284
collected tests. The collected-test figure is this machine's; CI has not collected tests (this machine; it was 166 · 2423 after track A). CI has
run on this tree yet, and the pre-existing 1369-vs-1363 drift between the not run on this tree yet, and the pre-existing 1369-vs-1363 drift between
README and Linux collection predates the track and is superseded by the the README and Linux collection predates both tracks and is superseded by
new figure. the new figure.
### Live COM smoke ### Live COM smoke
+10 -4
View File
@@ -82,17 +82,20 @@ Tools are organized into sections (counts are indicative — `system_about` is a
8. Analysis & Query (8 tools): `analysis_*` — plus Batch (2), Templates (2), Validation (1) 8. Analysis & Query (8 tools): `analysis_*` — plus Batch (2), Templates (2), Validation (1)
9. View & Screenshot (4 tools — includes `view_zoom_and_screenshot`): `view_*` 9. View & Screenshot (4 tools — includes `view_zoom_and_screenshot`): `view_*`
10. Transactions (3 tools): `transaction_begin/commit/rollback` 10. Transactions (3 tools): `transaction_begin/commit/rollback`
11. System (8 tools): `system_status/get_variable/set_variable/run_command/run_lisp/about/capabilities`, plus `drawing_settings` (friendly units/scale/precision/osnap facade over system variables) 11. System (8 tools): `system_status/get_variable/set_variable/run_command/run_lisp/about/capabilities`, plus `drawing_settings` (friendly units/scale/precision/osnap facade over system variables; the facade now also covers limits, grid/snap/ortho/polar, PSLTSCALE, annotation scale (`"1:50"`), linear/angular unit formats and the current dimstyle/textstyle, with unknown keys refused and every key reported on read)
12. Engineering / Deterministic CAD (8 tools): `gear_draw_*`, `keyway_draw_*`, `titleblock_apply_iso_a3`, `drawing_finalize` 12. Engineering / Deterministic CAD (8 tools): `gear_draw_*`, `keyway_draw_*`, `titleblock_apply_iso_a3`, `drawing_finalize`
13. Premium meta-tools (12): `drawing_preflight`, `drawing_plan`, `drawing_critique`, `drawing_refine`, `drawing_deliver`, `point_from_snap/intersection/tangent`, `construction_*`, `drawing_apply_iso_layers`, `dimension_auto`, `entity_select_smart` 13. Premium meta-tools (12): `drawing_preflight`, `drawing_plan`, `drawing_critique`, `drawing_refine`, `drawing_deliver`, `point_from_snap/intersection/tangent`, `construction_*`, `drawing_apply_iso_layers`, `dimension_auto`, `entity_select_smart`
14. GD&T (ISO 1101 / ASME Y14.5): `gd_frame` (feature control frames), `datum_feature` — enforced by the `gdt` critique focus 14. GD&T (ISO 1101 / ASME Y14.5): `gd_frame` (feature control frames), `datum_feature` — enforced by the `gdt` critique focus
15. Layouts & Paper Space (12 tools): tab lifecycle `layout_list/create/set_current/delete/rename/copy`, viewports `viewport_create/list/set_scale/lock/delete`, and `entity_change_space` (CHSPACE — tagged `layout` *and* `modify`, and `layout` wins the group priority, so it files here). `drawing_export_pdf` takes an optional `layout` param and **does** project model content through viewports on both engines (`viewport_render` — v1.4 declared this COM-only and was wrong; the headless renderer only omits the viewport borders). `entity_change_space` is the mirror case — ezdxf-only (`chspace`), because ActiveX exposes no change-space member and the COM route is unverified. 15. Layouts & Paper Space (12 tools): tab lifecycle `layout_list/create/set_current/delete/rename/copy`, viewports `viewport_create/list/set_scale/lock/delete`, and `entity_change_space` (CHSPACE — tagged `layout` *and* `modify`, and `layout` wins the group priority, so it files here). `drawing_export_pdf` takes an optional `layout` param and **does** project model content through viewports on both engines (`viewport_render` — v1.4 declared this COM-only and was wrong; the headless renderer only omits the viewport borders). `entity_change_space` is the mirror case — ezdxf-only (`chspace`), because ActiveX exposes no change-space member and the COM route is unverified.
16. 3D Solids (5 tools, opt-in via `ENABLE_3D=true`, COM only): `solid_box/cylinder/extrude/revolve/boolean` — hidden from discovery and rejected while disabled; ezdxf reports `solid_3d` as unsupported (no headless ACIS). 16. 3D Solids (5 tools, opt-in via `ENABLE_3D=true`, COM only): `solid_box/cylinder/extrude/revolve/boolean` — hidden from discovery and rejected while disabled; ezdxf reports `solid_3d` as unsupported (no headless ACIS).
17. P&ID (9 tools, pack `pid`): `pid_symbol_list/insert` (ISO 10628-2 + ISA-5.1 catalogue authored in code, real blocks with TAG attributes, named ports, ACADMCP_PID XDATA), `pid_line_draw` (port-to-port orthogonal routing, ISA-5.1 line classes → layer/linetype/marker blocks, line numbers), `pid_tag_parse` (ISA-5.1 grammar), the reader `pid_graph` and its deliverables `pid_instrument_index/line_list/equipment_list`, and `pid_from_spec` (whole sheet, one transaction). Six `pid_*` critique focuses (`pid_dangling_line`, `pid_duplicate_tag`, `pid_incompatible_connection`, `pid_untagged_instrument`, `pid_illegal_tag`, `pid_unconnected_equipment`) run under `focus=None` and inside `drawing_finalize`; they return nothing on a drawing without P&ID nodes. Two resources (`autocad://pid/symbols`, `autocad://standards/isa51`) carry the catalogue and the ISA-5.1 letter tables. Both engines implement every P&ID contract; the COM paths were executed live once by `scripts/smoke_pid_com.py` (AutoCAD 2026). 17. P&ID (9 tools, pack `pid`): `pid_symbol_list/insert` (ISO 10628-2 + ISA-5.1 catalogue authored in code, real blocks with TAG attributes, named ports, ACADMCP_PID XDATA), `pid_line_draw` (port-to-port orthogonal routing, ISA-5.1 line classes → layer/linetype/marker blocks, line numbers), `pid_tag_parse` (ISA-5.1 grammar), the reader `pid_graph` and its deliverables `pid_instrument_index/line_list/equipment_list`, and `pid_from_spec` (whole sheet, one transaction). Six `pid_*` critique focuses (`pid_dangling_line`, `pid_duplicate_tag`, `pid_incompatible_connection`, `pid_untagged_instrument`, `pid_illegal_tag`, `pid_unconnected_equipment`) run under `focus=None` and inside `drawing_finalize`; they return nothing on a drawing without P&ID nodes. Two resources (`autocad://pid/symbols`, `autocad://standards/isa51`) carry the catalogue and the ISA-5.1 letter tables. Both engines implement every P&ID contract; the COM paths were executed live once by `scripts/smoke_pid_com.py` (AutoCAD 2026).
18. Styles (10 tools, pack `core`): `dimstyle_list/create/modify/set_current` (authored ISO-25 / ANSI presets from `engineering/standards/dimstyles.py`; `dimstyle_modify` accepts only `DIM_VARIABLE_WHITELIST` names (33) and refuses out-of-range values by name before writing; `changed` lists only variables that moved, and `rerender_required: true` says a headless DIMENSION keeps its rendered block until redrawn), `textstyle_list/create/set_current` (`font_resolved: false` is reported, never refused — DXF stores only the name), `mleaderstyle_list/create` (both engines: ezdxf on `doc.mleader_styles`, live through the `ACAD_MLEADERSTYLE` dictionary — ActiveX has no MLeaderStyle *collection*, which is not an engine boundary, so no `mleaderstyle` capability key exists), and `drawing_apply_standard("iso"|"ansi")` — dimstyle + text style + units + the `mech` layer set in one call, each item reporting `created` or already present.
19. Page setup & templates (6 tools, pack `core`): `page_setup_list/apply` (ISO 216 / ANSI Y14.1 sizes from `PAPER_SIZES`; an unknown ctb is written and reported `plot_style_known: false`), `plot_style_list` (catalog + the files actually installed on a live seat), `batch_plot` (every paper layout through `drawing_export_pdf(layout=)`; `mediabox_mm` is **read back from the PDF's own `/MediaBox`**, so the sheet size is verified, not assumed), `drawing_template_list` (the five bundled templates: `iso_a3_mech`, `iso_a1_arch`, `iso_a3_pid`, `ansi_b_mech`, `ansi_d_arch` — DXF headless, `.dwt` twin on COM, `scripts/build_templates.py --check` proves the DXFs reproducible), `drawing_template_save` (a `.dwt` request headlessly is refused with capability `dwt_write` naming the DXF route). `drawing_new(template=)` resolves a catalog name to the bundled file and reports `template: {name, source}`.
20. Environment (22 tools, pack `settings`): documents `document_list/activate/close` (both engines — the headless backend keeps a document registry; `document_close` refuses to discard unsaved work unless `discard=True`), layer states `layer_state_save/restore/list/delete` (portable: JSON chunks in an `ACADMCP_LAYERSTATES` XRECORD that travels with the file and **does not appear in AutoCAD's Layer States Manager** — `system_capabilities.layer_states` says so), named views `view_named_save/restore/list` (headless restore writes `$VIEWCTR/$VIEWSIZE` and reports `applied: "header_only"`), UCS `ucs_list/set/restore` (non-orthogonal axes refused with the measured angle; **tool coordinates stay WCS** — a UCS is stored for the operator, no tool interprets input in it), `system_variable_describe` (the 90-entry `SYSVAR_CATALOG`; an unknown name answers `known: false` plus nearest names, never an error; `system_set_variable` now refuses an out-of-range value for a catalogued name before writing), `drawing_properties_get/set` (custom properties on both engines through `$CUSTOMPROPERTYTAG`; the five summary fields are COM-only, capability `dwgprops`), and the live-only group `system_launch` (`live_application`), `system_preferences_get/set` (`preferences`; a whitelist of `Preferences.*` keys with ranges, read-only keys refused by name, writes report `old`/`new`), `user_pick_point/select`, `system_prompt_message` (`interactive_prompt`; a cancelled pick returns `{cancelled: true}`, a `COM_CALL_TIMEOUT` overrun reports `timed_out`). The COM paths were executed live once by `scripts/smoke_settings_com.py` (AutoCAD 2026), which also built the `.dwt` twins.
**Tool profiles:** `TOOL_PROFILE=lean|full` (default `full`) controls the advertised surface — `lean` ≈ 50 curated drafting tools (47 with `TOOL_PACKS=core`; including `cad_batch`, since a client with a tight tool cap is exactly the client paying most per turn). Applied in the lifespan; reported by `system_about`. The `core` profile was removed in v1.5.0 (the discovery layer replaced it); `TOOL_PROFILE=core` falls back to `full` with a warning. **Tool profiles:** `TOOL_PROFILE=lean|full` (default `full`) controls the advertised surface — `lean` = 55 curated drafting tools (52 with `TOOL_PACKS=core`; the five settings essentials — `drawing_apply_standard`, `dimstyle_set_current`, `textstyle_set_current`, `page_setup_apply`, `batch_plot` — are core-pack tools and stay; including `cad_batch`, since a client with a tight tool cap is exactly the client paying most per turn). Applied in the lifespan; reported by `system_about`. The `core` profile was removed in v1.5.0 (the discovery layer replaced it); `TOOL_PROFILE=core` falls back to `full` with a warning.
**Tool packs:** `TOOL_PACKS=all|core,pid` (default `all`) advertises only the vertical packs a client uses; `core` is always on and is everything no other pack claims; unknown names are ignored with a warning; a `lean` profile intersects with the enabled packs. `system_about` reports `tool_packs`. **Tool packs:** `TOOL_PACKS=all|core,pid,settings` (default `all`) advertises only the vertical packs a client uses; `core` is always on and is everything no other pack claims; `settings` is the 22 SECTION 20 environment tools, `pid` the nine P&ID tools; SECTION 18/19 are core; unknown names are ignored with a warning; a `lean` profile intersects with the enabled packs. `system_about` reports `tool_packs`.
**Tool discovery:** `DISCOVERY_MODE=off|search` (default `off`). `search` replaces the advertised catalog with `search_tools` + `call_tool`, ranking hits over an AutoCAD command / synonym corpus (`discovery/aliases.py`) layered on fastmcp's BM25 index. **Tool discovery:** `DISCOVERY_MODE=off|search` (default `off`). `search` replaces the advertised catalog with `search_tools` + `call_tool`, ranking hits over an AutoCAD command / synonym corpus (`discovery/aliases.py`) layered on fastmcp's BM25 index.
@@ -131,7 +134,10 @@ Tools are organized into sections (counts are indicative — `system_about` is a
- **Engineering layer scaffold**: `drawing_new` auto-bootstraps standard linetypes (CENTER, HIDDEN, PHANTOM) and engineering layers (GEOMETRY, DIM, CENTER, HIDDEN, PHANTOM, HATCH, TEXT, TITLEBLOCK). Pass `bootstrap=False` to opt out. - **Engineering layer scaffold**: `drawing_new` auto-bootstraps standard linetypes (CENTER, HIDDEN, PHANTOM) and engineering layers (GEOMETRY, DIM, CENTER, HIDDEN, PHANTOM, HATCH, TEXT, TITLEBLOCK). Pass `bootstrap=False` to opt out.
- **Generic contracts added in 1.6:** `block_define(name, entities, attdefs)` (typed primitives + ATTDEFs, both engines; `overwrite` replaces contents so INSERTs keep the name) and `entity_get/set_xdata` (typed by group code; 255-char strings, 16 KB per entity, enforced before writing). - **Generic contracts added in 1.6:** `block_define(name, entities, attdefs)` (typed primitives + ATTDEFs, both engines; `overwrite` replaces contents so INSERTs keep the name) and `entity_get/set_xdata` (typed by group code; 255-char strings, 16 KB per entity, enforced before writing).
- **P&ID reader rules:** `pid_graph` never modifies the drawing, reads geometry from the drawing (an INSERT's real rotation/scale) rather than the catalogue, and reports `source`/`confidence` per node (catalog 1.0, xdata 0.95, heuristic 0.6, inferred 0.3) — never raised by agreement between heuristics. Read `stats.confidence_min` before trusting a foreign drawing. - **P&ID reader rules:** `pid_graph` never modifies the drawing, reads geometry from the drawing (an INSERT's real rotation/scale) rather than the catalogue, and reports `source`/`confidence` per node (catalog 1.0, xdata 0.95, heuristic 0.6, inferred 0.3) — never raised by agreement between heuristics. Read `stats.confidence_min` before trusting a foreign drawing.
- **`TOOL_PACKS=all|core,pid`** advertises only the packs a client uses; `core` is always on; `system_about` reports `tool_packs`. - **`TOOL_PACKS=all|core,pid,settings`** advertises only the packs a client uses; `core` is always on; `system_about` reports `tool_packs`.
- **Layer states are ours, not AutoCAD's.** `layer_state_*` stores a portable snapshot in an `ACADMCP_LAYERSTATES` XRECORD; it survives save/reopen on both engines and travels with the file, and it is not listed in AutoCAD's Layer States Manager. Said in the tool docstring, in `system_capabilities.layer_states` (`mode: "xrecord"`, reason `portable_acadmcp_xrecord;not_listed_in_autocad_layer_states_manager`) and in the README.
- **Page-setup evidence is the PDF.** `batch_plot` reports `mediabox_mm` parsed from the file's `/MediaBox` (`engineering/standards/pdfinfo.py`); a page setup is verified by what a printer would get, not by the setter's return value. A style or setting write reports `changed` — re-setting a value to itself is not a change.
- **Nothing interprets coordinates in UCS.** `ucs_set` / `ucs_restore` store and activate a UCS for the operator's benefit; every tool input and output stays WCS (the repository rule above).
- **Production drawings**: For real engineering output, use the `engineering/` package primitives via the `gear_*` / `keyway_*` / `titleblock_*` MCP tools — do NOT hand-draw teeth/keyways/sections with raw `entity_create_*` calls. Always end with `drawing_finalize` for the 8-step validator. - **Production drawings**: For real engineering output, use the `engineering/` package primitives via the `gear_*` / `keyway_*` / `titleblock_*` MCP tools — do NOT hand-draw teeth/keyways/sections with raw `entity_create_*` calls. Always end with `drawing_finalize` for the 8-step validator.
### Premium Drawing Rules ### Premium Drawing Rules
+20 -10
View File
@@ -33,15 +33,16 @@ Live through COM on Windows, or headless through ezdxf anywhere — one typed co
## Why this exists ## Why this exists
**A big MCP server is expensive to be connected to.** The full catalog costs a client **44,930 tokens** before it has asked for anything. Discovery mode replaces it with two tools and costs **356**. **A big MCP server is expensive to be connected to.** The full catalog costs a client **59,315 tokens** before it has asked for anything. Discovery mode replaces it with two tools and costs **356**.
**A drafter searches for `FILLET`, not `entity_fillet`.** Those command names appeared in no tool name or description — `df = 0` against a stock index, not badly ranked but *absent*. The fix was data: an authored corpus of **162 AutoCAD command names and 731 synonym phrases** covering all 166 tools. A test refuses to let a tool exist without one. **A drafter searches for `FILLET`, not `entity_fillet`.** Those command names appeared in no tool name or description — `df = 0` against a stock index, not badly ranked but *absent*. The fix was data: an authored corpus of **186 AutoCAD command names and 933 synonym phrases** covering all 204 tools. A test refuses to let a tool exist without one.
| Advertised surface | Tools seen | Idle cost | | Advertised surface | Tools seen | Idle cost |
|---|---:|---:| |---|---:|---:|
| `TOOL_PROFILE=full` (default) | 161 | 44,930 tokens | | `TOOL_PROFILE=full` (default) | 199 | 59,315 tokens |
| `TOOL_PACKS=core` (full profile) | 152 | 41,420 tokens | | `TOOL_PACKS=core,settings` (full profile) | 190 | 55,593 tokens |
| `TOOL_PROFILE=lean` | 50 | 14,007 tokens | | `TOOL_PACKS=core` (full profile) | 168 | 48,825 tokens |
| `TOOL_PROFILE=lean` | 55 | 16,360 tokens |
| `DISCOVERY_MODE=search` | 2 | **356 tokens** | | `DISCOVERY_MODE=search` | 2 | **356 tokens** |
> [!NOTE] > [!NOTE]
@@ -101,11 +102,12 @@ Claude Desktop, Cursor, or any stdio MCP host. For HTTP: `autocad-mcp --transpor
| Annotation | ISO 129 toleranced dimensions, ISO 286 fits (`fit="H7"`), TABLE, MLEADER, GD&T frames and datums (ISO 1101) | | Annotation | ISO 129 toleranced dimensions, ISO 286 fits (`fit="H7"`), TABLE, MLEADER, GD&T frames and datums (ISO 1101) |
| Engineering generators | involute gears (front + section A-A), DIN 6885 keyed bores, ISO A3 title block | | Engineering generators | involute gears (front + section A-A), DIN 6885 keyed bores, ISO A3 title block |
| P&ID | catalogue blocks with ports and tags (ISO 10628-2 / ISA-5.1), port-to-port lines with ISA-5.1 classes and line numbers, `pid_graph` reads any P&ID back with confidence, instrument index / line list / equipment list, `pid_from_spec` one-call sheets | | P&ID | catalogue blocks with ports and tags (ISO 10628-2 / ISA-5.1), port-to-port lines with ISA-5.1 classes and line numbers, `pid_graph` reads any P&ID back with confidence, instrument index / line list / equipment list, `pid_from_spec` one-call sheets |
| Discovery | `search_tools` ranked over an AutoCAD command and synonym corpus — `FILLET`, `BPOLY`, `QSELECT`, `WBLOCK`, `OVERKILL`, `CHSPACE` each rank **#1** of the 161-tool advertised catalog | | Styles & standards | ISO-25 / ANSI dimension styles, ISOCP / ROMANS text styles, ISO / ANSI leader styles from authored presets; `drawing_apply_standard("iso")` sets all of it plus units and the `mech` layers in one call; `changed` reports only what moved |
| Discovery | `search_tools` ranked over an AutoCAD command and synonym corpus — `FILLET`, `BPOLY`, `QSELECT`, `WBLOCK`, `OVERKILL`, `CHSPACE` each rank **#1** of the 199-tool advertised catalog |
| Batching | `cad_batch` runs a step list in one round trip; `fields=` projects 11 result-heavy tools | | Batching | `cad_batch` runs a step list in one round trip; `fields=` projects 11 result-heavy tools |
| Paper space | tab lifecycle, viewports, `entity_change_space` (CHSPACE), `page_setup_apply` (ISO 216 / ANSI Y14.1 paper, ctb, scale, device — on both engines), `batch_plot` with every sheet size read back from its PDF's `/MediaBox`, `drawing_export_pdf(layout=…)` | | Paper space | tab lifecycle, viewports, `entity_change_space` (CHSPACE), `page_setup_apply` (ISO 216 / ANSI Y14.1 paper, ctb, scale, device — on both engines), `batch_plot` with every sheet size read back from its PDF's `/MediaBox`, `drawing_export_pdf(layout=…)` |
| Templates | five bundled templates built by the server's own tools and pinned reproducible (`iso_a3_mech`, `iso_a1_arch`, `iso_a3_pid`, `ansi_b_mech`, `ansi_d_arch`) — `drawing_new(template="iso_a3_mech")`, `drawing_template_list`, `drawing_template_save` (.dwt on live AutoCAD, `dwt_write` refused headlessly) | | Page setup & templates | ISO 216 / ANSI Y14.1 sheets, ctb catalog, `batch_plot` verified by the PDF's own `/MediaBox`, five bundled templates built by the server's own tools and pinned reproducible (`drawing_new(template="iso_a3_mech")`, `iso_a1_arch`, `iso_a3_pid`, `ansi_b_mech`, `ansi_d_arch`), save any drawing as a template (`.dwt` on live AutoCAD, `dwt_write` refused headlessly) |
| Environment | `document_list/activate/close` — several drawings open at once on both engines; portable layer states (`ACADMCP_LAYERSTATES` XRECORDs — in the file, not in AutoCAD's Layer States Manager); named views; UCS stored and made current *(tool coordinates stay WCS)*; live only: launch/attach, a preference whitelist (`OPTIONS`), and operator prompts — pick a point, select on screen, a command-line message — where ESC is `cancelled`, not an error | | Environment | several open documents headlessly, portable layer states (`ACADMCP_LAYERSTATES` XRECORDs — in the file, not in AutoCAD's Layer States Manager), named views, UCS *(tool coordinates stay WCS)*, a system-variable catalog with ranges, document properties, and on a live seat: launch/attach, preferences, an operator prompt / pick / select — where ESC is `cancelled`, not an error |
| Selection | window vs crossing stated back to the caller; a polygon tested against its own shape, not its bounding box | | Selection | window vs crossing stated back to the caller; a polygon tested against its own shape, not its bounding box |
| Boundaries | `boundary_trace` (BOUNDARY/BPOLY) chains loose edges into one closed polyline, arcs kept as bulges *(headless)* | | Boundaries | `boundary_trace` (BOUNDARY/BPOLY) chains loose edges into one closed polyline, arcs kept as bulges *(headless)* |
| Measurement | `analysis_measure_entity` measures what is *in* the drawing, by handle | | Measurement | `analysis_measure_entity` measures what is *in* the drawing, by handle |
@@ -171,7 +173,7 @@ An earlier matrix scored this server 10/10, which carried no information: every
| Task | Verified against | | Task | Verified against |
|---|---| |---|---|
| `tool_discovery` | six AutoCAD command names, each ranking #1 | | `tool_discovery` | six AutoCAD command names, each ranking #1 |
| `token_budget` | 44,930 → 356 tokens, against a ceiling fixed in advance | | `token_budget` | 59,315 → 356 tokens, against a ceiling fixed in advance |
| `hatch_islands` | 300 filled with the island, 400 ignoring it | | `hatch_islands` | 300 filled with the island, 400 ignoring it |
| `selection_filter` | window 1, crossing 2, bounding box 3, polygon 1 | | `selection_filter` | window 1, crossing 2, bounding box 3, polygon 1 |
| `measure_from_handle` | 139.2699 against the 100.0 a vertex shoelace gives | | `measure_from_handle` | 139.2699 against the 100.0 a vertex shoelace gives |
@@ -206,6 +208,14 @@ A page that only lists strengths is a page that has not been measured.
**Same-file only, DXF headlessly.** Off-page connectors link within one drawing; links across files are not resolved. The headless engine reads DXF; a DWG P&ID is read through the live backend. No DEXPI/Proteus export and no ISA-5.2 binary-logic symbols in this release, recorded in the spec so nobody re-derives the cut. **Same-file only, DXF headlessly.** Off-page connectors link within one drawing; links across files are not resolved. The headless engine reads DXF; a DWG P&ID is read through the live backend. No DEXPI/Proteus export and no ISA-5.2 binary-logic symbols in this release, recorded in the spec so nobody re-derives the cut.
### Known limitations of the settings track
**Layer states are ours.** `layer_state_save` writes a portable snapshot into an `ACADMCP_LAYERSTATES` XRECORD. It survives save/reopen on both engines and travels with the DWG/DXF; it is **not** an AutoCAD `LAYERSTATE` and does not appear in the Layer States Manager. `system_capabilities` reports `layer_states` as `mode: "xrecord"` for that reason.
**Six of the 22 environment tools need a live seat.** Preferences, launching, the operator prompts, and the five summary fields of document properties are refused headlessly with `preferences` / `dwgprops` / `live_application` / `interactive_prompt` — a refusal, not a stub. A `.dwt` template is the same case (`dwt_write`): a `.dwt` is a DWG container, so headlessly the template is saved as DXF. `mleaderstyle_create` is *not* such a case — ActiveX has no MLeaderStyle collection, but the `ACAD_MLEADERSTYLE` dictionary holds full `IAcadMLeaderStyle` objects, so both engines create leader styles.
**A headless dimension does not re-render.** `dimstyle_modify` reports `dimensions_using_style` and `rerender_required: true` on the ezdxf engine; the DIMENSION keeps its rendered block until it is redrawn. AutoCAD regenerates on the next regen.
## Configuration ## Configuration
Nothing loads a `.env` file — export these, or set them in your MCP client's `env` block. Nothing loads a `.env` file — export these, or set them in your MCP client's `env` block.
@@ -217,7 +227,7 @@ Nothing loads a `.env` file — export these, or set them in your MCP client's `
|---|---|---| |---|---|---|
| `AUTOCAD_MCP_BACKEND` | `auto` | `auto`, `com`, or `ezdxf` | | `AUTOCAD_MCP_BACKEND` | `auto` | `auto`, `com`, or `ezdxf` |
| `CAD_PROGID` | `AutoCAD.Application` | COM ProgID the live backend attaches to | | `CAD_PROGID` | `AutoCAD.Application` | COM ProgID the live backend attaches to |
| `TOOL_PROFILE` | `full` | `lean` (50 curated tools) or `full` | | `TOOL_PROFILE` | `full` | `lean` (55 curated tools, 52 with `TOOL_PACKS=core`) or `full` |
| `TOOL_PACKS` | `all` | Vertical packs to advertise: `core,pid,settings` (`core` always on) | | `TOOL_PACKS` | `all` | Vertical packs to advertise: `core,pid,settings` (`core` always on) |
| `DISCOVERY_MODE` | `off` | `search` replaces the catalog with `search_tools` + `call_tool` | | `DISCOVERY_MODE` | `off` | `search` replaces the catalog with `search_tools` + `call_tool` |
| `ENABLE_3D` | `false` | Expose the opt-in `solid_*` tools (COM) | | `ENABLE_3D` | `false` | Expose the opt-in `solid_*` tools (COM) |
@@ -1,7 +1,7 @@
# v1.6 Track E — AutoCAD settings and environment # v1.6 Track E — AutoCAD settings and environment
**Date:** 2026-09-16 · **Status:** design approved in conversation; plan at **Date:** 2026-09-16 · **Status:** implemented 2026-09-22 (26 tasks of
`docs/superpowers/plans/2026-09-16-v1.6-settings-implementation.md` · **Parent:** `docs/superpowers/plans/2026-09-16-v1.6-settings-implementation.md`; live COM smoke on AutoCAD 2026 recorded in `CHANGELOG.md` Unreleased, `.dwt` twins built by it; A/B vs v1.5.1 32 / 32) · **Parent:**
`2026-09-15-v1.6-roadmap-design.md` (track E) · **Baseline:** main after `2026-09-15-v1.6-roadmap-design.md` (track E) · **Baseline:** main after
Track A (166 tools, 8 resources) Track A (166 tools, 8 resources)