GameCult.Geometry.Csg/docs/brush-tree-map.md
Meta Vens 49948c8b80 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 <noreply@anthropic.com>
2026-10-10 21:57:45 +02:00

32 lines
6.9 KiB
Markdown

# 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 <script>`) | The script's content hash, recorded in the intent and the receipt. | Executed at most once as one undo step. The script is not stored by Brokkr. | Admission (allowed-action list, sink enabled) decides. Blender executes. Default admission: proposed Defaulted ruling. |
| **Agent-command enable flag (Blender)** | One per Blender project or file, echoed in the snapshot. | Off by default. Toggled only by the operator. | The operator only (Unity F5 carried over). |
| **Transport and auth material** | Q `blender-transport`. | Q `blender-transport`. | Q `blender-transport`. |
| **Blender projection objects** (lowered-mesh object, brush proxies) | A custom property holding tree key plus brush id. | Rebuilt from the revision. An operator edit to a proxy, such as a gizmo move, becomes a proposed tree commit through the bridge. Edits to the lowered-mesh object are never read back. | The bridge projects them. The tree commit decides. |
| **Tripo source mesh** | Its Blender object in the `Source` collection. | Read-only for the loop (I14). | The operator, and Aetheria's add-on. |
| **Shipped hull geometry** (Aetheria ship `.cc`) | Aetheria's existing package keys. | Written by Package from the Blender object (I15). | Aetheria's Package. Whether the lowered mesh enters Blender first: proposed Defaulted ruling. |
| **Impostor atlas** (far LOD) | `(tree key, revision)`. | Derived from the lowered mesh and materials, not from SDF marching. Whether built here: Q `impostor-scope`. | Whichever campaign builds it. Not this one, if recommended. |
| **In-game rebuild** | Q `bake-or-runtime`. | Q `bake-or-runtime`. | Q `bake-or-runtime`. |