Repository navigation
feat: edit plate contours vertex by vertex (A12.3) - #751
Merged
Blogbotana merged 1 commit intoOct 30, 2026
Merged
Blogbotana merged 1 commit into
Blogbotana merged 1 commit into
Conversation
Blogbotana
previously approved these changes
Oct 30, 2026
* feat: edit plate contours vertex by vertex (A12.3) The A12.3 prerequisite (atomic --corners replacement) could only retype the whole sparse list; editing a contour after creation meant rewriting it from scratch. This delivers the amendment's five editing commands on top of that replacement: move-plate-vertex, move-plate-edge, insert-plate-vertex, delete-plate-vertex and set-plate-corner. The engine part is the pure contour_edit module: each edit maps the authored contour and its sparse corner list to the edited pair, remapping treatment positions after an insertion or deletion and carrying the deleted vertex's treatment away. UpdateElement grows a complete contour_points_mm replacement (fingerprinted append-only, so earlier patch fingerprints are unchanged); the CLI commits each edit as one shape-changing contour + corners patch through the existing update path, so the kernel revalidates the new contour, every hole and cut replays, a linked definition group updates atomically and the revision is one undo unit. delete-plate-vertex refuses on a three-vertex contour whatever the caller asks; invalid geometry refuses before publication. keep_degenerate (P-Degenerate) remains outstanding. * fix: separate the contour-edits help segment from the next one Completes the plate-contour editing remainder of #520. Co-authored-by: axisrow <[email protected]>
axisrow
force-pushed
the
ao/fork-sync-upstream/upstream-a12-3-solo
branch
from
October 30, 2026 20:30
04cefe0 to
73fd64d
Compare
Blogbotana
approved these changes
Oct 30, 2026
axisrow
added a commit
to axisrow/BeamCraft
that referenced
this pull request
Oct 31, 2026
…d the wave-one registry integration (#345) * feat: deliver I04 user attributes, the expanded Q01 alpha story and C04 acceptance fixes (Apibim-com#748) * feat: deliver I04 user attributes, the expanded Q01 alpha story and C04 acceptance fixes Typed user attributes (I04): attribute definitions and values on any element across model, engine, layer engine and CLI, stored in USD, unknown attributes never dropped. Expanded Q01 alpha story: a real-binary end-to-end scenario with its coverage matrix. C03-C06 acceptance rows marked executable with the corrected C04-09 cap; the document arrives in its fork state, overlapping the open C03/C06 pull request that carries its new coordinator and compensation tests. * bug: reject control characters in an attribute-set name AttrDef::validate checked only the length of a set name, the one free-text field admitted without the label rule, so a raw newline or other control byte could ride into the USDA string through bim:attr:set. The check now refuses bytes up to U+001F and DEL, like unit labels, option strings and text values, and the design card and the adversarial suite say so. --------- Co-authored-by: axisrow <[email protected]> * feat: rebase the workspace draft through the coordinator (C03) (Apibim-com#749) The coordinator wire gains a `rebase` operation and the CLI a `coordinator-rebase` client, so a client no longer needs a separate local `rebase-workspace` process between publications: the same guarded local rebase runs server-side with the token-derived actor as the only trusted actor, never moves the published head, and replays one request identity across both entry points and crash windows. Acceptance C03-R01..C03-R08 runs against a real `serve-coordinator` process with real token files (`apps/beamcraft-cli/tests/coordinator_rebase.rs`). The transport needed a host-side conversion from the validated model id of the authenticated actor. It deliberately takes the validated `beamcraft_model::id::Uuid7` instead of raw bytes: a constructor from unchecked bytes would hand out a `Uuid7` that `Uuid7::parse` rejects and break the invariant every persisted id relies on (review finding on the combined C03/C06 delivery, Apibim-com#737). A round-trip unit test pins the conversion. Compensation (C06) is not part of this change: per that review, compensating a published version is an administrator-only action that needs the post-MVP roles-and-permissions model, so it stays deferred. Co-authored-by: axisrow <[email protected]> * refactor: add a single CLI command registry and a `commands` listing (Apibim-com#754) * feat: schedule the verified head through attribute templates (I05) (Apibim-com#750) * docs: design I05 schedules on the shared BOM and filter layers * feat: schedule the verified head through attribute templates (I05) Schedules by attributes: a declarative schedule template renders the verified head — the same read `export-bom` uses — through columns from standard report fields and typed user attributes (I04), one optional element filter, grouping and totals, into CSV and HTML. The engine part is pure computation (template and typed neutral CellValue rows in, sorted element table and group table out, CSV and HTML rendering, the filter evaluator), the CLI decodes the template against the pinned I04 attribute state and `schedule-export` writes the files with the E03 atomic discipline. Unknown and stale values are shown, never zeroed or dropped; identical inputs render byte-identical files. * fix: quote schedule CSV headers and bound the template read Fixes #532 Co-authored-by: axisrow <[email protected]> * feat: edit plate contours vertex by vertex (A12.3) (Apibim-com#751) * feat: build fastener geometry prototypes (A14.2) (Apibim-com#752) * feat: build fastener geometry prototypes (A14.2) One fastener prototype from a pinned FastenerSpec — head, shank, optional nut and washers as separate closed meshes, hex and round polygons to the 0.05 mm chord rule (vertex count a multiple of four), no threads, no chamfers — plus per-component counts, volumes and mass with its source shown for a group of n fasteners. beamcraft_kernel::fastener builds the components in stack order from the bearing face as sealed G05 extrusions with exact volumes, mesh digests and chord-rule provenance; the definition is re-admitted and refused builds produce nothing. beamcraft_engine::fastener maps kernel refusals to command fields and computes the group quantities in the P-Mass pattern (a declared mass is never split, per-component masses are never invented, an unknown density stays unknown). The headless `fastener-geometry` command reads the library, never a store, and prints the component rows and group totals with `mass_source`. The geometry is derived, nothing new is stored: SCHEMA_DESCRIPTOR is untouched and A14.1 stores stay valid. * fix: count the shank-through-head overlap once and keep the profile codes Fixes #522 Co-authored-by: axisrow <[email protected]> * Give a new model its environment so beams and columns can be placed at once (Apibim-com#755) A new model had no profile or material definitions and the window only lists the model's definitions, so no beam or column could be placed. The environment chosen on the start window was only a saved setting. - Add the built-in `starter` environment (nineteen generic, invented profiles) and prefer it on the start window over the empty `blank`. - `create-project --environment ID` copies the environment into the project folder and publishes two default materials, so the project carries its environment and needs no option or setting afterwards. - `--profile NAME` of create-member, create-polybeam and create-curved-beam defines the profile from the project's environment on first use; `definitions` lists the rest as `environment_profiles` and the window offers them in the profile picker. - Allow an exactly zero density: `Steel_Undefined` is the massless material of auxiliary parts with a known mass of 0 kg, unlike an unknown density. Negative densities and underflowing products are still refused. * Amend F04 and F06: a material density may be zero (Apibim-com#756) * Let a placed member change its profile, in the CLI and in the window (Apibim-com#757) A member's profile could only be chosen when it was created, and the properties panel showed it as text, so a wrong section meant placing the member again. - ElementPatch gains a profile; the engine treats it as a shape change, rebuilds the body and the mass, and refuses it on a plate. - update-element takes --profile NAME or --profile-digest; a name is resolved in the model and then in the project's environment, as for create-member. The existing layer-engine profile change repins the canonical part, so parts that share a definition follow it. - The properties panel offers the model's and the environment's profiles for a beam or column and applies the choice with update-element. * refactor: dispatch CLI commands from the registry and list access and parameters (slices 2-3 of Apibim-com#753) (Apibim-com#760) * refactor: dispatch CLI commands from the registry (second slice of Apibim-com#753) The binary chose an adapter with a chain of `c == "..."` comparisons in main.rs plus a `handles()` function per adapter, a second hand-kept inventory that could drift from the registry. Each registry entry now names its adapter (`Route`), and main.rs matches on `registry::route(word)`. A word that is not registered cannot reach an adapter and takes the store-level path, which refuses it as before, so a command that is dispatched but unregistered is no longer possible. The per-adapter `handles()` functions are removed. Behaviour, exit codes and output of existing commands are unchanged. * test: wait for the dropped rebase request before the retry The coordinator answers each connection on its own thread, so in lost_answers_and_a_killed_server_replay_exactly_once the retry could overtake the request whose client was dropped and do the merge itself, answering workspace_rebased instead of workspace_rebase_replayed. It failed once on the ubuntu CI runner. Wait until the draft head moves, which happens when the dropped request has merged, before sending the retry. * refactor: list access and parameters of every CLI command (third slice of Apibim-com#753) `beamcraft commands` now carries, for every command, whether it reads or writes (Access) and its options: value shape, whether it is required and, for alternatives, a one_of group. The five common request identity options are listed on the commands that take them (Ids::Common) instead of being repeated in 125 entries. The data was taken from each adapter's allow-list and required checks, not from the help prose; where they differ (for example update-element --corners and --axis-point, create-grid, create-plate --material) the code wins. A rule that links optional options (--width with --length) stays in the family help. Tests: the listing carries access and parameters; an unlisted option is refused as unknown (so the probe is valid); every listed option is accepted by its command, which fails if a listed name is wrong or removed. --------- Co-authored-by: Yury Isachenkov <[email protected]> * docs: generate the CLI command reference from the registry (slice 7 of Apibim-com#753, first part) (Apibim-com#761) COMMANDS.md renders every command from the registry as one usage line (required options bare, optional ones in brackets, one-of groups in parentheses) with its family, tier and access. A test fails when the committed file differs from the generated text, and BEAMCRAFT_BLESS=1 rewrites it, so the reference cannot drift from `beamcraft commands`. The README is not shortened yet: it carries rules and examples that the registry does not hold. Also lists three options the adapters accept but the registry missed: update-element --profile and --profile-digest (added by Apibim-com#757) and create-project --environment (added by Apibim-com#755). The "listed option is accepted" test cannot see an omission, so every undeclared sibling option was probed once by hand; no other command accepts an unlisted option except the shared drawing allow-list and a few options that are accepted and ignored or refused later. Co-authored-by: Yury Isachenkov <[email protected]> * docs: interactive-assist features need no CLI command (Apibim-com#762) An agent builds a model by giving coordinates and ids directly, so cursor picking and snapping and the start screen (settings, environments, project-name suggestion, recent projects) do not need a CLI command. Narrow the headless-first rule in AGENTS.md section 3 to features an agent or script needs, and record the decision. The CLI commands themselves are removed in a separate change; the engine APIs stay for the window. Co-authored-by: Yury Isachenkov <[email protected]> * refactor: remove the interactive-assist CLI commands and the tier (slices 4-5 of Apibim-com#753) (Apibim-com#764) An agent builds a model by giving coordinates and ids directly, so the CLI no longer needs cursor picking, snapping or the start screen. Remove pick, snap, show-settings, set-settings, list-environment, suggest-project-name, list-recent and add-recent (owner decision of 2026-10-31, see AGENTS.md section 3). The engine and host functions behind them stay. list-feature, lookup-feature, element-edges and work-plane stay: preview-drawing takes a feature id. With no ui-assist command left, the tier is empty information: drop `Tier`, the `tier` field of `commands` and `commands --tier`. The window still runs pick and the settings commands as a child process, so its start screen, theme persistence and click selection are broken until Apibim-com#763 moves it to the engine; the six UI tests that need them are ignored with that issue's number. The CLI tests of the removed commands are deleted (construction_snaps.rs, the pick and snap tests, the settings tests) or cut down to the commands that remain. The agent skill and the design notes no longer present them. Co-authored-by: Yury Isachenkov <[email protected]> * docs: point the CLI README at the generated command reference (slice 7 of Apibim-com#753) (Apibim-com#765) The README repeated a usage block for most commands. They had drifted (create-plate and update-element lacked many options the commands take) and the generated COMMANDS.md now states them from the registry, with a test that keeps it current. Replace each usage block with a link to the command's entry there; the rules, examples and acceptance notes of each section stay. The one worked example (define-profile then create-member with concrete values) stays too. Co-authored-by: Yury Isachenkov <[email protected]> * Keep the fork's pick and snap commands through the sync: T02's acceptance and the window drive them, so the fork's copy of the registry contract test drops their removal spot-check * Document the snap construction and grid switches and restore the construction snap acceptance suite the registry test spot-check had buried * Regenerate the command reference with the annotation entries --------- Co-authored-by: axisrow <[email protected]> Co-authored-by: Yuri Isachenkov <[email protected]> Co-authored-by: Yury Isachenkov <[email protected]>
axisrow
added a commit
to axisrow/BeamCraft
that referenced
this pull request
Oct 31, 2026
… the #345 squash (#348) * feat: deliver I04 user attributes, the expanded Q01 alpha story and C04 acceptance fixes (Apibim-com#748) * feat: deliver I04 user attributes, the expanded Q01 alpha story and C04 acceptance fixes Typed user attributes (I04): attribute definitions and values on any element across model, engine, layer engine and CLI, stored in USD, unknown attributes never dropped. Expanded Q01 alpha story: a real-binary end-to-end scenario with its coverage matrix. C03-C06 acceptance rows marked executable with the corrected C04-09 cap; the document arrives in its fork state, overlapping the open C03/C06 pull request that carries its new coordinator and compensation tests. * bug: reject control characters in an attribute-set name AttrDef::validate checked only the length of a set name, the one free-text field admitted without the label rule, so a raw newline or other control byte could ride into the USDA string through bim:attr:set. The check now refuses bytes up to U+001F and DEL, like unit labels, option strings and text values, and the design card and the adversarial suite say so. --------- Co-authored-by: axisrow <[email protected]> * feat: rebase the workspace draft through the coordinator (C03) (Apibim-com#749) The coordinator wire gains a `rebase` operation and the CLI a `coordinator-rebase` client, so a client no longer needs a separate local `rebase-workspace` process between publications: the same guarded local rebase runs server-side with the token-derived actor as the only trusted actor, never moves the published head, and replays one request identity across both entry points and crash windows. Acceptance C03-R01..C03-R08 runs against a real `serve-coordinator` process with real token files (`apps/beamcraft-cli/tests/coordinator_rebase.rs`). The transport needed a host-side conversion from the validated model id of the authenticated actor. It deliberately takes the validated `beamcraft_model::id::Uuid7` instead of raw bytes: a constructor from unchecked bytes would hand out a `Uuid7` that `Uuid7::parse` rejects and break the invariant every persisted id relies on (review finding on the combined C03/C06 delivery, Apibim-com#737). A round-trip unit test pins the conversion. Compensation (C06) is not part of this change: per that review, compensating a published version is an administrator-only action that needs the post-MVP roles-and-permissions model, so it stays deferred. Co-authored-by: axisrow <[email protected]> * refactor: add a single CLI command registry and a `commands` listing (Apibim-com#754) * feat: schedule the verified head through attribute templates (I05) (Apibim-com#750) * docs: design I05 schedules on the shared BOM and filter layers * feat: schedule the verified head through attribute templates (I05) Schedules by attributes: a declarative schedule template renders the verified head — the same read `export-bom` uses — through columns from standard report fields and typed user attributes (I04), one optional element filter, grouping and totals, into CSV and HTML. The engine part is pure computation (template and typed neutral CellValue rows in, sorted element table and group table out, CSV and HTML rendering, the filter evaluator), the CLI decodes the template against the pinned I04 attribute state and `schedule-export` writes the files with the E03 atomic discipline. Unknown and stale values are shown, never zeroed or dropped; identical inputs render byte-identical files. * fix: quote schedule CSV headers and bound the template read Fixes #532 Co-authored-by: axisrow <[email protected]> * feat: edit plate contours vertex by vertex (A12.3) (Apibim-com#751) * feat: build fastener geometry prototypes (A14.2) (Apibim-com#752) * feat: build fastener geometry prototypes (A14.2) One fastener prototype from a pinned FastenerSpec — head, shank, optional nut and washers as separate closed meshes, hex and round polygons to the 0.05 mm chord rule (vertex count a multiple of four), no threads, no chamfers — plus per-component counts, volumes and mass with its source shown for a group of n fasteners. beamcraft_kernel::fastener builds the components in stack order from the bearing face as sealed G05 extrusions with exact volumes, mesh digests and chord-rule provenance; the definition is re-admitted and refused builds produce nothing. beamcraft_engine::fastener maps kernel refusals to command fields and computes the group quantities in the P-Mass pattern (a declared mass is never split, per-component masses are never invented, an unknown density stays unknown). The headless `fastener-geometry` command reads the library, never a store, and prints the component rows and group totals with `mass_source`. The geometry is derived, nothing new is stored: SCHEMA_DESCRIPTOR is untouched and A14.1 stores stay valid. * fix: count the shank-through-head overlap once and keep the profile codes Fixes #522 Co-authored-by: axisrow <[email protected]> * Give a new model its environment so beams and columns can be placed at once (Apibim-com#755) A new model had no profile or material definitions and the window only lists the model's definitions, so no beam or column could be placed. The environment chosen on the start window was only a saved setting. - Add the built-in `starter` environment (nineteen generic, invented profiles) and prefer it on the start window over the empty `blank`. - `create-project --environment ID` copies the environment into the project folder and publishes two default materials, so the project carries its environment and needs no option or setting afterwards. - `--profile NAME` of create-member, create-polybeam and create-curved-beam defines the profile from the project's environment on first use; `definitions` lists the rest as `environment_profiles` and the window offers them in the profile picker. - Allow an exactly zero density: `Steel_Undefined` is the massless material of auxiliary parts with a known mass of 0 kg, unlike an unknown density. Negative densities and underflowing products are still refused. * Amend F04 and F06: a material density may be zero (Apibim-com#756) * Let a placed member change its profile, in the CLI and in the window (Apibim-com#757) A member's profile could only be chosen when it was created, and the properties panel showed it as text, so a wrong section meant placing the member again. - ElementPatch gains a profile; the engine treats it as a shape change, rebuilds the body and the mass, and refuses it on a plate. - update-element takes --profile NAME or --profile-digest; a name is resolved in the model and then in the project's environment, as for create-member. The existing layer-engine profile change repins the canonical part, so parts that share a definition follow it. - The properties panel offers the model's and the environment's profiles for a beam or column and applies the choice with update-element. * refactor: dispatch CLI commands from the registry and list access and parameters (slices 2-3 of Apibim-com#753) (Apibim-com#760) * refactor: dispatch CLI commands from the registry (second slice of Apibim-com#753) The binary chose an adapter with a chain of `c == "..."` comparisons in main.rs plus a `handles()` function per adapter, a second hand-kept inventory that could drift from the registry. Each registry entry now names its adapter (`Route`), and main.rs matches on `registry::route(word)`. A word that is not registered cannot reach an adapter and takes the store-level path, which refuses it as before, so a command that is dispatched but unregistered is no longer possible. The per-adapter `handles()` functions are removed. Behaviour, exit codes and output of existing commands are unchanged. * test: wait for the dropped rebase request before the retry The coordinator answers each connection on its own thread, so in lost_answers_and_a_killed_server_replay_exactly_once the retry could overtake the request whose client was dropped and do the merge itself, answering workspace_rebased instead of workspace_rebase_replayed. It failed once on the ubuntu CI runner. Wait until the draft head moves, which happens when the dropped request has merged, before sending the retry. * refactor: list access and parameters of every CLI command (third slice of Apibim-com#753) `beamcraft commands` now carries, for every command, whether it reads or writes (Access) and its options: value shape, whether it is required and, for alternatives, a one_of group. The five common request identity options are listed on the commands that take them (Ids::Common) instead of being repeated in 125 entries. The data was taken from each adapter's allow-list and required checks, not from the help prose; where they differ (for example update-element --corners and --axis-point, create-grid, create-plate --material) the code wins. A rule that links optional options (--width with --length) stays in the family help. Tests: the listing carries access and parameters; an unlisted option is refused as unknown (so the probe is valid); every listed option is accepted by its command, which fails if a listed name is wrong or removed. --------- Co-authored-by: Yury Isachenkov <[email protected]> * docs: generate the CLI command reference from the registry (slice 7 of Apibim-com#753, first part) (Apibim-com#761) COMMANDS.md renders every command from the registry as one usage line (required options bare, optional ones in brackets, one-of groups in parentheses) with its family, tier and access. A test fails when the committed file differs from the generated text, and BEAMCRAFT_BLESS=1 rewrites it, so the reference cannot drift from `beamcraft commands`. The README is not shortened yet: it carries rules and examples that the registry does not hold. Also lists three options the adapters accept but the registry missed: update-element --profile and --profile-digest (added by Apibim-com#757) and create-project --environment (added by Apibim-com#755). The "listed option is accepted" test cannot see an omission, so every undeclared sibling option was probed once by hand; no other command accepts an unlisted option except the shared drawing allow-list and a few options that are accepted and ignored or refused later. Co-authored-by: Yury Isachenkov <[email protected]> * docs: interactive-assist features need no CLI command (Apibim-com#762) An agent builds a model by giving coordinates and ids directly, so cursor picking and snapping and the start screen (settings, environments, project-name suggestion, recent projects) do not need a CLI command. Narrow the headless-first rule in AGENTS.md section 3 to features an agent or script needs, and record the decision. The CLI commands themselves are removed in a separate change; the engine APIs stay for the window. Co-authored-by: Yury Isachenkov <[email protected]> * refactor: remove the interactive-assist CLI commands and the tier (slices 4-5 of Apibim-com#753) (Apibim-com#764) An agent builds a model by giving coordinates and ids directly, so the CLI no longer needs cursor picking, snapping or the start screen. Remove pick, snap, show-settings, set-settings, list-environment, suggest-project-name, list-recent and add-recent (owner decision of 2026-10-31, see AGENTS.md section 3). The engine and host functions behind them stay. list-feature, lookup-feature, element-edges and work-plane stay: preview-drawing takes a feature id. With no ui-assist command left, the tier is empty information: drop `Tier`, the `tier` field of `commands` and `commands --tier`. The window still runs pick and the settings commands as a child process, so its start screen, theme persistence and click selection are broken until Apibim-com#763 moves it to the engine; the six UI tests that need them are ignored with that issue's number. The CLI tests of the removed commands are deleted (construction_snaps.rs, the pick and snap tests, the settings tests) or cut down to the commands that remain. The agent skill and the design notes no longer present them. Co-authored-by: Yury Isachenkov <[email protected]> * docs: point the CLI README at the generated command reference (slice 7 of Apibim-com#753) (Apibim-com#765) The README repeated a usage block for most commands. They had drifted (create-plate and update-element lacked many options the commands take) and the generated COMMANDS.md now states them from the registry, with a test that keeps it current. Replace each usage block with a link to the command's entry there; the rules, examples and acceptance notes of each section stay. The one worked example (define-profile then create-member with concrete values) stays too. Co-authored-by: Yury Isachenkov <[email protected]> --------- Co-authored-by: axisrow <[email protected]> Co-authored-by: Yuri Isachenkov <[email protected]> Co-authored-by: Yury Isachenkov <[email protected]>
axisrow
added a commit
to axisrow/BeamCraft
that referenced
this pull request
Oct 31, 2026
…upstream Apibim-com#748-Apibim-com#765 (#356) * feat: deliver I04 user attributes, the expanded Q01 alpha story and C04 acceptance fixes (Apibim-com#748) * feat: deliver I04 user attributes, the expanded Q01 alpha story and C04 acceptance fixes Typed user attributes (I04): attribute definitions and values on any element across model, engine, layer engine and CLI, stored in USD, unknown attributes never dropped. Expanded Q01 alpha story: a real-binary end-to-end scenario with its coverage matrix. C03-C06 acceptance rows marked executable with the corrected C04-09 cap; the document arrives in its fork state, overlapping the open C03/C06 pull request that carries its new coordinator and compensation tests. * bug: reject control characters in an attribute-set name AttrDef::validate checked only the length of a set name, the one free-text field admitted without the label rule, so a raw newline or other control byte could ride into the USDA string through bim:attr:set. The check now refuses bytes up to U+001F and DEL, like unit labels, option strings and text values, and the design card and the adversarial suite say so. --------- Co-authored-by: axisrow <[email protected]> * feat: rebase the workspace draft through the coordinator (C03) (Apibim-com#749) The coordinator wire gains a `rebase` operation and the CLI a `coordinator-rebase` client, so a client no longer needs a separate local `rebase-workspace` process between publications: the same guarded local rebase runs server-side with the token-derived actor as the only trusted actor, never moves the published head, and replays one request identity across both entry points and crash windows. Acceptance C03-R01..C03-R08 runs against a real `serve-coordinator` process with real token files (`apps/beamcraft-cli/tests/coordinator_rebase.rs`). The transport needed a host-side conversion from the validated model id of the authenticated actor. It deliberately takes the validated `beamcraft_model::id::Uuid7` instead of raw bytes: a constructor from unchecked bytes would hand out a `Uuid7` that `Uuid7::parse` rejects and break the invariant every persisted id relies on (review finding on the combined C03/C06 delivery, Apibim-com#737). A round-trip unit test pins the conversion. Compensation (C06) is not part of this change: per that review, compensating a published version is an administrator-only action that needs the post-MVP roles-and-permissions model, so it stays deferred. Co-authored-by: axisrow <[email protected]> * refactor: add a single CLI command registry and a `commands` listing (Apibim-com#754) * feat: schedule the verified head through attribute templates (I05) (Apibim-com#750) * docs: design I05 schedules on the shared BOM and filter layers * feat: schedule the verified head through attribute templates (I05) Schedules by attributes: a declarative schedule template renders the verified head — the same read `export-bom` uses — through columns from standard report fields and typed user attributes (I04), one optional element filter, grouping and totals, into CSV and HTML. The engine part is pure computation (template and typed neutral CellValue rows in, sorted element table and group table out, CSV and HTML rendering, the filter evaluator), the CLI decodes the template against the pinned I04 attribute state and `schedule-export` writes the files with the E03 atomic discipline. Unknown and stale values are shown, never zeroed or dropped; identical inputs render byte-identical files. * fix: quote schedule CSV headers and bound the template read Fixes #532 Co-authored-by: axisrow <[email protected]> * feat: edit plate contours vertex by vertex (A12.3) (Apibim-com#751) * feat: build fastener geometry prototypes (A14.2) (Apibim-com#752) * feat: build fastener geometry prototypes (A14.2) One fastener prototype from a pinned FastenerSpec — head, shank, optional nut and washers as separate closed meshes, hex and round polygons to the 0.05 mm chord rule (vertex count a multiple of four), no threads, no chamfers — plus per-component counts, volumes and mass with its source shown for a group of n fasteners. beamcraft_kernel::fastener builds the components in stack order from the bearing face as sealed G05 extrusions with exact volumes, mesh digests and chord-rule provenance; the definition is re-admitted and refused builds produce nothing. beamcraft_engine::fastener maps kernel refusals to command fields and computes the group quantities in the P-Mass pattern (a declared mass is never split, per-component masses are never invented, an unknown density stays unknown). The headless `fastener-geometry` command reads the library, never a store, and prints the component rows and group totals with `mass_source`. The geometry is derived, nothing new is stored: SCHEMA_DESCRIPTOR is untouched and A14.1 stores stay valid. * fix: count the shank-through-head overlap once and keep the profile codes Fixes #522 Co-authored-by: axisrow <[email protected]> * Give a new model its environment so beams and columns can be placed at once (Apibim-com#755) A new model had no profile or material definitions and the window only lists the model's definitions, so no beam or column could be placed. The environment chosen on the start window was only a saved setting. - Add the built-in `starter` environment (nineteen generic, invented profiles) and prefer it on the start window over the empty `blank`. - `create-project --environment ID` copies the environment into the project folder and publishes two default materials, so the project carries its environment and needs no option or setting afterwards. - `--profile NAME` of create-member, create-polybeam and create-curved-beam defines the profile from the project's environment on first use; `definitions` lists the rest as `environment_profiles` and the window offers them in the profile picker. - Allow an exactly zero density: `Steel_Undefined` is the massless material of auxiliary parts with a known mass of 0 kg, unlike an unknown density. Negative densities and underflowing products are still refused. * Amend F04 and F06: a material density may be zero (Apibim-com#756) * Let a placed member change its profile, in the CLI and in the window (Apibim-com#757) A member's profile could only be chosen when it was created, and the properties panel showed it as text, so a wrong section meant placing the member again. - ElementPatch gains a profile; the engine treats it as a shape change, rebuilds the body and the mass, and refuses it on a plate. - update-element takes --profile NAME or --profile-digest; a name is resolved in the model and then in the project's environment, as for create-member. The existing layer-engine profile change repins the canonical part, so parts that share a definition follow it. - The properties panel offers the model's and the environment's profiles for a beam or column and applies the choice with update-element. * refactor: dispatch CLI commands from the registry and list access and parameters (slices 2-3 of Apibim-com#753) (Apibim-com#760) * refactor: dispatch CLI commands from the registry (second slice of Apibim-com#753) The binary chose an adapter with a chain of `c == "..."` comparisons in main.rs plus a `handles()` function per adapter, a second hand-kept inventory that could drift from the registry. Each registry entry now names its adapter (`Route`), and main.rs matches on `registry::route(word)`. A word that is not registered cannot reach an adapter and takes the store-level path, which refuses it as before, so a command that is dispatched but unregistered is no longer possible. The per-adapter `handles()` functions are removed. Behaviour, exit codes and output of existing commands are unchanged. * test: wait for the dropped rebase request before the retry The coordinator answers each connection on its own thread, so in lost_answers_and_a_killed_server_replay_exactly_once the retry could overtake the request whose client was dropped and do the merge itself, answering workspace_rebased instead of workspace_rebase_replayed. It failed once on the ubuntu CI runner. Wait until the draft head moves, which happens when the dropped request has merged, before sending the retry. * refactor: list access and parameters of every CLI command (third slice of Apibim-com#753) `beamcraft commands` now carries, for every command, whether it reads or writes (Access) and its options: value shape, whether it is required and, for alternatives, a one_of group. The five common request identity options are listed on the commands that take them (Ids::Common) instead of being repeated in 125 entries. The data was taken from each adapter's allow-list and required checks, not from the help prose; where they differ (for example update-element --corners and --axis-point, create-grid, create-plate --material) the code wins. A rule that links optional options (--width with --length) stays in the family help. Tests: the listing carries access and parameters; an unlisted option is refused as unknown (so the probe is valid); every listed option is accepted by its command, which fails if a listed name is wrong or removed. --------- Co-authored-by: Yury Isachenkov <[email protected]> * docs: generate the CLI command reference from the registry (slice 7 of Apibim-com#753, first part) (Apibim-com#761) COMMANDS.md renders every command from the registry as one usage line (required options bare, optional ones in brackets, one-of groups in parentheses) with its family, tier and access. A test fails when the committed file differs from the generated text, and BEAMCRAFT_BLESS=1 rewrites it, so the reference cannot drift from `beamcraft commands`. The README is not shortened yet: it carries rules and examples that the registry does not hold. Also lists three options the adapters accept but the registry missed: update-element --profile and --profile-digest (added by Apibim-com#757) and create-project --environment (added by Apibim-com#755). The "listed option is accepted" test cannot see an omission, so every undeclared sibling option was probed once by hand; no other command accepts an unlisted option except the shared drawing allow-list and a few options that are accepted and ignored or refused later. Co-authored-by: Yury Isachenkov <[email protected]> * docs: interactive-assist features need no CLI command (Apibim-com#762) An agent builds a model by giving coordinates and ids directly, so cursor picking and snapping and the start screen (settings, environments, project-name suggestion, recent projects) do not need a CLI command. Narrow the headless-first rule in AGENTS.md section 3 to features an agent or script needs, and record the decision. The CLI commands themselves are removed in a separate change; the engine APIs stay for the window. Co-authored-by: Yury Isachenkov <[email protected]> * refactor: remove the interactive-assist CLI commands and the tier (slices 4-5 of Apibim-com#753) (Apibim-com#764) An agent builds a model by giving coordinates and ids directly, so the CLI no longer needs cursor picking, snapping or the start screen. Remove pick, snap, show-settings, set-settings, list-environment, suggest-project-name, list-recent and add-recent (owner decision of 2026-10-31, see AGENTS.md section 3). The engine and host functions behind them stay. list-feature, lookup-feature, element-edges and work-plane stay: preview-drawing takes a feature id. With no ui-assist command left, the tier is empty information: drop `Tier`, the `tier` field of `commands` and `commands --tier`. The window still runs pick and the settings commands as a child process, so its start screen, theme persistence and click selection are broken until Apibim-com#763 moves it to the engine; the six UI tests that need them are ignored with that issue's number. The CLI tests of the removed commands are deleted (construction_snaps.rs, the pick and snap tests, the settings tests) or cut down to the commands that remain. The agent skill and the design notes no longer present them. Co-authored-by: Yury Isachenkov <[email protected]> * docs: point the CLI README at the generated command reference (slice 7 of Apibim-com#753) (Apibim-com#765) The README repeated a usage block for most commands. They had drifted (create-plate and update-element lacked many options the commands take) and the generated COMMANDS.md now states them from the registry, with a test that keeps it current. Replace each usage block with a link to the command's entry there; the rules, examples and acceptance notes of each section stay. The one worked example (define-profile then create-member with concrete values) stays too. Co-authored-by: Yury Isachenkov <[email protected]> --------- Co-authored-by: axisrow <[email protected]> Co-authored-by: Yuri Isachenkov <[email protected]> Co-authored-by: Yury Isachenkov <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
A12.3, plate contour editing commands: the five contour-editing commands of the accepted F04
plate amendment (section 3), on top of the already-delivered atomic
--cornersreplacement(#281). This is the remainder of the A12.3 work — the prerequisite slice landed, the editing
commands below did not (#520 was closed at the prerequisite).
beamcraft-engine::contour_edit, new): pure functionsmove_vertex,move_edge,insert_vertex,delete_vertex,set_corner— each maps the authored contourand its sparse corner list to the edited pair. Insertions and deletions remap treatment
positions; the deleted vertex's treatment goes with it; an inserted vertex is sharp;
set_cornerreplaces, clears (sharp/none) or inserts one treatment in vertex order.Indices are admitted by position (decision O-1); points are admitted finite and within the
coordinate cap; a three-vertex contour is never reduced (
INVALID_ARGUMENT, fieldcontour_points_mm).ElementPatch.contour_points_mm— a complete contour replacement, validated like acreated contour (count, finiteness, caps) and fingerprinted append-only
(
A12.3/contour-patch/v1), so fingerprints of earlier patches are unchanged.edit.rs): a contour patch is a shape patch; it is authored asChange::Contouron the canonical definition (next to
Thickness/Corners) and applied to the linkeddefinition group in the same revision.
move-plate-vertex,move-plate-edge,insert-plate-vertex,delete-plate-vertex,set-plate-corner): each reads the head plate, applies the engine edit and commits throughthe existing
update_elementpath — so the kernel revalidates the new contour (winding,simplicity, holes, cuts, treated corners), a linked group follows, and each edit is one
revision and one undo unit. Retry follows the documented
UpdateElementcontract, decidedfrom the head state. Help text updated.
keep_degenerate/recovery (P-Degenerate) remains outstanding: invalid geometry refuses, as for
every update today. No UI acceptance is claimed (V18 calls these commands).
Design note:
docs/design/a12-3-corner-edits.md.How you verified it
cargo fmt --all -- --checkcargo clippy --workspace --all-targets -- -D warningscargo nextest run --workspace(1909 passed on this branch)cargo test --workspace --doc, wasm32 check of the pure crates — all greenNew behaviour is tested: engine unit tests (index and finiteness refusals, treatment
carry-over, index remapping after insert/delete, triangle floor, set/clear/replace ordering),
update.rstests (a contour patch is a shape change, validates the contour+corners pair, amember refuses the field) and the e2e suite
plate_contour_edits.rs(real binary): amendmentcase 6 (delete gives a triangle, insert then move gives a pentagon, an edge move changes
exactly its two end vertices, closed-form volumes), treatment carry-over and remapping over
edits, negative cases 3–6 (collinear corner, delete on a triangle, self-crossing bowtie, hole
left outside) plus malformed/out-of-range/non-finite arguments and a member target — each
refusal leaves the store byte-identical; linked instance group updates atomically; immediate
retry replays; op-id reuse refuses; undo/redo round-trips.
Never-crash
unwrap/expect/panic!/todo!outside testsunsafeProvenance
ATTRIBUTION.mdentriesKnown risks / follow-ups
OP_ID_REUSE— thedocumented update-element family behaviour, kept here on purpose.
Anything a reviewer should look at first
The contour patch is authored as one complete replacement (not a delta) so the append-only
fingerprint chain of earlier patches never changes — worth a second look against the
UpdateElementreplay contract.