@ai-matrx/records-ui 0.44.0 → 0.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,152 @@
1
1
  # Changelog — @ai-matrx/records-ui
2
2
 
3
+ ## 0.48.0
4
+
5
+ **The record panel says when it could not read the footnote.**
6
+
7
+ `@ai-matrx/records` 0.33.0 stops `custom.computed_provenance` — a door a person's
8
+ seat cannot call — from failing the whole record read, which is what told Cedar
9
+ Ridge Dental's own owner "You do not have access to this" above a record that
10
+ loaded everywhere else. This is the visible half: `Peek` says, in one line, that
11
+ it could not read which columns the system worked out for itself, instead of
12
+ leaving an empty space that means either "nothing is worked out here" or "nobody
13
+ could look" and never says which.
14
+
15
+ Needs `@ai-matrx/records` >= 0.33.0 for `RecordRead.computedUnavailable`; on an
16
+ older one the line simply never appears.
17
+
18
+ **Consumer action:** none.
19
+
20
+ ## 0.47.0
21
+
22
+ Carries 0.45.0 and 0.46.0, neither of which reached npm: the publish of 0.45.0
23
+ failed on a live clause that had gone stale under a store change (see the last
24
+ item), and 0.46.0 was cut behind it.
25
+
26
+ **A refusal with two remedies, one of them wrong.**
27
+
28
+ A plumbing company wants to give ONE customer view access to the jobs table her
29
+ work is on. She has an account; she is not in their organization.
30
+ `custom.share_grant` refuses, and it refuses WELL — measured verbatim on the live
31
+ store: *"That person is not in this organization, so they cannot be given access
32
+ to this table yet."*, with three ways forward in its hint: invite them, share
33
+ with their organization instead, or — if they are a client rather than a
34
+ colleague — put them in a portal.
35
+
36
+ The screen threw all of that away, in three separate ways, all of them in
37
+ `plainWords.ts` and all of them fixed here:
38
+
39
+ 1. **Two remedies, one wrong.** The formatter printed the door's ways forward AND
40
+ then its own table's *"Change the value so it passes, then try again"*, which
41
+ is not a thing anybody can do about a membership. A person follows the last
42
+ sentence they read. The DOOR's hint is the remedy now whenever it survives the
43
+ machine-identity filter; the table is the fallback it always should have been.
44
+ 2. **One footnote binned the sentence around it.** The hint's human half carried
45
+ `(VIS-23)`, so the whole clause was judged machine identity and dropped — which
46
+ is why the plumber got no remedy at all. A bracketed contract id is a
47
+ footnote: it is lifted out, the sentence is kept, and the id still reaches the
48
+ engineer.
49
+ 3. **The cleaner re-wrote a sentence it had no reason to touch.** It splits on
50
+ `", so "` — one of the store's own `format()` joins, and also how ordinary
51
+ English joins two clauses — and rejoins with `". "`. So every person, on every
52
+ such refusal, read *"That person is not in this organization. they cannot be
53
+ given access to this table yet."* A cleaner that dropped nothing now changes
54
+ nothing.
55
+
56
+ `src/one-remedy.test.tsx` runs all five clauses on that exact measured refusal.
57
+
58
+ **A live clause that had gone stale, and was blocking every publish.**
59
+
60
+ `demo/live-smoke.test.tsx` asserted that a table declared with one column NAME has
61
+ no columns — true until lane LIMITS-FIX landed "a table's declared fields exist"
62
+ (2026-09-21, and the root cause behind crew C's fifty-one rows under "this table
63
+ has no columns yet"). The store cannot produce that state any more. The clause
64
+ asserts what it produces instead, which is strictly the stronger of the two, and
65
+ `declareTableWithNoColumns` — a name that had become a lie — is
66
+ `declareTableWithItsFirstColumn`.
67
+
68
+ **Consumer action:** none.
69
+
70
+ ## 0.45.0
71
+
72
+ **The record grid vanished when you looked at a dashboard and then opened a panel.**
73
+
74
+ Ridgeline Physical Therapy keeps ten patients in a table. Its owner pressed
75
+ Dashboards, then Checklists to compare the two panels, and the patients were
76
+ gone — with no New record button and no way back but a reload. Reproduced
77
+ headless on the live app: `aria-pressed` was `"true"` on Dashboards, ABSENT on
78
+ Checklists, no grid in the document.
79
+
80
+ That row of buttons was TWO state machines wearing one coat. `main` decided the
81
+ middle of the page, `rail` decided the right-hand panel, nothing joined them,
82
+ and the NINE rail buttons carried no pressed state at all — so the only tab that
83
+ ever looked chosen was the one that was not.
84
+
85
+ `chooseSurface` decides both now and `surfaceChosen` answers, for every button
86
+ in the row, whether it is the chosen one. Opening a panel brings the records
87
+ back (a panel is read BESIDE the records); opening the dashboards over a panel
88
+ leaves the panel alone, because that direction takes nothing away. Pressing the
89
+ chosen button closes it, as it always did. `src/surface-choice.test.tsx`, five
90
+ clauses, all red on 0.44.0.
91
+
92
+ **The Share button was called something it never said.**
93
+
94
+ It read "Share" and carried `aria-label="Share this table"` — and an
95
+ `aria-label` REPLACES the visible text as the accessible name. So a screen
96
+ reader, a voice user saying "click Share", a keyboard palette and every
97
+ automation all resolved a sentence the screen never shows. A crew reported it
98
+ twice as an absent button ("Playwright could not find a clickable, visible
99
+ 'Share' button even though the same label renders as a normal-looking button"),
100
+ and the clinic's front desk never got read access to the patients table.
101
+
102
+ The context is the `title` now, which describes and never renames.
103
+ `scripts/check-label-in-name.mjs` is the census — it carries `--self-test`,
104
+ which plants this exact rename and requires the census to go red on it — and it
105
+ found one more of the same: the grid's Delete button, which read "Delete" and
106
+ was named "Delete this record". Wired into `check:package`, so the class cannot
107
+ come back. A glyph (`+`, `×`) is not a label and is not judged: there
108
+ `aria-label` is the only name there is.
109
+
110
+ **Every cell asked "who?" and never answered.**
111
+
112
+ A crew reading ten real patients: *"Every single cell shows a small 'who?' hover
113
+ badge next to its value instead of a resolved author name, an agent/rule label,
114
+ or even 'system' — the attribution feature is visibly wired up (it renders on
115
+ every cell) but never resolves to anything readable."* They were right, and the
116
+ reason was that nothing ever asked: the badge opened a panel and looked nothing
117
+ up, while `custom.field_history` on those exact patients had been answering
118
+ *created by admin* since the day they were written.
119
+
120
+ It asks now, on the hover or the Tab that already makes it visible, for that one
121
+ cell — so a page of two hundred cells nobody points at costs nothing. `who?` is
122
+ what it says while the question is still a question; the moment it has the
123
+ answer, the answer is what it wears, and the hover carries the whole sentence.
124
+ `src/whoChanged.ts` owns those words for every surface that shows an author: an
125
+ agent ALWAYS names the person it acted for, the platform is "the system", a
126
+ person the door did not name is resolved through the app's one
127
+ organization-scoped roster (the `members` port), and a uuid is never printed at
128
+ anybody.
129
+
130
+ **Opening a table showed an error about a column in a table you will never see.**
131
+
132
+ The Alvarado-Chen family opened their recipes and met *"That already exists —
133
+ This table already has a field called 'Name'"*, every time. `Name` is the first
134
+ column of the PACKAGE's own bookkeeping table (`records_ui_view`, where a saved
135
+ view is a record), which `ViewBar` levels on every table page: the store's read
136
+ answered without the field, the store's write answered 23505 with it, and that
137
+ refusal was painted over the family's recipes.
138
+
139
+ Two classes, both closed. A step written to be idempotent no longer calls its own
140
+ desired end state a failure — 23505 from `field_declare` means exactly what
141
+ `addMissingFields` was trying to arrange, and every other refusal still comes
142
+ straight back out. And bookkeeping is never the person's error: a refusal
143
+ levelling the package's own table degrades the saved views with one sentence
144
+ (`SAVED_VIEWS_UNAVAILABLE`) and leaves the table's own screen alone.
145
+ `src/ensure-idempotent.test.tsx`, two clauses, red on 0.44.0.
146
+
147
+ **Consumer action:** none. No export changed — `chooseSurface`, `surfaceChosen`,
148
+ `WhoChangedSource`, `useWhoChanged` and the `whoChanged` vocabulary are added.
149
+
3
150
  ## 0.44.0
4
151
 
5
152
  **Pressing Open in the inbox landed you on the table with the record still shut.**