You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 6c2eed8
Browse filesBrowse the repository at this point in the historyBrowse files
Data-model, filter, predicate, search, sort, security, seed, view, widget and registry findings no longer cite tracker numbers; each one states the decision behind it in words
6
+
7
+
Clause-②: no
8
+
9
+
The remaining `@objectstack/lint` findings that `os validate`, `os lint` and `os build` show to authors, plus the `surfaceReason` texts of the exported `AUTHORING_RULES` registry and one integrity error, pointed at an issue-tracker number for the reason behind them. The number goes; where the sentence did not already say what was decided, it now does.
10
+
11
+
- Data model: the bare declared `unique: true` warning says that protocol 18 rejects the spelling and that stored metadata still carrying it converts to `unique: 'global'`, which builds the same physical index.
12
+
- Empty filter combinators: the `$and: []`, `$or: []` and empty-node messages say every backend reduces an empty combinator to its boolean identity; the `$or: []` message says an empty disjunction never opens a read scope to the whole table.
13
+
- Null guards: the fail-closed outcome says a predicate that cannot evaluate refuses the write rather than being skipped.
14
+
- Visibility and metadata-form predicates: the fall-open consequence says failing open is the console's settled behaviour; the dotted right-hand-side message says the form evaluator keeps its right-hand side a literal by design and says why only in a development build.
15
+
- Component props: the advisory hint says props are judged at the authoring door as a warning before they become an error.
16
+
- Rule schema formats: the format hint says `rule-validator.ts` registers the default `ajv-formats` set so that a `format` is enforced on every write.
17
+
- Security posture: the unset-OWD message describes the leave_request incident (an object with no `sharingModel` let an ordinary read/write grant read and edit every other user's records); the `controlled_by_parent` message says the write is refused as a metadata defect rather than a permission denial.
18
+
- Seeds and views: the seed state-machine message says a seed records established facts rather than walking the lifecycle; the `views:` container message says the stack schema, the rule and the registration loop hold `views:` to one container-only contract.
19
+
- React pages: the absent-`groupBy` hint states the ruling directly.
20
+
- Liveness: the unrecognised-status integrity error says such a status fails loudly rather than being graded `dead`.
21
+
-`AUTHORING_RULES``surfaceReason` texts: the full-snapshot, capability-reference and sharing-rule reasons name the runtime publish gate (the Studio, REST and MCP door that runs this registry) in place of a tracker number; the advisory-volume reason says the object door opened to the gating object rules alone; the component-types reason names the crossing discipline the gating object rules went through.
22
+
- The other findings (search fields, sort fields, nav servability, dashboard actions, widget bindings and the remaining predicate and combinator messages) drop a citation the sentence already explained.
23
+
24
+
Text only: no rule id, severity, condition, finding or registry field moves. A tool or test that matches the old text (for example a tracker-number suffix) needs the new spelling.
An approval action now records the user who took it in `sys_approval_action.actor_id`, and the pending-approver slot it was taken as in a new `acted_as` column; rows stored before this move their slot out of `actor_id` at the next boot
6
+
7
+
Clause-②: no
8
+
9
+
`actor_id` is a lookup to `sys_user`, so under ADR-0118 D1 it holds a user id or nothing. A slot-gated action used to record the slot it took there instead: a `position:<name>` literal for a position staffed after the request opened, or an email for a `user` approver authored as one. On those decisions no record named the person who decided. The audit ledger and activity rows the write produces carry no user, so the attribution was lost, and every join or report on the lookup silently dropped the row.
10
+
11
+
**This supersedes the "What is recorded" sentence of the unreleased `21379-position-address-readers` changeset**, which says `actor_id` holds the slot. From this release it holds the person.
12
+
13
+
-**What is recorded.**
14
+
-`actor_id` is the user the request's context vouches for: the signed-in caller, whatever address they named.
15
+
-`acted_as` is the slot the action took, in the slot's stored spelling (a user id, an email, or `position:<name>`). It is empty on actions no slot admitted: the submitter's own actions, system actions, and an admin override, which `via_override` still marks.
16
+
- An emailed action link records the one account that carries the token's email. If no account carries it, the link records no person.
17
+
- The SLA sweep keeps its reserved `system:sla` actor for now.
18
+
-**What reads it.**
19
+
- The multi-approver tally and `decision_progress` count `acted_as`.
20
+
- A participant who already acted keeps sight of a request by either of two facts: `actor_id` is their user id, or `acted_as` is a slot they act under (so a decision taken as `position:<name>` stays visible to that position's holders).
21
+
- Nothing compares a slot with `actor_id` any more.
22
+
- The action log (`GET /api/v1/approvals/requests/:id/actions`, `listActions`) returns `acted_as` beside `actor_id` and `actor_name`, filling the `ApprovalActionRow.acted_as` member `@objectstack/spec` declares. It is omitted when the action took no slot, or when no stored record kept the slot.
23
+
-**Stored rows.** A repair runs on every boot and is idempotent.
24
+
- Pass 1: a row whose `actor_id` still holds a slot address gets `acted_as` set to it and `actor_id` cleared. No stored record names who decided it, so it shows the slot and no person.
25
+
- Pass 2: the approve votes a still-pending request's tally counts get their `acted_as`, so in-flight `unanimous`, `quorum` and `per_group` requests keep the approvals they already collected.
26
+
- A failure is logged at error level and retried at the next boot.
27
+
-**For a report or integration that read `actor_id` as the slot:** read `acted_as` instead. `actor_id` now always joins to `sys_user`.
fix(types): `operatorFacingErrorText` answers through the driver-fault redaction, so an operator-facing record carries no statement and no bound value
6
+
7
+
Clause-②: no
8
+
9
+
-**What changed.**`operatorFacingErrorText` passes every text it returns through `redactStatementFromMessage`, the one driver-fault redaction in this package. Text it reads off a raw-statement fault's `cause` is cut with `{ statementSent: true }`, which is the cut `@objectstack/driver-sql` applies to its own log line for the same fault. Every other text asks the shared leak predicate, as the engine's own log line does.
10
+
-**What an operator reads now.** The records this helper fills, in `os db clean` and in the metadata migrations and probes, keep the dialect's own diagnostic: the missing column, the failed constraint or the locked database. The value slots the redaction's dialect templates own are cut from it, and the redaction's marker stands where the statement was removed. The records no longer carry the statement or the values bound into it.
11
+
-**What does not change.** Text that is not a driver dump comes back exactly as before, empty text included. The thrown error is not touched: its `code`, `status`, class and `cause` reach every other reader as the driver composed them. The function's signature and the package's exports are unchanged.
Copy file name to clipboardExpand all lines: content/docs/permissions/tenant-audit-census.mdx
+17-17Lines changed: 17 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -122,7 +122,7 @@ are reported as `undecidable` rather than assumed either way.
122
122
123
123
The same holds twice over for the context. An options argument spelled as a
124
124
literal can be read; one spelled `options`, `{ ...opts }`, or handed through a
125
-
forwarding shim cannot, and **67 of the 229 sites are spelled that way**. A
125
+
forwarding shim cannot, and **67 of the 231 sites are spelled that way**. A
126
126
context resolved from an inline literal or a local `const` can be tested for
127
127
`isSystem`; one arriving from a helper call cannot.
128
128
@@ -187,10 +187,10 @@ reproduce them. Where it disagrees, it disagrees on the page:
187
187
188
188
| carried figure | where it survives | this census |
189
189
| :--- | :--- | ---: |
190
-
| 175 write call sites | quoted in the merged changeset |**229**|
190
+
| 175 write call sites | quoted in the merged changeset |**231**|
191
191
| 24 carrying no tenant context | quoted in the merged changeset |**9** provable and tenancy-enabled; **34** more whose options argument is unreadable |
192
-
| 127 of 175 statically decidable, 48 runtime-parameter-name sites | restated on the `isSystem`-scoping card |**152 of 229** decidable, **77** undecidable |
193
-
| 135 (77%) silenced by the `isSystem` guard before the posture gate | the lost issue body — **no surviving corroboration**|**not reproduced**: 110 decidably elevated, 0 decidably not, 102 undecidable |
192
+
| 127 of 175 statically decidable, 48 runtime-parameter-name sites | restated on the `isSystem`-scoping card |**154 of 231** decidable, **77** undecidable |
193
+
| 135 (77%) silenced by the `isSystem` guard before the posture gate | the lost issue body — **no surviving corroboration**|**not reproduced**: 112 decidably elevated, 0 decidably not, 102 undecidable |
194
194
| 141 and 132, two independent re-derivations | the card that filed this work | — |
195
195
196
196
**The differences are not reconciled, and deliberately so.** The old census's
@@ -207,11 +207,11 @@ would report a smaller number and would not say so.
207
207
208
208
The fourth row is the one worth flagging to anyone citing it. **The 135 / 77%
209
209
figure has no surviving corroboration anywhere in the tree.** This census reads
210
-
110 of 229 (48%) as decidably elevated, with 102 more whose elevation is a
210
+
112 of 231 (48%) as decidably elevated, with 102 more whose elevation is a
211
211
run-time fact — so the claim is neither confirmed nor refuted, and the honest
212
212
answer is that a static reading cannot settle it.
213
213
214
-
⇒ **Cite `9 / 229`, and say what it is**: the sites whose options argument was
214
+
⇒ **Cite `9 / 231`, and say what it is**: the sites whose options argument was
215
215
READ and holds no tenant context, against a decidably tenancy-enabled object.
216
216
That is the control's provable yield surface. ⛔ Do not cite it as "the sites
217
217
without tenant context" — **34 further sites** have an options argument this
@@ -223,28 +223,28 @@ cannot read, and they are neither in nor out.
223
223
224
224
| what | count |
225
225
| :--- | ---: |
226
-
| write call sites on the application surface |**229**|
227
-
| …whose object name is statically decidable |152|
226
+
| write call sites on the application surface |**231**|
227
+
| …whose object name is statically decidable |154|
228
228
| …whose object name is chosen at run time | 77 |
229
-
| …against an object with tenancy ENABLED |151|
229
+
| …against an object with tenancy ENABLED |153|
230
230
| …against an object that declares tenancy off | 1 |
231
-
| threading a tenant context |145|
231
+
| threading a tenant context |147|
232
232
| PROVABLY carrying none (options read, no context key) |**17**|
233
233
| …of those, against a decidably tenancy-enabled object |**9**|
234
234
| options argument UNREADABLE — may or may not carry one | 67 |
235
235
| …of those, against a decidably tenancy-enabled object | 34 |
236
-
| threading a decidably ELEVATED (`isSystem`) context |110|
236
+
| threading a decidably ELEVATED (`isSystem`) context |112|
237
237
| threading a context that is decidably NOT elevated | 0 |
238
238
| threading a context whose elevation is a run-time fact | 102 |
239
239
240
240
| how the instrument reached the site | count |
241
241
| :--- | ---: |
242
-
| receiver carried a readable engine type |181|
242
+
| receiver carried a readable engine type |183|
243
243
| receiver erased, placed by the object NAME | 28 |
244
244
| receiver erased, placed by an `object: string` PARAMETER | 15 |
245
245
| receiver erased, placed by an `UNTYPED_RECEIVERS` row | 5 |
246
246
247
-
| object name spelled inline |101|
247
+
| object name spelled inline |103|
248
248
| object name spelled through a `const`| 51 |
249
249
| object name is an `object: string` parameter | 17 |
250
250
| object name is some other run-time expression | 60 |
@@ -297,13 +297,13 @@ holds still. They are required to be HERE and to say WHEN they were true;
297
297
their values are not compared. The reasoning, and the measurement behind it,
0 commit comments