Skip to content

docs(qa): 18.0 sweep round 11 — the walled pass of QA round 3: RUNNER's walled boot under serve, and eight items' producers, recipes and refusals - #24801

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-24579-v18-sweep-round11
Oct 20, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-24579-v18-sweep-round11

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Refs #24579
Clause-②: no

Round 11 of the 18.0 release sweep's wave anchor (#24579), claim 6284734380. This is the walled pass of QA round 3: QA record #24783's checklist-accuracy findings F1 to F8, the round-3 summary's (6284472874) §1 re-point and §6 environment fact, and access-security.scope-depth-asymmetry's pin. Only checklist text changes: RUNNER.md (which carries no revision) and 8 items in 5 area files, each with one revision bump and one history row. No product code, test, pin or changeset text changed.

Base 46bb5e3e54. The edits are commits 79222a3b2e (RUNNER) and 8a5a8b0660 (area files). origin/main then moved to a43405d596 (#24743, one .claude skill reference, disjoint), merged at 423d2726dc. Each history row's ref is written as this branch's name and is filled with this PR's number in one later commit that changes only those 8 strings.

Each finding was re-read in the code at the base before it was written. Where the code disagreed with the finding, the finding was not applied as written, and the table says so.

RUNNER.md

place old → new code anchor read at 46bb5e3e54
"A walled boot is a fixture of its own", the prerequisites sentence (F2) "Each prerequisite below refuses the boot with a FATAL naming itself" → "Through os dev, each prerequisite below refuses …" (QA run #24783 measured all three). Round 10's first sentence, the 18.0.0 / next.5 attribution, is unchanged. os dev spawns serve --dev; resolveAuthSecret() in packages/core/src/stack-auth.ts falls back to DEV_AUTH_SECRET_FALLBACK on a development boot
same entry, new paragraph (F2) A bare os serve in production mode judges none of the three until OS_AUTH_SECRET resolves. Without it AuthPlugin is skipped and the boot comes up DEGRADED: missing core services: auth, not FATAL. It also needs a stable encryption key. resolvePlatformAuthComposition() (reason no-secret); the ⚠ AuthPlugin skipped branch in serve.ts, with the multi-org runtime load inside that branch's composing arm; the owner-email throw in AuthPlugin.init(); assertWalledMembershipPolicyDeclared() skips a kernel with no auth service; printServerReady() prints the DEGRADED line; LocalCryptoProvider's "Refusing to start in production without a stable encryption key"
same entry, prerequisite 1 (F2) "a scratch app that does" → a full copy of examples/app-showcase (with src/), every dependency as link: plus @objectstack/organizations, pnpm install --ignore-workspace. A config that only re-exports the showcase does not boot. the OpenAPI connector's spec: './src/system/connectors/status-openapi.json' (examples/app-showcase/src/system/connectors/index.ts) resolves against the package root at materialization
same entry, new paragraph (F2) Walled personas come from POST /api/v1/auth/admin/create-user: sign-up answers 403 SELF_REGISTRATION_CLOSED, and under invite-only each created user lands with membershipCreated: false. decideAudienceAdmission() (audience-posture.ts); runAdminCreateUser(); reconcileMembership() answers policy-skip under invite-only
new environment fact, after the ss entry (round-3 §6) A SIGTERM to the pnpm wrapper leaves the serve grandchild listening. Start with setsid, read the group id from the listener, and stop the process group. os dev's SIGTERM handler forwards to its child only (beginShutdown() of ServeRestartCoordinator, packages/cli/src/utils/dev-restart.ts). Measured here with a stand-in tree under pnpm -C examples/app-showcase exec: two seconds after a SIGTERM to pnpm the child still answered 200, and a SIGTERM to the group stopped all four processes. It also measured that a backgrounded setsid forks, so $! is not the group id.

Not applied as written: the dispatch's "bare os serve / os start". os start hands its serve child an auth secret (its flag, the environment, or a persisted auth-secret file) and sets OS_CRYPTO_AUTOKEY (packages/cli/src/commands/start.ts). So the secret skip is serve's alone. The entry says this was read from the code and not booted.

Items

finding item field old → new code anchor read at 46bb5e3e54
F3 access-security.no-active-org-session-semantics 5 → 6 personas[0], personas[1], fixtures.requires[1], knownGaps[0], knownGaps[1] The signup race and the removed-member producers → (1) a user the operator creates under invite-only (membershipCreated: false, no sys_member row) and (2) a member that sends set-active {"organizationId": null}. SSO-JIT stays blocked(fixture). reconcile-membership.ts#reconcileMembership (policy-skip) and admin-user-endpoints.ts#bindUserToSoleOrganization. The signup race is closed by ADR-0123 D3's settle in auth-manager.ts#composeDatabaseHooks (defaultActiveOrg). Removal revokes the session or re-points it (membership-ended-session.ts#endSessionClaimsForEndedMembership), and QA measured 401.
F3 same acceptance[0] clause + verify "resolve to nothing" → for a caller with no organization scope: no active organization under isolated, an empty membership set under group. A group member with no active organization reads its own memberships' rows. Governing text: ADR-0123 D2 ("Under group, 'no organization scope' means an empty membership set") and ADR-0105 D2 (the active organization "no longer bounds read reach in group posture — membership does"); tenant-layer.ts#computeTenantLayer0Filter
F3 same knownGaps[3] (new) acceptance[4] left as written: no ADR states the answer for a member-less user's NULL-tenanted login/logout audit rows. The new line names the question and how to score until it is ruled. ADR-0123 D3: rows from this state are refused NULL "in any subsystem", while the ordering fix "must not manufacture a membership"
F3 same knownGaps[4] (new) Names #24784 (open): the group member write answers 500 where isolated answers 403. The clauses stand as written. (QA run #24783)
F3 + F2 same knownGaps[2] "each one absent refuses the boot" → "… refuses an os dev boot …, while a bare os serve in production mode judges none of them until OS_AUTH_SECRET is set". The blocked marker's stated reason changes from the producers to "every clause is a walled leg". The blocked marker itself is unchanged. as RUNNER
F7 access-security.walled-environment-metadata-operator-only 4 → 5 fixtures.requires[2]; knownGaps[0] (F2 sentence) Adds the recipe for the org-owner manage_metadata grant, a system-context engine insert as the dogfood harness does it. The line also gives the two measured refusals. security-plugin.ts#denyTenantPlacement ("outside the caller's organization scope"); ADR-0090 D12 (c) in delegated-admin-gate.ts#organizationBoundaryFailure (manage_metadata is scope: 'platform' in capabilities.ts); wall-environment-metadata-refusal.dogfood.test.ts#boot
F7 access-security.activation-write-operator-gate 7 → 8 fixtures.requires[3]; knownGaps[0] (F2 sentence) the same recipe, for the walled legs (steps[8], acceptance[4]) same
F4 integration-system.webhook-lifecycle 8 → 9 fixtures.requires[0] "under a walled posture it would be refused as belonging to no organization" → under a wall the webhook is deployment-wide too: the operator switches it on, it writes one delivery row per event stamped with that event's organization, and each organization reads only its own rows. The scratch sys_webhook needs definition_json (required) and a lower-case method. auto-enqueuer.ts admitsOrganization (deploymentWide first); wall-declared-webhook-deployment-wide.dogfood.test.ts (its "[ruling A] … a declared webhook is deployment-wide" describe, run under both postures); sys-webhook.object.ts (definition_json required: true, Field.select lower-cases the options)
F5 api-backend.action-activation-door-contract 3 → 4 fixtures.knownGaps[2] "needs an enterprise tenancy runtime no example app composes" → points at RUNNER's walled-boot entry. QA run #24783 measured the order on both postures. actions.ts#handleActionActivationWrite (both authority tiers before shape, body and lookup)
F6 platform-core.settings-organization-isolation-and-platform-rung 4 → 5 fixtures.requires[2], steps[2], knownGaps[1] (new); knownGaps[0] (F2 sentence) "save a tenant key and lock it" → save over HTTP, then lock A's row with a named fixture write (a system write on the run's own scratch DB). The new knownGap says that no HTTP door sets the lock. sys-setting.object.ts apiMethods: ['get', 'list'] (an update answers 405); settings-service.ts#setMany takes a key-to-value patch and never writes locked
F8 identity-auth.workspace-org-switch 4 → 5 fixtures.requires[0], fixtures.requires[1], personas[2] The pre-#24580 "REFUSES TO BOOT … QA run #23166" text → a pointer to RUNNER's walled-boot entry, keeping the seeded-admin owner-email hint. The second membership now comes from the user creating a second organization itself, so add-member is not needed and the admin only mints the member. QA run #24783 (both postures); auth-manager.ts creator role on create
theme B access-security.scope-depth-asymmetry 3 → 4 automated dropped; fixtures.knownGaps[0] added Under round 6's rule (no pin asserts a full clause), the automated field is dropped. The new line says what the three dogfood suites assert and when automated may return. The item is now Tier 2. the three suites never drive the manager, executive or ops personas, or showcase_inquiry (read at the base)

F1: nothing recorded. No ledger field marks an item as walled. The 21 item keys used across the area files hold no tag and no walled marker. scripts/checklist-select.mjs has no walled selector key, so walled:isolated+group resolves to 0 items. The three items matched on words in free text: lead_walled in knownGaps[1] and automated.ref; "boot showcase isolated" in steps[0]; "isolated scratch file DB" in knownGaps[0]. The 14-item list was the runner's own selection.

Governing-text decision (F3). acceptance[0] is aligned, citing ADR-0123 D2 and ADR-0105 D2, which state the group answer. acceptance[4] is left as written, because no ADR states it, and knownGaps[3] names the question. #24784 is named in knownGaps[4].

Left alone, and why

  • platform-core.v18-boot-refusals and areas/cli.json: PR feat(cli,runtime)!: the upgrade ceremony opens — v17 and 18.0 databases take it, and a server serves only a database it created or one the ceremony certified (18.x steps 5 and 6) #24681 (open) edits them, and the claim excludes them.
  • access-security.grant-table-write-contract and access-security.parent-and-organization-write-guards: both carry round 10's walled line, with the same "each one absent refuses the boot naming itself" sentence. They are outside this claim's file surface, so they still read the old way, and the card report names them.
  • access-security.platform-owner-email-anchor and attachments-storage.chunked-upload-integrity: both cite the RUNNER entry but carry no refusal sentence.
  • no-active-org-session-semantics's blocked marker, and its acceptance[1], [4] to [6]: the marker still holds (the stock showcase cannot run any clause). The clauses have no governing text to align them to.
  • History rows of earlier revisions: history is append-only.

Gates

  • Derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack and no paths: 13 families, the same list at 8a5a8b0660 and 423d2726dc. All 13 exited 0 at 423d2726dc, each exit code captured before any pipe: check-ci-filter-parity, check-closing-keyword-parity (and its --self-test), check-comment-mask-corpus, check:doc-formula-expressions, check:cross-package-test-inputs, check:doc-authoring, check:driver-memory-census, check:gitlink-declared, check:nul-bytes, check:platform-checklist, check:refd-timer-probe and check:watch-hint-literal. The --ran reconciliation reads "13 run, 0 NOT-MEASURED (a DERIVED zero — all 13 recorded an exit code)". They are run again on the final head, after the ref fill, and those readings go in the card's report.
  • check:platform-checklist runs in no per-PR CI, so this local reading is its evidence:
    • at 46bb5e3e54: "line citations: 0 survive across 21 swept documents", "symbol anchors: 943/953 resolved", 10 on the residual, 18 file floors held;
    • at 423d2726dc: line citations 0, "symbol anchors: 955/965 resolved", 10 on the residual, 18 file floors held.
    • The census moved: access-security.json 104 → 115, api-backend.json 85 → 86, platform-core.json 95 → 96, identity-auth.json 118 → 117 (its floor is 82). The one anchor removed is membership-policy-gate.ts#MEMBERSHIP_POLICY_ERROR_CODE, part of the F8 parenthetical that was replaced.
  • git merge-tree --write-tree HEAD c6f775cbd7 (PR feat(cli,runtime)!: the upgrade ceremony opens — v17 and 18.0 databases take it, and a server serves only a database it created or one the ceremony certified (18.x steps 5 and 6) #24681's head, fetched from pull/24681/head) exits 0 (tree 7829f37ae3). PR feat(cli,runtime)!: the upgrade ceremony opens — v17 and 18.0 databases take it, and a server serves only a database it created or one the ceremony certified (18.x steps 5 and 6) #24681 touches platform-core.json (item v18-boot-refusals only) and cli.json, so it shares no item with this PR, and no path here is routed to the os-regen driver.
  • The control-byte scan of the 6 files reads 0.

How the edits were made

The area files went through a span-recording editor. It applies each declared op twice, once to the parsed item and once to the item's own text span, and then asserts four things:

  1. the new document equals the old one with the ops applied (key order included);
  2. every other item and top-level key is value-equal to before;
  3. the changed leaf paths are exactly the declared fields plus revision plus one new history row;
  4. the text outside the edited items is byte-identical.

Its changed-path report matched the declarations for all 8 items.

Acceptance notes


Generated by Claude Code

…full-copy scratch app, the admin persona door; the setsid stop recipe

Claude-Session: https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp
Co-authored-by: Claude <noreply@anthropic.com>
…F3–F8 on eight items, scope-depth's pin dropped

Claude-Session: https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 20, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Seat review

ACCEPT · domain:devx seat 1 · os-warren · session_01FM29ZqLTrnPNXxijioZwMp · 2026-10-20T07:13Z · head fdf44fe5e4 · card #24579, round 11 (claim 6284734380)

This seat readies the PR and queues it with auto-merge.


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 20, 2026 07:14
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 20, 2026 07:14
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 20, 2026
Merged via the queue into main with commit 307ce4c Oct 20, 2026
40 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-24579-v18-sweep-round11 branch October 20, 2026 07:41
os-warren pushed a commit that referenced this pull request Oct 20, 2026
Conflict in access-security.no-active-org-session-semantics only, both
sides kept: round 11 of the wave anchor (#24801) rewrote knownGaps[0]-[4]
and took revision 6; this branch's acceptance[7] gap follows them as
knownGaps[5], and its history row moves to revision 7.

Claude-Session: https://claude.ai/code/session_01MRkuLGosywLTY6EMcP6fGK
Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants