From 49948c8b80380f3fef51e2ca6e67ec52618de781 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sat, 10 Oct 2026 21:57:45 +0200 Subject: [PATCH 01/29] Brush tree: campaign target and model page (Eureka step 0) The ends of the brush-tree campaign: OpenSCAD-shaped CSG trees authored in Blender through brokkr-ctl, with the typed brush tree as the one truth. Sixteen invariants, scope, canonical implementations, evidence, and the identity/lifecycle/authority table. No cut plan. Co-Authored-By: Claude Opus 5.5 --- docs/brush-tree-map.md | 32 +++++ docs/brush-tree-target.md | 256 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 288 insertions(+) create mode 100644 docs/brush-tree-map.md create mode 100644 docs/brush-tree-target.md diff --git a/docs/brush-tree-map.md b/docs/brush-tree-map.md new file mode 100644 index 0000000..7b9bdea --- /dev/null +++ b/docs/brush-tree-map.md @@ -0,0 +1,32 @@ +# Brush tree: map (model page: identity, lifecycle and authority) + +One row for each persistent or crossing kind. A cell this draft cannot settle +names the question that settles it (questions in the mind, campaign brush-tree). No cut is mapped until +those questions are answered. + +| Kind | What names it | What happens to it over time | Who decides | +|---|---|---|---| +| **Brush-tree document** (CultCache `.cc`, Geometry.Csg schema) | One document per ship hull. The key is the hull's asset id (store location and granularity: Q `tree-store`). | Created by the first commit. Each accepted commit replaces it and bumps a monotonic `revision`. It is never edited in place outside a commit. It is deleted only by the operator. | The commit primitive (I3) decides whether a change lands, by revision check. The operator and the model propose changes; neither writes around the commit. | +| **Branch node** (union, difference, intersection, and grouping `module` instances if kept) | Its name path within the tree, siblings unique (Q `brush-identity`). | Lives and dies with tree revisions. Ops apply to its children only (I6). | The tree commit. | +| **Parametric layer** (top-level parameters, module definitions, symmetry and relations) | Parameter name and module name, tree-scoped. | Whether it persists in the tree or is flattened at parse is Q `openscad-surface`. If kept, evaluation to brushes is derived per revision. | The tree commit. Fits propose values; the commit accepts them. | +| **Brush** (leaf: primitive, op, transform, params) | Q `brush-identity` (recommended: a stable minted id carried in the text as a named argument, plus a human name). | Created, edited and deleted only by tree commits. `generation` bumps on each edit, for dirty-frontier rebuilds. | The tree commit. A fitter or a Blender gizmo only proposes. | +| **Primitive vocabulary** (the set of primitive kinds and ops) | Kind name in the schema, matched to an OpenSCAD built-in where one exists. | Grows by schema version. A kind enters the authoring surface only when the polygon kernel and the field both honour it (I5). Which kinds: Q `vocabulary-growth`. | Geometry.Csg, through Hands cuts; the operator rules the set. | +| **Brush surface** (material, UV parameterisation, seam, smoothing, bevel or blend radius) | `(brush id, surface slot)`. Slots are fixed per primitive kind, e.g. cylinder side, top cap, bottom cap. | Exists while its brush exists, edited with it. A cut face takes one explicit policy (Q `cut-face-surface`). Seam placement per curved kind: Q `seam-policy`. UV channel meaning: Q `uv-channels`. | The brush (I7). Lowerings only evaluate it. | +| **Blend or bevel radius** | A surface or op argument on the brush (Q `bevel-operator`). | Edited with the brush. | The brush. Operator family and placement: Q `bevel-operator`. | +| **Authoring text** (OpenSCAD-shaped) | Not persisted as truth. A printed text carries a header naming the tree key and its base revision. | Printed on demand from a revision. Parsed back only through the commit primitive. A stale base is refused. It may be written to scratch for the model to edit, then discarded. | The printer derives it. The commit decides whether a parse lands. | +| **Lowered mesh** (triangles, normals, UVs, per-triangle brush and surface ids) | `(tree key, revision, LOD)`. | A cache, regenerated whenever the revision changes. Never edited and never read back (I8). | Geometry.Csg's lowering derives it. | +| **Field and bevel geometry** (SDF bound, smooth-blended cut strips) | Same as the lowered mesh. | Derived per revision. | Geometry.Csg's field (I4, I9). How bevels reach the mesh: Q `bevel-to-mesh`. | +| **Fit request and result** (primitive, parameters, residual, inlier set) | Not persisted. The `brokkr-ctl` call returns it; the receipt id is its only handle. | Ephemeral. Accepting a fit is a tree commit; the rejected ones vanish. | Fitter math computes it with I4's distance (location: Q `fitting-home`). The model and the operator decide acceptance. | +| **Selection read** (Edit Mode vertices and faces with world coordinates) | The receipt of the `selection` command. | Read live per call, never cached as truth. Written as a scratch file the receipt points to (format: Q `blender-transport`). | Blender owns selection. The bridge reports it. | +| **Viewport image** (`look`) | A file path printed by `brokkr-ctl`, named by command id. | Written per call to a Brokkr scratch directory, pruned by count, never kept as state. | Blender renders it. The bridge writes it. The retention cap is a proposed Defaulted ruling. | +| **Deviation heatmap** | `(tree key, revision, source mesh)`. | Derived per revision. Shown in Blender as a colour attribute on a projection copy, never on the source. | Geometry.Csg's distance (I4) computes it. The bridge displays it. | +| **Blender command intent** (`brokkr.blender.command_intent.v0`, extended: look, selection, fit, run, apply-tree) | Single-use `commandId` minted per act (Unity F6 carried over). | Written once by a caller, executed at most once, never rewritten. | Callers write it. The bridge alone decides execution, after admission. | +| **Blender command receipt** (`brokkr.blender.command_receipt.v0`) | Keyed by `commandId`. | Written once by the bridge. Pruned by the cap rule Unity already uses. | The bridge alone. The `brokkr-ctl` exit code derives from its status. | +| **Run script** (`brokkr-ctl blender run