fix(dev): eliminate three fixed startup log warnings so official examples boot clean (#3420)#3449
Merged
Merged
Conversation
…ples boot clean (#3420) `os dev` on the stock showcase printed three fixed noise sources on every boot, training users to ignore warnings (cry-wolf). Clear all three: 1. field-zoo password warning — ObjectSchema.create() warned that showcase_field_zoo.f_password declares `password` on a non-auth object, yet offered no way to express the "this is intended" its own text invited. Add a field-level `ackPlaintextMasking: true` opt-out (ADR-0100) that skips the warning for a deliberately-masked field, and set it on field-zoo's demo field. The warning text now points authors at the flag. 2. Better Auth well-known warning (printed twice) — @better-auth/oauth-provider warned "Please ensure '/.well-known/oauth-authorization-server/api/v1/auth' exists…" even though registerOidcDiscoveryRoutes already mounts those documents at the issuer root (RFC 8414 §3). Silence the false positive with the documented `silenceWarnings.oauthAuthServerConfig` option; gating the emitter also removes the duplicate print. 3. Registry re-register output — `[Registry] Overwriting package…` and `Re-registering owned object…` are normal rebuild/HMR/seed-replay paths but were emitted via console.warn (always on). Route them through a new debug-only SchemaRegistry.debug() so they stay out of the default 'info' boot log while remaining available at logLevel 'debug'. Adds spec tests for the ackPlaintextMasking opt-out (suppress, partial-ack, warning-text hint); updates ADR-0100 §B5 to record the opt-out. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TXHXXHnquzVUjeQYPs9bmy
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 3 package(s): 110 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
…liveness, add changeset (#3420) Follow-ups required by CI for the new field-level `ackPlaintextMasking` option: - Regenerate content/docs/references/data/field.mdx (generated from FieldSchema). - Classify field/ackPlaintextMasking as `live` in the spec liveness ledger — its consumer is warnGenericPasswordFields (object.zod.ts), proven by the ADR-0100 author-warning suite in object.test.ts. - Add the changeset for @objectstack/spec, @objectstack/objectql, @objectstack/plugin-auth. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TXHXXHnquzVUjeQYPs9bmy
os-zhuang
marked this pull request as ready for review
July 24, 2026 15:05
…nv seam (#3420) Follow-ups so the startup log stays at zero warnings and the debug output is discoverable: 1. Regression guards for all three noise sources: - password: examples assert every generic (non-better-auth) `password` field affirms `ackPlaintextMasking` (showcase no-startup-warnings.test.ts; crm smoke.test.ts — future-proofs an example with none today). - better-auth: auth-manager.mcp-oauth.test.ts asserts oauthProvider is wired with `silenceWarnings.oauthAuthServerConfig: true`. - registry: registry-log-level.test.ts asserts the re-register / package- overwrite lines are silent at the default `info` level and only emit via console.debug at `debug` (never console.warn). 2. Other examples: verified only showcase declared a generic password field; the better-auth and registry fixes are framework-level so crm/todo inherit them. crm now carries the same password guard. (todo ships no password fields and uses the custom `objectstack test` runner, so no vitest guard is added there.) 3. better-auth double-print root cause: the notice fires in oauth-provider's `init(ctx)`, run once per betterAuth() construction; auth is (re)built more than once at boot (initial lazy build, then a rebuild after boot-time auth settings apply — applyConfigPatch nulls the cached instance). silenceWarnings gates the emitter itself, so it is covered on every build path. Corrected the inaccurate inline comment accordingly. 4. Registry debug discoverability: add a `logLevel` option to SchemaRegistryOptions resolved from `OS_REGISTRY_LOG` (unknown → info), so a developer can surface the debug-gated housekeeping with OS_REGISTRY_LOG=debug. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TXHXXHnquzVUjeQYPs9bmy
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TXHXXHnquzVUjeQYPs9bmy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #3420.
os devon the stock showcase printed three fixed noise sources on every boot, with zero example-side changes — training users to ignore warnings (cry-wolf). This clears all three so an official example boots warning-free, adds regression guards so it stays clean, and makes the debug output discoverable — without weakening any real diagnostic.Repro:
pnpm -C examples/app-showcase exec objectstack dev --ui --seed-admin.The three fixes
1. field-zoo
passwordwarning → field-level opt-outObjectSchema.create('showcase_field_zoo')warned thatf_passwordusespasswordon a non-auth object (plaintext-at-rest, masked-on-read — ADR-0100). The text said "if this is intended … safe to ignore" but gave authors no way to express that intent.ackPlaintextMasking: trueopt-out (packages/spec/src/data/field.zod.ts). When set on apasswordfield,warnGenericPasswordFieldsskips it; the warning text now points authors at the flag.better-authexemption are unchanged.2. Better Auth well-known warning (printed twice) → silence the false positive
@better-auth/oauth-provideremitted "Please ensure/.well-known/oauth-authorization-server/api/v1/authexists. Upon completion, clear withsilenceWarnings.oauthAuthServerConfig." — butregisterOidcDiscoveryRoutesalready mounts those documents at the issuer root (RFC 8414 §3 requires them there, outside better-auth's own routing, so the plugin can't see them).silenceWarnings: { oauthAuthServerConfig: true }tooauthProvider(...). Verified against@better-auth/oauth-provider@1.7.0-rc.1: the option is a member ofOAuthOptionsand gates the exactlogger.warn.init(ctx), run once perbetterAuth()construction, and the auth instance is built more than once at boot — an initial lazy build, then a rebuild after boot-time auth settings are applied (applyConfigPatchnulls the cached instance so the next request rebuilds with the new policy). Gating the emitter covers every build path, so the count no longer matters.3. Registry re-register output → debug level
[Registry] Overwriting package: …andRe-registering owned object: …are normal rebuild / HMR / seed-replay paths, but were emitted viaconsole.warn(always on) and looked like errors.SchemaRegistry.debug()(emits only atlogLevel === 'debug') and route both lines through it.logLevelconstruction option resolved fromOS_REGISTRY_LOG(unknown value →info), so a developer chasing a registration issue can surface the lines withOS_REGISTRY_LOG=debug.Regression guards (keep the boot log at zero)
passwordfield affirmsackPlaintextMasking(examples/app-showcase/test/no-startup-warnings.test.ts;examples/app-crm/test/smoke.test.ts, future-proofing an example with none today).auth-manager.mcp-oauth.test.tsassertsoauthProvideris wired withsilenceWarnings.oauthAuthServerConfig: true.registry-log-level.test.tsasserts the re-register / package-overwrite lines are silent at the defaultinfolevel and only emit viaconsole.debugatdebug(neverconsole.warn), plus theOS_REGISTRY_LOGresolution.Other examples
Only showcase declared a generic password field; the better-auth and registry fixes are framework-level, so
app-crm/app-todoinherit clean boots.app-crmnow carries the same password guard;app-todoships no password fields and uses the customobjectstack testrunner (no vitest guard added there).Docs
ackPlaintextMaskingopt-out and its rationale; the generatedcontent/docs/references/data/field.mdxand the spec liveness ledger (field/ackPlaintextMasking) are updated; a changeset covers the three packages.Verification (local, real test runner)
packages/spec—object.test.ts+field.test.ts: 200 passed (incl. 3 new: ack suppresses, partial-ack still warns about the un-acked field, warning text names the flag).packages/objectql— registry suites: 122 passed (incl. newregistry-log-level.test.ts).packages/plugins/plugin-auth— auth-manager suites (incl. mcp-oauth, which builds the realoauthProvider): 215 passed.examples/app-showcase(1) +examples/app-crm(20) guards: pass — confirmsackPlaintextMaskingsurvivesObjectSchema.createend-to-end.check:liveness+check:docs: green. ESLint on changed files: clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01TXHXXHnquzVUjeQYPs9bmy