Repository navigation
Federated read × org-walled deployment has no reachable end-to-end coverage — the required dogfood test that names the path boots single-tenant and cannot emit the predicate #7834
Description
Activity
Routing fix (route A) from the triage seat: appended
domain:cli— routing only; thefindinggrade is unchanged and no ownership is taken.Landing rationale (read from source at
origin/main@ 31fb03d, not inferred from the title): the fix lands in the QA/verify harness surface —packages/qa/dogfood/test/showcase-external-autoconnect.dogfood.test.ts(therows.length >= 3assertion is at the cited site) andpackages/verify/src/harness.ts(confirmed:OS_TENANCY_POSTURE = 'isolated'is requested only whenopts.multiTenantis truthy). Bothpackages/qaandpackages/verifyaredomain:cliper the lanes table.Dedup: distinct from #7737 (the empty-read defect itself,
pm:blocked) and #7738 (the org-predicate injection defect, dispatched via PR #7833) — this card is the coverage gap those two lived in, filed from #7738's dev report. No existing open card covers it.Stale-premise check: both cited files exist at current
origin/maintip and read as the card describes.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
Triage grading (same round as the routing comment above): regraded
finding→needs-user-decision— the card's own "Step one — a decision, not code" section is right: choosing between a posture-aware fixture (needs the cloud-private@objectstack/organizationsboundary re-examined) and formally accepting seam-tier-only coverage is a maintainer appetite/strategy call, not something a dev agent should pick silently.domain:clistays (execution lands inpackages/qa/packages/verifyonce ruled).Required four-lens block (#7498):
- Platform long-term coherence — Option 2 (declare seam-tier coverage honestly on the dogfood test) adds zero new machinery; Option 1 (a fixture that emits the org wall without the cloud-private package) risks a second, half-honest wall implementation — special-case growth in the exact place the harness docstring warns about.
- Measured business pull — measured today, not hypothetical: this green required gate sat over external-datasource-federated-read: the platform injects its org-scoping predicate onto a federated remote table that has no organization_id column #7738's fail-open federated read; the poisoned intersection shipped and was found by dogfooding, not CI.
- AI-agent error-resistance — a green required test that names the path but boots it inert is actively misleading to agent readers ("reads as coverage"); a loud in-test statement of what is NOT covered beats silent green.
- Startup scope discipline — Option 1 is declare-and-maintain (a new fixture posture is a permanent obligation); Option 2 is document-and-move-on. Default lens favors 2.
Recommendation: Option 2 now (one comment on
showcase-external-autoconnect.dogfood.test.tsstating the wall is NOT exercised there + a seam-tier pointer to #7833's pin), and treat Option 1 as a separate appetite question only if the maintainer wants the general answer this card shares with #7802's class.Dedup/premise: #7818 (the #7802 exemption) merged at
60b672eafter this card was filed; it does not change this card's substance (different mechanism, same class). PR #7833 still open; its pin is seam-tier by its own description.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
huangyiirene commented
on Aug 12, 2026 CollaboratorMore actionsMaintainer ruling — 2026-08-12
裁定:选项 2 —— 承认该交叉面只有 unit/seam 层覆盖,并把边界写在 dogfood 测试上。
要点:
- 在
showcase-external-autoconnect.dogfood.test.ts的断言处写明:此测试覆盖 autoconnect 路径,不覆盖 org 墙(单租户 boot,谓词不发射);墙的回归防线是 fix(objectql): withhold the org-scope predicate from federated objects (#7738) #7833 的 seam pin(DriverOptions接缝,无需企业包即可达)。 - ⛔ 不建 posture-aware fixture:它依赖 cloud 私有的
@objectstack/organizations,可行性未测,不为一个交叉面投资测试基建。若未来该交叉面再出实measured 缺陷,先测 fixture 可行性再立卡。 - ⛔ 卡内三条「不要做」维持:不给单租户 boot 加断言(钉死惰性路径)、不 skip 该测试(autoconnect 半边是真覆盖)、不把 fix(objectql): withhold the org-scope predicate from federated objects (#7738) #7833 的 unit pin 当端到端证明。
- 与
mainis red for every PR that touchespackages/spec: #7769 gavesys_api_keyupdatewithoutbulk, and the conformance scan that catches it lives in a package #7769 never touched #7802 同类(「绿灯盖在未走过的路上」):两卡的一般性答案就是诚实注释 + seam pin,不再另立通用机制。
裁定人:维护者 huangyiirene(2026-08-12,接受 PM 综合分析后批准);由 PM 会话
session_01GZKbx4xyF7U5WXj6ch49BM代笔落卡。转pm:queue(注释卡,小)。
Generated by Claude Code
- 在
Claim: PM loop round 4 —
domain:cliseat.- Session:
session_01B3Kurx8qufrDzNjk4rag7V(accounthotlong) - Branch:
claude/issue-7834-dogfood-org-wall-boundary - Worktree: dedicated (cloud container)
- Domain:
domain:cli - File surface:
packages/qa/dogfood/test/showcase-external-autoconnect.dogfood.test.ts(the comment at therows.length >= 3assertion site) — and nothing else unless the measurement forces it, with a report. Stop on breach. - Container & model: S per the ruling (「注释卡,小」), but the deliverable IS the wording, which no gate checks ⇒ M treatment,
mode:cloud,model: claude-opus-5. - Serial constraints cleared:
packages/qa/**is touched by no in-flight claim — finding:/meta/_draftsserves DRAFT object schemas unmasked — the one ADR-0106 outlet left uncovered #6599/PR fix(meta): gate_draftsoutlets as authoring surfaces (ADR-0106 D5(4), #6599) #7907 (packages/rest+runtime/domains/meta.ts), [finding]ctx.log.debugis inferred, granted and documented, but the sandbox never installs it — a body calling it throwsTypeError: not a function#7661/PR fix(runtime): installctx.log.debugin the sandbox — the fourth level the CLI and docs already promise #7908 (runtime/src/sandbox/**), open-edition-honest-degradation c3: anonymous-deny ordering inverted on /ai/** (unauth /ai/models → 501, /ai/agents → 200 instead of 401) #7653/PR fix(runtime): consult the anonymous-deny gate before /ai/** capability answers (#7653) #7910 (runtime/domains/ai.ts), mcp-stdio-fail-closed c3: the stdio MCP transport starts but is permanently deaf (oclif arg parser pauses process.stdin) #7645 (packages/mcp), capability-declaration-lifecycle: no shipped resource enforces a package capability server-side (no REST action-invoke route on this build) #7680 (rest-route-ledger.ts+docs/qa/platform-checklist/**— a different tree frompackages/qa/). Disjoint.
Dispatched to execute the maintainer's 2026-08-12 ruling (comment
5261737155) as written; the dispatch carries it verbatim and untranslated.The failure mode I am holding the dev to: this card's whole point is that a green required test which names a path but boots it inert reads as coverage and is not. So the comment has to state plainly what is not exercised (the org wall — single-tenant boot, the predicate never fires) and where the actual regression defence lives (#7833's seam pin on the
DriverOptionsseam). A vague "see also" note reproduces the original problem in comment form.The ruling's three ⛔s travel with it: no posture-aware fixture (it depends on the cloud-private
@objectstack/organizations, feasibility untested, and one crossing does not justify test infrastructure); no assertions added to the single-tenant boot (that would pin the inert path); no skipping the test (the autoconnect half is real coverage); and ⛔ #7833's unit pin is not to be described as end-to-end proof.
Generated by Claude Code
- Session:
{ "issue": 7834, "status": "done", "branch": "claude/issue-7834-dogfood-org-wall-boundary", "pr": "https://github.com/objectstack-ai/objectstack/pull/7919", "premise_still_valid": true, "summary": "Executed the maintainer's 2026-08-12 ruling (comment 5261737155, option 2) verbatim: recorded the org-wall boundary as a 44-line comment at the `rows.length >= 3` assertion in packages/qa/dogfood/test/showcase-external-autoconnect.dogfood.test.ts. Comment-only, 1 file, +44/-0, no behaviour change, no new assertion. The comment states four things concretely so no future reader can mistake this test for org-wall coverage: (1) what it DOES cover — the ADR-0062 D8 autoconnect path, real coverage, which is why it is not skipped; (2) what it does NOT — the organization wall, because bootStack(showcaseStack) passes no options, `requestIsolatedPosture` in packages/verify/src/harness.ts requests OS_TENANCY_POSTURE='isolated' only when opts.multiTenant is truthy, AuthPlugin boots with autoDefaultOrganization:false and no org plugin is registered, so execCtx.tenantId is undefined, `hasTenant` short-circuits false on its FIRST conjunct before the isFederated exemption is reached, and the driver is handed no tenantId; (3) where the regression defence actually lives — #7833's pin in packages/objectql/src/engine-external-tenant-scope.test.ts at the DriverOptions seam, both directions, reachable without the enterprise package — described explicitly as a UNIT/SEAM pin and explicitly NOT as end-to-end proof; (4) why it is deliberately left this way — a posture-aware fixture depends on the cloud-private @objectstack/organizations, feasibility untested, and one intersection does not justify that test infrastructure. All three of the ruling's forbidden moves were held: no posture-aware fixture (harness.ts untouched), no assertion added to the single-tenant boot, no skip/todo.", "tests": { "behaviour_pinned": "none — deliberately. The deliverable is a comment; there is no behaviour to pin, and every alternative the card names (posture-aware fixture, assertion on the single-tenant boot, skip) is explicitly forbidden by the ruling. A test asserting that a comment exists would be theatre. Verification is instead: each factual claim in the comment re-measured, plus the test passing unchanged.", "showcase-external-autoconnect.dogfood.test.ts (post-change)": "3 passed / 3, 1 file — unchanged from before", "packages/qa/dogfood full suite": "92 passed / 1 skipped (93 files), 588 passed / 3 skipped (591 tests), 0 failed", "eslint (changed file)": "exit 0, clean", "tsc --noEmit (packages/qa/dogfood)": "exit 0", "pnpm build (full workspace)": "exit 0, 71/71 tasks", "dispatch-gates.mjs": "'No check family names the given paths in its own source' — no path-scoped gate family; 25 repo-wide families left to CI. lint.yml farm deliberately not run locally per dispatch.", "measurement_1_premise": "Both cited sites still read as the card describes on origin/main d447939. `expect(rows.length).toBeGreaterThanOrEqual(3)` present at the cited assertion. harness.ts: `const requestIsolatedPosture = !!opts.multiTenant && !prevTenancyPosture;` — isolated posture requested only when opts.multiTenant is truthy. Fixture calls bootStack(showcaseStack) with one argument.", "measurement_2_single_tenant_boot": "Quoted from this test's own boot log: \"[security] tenancy posture 'single' — Layer 0 is inert; the platform's own tenant-scoped RLS policies are stripped (app-authored ones are retained and fail closed, ADR-0105 D3)\". Corroborated by \"[security] org-admin grant backfill complete {...,\\\"posture\\\":\\\"single\\\"}\" in the same run.", "measurement_3_predicate_never_fires": "Re-measured directly rather than inherited from #7738's report. (a) #7833's `!isFederated` guard was temporarily removed from buildDriverOptions and @objectstack/objectql rebuilt: the file still passed 3/3, reproducing the original finding — a test that could catch the defect would have gone red. (b) With the guard still removed, a temporary probe in buildDriverOptions recorded every call in the boot: `object=showcase_ext_customer tenantId=undefined isFederated=true hasTenant=false` and the same for showcase_ext_order. Across the whole boot: 1069 buildDriverOptions calls, 0 with hasTenant=true, tenantId=undefined the only value ever observed. Both the guard removal and the probe were reverted; objectql rebuilt from unmodified source before all gates above; git status clean apart from the comment.", "measurement_4_what_7833_pins": "Read from the merged code on main, not from PR #7833's body. packages/objectql/src/engine-external-tenant-scope.test.ts asserts on DriverOptions in both directions: external objects get `expect(call!.options?.tenantId ?? undefined).toBeUndefined()` (and tenantIds) over it.each(READ_DOORS); ordinary objects still get `expect(call!.options?.tenantId).toBe('org_msoroxgurm6423gz')` plus the group-posture tenantIds union; a caller-supplied tenantId still wins. It constructs its own ExecutionContext with a literal tenantId and a fake driver, so it is reachable without @objectstack/organizations. Seam/unit only — it constrains what the engine hands the driver, never what a walled deployment returns over HTTP. The comment says exactly that. No false pointer (the #7578 class was checked for specifically).", "measurement_5_structural_claim": "Corroborated by the suite: test/rls-multitenant.dogfood.test.ts — the file that would exercise cross-tenant isolation — skips entirely in this repo (1 skipped file / 2 skipped tests, confirmed by running it alone) because @objectstack/organizations is absent. It accounts for the '1 skipped' file in the full-suite result. Pre-existing, unrelated to this change." }, "open_questions": [ "Comment placement: the ruling says '在断言处' (at the assertion). I put the whole block at the `rows.length >= 3` assertion and deliberately did NOT also add a pointer to the file's header comment, to hold the PM's stated file surface exactly. A reader who skims only the header will not see it. If the maintainer prefers a one-line header pointer as well, it is a two-line follow-up — not done here rather than guessed at.", "Comment length: 44 lines is long for one assertion, chosen because the card's failure mode is precisely a note too vague to stop a misreading, and because this repo's surrounding style (the BootOptions.multiTenant docstring, the #7833 pin's header) is equally long-form. If the maintainer wants it compressed, the four required facts survive in roughly half the lines.", "The comment cites #7738's original re-measurement AND states it as re-verified here. I re-ran it myself rather than quoting, so the claim is first-hand; the comment does not say 'measured on this branch' explicitly, only 'Measured on #7738'. That reads accurate but understates the evidence. Left as-is because the comment's job is to inform a future reader, and #7738 is the durable reference; the branch-local re-measurement is recorded in the PR body instead." ], "out_of_scope_findings": [] }
Generated by Claude Code
ACCEPTED — PR #7919. Landing on gate-green.
Reviewed by the
domain:cliseat (hotlong, sessionsession_01B3Kurx8qufrDzNjk4rag7V) against the diff. One file, comment-only,packages/qa/dogfood/test/showcase-external-autoconnect.dogfood.test.ts— exactly the declared surface, no adr/skills paths, nocontent/docs/releases/.It proved the blindness instead of asserting it
The claim this comment has to support is "this green assertion cannot catch an org-wall regression." That could have been written as a plausible paragraph. Instead it is measured: on #7738,
engine.tswas checked back out at pre-fixmain,@objectstack/objectqlrebuilt, and this file re-run — 3 passed / 3 both WITH the fix and WITHOUT it. A test that scores identically on a fixed and a broken engine is not coverage of that engine, and now the file says so with the experiment attached.The mechanism is traced, not gestured at
bootStack(showcaseStack)passes no options →requestIsolatedPosturefires only whenopts.multiTenantis truthy → posture issingle(the boot log line is quoted) →execCtx.tenantIdis undefined → that is the first conjunct ofhasTenantinbuildDriverOptions, so it short-circuits false before theisFederatedexemption is even reached. That last step matters: a reader who assumed the exemption was doing the work here would draw the wrong conclusion about what a regression would look like.All three of the ruling's ⛔s are honored
No posture-aware fixture. No assertions added to the single-tenant boot — and the comment says why in the imperative ("⛔ Do not 'fix' this by asserting tenancy on this single-tenant boot — that pins the inert path and makes the false reading of coverage worse"), so the next author is warned off the same trap. The test is not skipped, and the comment leads with what it genuinely does cover so nobody deletes it as dead weight.
#7833's pin is pointed at and correctly bounded — named as a
DriverOptionsseam pin asserting both directions, and explicitly marked ⛔ UNIT/SEAM, not end-to-end proof: it pins what the engine hands the driver, never what a walled deployment returns over HTTP. I asked for that boundary to be explicit precisely because "there is a pin for it" is how a seam test gets quietly promoted to end-to-end in someone's memory.I also required that #7833's pin be verified to exist and to be what the comment claims — a comment pointing at a defence that does not exist is the false-pointer class #7578 just fixed in this same repo, and re-creating it one card later would have been a poor look. It checks out.
One detail worth keeping: the comment records that
'posture-only'stamps nothing and scopes no query, so even that cheaper harness option would assert nothing here. That closes the obvious "why not just use posture-only?" follow-up before it is asked.⛔ Not flipped yet: ESLint and TypeScript Type Check must both read
conclusion: successon the head commit first.
Generated by Claude Code
- added a commit that references this issue
on Aug 17, 2026
Measured by #7738's dev, who then re-measured their own first explanation and found it wrong (report, correction). Filed unassigned.
The gate that should have caught #7738, and could not
packages/qa/dogfood/test/showcase-external-autoconnect.dogfood.test.ts:37assertsrows.length >= 3for an authenticated admin read ofshowcase_ext_customer. It is part of a required CI job (3 shards,ci.yml:709).Per #7738's QA capture, that authenticated read returned 0 rows — a declared, correctly-bound external object silently answering empty. So this assertion is exactly the shape that should have failed, and CI was green.
The first explanation was plausible and wrong — the second is measured
The initial hypothesis was that the
@objectstack/verifyharness's signed-in admin carries no active org, leaving the wall dormant. Rather than leave that standing, the dev checkedengine.tsback out atmain, rebuilt@objectstack/objectql, and re-ran the same file: 3 passed / 3 — with the fix and without it.That is the decisive measurement. The test does not merely fail to assert the wall; it never emits the predicate at all, in either direction. It could not have caught this defect and cannot catch a regression of it.
Mechanism, one line of harness:
bootStacksetsOS_TENANCY_POSTURE=isolatedonly whenopts.multiTenantis truthy —packages/verify/src/harness.ts:268. This test callsbootStack(showcaseStack)with no options.[security] tenancy posture 'single' — Layer 0 is inert; the platform's own tenant-scoped RLS policies are stripped.execCtx.tenantIdis undefined,hasTenantis false atengine.ts:2528, the driver never receives atenantId, andapplyTenantScopeearly-returns.The structural part — this is not a missing assertion
Per
BootOptions.multiTenant's own docstring, the only honest way to boot the organization wall ismultiTenant: truewith the cloud-private@objectstack/organizations.'posture-only'is explicitly documented as performing no isolation — "nothing stampsorganization_id, nothing scopes a query" — and the gates that need the real wall SKIP without that package.⇒ The intersection this bug lived in — a federated read × an org-walled deployment — has no reachable end-to-end coverage in this repo's dogfood tier. The one federated-read fixture boots single-tenant; the one honest walled harness is unavailable here.
Same class as #7802, different mechanism
#7802: a cross-package conformance scan is never run because affected-subset CI is keyed on the package the scan lives in.
This: a required test runs, passes, and names the path — while booting a posture in which the thing under test is inert.
Both are a green gate over a path it does not exercise, which is worse than an absent gate because it reads as coverage. Worth deciding together whether there is a general answer.
⛔ What not to do
DriverOptionsseam and is reachable without the enterprise package — it closes the regression risk, and it is genuinely not an end-to-end proof.Step one — a decision, not code
Pick honestly between:
Related
mainis red for every PR that touchespackages/spec: #7769 gavesys_api_keyupdatewithoutbulk, and the conformance scan that catches it lives in a package #7769 never touched #7802 — the sibling green-gate-over-unrun-path card (CI affected-subset scoping).