Repository navigation
Commit 24b7085
fix(service-settings): audience help and the identity-auth checklist state the email-verification rule as shipped (#20421)
Part of #20413 — the settings console text (4 locales) and the
identity-auth checklist. The plugin-auth boot-diagnostic location of the
same stale statement follows in a second round on the card (seat append
below).
Clause-②: no
## What changed
The auth settings console and the identity-auth platform checklist both
said every audience posture other than `invite_only` forces email
verification on. Commit `65352b7d` changed that rule. Each location now
states the rule the code enforces.
**The rule, re-derived from `packages/plugins/plugin-auth/src` at base
`40b315b0`:**
- **`email_domain`** always forces verification on
(`resolveEmailVerificationRequirement`, audience-posture.ts). An
explicit `false` is refused at entry from any source
(`assertAudienceConfig`).
- **`open`** forces it on unless the deployment declares an explicit
`false`, in either of two ways:
- `emailAndPassword.requireEmailVerification: false` in the stack
config;
- `OS_AUTH_REQUIRE_EMAIL_VERIFICATION=false`. `bindAuthSettings` in
auth-plugin.ts treats an env-sourced value as the deployment's own
declaration.
- **Under `open`, a `false` stored through the settings console is
refused.** This is the `verificationDeclaredBy: 'console'` branch of
`assertAudienceConfig`, and it plays out two ways:
- Posture and `false` saved in one pass: the posture change is refused.
- `false` saved while `open` already stands: the stored `false` is
refused.
- In both cases the standing config keeps ruling.
- **`invite_only`** uses whatever value is declared, and defaults to
off.
The code agrees with the card's statement of the rule.
### Landing points (strings re-located on this tree by key and by each
locale's wording)
| File | Keys | Hits by key / by wording |
|---|---|---|
| `service-settings/src/manifests/auth.manifest.ts` | `audience` group
`description`; `audience_posture` `description` | 2 / 2 |
| `service-settings/src/translations/en.ts` |
`groups.audience.description`; `keys.audience_posture.help` | 2 / 2 |
| `service-settings/src/translations/zh-CN.ts` | same keys | 2 / 2 |
| `service-settings/src/translations/es-ES.ts` | same keys | 2 / 2 |
| `service-settings/src/translations/ja-JP.ts` | same keys | 2 / 2 |
| `docs/qa/platform-checklist/areas/identity-auth.json` | two items,
below | |
The card calls the posture string `help`. In the manifest it is actually
the specifier's `description`; only the bundles call it `help`.
A repo-wide search for each locale's wording found these files and
nothing else that repeats the old rule, with one exception listed under
Acceptance notes. Three other hits already state the new rule:
- the spec `describe`;
- the generated reference page;
- `content/docs/deployment/self-hosting.mdx`.
No `*.generated.ts` bundle holds these strings.
### "No env knob" was measured, and it is false
The checklist said the audience is config-only, with no env knob. In
fact, the settings service derives an `OS_AUTH_*` override for every
auth manifest key (`envKeyOf`, settings-service.types.ts). So the three
audience keys have these overrides:
- `OS_AUTH_AUDIENCE_POSTURE`
- `OS_AUTH_AUDIENCE_ALLOWED_EMAIL_DOMAINS`
- `OS_AUTH_AUDIENCE_SELF_REGISTRATION_PERMISSION_SET`
**Probe.** A one-off probe, not committed, ran the real
`SettingsService` with the shipped `authSettingsManifest`, set the env
as shown, and called `getNamespace('auth')`:
```text
control, no env: audience_posture = "invite_only" source=default locked=false
open + set + off: audience_posture = "open" source=env locked=true
audience_self_registration_permission_set = "member_default" source=env locked=true
require_email_verification = false source=env locked=true
email_domain + list: audience_posture = "email_domain" source=env locked=true
audience_allowed_email_domains = "acme.com" source=env locked=true
off-vocabulary value: audience_posture = "invite_only" source=default (override logged as IGNORED)
```
**The plugin-auth half is already pinned.** In
`audience-posture-setting.test.ts`, the case "open with the
OS_AUTH_REQUIRE_EMAIL_VERIFICATION env override OFF is honoured" drives
`bindAuthSettings` with env-sourced audience keys and asserts posture
`open`.
**Composition.** `settings` is in the always-on capability slate for
every `serve` preset except `minimal`.
**Not measured:** a live stock boot with those variables set. The
checklist text says this.
### Checklist: two items, beyond the two quoted sentences
The card quotes two `knownGaps` sentences. The same file states the same
old rule in seven more fields across two items. These are fixed here as
a bounded in-place fix, which all four conditions allow:
1. It is the same defect class.
2. The edit is mechanical, and the rule above fixes its form.
3. The file is on this claim's declared surface.
4. It is the same gate, `check:platform-checklist`.
Left alone, those fields would contradict the rewritten gaps.
- **`identity-auth.self-signup-gate`, revision 1 to 2:**
- `knownGaps[0]` now names both doors: stack config, and the settings
namespace through the console or env. It says the env door is measured
in halves, not yet end to end.
- `knownGaps[1]` (the BOUNDARY note).
- `variants[2]`.
- `source[2]`.
- **`identity-auth.email-verification-loop`, revision 1 to 2:**
- `fixtures.requires[0]`.
- `acceptance[5]`.
- `negative[2]`. As written, it would have scored an `open` boot with
the deployment opt-out as a FAIL. That boot correctly advertises
`false`.
- `source[0]` and `source[1]`.
Each item gets a new `history` entry with ref `#20413`. The earlier
entries keep their text. I searched the file for nine old-rule phrases,
such as `config-only`, `no env knob` and `permitting-posture boot
advertising`. On base `40b315b0` they occur 11 times; at head they occur
0 times outside the two new history entries.
## Verification
Every run below is at head `a22b90fc`.
**Build.** `pnpm --filter '@objectstack/service-settings^...' build`
finished with VERDICT command-exit 0, then the package itself was built.
**Tests.** `pnpm --filter @objectstack/service-settings exec vitest run
--maxWorkers=2`: Test Files 33 passed (33), Tests 584 passed (584). This
includes:
- `settings-translation-coverage.test.ts`, which checks that zh-CN,
ja-JP and es-ES cover `settings.auth`;
- `auth.manifest.test.ts`.
**Typecheck.** `pnpm --filter @objectstack/service-settings run
typecheck` (`tsc --noEmit`) exits 0.
**Derived gates.** `node scripts/pm/dispatch-gates.mjs --repo
objectstack-ai/objectstack --commands` derived 57 commands, and all 57
were run. Reconciled with `--ran` and exit codes: 57 derived, 56 run, 1
NOT-MEASURED.
- **NOT MEASURED: `pnpm check:dual-build-cjs-loads`.** It exited 3
(PREREQUISITE NOT MET) because it needs every package's `dist/`.
**Declared narrowing:** I applied the gate's two properties to the one
package the diff touches.
- `node --check dist/index.cjs` exits 0.
- `require('./dist/index.cjs')` loads (46 exports, new text present).
- The diff only changes string literals.
- **`check-plugin-teardown-shape.mjs --self-test`** first exited 3,
because its pinned fixture commit was outside the shallow clone. After I
fetched that one commit at depth 1, it passed 48 cases.
- **`pnpm check:platform-checklist`:** OK, 15 areas, 266 items.
- **`pnpm check:nul-bytes`:** OK.
**Roster gates.** The derivation said the rosters of three gates live
under `packages/`, so their silence is not evidence either way. I ran
them anyway, and all three exit 0: `check:authz-resolver`,
`check:error-code-casing`, `check:filter-alias-parity`.
**Translation gates.** No gate script reads these translation files. A
search of `scripts/` and `.github/` for
`service-settings/src/translations` and `settingsBuiltinTranslations`
finds 0 hits. As a control, the same search surface does find
`service-automation`. The only gate on these files is the package's
coverage test above.
## Acceptance notes
- **Stale boot report text.**
`packages/plugins/plugin-auth/src/boot-sign-in-reachability.ts` line 478
still says an `open` or `email_domain` posture "forces email
verification on the INVITED login too". Line 492 of the same message
already names the `open` opt-out. plugin-auth source is outside this
claim, so this goes to the PM as a finding. The phrase is pinned in
`boot-sign-in-reachability.test.ts`.
- **Stale comment.** A comment in `auth-manager.ts`, near line 2295,
still says a self-registration posture forces verification on. It is a
comment only.
## Changeset
`.changeset/20413-verification-posture-statements.md`:
`@objectstack/service-settings` patch, because the strings ship in that
package. The `docs/qa` file is not published.
## Seat append (`domain:services` seat #6021,
`session_017B6YKCGu8CTY2KBWgwaHAs`)
- The first line changed from a closing keyword to `Part of #20413`. The
dev's report `5867903998` found one more location of the same stale
statement, outside this PR's claim surface: the
`no_sign_in_account_at_boot` remedy prose in
`packages/plugins/plugin-auth/src/boot-sign-in-reachability.ts`, pinned
by its test. By the family rule it joins #20413 as a second round
instead of a new card, so this PR no longer closes the card.
---
_Generated by [Claude
Code](https://claude.ai/code/session_017B6YKCGu8CTY2KBWgwaHAs)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 0283cb9 commit 24b7085
7 files changed
Lines changed: 40 additions & 23 deletions
File tree
- .changeset
- docs/qa/platform-checklist/areas
- packages/services/service-settings/src
- manifests
- translations
| 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 | + | |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
92 | | - | |
| 92 | + | |
93 | 93 | | |
94 | 94 | | |
95 | 95 | | |
| |||
103 | 103 | | |
104 | 104 | | |
105 | 105 | | |
106 | | - | |
| 106 | + | |
107 | 107 | | |
108 | 108 | | |
109 | 109 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
141 | 141 | | |
142 | 142 | | |
143 | 143 | | |
144 | | - | |
| 144 | + | |
145 | 145 | | |
146 | 146 | | |
147 | 147 | | |
| |||
171 | 171 | | |
172 | 172 | | |
173 | 173 | | |
174 | | - | |
| 174 | + | |
175 | 175 | | |
176 | 176 | | |
177 | 177 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
91 | 91 | | |
92 | 92 | | |
93 | 93 | | |
94 | | - | |
| 94 | + | |
95 | 95 | | |
96 | 96 | | |
97 | 97 | | |
| |||
133 | 133 | | |
134 | 134 | | |
135 | 135 | | |
136 | | - | |
| 136 | + | |
137 | 137 | | |
138 | 138 | | |
139 | 139 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
91 | 91 | | |
92 | 92 | | |
93 | 93 | | |
94 | | - | |
| 94 | + | |
95 | 95 | | |
96 | 96 | | |
97 | 97 | | |
| |||
133 | 133 | | |
134 | 134 | | |
135 | 135 | | |
136 | | - | |
| 136 | + | |
137 | 137 | | |
138 | 138 | | |
139 | 139 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
257 | 257 | | |
258 | 258 | | |
259 | 259 | | |
260 | | - | |
| 260 | + | |
261 | 261 | | |
262 | 262 | | |
263 | 263 | | |
| |||
298 | 298 | | |
299 | 299 | | |
300 | 300 | | |
301 | | - | |
| 301 | + | |
302 | 302 | | |
303 | 303 | | |
304 | 304 | | |
| |||
0 commit comments