Skip to content

QA run · all (214/215) · 502ff8b5 · 2026-08-30 · 39 PASS / 88 PARTIAL / 5 FAIL / 82 BLOCKED / 1 NOT-RUN #13404

Description

@baozhoutao

Full platform-checklist run (selector: all) executed against a live multi-node ObjectOS EE deployment — the specific ask was "run the whole checklist in Traefik cluster deployment mode". This is a deployed EE runtime, not the stock showcase dev app, which is why the blocked count is high and honest: a large slice of the checklist is authored against showcase fixtures / objectui browser pins that a deployed EE runtime does not carry.

Environment fingerprint

  • Subject: ObjectOS EE (com.objectstack.objectos-ee 4.1.1, runtime 17.2.0), framework pinned at 502ff8b5, objectui console vendored at 2a23000f.
  • Topology: 3 app replicas behind Traefik (docker provider, /api/v1/ready health-checked upstreams), Postgres 16 + Redis 7 (OS_CLUSTER_DRIVER=redis), one-shot migrate. Single-DB multi-org, OS_TENANCY_POSTURE=isolated, membership invite-only, OS_AI_STUDIO_AGENTS=ask (AI Builder withheld), OS_CLOUD_URL=off.
  • Checklist source: docs/qa/platform-checklist/ at 277948f7; each verdict is stamped with its item revision in the in-session JSON scratch.
  • Runner: 15 area-runners + 2 verify-passes (RUNNER rule 7), each an independent agent driving server-truth oracles; browser only where a clause's oracle demanded it. Metadata writes pinned per-replica to sidestep the known cross-node invalidation gap (objectstack#13331).

Scope & coverage

215 runnable checklist items across 15 areas (6 blocked items hidden by the selector, excluded). 214 judged, 1 not-run (platform-core.shell-nav-personalization, P2 objectui-persistence, browser budget).

area items pass partial fail blocked not-run
access-security 22 1 14 0 7 0
ai 7 2 5 0 0 0
api-backend 16 6 4 0 6 0
approvals 12 1 0 0 11 0
attachments-storage 9 6 2 0 1 0
automation 16 0 3 0 13 0
cli 16 4 12 0 0 0
dashboards 10 1 5 0 4 0
i18n 5 2 3 0 0 0
identity-auth 16 3 9 0 4 0
integration-system 16 2 9 1 4 0
platform-core 18 3 8 0 6 1
records-forms 32 5 8 1 18 0
search 6 2 4 0 0 0
studio-authoring 14 1 2 3 8 0
total 215 39 88 5 82 1

The per-clause verdict detail (every acceptance/negative clause, its oracle, and the text evidence) is the in-session JSON scratch per RUNNER; this record carries the per-area rollup, every FAIL in full, and the accuracy/fixture findings.

FAILs (5) → extraction

Each FAIL was reproduced ×2 and, for the release-relevant ones, independently re-derived by a second agent from the captured evidence alone (RUNNER rule 7).

  1. integration-system.datasource-credential-refusal-matrix (P0, security). CONFIRMED by verify-pass. A credential exposure on the datasource read path. Per RUNNER rule 2's carve-out (auth/authz/secrets), detail withheld pending maintainer — no reproduction is published here or on any extracted card. Extracted as an existence-only card (below).
  2. records-forms.concurrent-edit-conflict (P1). Optimistic-concurrency token mismatch against the Postgres driver — CONFIRMED by verify-pass. This is already tracked as objectstack#13382 (same mechanism and source line); not re-filed — a QA-source pointer is added there.
  3. studio-authoring.draft-publish-lifecycle (P1) and studio-authoring.view-authoring-live (P1) and studio-authoring.packaged-display-class-direct-edit (P2) — three FAILs that resolve to two distinct root causes under isolated multi-org, both CONFIRMED by verify-pass:

Product defects extracted (RUNNER extraction obligation)

Checklist-accuracy notes (for the checklist owner; not extracted as bugs)

  • records-forms.bulk-write-contract — updateMany/deleteMany are id-based ({records:[{id,data}]} / {ids:[]}) and createMany takes a raw array; the item's where-clause steps don't match this build.
  • api-backend.date-range-preset-matrix — DATE_RANGE_PRESETS are not wired to the data-API filter door at this sha.
  • ADR-0126 items (automation.packaged-flow-*, automation.setup-packaged-automation-board, platform-core.activation-ledger-*, access-security.activation-write-operator-gate, api-backend.packaged-action-disabled-dispatch, action-activation-door-contract) test machinery (sys_metadata_activation, kill-switch) that postdates framework 502ff8b5 — blocked(dependency) with grep-absence evidence.
  • Two client-error-shape observations matching items' own knownGaps: manifest protocol-incompat and namespace-conflict return 500 where a 4xx would be the client-error shape (platform-core.manifest-install-contract); FileConstraintError exits /api/v1/data as a sanitized 500 (records-forms.field-accept-maxsize-server-enforced).

Fixture / environment gaps (inherent to testing a deployed EE runtime)

  • No showcase corpus on the EE deployment (objects, seed data, apps, flows, dashboards, permission sets, business-unit tree, public forms, packaged flows) — the dominant blocker; ~half the browser/mixed clauses are blocked(fixture) because their steps name showcase fixtures.
  • Subsystems not mounted on this EE image: plugin-approvals (approvals area 11/12 blocked — decision routes 501), reports service (501), analytics cubes (none registered), webhook subsystem (sys_webhook 404), authorable connector/job/email_template/datasource metadata types.
  • objectui-only automated.ref pins (documented RUNNER environment fact) — 23+ browser items' pins live entirely in the objectui repo and are not runnable/pin-evidenced from a framework checkout.
  • No restart permitted on the shared live cluster mid-run → 2FA arming, env-lock, migration scratch-boot clauses blocked(environment).
  • objectstack#13331 (cross-node metadata invalidation disabled on this boot path) attributed throughout — runtime-authored metadata registers only on the writing replica; all such traffic was pinned per-replica.

Cluster resilience observed during the run

The deployment stayed healthy across the sweep except for one self-inflicted outage: a test datasource with an unstartable driver drove /ready to 503 on every replica (drivers list qa_integration_ds1/qa_integration_dsbad), draining all Traefik upstreams; delete did not evict the engine driver registry, so only a restart cleared it (extracted as the availability card above). Redis cluster coordination (os:lock:* / os:fence:*), leader-elected cron single-execution, session-across-replicas, org isolation, and readiness-drained rolling restarts all held (see the deployment verification record in objectstack-ai/cloud, branch claude/enterprise-cluster-deployment-qxiexe).

Activity

  1. baozhoutao commented on Aug 30, 2026

    @baozhoutao
    ContributorAuthor

    Close-out — extraction complete.

    Extracted: #13405 · integration-system.datasource-credential-refusal-matrix · clauses 1,3 (security, existence-only)
    Extracted: #13406 · studio-authoring.draft-publish-lifecycle · history,diff
    Extracted: #13406 · studio-authoring.packaged-display-class-direct-edit · dashboard-overlay
    Extracted: #13407 · studio-authoring.view-authoring-live · consumer-read
    Extracted: #13408 · integration-system · availability (observed during run)
    Carried-forward: #13382 · records-forms.concurrent-edit-conflict · fail (pre-existing card, live corroboration commented)
    

    Checklist-accuracy notes and fixture gaps are recorded in the body above (no separate anchor card for a standalone all run). objectstack#13331 (cross-node metadata invalidation disabled) attributed throughout, not re-filed. Two environment blockers recorded in body: no showcase corpus and several subsystems (approvals/reports/cubes/webhooks) not mounted on the EE image — inherent to testing a deployed EE runtime rather than the showcase dev app.


    Generated by Claude Code

  2. baozhoutao commented on Aug 31, 2026

    @baozhoutao
    ContributorAuthor

    Coverage follow-up — custom-permission clauses upgraded from pin-only/blocked to live-driven on the same cluster (namespaced qa_perm_* fixture, cleaned up, no restart):

    • access-security.crud-permission-matrix (was pin-only) → live: built 3 objects + 3 permission sets + 3 server-proven personas and drove the full 36-cell CRUD grid — allow 15/15 succeed+persist, deny 21/21 403 PERMISSION_DENIED, denied-CREATE leaves 0 rows; viewAllRecords/modifyAllRecords both-sides pass. 0 fail-open cells, no cross-persona leak. (clause 5 guest-lane still blocked(fixture).)
    • access-security.permission-matrix-edit-loop partial → pass: the console PermissionMatrixEditor (clause 5) now driven live — checkbox toggle → PUT /meta/permission/... → server-truth re-read confirms the verb flipped.
    • studio-authoring.permission-matrix-editor-ux blocked → partial (live): editor reachable and functional (field-filter, read-only badge, narrow-viewport bulk column); B4 bulk-over-visible blocked(environment).
    • access-security.capability-declaration-lifecycle blocked → partial (live): sys_capability DECLARE (data door) + shadow-name guard (platform names 403) + write-door validation + GRANT side all live; REQUIRE-side blocked(fixture) (no runtime-drivable capability-gated action; platform system-cap gates key off positions/isPlatformAdmin, so a set-held cap is fail-safe refused).

    Revised totals: 40 PASS / 89 PARTIAL / 5 FAIL / 80 BLOCKED / 1 NOT-RUN (judged 214/215; title unchanged).

    Observation (fail-safe, not filed): the console permission-matrix editor writes the meta/permission projection, but live enforcement resolves from sys_permission_set data rows — so an editor save did not flip a data-row-backed persona's access on this EE image (runtime-created sets also resolve read-only in the editor). It is fail-safe (never fail-open), but "editor edits don't reach enforcement" is a two-store-consistency question worth a maintainer look; not filed pending that call.


    Generated by Claude Code

  3. baozhoutao commented on Aug 31, 2026

    @baozhoutao
    ContributorAuthor

    UI supplement — the approvals / dashboards / charts / reports items that were blocked(fixture) on the EE cluster (those subsystems aren't mounted on the EE image) were re-run in a real browser against a showcase dev app with the console UI (framework 502ff8b5, console pin 190fbd01, examples/app-showcase at :4100 — approvals/analytics/dashboards/reports all mounted, 132 seed rows). Chromium via /opt/pw-browsers/chromium, screenshot-first, every pixel cross-checked against the API.

    Approvals (was 1 PASS / 11 BLOCKED on the cluster → 12/12 PASS live-UI): inbox render + drawer actions, per-group signoff (server-computed chips reconciled at each stage), viewer-gating (both sides — non-approver drawer omits Approve/Reject, forged approve → 403), notification deep-link (cold-load opens the right drawer), the 9-way decision-action matrix (approve/reject/reassign/revise/resubmit/maxRevisions-auto-reject/recall/remind/request-info), decision-only-via-service (forged resume → 403, owner service → completed), dynamic approver routing (typed record-picker, staged), OOO delegation reroute (+audit +notif +expiry), record-page decisions (locked exec vs editable manager, single reject dialog — no #3126 double), setup nav order, pending-count badge clamp ("9+" badge / unclamped popover). No defects.

    Dashboards / charts / reports (was 1 PASS / 5 PARTIAL / 4 BLOCKED → 6 PASS / 3 PARTIAL / 1 BLOCKED live-UI): charts actually paint — recharts SVG with real geometry (treemap 5 nested rects, sankey 5 flow links, scatter 6 points, combo dual-axis), mark counts equal the analytics buckets; chart-type-matrix all 16 families; strict-widget author-time rejection (12 stray-key variants → 422); dataset-report designer draft→publish→auto-flow render; system-overview live counts reconciled; cube-query reconciled bucket-for-bucket. Partials: global-filters-rescope (runtime clauses pass; only the Studio widget-inspector authoring round-trip not driven), drill-through-range and empty-null-bucket (month-bucket UI path blocked by the analytics defect below). Blocked: saved-report-ownership — the saved-reports service (/api/v1/reports*) returns 501 "not configured" on the showcase dev app too, not just EE — the sys_saved_report service is a separate plugin absent in both; the /meta/report metadata reports render fine. So "reports 501" is a genuinely-unmounted service in both builds, not an EE-only gap.

    New defect extracted: #13714 — analytics cube query with a timeDimensions month granularity on a date dimension crashes 500 DATABASE_ERROR (count/status buckets fine); this is what blocks the month-bucket UI drill/empty-state clauses above.

    Net: the three subsystems the maintainer asked to test (reports/approvals/charts) are now UI-verified end-to-end on the environment that actually carries them; the cluster's blocked verdicts for these stand as "not mounted on the EE image" (a deployment-shape fact), now paired with live-UI PASS on the composed showcase app.


    Generated by Claude Code

  4. baozhoutao commented on Aug 31, 2026

    @baozhoutao
    ContributorAuthor

    UI supplement complete — the remaining browser bands were driven in the showcase console (framework 502ff8b5, console 190fbd01, :4100), screenshot-first, API cross-checked. Combined with the earlier approvals + dashboards UI, every browser/UI surface the checklist defines is now live-driven across the two environments (EE cluster for the deployment shape, showcase for the composed feature set).

    records-forms browser (21 items · 2 PASS / 16 PARTIAL / 2 BLOCKED / 1 NOT-RUN / 0 FAIL): kanban drag-persistence (illegal transition → 400 snap-back + toast), all 6 view types render, CRUD roundtrip, calendar/gantt drag → PATCH confirmed, conditional-rules row-scoped requiredWhen, master-detail roll-up, related-list parent-scoped pagination, discussion → sys_comment, saved-view create, lookup-picker, list-view + CJK $search, form visibleWhen both-sides. Partials are objectui-only pin clauses + single-user/seed-thin limits; the two candidate negatives (modal-form Undo; calendar quick-create 400) were ruled wrong-panel / fixture-mismatch, not defects.

    studio-authoring UI (14 items · 5 PASS / 7 PARTIAL / 2 FAIL): first-run-loop (new package → object designer → app → publish, all API-reconciled), object-designer field roundtrip, CEL expression editors with record. autocomplete + aria-invalid, custom pages (KPIs match the data plane cell-for-cell), page-variables (resolved POST body, real server effect), permission-matrix editor (writable + read-only-package gate), packaged-automation lock. The 2 FAILs are the already-filed #13406 (overlay /history+/diff empty; packaged dashboard overlay stored-but-not-served) — now reproduced on single-node showcase via the Studio UI, which broadens that card's root beyond isolated-multi-org (commented on #13406). No new defects.

    i18n / search / nav (9 items · 6 PASS / 3 PARTIAL / 0 FAIL): locale switch (zh chrome/notifications/Studio, zero dotted keys, unknown locale → 200 empty), global search (Ctrl+K, grouped by object, Enter navigates, RLS parity — contributor member's INV-1003 → [] vs admin), nav-surfaces (32 destinations 0-error), builtin-apps (member Setup denied server-side), and shell-nav-personalization — the run's single NOT-RUN — upgraded to partial live (collapse/pin/recents persist across reload).

    UI-run defect ledger: #13714 (new — analytics cube month time-dimension → 500) and #13406 (strengthened — overlay history/diff + dashboard overlay read, now shown non-multi-org). No new auth/authz findings; every candidate negative across the UI bands was ruled a false signal per RUNNER rules 2/5 before filing.

    Consolidated coverage: the deployed EE cluster proved the deployment shape (cluster coordination, org isolation, RLS/permissions, API contracts, plus the 5 FAILs and the #13331-under-load severity), and the composed showcase app proved the feature surfaces the EE image doesn't mount (approvals, reports/charts, Studio authoring) end-to-end through the real console UI.


    Generated by Claude Code

  5. os-warren commented on Aug 31, 2026

    @os-warren
    Collaborator

    分诊处置:记录类,按设计不打 domain:*。 标签保持 qa-run 不变。

    本卡是一次 QA 运行的证据记录,不是任何车道里的工作项 —— 它横跨 15 个区域,任何单一 domain:* 都会是错的。与 finding(定级前无车道)同理:qa-run 是一个不进车道的类。写在这里,是因为本卡会持续出现在「无车道」的扫描视野里,而它不是漏标。

    提取义务已核,无悬空

    本卡列了四条 extracted 卡但正文只写「see card」未给编号,逐条查过:

    提取项 卡 状态
    P0/security · datasource 嵌套 config 凭据明文下发(存在性卡,细节按 RUNNER 规则 2 扣留) #13405(security priority:p1 domain:spec) 已关闭
    functional · getViewsByObject 漏运行时创作的 view 容器 #13407 本轮已分诊 → domain:engine · p1 · pm:queue
    functional · org-scoped metadata 读路由在 isolated 下按 env 读 见 #10340 / #10503 / #6780 家族 ⚠️ 未在本轮核对编号
    availability · 驱动起不来的 datasource 让 /ready 全集群 503 且删除不驱逐 相关 #3756 ⚠️ 未在本轮核对编号

    ⚠️ 后两条我没有逐一确认提取卡是否真的开出来了 —— 上表只对前两条是读数。若某一条实际未立卡,那它就只存在于本记录的散文里,对候选查询与老化告警不可见;请立卡方回贴编号,或告诉我,我下一轮补立。

    本轮由本记录带出的两处交叉

    「Checklist-accuracy notes」一节(bulk-write-contract 的 where 子句不符、DATE_RANGE_PRESETS 未接线、ADR-0126 机件晚于该 sha)是给清单所有者的,⛔ 不作为产品缺陷提取 —— 本记录自己已经这么声明,分诊认同。


    Generated by Claude Code

  6. baozhoutao commented on Sep 1, 2026

    @baozhoutao
    ContributorAuthor

    Cluster-mode test matrix — the coordination / data-integrity / topology concerns that the feature checklist doesn't cover, run directly against the live 3-replica EE deployment (Traefik + redis cluster driver), driving replicas individually via docker exec to control which node handles each request.

    Coordination primitives / data integrity across replicas

    • Autonumber counter — 60 concurrent creates spread across all 3 replicas → 60 distinct autonumber values, no collision. (The #8686 seed warning about two counters is a seed/API tenancy split, not a cross-replica race; the cross-replica counter is coordinated.) ✅
    • Unique constraint — same value inserted concurrently on all 3 replicas → exactly 1 × 201 / 2 × 409, one row persisted. ✅
    • Concurrent write durability (from the load harness) — 200 concurrent creates → 200 persisted, 200 distinct, no lost writes / dupes; 30 concurrent unguarded PATCH to one record → row consistent, one winner. ✅
    • OCC across replicas — broken, tracked as objectstack#13382 (Postgres token format). 🔴

    Metadata / cache coherence

    Session / authz across replicas

    • Session revocation — after POST /auth/sign-out on app-2, the token is rejected on all 3 replicas (DB-backed sessions). ✅ (First reading was a test artifact — sign-out needs a JSON body or returns 400; with {} it revokes cluster-wide.)
    • Authz grants cache — OS_AUTHZ_GRANTS_CACHE_TTL_MS is unset (0) → cache off → no revocation-staleness window; permission edits take effect immediately (matches the permission-matrix edit-loop live result). ✅ (safe by default)

    Topology / availability

    • Replica kill + recover — docker stop app-4 during load → LB served 30/30 200 (Traefik routed to survivors), data readable, app-4 rejoined in ~15s. ✅
    • Rolling restart drain — 60/60 probes through a one-replica restart under Traefik readiness health-checks (earlier). ✅
    • Split-brain guard — a boot with OS_CLUSTER_DRIVER=memory + OS_CLUSTER_REPLICAS=2 refuses to start (✗ ClusterServicePlugin: multi-node deployment declared … driver is in-process "memory" … split-brain, exit 1), override OS_ALLOW_MEMORY_CLUSTER_MULTINODE=true. ✅
    • Leader failover / job continuity — a per-minute schedule flow fired exactly once per minute across a mid-window docker stop of a replica (the killed minute and the recovery minute each = 1 row, no miss, no double). The per-tick cluster.lock acquisition gives inherent failover. ✅
    • Stuck-datasource readiness — a datasource with an unstartable driver 503s /ready cluster-wide and isn't evicted on delete → LB drains everything; tracked as objectstack#13408. 🔴
    • Licensed node-cap advisory — the documented cluster.mdx §8 advisory never fires because the EE gate returns no admitted; the license maxNodes is inert. Filed as objectstack-ai/cloud#1824. 🟠

    Documented non-goals (verified, not defects)

    • Cross-node realtime fan-out is a documented non-goal (cluster.mdx §3); the EE image does not mount a realtime HTTP surface (/realtime, /events → 404). Recorded.

    Net cluster-mode posture: coordination (locks/counters/unique/leader-failover), org isolation, session/permission propagation, and HA (node loss, rolling restart, split-brain refusal) all hold; the open gaps are the three already-tracked defects (#13331 runtime-metadata registration, #13382 OCC, #13408 readiness) plus the inert node-cap (cloud#1824). All test fixtures cleaned up; cluster left healthy.


    Generated by Claude Code

  7. baozhoutao commented on Sep 1, 2026

    @baozhoutao
    ContributorAuthor

    Cluster load/stress test — ramped to saturation against the live 3-replica EE deployment (Traefik LB, redis driver, Postgres 16 max_connections=200), sampling DB connections + /ready every 5s.

    P1 — /health (process-only, no DB), 8s/step: clean to saturation.

    conc rps err% p50 p95 p99 max
    25 973 0 20 64 102 333
    100 1051 0 80 187 349 2695
    400 1376 0 197 405 3631 8050

    The HTTP / Traefik / Node layer sustains ~1,000–1,400 rps of trivial requests with 0 errors — the front door is not the bottleneck.

    P2 — authed GET /data/note?limit=10 (org-scoped, DB), 8s/step: this is the ceiling.

    conc rps err% p50 p95 p99
    10 19 0 513 813 1016
    50 24 0 1988 2485 2627
    100 25 0 3738 4584 5141
    150 — 77.8% — 12027 12834 (1070× 503)

    Throughput plateaus at ~25 rps across the whole cluster while latency climbs linearly with concurrency (classic closed-system saturation: throughput flat ⇒ latency = concurrency ÷ throughput). At conc=150 the app sheds load — 78% 503 — rather than queueing unbounded.

    P3 — POST /data/note create, 8s/step: same ~25 rps write ceiling, 0 errors to conc=80, p50 446ms→2638ms.

    P4 — sustained 45s @ conc=50 (80/20 read/write): 27 rps, 0 errors, p50 1746ms / p95 2638ms — stable, no drift or degradation over the window (no memory-creep collapse, no readiness flap).

    Root cause of the ~25 rps ceiling — the default DB connection pool, not Postgres. Throughout every phase the sampler showed Postgres holding only ~9–21 connections against its 200 limit, and at steady state the app accounts for just 9 connections total across 3 replicas (~3 per replica). No OS_*/pool-size env is set on this deployment, so the pg driver's small default pool is in force: ~3 concurrent DB ops per replica × 3 replicas ÷ ~350ms/query ≈ the 25 rps observed. The DB has ~10× headroom that the pool never uses.

    Takeaways for a cluster deployment:

    1. Authed data-API throughput is pool-bound at ~25 rps by default and scales with replica count, not with the (idle) DB headroom — raising the per-replica connection pool is the lever, but no documented OS_* knob exposes it on this image (worth surfacing one).
    2. Under a concurrency spike (≥~150) the data path sheds to 503 rather than degrading gracefully; combined with Traefik readiness-draining, a sustained spike risks the whole-fleet-drain failure mode already seen with the stuck-datasource case (availability: a datasource whose driver fails to start pins /api/v1/ready to 503 cluster-wide and is not evicted on delete — one bad tenant datasource drains every LB upstream #13408). Front-door (/health, static) capacity is ~1,400 rps and is not the constraint.

    No data corruption or lost writes at any load level (the concurrency-integrity tests above cover that); this phase characterizes throughput/latency/failure-mode only. All load rows cleaned up; cluster left healthy (/ready 200, DB back to baseline).


    Generated by Claude Code

  8. baozhoutao commented on Sep 1, 2026

    @baozhoutao
    ContributorAuthor

    Supplement · single-DB multi-org isolation verification on Postgres

    The main sweep exercised the deployment under OS_TENANCY_POSTURE=isolated but did not carry a dedicated tenant-isolation enforcement matrix. This supplement targets that gap directly — the isolation boundary itself, on Postgres 16.15, against a single shared database in multi-org mode. All four cases PASS.

    Enforcement point (established first)

    The isolation boundary is application-layer (WHERE organization_id = <session org> on every data-path query), not native Postgres row-level security. Confirmed on the live DB: pg_policies → 0 rows, pg_class where relrowsecurity → 0 tables. So these tests exercise the code path that actually enforces tenancy, not a DB feature that isn't in use.

    Method

    Two real users (owner@cluster.test, member of both orgs acme/globex; alice@cluster.test, acme-only), driving one replica directly (docker exec), object qa_iso (sharingModel: public_read_write — the most permissive OWD, so any leak is attributable to tenancy, not record sharing), fields: anum (autonumber), ucode (unique text), tag. Server-truth oracles (HTTP status + persisted organization_id), each case run twice.

    # case result
    T1 Forged cross-org read by id — create record in acme, switch same session to globex, GET /data/qa_iso/{id} PASS — 404 (isolated); the row is invisible outside its owning org even by direct id
    T2 Cross-org write stamp — acme session POST with organization_id: <globex> in the body PASS — 201, persisted organization_id = acme; body-supplied org ignored, re-stamped to session org (no write into a foreign tenant)
    T3 Unique-constraint tenant scope — same ucode created in acme then globex PASS — both 201; uniqueness is per-org, not a global index (no cross-tenant coupling / no enumeration oracle)
    T4 Autonumber under multi-org (#8686) — two creates in each org, compare anum PASS — acme: 0009,0010 · globex: 0005,0006, all distinct; single global counter, no per-org counter collision (the #8686 failure mode does not reproduce here)

    Read this against #13331

    This confirms the data plane isolates correctly per org on Postgres. It does not revisit the separate, already-filed metadata-read org-scope gap from the main sweep (/meta/:type/:name/history·/diff·single-item dashboard overlay reading env-wide under isolated) — that is a distinct read path and remains as extracted. Record-level tenant isolation and metadata-read org-scoping are two different enforcement points; this supplement closes the former.

    Environment otherwise identical to the run above (EE 4.1.1 / runtime 17.2.0, framework 502ff8b5, 3 replicas behind Traefik, single Postgres + Redis, isolated posture). Test object/rows cleaned up after the run.


    Generated by Claude Code

  9. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    Contributor

    Superseded: closed not_planned

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-06T16:02Z. The maintainer approved clearing the open qa-run records' close-out debt: 「同意,动手」. This was audited row by row (read-only) against checklist-test §5 before this write.

    Superseded-by: #21720
    Superseded-by: #21721
    Superseded-by: #21722
    Superseded-by: #21782
    Superseded-by: #21784


    Generated by Claude Code

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions