9168d613977909263d6390bc05dfd9ddc8b78bfd
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3b033033f9 |
feat(mech): six mech_* critique focuses, the mech pack, lean 60, aliases and the counts
The four track-B/G branches are merged; this is the integration that makes the 25 new tools one surface instead of four. - engineering/mech/critique.py: the six focuses of spec 13, dispatched the way the P&ID ones are. One index per critique run, shared through run_critique's context, so six focuses cost one read of the drawing; a drawing with no ACADMCP_MECH payload yields nothing at all, which is what keeps focus=None cheap for a P&ID sheet or a plain DXF. Each focus has a positive and a negative fixture. Two narrowings are in the module docstring rather than hidden: mech_view_misaligned checks the projection axis and not the quadrant, because the pinned payload carries no projection angle to check it against, and mech_duplicate_dimension catches two dimensions in the same place rather than a semantic restatement, because no engine exposes what a dimension measured. - The index reads what the tools actually write, not only the plan's fixture shape. mech_part_draw anchors its part payload on a POINT (layer MECH) and lists every drawn view under "views"; the plan's index read INSERT/CIRCLE only and one "view" per payload, so it was silent on every part the server draws. It now reads POINT too, expands "views" into one entry per drawn view (the section check looks in the section's own WCS box, the alignment check compares frame_bbox centres), and pages entity_list instead of one call. Test: a part drawn by draw_part + add_view is read and passes all six; the same part with its hatch erased is reported. - Live type names, measured on AutoCAD 2026 (2026-09-23, scratch document, closed): ObjectName AcDbBlockReference -> BLOCKREFERENCE, AcDbRotatedDimension -> ROTATEDDIMENSION, AcDbAlignedDimension -> ALIGNEDDIMENSION, AcDbPoint -> POINT with GetBoundingBox = the point. The index reads BLOCKREFERENCE as an INSERT and any *DIMENSION as a dimension; a wrapper test reports the ezdxf entities under exactly those measured names. - mech_thread_unrepresented uses the view engine's own MINOR_RATIO, and checks the thin line ISO 6410 draws: the minor diameter of an external thread, the major of an internal one. - mech_bom_balloon_mismatch: identical parts share one balloon (ISO 6433 balloons a parts-list row), so a second M12x60 is covered by the first one's balloon instead of reported. - TOOL_PACK_NAMES has "mech" (the 14 tools of SECTIONS 21-23). SECTION 24 stays core: a frame, a title block, a parts list and an xref are universal drafting, not a vertical. Lean gains five and reaches 60 (54 with TOOL_PACKS=core). - _GROUP_TAG_PRIORITY gains sheet directly after mech; the mech group label becomes "mechanical". SECTION 24's last four tools (xref_attach, xref_manage, image_attach, drawing_export_dwg) now carry the sheet tag, so group, pack and SECTION are one list: 229 tools in 25 groups, and engineering/blocks/entity_creation/drawing return to their pre-SECTION-24 sizes. - Ten golden tuning cases, two of them Turkish (with the diacritic spellings added to the alias records next to the ASCII-folded ones). The shared AutoCAD command set needed no change: the merge had already resolved TABLE, REVCLOUD, SECTIONPLANE, INSERT, ARRAY and SAVEAS, and nothing is stale. - Inventory regenerated, the frozen group-size snapshot retaken from the live registry, and the README release-snapshot / pack / lean figures taken from scripts/check_doc_numbers.py rather than typed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd |
||
|
|
70afd57831 |
feat(server): settings pack — 22 environment tools behind TOOL_PACKS, lean grows to 55, three groups, golden set +10
Task 24 (merge sanity) on main after the five track E groups merged.
- TOOL_PACK_NAMES = ("core", "pid", "settings"); PACK_TOOL_NAMES["settings"]
is exactly the 22 SECTION 20 tools. Styles and page setup stay in core.
- LEAN_TOOL_NAMES += page_setup_apply, batch_plot (53 -> 55).
- _GROUP_TAG_PRIORITY / _GROUP_TAG_LABELS: "style" moved up next to "pid",
"pagesetup" -> page_setup and "environment" -> environment added; the 28
SECTION 19/20 decorators gain their section tag, so _tool_groups() reports
styles 10 / page_setup 6 / environment 22 (23 groups, 204 tools) and
pack == group == section for the settings pack.
- SECTION headers, backends/base.py composition, contracts/__init__.py
exports and the layer_states feature entry were already correct after the
merge (read and confirmed, nothing edited).
- Pack text: config.py, .env.example, README config row; README <sub> line
204 tools in 23 groups; release snapshot 3259 collected tests (measured).
- docs/tool-inventory.json regenerated; registry snapshot re-derived.
- tests: test_tool_packs.py replaced (11 tests), test_capability_contract.py
+3 (composition, the agreed capability flags, layer_states honesty),
golden set +10 tuning cases (81 = 66 tuning + 15 holdout); all ten route
in the top 3 without alias edits.
Deviation from the plan text: TRACK_E_KEYS carries five keys, not six. The
plan's "mleaderstyle" (ezdxf True / com False) contradicts spec §8.1, which
retracted that key because the ActiveX route exists (§4.2); measured on the
tree: capability_keys() == {boundary_trace, chspace, interactive_prompt,
live_application, preferences, revcloud, wipeout}, and
ComBackend.mleaderstyle_create is a native implementation
(backends/com_backend.py:6752, is_capability_default -> False). The test now
also asserts the key is absent.
No new ActiveX call was written in this task, so no live probe was needed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
|
||
|
|
d3ef7b45a2 |
feat(discovery): style golden queries; dimstyle/textstyle set_current and drawing_apply_standard join the lean profile
Five tuning cases for the styles surface (DDIM, the ISO-25 set-current paraphrase, the one-call drafting-standard paraphrase, the isocp text style, and the dimstyle counting question) — measured against the live catalog every one ranks top-1, so no alias vocabulary changed. The docstring count moves to seventy-one (56 tuning + 15 holdout); the holdout set is untouched. Lean decision (spec §8.2): dimstyle_set_current, textstyle_set_current and drawing_apply_standard join LEAN_TOOL_NAMES (50 -> 53); the seven authoring/list tools stay full-only and all ten stay in core (no pack claims them). Pinned by the new profile test in tests/test_styles.py, written async like the rest of that module (its module-wide asyncio mark warns on a sync test). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd |
||
|
|
2344b3b9d4 |
fix(task-6): bind the invalid-tag fixture to the reported letter and position
Every grammar error is prefixed with the tag's own letters, so the old
single-letter fragments (FCI/"I", PSVX/"X", ...) matched whatever the
grammar said: a mutation that dropped the letter and position from every
error left 9 of 11 invalid rows green. The fixture now quotes the error
text the spec demands ("unexpected letter I at position 3", "... after
valve V", "trailing O (open/closed) ...", "needs at least one function
letter after F"), and the test pins it to the single first error.
ABCDEF-106 was mispinned as a grammar rejection of "D": six letters
exceed the regex cap, so it never reached the grammar. It is now pinned
as a format rejection, and ABCDE-106 carries the "letter D at position 4"
case.
A fixture lint rejects any fragment that is a substring of its own tag
and requires grammar rows to name a letter, position or trailing rule,
so a future row cannot reintroduce the hole.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
|
||
|
|
b8de3968f9 |
feat(pid): ISA-5.1 identification-letter grammar with a pinned fixture
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd |
||
|
|
b03a7615b1 |
release: v1.5.0 — discovery layer, honesty debt closed, Wave A
Tool count 131 -> 154; 474 -> 1242 collected tests. The release exists for two measured reasons. A 149-tool catalog costs a client ~40,300 tokens before it has asked for anything, and a drafter searching the way drafters think -- FILLET, BPOLY, QSELECT, WBLOCK -- scored df=0 against the stock index, because those words were simply not in the data. Discovery and batching - DISCOVERY_MODE=search replaces the catalog with search_tools + call_tool, ranked over an AutoCAD command and synonym corpus (discovery/aliases.py) on top of fastmcp's BM25 index. Measured: 40,305 -> 356 tokens advertised. - cad_batch runs a step list in one round trip; fields= projects result-heavy responses. The `core` profile is gone -- discovery replaced it. Honesty debt (Tier 0) - OCS/ECS: `extrusion` appeared nowhere in this codebase, so mirrored and rotated geometry reported coordinates that were quietly wrong. backends/ocs.py translates at the backend boundary; every tool coordinate is WCS on both engines, and a tilted plane refuses rather than answering with a number that looks fine. - drawing_save_as(fmt="dwg") wrote DXF bytes to a .dwg path. drawing_audit never repaired. analysis_measure_area shoelaced points the caller typed in. - ezdxf calls gained a per-call timeout, so one hung call can no longer wedge a server whose document lock is a single asyncio.Lock. Architecture - The 1854-line backend ABC is 19 contract modules; @capability(key, reason=) makes optional methods declarative and a gate fails on undeclared holes. - 8 layout/viewport tools, CHSPACE, CAD_PROGID escape hatch. - Wave A: selection filters, boundary tracing, hatch depth, annotation objects, measurement -- 13 tools of a planned 39. The REGION and 2D-boolean family was cut on evidence: add_region() yields zero ACIS bytes and the greiner_hormann substitute loses 28.2% of the area on a square with one semicircular edge. Verified against a live AutoCAD 2026, which found four COM defects no amount of reading would have caught -- AcadPViewport has no ViewCenter, and the line that set it had been swallowed by a bare except since v1.4. Benchmark v3 (15 tasks) and what it caught - v2 scored this server 10/10, which carried no information: every task in it exercised something the server was built around. Five tasks were added because they can fail, and three did while being written -- a hatch could not be measured though the refusal listed HATCH as measurable, the boundary tools and the measure tool disagreed about the same shape (139.2177 vs 139.2699), and a circle stored as two bulged vertices measured 0.0. - Competitor reports are NOT re-scored. They are pinned v1.4 runs against v2 and were never asked these five questions; the chart shows those rows `not run`. - Correctness A/B: 21/24 -> 24/24, zero regressions. Performance, stated plainly The published v1.4 perf report was recorded on CPython 3.14 and the new one on 3.11.15, so the apparent 2-6x speedup is the interpreter, not this release. Re-measured on one interpreter, v1.5.0 is 28% slower creating entities and 22% slower on the 10k roundtrip. Fully attributed: EZDXF_CALL_TIMEOUT=0 restores v1.4.0's exact numbers. That is the deadlock fix being paid for, the knob is documented, and winning it back is on the 1.6 roadmap. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |