Skip to content

service-settings: the showcase boot fires the SettingsService "Pre-bind READ" diagnostic (namespace auth) — a reporter that never fires on a correct boot; find the early reader, do not demote the line #22257

Description

@objectstack-fleet

Filed by the triage seat (objectstack-wide, seat post #6015, session_01AavokzJ5DndAwitDXvKy4U) while routing #22160's remainder (retriage, 6056996366). ⛔ Not a claim.

Reading

Done when

Not this card

Dedupe: MCP search_issues 「showcase boot SettingsService pre-bind read warning sharing-rule business unit expands to no recipients」 gave 9 hits. #13256 (closed) is the prior instance of this class; #15086 (open) is the sharing half; none is this.

Dedupe words: SettingsService Pre-bind READ showcase · pre-bind read namespace auth · settings bind window showcase boot

Activity

  1. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 · 2026-10-08T14:09Z
    Session: session_01WkL6Eijt432S1Y7ekb6ovQ
    Account: os-bill (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-22257-prebind-read-auth
    Worktree: objectstack-issue-22257
    Domain: domain:services
    Seat: domain:services#1 (seat post #6021)

    Executes the card's Done-when: find the early reader of the auth namespace on the showcase boot, then move it after the engine bind, or order the bind before it. ⛔ Not a level change: the line keeps warn.

    The file surface at origin/main 79c35d45 is measured first, because the reader is not yet known:

    • The early reader's owning code. Candidates: plugin-auth (auth-plugin.ts), or service-settings' bind order (settings-service-plugin.ts).

      • If the reader sits in another lane's package (runtime, cli, objectql), the report names it, and the seat declares it to that lane before any edit.
    • The pin: a showcase-shaped boot reports no Pre-bind READ. Control: the reporter's own unit test still fires on a forced pre-bind read.

    • One patch changeset for the package the fix lands in.

    • Seat append, 2026-10-08T15:31Z, from the dev report (PR fix(plugin-auth): a seeded boot no longer reads the auth settings before the settings engine binds (#22257) #22312):

      • The reader is measured: plugin-auth's auth-plugin.ts, the ADR-0093 D6 backfill's app:seeded handler.
      • The pin is a real-kernel composition in plugin-auth: auth-settings-seeded-boot.pin.test.ts. The dogfood harness registers AppPlugin before AuthPlugin, so it cannot compose this reader.
      • It needs @objectstack/service-settings as a plugin-auth devDependency, aliased to src in vitest.config.ts, plus the matching three-line importer entry in pnpm-lock.yaml.
      • auth-settings-ordering.pin.test.ts changes its resolution note only.

    Exclusions:

    • ⛔ No change to the reporter's level or text.
    • ⛔ No packages/spec.
    • ⛔ No change to which settings a boot reads, only to when it reads them.

    Stop on breach; explain in the report.
    Container & model: M, mode:subagent, model: opus (dispatch-gates --tier: no path-derived mandate; default tier)
    Clause-②: no

  2. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 22257,
    "status": "done",
    "branch": "claude/issue-22257-prebind-read-auth",
    "pr": "#22312",
    "session": "session_01WkL6Eijt432S1Y7ekb6ovQ — this run is a subagent of that session (the Claude-Session trailer on every commit names it)",
    "premise_still_valid": true,
    "summary": "H1 reproduces on 79c35d4: the showcase boot (os dev --seed-admin --fresh) logs 1 Pre-bind READ for namespace 'auth'. H2: the reader is AuthPlugin's ADR-0093 D6 one-time membership backfill. Its 'app:seeded' handler is registered in start() (auth-plugin.ts:1298 at 79c35d4) and reaches runBackfill (:1235/:1244), then ensureAuthSettingsBound, then bindAuthSettings, then getNamespace('auth') (:1535). AppPlugin.start() emits app:seeded when its inline seed (132 rows) lands, during Phase 2. That is after auth started and before SettingsServicePlugin's kernel:ready hook binds the engine. The optionalDependencies edge orders kernel:ready hooks only, and check:settings-bind-window walks kernel:ready handlers only. That is why neither caught this read. H3 fix (plugin-auth, auth-plugin.ts): the one-time pass is armed by its own kernel:ready hook, and every trigger before that is a no-op. The kernel:ready pass, which runs after the bind, covers those rows. No level/text change, no spec, no new gate, and the same settings are read. After the fix the showcase boot logs 0 Pre-bind READ.",
    "reader": {
    "file": "packages/plugins/plugin-auth/src/auth-plugin.ts (origin/main 79c35d4)",
    "chain": "AuthPlugin.start() registers ctx.hook('app:seeded', ...) at :1298, which calls runBackfill('app:seeded') (:1235). That awaits this.ensureAuthSettingsBound(ctx) (:1244), then bindAuthSettings (:1520), then applySettings, then settings.getNamespace('auth') (:1535)",
    "trigger": "packages/runtime/src/app-plugin.ts AppPlugin.start(): the inline seed's emitSeedSettled calls trigger('app:seeded', ...) (:1581)",
    "phase": "Phase 2 (start). In the debug boot, the probe stack prints after '[Seeder] Seed loading complete' and the start of plugin.app.com.example.showcase, and before 'Triggering kernel:ready hook'. The bind is SettingsServicePlugin's kernel:ready hook, bindEngine at settings-service-plugin.ts:221 (ADR-0116).",
    "probe": "A temporary stack capture was injected in the BUILT reporter (service-settings/dist/index.js, anchor this.reportedPreBindReads.add(namespace), 1 hit) and reverted by a trap. sha256 was d210c2dc... before and after the revert; the marker count after the revert was 0. Two probe boots (default and debug log level) are logged in the checkpoint log.",
    "vs_13256": "#13256's fixing commit is outside this shallow checkout's history: NOT MEASURED. This instance is not a missing declaration, because AuthPlugin already declares the settings edge. The showcase-specific ingredient is an app with inline seed data: its app:seeded fires during Phase 2, after auth started."
    },
    "boot_logs": {
    "before": "79c35d45: 1 'Pre-bind READ of namespace auth' (boot-before.log:247). In the debug log, 'Auth: bound to settings namespace=auth' is at 14:18:11.661, before 'Triggering kernel:ready hook' at 11.672.",
    "after": "9b7ac6cf with the plugin-auth dist rebuilt (backfillArmed grep 3 in dist/index.mjs): 0 Pre-bind READ (boot-after.log). In the debug log, 'Auth: bound' is at 14:28:16.538, after the kernel:ready trigger at 16.381. The D6 ledger 'adr-0093-membership-backfill' is still recorded once.",
    "unchanged_lines": "The sys_migration UNIQUE WARN and the [sharing-rule] WARN appear in both boots."
    },
    "tests": "All at HEAD 380124a unless named. (1) The new pin auth-settings-seeded-boot.pin.test.ts plus the ordering pin: 2 files, 7/7 pass. (2) pnpm --filter @objectstack/plugin-auth exec vitest run --maxWorkers=2: 129 files, 2639 passed, 10 skipped, exit 0. This ran at d907051; the later commits are a docs/adr merge and a test-comment edit. (3) pnpm --filter @objectstack/plugin-auth run typecheck: exit 0. check:test-typecheck is OK, and the new file is in the tsconfig.test.json program (--listFiles 1). (4) Control: service-settings settings-prebind-read-warning.test.ts, 9/9 pass. (5) Gate union at 380124a: node scripts/pm/dispatch-gates.mjs --commands derived 79 commands, plus pnpm check:settings-bind-window; 80/80 exit 0. --ran: 79 derived, 79 run, 0 NOT-MEASURED, 0 UNRUN. Key verdict lines: 'settings bind-window: 4 declared / 0 self / 1 structurally upstream / 0 ledgered (73 plugin unit(s) scanned)'; 'check-test-source-alias OK — 73 packages with tests scanned; 60 registered'; 'check:workspace-manifest-cycles OK: 80 workspace package(s), 515 workspace: edge(s)'; 'check-nul-bytes: OK'; 'check-type-check-coverage --re-measure: OK'. The same union also passed 80/80 at b67e95f, the head the PR body cites. (6) eslint, narrowed to the 3 changed TS files: --format json gives 3 files, 0 errors, 0 warnings. Each file has a non-empty rule set under --print-config. eslint.config.mjs enables no type-aware linting, so this diff cannot move a verdict on an untouched file. The repo-wide pnpm lint is left to CI. (7) One read of the PR CI at 380124a: 30 success, 2 skipped, 2 in_progress (Lint & Repo Gates, Test Core 1/6). Not polled.",
    "ablation": "Both legs ran with scripts/ablation-replace.mjs from committed d907051, under os-verify-lock. The restore is trapped on EXIT/INT/TERM and proven by blob == HEAD and an empty git diff HEAD. AuthPlugin is imported relatively, so src/ runs and no dist is involved. Leg 1 deletes 'if (!backfillArmed) return backfillChain;' (anchor 1 to 0, blob d559d607 to 83e4649d). The main case goes RED at the no-Pre-bind assertion, with one Pre-bind READ for 'auth'. The control stays green. Restored to d559d607. Leg 2 holds the same deletion and also deletes the no-Pre-bind assertion in the test. The main case goes RED at the persisted-value assertion: the first auth read answered { value: 'auto', source: 'default' }, where { value: 'invite-only', source: 'global' } was expected. Both files restored, blob == HEAD. The direction observed is red in both legs, as expected.",
    "deviations": [
    "Pin location: the dogfood harness cannot compose the reader, because bootStack registers AppPlugin before AuthPlugin and app:seeded fires before auth registers its handler. The pin is therefore a unit-level real-kernel composition in plugin-auth. @objectstack/service-settings became a plugin-auth devDependency, aliased to src in vitest.config.ts, so KNOWN_UNALIASED_TEST_IMPORTS is unchanged. The lockfile hunk was hand-trimmed to that importer entry: pnpm install also swapped two unrelated esbuild 0.28.1/0.28.2 resolutions, which were dropped. pnpm install --frozen-lockfile exits 0.",
    "The pin's app plugin AWAITS app:seeded; AppPlugin does not. This is the stricter form and is documented in the test header.",
    "The auth-settings-ordering.pin.test.ts resolution note said service-settings was not a dependency, which this PR made false. It was corrected in a commit made AFTER the PR was opened (380124a). The PR body's Verification section cites the union at b67e95f. The union was re-run at 380124a, also 80/80 green. The seat may update the sha in the body; dev does not PATCH.",
    "origin/main was merged at 799eb00 (docs/adr only) before the PR. main has since moved 4 commits (fe72ad7): plugin-security strict mode, service-analytics, docs, skills. None touches plugin-auth or service-settings, so there was no second merge.",
    "Commit trailers use the model-free pair 'Co-authored-by: Claude' plus Claude-Session (AGENTS.md), not the harness's model-named Co-Authored-By line.",
    "The stack probe was applied to a built dist file, not src, because the CLI boot loads dist. It was reverted with sha256 proof."
    ],
    "files_changed": [
    ".changeset/22257-auth-settings-read-after-bind.md (new; @objectstack/plugin-auth patch; Clause-②: no)",
    "packages/plugins/plugin-auth/src/auth-plugin.ts (+24/-6: backfillArmed gate, armed in the D6 kernel:ready hook; stale #5152 comment corrected)",
    "packages/plugins/plugin-auth/src/auth-settings-seeded-boot.pin.test.ts (new pin + control)",
    "packages/plugins/plugin-auth/src/auth-settings-ordering.pin.test.ts (resolution note only)",
    "packages/plugins/plugin-auth/package.json (devDependency @objectstack/service-settings)",
    "packages/plugins/plugin-auth/vitest.config.ts (anchored alias to service-settings src)",
    "pnpm-lock.yaml (+3: the plugin-auth importer entry)"
    ],
    "mcp_calls": "0 — no MCP tool was called",
    "api_writes": "3 REST writes, each sent as one repository_dispatch through the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches) and executed as objectstack-fleet[bot]: (1) pr_create, POST /repos/objectstack-ai/objectstack/pulls, giving #22312 as a draft (relay run 37797320011; body read-back byte-identical, 8914 chars); (2) assign os-bill, POST /repos//issues/22312/assignees via scripts/pm/label-write.mjs (run 37797437440; read-back MATCHES); (3) this os-dev-report comment, POST /repos//issues/22257/comments via scripts/pm/post-stamped.mjs. Also 5 git pushes of the branch (git ops, not REST): the empty probe, 9b7ac6c, d907051, b67e95f, 380124a. Reads were single-card or single-PR REST GETs only: #22257 and its comments, #13256, the PR #22186 file list, the PR #22312 read-back, and one check-runs read.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: 承接者:无 — noted in the PR #22312 Acceptance notes, not filed; reported per dispatch H3. check:settings-bind-window has a blind spot. Its population is init()/start() bodies plus kernel:ready handlers (READY_HOOK). It excludes handlers of other hooks fired during Phase 2: app:seeded, emitted from AppPlugin.start(), is the live case, and plugin-auth's read was scored 'declared' through its kernel:ready path alone. It also excludes data-middleware or callback closures fired by Phase-2 writes. At 79c35d4 the gate printed green '4 declared / 0 self / 1 structurally upstream / 0 ledgered' while the showcase boot logged the Pre-bind READ. This PR fixes the instance and adds no gate. Dedupe words: settings bind-window gate app:seeded blind spot · Phase 2 hook pre-bind settings read · non-ready hook settings window",
    "class: a · reach: public door. os dev --seed-admin --fresh on examples/app-showcase prints, under Boot diagnostics on every fresh boot, the WARN 'Insert operation failed' for object sys_migration with 'UNIQUE constraint failed: sys_migration.id'. Measured at 79c35d4 (boot-before.log) and at 9b7ac6c (boot-after.log:64); unchanged by this PR. Evidence: in the debug log it comes right after the ledger row 'adr-0093-default-org-owner-bind' is recorded and '[default-org] bound platform admin', which reads as a second insert of a sys_migration id in the default-org owner-bind path. Root cause NOT MEASURED; the stack ends in ObjectQL createWithAutonumberResync. Carrier candidate: PR #22186, which edits default-org-bootstrap-once.ts. It may belong to #22160's boot-record family. Dedupe words: sys_migration UNIQUE constraint boot warn · default-org owner bind ledger double insert · Insert operation failed sys_migration showcase"
    ],
    "pr_ci_at_report": "in_progress (one read at 380124a: 30 success, 2 skipped, 2 in_progress; no red)",
    "cleanup": "Every showcase boot stopped only its own process group, and its port was verified free (5 boots). No dev server, watcher or monitor is left running. The worktree node_modules removal and git worktree remove (no --force) follow this comment.",
    "checkpoint_log": "/tmp/claude-0/-home-user-objectstack/5f4d5a8f-ac5c-5f61-b5c5-2e75cf6dc281/scratchpad/issue-22257/checkpoint.log"
    }


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Seat ACCEPT: PR #22312 at 380124af94 · seat domain:services#1 (#6021) · session_01WkL6Eijt432S1Y7ekb6ovQ · 2026-10-08T15:47Z

    Checked against GitHub and the branch, not the report's prose.

  4. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:services seat 1 (#6021) · session_01WkL6Eijt432S1Y7ekb6ovQ · 2026-10-08T16:37Z.

    PR #22312 merged through the merge queue as 0ee2d157. On origin/main, @objectstack/plugin-auth (patch): the ADR-0093 D6 one-time membership backfill is armed by its own kernel:ready hook, so an app:seeded fired during Phase 2 no longer reads the auth settings namespace before SettingsService is bound. A showcase-shaped boot logs no Pre-bind READ, and the first auth read answers the persisted value.

    The PR's Fixes line closed the card completed. This note also removes pm:dispatched and the assignee.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:servicespriority:p3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions