|
| 1 | +# Metadata Property Liveness & Necessity Audit |
| 2 | + |
| 3 | +A protocol-level audit of **every ObjectStack metadata type**: for each schema property, cross-reference its spec definition against its **actual consumers** (`file:line`) in the runtime and renderers, to answer two questions in order — **(1) does the property take effect?** and **(2) is it necessary / reasonable?** |
| 4 | + |
| 5 | +Liveness is judged by **code consumption**, not browser observation (an unreactive UI can't distinguish "dead property" from "data didn't trigger it"). "DEAD" = parsed but read by no non-spec/non-test consumer → a **silent no-op** for authors. |
| 6 | + |
| 7 | +## Per-type reports |
| 8 | +| Type | Doc | Health | |
| 9 | +|---|---|---| |
| 10 | +| field | `2026-06-fieldschema-property-liveness.md` | ~half dead | |
| 11 | +| object | `2026-06-objectschema-property-liveness.md` | ~half dead | |
| 12 | +| view | `2026-06-viewschema-property-liveness.md` | list-family healthy; chart/form-variants broken | |
| 13 | +| app | `2026-06-appschema-property-liveness.md` | nav core healthy; aspirational tail | |
| 14 | +| page | `2026-06-pageschema-property-liveness.md` | drift breaks layouts | |
| 15 | +| dashboard | `2026-06-dashboardschema-property-liveness.md` | ADR-0021 half-done | |
| 16 | +| report | `2026-06-reportschema-property-liveness.md` | dataset live; chart dead | |
| 17 | +| dataset | `2026-06-datasetschema-property-liveness.md` | live; Studio under-covers | |
| 18 | +| action | `2026-06-actionschema-property-liveness.md` | disabled-CEL ignored; form/shortcut dead | |
| 19 | +| flow | `2026-06-flowschema-property-liveness.md` | enum out of sync; runAs unenforced | |
| 20 | +| agent | `2026-06-agentschema-property-liveness.md` | autonomy + access-control aspirational | |
| 21 | +| tool | `2026-06-toolschema-property-liveness.md` | **write-only metadata** | |
| 22 | +| skill | `2026-06-skillschema-property-liveness.md` | triggerPhrases display-only | |
| 23 | +| hook | `2026-06-hookschema-property-liveness.md` | **healthy** (near-total) | |
| 24 | +| validation | `2026-06-validationschema-property-liveness.md` | **healthy** (all 6 types enforced) | |
| 25 | +| security/identity (role, permission, policy, sharing) | `2026-06-security-identity-property-liveness.md` | **policy 100% dead** | |
| 26 | +| system/integration (email/i18n/theme/job/webhook/portal) | `2026-06-system-integration-property-liveness.md` | email + portal dead | |
| 27 | + |
| 28 | +## Cross-cutting patterns (in priority order) |
| 29 | + |
| 30 | +### 1. 🔴 Parsed-but-UNENFORCED security props (latent access-control gaps) |
| 31 | +The most serious cluster — properties that imply a security boundary but enforce nothing: |
| 32 | +- **PolicySchema** — 100% dead (password complexity, session timeout, `forceMfa`, IP allow-list, audit retention); not even registered. better-auth's hardcoded defaults govern. **False compliance.** |
| 33 | +- **Permission `allowTransfer`/`allowRestore`/`allowPurge`** — destructive ops (transfer, undelete, GDPR purge) not gated by RBAC. |
| 34 | +- **Agent `permissions`/`visibility`/`access`** — "who can chat with this agent" is a no-op (route hardcodes `['ai:chat','ai:agents']`). |
| 35 | +- **Flow `runAs`** — never switches execution identity. |
| 36 | +- **Object `apiEnabled`/`apiMethods`** — not enforced by REST (object can't be hidden from the API). |
| 37 | +- **Action `disabled`** (CEL form) — silently ignored (renderer reads non-spec `enabled`). |
| 38 | +- **Role `parent`** / **SharingRuleSchema** — manager rollup & spec sharing rules disconnected from the live engine. |
| 39 | + |
| 40 | +### 2. 🔴 ADR-0021 analytics migration debt |
| 41 | +Spec moved to `dataset`+`values`/`dimensions`, but: the **chart view variant** + **dashboard renderer + Studio WidgetConfigPanel** still read the *removed* legacy `object/valueField/categoryField/aggregate` shape; **report `chart`** is dead; `ReportColumn`/`ReportGrouping` are obsolete re-exports. (Same debt that invalidated the showcase dashboard/report seeds.) |
| 42 | + |
| 43 | +### 3. 🟠 Naming drift → silent no-ops (spec key ≠ consumed key) |
| 44 | +field `maxLength`/`minLength`/`referenceFilters`/`maxRating`; page `type`→`pageType` & `label`→`title` & `visibility`; dashboard `title` vs `label`; app `accentColor`/`badgeVariant`/`separator` (renderer reads, **not in spec**); action `disabled`→`enabled`; flow `http` vs `http_request`; skill `requiredPermissions` vs `permissions`; agent `knowledge.{topics→sources}`; webhook `object`→`object_name`, `isActive`→`active`. |
| 45 | + |
| 46 | +### 4. 🟠 Aspirational config (rich spec, zero runtime) — prune or mark `experimental` |
| 47 | +field enhanced-type configs (barcode/qr/slider/rating/color/location) + governance (encryption/masking/audit/dataQuality); object `enable`/versioning/partitioning/cdc/softDelete/search; agent autonomy (memory/guardrails/structuredOutput/lifecycle); tool `outputSchema`; job `retryPolicy`/`timeout`; theme rtl/density/touchTarget; translation `messageFormat:'icu'` (no ICU engine); **portal (entire)**; webhook non-HMAC auth. |
| 48 | + |
| 49 | +### 5. 🟠 Write-only / disconnected metadata (type implies authorability it lacks) |
| 50 | +**tool** (write-only projection — can't author a working tool as metadata); **EmailTemplateSchema** (registered, but runtime reads differently-shaped `sys_email_template`); **SharingRuleSchema** (runtime uses `sys_sharing_rule`); **spec-bridge** page/dashboard bridges orphaned (their exclusive props dead). |
| 51 | + |
| 52 | +### 6. Inverse drift — renderer depends on UNDECLARED props |
| 53 | +dashboard `component`/`data`/`rowField`/`columnField`; view `ObjectView` form-adapter keys; app `accentColor`/`badgeVariant`/`separator`. These break a strict `Schema.parse()`. |
| 54 | + |
| 55 | +### 7. Designer authoring gaps (live prop, no Studio editor) |
| 56 | +dataset `filter`/`format`/`derived`/`dateGranularity`; skill `triggerConditions` (the activation-critical field); flow `notify` (absent from static palette). |
| 57 | + |
| 58 | +## Healthiest vs worst |
| 59 | +- **Healthiest** (near-total liveness, model schemas): **hook**, **validation**. |
| 60 | +- **Worst**: **policy** (100% dead), **portal** (100% dead), **tool** (write-only). |
| 61 | + |
| 62 | +## Suggested ADRs |
| 63 | +1. **Security enforcement** (cluster #1) — highest priority; either enforce or remove every parsed-but-unenforced security prop. |
| 64 | +2. **Finish ADR-0021** (cluster #2) — migrate chart/dashboard/report renderers + Studio off the legacy inline shape. |
| 65 | +3. **Spec hygiene** (clusters #3–#7) — normalize naming drift, prune aspirational config, reconcile write-only/disconnected types, declare the undeclared-but-read props, close designer authoring gaps. |
0 commit comments