You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat(objectql,cli)!: 18.x step 4: the walled lift (8b walled half plus the walled part of #24489) #24580
Filing gate ③: a task the maintainer directed. It is a step of the 18.x line, under ruling records 6266750393 and 6267391172 on #15194. It is filed from step 0's measured plan: os-dev-report 6268559156 on #24522, step_plan.steps[3], plus its line_facts F1–F6 and flags.
Reader who acts: the epic seat (epic:#15194, session_01Y5583bs2RDd53MH6kM1ca3).
Dedupe: none.
Part of #15212 (C8) and #24489 (the 18.0-guards restore) · Step 4: the walled lift · ⛔ Not an 18.0 gate.
Scope (from the measured plan; re-measure before building)
8b's walled half. Lift the platform-object exemption under group / isolated (engine.ts about :7251, one condition, plus its docblocks). PLATFORM_OBJECT_TENANCY keeps its every-posture reader, the bypassTenantAudit mute; only the walled reader retires.
R4 is restated: from this step on, a walled os serve boots.
Recorded for step 5: walled 18.0 databases that exist anyway (embedded hosts were never refused) go through the ceremony's attribution and report fates.
Expect fallout in walled test rigs (step_plan: up to 164 walled-posture test files). Fix fixtures, not assertions.
Not dispatched yet. The seat claims it when its ordering is met.
Epic seat (epic:#15194, session_01Y5583bs2RDd53MH6kM1ca3) · 2026-10-19T14:30Z. Ordering of the 18.x line (ruling 6266750393), recorded so the unlock scan can read it:
Epic seat (epic:#15194, session_01Y5583bs2RDd53MH6kM1ca3) · 2026-10-19T16:01Z. Two items step 4 must carry, from the contract review of step 1, PR #24588, ③ items 4 and 6:
The declared-name guard for webhooks: a 409 is required before the walled lift.heldByRow (plugin-webhooks/src/auto-enqueuer.ts) withholds a declaration whenever a sys_webhook row holds its name, and it does so deployment-wide. Under a wall, one organization's same-name row would therefore silence a deployment-wide declaration for every organization. Refuse an insert of a declared name, and a rename onto one, with 409 RESOURCE_CONFLICT, as bindDeclaredRuleNameGuard does for sharing rules (plugin-sharing: refuse a new or renamed sys_sharing_rule row that takes a declared rule's name, and reconcile the shadowed declaration's grants on a same-name write (ruling B′ on #24378) #24421). System writes and existing 18.0 rows stay untouched, which is compatible with expand-first.
Claim: epic seat round · 2026-10-19T20:35Z
Session: session_01Y5583bs2RDd53MH6kM1ca3
Account: os-steve (the card's assignee)
Branch: claude/issue-24580-walled-lift
Worktree: the cloud session's own checkout (mode:cloud)
Domain: domain:engine
Seat: epic:#15194 (the epic lane) Base, and an early start. Steps 2 and 3 have merged (#24590b12e16a56, #24587fbafb8533). Step 1, PR #24588, is green and clean, and waits only on the maintainer's approval. The maintainer's standing order is 「你正常开发就行,只要确保你合并进main的代码都不是开发了一半的」. So this branch starts now from origin/main, merged with origin/claude/issue-24529-8b0g-webhooks-registry (#24588's head) because it builds on the declared-webhook reader. ⛔ It lands only after #24588 has merged and this branch has merged main again.
File surface, read at or after 14ccb1da9. The dev measures first; a breach stops the work and is explained in the report.
Seat note 6271514301, item 1: the 409 declared-name guard on sys_webhook, for both an insert of a declared name and a rename onto one, shaped like bindDeclaredRuleNameGuard. System writes and existing 18.0 rows stay untouched.
Seat note 6271514301, item 2: the walled shape of a declared webhook. ⛔ This is a decision. The seat puts it to the maintainer. Build everything else first. Implement this item only after the seat relays the ruling, and until then keep today's behaviour (organization-less under a wall, refused with one warning).
Walled test rigs (up to 164 files per the plan): fix the fixtures, never the assertions.
{
"issue": 24580,
"status": "blocked",
"branch": "claude/issue-24580-walled-lift",
"pr": "https://github.com/objectstack-ai/objectstack/pull/24667",
"session": "session_01XA1XHtvWd8Q1Q1gyWvhZZz",
"premise_still_valid": true,
"summary": "Built and pushed: (1) 8b's walled half — the platform-object exemption in Engine.resolveSystemInsertOrganization is lifted under group/isolated (walled org-less system inserts are refused ERR_SYSTEM_WRITE_ORGANIZATION_REQUIRED/500), PLATFORM_OBJECT_TENANCY keeps only its bypassTenantAudit reader; (2) note 6271514301 item 1 — bindDeclaredWebhookNameGuard, 409 RESOURCE_CONFLICT on a non-system sys_webhook insert of a declared name or a rename onto one, system writes and name-keeping updates pass, bound by WebhookOutboxPlugin; (3) walled rigs: 164 files measured, 2 plugin-security fixtures fixed (organization carried), no assertion moved; (4) item 4 measured, not implemented. BLOCKED: #24489 items 2 and 3 (delete walledPostureRefusal and its test, restore the 7 e2e cases from ae6bd1a6^, remove WALLED_POSTURE_RELEASE_NOTE / walledPostureFinding / the 18.0 walled docs sentences) — the session's automated permission classifier refused the deletion as a security-test removal; it needs the session owner's permission, not a PM action. R4 therefore still refuses; PR body says Part of #24580, not Closes.",
"tests": "head 37a67fa98. objectql whole package: 449 files / 8454 tests passed. plugin-webhooks build closure + typecheck + package: 20 files / 221 passed. plugin-security package: 188 files / 3754 passed, 45 skipped. Walled rigs (164 files, 17 objectql-dependent packages): all green after the 2 fixture fixes (dogfood 12 passed 1 skipped). typecheck objectql/plugin-webhooks/plugin-security: exit 0. R1: full pnpm build, pnpm dev -- --fresh (showcase single) ready, discovery 200, no system-write refusal. R2: upgrade-18x-harness 6/6. R3: harness case 4 green. R4 restated: NOT MET (blocked half). Ablations via ablation-replace.mjs, restored to git diff HEAD empty: walled exemption re-inserted -> 6 walled cases red; guard throw -> return -> 4 red; guard system pass + rename check removed -> 3 control cases red.",
"gates": "dispatch-gates --commands derived 135 (change set includes #24588's step-1 diff); local subset run over this card's files, final exit 0 each: check-adr-0087-registration, check-changeset-no-major, check-empty-changeset, check-closing-keyword-parity, check-issue-citations, check-platform-object-tenancy-census, check-tenant-audit-census, check-system-context-census (red first on the new guard's isSystem read, fixed with a census row), check-plugin-teardown-shape, check-scripts-symbol-anchors, check-spec-docblock-symbol-anchors, check-engine-split-ratio (after deepening to 2026-07-14), check-undeclared-dep-imports, check-registry-log-declared, check-rest-log-spy-declared, doc-authoring, engine-double-contract, objectql-double-limit, query-options-erasure, nul-bytes, cross-package-test-inputs, test-source-alias, durability-log-level, error-status-conformance, route-envelope, platform-checklist, pm-prior-rulings, org-identifier, swallow-census-controls, where-matcher (red first on the new test fake, fixed: refuses combinators), slot-lookup, agent-test-spelling, tier-file-adoption. Targeted eslint on changed files exit 0. CI farm: in_progress at report time. check-governed-merges --branch: 0 governed paths, 3899 changed lines > 3000 (includes #24588's diff).",
"mcp_calls": "4 — issue_read x2 (get, get_comments), plus tool-schema loads; no MCP write",
"api_writes": "2 — fleet relay pr_create (objectstack-ai/objectstack#24667), fleet relay comment (this report)",
"open_questions": [
{
"question": "Item 4: the walled shape of a declared webhook (put to the maintainer by the seat).",
"options": [
"A deployment-wide across the wall: ~60-80 lines (postureBuildsNoWall retires, declaredWebhooksDeploymentWide answers true; delivery already stamped with the event's organization; ledger already deployment-level and the door already operator-gated under a wall; 2 tests flip; no ADR or schema change)",
"B per organization: ~0.6-1.2k lines + objectui (per-organization switch storage, which tenant-less sys_metadata_activation cannot hold; activation door opened to tenant admins = ADR-0126 §5 change; per-organization admission in dispatcher and redelivery guard; heldByRow per organization; contradicts ADR-0131 D6 regime C's deployment-level switch, so an ADR amendment)"
],
"recommendation": "A, because every mechanism it needs is already in the tree and it keeps D6 regime C as written; B is an ADR change plus a schema expansion."
},
{
"question": "The os serve half (#24489 items 2-3) was refused by the session's permission classifier.",
"options": [
"The session owner grants the edit and this branch finishes it (mechanical: inverse of ae6bd1a6 / 5b14b7f walled lines, e2e files restore whole)",
"Another session or the maintainer lands it"
],
"recommendation": "The first; the PR stays draft until it is in."
}
],
"out_of_scope_findings": [],
"deviations": "PR body says 'Part of #24580' instead of the dispatch's 'Closes #24580', because the card is not complete. The plugin-webhooks typecheck first run was red on unbuilt dependency dist (NOT a measurement; re-run after the closure build: exit 0)."
}
Ruling record: the walled shape of a declared webhook is deployment-wide (A) · epic PM session_01Y5583bs2RDd53MH6kM1ca3 (os-steve) · 2026-10-19T22:18Z
Provenance. This is seat note 6271514301, item 2, from the contract review of step 1 (PR #24588, ③ item 6). The dev measured both options on PR #24667 (os-dev-report 6278532264). The seat put two options to the maintainer in its chat, with the Acme/Beta example and the costs:
A: deployment-wide across the wall. There is one declaration and one switch. The switch is the sys_metadata_activation row, deployment-level and operator-gated under a wall. When it is on, the webhook receives every organization's events, and each sys_http_delivery row is stamped with its event's organization. Measured at about 60–80 lines, with no ADR change.
B: per organization. Each organization has its own switch, and only that organization's events are delivered. Measured at about 0.6–1.2k lines, plus objectui. It would amend ADR-0126 §5 and ADR-0131 D6, and it leaves open each organization's default and whether an organization administrator may switch on a vendor URL.
Under group and isolated, a declared webhook is deployment-wide, exactly as it is under single since step 1. It receives every organization's events, and each delivery is stamped with its event's organization, so delivery history is walled like any other organization-stamped row.
The switch is the existing activation-ledger row: deployment-level, and operator-gated under a wall. An organization administrator who tries the door gets the server's refusal.
{
"issue": 24580,
"status": "blocked",
"branch": "claude/issue-24580-walled-lift",
"pr": "https://github.com/objectstack-ai/objectstack/pull/24667",
"session": "session_01XA1XHtvWd8Q1Q1gyWvhZZz",
"premise_still_valid": true,
"summary": "ADDENDUM to os-dev-report 6278532264: item 4 implemented under ruling A (record 6278609968). Under group/isolated a declared webhook is deployment-wide as under single: every declared subscription is deploymentWide, the posture-reading option declaredWebhooksDeploymentWide and postureBuildsNoWall are removed (both from #24588, unreleased), each sys_http_delivery row is stamped with its event's organization, the switch stays the deployment-level ledger row (operator-gated under a wall), no ADR change. Still BLOCKED: #24489 items 2 and 3 (the os serve lift) wait on the session owner's permission; PR stays draft, Part of #24580.",
"tests": "head a4cee54b1. New dogfood pin wall-declared-webhook-deployment-wide.dogfood.test.ts (real walled boot, isolated and group, two organizations via the auth API, engine record events through the plugin's dispatcher): 8/8 - org admin holding manage_metadata in its own org refused 403 PERMISSION_DENIED at the activation door with nothing written, operator switches on; one delivery per event stamped with the event's organization; each organization reads only its own deliveries via GET /data/sys_http_delivery. Unit: declared-webhooks.test.ts flipped (two-organization delivery; deployment-wide under single/group/isolated/no tenancy service); plugin-webhooks package 20 files / 221 passed, typecheck exit 0. Dogfood rerun: upgrade-18x-harness + webhook-materialization + new pin, 3 files / 15 passed. Ablations via ablation-replace.mjs with the package rebuilt, restored to git diff HEAD empty: deploymentWide true->false -> 3 unit + 4 dogfood red; event-organization stamp -> subscription's -> 3 unit + 4 dogfood red; the door's posture refusal removed (runtime dist mutated 2->1) -> dogfood door case red under both postures and runtime door unit test 12 red. The first door-ablation run stayed green because org A lacked manage_metadata (refused on authority, not posture); the fixture now grants it, and that is the reading above.",
"gates": "After ruling A, exit 0 each: check-adr-0087-registration, check-changeset-no-major, check-empty-changeset, check-system-context-census, check-plugin-teardown-shape, where-matcher, cross-package-test-inputs, test-source-alias, nul-bytes, doc-authoring, issue-citations, durability-log-level, startup-registry-verdict; targeted eslint exit 0. check-governed-merges --branch: 0 governed paths, 4058 changed lines (includes #24588's diff). Earlier gate readings in 6278532264 stand.",
"mcp_calls": "0 more",
"api_writes": "2 more - fleet relay issue_patch (PR #24667 body), fleet relay comment (this addendum)",
"open_questions": [
{
"question": "The os serve half (#24489 items 2-3) was refused by the session's permission classifier.",
"options": [
"The session owner grants the edit and this branch finishes it (mechanical: inverse of ae6bd1a6 / 5b14b7f walled lines, e2e files restore whole)",
"Another session or the maintainer lands it"
],
"recommendation": "The first; the PR stays draft until it is in."
}
],
"out_of_scope_findings": [],
"deviations": "The PR body was patched once more at the seat's request (the standard says the dev writes it once); read back byte-identical."
}
{
"issue": 24580,
"status": "done",
"branch": "claude/issue-24580-walled-lift",
"pr": "https://github.com/objectstack-ai/objectstack/pull/24667",
"session": "session_01XA1XHtvWd8Q1Q1gyWvhZZz",
"premise_still_valid": true,
"summary": "ADDENDUM 2 (to 6278532264 and 6278908733): the session owner granted the permission, and #24489 items 2 and 3 are in at 45898dbf6. Changes: walledPostureRefusal and serve-walled-posture-refusal.test.ts deleted (exact inverse of ae6bd1a6's serve.ts hunks); the 7 walled e2e cases restored whole from ae6bd1a6^ (neither file had changed since); walledPostureFinding and WALLED_POSTURE_RELEASE_NOTE removed, with their 4 test files restored from 5b14b7f^ (untouched since); the 18.0 walled docs sentences removed, each keeping its upgrade half for steps 5-6; changeset 15212-walled-posture-boots.md. R4 as restated is met. The card is complete: PR body is now 'Closes #24580', still a draft, landing after #24588 and a main merge.",
"tests": "head 45898dbf6. CLI build + typecheck + --project unit: exit 0, 313 files / 4633 passed. The 7 restored e2e cases (OS_TEST_TIERS=nightly): 7/7. R4: the built CLI (bin/run-dev.js serve) under OS_TENANCY_POSTURE=isolated, with OS_PLATFORM_OWNER_EMAIL and OS_AUTH_MEMBERSHIP_POLICY=invite-only (pre-18.0 walled prerequisites), on a throwaway app declaring the real @objectstack/organizations: 'Press Ctrl+C to stop', Organizations mounted, discovery 200, 0 ERR_SYSTEM_WRITE_ORGANIZATION_REQUIRED in the log; server killed by recorded PID, app removed. Ablation: a walled refusal re-inserted at serve's posture gate -> all 7 restored e2e cases red; restored to git diff HEAD empty. Earlier readings in the two prior reports stand.",
"gates": "exit 0 each: check-platform-checklist --changed-from origin/main (removed exports), check-adr-0087-registration, check-changeset-no-major, check-empty-changeset, check-closing-keyword-parity, docs-audit/check-affected-docs, check-drift-comment, check-doc-frontmatter, doc-anchors, doc-authoring, docs-spec-enumerations, docs-transcript-drift, doc-security-posture, cli-command-ids, issue-citations, nul-bytes, cross-package-test-inputs, tier-file-adoption, pm-prior-rulings, platform-checklist; targeted eslint exit 0. check-governed-merges --branch: 0 governed paths, 4628 changed lines (includes #24588's diff). CI farm: in_progress.",
"mcp_calls": "0 more",
"api_writes": "2 more - fleet relay issue_patch (PR #24667 title and body), fleet relay comment (this addendum)",
"open_questions": [],
"out_of_scope_findings": [],
"deviations": "The PR closing line moved from 'Part of #24580' to 'Closes #24580' now that the card is complete; the PR stays a draft."
}
cloud is waiting on this card: cloud's framework pin stays at fb9c22aa until this card merges. That is before #24480's 18.0 guard. Maintainer ruling, 2026-10-20: 「框架 pin 留在 fb9c22a,只把 objectui 抬到最新…等 objectstack#24580 合并后再抬框架。」
Why cloud can't cross #24480 now: cloud boots objectstack serve / objectstack dev under a walled posture (OS_MULTI_ORG_ENABLED=true, which resolves to isolated) on these paths:
cloud path
boot
.github/workflows/deploy-cloud-staging.yml, deploy-cloud-prod.yml: the control plane's deploy-time schema sync
objectstack serve dist/objectstack.config.js --prebuilt --no-ui with OS_MIGRATE_AND_EXIT=1
scripts/dev-local/run-stack.sh (local rigs, pin smoke, golden journey)
objectstack dev for the control plane; OS_MULTI_ORG_ENABLED defaults to true
Reproduced with the CLI from both trees:
At eadea572, serve with OS_MULTI_ORG_ENABLED=true exits with FATAL: tenancy posture 'isolated' is not supported in 18.0 (NOT_IMPLEMENTED).
At fb9c22aa, the same command passes that gate.
Not affected: the running control plane boots through cloud's own dist/server/serve-node.js, a kernel-level boot that ADR-0131 D14 says stays outside the refusal. os migrate plan/apply (migrate-control-db.yml) also stays outside it.
For #24582: cloud's tenant v18 upgrade (packages/objectos-runtime/src/tenant-v18-upgrade-cli.ts) runs os migrate organization-ownership plan and --apply, so it waits on the ceremony re-opening too.
When this card lands, cloud moves its framework pin past the guard in one step. Its acceptance will re-run each of the boots above.
cloud builds the console's @objectstack/* packages from its own framework tree. At fb9c22aa0929, objectui main fails with TS2724 (cloud PR feat(docs): landing page at / + self-hosted logo assets #3088's first run: console-boots and the EE image build).
So cloud's objectui pin stops at cc4ae3e1, the parent of 2493e85a. When this card lands, cloud's framework and objectui pins move together.
{
"issue": 24580,
"status": "done",
"branch": "claude/issue-24580-walled-lift",
"pr": "https://github.com/objectstack-ai/objectstack/pull/24667",
"session": "session_01XA1XHtvWd8Q1Q1gyWvhZZz",
"summary": "ADDENDUM 3. origin/main (3a931fca1, #24588 squash 191e0430e included) merged at fdfc84238 with a merge commit. 4 plugin-webhooks conflicts came only from the squash: main's copy equals the step-1 head this branch had merged (b4ae8e68); the branch side was kept, proven per file (delta vs main == delta vs b4ae8e68). No regenerable artifact conflicted. CI on fdfc84238 was red in plugin-sharing and plugin-auth: two walled fixtures wrote organization-less legacy rows through the engine. Fixed at 1412586b4, fixtures only: legacy rows seeded through the driver; the activation-ledger fixture declares systemFields tenant:false as the platform object. Head 1412586b4; git diff --shortstat origin/main...HEAD: 34 files, +951/-548.",
"tests": "Merged tree after a fresh install and a full pnpm build: R1 fresh single boot discovery 200, 0 refusals; R2+R3 harness + webhook-materialization + walled declared-webhook pin 3 files/15 passed; plugin-webhooks 221/221 (409 guard pins included); objectql walled pins 68 and plugin-security walled fixtures 76 passed; CLI unit 314 files/4639 passed; the 7 restored walled e2e cases 7/7; typecheck objectql/plugin-webhooks/plugin-security/cli exit 0. R4 (isolated os serve boot with the real organizations runtime) was measured at 45898dbf6; the merge touched no serve.ts line, and the 7 e2e cases (which spawn a walled os serve) pass on the merged tree. After the fixture fix: plugin-sharing 49 files/1161 passed, plugin-auth 165 files/3168 passed 10 skipped, typecheck exit 0.",
"gates": "dispatch-gates --commands on the merged tree: 110/110 exit 0. CI on 1412586b4: 36 success, 5 skipped, 0 failures (Test Core 1-6/6, Build Core, Type Check, Lint, Governed Surface Queue Guard all success).",
"mcp_calls": "1 - pull_request_read get_check_runs",
"api_writes": "2 more - fleet relay issue_patch (PR #24667 body), fleet relay comment (this addendum)",
"open_questions": [],
"out_of_scope_findings": [],
"deviations": "The walled-rig grep (164 files) missed two walled fixtures that set the posture another way; CI caught them, and they are fixed above."
}
Activity
objectstack-fleet commentedon Oct 19, 2026
Epic seat (
epic:#15194,session_01Y5583bs2RDd53MH6kM1ca3) · 2026-10-19T14:30Z. Ordering of the 18.x line (ruling 6266750393), recorded so the unlock scan can read it:Blocked-by: #24529
Blocked-by: #24530
Blocked-by: #24531
objectstack-fleet commentedon Oct 19, 2026
Epic seat (
epic:#15194,session_01Y5583bs2RDd53MH6kM1ca3) · 2026-10-19T16:01Z. Two items step 4 must carry, from the contract review of step 1, PR #24588, ③ items 4 and 6:heldByRow(plugin-webhooks/src/auto-enqueuer.ts) withholds a declaration whenever asys_webhookrow holds its name, and it does so deployment-wide. Under a wall, one organization's same-name row would therefore silence a deployment-wide declaration for every organization. Refuse an insert of a declared name, and a rename onto one, with409 RESOURCE_CONFLICT, asbindDeclaredRuleNameGuarddoes for sharing rules (plugin-sharing: refuse a new or renamed sys_sharing_rule row that takes a declared rule's name, and reconcile the shadowed declaration's grants on a same-name write (ruling B′ on #24378) #24421). System writes and existing 18.0 rows stay untouched, which is compatible with expand-first.sys_flow_credential) and boot-seeded declared webhooks (sys_webhook) #24435's rejection of Q2 C, silent loss under a wall. Today a declared webhook under a wall is organization-less and refused with one warning. That is unreachable while R4 holds, and step 4 lifts R4.objectstack-fleet commentedon Oct 19, 2026
Claim: epic seat round · 2026-10-19T20:35Z
Session:
session_01Y5583bs2RDd53MH6kM1ca3Account:
os-steve(the card's assignee)Branch:
claude/issue-24580-walled-liftWorktree: the cloud session's own checkout (
mode:cloud)Domain:
domain:engineSeat:
epic:#15194(the epic lane)Base, and an early start. Steps 2 and 3 have merged (#24590
b12e16a56, #24587fbafb8533). Step 1, PR #24588, is green and clean, and waits only on the maintainer's approval. The maintainer's standing order is 「你正常开发就行,只要确保你合并进main的代码都不是开发了一半的」. So this branch starts now fromorigin/main, merged withorigin/claude/issue-24529-8b0g-webhooks-registry(#24588's head) because it builds on the declared-webhook reader. ⛔ It lands only after #24588 has merged and this branch has mergedmainagain.File surface, read at or after
14ccb1da9. The dev measures first; a breach stops the work and is explained in the report.engine.ts), and chore(cli)!: 18.x restore of the 18.0 guards — re-open the upgrade ceremony and walled boots #24489 items 2 and 3 (walledPostureRefusalinserve.tsand its test, the seven walled e2e cases, the 18.0 walled docs sentences,WALLED_POSTURE_RELEASE_NOTE,walledPostureFinding).sys_webhook, for both an insert of a declared name and a rename onto one, shaped likebindDeclaredRuleNameGuard. System writes and existing 18.0 rows stay untouched.docs/adr/**. ⛔ Notcontent/docs/releases/. ⛔ Not the ceremony files of feat(cli): 18.x step 5: the upgrade ceremony steps behind the refusal (webhook re-source, sibling moves, 9c, 8e NOT NULL) #24581/feat(cli,runtime)!: 18.x step 6: open the upgrade ceremony for v17 and 18.0 databases (and the deferred flips) #24582 (organization-ownership-apply.ts, the ceremony command).Container & model:
L,mode:cloud,model: TIER_DEFAULTClause-②: yes (the dev re-measures). Lifting the walled refusal widens what boots, and the 409 narrows what can be written.
Responsibility: n/a. A ruled step of the line (6266750393, 6267391172 on [epic] ADR-0131 — total organization ownership: no NULL organization_id (v18 line) #15194).
Thread-read: 6271514301
Serial constraints cleared:
serve.ts(chore(cli)!: 18.x restore of the 18.0 guards — re-open the upgrade ceremony and walled boots #24489 items 2 and 3 here; items 1, 4 and 6 there). Whichever lands second mergesmain.os serveboots.Merge gate: the PR opens as a draft. It lands after feat(plugin-webhooks,runtime)!: declared webhooks are read from the registry, the seeder retires, and the activation ledger switches them (18.x step 1, 8b-0g′) #24588, with the harness green on the merged tree (R1–R3, and R4 as restated).
objectstack-fleet commentedon Oct 19, 2026
os-dev-report
{ "issue": 24580, "status": "blocked", "branch": "claude/issue-24580-walled-lift", "pr": "https://github.com/objectstack-ai/objectstack/pull/24667", "session": "session_01XA1XHtvWd8Q1Q1gyWvhZZz", "premise_still_valid": true, "summary": "Built and pushed: (1) 8b's walled half — the platform-object exemption in Engine.resolveSystemInsertOrganization is lifted under group/isolated (walled org-less system inserts are refused ERR_SYSTEM_WRITE_ORGANIZATION_REQUIRED/500), PLATFORM_OBJECT_TENANCY keeps only its bypassTenantAudit reader; (2) note 6271514301 item 1 — bindDeclaredWebhookNameGuard, 409 RESOURCE_CONFLICT on a non-system sys_webhook insert of a declared name or a rename onto one, system writes and name-keeping updates pass, bound by WebhookOutboxPlugin; (3) walled rigs: 164 files measured, 2 plugin-security fixtures fixed (organization carried), no assertion moved; (4) item 4 measured, not implemented. BLOCKED: #24489 items 2 and 3 (delete walledPostureRefusal and its test, restore the 7 e2e cases from ae6bd1a6^, remove WALLED_POSTURE_RELEASE_NOTE / walledPostureFinding / the 18.0 walled docs sentences) — the session's automated permission classifier refused the deletion as a security-test removal; it needs the session owner's permission, not a PM action. R4 therefore still refuses; PR body says Part of #24580, not Closes.", "tests": "head 37a67fa98. objectql whole package: 449 files / 8454 tests passed. plugin-webhooks build closure + typecheck + package: 20 files / 221 passed. plugin-security package: 188 files / 3754 passed, 45 skipped. Walled rigs (164 files, 17 objectql-dependent packages): all green after the 2 fixture fixes (dogfood 12 passed 1 skipped). typecheck objectql/plugin-webhooks/plugin-security: exit 0. R1: full pnpm build, pnpm dev -- --fresh (showcase single) ready, discovery 200, no system-write refusal. R2: upgrade-18x-harness 6/6. R3: harness case 4 green. R4 restated: NOT MET (blocked half). Ablations via ablation-replace.mjs, restored to git diff HEAD empty: walled exemption re-inserted -> 6 walled cases red; guard throw -> return -> 4 red; guard system pass + rename check removed -> 3 control cases red.", "gates": "dispatch-gates --commands derived 135 (change set includes #24588's step-1 diff); local subset run over this card's files, final exit 0 each: check-adr-0087-registration, check-changeset-no-major, check-empty-changeset, check-closing-keyword-parity, check-issue-citations, check-platform-object-tenancy-census, check-tenant-audit-census, check-system-context-census (red first on the new guard's isSystem read, fixed with a census row), check-plugin-teardown-shape, check-scripts-symbol-anchors, check-spec-docblock-symbol-anchors, check-engine-split-ratio (after deepening to 2026-07-14), check-undeclared-dep-imports, check-registry-log-declared, check-rest-log-spy-declared, doc-authoring, engine-double-contract, objectql-double-limit, query-options-erasure, nul-bytes, cross-package-test-inputs, test-source-alias, durability-log-level, error-status-conformance, route-envelope, platform-checklist, pm-prior-rulings, org-identifier, swallow-census-controls, where-matcher (red first on the new test fake, fixed: refuses combinators), slot-lookup, agent-test-spelling, tier-file-adoption. Targeted eslint on changed files exit 0. CI farm: in_progress at report time. check-governed-merges --branch: 0 governed paths, 3899 changed lines > 3000 (includes #24588's diff).", "mcp_calls": "4 — issue_read x2 (get, get_comments), plus tool-schema loads; no MCP write", "api_writes": "2 — fleet relay pr_create (objectstack-ai/objectstack#24667), fleet relay comment (this report)", "open_questions": [ { "question": "Item 4: the walled shape of a declared webhook (put to the maintainer by the seat).", "options": [ "A deployment-wide across the wall: ~60-80 lines (postureBuildsNoWall retires, declaredWebhooksDeploymentWide answers true; delivery already stamped with the event's organization; ledger already deployment-level and the door already operator-gated under a wall; 2 tests flip; no ADR or schema change)", "B per organization: ~0.6-1.2k lines + objectui (per-organization switch storage, which tenant-less sys_metadata_activation cannot hold; activation door opened to tenant admins = ADR-0126 §5 change; per-organization admission in dispatcher and redelivery guard; heldByRow per organization; contradicts ADR-0131 D6 regime C's deployment-level switch, so an ADR amendment)" ], "recommendation": "A, because every mechanism it needs is already in the tree and it keeps D6 regime C as written; B is an ADR change plus a schema expansion." }, { "question": "The os serve half (#24489 items 2-3) was refused by the session's permission classifier.", "options": [ "The session owner grants the edit and this branch finishes it (mechanical: inverse of ae6bd1a6 / 5b14b7f walled lines, e2e files restore whole)", "Another session or the maintainer lands it" ], "recommendation": "The first; the PR stays draft until it is in." } ], "out_of_scope_findings": [], "deviations": "PR body says 'Part of #24580' instead of the dispatch's 'Closes #24580', because the card is not complete. The plugin-webhooks typecheck first run was red on unbuilt dependency dist (NOT a measurement; re-run after the closure build: exit 0)." }Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
Ruling record: the walled shape of a declared webhook is deployment-wide (A) · epic PM
session_01Y5583bs2RDd53MH6kM1ca3(os-steve) · 2026-10-19T22:18ZProvenance. This is seat note 6271514301, item 2, from the contract review of step 1 (PR #24588, ③ item 6). The dev measured both options on PR #24667 (os-dev-report 6278532264). The seat put two options to the maintainer in its chat, with the Acme/Beta example and the costs:
sys_metadata_activationrow, deployment-level and operator-gated under a wall. When it is on, the webhook receives every organization's events, and eachsys_http_deliveryrow is stamped with its event's organization. Measured at about 60–80 lines, with no ADR change.The maintainer replied 「A」.
What it binds (step 4, #24580 / PR #24667):
groupandisolated, a declared webhook is deployment-wide, exactly as it is undersinglesince step 1. It receives every organization's events, and each delivery is stamped with its event's organization, so delivery history is walled like any other organization-stamped row.sys_flow_credential) and boot-seeded declared webhooks (sys_webhook) #24435's rejection of Q2 C.sharing_ruleunder ruling A on [Decision] Declared sharing rules: what switching off a vendor's rule means once they are read from the registry #24378, where the activation bit is deployment-level and operator-gated under a wall.objectstack-fleet commentedon Oct 19, 2026
os-dev-report
Addendum to 6278532264: item 4 under ruling A.
{ "issue": 24580, "status": "blocked", "branch": "claude/issue-24580-walled-lift", "pr": "https://github.com/objectstack-ai/objectstack/pull/24667", "session": "session_01XA1XHtvWd8Q1Q1gyWvhZZz", "premise_still_valid": true, "summary": "ADDENDUM to os-dev-report 6278532264: item 4 implemented under ruling A (record 6278609968). Under group/isolated a declared webhook is deployment-wide as under single: every declared subscription is deploymentWide, the posture-reading option declaredWebhooksDeploymentWide and postureBuildsNoWall are removed (both from #24588, unreleased), each sys_http_delivery row is stamped with its event's organization, the switch stays the deployment-level ledger row (operator-gated under a wall), no ADR change. Still BLOCKED: #24489 items 2 and 3 (the os serve lift) wait on the session owner's permission; PR stays draft, Part of #24580.", "tests": "head a4cee54b1. New dogfood pin wall-declared-webhook-deployment-wide.dogfood.test.ts (real walled boot, isolated and group, two organizations via the auth API, engine record events through the plugin's dispatcher): 8/8 - org admin holding manage_metadata in its own org refused 403 PERMISSION_DENIED at the activation door with nothing written, operator switches on; one delivery per event stamped with the event's organization; each organization reads only its own deliveries via GET /data/sys_http_delivery. Unit: declared-webhooks.test.ts flipped (two-organization delivery; deployment-wide under single/group/isolated/no tenancy service); plugin-webhooks package 20 files / 221 passed, typecheck exit 0. Dogfood rerun: upgrade-18x-harness + webhook-materialization + new pin, 3 files / 15 passed. Ablations via ablation-replace.mjs with the package rebuilt, restored to git diff HEAD empty: deploymentWide true->false -> 3 unit + 4 dogfood red; event-organization stamp -> subscription's -> 3 unit + 4 dogfood red; the door's posture refusal removed (runtime dist mutated 2->1) -> dogfood door case red under both postures and runtime door unit test 12 red. The first door-ablation run stayed green because org A lacked manage_metadata (refused on authority, not posture); the fixture now grants it, and that is the reading above.", "gates": "After ruling A, exit 0 each: check-adr-0087-registration, check-changeset-no-major, check-empty-changeset, check-system-context-census, check-plugin-teardown-shape, where-matcher, cross-package-test-inputs, test-source-alias, nul-bytes, doc-authoring, issue-citations, durability-log-level, startup-registry-verdict; targeted eslint exit 0. check-governed-merges --branch: 0 governed paths, 4058 changed lines (includes #24588's diff). Earlier gate readings in 6278532264 stand.", "mcp_calls": "0 more", "api_writes": "2 more - fleet relay issue_patch (PR #24667 body), fleet relay comment (this addendum)", "open_questions": [ { "question": "The os serve half (#24489 items 2-3) was refused by the session's permission classifier.", "options": [ "The session owner grants the edit and this branch finishes it (mechanical: inverse of ae6bd1a6 / 5b14b7f walled lines, e2e files restore whole)", "Another session or the maintainer lands it" ], "recommendation": "The first; the PR stays draft until it is in." } ], "out_of_scope_findings": [], "deviations": "The PR body was patched once more at the seat's request (the standard says the dev writes it once); read back byte-identical." }Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
os-dev-report
Addendum 2: the os serve lift, R4 met.
{ "issue": 24580, "status": "done", "branch": "claude/issue-24580-walled-lift", "pr": "https://github.com/objectstack-ai/objectstack/pull/24667", "session": "session_01XA1XHtvWd8Q1Q1gyWvhZZz", "premise_still_valid": true, "summary": "ADDENDUM 2 (to 6278532264 and 6278908733): the session owner granted the permission, and #24489 items 2 and 3 are in at 45898dbf6. Changes: walledPostureRefusal and serve-walled-posture-refusal.test.ts deleted (exact inverse of ae6bd1a6's serve.ts hunks); the 7 walled e2e cases restored whole from ae6bd1a6^ (neither file had changed since); walledPostureFinding and WALLED_POSTURE_RELEASE_NOTE removed, with their 4 test files restored from 5b14b7f^ (untouched since); the 18.0 walled docs sentences removed, each keeping its upgrade half for steps 5-6; changeset 15212-walled-posture-boots.md. R4 as restated is met. The card is complete: PR body is now 'Closes #24580', still a draft, landing after #24588 and a main merge.", "tests": "head 45898dbf6. CLI build + typecheck + --project unit: exit 0, 313 files / 4633 passed. The 7 restored e2e cases (OS_TEST_TIERS=nightly): 7/7. R4: the built CLI (bin/run-dev.js serve) under OS_TENANCY_POSTURE=isolated, with OS_PLATFORM_OWNER_EMAIL and OS_AUTH_MEMBERSHIP_POLICY=invite-only (pre-18.0 walled prerequisites), on a throwaway app declaring the real @objectstack/organizations: 'Press Ctrl+C to stop', Organizations mounted, discovery 200, 0 ERR_SYSTEM_WRITE_ORGANIZATION_REQUIRED in the log; server killed by recorded PID, app removed. Ablation: a walled refusal re-inserted at serve's posture gate -> all 7 restored e2e cases red; restored to git diff HEAD empty. Earlier readings in the two prior reports stand.", "gates": "exit 0 each: check-platform-checklist --changed-from origin/main (removed exports), check-adr-0087-registration, check-changeset-no-major, check-empty-changeset, check-closing-keyword-parity, docs-audit/check-affected-docs, check-drift-comment, check-doc-frontmatter, doc-anchors, doc-authoring, docs-spec-enumerations, docs-transcript-drift, doc-security-posture, cli-command-ids, issue-citations, nul-bytes, cross-package-test-inputs, tier-file-adoption, pm-prior-rulings, platform-checklist; targeted eslint exit 0. check-governed-merges --branch: 0 governed paths, 4628 changed lines (includes #24588's diff). CI farm: in_progress.", "mcp_calls": "0 more", "api_writes": "2 more - fleet relay issue_patch (PR #24667 title and body), fleet relay comment (this addendum)", "open_questions": [], "out_of_scope_findings": [], "deviations": "The PR closing line moved from 'Part of #24580' to 'Closes #24580' now that the card is complete; the PR stays a draft." }Generated by Claude Code
hotlong commentedon Oct 19, 2026
cloud is waiting on this card: cloud's framework pin stays at
fb9c22aauntil this card merges. That is before #24480's 18.0 guard. Maintainer ruling, 2026-10-20: 「框架 pin 留在 fb9c22a,只把 objectui 抬到最新…等 objectstack#24580 合并后再抬框架。」Why cloud can't cross #24480 now: cloud boots
objectstack serve/objectstack devunder a walled posture (OS_MULTI_ORG_ENABLED=true, which resolves toisolated) on these paths:.github/workflows/deploy-cloud-staging.yml,deploy-cloud-prod.yml: the control plane's deploy-time schema syncobjectstack serve dist/objectstack.config.js --prebuilt --no-uiwithOS_MIGRATE_AND_EXIT=1.github/workflows/migrate-environment-types.yml,migrate-installation-package-names.yml,migrate-last-published-at.ymlserve … --no-uibootscripts/dev-local/run-stack.sh(local rigs, pin smoke, golden journey)objectstack devfor the control plane;OS_MULTI_ORG_ENABLEDdefaults totrueReproduced with the CLI from both trees:
eadea572,servewithOS_MULTI_ORG_ENABLED=trueexits withFATAL: tenancy posture 'isolated' is not supported in 18.0 (NOT_IMPLEMENTED).fb9c22aa, the same command passes that gate.Not affected: the running control plane boots through cloud's own
dist/server/serve-node.js, a kernel-level boot that ADR-0131 D14 says stays outside the refusal.os migrate plan/apply(migrate-control-db.yml) also stays outside it.For #24582: cloud's tenant v18 upgrade (
packages/objectos-runtime/src/tenant-v18-upgrade-cli.ts) runsos migrate organization-ownershipplan and--apply, so it waits on the ceremony re-opening too.When this card lands, cloud moves its framework pin past the guard in one step. Its acceptance will re-run each of the boots above.
hotlong commentedon Oct 20, 2026
Addendum (cloud): cloud's objectui pin is capped by the same guard.
mainnow needsEvalSystemPermissionsfrom@objectstack/formula. It came in with objectui2493e85a(objectui#13006); the framework added the export inca426cb65d, which comes after feat(cli)!: 18.0 guards — os migrate organization-ownership refuses, and os serve refuses a walled posture at boot #24480.@objectstack/*packages from its own framework tree. Atfb9c22aa0929, objectuimainfails withTS2724(cloud PR feat(docs): landing page at / + self-hosted logo assets #3088's first run:console-bootsand the EE image build).cc4ae3e1, the parent of2493e85a. When this card lands, cloud's framework and objectui pins move together.objectstack-fleet commentedon Oct 20, 2026
os-dev-report
Addendum 3: main merged, CI green.
{ "issue": 24580, "status": "done", "branch": "claude/issue-24580-walled-lift", "pr": "https://github.com/objectstack-ai/objectstack/pull/24667", "session": "session_01XA1XHtvWd8Q1Q1gyWvhZZz", "summary": "ADDENDUM 3. origin/main (3a931fca1, #24588 squash 191e0430e included) merged at fdfc84238 with a merge commit. 4 plugin-webhooks conflicts came only from the squash: main's copy equals the step-1 head this branch had merged (b4ae8e68); the branch side was kept, proven per file (delta vs main == delta vs b4ae8e68). No regenerable artifact conflicted. CI on fdfc84238 was red in plugin-sharing and plugin-auth: two walled fixtures wrote organization-less legacy rows through the engine. Fixed at 1412586b4, fixtures only: legacy rows seeded through the driver; the activation-ledger fixture declares systemFields tenant:false as the platform object. Head 1412586b4; git diff --shortstat origin/main...HEAD: 34 files, +951/-548.", "tests": "Merged tree after a fresh install and a full pnpm build: R1 fresh single boot discovery 200, 0 refusals; R2+R3 harness + webhook-materialization + walled declared-webhook pin 3 files/15 passed; plugin-webhooks 221/221 (409 guard pins included); objectql walled pins 68 and plugin-security walled fixtures 76 passed; CLI unit 314 files/4639 passed; the 7 restored walled e2e cases 7/7; typecheck objectql/plugin-webhooks/plugin-security/cli exit 0. R4 (isolated os serve boot with the real organizations runtime) was measured at 45898dbf6; the merge touched no serve.ts line, and the 7 e2e cases (which spawn a walled os serve) pass on the merged tree. After the fixture fix: plugin-sharing 49 files/1161 passed, plugin-auth 165 files/3168 passed 10 skipped, typecheck exit 0.", "gates": "dispatch-gates --commands on the merged tree: 110/110 exit 0. CI on 1412586b4: 36 success, 5 skipped, 0 failures (Test Core 1-6/6, Build Core, Type Check, Lint, Governed Surface Queue Guard all success).", "mcp_calls": "1 - pull_request_read get_check_runs", "api_writes": "2 more - fleet relay issue_patch (PR #24667 body), fleet relay comment (this addendum)", "open_questions": [], "out_of_scope_findings": [], "deviations": "The walled-rig grep (164 files) missed two walled fixtures that set the posture another way; CI caught them, and they are fixed above." }Generated by Claude Code