Skip to content

Published auth docs define bootstrap-status as "does this environment have any user yet" in two places — #14157 changes it to the bootstrap-window question #14357

Description

@huangyiirene

Filed by the triage seat (session session_019kDRpB7D2XzVzkaLp57T5D, R+90) while grading #14349 and #14350. Same family as #14350, different surface: that card covers the internal QA checklist's quotation of the --seed-admin flag sentence; this one covers the customer-facing published documentation for a public, unauthenticated endpoint.

⭐ #14374 is the same finding, filed independently 18 minutes later by the domain:services PM seat from its in-seat Clause-② review of PR #14352 (non-blocking follow-up 4). Converged here as the single dispatch entry; its two additions are folded in below.

The measured drift

content/docs/permissions/authentication.mdx defines the endpoint's semantics in two places, and both state the population question:

  • line 251 (### First-run bootstrap status): "GET /api/v1/auth/bootstrap-status answers one question — does this environment have any user yet?"
  • line 1075 (the endpoint index): "Public, unauthenticated first-run probe: { "hasOwner": boolean }, telling a client whether this environment has any user yet"

Both are false as of PR #14352 (#14157), now landed. Re-verified on origin/main @ 5c9e40a:

  • packages/plugins/plugin-auth/src/auth-plugin.ts:2025 is now return c.json({ hasOwner: !(await this.authManager!.hasBootstrapWindow()) }); — the unfiltered dataEngine.count('sys_user', {}) is gone.
  • packages/plugins/plugin-auth/src/auth-manager.ts:4148 — hasBootstrapWindow() delegates to isBootstrapCreation(), which is keyed on isHumanUserRow.

⇒ The two questions diverge on a real population: a database carrying only the legacy usr_system service row answered hasOwner: true under the documented sentence and answers hasOwner: false now. That is exactly the population where the console and the admission gate used to disagree, which is what #14157 set out to fix.

Why this is p2 where #14350 is p3

This is a published page about a public endpoint with an SDK method (client.auth.bootstrapStatus()), and the sentence is the endpoint's definition, not a passing mention. A customer who routes on hasOwner — which is exactly what the page tells them it is for ("a routing signal") — is integrating against the documented question. #14350's drift is a quotation inside an internal QA checklist read only by the checklist author.

Fix

Re-state both sentences from the handler's own behaviour. The wording the reviewing seat asked for, and which matches the code: bootstrap-status reports whether the admission gate's bootstrap window is open — no human user yet; service rows do not count.

Two things worth getting right rather than paraphrasing:

  • The surrounding prose is still correct — do not rewrite the section. Public/unauthenticated by design, boolean-only, drives the Console's /login vs /setup choice: all unchanged. The fails-open sentence is also still true and was checked rather than assumed: isBootstrapCreation() returns false when no engine is wired, so hasOwner is !false = true, and a no-engine composition still reads as bootstrapped exactly as documented. Only the question moves.
  • Name what the new predicate excludes. "Has a bootstrap window" is the honest phrasing and is what the admission gate agrees with; "has any user" is what it stops being.

Grade: documentation · priority:p2 · domain:devx (content/docs/**) · type Task · pm:queue.

Size/model suggestion: XS, sonnet — two sentences.

Refs: #14157 / PR #14352 (the change) · #14374 (the duplicate, converged here) · #14350 (the QA-checklist twin) · #14349 (the posture question over the same predicate family — ⛔ not this card's to answer).

Generated by Claude Code

Activity

  1. added theissue type on Sep 2, 2026
  2. added
    documentationImprovements or additions to documentation
    domain:devxDomain lane — seat card indexed by label:pm:seat
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    pm:queueReady for the PM dispatch loop
    and removed
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    on Sep 2, 2026
  3. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Sep 2, 2026
  4. claude commented on Sep 2, 2026

    @claude
    Contributor

    Claim: session session_01WLJQhde67SeTccsmnBVarV (domain:devx execution seat, seat post #6023) — R1 wave 7 (concurrency raised to 5 by the maintainer, 2026-09-02 「并发加到五」).


    Generated by Claude Code

  5. claude commented on Sep 2, 2026

    @claude
    Contributor

    os-dev-report

    {
      "issue": 14357,
      "status": "done",
      "branch": "claude/issue-14357-bootstrap-status-docs-window",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/14429",
      "premise_still_valid": true,
      "summary": "Restated both drift sites in content/docs/permissions/authentication.mdx (line 251 First-run bootstrap status prose, line 1075 endpoint index) to say bootstrap-status reports whether the admission gate's bootstrap window is open -- no human user yet, service rows such as usr_system do not count -- matching the handler (auth-plugin.ts:2025 hasBootstrapWindow(), auth-manager.ts:4148, keyed on isHumanUserRow). Verified exactly the two 'any user' hits existed pre-edit and zero remain post-edit. Left the rest of the section (public/unauthenticated, boolean-only, /login vs /setup routing, fails-open) untouched as instructed.",
      "tests": "node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands content/docs/permissions/authentication.mdx derived 30 families (22 pnpm, 8 direct node). All 30 run under scripts/pm/os-verify-lock.sh (some required building prerequisite packages first: @objectstack/spec, @objectstack/formula, @objectstack/lint, @objectstack/client-react -- their check:docs / check:skill-examples / check:doc-formula-expressions / check:doc-security-posture gates refuse PREREQUISITE NOT MET otherwise). 29/30 RAN-PASS (all printed their own PASS/checkmark verdict line, exit 0, captured pre-pipe): check-ci-filter-parity, check-cross-package-test-inputs (node+pnpm), check-doc-frontmatter, check-doc-route-spelling, check-docs-section-name, check-section-landing-index, check-shard-attestation, check:doc-formula-expressions, check:doc-security-posture, spec check:docs, check:empty-state, check:liveness, check:skill-examples, check:strictness-ledger, check:variant-docs, check:yaml-examples, check:corpus-claim-drift, check:doc-anchors, check:doc-authoring, check:docs-audit-scope, check:docs-redirects, check:docs-single-h1, check:merge-driver, check:published-readme-links, check:react-page-adapter-contract, check:role-word, check:skill-identifier-liveness, check:vendor-version-stamps. 1 NOT-MEASURED: node scripts/check-test-completeness.mjs exits 3 (PREREQUISITE NOT MET) when run with no argument locally -- it needs a saved `turbo run test` log that only CI produces; its own printed guidance says record this as NOT-MEASURED, not a finding. Reconciled with `dispatch-gates.mjs --ran ran.list`: '30 derived, 29 run, 1 NOT-MEASURED, 0 UNRUN'. pnpm changeset status: no changeset needed (docs-only, zero package changes) -- skip-changeset label applied to PR #14429 and read back confirmed present. Head sha at gate time: 6e4304343 (git rev-parse --short HEAD, matches the pushed branch tip).",
      "mcp_calls": 0,
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  6. removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Sep 2, 2026
  7. claude commented on Sep 2, 2026

    @claude
    Contributor

    ACCEPT — #14357 landed. PR #14429 merged to main as 365a740a8 via the merge queue (auto-merge armed after the CI watcher read GREEN; the auto_merge: null / mergeable_state: unknown reading while queued is the PR mid-queue, not disarmed).

    Close-out probes executed on origin/main (fresh fetch, throwaway worktree — not the shared checkout; 365a740a8 confirmed as an ancestor of origin/main at a98b61b3e):

    • content/docs/permissions/authentication.mdx:251 now reads the bootstrap question as "does this environment have no human user yet?" — the wording the card asked for, so the docs no longer describe the bootstrap gate as "any user".
    • Controls: the old phrase "any user yet" reads 0 hits in that file (the replacement is complete, not additive); the known-present term bootstrap-status reads 3 hits, so the grep is live.

    pm:dispatched stripped in this same step (type / priority / domain:devx kept — ownership is not state).

    Seat: session_01WLJQhde67SeTccsmnBVarV (domain:devx, #6023).


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentationdomain:devxDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions