From ca198eaa23cd77df1f78ec60d354dc051a7f6eff Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 1 Sep 2026 10:21:12 +0000 Subject: [PATCH] docs(plugin-detail): record the downstream-consumer census for PointInTimeRestore objectui#7163 measured zero IN-REPO consumers for the barrel-exported `PointInTimeRestore`. That is not the same claim as zero consumers, because the component is published public API, so this records the downstream reading instead. hotcrm, measured at a6be39a3d by anonymous shallow clone: zero on every spelling (case/separator-insensitive, named import, type import, lazy import, kebab and snake type strings), against a positive control of 104 plugin-detail node references resolved in that same repo on that same instrument. It is also structurally unreachable there -- hotcrm has zero @object-ui imports and PointInTimeRestore is never registered with ComponentRegistry, so a metadata app has no type string to name it with. cloud is reported as NOT MEASURED: refused on three independent channels, two of them beside a live control in the same command. Bonus, at no marginal cost: PointInTimeRestore is one of seven plugin-detail barrel exports that are neither registered nor mounted anywhere in this repo, so it is the visible instance of a class rather than an isolate. No source, behaviour, or public-surface change. Retires nothing. --- .changeset/7175-downstream-consumer-census.md | 16 ++ ...lugin-detail-downstream-consumer-census.md | 194 ++++++++++++++++++ 2 files changed, 210 insertions(+) create mode 100644 .changeset/7175-downstream-consumer-census.md create mode 100644 docs/audits/2026-09-plugin-detail-downstream-consumer-census.md diff --git a/.changeset/7175-downstream-consumer-census.md b/.changeset/7175-downstream-consumer-census.md new file mode 100644 index 0000000000..329ae19621 --- /dev/null +++ b/.changeset/7175-downstream-consumer-census.md @@ -0,0 +1,16 @@ +--- +--- + +Docs-only: records the downstream-consumer census for +`@object-ui/plugin-detail`'s `PointInTimeRestore` as +`docs/audits/2026-09-plugin-detail-downstream-consumer-census.md` (objectui#7175). + +objectui#7163 measured that the component has zero *in-repo* consumers. That is not the +same statement as zero consumers, because it is barrel-exported public API, so this audit +reads the downstream populations instead: `hotcrm` measured at `a6be39a3d` (zero on every +spelling, against a positive control of 104 `plugin-detail` node references in the same +repo on the same instrument), and `cloud` reported as **NOT MEASURED** — refused on three +independent channels, two of them beside a live control. + +No source, behaviour, or public-surface change; the audit records evidence so the +ADR-0049 enforce-or-remove question can be decided later. It deliberately retires nothing. diff --git a/docs/audits/2026-09-plugin-detail-downstream-consumer-census.md b/docs/audits/2026-09-plugin-detail-downstream-consumer-census.md new file mode 100644 index 0000000000..e6f9973762 --- /dev/null +++ b/docs/audits/2026-09-plugin-detail-downstream-consumer-census.md @@ -0,0 +1,194 @@ +# Audit: downstream consumer census — `PointInTimeRestore` and the `plugin-detail` barrel (2026-09) + +**Question** (objectui#7175): does anything *outside this repo* render +`@object-ui/plugin-detail`'s `PointInTimeRestore`? + +**Why it exists**: objectui#7163 / PR #7172 measured that `PointInTimeRestore` has **zero +in-repo consumers** — barrel-exported only, no mount point anywhere in `objectui`. That +measurement was correct but it is *not* the question ADR-0049 enforce-or-remove needs +answered, because **"zero in-repo consumers" is not "zero consumers."** The component is +published public API; a downstream application may render it. This audit takes the +reading the in-repo one could not. + +**Populations**: `objectstack-ai/hotcrm`, `objectstack-ai/cloud`. + +⛔ **This audit does not retire anything.** Retiring a published component is +ADR-0049 / ADR-0087 (objectstack) and narrows public surface. This is the measurement that +makes that decision *possible*, not the decision. + +--- + +## Summary + +| Population | Channel | Positive control | `PointInTimeRestore` | Verdict | +| --- | --- | --- | --- | --- | +| `objectui` (in-repo, re-confirmed) | local worktree @ `899730e0a` | `RecordComments` mounted 2x in `DetailView.tsx` | 0 mounts | unrendered here (confirms #7163) | +| `hotcrm` @ `a6be39a3d` | anonymous shallow git clone | **HIT** — 104 `plugin-detail` node references | **0 on every spelling** | **zero — measured** | +| `cloud` | none reachable | n/a | n/a | ⚠️ **NOT MEASURED** | + +**Headline**: no measured consumer, anywhere, renders `PointInTimeRestore` — and in +`hotcrm` it is not merely absent, it is **structurally unreachable** (see below). One +population, `cloud`, could not be read at all and is reported as its own category. + +⚠️ **NOT MEASURED is not zero and not green.** `cloud` is unread, not clean. + +--- + +## Channel evidence + +Each clone's exit code was captured **before any pipe**, beside a same-shape control. + +| Command | Exit | Reading | +| --- | --- | --- | +| `git clone --depth 1 .../hotcrm.git` | **0** | 828 tracked files at `a6be39a3d` | +| `git clone --depth 1 .../objectui.git` (control) | **0** | 6039 tracked files at `899730e0a` | +| `git clone --depth 1 .../cloud.git` | **128** | `could not read Username` — auth wall | +| `git ls-remote .../cloud.git` | **128** | same wall, second command shape | +| `git ls-remote .../hotcrm.git` (control) | **0** | refs listed | +| session repo-attach for `cloud` | error | `you don't have access to objectstack-ai/cloud` | + +`cloud` was refused on **three independent channels**, two of which returned a live +control in the same breath. It is unreadable from this seat, not empty. + +--- + +## The reachability argument — stronger than the grep + +`hotcrm` is a **metadata application**. It declares UI as JSON-ish metadata rendered by +objectui; it does **not** import objectui as a library: + +- `@object-ui/*` appears in exactly **3** `hotcrm` files, and all three are **prose + comments** (`crm.app.ts:169`, `account_detail.page.ts:32`, + `scripts/analytics-reconcile/macros.ts:5`). +- Real imports of any `@object-ui` package: **0**. `hotcrm`'s `package.json` depends on + `@objectstack/*` only. + +So the only channel by which `hotcrm` can reach an objectui component is a **registered +component type string** in metadata. And: + +> `PointInTimeRestore` is **never** passed to `ComponentRegistry.register`. `plugin-detail` +> makes 16 registrations; none of them is this component. There is no auto-registration — +> no `Object.entries(...)`/`forEach(register)` pattern exists in the barrel (0 hits). + +⇒ `PointInTimeRestore` **has no type string**, so a metadata app cannot name it. The zero +below is therefore not a lucky grep; it is what the architecture requires. + +--- + +## The `hotcrm` reading + +**Positive control — same repo, same instrument, same channel** (`plugin-detail` +components that `hotcrm` actually mounts): + +| Node type | References in `hotcrm` | +| --- | --- | +| `record:details` | 31 | +| `record:related_list` | 21 | +| `record:highlights` | 17 | +| `record:activity` | 16 | +| `record:path` | 12 | +| `record:chatter` | 4 | +| `record:history` | 3 | +| **total** | **104** | + +The instrument resolves 104 references to *this very package* in *this very repo*. It is +productive here, so a zero from it is a reading. + +**Target — every spelling, all zero:** + +| Spelling probed | Hits in `hotcrm` | Same probe in `objectui` (control) | +| --- | --- | --- | +| `point[-_ ]?in[-_ ]?time[-_ ]?restore`, case-insensitive | **0** | 26 | +| `PointInTimeRestore` exact identifier | **0** | 26 | +| `PointInTimeRestoreProps` | **0** | 3 | +| `RevisionEntry` (the co-exported type) | **0** | 5 | +| loose `point[-_ ]?in[-_ ]?time` | **0** | 30 | +| `import(...PointInTime...)` lazy form | **0** | 0 | +| `plugin-detail` package specifier | **0** | 870 | + +The separator/case-insensitive pattern covers named import, namespace member, re-export, +kebab (`point-in-time-restore`), snake (`point_in_time_restore`) and camel spellings in +one shot. **The identical pattern set returns 26 hits in `objectui`** — the probes fire. + +**Every semantic near-miss attributed.** One hit for `snapshot.*restore`: +`test/forecast-manual-override.test.ts:279` — *"deleting the manual row restores automated +snapshotting"*. Forecast snapshots, unrelated to revision history. Not a render. + +Non-zero hits for sibling *identifiers* (`DetailSection` 4, `CommentInput` 3, and so on) +were each read: all are prose comments, test docstrings, or `@objectstack/spec/ui` type +names such as `RecordRelatedListProps`. Since `hotcrm` has zero objectui imports, none can +be a render. + +--- + +## Bonus: `PointInTimeRestore` is not an isolate + +Once the instrument answers "is X reachable", it answers it for X's siblings for free. Of +`plugin-detail`'s **29** component-shaped barrel exports, **7** are neither registered +(no metadata type string) nor mounted anywhere in this repo: + +| Unregistered **and** unmounted | Registered? | In-repo mounts | +| --- | --- | --- | +| `CommentInput` | no | 0 | +| `DiffView` | no | 0 | +| `InlineCreateRelated` | no | 0 | +| `MentionAutocomplete` | no | 0 | +| **`PointInTimeRestore`** | no | 0 | +| `RecordNavigationEnhanced` | no | 0 | +| `RelationshipGraph` | no | 0 | + +None of the seven has a dynamic reference either (`React.lazy`, `createElement`, or a +string literal of its own name): 0 for all seven. + +⇒ `PointInTimeRestore` is the **visible instance of a seven-member class**, not a one-off. +That is the difference between one retirement card and an enforce-or-remove ledger. This +audit does not act on the other six; it records them. + +⚠️ Unmounted is **not** the same as unreachable-and-dead. `RecordComments` is also +unregistered, yet `DetailView` mounts it directly at `:1479` and `:1705` — a component can +be perfectly live through a sibling's JSX without ever having a type string. The class +above is specifically *both* doors closed. + +--- + +## Method — re-runnable, and its one recorded failure + +Deliberately **not committed as a test**: it clones external repositories, so it cannot +run in CI, and a committed test that cannot run renders as coverage while measuring +nothing (objectui#7183). It is recorded here instead, to be re-run by hand. + +```bash +git clone --depth 1 https://github.com/objectstack-ai/hotcrm.git /tmp/hotcrm # exit BEFORE any pipe +# controls first, target second; every count printed as an integer, never blank +grep -rIF --exclude-dir=.git 'record:details' /tmp/hotcrm | wc -l # expect > 0 +grep -rIE --exclude-dir=.git -i 'point[-_ ]?in[-_ ]?time[-_ ]?restore' /tmp/hotcrm | wc -l +``` + +⚠️ **Two instrument traps, both hit during this audit.** + +1. `git grep -c` prints **nothing**, not `0`, on no match. Every count above is piped + through `wc -l` so a zero is always a printed integer. +2. The in-repo mount probe first used `]` and reported **0 mounts for + `RecordComments`** — a component known to be mounted twice. Cause: grep is + line-oriented and these JSX tags end the line (`])`, which returns the expected 2. **The whole sibling table was + re-derived after the fix and gated on that control passing.** A probe that cannot see + its own known-positive is not measuring. + +Counts are from `main` at audit time — a baseline, not a frozen census. + +--- + +## What this audit does NOT claim + +- ⛔ Not that `PointInTimeRestore` should be retired. That is ADR-0049 / ADR-0087, it + narrows public surface, and it is a decision this audit only makes *possible*. +- ⛔ Not that `cloud` is clean. `cloud` is **unread**. +- ⛔ Not that the other six unmounted exports are dead. They are unmounted and + unregistered *here*; they have had no downstream census of their own. +- ⛔ Not that PR #7172's i18n sweep was wrong. It was reviewed and upheld. + +Refs: objectui#7175 (this census) · objectui#7163 / PR #7172 (the in-repo measurement and +the sweep) · objectui#7183 (why this is not a committed test) · objectstack ADR-0049, +ADR-0087.