Skip to content

docs(qa): 18.0 sweep anchor round 5 — the walled-posture and second-organization themes, runner environment facts, and two carried notes - #24687

Merged
objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/issue-24579-v18-sweep-round5-themes-runner
Oct 20, 2026
Merged

objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/issue-24579-v18-sweep-round5-themes-runner

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Refs #24579
Clause-②: no

Round 5 of the 18.0 release sweep's wave anchor (#24579), one PR in four parts. Rounds 1–4 landed as #24622, #24632, #24649 and #24671. This is a partial landing: the card keeps §2's other two themes and §4 for later rounds.

The diff is the checklist ledger and its runner docs only: four area files, RUNNER.md and FOLLOW-UPS.md. No product code, test or pin changes. Every edited area item takes one revision bump and one history row (ref: this PR). Every finding was re-derived from source before it was edited. The base is bfc1539fe0, merged with origin/main 92ce3af404 before this PR opened. Main's 8 new commits touched none of the cited sources except .objectui-sha (#24660 moved the pin 4016370a → 12dc7b47c340), and the one fact that reads it, the map-tile entry, was re-checked at the new pin. Findings that did not hold are left alone and listed at the end, each with the reading that refutes it.

Part (a) — §2's two wave themes

What the ledger allows. planned is an item-level status only. statusFieldProblems in scripts/check-platform-checklist.mjs judges status per item; a planned item must carry no steps; no clause carries a status of its own; and checklist-select.mjs drops a planned item from every runnable set. So a walled leg on an otherwise runnable item can only be recorded in knownGaps. The gate validates the planned shape and does not read knownGaps at all (PM H3).

Where 18.0 refuses (PM H1 holds). The walled refusal lives in one place: walledPostureRefusal() in packages/cli/src/commands/serve.ts. Serve.run asks it right after the posture gate, before a config is read, a plugin is mounted or the HTTP server starts. os dev and os start boot through serve. The organizations-runtime load and OS_ALLOW_DEGRADED_TENANCY come later in the same method, so nothing skips the refusal. Kernel-level boots (bootStack, the dogfood wall suites) never pass through serve, which is why the pins still prove walled behaviour.

Measured live at bfc1539fe0 with the built CLI:

  • os serve, OS_TENANCY_POSTURE=isolated: exit 1, ✖ FATAL: tenancy posture 'isolated' is not supported in 18.0 (NOT_IMPLEMENTED).
  • group: the same, naming group.
  • OS_MULTI_ORG_ENABLED=true: the same, naming isolated.
  • single (the control): passes the gate and stops later, on "Nothing to serve".
  • os start under isolated: the same FATAL.

The refusal names no release ("an 18.x release"), so the knownGaps say "a later 18.x release".

Where the second organization is refused (PM H2). The door is beforeCreateOrganization in packages/plugins/plugin-auth/src/auth-manager.ts. It answers 403 ORGANIZATION_CREATION_DISABLED wherever the effective posture enforces no wall, and on 18.0 that is every boot. Two more facts close the other routes: sys_organization declares apiMethods: ['get', 'list', 'update'], so the data API has no create, and 18.0 serves fresh installs only. Per-item decision: an org-switch clause is the §2 theme ("not scored on a stock 18.0 boot"). A planted second organization is a fixture route. QA run #24560 used one, a system write, and the knownGap says such a run must declare it. That route itself stays with §4.

Shape. The ledger has no area-level or README-level slot for a wave theme. An area file carries $comment and provisioning recipes, and a recipe must have a provisioning.use consumer. The README has no such section. RUNNER.md's "Environment facts the runner should not re-derive" is the standing-facts slot runners read first. So each theme is stated once there, as the entries "18.0 boots the single tenancy posture only" and "A stock 18.0 boot holds exactly one organization". Each item's knownGap points at the entry and restates the refusal in one sentence with its anchor. That keeps the item readable on its own through checklist-select.mjs, and lets the anchor gate resolve each citation (a RUNNER.md anchor would red: the anchor floor file declares no floor for RUNNER.md). The entry also settles the verdict word. The live leg is recorded skipped with the entry cited, as the withdrawn ownership command's clauses are, and never blocked(fixture). The sweep's records had scored it both blocked(environment) (QA runs #24557, #24559) and blocked(fixture) (QA run #24558).

knownGaps vs planned, per item, on the four axes. Every item below takes knownGaps. The common reason on each axis:

  • Business need. Each item has runnable 18.0 clauses: its pin clause, plus single-posture clauses. The walled capability is built and pin-verified in-process. 18.0 refuses it at the CLI boot by ruling.
  • Long-term. The clause stays where it is and returns when the refusal lifts. A planned split would duplicate clause text across two ids, delete the steps a planned item may not carry, and need a passing run to promote it back.
  • AI-error. planned would tell the next sweep the capability is unbuilt, which is the wrong debt (README: "Scoring one as the other sends the next sweep to fix the wrong thing"). The knownGap names the exact clauses and the verdict word.
  • Startup scope. No new ids and no new surface.
item fields edited revision run record choice and why
platform-core.settings-organization-isolation-and-platform-rung fixtures.knownGaps (new, [0]); acceptance[3].clause 1 → 2 QA runs #24557, #24558 (c2, c3) knownGaps. acceptance[0] (pins) and [1] run on single. acceptance[3] was a second walled leg: settings-service.ts#organizationlessTenantKeyError refuses only under a walled posture, and the pin asserts single does not refuse. So the clause is now marked walled:
access-security.walled-environment-metadata-operator-only fixtures.knownGaps (new, [0]); steps[0] 1 → 2 QA runs #24556, #24558, #24559 (c1, c2, N0) knownGaps. acceptance[0]'s pins are the 18.0 evidence. steps[0] now declares sharingModel (round 2's note): the admitted repeats in steps[2]/[3] reach the save door's authoring rules, which refuse an object with none 422 security-owd-unset (validate-security-posture.ts#SECURITY_OWD_UNSET, error tier). The walled refusal answers ahead of them (meta-item-write-routes.ts)
access-security.activation-write-operator-gate fixtures.knownGaps[0]; steps[8]; acceptance[4].clause; acceptance[4].verify; variants[1]; variants[2] 3 → 4 #24579 §2 knownGaps (re-grounded). The legs were blocked(fixture) on an "enterprise runtime" gap. On 18.0 the refusal runs ahead of the runtime load, and the runtime is open code since ADR-0132. Clause 5 keeps its unit pins as its oracle
access-security.grant-table-write-contract fixtures.knownGaps (new, [0]) 2 → 3 QA run #24559 (c4, live leg) knownGaps. Rounds 2–3 named acceptance[4]. ⚠️ The refusal's predicate is posture-independent (pin case "the predicate is the same on every posture"), so the leg is walled by its wording, not its mechanism. Recorded, not re-pointed: a single-posture rig is not measured here
access-security.parent-and-organization-write-guards fixtures.knownGaps (new, [0]) 1 → 2 QA run #24559 (c1, live leg) knownGaps. The emptied-organization refusal is a Layer 0 rule, and its pin's control keeps single unchanged
access-security.no-active-org-session-semantics fixtures.knownGaps[2] (appended) 2 → 3 #24579 §0 / §2 knownGaps. Every clause is walled, and the item is already blocked {fixture, #9334} with a pin. planned would also be wrong here: the capability is built and pinned. The marker is unchanged
attachments-storage.chunked-upload-integrity fixtures.knownGaps[0] (round 2's pointer sentence replaced by the theme's statement, not duplicated) 3 → 4 QA runs #24560, #24558 (c3) knownGaps (second-organization theme). acceptance[3] has no chunked-door pin either, so a stock 18.0 run carries no verdict on it

Taken, but not in the card's five: no-active-org-session-semantics (its clauses need a walled boot) and chunked-upload-integrity (the second-organization theme). Read and left alone: platform-owner-email-anchor, suggested-binding-loop, public-form-withdrawal-layers and the three attachments items carrying the CROSS-TENANT marker (see the end). No item in automation.json carries a walled or org-switch clause.

Part (b) — RUNNER.md

RUNNER.md records its own provenance inline: the measured-at sha, the QA run and the card section, inside each entry. The rows below follow that convention.

section lines (head) edit provenance
Environment facts → Playwright entry 172–197 (173–179, 184, 191 changed) @playwright/test 1.62.1 → 1.63.0, chromium build 1234 → 1243 (three places). The Check reads browsers.json from the pnpm store, because the root node_modules/playwright-core the old line named does not exist re-measured at bfc1539fe0; #24579 §6
Environment facts → self-registration → recipe 1 "Invite, then sign up" 337–356 (341–356 added) Sign-up binds the invitee as member and leaves the invitation pending (reconcileMembership). Any other role takes effect only after the persona's own POST /api/v1/auth/organization/accept-invitation with {"invitationId": "ID"} (adoptExistingMembership, never lowers a grade). Email verification is not required (requireEmailVerificationOnInvitation: false) source at bfc1539fe0; pin accept-invitation-adopt-membership.test.ts 6 passed; QA run #24616
Environment facts → new "18.0 boots the single tenancy posture only" 455–477 the walled theme's shared statement, the verdict word, the pin, the live measurement bfc1539fe0 live + pin 5 passed; QA runs #24557, #24558, #24559
Environment facts → new "A stock 18.0 boot holds exactly one organization" 479–496 the second-organization theme's shared statement source + pin org-create-posture-gate.test.ts 25 passed; QA runs #24560, #24558
Environment facts → new "One container builds one tree at a time" 498–516 the build race (build-console.sh runs turbo builds in this checkout), the cgroup limit, --concurrency=2 / --maxWorkers=1, the OBJECTUI_DEPS_BUILD_CMD override, exit 137 #24579 §6; the cgroup read 14343688192 at bfc1539fe0; QA run #24598's fingerprint. The OOM is not re-run
Environment facts → new "OS_TEST_TIERS narrows packages/cli's vitest population" 518–531 nightly vs queue population; only packages/cli owns tier files (1 package, 83 files) nightly-tiers.mjs --packages at bfc1539fe0; #24579 round 2 (6272032736); QA runs #24556, #24558, #24598
Environment facts → new "scripts/qa/qa-rollup.mjs has two blind spots" 533–546 classifySelector('area:X') → other (16 records of 2026-10-16); page 2 via the repositories/ID path → proxy 403, and fetchRunRecords throws classifySelector run on 5 selectors; page-1 Link header → 403, repos/OWNER/REPO page 2 → 200 (130 records), at bfc1539fe0; #24579 §6
Environment facts → new "A map view draws its markers under a 'Map failed to load' banner" 548–559 DEFAULT_MAP_STYLE is unreachable behind the proxy, and the amber banner keeps the markers objectui ObjectMap.tsx at 4016370a and 12dc7b47c340; curl → CONNECT tunnel failed, response 403; QA run #24616 (round 4's note)

scripts/qa/ is not edited (ruling).

Part (c) — FOLLOW-UPS.md

The file's own convention: append, never rewrite; a corrected row keeps its old content as "⚠️ This row used to …; DATE with #PR" (rows E2 and §6's second row), and a closed row carries its marker in bold (FIXED in #N, closed by …).

row line (head) edit
§10b E3 615 The stale tail ("… the other two are still owed") becomes "⚠️ This row used to end that …; paid 2026-10-19 with #24649 (cc95f5e63e)". rest-crud-config-contract and rest-batch-config-contract (revision 3 each) name the mount pin in automated.ref and say in knownGaps[1] that the mount half is pinned. Measured in api-backend.json at bfc1539fe0

Part (d) — automation.json

item fields edited revision run record
automation.paused-run-trigger-record-masked fixtures.knownGaps[0] 2 → 3 round 3's report on #24579 (6277457406)

"showcase_approver_bindings is draft on purpose" becomes status: 'obsolete' on purpose (approver-bindings.flow.ts#ApproverBindingsFlow). Its docblock says why not draft: a draft flow binds and fires like an active one. It is still the only flow on showcase_field_zoo, so the gap's conclusion holds.

Findings left alone, each with its refuting reading

  • §6 "scaffold-e2e.yml has not run on the candidate sha; its latest scheduled run failed on 9112bcd8" (round 2). Re-read: still true. The newest schedule run is 9112bcd887, failure, 2026-10-19T03:39Z, and only pull_request runs follow it. Not taken: it is a dated CI state that the next scheduled run changes, not a standing environment fact.
  • §6 "objectui live e2e is still red at its own pin 4016370a" (round 2). Not taken. It is §2's objectui-live-e2e theme, which the dispatch gives to the next round, and the pin it names has since moved (chore(console): move the objectui pin 4016370af3c9 → 12dc7b47c340, regime C for sharing rules (objectui#13050) #24660 → 12dc7b47c340). Not re-measured: that needs the objectui live suite.
  • grant-table-write-contract acceptance[4] "needs a walled boot" (card §2, rounds 2–3). Half refuted: grant-holder-membership-refusal.ts's predicate does not read the posture. The knownGap records this and keeps the clause as written. A single-posture rig, a grantee with no membership in the writer's organization, is a fixture route and is not measured here.
  • The card's "five items" list. Not enough on its own: no-active-org-session-semantics (every clause walled) and chunked-upload-integrity (org switch) also carry the themes and were taken.
  • platform-owner-email-anchor. No clause needs a walled boot: acceptance[5], the walled half, is test-only already. steps[0]'s parenthetical still reads "a walled posture … refuses to boot with it unset (plugin-auth init …)". On 18.0 the boot is refused earlier, set or unset. Noted, not edited: the item boots single and scores nothing on it.
  • suggested-binding-loop negative[1] ("under a walled posture only the platform operator may accept"). A negative note, not a clause. Left alone.
  • public-form-withdrawal-layers. Its set-active switches between the Default Organization and null, which a stock 18.0 boot can do, and it already puts the walled half out of scope.
  • attachments-storage download-authz-both-sides, read-inherits-parent-rls, attach-requires-parent-edit (the CROSS-TENANT marker). That marker is about the dogfood matrix's skipIf block, already blocked(dependency). None of their acceptance clauses needs a walled boot.

Measurements (at bfc1539fe0)

  • Built under os-verify-lock: turbo run build --concurrency=2 --filter='@objectstack/plugin-auth^...' (27/27, cache), then --filter='@objectstack/cli^...' (60/60, 37 cached, held 101 s), then --filter=@objectstack/cli. VERDICT command-exit 0 each time.
  • Pins, under the lock, vitest run --maxWorkers=2, VERDICT command-exit 0:
    • plugin-auth org-create-posture-gate.test.ts: 25 passed.
    • plugin-auth accept-invitation-adopt-membership.test.ts: 6 passed.
    • cli serve-walled-posture-refusal.test.ts: 5 passed.
  • Live walled probes: listed in Part (a).
  • Proxy reads: classifySelector on 5 selectors, the qa-run page-2 403 and 200, and the demotiles CONNECT 403.

Gates

Derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 13 families for the 6 paths, against merge base 92ce3af40, tree cfb070a467. All 13 ran at cfb070a467, each exit captured before any pipe, all exit 0:

  • node scripts/check-ci-filter-parity.mjs
  • node scripts/check-closing-keyword-parity.mjs
  • node scripts/check-closing-keyword-parity.mjs --self-test
  • node scripts/check-comment-mask-corpus.mjs
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions
  • pnpm check:cross-package-test-inputs
  • pnpm check:doc-authoring
  • pnpm check:driver-memory-census
  • pnpm check:gitlink-declared
  • pnpm check:nul-bytes
  • pnpm check:platform-checklist
  • pnpm check:refd-timer-probe
  • pnpm check:watch-hint-literal

--ran reports: "13 derived famil(ies) accounted for — 13 run, 0 NOT-MEASURED (a DERIVED zero …)".

check:platform-checklist runs in no per-PR CI, so this local reading is its evidence: "check-platform-checklist: OK — 16 areas, 327 items (322 active, 1 planned)". Symbol anchors are 875/885 at bfc1539fe0 and at merged origin/main 92ce3af404, and 886/896 at head: 11 added (access-security +7, platform-core +2, attachments-storage +1, automation +1), 0 lost, 10 on the #16898 residual, 18 file floors held. RUNNER.md carries no anchor, by design (it has no floor entry). check:platform-checklist --changed-from was not run: no symbol was renamed or removed. A control-character scan of the six files is empty.

Changeset

skip-changeset. docs/qa/** sits in no package, so this diff publishes nothing.

Not in this PR


Generated by Claude Code

…rganization themes, runner environment facts, and two carried notes

Part (a): seven items record that a stock 18.0 boot cannot run their walled or
second-organization legs (knownGaps, one revision and one history row each):
settings-organization-isolation-and-platform-rung, walled-environment-metadata-
operator-only, activation-write-operator-gate, grant-table-write-contract,
parent-and-organization-write-guards, no-active-org-session-semantics and
chunked-upload-integrity. Part (b): RUNNER.md's environment facts gain the two
theme entries and four section-6 facts, the Playwright entry is re-measured, and
the invite recipe gains the accept-invitation step. Part (c): FOLLOW-UPS.md row
E3 records its payment. Part (d): paused-run-trigger-record-masked's knownGap
names the flow's real status.

Claude-Session: https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp
Co-authored-by: Claude <noreply@anthropic.com>
… the Playwright check reads the store path

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 19, 2026
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Oct 19, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Seat review

ACCEPT · domain:devx seat 1 · os-warren · session_01FM29ZqLTrnPNXxijioZwMp · 2026-10-19T23:45Z · head d62a862771 · card #24579 round 5 (claim 6278881973)

  • Form.

    • Draft, base main, first lines Refs #24579 / Clause-②: no.
    • Assignee os-warren, label skip-changeset.
    • node scripts/pm/check-governed-merges.mjs --pr 24687 → NOT governed, 238 changed lines.
    • git merge-tree against main 92ce3af404 is clean.
  • Scope. The six claimed paths, +213 / −25: four area files, RUNNER.md and FOLLOW-UPS.md. No package, test or pin.

  • Ledger invariants, by parse against 92ce3af404. Eight items differ:

    • platform-core 1;
    • access-security 5;
    • attachments-storage 1;
    • automation 1.

    Each took one revision bump and one history row with ref docs(qa): 18.0 sweep anchor round 5 — the walled-posture and second-organization themes, runner environment facts, and two carried notes #24687. No item was added or removed. No area-level key moved.

  • The two themes, checked at the head.

    • Walled postures. walledPostureRefusal (packages/cli/src/commands/serve.ts:6266, called at :2419) refuses isolated / group / OS_MULTI_ORG_ENABLED=true before config, mount or listen. The dev measured it live on os serve and os start (exit 1, FATAL NOT_IMPLEMENTED), with a single control.
    • Second organization. ORGANIZATION_CREATION_DISABLED_CODE (auth-manager.ts:1435, used at :3576) answers 403 on every 18.0 boot.
    • Where it is written down. Each theme is stated once, under RUNNER.md's environment facts. Each item's new knownGaps line points at that entry and repeats the one anchored sentence.
    • knownGaps over planned. Every item chose knownGaps over planned, for the same reasons: planned is item-level only, and each item keeps runnable 18.0 clauses.
  • Verdict word, accepted. A walled or second-organization live leg is recorded skipped, citing the entry, ⛔ never blocked(fixture). No fixture provisions a posture the release refuses. This fixes the wave's split between blocked(environment) (QA run · platform-core (27/34) · 5b14b7f3 · 2026-10-19 · 21 PASS / 4 PARTIAL / 2 FAIL / 0 BLOCKED / 7 NOT-RUN #24557, QA run · access-security (31/35) · 5b14b7f3 · 2026-10-19 · 25 PASS / 4 PARTIAL / 2 FAIL / 0 BLOCKED / 4 NOT-RUN #24559) and blocked(fixture) (QA run · since:v18 (48/48) · 5b14b7f3 · 2026-10-19 · 38 PASS / 7 PARTIAL / 3 FAIL / 0 BLOCKED / 0 NOT-RUN #24558).

  • RUNNER.md.

    • Four §6 facts, re-measured:
      • the one-tree-at-a-time build and its memory cap (cgroup 14 343 688 192 bytes);
      • OS_TEST_TIERS;
      • qa-rollup's two blind spots, including the page-2 /repositories/{id} 403;
      • the map tiles, at both console pins.
    • The Playwright entry re-measured at 1.63.0.
    • The invite recipe now adds the accept-invitation step. It names reconcileMembership (writes member) and adoptExistingMembership (applies the invited role), and its pin passes 6.
  • FOLLOW-UPS.md E3 records its payment by docs(qa): 18.0 sweep anchor round 3 — the approvals token door after the reminder link removal, a consumed-changeset citation, and §3 accuracy corrections in six areas #24649, in the file's own "This row used to" convention.

  • Gates.

    • The dev's dispatch-gates union: 13 derived, 13 run, all exit 0 at d62a862771.
    • check:platform-checklist anchors 875/885 → 886/896 (+11, none lost).
    • Check-runs at d62a862771: 39, all completed, 31 success, 8 skipped. node scripts/pm/check-expected-skips.mjs --pr 24687 → OK — 8 skipped check-run(s), every one in the roster (exit 0).
    • No review and no comment.
  • Carried on the card.

    • activation-write-operator-gate cites source lines in a comma-range spelling the line-citation limb does not catch.
    • platform-owner-email-anchor steps[0]'s plugin-auth parenthetical is superseded by the walled refusal.
    • A single-posture rig could give grant-table-write-contract acceptance[4] a live leg (§4).
    • RUNNER.md has no anchor floor in scripts/checklist-symbol-anchor-baseline.json, so its first resolving anchor would red the gate.

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


Generated by Claude Code

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