Repository navigation
Commit 1878ef9
Fixes #21237
Clause-②: no
**Files outside the original surface, named before the change list.**
- **Cross-lane declaration (claim revision 1, triage Q1 = B):** one line
in `packages/platform-objects/src/identity/sys-user.object.ts`, a
`domain:engine` file. The identity object's deactivation flag moves from
the `Admin` field group to the `Account` group, so it stays directory
data that org peers are served. This is the only `platform-objects`
edit.
- **Claim surface revision 2 (option A of the dev report's open
question):** the ruled behaviour made two existing tests false. Each
keeps its intent:
-
`packages/plugins/plugin-auth/src/sys-user-self-service-route.test.ts`:
the mixed-payload case of PIN 4 now uses a non-whitelisted column
outside the group. It still measures the identity guard's strip. A group
field is refused one layer earlier, by the field-level write gate.
-
`packages/qa/dogfood/test/admin-ledger-decision-metadata.dogfood.test.ts`:
its masked and gated classes ride two `Admin`-group fields. The readers'
own fixture sets now grant those two fields back as readable, the way an
app does, so each class applies only through its own mechanism.
## What changes
- **The non-admin sets withhold the group.** `member_default` and
`viewer_readonly` declare the identity object's `Admin` field group
`readable: false` (with `editable: false`). They use the permission
set's existing `fields` mechanism, built from the identity object's
declaration, with no hand-kept list. These are the two shipped non-admin
sets that open an org peer's identity row through
`sys_user_org_members`.
- **The admin sets keep the group.** `admin_full_access` and
`organization_admin` (and so the derived `organization_admin_no_bypass`)
declare the group `readable: true, editable: true`, the same state as a
field no set names. That entry is required: `member_default` is the
additive `everyone` baseline that every authenticated human resolves,
admins included, and field grants merge most-permissively.
- **The #11965 neutrality pin.** Its literal in
`default-permission-sets.test.ts` gains the admin set's keeping `fields`
block, read off the declaration. One docblock line says why, in the
shape #21260 used for its own addition.
- **New pins.**
- `plugin-security/src/identity-admin-field-group.test.ts` holds three:
group equality against the declaration plus a completeness check over
every shipped set that opens an org peer's identity row; the evaluator's
real merge per persona; and the deactivation flag as a served control.
- `qa/dogfood/test/identity-admin-fields-org-peer.dogfood.test.ts` pins
the HTTP door on a real boot.
- The two test edits named above.
- A changeset for `@objectstack/plugin-security` and
`@objectstack/platform-objects` (patch).
## Measured at the HTTP door (real boot, showcase, `single` posture,
head `017857056`)
| Persona / door | Result |
|:--|:--|
| Org member reading a colleague, by id and through the list | 200, 0
group fields; name, email and the deactivation flag served |
| The same member through the activity door (object-level read granted)
| rows served, 0 group keys in any recorded change |
| The member's own row through the generic data API | 0 group fields.
Field-level security is row-blind; every reader of the group on a
member's own row reads under system or auth context |
| The member's user-context write naming a group field, mixed with a
profile field | 403 `PERMISSION_DENIED`, naming the field; the profile
field does not land |
| The member's profile-only write | 200 (control) |
| The user picker's candidate query (the not-deactivated filter) as the
member | 200. The deactivated peer is excluded, and is served when the
query is unfiltered |
| The member filtering on a group field | 403 `PERMISSION_DENIED` (the
filter oracle stays closed) |
| Org owner, and a platform admin holding no org-admin grant | full
group on the direct read and in the activity metadata |
| The platform admin's write naming a group field | not refused by the
field-level gate (admin writes unchanged) |
The dogfood file passes 12/12 at `017857056`. In round 1, no reader
outside the organization was served the group: a second-org member got
404 by id and 0 rows through the list. The walled posture is NOT
MEASURED, because the enterprise organizations package is absent here.
## Ablations
Each leg was restored afterwards and checked: blob == HEAD, and `git
diff HEAD` empty.
**Unit legs** (the subject resolved from `src`):
| Mutation | Pins red |
|:--|:--|
| member set's `fields` entry removed | 3 |
| one group field dropped from the built set | 12, incl. the #11965 pin
|
| org admin set given the withholding entry | 5 |
| `admin_full_access` keeping entry removed | 3, incl. the #11965 pin |
**Dist legs** (rebuild, then `ablation-dist-preflight` both ways):
| Mutation | Pins red |
|:--|:--|
| member set's entry removed | 6 of 11 dogfood |
| `admin_full_access` keeping entry removed | 2 of 11 dogfood (the admin
read and the admin write) |
| deactivation flag moved back into the `Admin` group (platform-objects
rebuilt) | 3 of 12 dogfood (incl. the picker query); 2 unit (the
control) |
## Tests and gates
**At `017857056`:**
| Suite | Test Files | Tests |
|:--|:--|:--|
| `plugin-security` | 158 passed (158) | 3420 passed, 23 skipped (3443)
|
| `platform-objects` | 59 passed (59) | 948 passed (948) |
| `plugin-auth` | 116 passed (116) | 2484 passed (2484) |
| `sys-user-self-service-route.test.ts` | 1 passed | 12/12 |
| `admin-ledger-decision-metadata.dogfood.test.ts` | 1 passed | 8/8 |
| The new dogfood pin | 1 passed | 12/12 |
| Dogfood subset (the 34 files that read the shipped sets or identity
rows) | 33 passed, 1 skipped (34) | 313 passed, 3 skipped (316) |
**At `77b116888`, before the merge of `origin/main`:**
| Suite | Test Files | Tests |
|:--|:--|:--|
| `rest` | 254 passed | 4805 passed, 316 skipped |
| `runtime` | 302 passed | 4329 passed, 11 skipped |
| `verify` | 16 passed | 120 passed |
| `service-automation` | 162 passed | 2027 passed |
| `cli` unit layer (the integration layer is left to CI) | 243 passed |
3439 passed |
The full dogfood suite is left to CI's sharded gate.
**Typecheck** (exit 0 for each): `plugin-security`, `platform-objects`,
`plugin-auth`, `dogfood`.
**Gates:** `dispatch-gates --commands` at `017857056` (merge base
`222ecc27f`) derived 68 commands. All 68 ran and exited 0, and `--ran`
reconciles 68/68 with 0 NOT-MEASURED.
## Acceptance notes
- **Docs.** I grepped `content/docs/**` (outside `releases/`) and
`skills/**` for what a member reads of the identity object. No sentence
is made false. `field-level-security.mdx` already states the
most-permissive merge this change relies on.
- **Self-service route classifier.** The `route()` helper in the
self-service route test labels any middleware refusal raised after the
pre-image read `row-scope`. That would misattribute a field-level
write-gate refusal. No case in the file sends a group field now, so
nothing is misattributed today. A fix needs a fourth layer label, a
classifier change and a case producing it (the file's own non-vacuity
rule), which is more than one hunk, so it is left as a note. The dogfood
pin asserts that this refusal names the field.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01DiCSbmJrkzNhuEAier4VoJ)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 50e1c65 commit 1878ef9
8 files changed
Lines changed: 585 additions & 6 deletions
File tree
- .changeset
- packages
- platform-objects/src/identity
- plugins
- plugin-auth/src
- plugin-security/src
- objects
- qa/dogfood/test
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
708 | 708 | | |
709 | 709 | | |
710 | 710 | | |
711 | | - | |
| 711 | + | |
712 | 712 | | |
713 | 713 | | |
714 | 714 | | |
| |||
Lines changed: 3 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
428 | 428 | | |
429 | 429 | | |
430 | 430 | | |
431 | | - | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
432 | 434 | | |
433 | 435 | | |
434 | 436 | | |
| |||
Lines changed: 154 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
Lines changed: 9 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
365 | 365 | | |
366 | 366 | | |
367 | 367 | | |
368 | | - | |
| 368 | + | |
| 369 | + | |
369 | 370 | | |
370 | 371 | | |
371 | 372 | | |
| |||
394 | 395 | | |
395 | 396 | | |
396 | 397 | | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
397 | 405 | | |
398 | 406 | | |
399 | 407 | | |
| |||
0 commit comments