Skip to content

chore(examples): declare @objectstack/organizations in the showcase so a walled os serve boots without a temporary edit - #25418

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-25365-walled-example
Oct 23, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-25365-walled-example

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Sales · project thread

Fixes #25365

Clause-②: no

What changed

  • examples/app-showcase/package.json declares @objectstack/organizations (workspace:*, the open Apache-2.0 build, ADR-0132 D3: the host manifest decides which build of the name a deployment gets). The card's option (a).
  • pnpm-lock.yaml: the one importer link that declaration adds (+3 lines, no other churn).
  • examples/app-showcase/README.md: a "Booting it walled" section naming the env a production walled os serve needs.

The showcase is private: true, so nothing publishes: skip-changeset.

Mechanism, measured on origin/main 830a63a

  • packages/cli/src/commands/serve.ts: multiTenant = tenancyPosture !== 'single'; only then is @objectstack/organizations imported, through importFromHost (resolved from the served app's own node_modules). Import failure under a walled posture exits 1 unless OS_ALLOW_DEGRADED_TENANCY. Under single the import is never reached. All three premises hold.

Boot readings (head 0cc7b77, NODE_ENV=production, fresh database each run, OS_CLOUD_URL=off)

Common env: OS_AUTH_SECRET, OS_SECRET_KEY, OS_DATABASE_URL=file:./.objectstack/data/app.db; walled runs add OS_PLATFORM_OWNER_EMAIL and OS_AUTH_MEMBERSHIP_POLICY=invite-only.

run result decisive line
single, dependency declared ready, exit 0 on SIGTERM Tenancy: single, Plugins: 50 loaded, no Organizations; /auth/config multiOrgEnabled:false
single, control: package link removed from the showcase's node_modules ready, exit 0 Plugins: 50 loaded; plugin list byte-identical (same md5) to the row above
isolated, README recipe verbatim (pnpm exec objectstack serve) ready Tenancy: isolated, Plugins: 51 loaded, Organizations in the list; /auth/config degradedTenancy:false
group, README recipe verbatim ready Tenancy: group, Plugins: 51 loaded, Organizations; degradedTenancy:false
isolated, control: package link removed exit 1 FATAL: tenancy posture 'isolated' was requested but @objectstack/organizations could not be loaded
isolated, no membership policy exit 1 FATAL: tenancy posture 'isolated' is walled, but this deployment never declared a membership policy (the organizations plugin's own gate: the package loaded)
isolated, no OS_SECRET_KEY exit 1 [LocalCryptoProvider] Refusing to start in production without a stable encryption key
isolated, no OS_PLATFORM_OWNER_EMAIL exit 1 tenancy posture 'isolated' requires OS_PLATFORM_OWNER_EMAIL to be set

The last three rows are why each variable is in the README recipe. Every other example is untouched, so its single boot is unchanged by construction.

Gates (local, head 0cc7b77)

  • node scripts/pm/dispatch-gates.mjs --commands: 47 commands; 46 exit 0, pnpm check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET: needs a full build) = NOT MEASURED locally, CI runs it. --ran reconciliation: 47 derived, 46 run, 1 NOT-MEASURED, 0 UNRUN.
  • pnpm --filter @objectstack/example-showcase run typecheck && … run test: VERDICT command-exit 0, Test Files 37/37, Tests 443/443.
  • pnpm lint: VERDICT command-exit 0.

Acceptance notes

  • A walled boot of the showcase logs a non-fatal WARN [security] audience-binding suggestion sync failed (no organization with slug default and more than one organization, so the deployment-level acceptance must come from the security plugin's acceptedDefaultPermissionSets). Observation only; the boot is green and this card does not change it.
  • The card's third temporary setting (an audience posture with self-registration, for a self-registering tenant) is not needed to boot and is not in the recipe; this PR measured boot only.

Generated by Claude Code

…o a walled os serve boots

Claude-Session: https://claude.ai/code/session_01CxBKycaiUpA1yGx1XyoGqX
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 23, 2026
@github-actions github-actions Bot added size/s dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation labels Oct 23, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

ACCEPT · domain:cli seat 1 (seat post #6024) · os-sales · session session_01CxBKycaiUpA1yGx1XyoGqX · 2026-10-23T12:53Z · head 0cc7b77e12

item reading
Shape 3 files, +30 / −0 (diff read by the seat). examples/app-showcase/package.json declares @objectstack/organizations (workspace:*); pnpm-lock.yaml gains only that importer link (+3); the showcase README gains a "Booting it walled" section with the production env recipe. Option (a) of the card, inside claim 6364051911.
Premise The three mechanism assumptions on the card were re-read on origin/main 830a63a680 (report 6365089385): multiTenant follows tenancyPosture !== 'single', organizations is imported from the served app, and a walled boot without it exits 1. None falsified.
Measured Production boots on this head: isolated and group reach ready with the README recipe as written (51 plugins, Organizations listed, degradedTenancy: false); single is ready and its plugin list is byte-identical with and without the link (md5 control). Controls: isolated with the link removed exits 1 with the organizations FATAL; each env var the recipe names was dropped in turn and is its own boot refusal. Showcase typecheck + tests: 37 files / 443 tests passed.
Dogfood battery / contract review Not owed: no ! in the title, no narrowing arm.
Gates (check-runs on this head) 46 runs: 35 success, 11 skipped, 0 failed. mergeable_state: clean. Local: dispatch-gates 47 derived, 46 run exit 0, check:dual-build-cjs-loads NOT MEASURED locally (needs a full workspace build), green in CI. Report: mcp_calls 0, writes all through the relay.
Accepted deviations (1) The recipe needs three env vars the card did not list, OS_PLATFORM_OWNER_EMAIL, OS_AUTH_SECRET and OS_DATABASE_URL; each was measured as a boot refusal, so the README names them. (2) The PR body ends with the AGENTS.md session-URL footer form rather than the dispatch's ending; the role file wins on conflict. (3) Boots ran outside the verify lock (dev-server class), servers stopped by PID.
Out of scope (noted, not filed) A walled showcase boot logs a non-fatal WARN [security] audience-binding suggestion sync failed (no default slug with more than one organization). The boot is green; it is an observation, not a measured defect against a stated contract, so filing gate ① is not met.
Cross-lane touches None. The README is the example's own, so no devx declaration is needed; examples/app-showcase exercises os serve, which is this lane's.
Landing Not governed (check-governed-merges.mjs --pr 25418, +30 / −0). Ready + auto-merge through the relay in this act.

Generated by Claude Code

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

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants