Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/26257-archive-2026-06-liveness-audits.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@objectstack/spec': patch
---

docs(spec): the liveness ledger's `_note` paths follow eleven closed 2026-06 audits into `docs/audits/archive/2026-06/`

Clause-②: no
Metadata-protocol: none

The `_note` of `liveness/{action,agent,dashboard,field,flow,hook,object,report,skill,tool,view}.json` named its seeding audit as `docs/audits/2026-06-<type>schema-property-liveness.md`. Those audits are closed and now live under `docs/audits/archive/2026-06/`, so each note names the new path, and `liveness/README.md` says where the series sits. No status, evidence or accepted shape changes: only the path text inside notes moves.
2 changes: 1 addition & 1 deletion docs/audits/2026-06-record-search-liveness.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Record search is a **declared-but-unenforced** capability (cf. ADR-0049). `$sear
- `object.searchable` boolean (`object.zod.ts:52`) — consumed by metadata-admin UI + the command-palette object gate; **not** the data layer.
- `object.search` (`SearchConfigSchema`, `object.zod.ts:113`) — `fields`/`displayFields`/`filters`; **no runtime consumer**.
- `view.searchableFields` (`view.zod.ts:522`) — UI input control + ListView; not the data layer.
- field-level `searchable` — **DEAD** (per `2026-06-fieldschema-property-liveness.md`).
- field-level `searchable` — **DEAD** (per `archive/2026-06/2026-06-fieldschema-property-liveness.md`).

## 4. Lookup search (objectui) — sends `$search`, gets a no-op
- `LookupField.tsx:311` / `RecordPickerDialog.tsx:451` — bare `$search`. The picker "works" visually only because datasets are tiny; there is **no server filtering**.
Expand Down
26 changes: 14 additions & 12 deletions docs/audits/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,29 @@

> **Lifecycle of a file in `docs/audits/`:** an audit is *open* while its findings are being worked and *closed* once each one is fixed, ruled out or carried into a tracked ledger or issue; a closed audit moves to `docs/audits/archive/`, and git history keeps every version.

> **Closed but kept in place:** a closed audit that an ADR cites by path stays where it is, because ADRs are append-only and a move would leave a dead link in their text. So does one cited by path from a published `CHANGELOG.md`, which is release-owned. In the 2026-06 series that holds `2026-06-handwritten-docs-accuracy-followups`, `2026-06-metadata-functional-completeness`, `2026-06-react-blocks-conformance`, `2026-06-react-tier-authoring-dogfood`, `2026-06-record-search-liveness` and `2026-06-security-identity-property-liveness` (ADR-cited), and `2026-06-appschema-property-liveness`, `2026-06-dead-surface-disposition-plan` and `2026-06-validationschema-property-liveness` (cited from `packages/spec/CHANGELOG.md`).

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?**

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.

## Per-type reports
| Type | Doc | Health |
|---|---|---|
| field | `2026-06-fieldschema-property-liveness.md` | ~half dead |
| object | `2026-06-objectschema-property-liveness.md` | ~half dead |
| view | `2026-06-viewschema-property-liveness.md` | list-family healthy; chart/form-variants broken |
| field | `archive/2026-06/2026-06-fieldschema-property-liveness.md` | ~half dead |
| object | `archive/2026-06/2026-06-objectschema-property-liveness.md` | ~half dead |
| view | `archive/2026-06/2026-06-viewschema-property-liveness.md` | list-family healthy; chart/form-variants broken |
| app | `2026-06-appschema-property-liveness.md` | nav core healthy; aspirational tail |
| page | `archive/2026-06/2026-06-pageschema-property-liveness.md` | drift breaks layouts |
| dashboard | `2026-06-dashboardschema-property-liveness.md` | ADR-0021 half-done |
| report | `2026-06-reportschema-property-liveness.md` | dataset live; chart dead |
| dashboard | `archive/2026-06/2026-06-dashboardschema-property-liveness.md` | ADR-0021 half-done |
| report | `archive/2026-06/2026-06-reportschema-property-liveness.md` | dataset live; chart dead |
| dataset | `archive/2026-06/2026-06-datasetschema-property-liveness.md` | live; Studio under-covers |
| action | `2026-06-actionschema-property-liveness.md` | disabled-CEL ignored; form/shortcut dead |
| flow | `2026-06-flowschema-property-liveness.md` | enum out of sync; runAs unenforced |
| agent | `2026-06-agentschema-property-liveness.md` | autonomy + access-control aspirational |
| tool | `2026-06-toolschema-property-liveness.md` | **write-only metadata** |
| skill | `2026-06-skillschema-property-liveness.md` | triggerPhrases display-only |
| hook | `2026-06-hookschema-property-liveness.md` | **healthy** (near-total) |
| action | `archive/2026-06/2026-06-actionschema-property-liveness.md` | disabled-CEL ignored; form/shortcut dead |
| flow | `archive/2026-06/2026-06-flowschema-property-liveness.md` | enum out of sync; runAs unenforced |
| agent | `archive/2026-06/2026-06-agentschema-property-liveness.md` | autonomy + access-control aspirational |
| tool | `archive/2026-06/2026-06-toolschema-property-liveness.md` | **write-only metadata** |
| skill | `archive/2026-06/2026-06-skillschema-property-liveness.md` | triggerPhrases display-only |
| hook | `archive/2026-06/2026-06-hookschema-property-liveness.md` | **healthy** (near-total) |
| validation | `2026-06-validationschema-property-liveness.md` | **healthy** (all 6 types enforced) |
| security/identity (role, permission, policy, sharing) | `2026-06-security-identity-property-liveness.md` | **policy 100% dead** |
| system/integration (email/i18n/theme/job/webhook/portal) | `archive/2026-06/2026-06-system-integration-property-liveness.md` | email + portal dead |
Expand All @@ -44,7 +46,7 @@ The most serious cluster — properties that imply a security boundary but enfor
### 2. 🔴 ADR-0021 analytics migration debt
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. (Same debt that invalidated the showcase dashboard/report seeds.)

**✅ Report slice resolved (#3463 + 2026-07 close-out).** `report.chart` is **wired** (`DatasetReportRenderer` plots `chart.xAxis`/`yAxis` via `DatasetReportChart`, now dogfooded by the showcase `…_chart` report); `ReportColumn`/`ReportGrouping` (+ objectui `SpecReport*` re-exports) and the unread `chart.groupBy` + dead `aria`/`performance` are **removed**; the legacy `ReportViewer` chart fallback is **retired**. See [`2026-06-reportschema-property-liveness.md`](./2026-06-reportschema-property-liveness.md). The **chart-view / dashboard / WidgetConfigPanel** legacy-shape readers above remain open.
**✅ Report slice resolved (#3463 + 2026-07 close-out).** `report.chart` is **wired** (`DatasetReportRenderer` plots `chart.xAxis`/`yAxis` via `DatasetReportChart`, now dogfooded by the showcase `…_chart` report); `ReportColumn`/`ReportGrouping` (+ objectui `SpecReport*` re-exports) and the unread `chart.groupBy` + dead `aria`/`performance` are **removed**; the legacy `ReportViewer` chart fallback is **retired**. See [`2026-06-reportschema-property-liveness.md`](./archive/2026-06/2026-06-reportschema-property-liveness.md). The **chart-view / dashboard / WidgetConfigPanel** legacy-shape readers above remain open.

### 3. 🟠 Naming drift → silent no-ops (spec key ≠ consumed key)
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`.
Expand Down
3 changes: 2 additions & 1 deletion packages/spec/liveness/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ For a metadata-driven platform, **the spec is the product surface**: authors wri
metadata against these schemas. A property that is parsed but has no runtime consumer
is a silent no-op — and for a *security* property, a silent no-op is **false
compliance** (e.g. `forceMfa: true` accepted and ignored). The metadata-liveness audits
(`docs/audits/2026-06-*-property-liveness.md`) found that large swaths of the declared
(`docs/audits/archive/2026-06/2026-06-*-property-liveness.md`, with the three still cited
from an ADR or a changelog left in `docs/audits/`) found that large swaths of the declared
surface are DEAD.

This ledger makes that classification **explicit and regression-proof**: every property
Expand Down
2 changes: 1 addition & 1 deletion packages/spec/liveness/action.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"type": "action",
"_note": "ActionSchema. Seeded from docs/audits/2026-06-actionschema-property-liveness.md. Renderers live in objectui (evidence cited as prose, not framework paths); framework-side: service-ai action-tools, runtime body-runner/http-dispatcher. Containers (params/resultDialog/ai/aria) classified at top level — no divergent sub-statuses in the audit. ⚠ EVIDENCE LIVES IN CLOUD/EE: the `cloud @<sha>: packages/service-ai/...` paths cited below are the closed `@objectstack/service-ai` runtime in the CLOUD repo, NOT git-tracked framework code. 2026-08-30 (#13272): the previous wording of this sentence was false in BOTH halves. (a) It called the framework's own service-ai tree “a stale build artifact with no src/” — there is no tree at all: `packages/services/` holds every sibling service EXCEPT service-ai, and `git ls-files | grep -ic service-ai` returns 0. Absent, not stale. (b) The citations spelled `packages/services/service-ai/...`, a path present in NEITHER repo; cloud's real layout, measured at cloud@15f55df (commit c19035e97), is `packages/service-ai/...`. Every citation below now carries the explicit `cloud` realm marker, so it is attributed by the marker `scanEvidence` reads rather than riding the `FOREIGN_PATH_PREFIXES` special case that silently exempted the stale spelling from resolution — which is why 22 dead pointers sat green. ✅ RE-VERIFIED 2026-09-15 (#13272): the re-verification half this entry parked is discharged. All three cloud consumers cited below were re-read in a cloud checkout at cloud @cb8ee7ff60c097cc21a584fe9caf8ef4391cc0e8 and all three are CONFIRMED; every row now carries `verifiedAt`, `evidenceScope: cross-repo`, and `#symbol` anchors pinned to the consuming functions instead of a line number — the one cited line (`action-tools.ts:535`) had already drifted to 545 in a 961-line file that is actively edited. The anchors are the load-bearing half, and they are why the DATE matters: `scanEvidence` never collects an anchor while a foreign realm marker is in force, so CI cannot re-derive a single one of the cloud anchors — each rests on that dated reading alone. ⛔ Never re-stamp `verifiedAt` here without re-reading cloud; a bare re-stamp restores exactly the unfalsifiable pointer this entry's history is made of. These props are `live` because that cloud runtime consumes them; the OPEN framework edition does not — see content/docs/ai for the open/cloud boundary. 2026-07-30 (#3896 close-out sweep): the dead authoring keys were REMOVED — tombstoned at the schema with prescriptions (retiredKey) and stripped by the protocol-17 close-out conversions; entries deleted per the #3715 precedent.",
"_note": "ActionSchema. Seeded from docs/audits/archive/2026-06/2026-06-actionschema-property-liveness.md. Renderers live in objectui (evidence cited as prose, not framework paths); framework-side: service-ai action-tools, runtime body-runner/http-dispatcher. Containers (params/resultDialog/ai/aria) classified at top level — no divergent sub-statuses in the audit. ⚠ EVIDENCE LIVES IN CLOUD/EE: the `cloud @<sha>: packages/service-ai/...` paths cited below are the closed `@objectstack/service-ai` runtime in the CLOUD repo, NOT git-tracked framework code. 2026-08-30 (#13272): the previous wording of this sentence was false in BOTH halves. (a) It called the framework's own service-ai tree “a stale build artifact with no src/” — there is no tree at all: `packages/services/` holds every sibling service EXCEPT service-ai, and `git ls-files | grep -ic service-ai` returns 0. Absent, not stale. (b) The citations spelled `packages/services/service-ai/...`, a path present in NEITHER repo; cloud's real layout, measured at cloud@15f55df (commit c19035e97), is `packages/service-ai/...`. Every citation below now carries the explicit `cloud` realm marker, so it is attributed by the marker `scanEvidence` reads rather than riding the `FOREIGN_PATH_PREFIXES` special case that silently exempted the stale spelling from resolution — which is why 22 dead pointers sat green. ✅ RE-VERIFIED 2026-09-15 (#13272): the re-verification half this entry parked is discharged. All three cloud consumers cited below were re-read in a cloud checkout at cloud @cb8ee7ff60c097cc21a584fe9caf8ef4391cc0e8 and all three are CONFIRMED; every row now carries `verifiedAt`, `evidenceScope: cross-repo`, and `#symbol` anchors pinned to the consuming functions instead of a line number — the one cited line (`action-tools.ts:535`) had already drifted to 545 in a 961-line file that is actively edited. The anchors are the load-bearing half, and they are why the DATE matters: `scanEvidence` never collects an anchor while a foreign realm marker is in force, so CI cannot re-derive a single one of the cloud anchors — each rests on that dated reading alone. ⛔ Never re-stamp `verifiedAt` here without re-reading cloud; a bare re-stamp restores exactly the unfalsifiable pointer this entry's history is made of. These props are `live` because that cloud runtime consumes them; the OPEN framework edition does not — see content/docs/ai for the open/cloud boundary. 2026-07-30 (#3896 close-out sweep): the dead authoring keys were REMOVED — tombstoned at the schema with prescriptions (retiredKey) and stripped by the protocol-17 close-out conversions; entries deleted per the #3715 precedent.",
"props": {
"name": {
"status": "live",
Expand Down
Loading
Loading