Filed unassigned from work on #5565 (the drawer summary card trim). Sibling surface, same missing filter — recording it rather than widening that PR.
What was measured
decisionAmountEntry in apps/console/src/pages/system/ApprovalsInboxPage.tsx picks the one decision-relevant numeric field of the request's payload_json snapshot by matching AMOUNT_KEY_RE (amount|total|price|value|cost|sum|budget|salary|fee|revenue|balance plus the CJK spellings) against the key. It is called from four places:
| line |
surface |
trimmed by #5565's fix? |
| ~1845 |
drawer summary card lead figure |
✅ yes |
| ~444 |
RecordCell — desktop queue row (· {amount.display}, plus title={label: display}) |
❌ no |
| ~1649 |
mobile queue card (· {amount.display}, title={amount.label}) |
❌ no |
| ~1061 |
the sortKey === 'amount' comparator |
❌ no |
So after #5565 lands, a field the app author declares hidden: true whose key matches AMOUNT_KEY_RE is trimmed out of the drawer but still renders inline in the queue list, on both the desktop row and the mobile card — and still drives the amount sort order, which leaks the relative magnitude of a hidden field even to a viewer who never sees the figure.
Same invariant as #5565 and #5553: the app author's hidden declaration is bypassed on the approver's path. Same ruling applies (objectstack#10749, verbatim: hidden: true stays UI-only; internal: true is the serialization primitive) — so the fix belongs in the UI, and this is default UI too.
Why it was NOT fixed in #5565
Scope, and a genuinely different cost model — not an oversight:
Widening #5565 to cover this would have replaced a bounded, mechanical filter with an unrelated cost model and a behaviour change to sorting.
Note on the interim state
Between #5565 landing and this one, the drawer and the queue row disagree about the same field for the same request: the row shows the amount, the drawer does not. That is strictly an improvement over both showing it, but it is a visible inconsistency and worth closing.
Pointers
Filed unassigned from work on #5565 (the drawer summary card trim). Sibling surface, same missing filter — recording it rather than widening that PR.
What was measured
decisionAmountEntryinapps/console/src/pages/system/ApprovalsInboxPage.tsxpicks the one decision-relevant numeric field of the request'spayload_jsonsnapshot by matchingAMOUNT_KEY_RE(amount|total|price|value|cost|sum|budget|salary|fee|revenue|balanceplus the CJK spellings) against the key. It is called from four places:RecordCell— desktop queue row (· {amount.display}, plustitle={label: display})· {amount.display},title={amount.label})sortKey === 'amount'comparatorSo after #5565 lands, a field the app author declares
hidden: truewhose key matchesAMOUNT_KEY_REis trimmed out of the drawer but still renders inline in the queue list, on both the desktop row and the mobile card — and still drives the amount sort order, which leaks the relative magnitude of a hidden field even to a viewer who never sees the figure.Same invariant as #5565 and #5553: the app author's
hiddendeclaration is bypassed on the approver's path. Same ruling applies (objectstack#10749, verbatim:hidden: truestays UI-only;internal: trueis the serialization primitive) — so the fix belongs in the UI, and this is default UI too.Why it was NOT fixed in #5565
Scope, and a genuinely different cost model — not an oversight:
hidden: true#5565's subject is the drawer summary card, one open request, one object. Its metadata read isgetObjectSchema(selected.object_name), one cached call, one object.useRecordReadabilitybatching pattern rather than the single read Approvals drawer summary card can render a field the object declareshidden: true#5565 added, plus a loading posture for rows whose object has not answered yet.Widening #5565 to cover this would have replaced a bounded, mechanical filter with an unrelated cost model and a behaviour change to sorting.
Note on the interim state
Between #5565 landing and this one, the drawer and the queue row disagree about the same field for the same request: the row shows the amount, the drawer does not. That is strictly an improvement over both showing it, but it is a visible inconsistency and worth closing.
Pointers
apps/console/src/pages/system/ApprovalsInboxPage.tsx—decisionAmountEntryand its four call sites.hidden: true#5565 added:apps/console/src/pages/system/hiddenFields.ts(hiddenFieldNames,readHiddenFields,useHiddenFields) — the reader is already batching-ready; only the hook is single-object.apps/console/src/pages/system/recordReadability.ts(planReadabilityProbeIS the cost model there).hidden: true#5565 (drawer summary card, the fix this was split out of), Approvals inbox detail drawer unconditionally renders a "Raw data (JSON)" panel — exposeshidden: truefields, internal ids and audit columns to business approvers #5553 (raw JSON panel gate) — neither is affected by this one either way.