# v1.6 Track E — AutoCAD settings and environment **Date:** 2026-09-16 · **Status:** implemented 2026-09-22 (26 tasks of `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 Track A (166 tools, 8 resources) ## 1. Summary v1.5 lets a model read and write raw system variables and a friendly `drawing_settings` facade, and nothing else about the environment a drawing lives in: no dimension/text/leader styles (every dimension inherits `Standard`), no page setup (a PDF is whatever the renderer's default is), no templates beyond a layer list, one document at a time, no named views, UCS or layer states, and no way to ask AutoCAD itself anything (preferences, document properties, a point picked on screen). This track adds those as **38 tools** in three new sections, on both engines wherever a headless file can hold the result, with an honest `@capability` refusal where only a live AutoCAD can (preferences, document properties' summary fields, launching, prompting the operator). Authored standards data — ISO-25 and ANSI dimension styles, text styles, five drawing templates built by the server's own tools — is pinned by tests. `drawing_apply_standard` makes the common case one call. **The user's principle for this track (2026-09-16):** tool count is not the goal. Every tool here has a rich alias record, a docstring that names its refusals, a pack, and a place in the `lean` profile decision; a near-duplicate is folded into an `action` enum rather than registered twice. Tool budget: **+38** → 204 registered. Packs: styles, settings, page setup and templates are `core` (drafting essentials); the environment and interactive groups form the new `settings` pack. ## 2. Scope **In:** sections 4–10. **Track A hardening (wave 0 of this track's plan):** the review findings from Track A that are real defects — `entity_create_block_ref` accepts an undefined block, `block_explode` drops ATTRIB text, `pid_from_spec` lets NaN reach the drawing and does not roll back on `BaseException`, signal lines receive a fabricated line number and label, a bubble's exit point ignores the first waypoint, `block_insert` coerces attribute values with `str()`, `block_define` writes NaN base points and dangling layer references — each a fix with a test; the rest of the ~80 findings are filed in `docs/analysis/track-a-review-backlog.md` with a one-line disposition each. **Out of 1.6 (recorded):** TABLESTYLE objects (ezdxf cannot author them), AutoCAD-native `LAYERSTATE` entries (our layer states are portable XRECORDs, see §8.3), CUI/ribbon/workspace changes, plotter (`.pc3`) authoring, annotative object *creation* (scales are settable; entities stay non-annotative), ANSI *inch* templates (ANSI templates here are metric ANSI: `ansi` dimstyle with decimal inches is a 1.7 item once an inch drawing benchmark exists). ## 3. Architecture ``` engineering/standards/ __init__.py dimstyles.py ISO_25, ANSI presets as data; DIM_VARIABLE_WHITELIST; apply/describe textstyles.py ISOCP, ISOCPEUR, ARIAL, ROMANS presets (font file, width, oblique) mleaderstyles.py ISO / ANSI leader presets sysvars.py SYSVAR_CATALOG (~60 entries: name, type, range, meaning, engines) papers.py PAPER_SIZES (ISO A0–A4, ANSI A–E), CTB_CATALOG, scale vocabulary templates.py TEMPLATE_CATALOG (5 bundled templates: what each contains) engineering/environment/ layer_states.py portable layer-state snapshot <-> XRECORD codec templates/ built artefacts: .dxf (headless) + .dwt (COM), README scripts/build_templates.py, scripts/smoke_settings_com.py backends/contracts/styles.py (new) dimstyle_*, textstyle_*, mleaderstyle_* backends/contracts/pagesetup.py (new) page_setup_*, plot_style_list, batch_plot, template_save backends/contracts/environment.py (new) document_*, layer_state_*, view_named_*, ucs_*, preferences_*, drawing_properties_*, system_launch, user_pick_point, user_select, system_prompt_message backends/contracts/settings.py (edit) drawing_settings facade grows server.py SECTION 18 Styles (10) · SECTION 19 Page setup & templates (6) · SECTION 20 Environment (22) ``` Every new contract method is `@abstractmethod` unless the table in §9 marks it `@capability`. Both backends implement every method; COM paths are fake-tested and executed once live by `scripts/smoke_settings_com.py`. ## 4. Styles (SECTION 18, 10 tools, pack `core`) ### 4.1 Authored presets (`engineering/standards/dimstyles.py`) | Variable | `iso-25` | `ansi` (metric) | Meaning | |---|---|---|---| | DIMTXT | 2.5 | 3.0 | text height (mm) | | DIMASZ | 2.5 | 3.0 | arrow size | | DIMEXE | 1.25 | 1.5 | extension beyond dim line | | DIMEXO | 0.625 | 1.5 | extension line offset | | DIMGAP | 0.625 | 1.0 | text gap | | DIMTAD | 1 (above) | 0 (centred) | text vertical placement | | DIMTIH / DIMTOH | 0 / 0 (aligned) | 1 / 1 (horizontal) | text orientation | | DIMDEC | 2 | 2 | linear decimals | | DIMDSEP | `,` | `.` | decimal separator | | DIMLUNIT | 2 (decimal) | 2 | linear unit format | | DIMZIN | 8 (trailing zeros suppressed) | 8 | zero suppression | | DIMBLK | `""` (closed filled) | `""` | arrowhead | | DIMTXSTY | `ISOCP` | `ROMANS` | text style (created if missing) | | DIMLWD / DIMLWE | -2 (ByBlock) | -2 | line/extension lineweight | | DIMSCALE | 1.0 | 1.0 | overall scale | Source: ISO 129-1:2018 (text and arrow sizes for the 2.5 mm lettering row of ISO 3098-1) and ASME Y14.2-2014 (line conventions and lettering: 3 mm / .12 in lettering, .125 in arrowheads), metric values. A provenance test asserts each preset's values against this table by name. `DIM_VARIABLE_WHITELIST` = the 15 variables above plus DIMTOL/DIMTP/DIMTM/ DIMTOLJ/DIMTFAC/DIMLFAC/DIMRND/DIMATFIT/DIMTMOVE/DIMCLRD/DIMCLRE/DIMCLRT/ DIMSAH/DIMBLK1/DIMBLK2/DIMCEN — `dimstyle_modify` refuses anything else by name. ### 4.2 Tools - `dimstyle_list()` → `[{name, current, values: {15 whitelist vars}}]` - `dimstyle_create(name, preset: "iso-25"|"ansi"|None = None, overrides: dict|None = None, set_current=False)` — preset values then overrides; unknown override key or a value outside the variable's range (`DIMDEC` 0–8, sizes > 0, DIMTAD 0–4, DIMDSEP one char) → `ValueError` naming it, nothing written; name clash → `ValueError` (use `dimstyle_modify`). - `dimstyle_modify(name, overrides)` — `changed` reports only variables that actually moved (the `hatch_edit` rule). Dimensions already using the style are listed in `dimensions_using_style` with `rerender_required: true` on the headless engine: AutoCAD re-renders them on the next regen, but a headless DIMENSION carries its rendered block, so the drawing shows the old style until the dimension is redrawn — stated rather than silent. - `dimstyle_set_current(name)` — `$DIMSTYLE`; the dimension tools then use it (the existing per-dimension override path stays as is). - `textstyle_list()`, `textstyle_create(name, font: "isocp.shx"|"isocpeur.ttf"|"arial.ttf"|"romans.shx"|, height=0.0, width_factor=1.0, oblique_deg=0.0, set_current=False)`, `textstyle_set_current(name)` — `$TEXTSTYLE`; a font file that is neither a bundled preset nor present in the engine's font path is written but reported `font_resolved: false` (AutoCAD substitutes at open; the headless renderer falls back), never refused, because DXF only stores the name. - `mleaderstyle_list()`, `mleaderstyle_create(name, preset: "iso"|"ansi", overrides)` — arrow size, landing gap, text style, text height, both engines: ezdxf on `doc.mleader_styles`; COM through the `ACAD_MLEADERSTYLE` dictionary, whose items are `IAcadMLeaderStyle` objects (`ArrowSize` / `LandingGap` / `TextHeight` in drawing units, `TextStyle` a name — verified against the AutoCAD 2026 type library), created with `Dictionaries.Item("ACAD_MLEADERSTYLE").AddObject(name, "AcDbMLeaderStyle")` followed by the property writes. ActiveX has no `MLeaderStyles` *collection* property, which is not an engine boundary — no `mleaderstyle` capability key exists. - `drawing_apply_standard(standard: "iso"|"ansi", layers: bool = True, units: bool = True)` — one call: the dimstyle preset (created and set current), its text style, `drawing_settings` (units mm, decimal linear and angular units, LTSCALE 1, DIMSCALE 1; the decimal separator comes from the preset) and, with `layers`, the `mech` layer set for both standards (ANSI layer naming is company-specific; the set reuses the mech names with ISO 128 lineweights — only styles and the separator differ between the two). Returns, per item, whether it was created or was already present. ## 5. Settings (SECTION 20 shares these; 3 tools + facade growth) - `drawing_settings` facade gains: `limits` (`[[xmin,ymin],[xmax,ymax]]` → `$LIMMIN/$LIMMAX`), `grid` (bool → GRIDMODE) and `grid_spacing`, `snap` (bool) and `snap_spacing`, `ortho` (bool), `polar` (bool + `polar_angle`), `psltscale` (0/1), `annotation_scale` (`"1:50"` → CANNOSCALE string + CANNOSCALEVALUE), `linear_units` (`decimal|engineering|architectural|fractional|scientific` → LUNITS 2/3/4/5/1), `angular_units` (`degrees|dms|grads|radians|surveyor` → AUNITS), `dimstyle` and `textstyle` (current names). Ranges enforced as today (`_RANGES`), unknown keys refused, and the read side reports every key. - `system_variable_describe(name=None, search=None)` — from `SYSVAR_CATALOG`: `{name, type, range|enum, default, meaning, saved_in: drawing|registry|not_saved, engines: {ezdxf: bool, com: bool}, friendly_key: str|None}`; `search` matches names and meanings; unknown name → `known: false` plus the nearest names, never an error. The catalog is authored (~60: the DIM* whitelist, LTSCALE, PSLTSCALE, INSUNITS, LUNITS, LUPREC, AUNITS, AUPREC, LIMMIN/LIMMAX, GRIDMODE/GRIDUNIT, SNAPMODE/SNAPUNIT, ORTHOMODE, POLARMODE/POLARANG, OSMODE, CANNOSCALE, TEXTSIZE, TEXTSTYLE, DIMSTYLE, CLAYER, CELTYPE, CECOLOR, CELWEIGHT, PDMODE/PDSIZE, FILLETRAD, MIRRTEXT, ATTREQ/ATTDIA, TILEMODE, CTAB, DWGNAME/DWGPREFIX, SAVETIME, FILEDIA, CMDECHO, HIGHLIGHT, REGENMODE, UCSNAME, VIEWCTR/VIEWSIZE, ANGBASE/ANGDIR, PLINEWID, HPNAME/HPSCALE/HPANG, LWDISPLAY, XREFCTL, PROXYSHOW, ISOLINES, FACETRES, DISPSILH). `system_set_variable` gains a soft check: a name in the catalog with a range refuses out-of-range values before writing; a name not in the catalog behaves as today. - `drawing_properties_get()` / `drawing_properties_set(title=None, subject=None, author=None, keywords=None, comments=None, custom: dict|None=None)` — COM: `SummaryInfo` (+ `AddCustomInfo/SetCustomByKey`); ezdxf: `custom` through `doc.header.custom_vars` (`$CUSTOMPROPERTYTAG`/`$CUSTOMPROPERTY` pairs, both engines) and the five summary fields refused with `capability: "dwgprops"` when any of them is passed headlessly (`get` returns them as `null` with `summary_available: false`). ## 6. Page setup, plotting, templates (SECTION 19, 6 tools, pack `core`) - `page_setup_list(layout=None)` → per layout: `{paper: "ISO_A3", size_mm: [420,297], orientation, plot_style, scale, plot_area, device, margins_mm}` — read from LAYOUT plot settings (ezdxf `dxf_layout.dxf.*`; COM `Layout.*`). - `page_setup_apply(layout, paper: "ISO_A4"|"ISO_A3"|"ISO_A2"|"ISO_A1"|"ISO_A0"|"ANSI_A"|…|"ANSI_E", orientation: "landscape"|"portrait" = "landscape", plot_style: str = "monochrome.ctb", scale: "fit"|"1:1"|"1:2"|"1:5"|"1:10"|"1:20"|"1:50"|"1:100"|"2:1"|"5:1"|"10:1" = "fit", plot_area: "layout"|"extents" = "layout", device: str = "DWG To PDF.pc3", margins_mm=None, center=True)` — `PAPER_SIZES` authored (ISO 216 / ANSI Y14.1 sizes in mm), `CTB_CATALOG` names the ctb files AutoCAD ships (`monochrome.ctb`, `acad.ctb`, `Grayscale.ctb`, `Screening 100%.ctb`, …); an unknown ctb is written and reported `plot_style_known: false` (a missing ctb only matters at plot time). Returns the applied setup and `changed`. - `plot_style_list()` — the authored catalog plus, on COM, the files actually present in `Preferences.Files.PrintStyleSheetPath` (`source: "catalog"|"installed"`). - `batch_plot(layouts: list[str]|None = None, output_dir: str, format: "pdf" = "pdf", file_pattern: "{drawing}-{layout}.pdf")` — every named (default: every paper) layout through the existing `drawing_export_pdf(layout=)` path; returns one row per layout `{layout, path, bytes, mediabox_mm}` where `mediabox_mm` is **read back from the PDF** (`/MediaBox` parsed from the file) so the sheet size is verified, not assumed. Model space is included only when named explicitly. - `drawing_template_list()` → `TEMPLATE_CATALOG` rows `{name, standard, sheet, layer_set, dimstyle, textstyle, title_block, files: {dxf, dwt}}`. - `drawing_new(template=…)` (existing tool, parameter grows): a catalog name resolves to the bundled file (`templates/.dxf` headless, `templates/.dwt` on COM); a path is used as today. Returns `template: {name|path, source: "bundled"|"path"}`. - `drawing_template_save(path, name=None, description=None)` — current drawing as a template: ezdxf writes DXF (a `.dwt` request headlessly is refused with `capability: "dwt_write"` naming the DXF route); COM `SaveAs(path, acTemplateDwg)` and the description goes to the template's summary. Path validated for write. **Bundled templates** (`scripts/build_templates.py` builds all five through the server's own backend methods — layers, styles, settings, ISO 5457 frame from `titleblock_apply_iso_a3` where the sheet is A3, page setup — then saves DXF; the `.dwt` twins are produced on the live machine by opening each DXF over COM and `SaveAs(..., acTemplateDwg)`, committed once, and a test asserts the DXF side is byte-reproducible from the script): | name | standard | sheet | layer set | styles | page setup | |---|---|---|---|---|---| | `iso_a3_mech` | ISO | A3 landscape | mech | ISO-25 / ISOCP | ISO_A3, monochrome.ctb, 1:1 | | `iso_a1_arch` | ISO | A1 landscape | iso13567 | ISO-25 / ISOCP, CANNOSCALE 1:50 | ISO_A1, monochrome.ctb, fit | | `iso_a3_pid` | ISO | A3 landscape | pid | ISO-25 / ISOCP | ISO_A3, monochrome.ctb, 1:1 | | `ansi_b_mech` | ANSI | ANSI B landscape | mech | ANSI / ROMANS | ANSI_B, monochrome.ctb, 1:1 | | `ansi_d_arch` | ANSI | ANSI D landscape | iso13567 | ANSI / ROMANS | ANSI_D, monochrome.ctb, fit | ## 7. Environment (SECTION 20, 22 tools, pack `settings`) ### 7.1 Documents (3, both engines) - `document_list()` → `[{name, path, active, saved, entity_count}]`. - `document_activate(name_or_path)` → switches the backend's active document; every later tool call targets it. ezdxf: the backend keeps `_docs: dict[key, DocState]` (document, path, dirty flag, undo stack, plan spec, transaction snapshot) and `_doc` becomes a property over the active key — `drawing_new` / `drawing_open` register a new entry instead of replacing the only one; `drawing_close` removes the active entry and activates the most recent other one (or none). COM: `Documents.Item(...).Activate()`. - `document_close(name_or_path, save=False)` — refuses to discard unsaved changes unless `discard=True` (the message names the unsaved document); closing the last document leaves the backend in the "no document" state every tool already handles. - `drawing_close` (existing) becomes the active-document case of `document_close`. ### 7.2 Layer states (4, both engines, portable) `layer_state_save(name, description=None)`, `layer_state_restore(name, properties: list|None = None)`, `layer_state_list()`, `layer_state_delete(name)`. A state is the layer table snapshot `{layer: {on, frozen, locked, color, linetype, lineweight, plot}}` plus `current_layer`, stored as JSON chunks in an XRECORD under the drawing's named object dictionary `ACADMCP_LAYERSTATES` → `` (ezdxf `rootdict.add_new_dict` / `add_xrecord`; COM `Dictionaries.Add` / `AddXRecord` / `SetXRecordData` with 1000-code chunks ≤ 255 chars). Restore applies only the requested `properties` (default all) and reports `applied`, `missing_layers` (in the state, not in the drawing — skipped, never created) and `new_layers` (in the drawing, not in the state — untouched). The docstring and `system_capabilities` say plainly that these states live in the file and travel with it but **do not appear in AutoCAD's Layer States Manager**. ### 7.3 Named views (3, both engines) `view_named_save(name, center=None, height=None, width=None)` (defaults: the current view on COM; on ezdxf the drawing's extents), `view_named_restore(name)` (COM: `ActiveViewport` set; ezdxf: `$VIEWCTR/$VIEWSIZE` and the reported no-op rule of the other view tools), `view_named_list()`. Refuses `height <= 0`; a name clash replaces (`replaced: true`). ### 7.4 UCS (3, both engines) `ucs_list()`, `ucs_set(name, origin, x_axis, y_axis)` (unit vectors normalised; non-orthogonal axes refused with the measured angle), `ucs_restore(name|"world")`. **Tool coordinates stay WCS** (the repository rule) — a UCS is stored and made current for the operator's benefit; no tool starts interpreting inputs in UCS. The docstring says so. ### 7.5 Application, preferences, properties, interactive (9) - `system_launch(visible=True, open_path=None)` — COM: connect or start the ProgID, optionally open a file; returns `{launched: bool, attached: bool, version, document}`; ezdxf: `capability: "live_application"`. - `system_preferences_get(keys=None)` / `system_preferences_set(key, value)` — whitelist (COM `Preferences.*`): `OpenSave.SaveAsType` (enum name ↔ value), `OpenSave.AutoSaveInterval` (0–600 min), `OpenSave.CreateBackup`, `OpenSave.IncrementalSavePercent` (0–100), `Display.CursorSize` (1–100), `Drafting.AutoSnapMarkerSize` (1–20), `Drafting.AutoSnapTooltip`, `Selection.PickBoxSize` (0–50), `Output.DefaultPlotStyleTable`, `Output.DefaultOutputDevice`, and read-only `Files.SupportPath`, `Files.TemplateDwgPath`, `Files.PrintStyleSheetPath`, `Files.PrinterConfigPath`. Writes report `old`/`new`; a read-only key or a value outside its range is refused by name; ezdxf: `capability: "preferences"`. - `drawing_properties_get/set` — §5. - `user_pick_point(prompt)`, `user_select(prompt, mode: "single"|"multiple")`, `system_prompt_message(text)` — COM `Utility.GetPoint` / `GetEntity` + `SelectionSets.Add(...).SelectOnScreen` / `Utility.Prompt`; a pick cancelled by the operator returns `{cancelled: true}` (not an error); a wall-clock timeout (`COM_CALL_TIMEOUT` applies) reports `timed_out`; ezdxf: `capability: "interactive_prompt"`. ## 8. Cross-cutting ### 8.1 Capability keys (added to **both** maps) `dwgprops` (ezdxf false: summary fields), `dwt_write` (ezdxf false), `live_application`, `preferences`, `interactive_prompt` (ezdxf false). `tests/test_capability_contract.py` enforces both maps. (`mleaderstyle` was listed here as COM false; the ActiveX route exists — §4.2 — so there is no key.) ### 8.2 Packs, profiles, discovery `PACK_TOOL_NAMES["settings"]` = the 22 SECTION 20 tools; SECTION 18/19 are core. `LEAN_TOOL_NAMES` gains `drawing_apply_standard`, `page_setup_apply`, `batch_plot`, `dimstyle_set_current`, `textstyle_set_current` (lean = 55). Alias records for all 38 (AutoCAD commands: `DIMSTYLE`, `DDIM`, `STYLE`, `MLEADERSTYLE`, `PAGESETUP`, `PLOT`, `PUBLISH`, `NEW`, `QNEW`, `SAVEAS`, `OPTIONS`, `DWGPROPS`, `LAYERSTATE`, `VIEW`, `UCS`, `UCSMAN`, `LIMITS`, `GRID`, `SNAP`, `ORTHO`, `UNITS`, `CANNOSCALE`, `SYSVAR`, `SETVAR`) and shop-floor synonyms; the discovery golden set gains ≥ 10 queries for them (`tests/test_discovery_transform.py` golden file). ### 8.3 Honesty rules specific to this track - A style or setting write is reported with `changed` (what moved) — re-setting a value to itself is not a change. - Page setup evidence is the PDF's own `/MediaBox`, read back. - Layer states are ours, not AutoCAD's; documented in three places (tool docstring, `system_capabilities`, README). - Nothing here starts interpreting coordinates in UCS. ## 9. Testing and evidence - Presets provenance: `tests/test_standards_presets.py` asserts every ISO-25 / ANSI value in §4.1 by name, every paper size against ISO 216 / ANSI Y14.1 (A0 841×1189 … A4 210×297; ANSI A 216×279 … E 864×1118), every catalog sysvar has type+meaning+engines. - Dual-engine tests for every tool (ezdxf real; COM fake-ActiveX asserting call shapes: `DimStyles.Add`, `TextStyles.Add`, `Dictionaries.Item("ACAD_MLEADERSTYLE").AddObject(name, "AcDbMLeaderStyle")`, `Layout.ConfigName/…`, `Documents.Item().Activate`, `Dictionaries.Add`+`AddXRecord`, `Views.Add`, `UserCoordinateSystems.Add`, `Preferences.OpenSave.*`, `SummaryInfo.*`, `Utility.GetPoint`). - Multi-document: two headless documents open, entity created in one is not in the other, activate switches, close-with-unsaved refuses, closing the last leaves "no document". - Layer states: save → change layers → restore → table equals snapshot; `missing_layers`/`new_layers` reported; the XRECORD survives save/reopen. - Page setup: apply ISO_A3 landscape → `batch_plot` → parsed `/MediaBox` is 420×297 mm (±0.5 mm at 72 dpi units); ANSI_B → 432×279. - Templates: `scripts/build_templates.py --check` proves the five DXFs are reproducible; `drawing_new(template="iso_a3_mech")` yields the mech layers, ISO-25 current, ISO_A3 page setup; a `.dwt` twin exists for each and opens on COM in the smoke. - `drawing_apply_standard("iso")` then `dimension_linear` → the DIMENSION carries DIMTXT 2.5 / DIMDSEP `,`; `"ansi"` → 3.0 / `.`. - Live COM smoke `scripts/smoke_settings_com.py`: styles, page setup + PDF mediabox, template `.dwt` open, layer state round trip, named view, UCS, preferences get (+ one reversible set), `SummaryInfo`, `system_prompt_message`; `user_pick_point` is exercised only if `--interactive` is passed (it needs the operator). Result recorded in the CHANGELOG. - Benchmark v4 gains `page_setup_truth` (`benchmarks/tasks_v4.py`, the same v3→v4 rule: competitors `not run`); correctness suite +3 (`settings_dimstyle_iso25_values`, `settings_layer_state_roundtrip`, `settings_pdf_mediabox_a3`). - Docs: CLAUDE.md sections 18–20 + packs, README rows + config table (`TOOL_PACKS=settings`), CHANGELOG `Unreleased`. ## 10. Milestones (input to the plan) 0. Track A hardening (7 fixes + backlog file) — independent, parallel wave. 1. `engineering/standards/` data modules + provenance tests (pure). 2. Styles contract + both engines + SECTION 18 tools. 3. Settings facade growth + `system_variable_describe` + properties. 4. Page setup + plot style list + batch_plot with mediabox read-back. 5. Templates: build script, bundled DXF, catalog, `drawing_new(template=)`, `drawing_template_save`; `.dwt` twins from the live machine. 6. Multi-document on both engines (+ `drawing_close` alignment). 7. Layer states, named views, UCS. 8. Launch, preferences, interactive tools, capability keys. 9. Packs/lean/aliases/golden queries, benchmark + correctness, live smoke, docs, gates. Groups 2, 4, 6+7 touch disjoint modules and get their own SECTIONs, so the plan runs them in parallel worktrees (the Track A wave-1 pattern) and a merge agent regenerates the three count files (`docs/tool-inventory.json`, README snapshot line, `tests/test_tool_registry.py`) after merging.