Estimate: 60m · Depends on: 2.7.2
Make the taxonomy structural. Add to prisma/schema.prisma the fields 2.7.2 froze, with a clean migration and the default helper the picker + loader both consume. 4-layer (motir-core/CLAUDE.md): the enum + columns are Prisma; the default helper is a pure lib/issues/* function; any read/write of the new fields flows Route → Service → Repository.
enum WorkItemType — the ten members exactly as 2.7.2 fixed (code, design, test, content, research, review, decision, deploy, manual, chore).enum Executor — coding_agent, human.work_item.type WorkItemType? — NULLABLE (epics/stories + legacy rows = null). Leaf-only is a SEMANTIC rule the service enforces (see below), not a DB constraint a column can express; the column itself is simply nullable.work_item.executor Executor? — nullable; set alongside type (seeded from the default map when a type is chosen).lib/issues/executorDefaults.ts — a pure defaultExecutorForType(type: WorkItemType): Executor encoding 2.7.2’s map exactly (a TOTAL function over the enum — no default branch hole), plus isLeafType-style guards. This is the SINGLE source the picker (2.7.4) + the loader (2.7.5) call — neither re-states the map.workItemsService (the write authority): reject (typed error) any attempt to set type/executor on an epic/story kind; allow it on task/subtask/bug. Keep it a service validation (the kind-parent grammar already lives there), not a trigger.Migration hygiene (motir-core/CLAUDE.md § migrations). The new columns are plain nullable enum columns — no FK — so no @relation concern; but run prisma migrate dev and confirm "No difference detected" on a second run (no drift). The enums + columns must be authored in schema.prisma (not raw-SQL-only) so the schema graph + the migration-built DB stay in sync.
prisma/schema.prisma declares enum WorkItemType (the ten members) + enum Executor + nullable work_item.type + work_item.executor; pnpm prisma migrate dev applies cleanly and a second migrate dev reports no drift.lib/issues/executorDefaults.ts exports a TOTAL defaultExecutorForType over every enum member matching 2.7.2’s map exactly (verified by 2.7.7).workItemsService rejects setting type/executor on an epic/story with a typed error, and permits it on task/subtask/bug; the 4-layer split is respected (route → service → repository → Prisma; the write goes through workItemsService, never raw Prisma in a route).motir-core/prisma/schema.prisma — the work_item model + the existing kind enum (the sibling axis type is distinct from).motir-core/lib/services/workItemsService.ts — the write authority where leaf-only enforcement lives.motir-core/lib/issues/parentRules.ts — the existing pure lib/issues/* rule module the default helper sits beside.motir-core/CLAUDE.md § 4-layer + § migrations.