Repository navigation
Description
qa#3 · os-tesla · session_01L9qibzj9DrVWXkq7joYHGB
Routine regression (checklist-test §6), the owed-retest list, dispatched by qa#3 (seat #33014) on the maintainer's 2026-11-14 21:46Z choice 「只跑 P0 和欠测复测」. Labels: qa-run only.
Environment fingerprint
- Framework: objectstack-ai/objectstack
main@0c2aeb96(2026-11-14 21:16Z). Console under/_consolebuilt in the same tree fromui/at 22:08Z; for every fix that landed inui/(Docs portal: a section cross-link through a flat permalink loses its #fragment on the redirect, so the doc opens at the top #33055, Edit form shows no home-amount preview for a record-mode amount computed by an expression (showcase invoice): the read-only branch of CurrencyField skips it #32941, Set as Default on a list view leaves two default views when the previous default is a package-shipped view (its unset PUT is refused 403, the new default still lands) #33098) the runner grepped the served bundle for the change before scoring a UI clause. - App:
examples/app-showcase, booted per item withobjectstack dev --seed-admin --no-compile --no-watch, ownOS_PORT(41160–41199) and own file DB under/tmp/qa3/{D,E,F}/. Install-local, authoring, CLI and override legs ran on scratch app copies under/tmp/qa3/{D,E}/wswith their ownOS_HOME/HOME. - Runner: one Claude Code cloud session (thread runner for qa#3), 3 parallel runner subagents (effort high): D api 14 · E cli+mixed 11 · F browser 5. Node 22.23.4, pnpm 10.31.0, Playwright chromium.
- Timestamps: setup 21:55–22:08Z (shared with the priority:P0 record of the same round); tests 22:26–23:43Z.
Scope
Selector owed:weekly: the list node scripts/qa/retest-owed.mjs computed at seating (2026-11-14 ~21:50Z) — 33 rows, minus platform-core.builtin-apps-nav-render and platform-core.console-login (judged in the priority:P0 record of this round) and smoke:npm-18.4.0·D2 (a smoke cell, re-judged at the next npm smoke). Each id resolved as a bare id (§0). For each item the runner drove the item's clauses at the pinned revision and the named fix card's own repro.
| item | rev | surface | fix card(s) re-judged | last judged by | verdict |
|---|---|---|---|---|---|
| access-security.permission-set-address-in-execution-context | 3 | api | #32945 | #32940 5fb79bc0 2026-11-12 |
PASS |
| access-security.security-catalog-activation-and-clone-doors | 5 | api | #33082 | #33081 8e3d4a54 2026-11-13 PASS |
PASS |
| ai.mcp-coded-refusals-and-runtime-exposure | 5 | api | #33030 | #33081 8e3d4a54 2026-11-13 PASS |
PASS |
| ai.mcp-dataset-tools | 1 | api | #33028, #32944 | #33081 8e3d4a54 2026-11-13 PASS |
PASS |
| ai.mcp-read-file-pdf-word-extraction | 2 | api | #33032, #32945 | #33025 ee9ad834 2026-11-13 FAIL |
PASS |
| ai.mcp-run-action-exposure-gate | 7 | api | #33029, #32163 | #33092 c4196099 2026-11-13 PASS |
PASS |
| ai.mcp-tool-call-interceptor | 2 | api | #32942 | #33089 8e3d4a54 2026-11-13 PASS |
PASS |
| api-backend.actions-namespace-address | 3 | api | #32946 | #33025 ee9ad834 2026-11-13 FAIL |
PASS |
| api-backend.error-sentences-and-unique-violation-wire-code | 9 | api | #33032 | #33081 8e3d4a54 2026-11-13 FAIL |
PASS |
| api-backend.package-rest-lifecycle | 6 | api | #33084 | #33081 8e3d4a54 2026-11-13 PASS |
PASS |
| api-backend.rest-metadata-config-contract | 10 | api | #33086, #33085 | #33081 8e3d4a54 2026-11-13 FAIL |
PASS |
| api-backend.second-object-exposure-and-internal-fields | 4 | api | #33086 | #33081 8e3d4a54 2026-11-13 FAIL |
PASS |
| approvals.ooo-delegation-reroute | 8 | mixed | #33062 | #33058 ee9ad834 2026-11-13 |
FAIL |
| approvals.record-page-decisions | 7 | browser | #33060 | #33093 c4196099 2026-11-13 FAIL |
PASS |
| attachments-storage.chunked-upload-integrity | 9 | api | #33027 | #33025 ee9ad834 2026-11-13 FAIL |
PASS |
| automation.package-flow-override | 4 | mixed | #33052 | #33048 ee9ad834 2026-11-13 |
PASS |
| cli.deploy-runtime-dry-run-json | 3 | cli | #32945 | #32940 5fb79bc0 2026-11-12 |
PASS |
| cli.validate-v18-authoring-verdicts | 3 | cli | #33086 | #33081 8e3d4a54 2026-11-13 FAIL |
PASS |
| platform-core.bare-name-one-holder-refusal | 5 | mixed | #33091, #33050, #33049 | #33089 8e3d4a54 2026-11-13 FAIL |
PASS |
| platform-core.docs-portal-render | 3 | browser | #33055 | #33048 ee9ad834 2026-11-13 |
PASS |
| platform-core.namespace-object-name-refusal | 3 | mixed | #32945 | #32940 5fb79bc0 2026-11-12 |
PASS |
| records-forms.field-unique-enforcement | 14 | api | #33032 | #33025 ee9ad834 2026-11-13 FAIL |
PASS |
| records-forms.home-amount-preview-states | 1 | browser | #32941 | #32940 5fb79bc0 2026-11-12 |
PASS |
| records-forms.multi-currency-invoice | 2 | mixed | #32941 | #33089 8e3d4a54 2026-11-13 FAIL |
PASS |
| records-forms.related-list-server-pagination | 12 | browser | #33051 | #33048 ee9ad834 2026-11-13 |
PASS |
| records-forms.saved-view-management | 2 | browser | #33098 | #33096 8e3d4a54 2026-11-13 FAIL |
PASS |
| studio-authoring.dataset-member-vocabulary | 2 | mixed | #32943 | #32940 5fb79bc0 2026-11-12 |
PASS |
| studio-authoring.expression-editors | 10 | mixed | #33100 | #33096 8e3d4a54 2026-11-13 |
PASS |
| studio-authoring.flow-status-matches-runtime | 7 | mixed | #33054 | #33048 ee9ad834 2026-11-13 |
PASS |
| studio-authoring.no-entry-property-matrix | 9 | mixed | #33101 | #33096 8e3d4a54 2026-11-13 |
PARTIAL |
Fix-card repros: every named fix card's own repro passes at 0c2aeb9 — #32941, #32942, #32943, #32944, #32945, #32946, #33027, #33028, #33029, #32163, #33030, #33032, #33049, #33050, #33051, #33052, #33054, #33055, #33060, #33062, #33082, #33084, #33085, #33086, #33091, #33098, #33100, #33101. (#32163 passes under its ruling E, "list and mark, do not hide": the member sees exactly the 15 membership-reach actions marked PERMISSION_DENIED. #33030: the stdio missing-id repro was driven; its RLS-hidden-id variant was not.)
Clauses that failed last time now pass:
ai.mcp-read-file-pdf-word-extractionacceptance[3] (FAIL at QA run · touched:5fb79bc0 (70/147) · ee9ad834 · 2026-11-13 · 56 PASS / 9 PARTIAL / 5 FAIL / 0 BLOCKED / 77 NOT-RUN #33025): at a 60 ms budget the long PDF answerstruncated:truewith "…(60 ms) after page 4 of 180".api-backend.actions-namespace-addressacceptance[0] (FAIL at QA run · touched:5fb79bc0 (70/147) · ee9ad834 · 2026-11-13 · 56 PASS / 9 PARTIAL / 5 FAIL / 0 BLOCKED / 77 NOT-RUN #33025): the bare call answers 409RESOURCE_CONFLICTnaming com.qa.addr-a and com.qa.addr-b and runs neither handler.api-backend.error-sentences-and-unique-violation-wire-codeacceptance[2] (FAIL at QA run · touched:ee9ad834 (82/174) · 8e3d4a54 · 2026-11-13 · 68 PASS / 8 PARTIAL / 6 FAIL / 0 BLOCKED / 92 NOT-RUN #33081): live 409 with details exactly{developerMessage, field:"email", object}.api-backend.rest-metadata-config-contractacceptance[2] (FAIL at QA run · touched:ee9ad834 (82/174) · 8e3d4a54 · 2026-11-13 · 68 PASS / 8 PARTIAL / 6 FAIL / 0 BLOCKED / 92 NOT-RUN #33081): the mount-table pin measures 4 and 14 routes, matching the re-worded clause.api-backend.second-object-exposure-and-internal-fieldsacceptance[0] (FAIL at QA run · touched:ee9ad834 (82/174) · 8e3d4a54 · 2026-11-13 · 68 PASS / 8 PARTIAL / 6 FAIL / 0 BLOCKED / 92 NOT-RUN #33081): the re-pointed pin file exists and passes (50 tests).records-forms.field-unique-enforcementacceptance[0] (FAIL at QA run · touched:5fb79bc0 (70/147) · ee9ad834 · 2026-11-13 · 56 PASS / 9 PARTIAL / 5 FAIL / 0 BLOCKED / 77 NOT-RUN #33025): live 409 names the field by label ('SKU' / 'Global SKU') withfieldsku / gsku.cli.validate-v18-authoring-verdictsacceptance[1] (FAIL at QA run · touched:ee9ad834 (82/174) · 8e3d4a54 · 2026-11-13 · 68 PASS / 8 PARTIAL / 6 FAIL / 0 BLOCKED / 92 NOT-RUN #33081): the controlled_by_parent arm as re-worded at rev 3 — no master_detail, or two required ones (inline or via objectExtensions), refused byos validateandos build; the optional master is a passing control; new acceptance[3]:os lintexits 1 with relationship/master-detail-required while validate and build exit 0.platform-core.bare-name-one-holder-refusalacceptance[0] and [3] (FAIL at QA run · #32940 round-1 FAIL items (11/11) · 8e3d4a54 · 2026-11-13 · 8 PASS / 0 PARTIAL / 3 FAIL / 0 BLOCKED / 0 NOT-RUN #33089): driven onconnector(the only covered type left outside the namespace-scoped list); the second install answers 422 naming both packages and a rename; the cold boot logs exactly one "Bare-name conflict at boot" warning.records-forms.multi-currency-invoiceacceptance[5] (FAIL at QA run · #32940 round-1 FAIL items (11/11) · 8e3d4a54 · 2026-11-13 · 8 PASS / 0 PARTIAL / 3 FAIL / 0 BLOCKED / 0 NOT-RUN #33089): the edit form'shome-amount-previewmounts in stateconvertedand re-reads on a date change (0.92) and a currency change to JPY (151.5); nothing saved.approvals.record-page-decisionsacceptance[4] (FAIL at QA run · touched:8e3d4a54 (25/52) · c4196099 · 2026-11-13 · 22 PASS / 1 PARTIAL / 2 FAIL / 0 BLOCKED / 27 NOT-RUN #33093): a forged approve by the contributor member answers 404REQUEST_NOT_FOUNDas rev 7 states, twice, the request still pending.records-forms.saved-view-managementacceptance[1] (set-default half) and negative[2] (FAIL at QA run · touched:ee9ad834 (59/174) · 8e3d4a54 · 2026-11-13 · 51 PASS / 4 PARTIAL / 4 FAIL / 0 BLOCKED / 115 NOT-RUN #33096): clearing the shipped All Tasks default goes through ensure-customization thenPUT …?package=com.example.showcase.custom(200); after reload exactly one default.attachments-storage.chunked-upload-integrity: QA run · touched:5fb79bc0 (70/147) · ee9ad834 · 2026-11-13 · 56 PASS / 9 PARTIAL / 5 FAIL / 0 BLOCKED / 77 NOT-RUN #33025 shows this item PASS; it passes again (acceptance[3] org-switch leg scored from the HTTP wall pin — a stock single boot holds one organization).
Per-clause verdict tables
Every acceptance and negative clause of all 30 items has a verdict with one line of text oracle evidence, the layer each pin reaches, and the fix-card repro line. They follow as three comments (body limit):
- Comment 1 (
record-OWED-clauses-1.md): group D — the 14 api items. - Comment 2 (
record-OWED-clauses-2.md): group E — the 2 cli and 9 mixed items. - Comment 3 (
record-OWED-clauses-3.md): group F — the 5 browser items.
Tier 1: D 13 package batches / 55 pin files, E 13 batches / 47 files, F pins for home-amount-preview (18/18, unit) and related-list (7/7, HTTP) — all green, --maxWorkers=1, 0 failed.
Failures
approvals.ooo-delegation-reroute · off-clause probe · security finding — detail withheld, reported to PM
No other fail; every clause of the 30 items passes.
Derived item verdicts and gaps
- 28 PASS, 1 PARTIAL, 1 FAIL (the withheld row above; every clause of
approvals.ooo-delegation-rerouteand its fix card Approval delegations accept an inverted window (valid_until before valid_from) and a self-delegation, both 201 and silently inert #33062 repro pass):studio-authoring.no-entry-property-matrix(rev 9) — PARTIAL: the Publish accepts an activityMilestones[].field or displayNameField that names no field; both are served and do nothing #33101 repro passes (displayNameField, nameField and activityMilestones[].field naming no field are refused at publish,INVALID_METADATA), and the 11 of 37 matrix rows driven (listed in clause comment 2) all show their declared effect; rows 3–5, 8–11, 14–21, 23–25, 28–36 were not reached this round and the matrix split owed by its knownGaps[3] is still owed.
- Fixture gaps:
records-forms.home-amount-preview-statessteps[2]: the member's invoice from the fixture recipe has no currency and no lines, so no preview can mount; the runner added currency USD and one line (100) as the member.cli.deploy-runtime-dry-run-json: anos deployto a showcase booted in the shared tree writes the runtime's install cache into the sharedexamples/app-showcase/.objectstack/installed-packages/; the runner moved it out after each install. Next round its target runtime should boot from a scratch copy.
Off-clause probes (RUNNER rule 8)
About 130 minutes in total across the 30 items (2–6 min each), on the same boots and personas: opposite credential (session vs osk_ key) on MCP doors; unknown / missing ids on marked actions, chunk sessions and approval requests; limit 0 / -1 / 1000 on dataset queries; retries on a completed chunked upload; restarts on the same file DB after package install, override and uninstall; uninstall followed by the bare action call; deploy dry run with the install-ledger file absent; delegation windows (equal bounds, inverted, self, open-ended, update path); rate effective-date boundaries; synonyms length/count limits; forged meta writes and forged contact slices as non-admins; unknown doc fragments. Findings that pass the filing gate — three low product defects, card drafts attached:
api-backend.package-rest-lifecycle— a package'sinstalledAtandupdatedAtread as the boot time after every restart (card draftcard-OWED-1.md).api-backend.actions-namespace-address— after an install-local uninstall the withdrawn package's action handler stays registered, so a bare/actionscall still refuses as ambiguous until restart (card draftcard-OWED-2.md).cli.deploy-runtime-dry-run-json—os deploy --dry-runreads the install-ledger file while the install gate reads the DB; with the file gone and the DB kept, the dry run plans clean and the install refuses 409 (card draftcard-OWED-3.md).
Not filed (observations / questions):
_activation/position/platform_admin {enabled:false}answers 200 and writes a ledger row but changes nothing (platform_admin is derived from admin_full_access).- Wording only: MCP
query_datasetrefusal says "body.selection.measures"; a completed chunked upload's retry with a different eTag says "the upload stays open"; the interceptor context omitsregisteredfor registered calls; deleting the current default view leaves the object with no default list view.
Checklist-accuracy notes (for the wave anchor, not extracted)
access-security.permission-set-address-in-execution-contextsteps[3]: the package-less row does not survive the restart it needs — the cold-boot activation-ledger backfill (ADR-0150 D8 R4) binds it to the name's one holder, so acceptance[3] measures the rebound row (answers still match).cli.validate-v18-authoring-verdictssteps[2] should namedefineStack(x, { strict: false }); inside a strict defineStackos lintnever sees the omittedrequired.studio-authoring.expression-editorssteps[1]:record.quantity * record.unit_priceinfers Unknown in both engine and editor, so it is not a proven-Number example.automation.package-flow-override: at 1500 px the override chip sits in the header itself, not folded into More.records-forms.home-amount-preview-statesacceptance[2].verify quotes "2024-06-01"; the page shows the user's format "Jun 1, 2024".records-forms.related-list-server-paginationsteps[1] says the wide layout has no tab strip; at 1440×900 the page draws one (clauses unaffected).platform-core.docs-portal-rendersteps[3]: a package with a single book skips its docs index and opens the book directly, by design.
Close-out lines (for the seat, after filing)
Extracted: #CARD1 · api-backend.package-rest-lifecycle · observed beside the clauses
Extracted: #CARD2 · api-backend.actions-namespace-address · observed beside the clauses
Extracted: #CARD3 · cli.deploy-runtime-dry-run-json · observed beside the clauses
Parked-on: #ANCHOR · studio-authoring.no-entry-property-matrix · rows 3–5, 8–11, 14–21, 23–25, 28–36 not driven; matrix split (knownGaps[3])
Activity
objectstack-fleet commentedon Nov 14, 2026
qa#3 · os-tesla · session_01L9qibzj9DrVWXkq7joYHGB
QA run · owed:weekly clause tables (1/3) · 0c2aeb9 · runner group D (api 14)
ai.mcp-run-action-exposure-gate · rev 7 · PASS · api · OWED: fix #33029, #32163
env: showcase @0c2aeb96, port 41162, db file:/tmp/qa3/D/mcp-runaction.db, --seed-admin --no-compile --no-watch. MCP HTTP /api/v1/mcp; admin osk_ key, admin session token, phone.demo osk_ key + session token. Staged qa_ai_gated (requiredPermissions manage_metadata), torn down (DELETE 200). No pin (Tier 2 only).
ai: { exposed: true, description: … }"}; REST re-read status in_progress, progress 55, updated_at unchanged 22:31:40.666ZobjectName"ai: { exposed: true, description: … }on it"; total 2 after; create_api_key absent from list; revoke_api_key listed {aiExposed:true,requiresConfirmation:true}; run via admin session token {confirm:true} → ok:true; GET sys_api_key/UDIlC3p_1UEZYfaK revoked:trueai.mcp-read-file-pdf-word-extraction · rev 2 · PASS · api · OWED: fix #33032, #32945
env: showcase @0c2aeb96, port 41163, db file:/tmp/qa3/D/mcp-readfile.db, --seed-admin --no-compile --no-watch; boot 1 default budget, boot 2 same DB with OS_MCP_READ_FILE_CPU_BUDGET_MS=60, boot 3 OS_MCP_READ_FILE_CPU_BUDGET_MS=abc (own DB). Fixtures generated locally (reportlab/python-docx): two.pdf (2 text pages), doc.docx (3 paragraphs), long.pdf (180 text pages, 156 KB), uploaded via POST /storage/upload/chunked → PUT chunk/0 → complete, then PATCH showcase_invoice_line/‹id› {receipt: fileId} (lines 4ixZkRqRpnhkb2jV, 9d6RRBS7dMu11BCg, AzZg4QCncMH6qRbu). MCP HTTP with admin osk_ key.
Tier 1: @objectstack/mcp mcp-file-tools.test.ts 47✓, 0 failed at 0c2aeb9 (plugin unit).
testai.mcp-dataset-tools · rev 1 · PASS · api · OWED: fix #33028, #32944
env: showcase @0c2aeb96, port 41161, db file:/tmp/qa3/D/mcp-dataset.db, --seed-admin --no-compile --no-watch; MCP HTTP /api/v1/mcp with admin osk_ key; member persona phone.demo osk_ key for probes.
Tier 1: @objectstack/service-analytics tests/dataset-tools.test.ts 32✓ (1 file, 0 failed; unit), @objectstack/mcp mcp-dataset-tools.test.ts 21✓ (plugin unit), @objectstack/runtime mcp-dataset-tools-bridge.test.ts 6✓ (unit) — at 0c2aeb9.
query_dataset… Several matches (two datasets or two members answer to the word): ask the user…"sqlkeydatasetkey → -32602 "Unrecognized key(s)…dataset. Did you meandataset→datasetName?"; top-level measures → -32602 "Selection members go insideselection, not beside it…"sqlkey in any query_dataset answer (default, limit 1, limit 2)ai.mcp-coded-refusals-and-runtime-exposure · rev 5 · PASS · api · OWED: fix #33030
env: showcase @0c2aeb96, port 41160, db file:/tmp/qa3/D/mcp-coded.db, --seed-admin --no-compile --no-watch; restarted once on the same file DB. MCP HTTP /api/v1/mcp, admin osk_ key (POST /api/v1/keys), auditor.demo osk_ key.
idarg → -32602 "Did you meanid→recordId?"os startOS_MCP_STDIO_ENABLED=true + admin osk_ key, port 41164): tools/call get_record {showcase_task, qa_missing_id_123} → isError {error:{code:"RECORD_NOT_FOUND",message:"Record qa_missing_id_123 not found in showcase_task",status:404}} (was uncoded text); update_record same id → same coded RECORD_NOT_FOUND. The RLS-hidden-id-under-member-key variant was not driven.ai.mcp-tool-call-interceptor · rev 2 · PASS · api · OWED: fix #32942
env: scratch copy /tmp/qa3/D/ws/examples/app-icpt (showcase @0c2aeb96 + the fixture's inline qa-mcp-interceptor plugin,
as any), port 41164, db file:/tmp/qa3/D/icpt.db. HTTP legs onos dev --seed-admin --no-watch(scratch compile); stdio leg onos start(same DB) with OS_MCP_STDIO_ENABLED=true + OS_MCP_STDIO_API_KEY=admin osk_, calls sent after /api/v1/health 200, both pipes captured in full.Tier 1: @objectstack/mcp tool-call-interceptor.test.ts 49✓, tests/plugin-execution-context.test.ts 9✓ (0 failed at 0c2aeb9; plugin unit).
[qa-interceptor] {"door":"mcp","transport":"http","toolName":"list_objects","userId":"5c9STJ04jzkjcHpBXqsi3PauIQmeLVKS"}= admin key owner[qa-interceptor] {…"toolName":"qa_no_such_tool","registered":false…}; client gets "MCP error -32602: Tool qa_no_such_tool not found"[qa-interceptor] {"door":"mcp","transport":"stdio","toolName":"list_objects","userId":"5c9STJ04…"}test)os startstdio: one[qa-interceptor] … "transport":"stdio"line per call on STDERR (list_objects, get_record, update_record); stdout carried only the JSON-RPC answers (ids 1–4, no stray lines).registered(only the unregistered call carries registered:false) — not a clause, not filed.access-security.security-catalog-activation-and-clone-doors · rev 5 · PASS · api · OWED: fix #33082
env: showcase @0c2aeb96, port 41165, db file:/tmp/qa3/D/catalog-act.db, --seed-admin --no-compile --no-watch, OS_PLATFORM_OWNER_EMAIL unset. Member = auditor.demo (sys_user_position showcase_auditor). SET = showcase_auditor (holder com.example.showcase).
Tier 1 (vitest --maxWorkers=1 at 0c2aeb9): @objectstack/qa-dogfood catalog-activation-door.dogfood 10✓, permission-set-clone-door.dogfood 11✓ (HTTP, in-process booted showcase); @objectstack/runtime catalog-activation-door 91✓, permission-set-clone 53✓, permission-set-package-doors 40✓ (domain handler over fakes); 0 failed.
extra"; bad name → 400; unknown source → 404; member → 403 PERMISSION_DENIED "…requires themanage_metadatacapability"; anonymous → 401 UNAUTHENTICATED; none of qa_clone_2..6 savedapi-backend.package-rest-lifecycle · rev 6 · PASS · api · OWED: fix #33084
env: showcase @0c2aeb96, port 41166, db file:/tmp/qa3/D/pkg-life.db, --seed-admin --no-compile --no-watch; restarted twice on the same file DB. Admin session. No pin (Tier 2). Tree install ledger examples/app-showcase/.objectstack/installed-packages/ absent before and after (POST /packages is not install-local).
installedAtandupdatedAtare re-stamped to the boot time on each restart (probe package: 22:38:41.421Z pre-restart → 22:39:02.508Z after restart 1 → 22:39:27.809Z after restart 2; com.example.showcase likewise), though acceptance[2]/negative[1] treat installedAt as a lifecycle field a PATCH must preserve. Reproduced on two restarts. No open issue found ("installedAt restart", "installedAt package registry").attachments-storage.chunked-upload-integrity · rev 9 · PASS · api · OWED: fix #33027
env: showcase @0c2aeb96, port 41167, db file:/tmp/qa3/D/chunked.db, --seed-admin --no-compile --no-watch, local storage adapter; admin session. (The door's chunkSize floor is 5242880, so the 3-chunk fixture is 5 MiB + 5 MiB + 10 B.) Note: prior record #33025 lists this item PASS 4/0/0/0; items-D's "FAIL" refers to the record overall.
Tier 1 (0c2aeb9, --maxWorkers=1): @objectstack/service-storage chunked-upload-integrity 23✓, chunk-part-record-concurrency 24✓ (unit); @objectstack/qa-dogfood storage-chunked-resume-integrity.dogfood 4✓ (HTTP, in-process); @objectstack/organizations storage-upload-organization-change.wall 10✓ (HTTP in-process on a booted organization wall); 0 failed.
completed(neverfailed); PUT chunk/0 to the completed session → 409 RESOURCE_CONFLICT "This chunked upload has already completed and its file is committed, so it takes no more chunks…"; file URL 200.completed.records-forms.field-unique-enforcement · rev 14 · PASS · api · OWED: fix #33032
env: showcase @0c2aeb96, port 41168, db file:/tmp/qa3/D/uniq.db (stock SQLite), --seed-admin --no-compile --no-watch; admin session. Fixture: POST /packages {com.objectstack.qa.unique, namespace qauniq, enableOnInstall} 201; PUT /meta/object/qauniq_item?package=… (sku unique:true label 'SKU', gsku unique:'global' label 'Global SKU', nick) 200.
Tier 1 (0c2aeb9): @objectstack/qa-dogfood field-unique-rest-refusal.dogfood 5✓ (HTTP, booted stack on SQLite); @objectstack/driver-memory memory-unique-constraint 27✓ (driver); @objectstack/driver-sql sql-driver-8577-tenant-scoped-declared-unique 39✓, sql-driver-declared-index-organization-respelling 26✓ (SqlDriver); 0 failed.
fieldmatch the re-pointed acceptance[0] exactly (SKU label inerrorand developerMessage, API key onfield).api-backend.rest-metadata-config-contract · rev 10 · PASS · api · OWED: fix #33086, #33085
env: showcase @0c2aeb96, port 41169, db file:/tmp/qa3/D/restmeta.db, --seed-admin --no-compile --no-watch; OS_ALLOW_UNMASKED_OBJECT_METADATA unset (env and boot log). Restricted persona: qa.liaison@example.com via POST /auth/admin/create-user + change-password, bound with POST /data/sys_user_position {position: showcase_client_liaison} 201 (me/permissions positions org_member, showcase_client_liaison, everyone). Non-default clauses scored with oracle
test(knownGaps ruling #15543).Tier 1 (0c2aeb9): @objectstack/rest rest-sub-config-parse-not-cast 25✓, discovery-services-route-follows-mount 10✓, meta-object-fls 147✓, rest-config-mount-table.pin 24✓ (route-handler / mount-table harness); @objectstack/qa-dogfood rest-config-contract-live.dogfood 7✓ (HTTP, booted showcase), rest-config-contract-harness 7✓ (real RestServer); 0 failed.
endpoints.itemdescribe() now names "the package-qualified by-name readGET /meta/:type/:ns/:name(ADR-0150 D5)" beside the 13; the pin measures 14.api-backend.second-object-exposure-and-internal-fields · rev 4 · PASS · api · OWED: fix #33086
env: showcase @0c2aeb96, port 41170, db file:/tmp/qa3/D/secobj.db, --seed-admin --no-compile --no-watch. Live fixture authored at runtime (no shared-file edit): qa_sox_target (enable.apiEnabled:false), qa_sox_getonly (enable.apiMethods:['get']), qa_sox_source (lookups t_ref→target, g_ref→getonly, internal_f internal:true). Personas: admin and qa.member (admin create-user + change-password).
Tier 1 (0c2aeb9): @objectstack/metadata-protocol protocol.relation-condition-target-exposure 13✓, protocol.expand-target-exposure 15✓, protocol.data-door-internal-field-delegation 6✓; @objectstack/objectql protocol-data-door-internal-field-positions 50✓, internal-field-positions 6✓ (protocol/engine); @objectstack/qa-dogfood second-object-exposure.dogfood 48✓, internal-field-data-door-positions.dogfood 15✓ (HTTP on a booted fixture app); 0 failed.
internal: true… refused rather than evaluated"; sys_api_key ?filter key → 400 INVALID_FIELD field key; no 500api-backend.error-sentences-and-unique-violation-wire-code · rev 9 · PASS · api · OWED: fix #33032
env: Tier 1 at 0c2aeb9 (--maxWorkers=1) + one live leg on showcase port 41171, db file:/tmp/qa3/D/errsent.db, --seed-admin --no-compile --no-watch (runtime-authored qa_es_contact with email unique:true and a declarative update action qa_es_dup; no shared file edited).
Tier 1: @objectstack/rest rest-write-route-hook-refusal-sentence.ledger 673✓, rest-hook-script-fault-envelope 18✓ (unit); @objectstack/runtime dispatcher-unique-violation-wire-code 7✓ (engine: HttpDispatcher over ObjectQL + SqlDriver); @objectstack/service-storage storage-routes.server-fault-withheld 18✓ (unit); @objectstack/qa-dogfood error-sentences-live.dogfood 4✓ (HTTP via @objectstack/verify bootStack on the scratch fixture app); 0 failed.
field= the duplicated column; live and pin both answer details {developerMessage, field:"email", object}.api-backend.actions-namespace-address · rev 3 · PASS · api · OWED: fix #32946
env: showcase @0c2aeb96, port 41172, db file:/tmp/qa3/D/actions-ns.db, --seed-admin --no-compile --no-watch, OS_HOME=/tmp/qa3/D/home-act (install ledger stayed there; tree ledger examples/app-showcase/.objectstack/installed-packages absent). Scratch packages /tmp/qa3/D/ws/examples/qa-a (com.qa.addr-a, ns qa_a: object qa_a_ticket with embedded script action escalate, object-less qa_a_ping, permission set qa_a_reader) and qa-b (com.qa.addr-b, ns qa_b: object qa_b_note, standalone script action escalate objectName qa_a_ticket; defineStack {strict:false} since qa_a_ticket is another package's), each
objectstack buildthenos package install DIR/dist/objectstack.json(admin). Handlers return {ran: ‹package id›}. RID 3EnXZFk2VRRCIwHd; env action qa_env_ping PUT /meta/action without ?package= 200.Tier 1 (0c2aeb9): @objectstack/runtime domains/actions-addressed-route 47✓, action-package-addressing 118✓, action-execution-addressed-exposure-refusal 16✓ (domain/runtime unit); 0 failed. All clauses also driven live.
os package installtwo scratch packages — com.qa.addr-a (object qa_a_ticket, embedded script action escalate) and com.qa.addr-b (standalone script action escalate, objectName qa_a_ticket); create one qa_a_ticket RID. 1) POST /api/v1/actions/qa_a_ticket/escalate/RID → 409 naming both packages (correct). 2) DELETE /api/v1/marketplace/install-local/com.qa.addr-b → 200, note "Cached manifest removed, the package withdrawn from the running kernel, …"; GET /api/v1/packages/com.qa.addr-b → 404. 3) Repeat step 1 → 409 RESOURCE_CONFLICT "Action handler 'qa_a_ticket:escalate' is ambiguous for a call that names no package: 2 owners register one ('app:com.qa.addr-a', 'app:com.qa.addr-b')…". Expected: one holder left, so 200 with com.qa.addr-a's result — which is what the same call answers after a restart. Mechanism (not proven): the uninstall withdraws the registry entry and metadata but not the handler registered under owner 'app:com.qa.addr-b' (the bare-call ambiguity check in packages/runtime/src/action-execution.ts reads the handler registry). QA-source: #RECORD · api-backend.actions-namespace-address · observed beside the clausesaccess-security.permission-set-address-in-execution-context · rev 3 · PASS · api · OWED: fix #32945
env: showcase @0c2aeb96, port 41173, db file:/tmp/qa3/D/psa.db, --seed-admin --no-compile --no-watch, OS_HOME=/tmp/qa3/D/home-psa (ledger stayed there); the same scratch packages as actions-namespace-address (com.qa.addr-a: qa_a_ticket + qa_a_reader read-only on it; com.qa.addr-b: no permission set) installed with
os package install. M = qa.m@example.com (admin create-user + change-password), granted via POST /data/sys_user_permission_set {user_id:M, permission_set:'qa_a_reader'} 201; one qa_a_ticket. Server stopped/restarted 4 times on the same file DB; ledger edits with better-sqlite3 while stopped.Tier 1 (0c2aeb9): @objectstack/plugin-security permission-set-address.test.ts 24✓ incl. "a holder of a grant the user does not hold switches nothing off for the one they do" ✓; @objectstack/core security/request-execution-context.test.ts 21✓; 0 failed (unit).
permissionSetAddresses: agent ? undefined : authz.permissionSetAddresses, with the comment "An agent principal'spermissionsare its scope-derived ceiling names, which carry no address and resolve by D3 with no caller" — OAuth agent arm carries none; the account arm carries authz.permissionSetAddresses. No pin tells the arms apart (FOLLOW-UPS §16b)fix-card qa(checklist): five assertion defects from the 18.4.0 acceptance (#32940): permission-set address, read_file budget, deploy confirm, two namespace refusals #32945 repro (item 1): pass — the stale-column row (package holding no set of the name) now reads as the D3 holder's switch per the re-pointed clause: M loses qa_a_reader, exactly as the card measured; the two-holder case is scored from the pin.
probe: 3 min · doors explain / me-permissions / data across restarts · classes: the row read back over GET /data/sys_metadata_activation after the NULL edit · findings: none
notes: checklist-accuracy — steps[3]'s package-less row does not survive the restart it needs: the cold-boot backfill (packages/objectql/src/activation-ledger-backfill.ts, ADR-0150 D8 R4) binds a package-less row to the name's one holder, so the DB row read com.qa.addr-a again after boot and acceptance[3] measures the backfilled row, not readDisabledCatalogNames' package-less arm. The answers still match the clause; a package-less live read would need a name two packages hold (not installable, knownGaps).
group notes: Tier 1 ran 13 vitest batches by package with
npx vitest run FILES --maxWorkers=1from each package dir (brief's rule; item text says --maxWorkers=2 via pnpm --filter), 22:28–22:33Z, all 55 pin files green, 0 failed. Every boot used --no-compile --no-watch in the shared tree except the interceptor scratch copy (own compile under /tmp/qa3/D/ws). Install-local items used their own OS_HOME; the tree ledger examples/app-showcase/.objectstack/installed-packages stayed absent throughout. No GitHub writes. No security finding.objectstack-fleet commentedon Nov 14, 2026
qa#3 · os-tesla · session_01L9qibzj9DrVWXkq7joYHGB
QA run · owed:weekly clause tables (3/3) · 0c2aeb9 · runner group F (browser 5)
approvals.record-page-decisions · rev 7 · PASS · browser · OWED: fix #33060
env: showcase boot :41190,
-d file:/tmp/qa3/F/approvals.db --seed-admin --no-compile, console dist 22:08Z (this tree). Projects created planned (budget 50000, spent 1000) then PATCHed: A/B/D → 200000, C → 600000. Member =qa-fixture.mjs contributor-member. Noautomated.ref(Tier 2 by hand).‹header›; no Send reminder/Resubmit; header has only Edit + overflow. First load: POST /api/v1/data/showcase_project/A/page 200 (no GET ?object&recordId until refresh); own GET → row pending manager_review viewer {can_act:true,is_submitter:true,can_override:true}{"data":[]}, page rendered (h1 "QA-F appr C"), 0 declared-action-*; forged POST /api/v1/approvals/requests/areq_497a…/approve ×2 → 404 {"code":"REQUEST_NOT_FOUND"}; admin re-read pending. Admin off-slate (D reassigned via bar picker to usr_showcase_auditor_demo, POST …/approval_reassign 200): row viewer {can_act:false,is_submitter:true,can_override:true}; status line "Pending · Waiting on Ada Auditor (demo)"; inline only Reply; declared-actions-override-menu aria-label "Admin override" → menuitems Override Approve/Override Reject/Override Reassign (data-override-decision=true) + Recall (plain); no Send back/Request infoplatform-core.docs-portal-render · rev 3 · PASS · browser · OWED: fix #33055
env: showcase boot :41191,
-d file:/tmp/qa3/F/docs.db --seed-admin --no-compile; console dist 22:08Z carries the fix (DocsSlug chunkNavigate to={pathname…,hash}present). Member = invite (role member) + invited sign-up, no position (member_default). Noautomated.ref(Tier 2 by hand).records-forms.home-amount-preview-states · rev 1 · PASS · browser · OWED: fix #32941
env: showcase boot :41192,
-d file:/tmp/qa3/F/homeamt.db --seed-admin --no-compile; console dist 22:08Z carries the fix (ui-components chunk: read-only CurrencyField branch mounts the preview when!disabled && currencyMode==='record' && homeAmount). Member =qa-fixture.mjs contributor-member(own invoice 2vxVLFm1nUCyRv1q). Rates (admin GET /data/sys_exchange_rate): EUR 0.92@2025-01-01, 0.9@2026-10-15; JPY 151.5@2025-01-01, 149.25@2026-10-15; home USD.Tier 1 pin (unit, objectui component layer — render over a stub data source, no HTTP):
ui/vitest run packages/fields/src/__tests__/homeAmountPreview-27196.test.tsx packages/plugin-form/src/__tests__/sectionFormHomeAmount-27196.test.tsx --maxWorkers=1→ 2 files, 18 tests passed. Below the dom oracle on the served bundle, so every clause was also driven live.[data-testid=home-amount-preview]count 1, data-state=converted "≈ $500.00 at 0.9 on Nov 14, 2026" (card's actual was 0, plain €450.00); Currency→JPY + Invoice Date 01/15/2026: still mounted, converted "≈ $2.97 at 151.5 on Jan 15, 2026" (450÷151.5). 2/2 fresh loads.amount(expression → null without a currency) is drawn as an EmptyValue and no preview can mount; I gave it currency USD (member PATCH 200) and one line (member POST showcase_invoice_line 2×50 → 201) so amount=100 before driving step 3. checklist-accuracy: steps[2]/provisioning should say the member's invoice needs a currency and a line. (2) acceptance[2].verify quotes "on or before 2024-06-01"; the served line formats the date for the locale ("Jun 1, 2024") — the clause's substance holds; the verify literal could name the formatted date.records-forms.related-list-server-pagination · rev 12 · PASS · browser · OWED: fix #33051
env: showcase boot :41193,
-d file:/tmp/qa3/F/related.db --seed-admin --no-compile, 1440×900. Northwind = PtaK1MoDuE2R1uNW. Personas:qa-fixture.mjs contributor-member(showcase_contributor) and… --position showcase_manager(contributor + manager; the child-read-entitled persona).Tier 1 pins (HTTP layer —
@objectstack/verifybootStack: full REST stack through Hono request injection, no port):packages/qa/dogfoodvitest run test/related-list-server-paging-and-gate.dogfood.test.ts test/record-page-related-slices-concurrent-read-scope.dogfood.test.ts --maxWorkers=1→ 2 files, 7 tests passed (A1/N1, A4, A5/N2; #33051 controls + order-independence).topon the detail page or the enlarged listrecord-page-related-slices-concurrent-read-scope.dogfood.test.ts4/4 at HTTP.records-forms.saved-view-management · rev 2 · PASS · browser · OWED: fix #33098
env: showcase boot :41194,
-d file:/tmp/qa3/F/savedview.db --seed-admin --no-compile; console dist 22:08Z carries the fix (index chunk: handleSetDefaultViewfor (let n of …) await Promise.all(…[n]); data-adapter chunk: updateView → ensureCustomization / "records no version"). Non-admin = invite (member) + invited sign-up (member_default, no position). Noautomated.ref(Tier 2 by hand).manage_metadatacapability."; PUT over existing qa_x → 403; PUT ?mode=draft → 403; DELETE qa_x → 403 "Resetting a metadata item requires…"; admin re-read: forged view 404 (published and draft), qa_x unchanged?package=com.example.showcase.custom, 200), one default remains.objectstack-fleet commentedon Nov 14, 2026
qa#3 · os-tesla · session_01L9qibzj9DrVWXkq7joYHGB
QA run · owed:weekly clause tables (2/3) · 0c2aeb9 · runner group E (cli+mixed 11)
cli.deploy-runtime-dry-run-json · rev 3 · PASS · cli · OWED: fix #32945
os deploy --dry-run@1.0.0 exit 0, plan "Objects + qa_deploy_item", "Nothing in this plan asks for a confirmation:os deployinstalls it as it is.", "✓ Dry run: nothing was installed into http://localhost:41175"; GET /api/v1/packages → 0 × "com.qa.deploy"--dry-run --jsonexit 0; stdout JSON.parse OK, keys url,result,package,plan,environment,wouldStop,refusal,confirm,error,target = {target:"runtime",url:"http://localhost:41175",result:"planned",package:{manifestId:"com.qa.deploy",version:"1.0.0",installedVersion:null},wouldStop:[],refusal:null,confirm:null,error:null}; the 36 human lines all on stderros deploy</dev/null exit 0, "✓ Live: http://localhost:41175 now serves com.qa.deploy 1.0.0."; packages lists com.qa.deploy ×1; GET /api/v1/data/qa_deploy_item → 200 {records:[],total:0}; 2 POSTs with note → 201-shaped recordsrenamedFromlinks them…";deploy --json</dev/null exit 1, result "refused", refusal 409 SCHEMA_UPGRADE_CONFIRMATION_REQUIRED (verbatim message, 2 rows), confirm "os deploy --confirm-upgrade schema-upgrade:9996319b…"; no question on stderr (0 prompt lines)‹app›/.objectstack/installed-packages/com.qa.deploy.jsonabsent, the v1.1.0 dry run read "Version: 1.1.0 (not installed)", "Objects + qa_deploy_item", "Nothing in this plan asks for a confirmation" (exit 0), while the realdeploy --jsonagainst the same runtime refused 409 for the rename (installedVersion "1.0.0" from the DB). The dry run reads the on-disk ledger (cloud-connection marketplace-install-local-plugin.ts answerUpgradeDryRun → this.ledger.read), the install gate reads the DB. Arose because I moved the cache file out of the shared tree (see notes); a host whose DB persists but whose.objectstack/does not would see the same mismatch. Re-run with the file restored: plan correct.os deployto a showcase booted in the SHARED tree writes the runtime's install cache into /home/user/objectstack/examples/app-showcase/.objectstack/installed-packages/com.qa.deploy.json ("re-registers on every boot"), which would leak com.qa.deploy into every other runner's showcase boot. I moved it out after each install and removed the (empty, newly created) installed-packages dir; next round the item's fixture should boot the target runtime from a scratch copy. HOME isolated to /tmp/qa3/E/home for use-runtime + deploy (rev 3 fixture). Port 41175, db /tmp/qa3/E/deploy.db.cli.validate-v18-authoring-verdicts · rev 3 · PASS · cli · OWED: fix #33086 (item 3)
typo", build exit 1 "Author-time rules failed" · previous["typo"] → same rule/path, build 1 · two datasources alike → exit 1 "Datasource 'showcase_external' is declared twice indatasources: stack.datasources[0] and stack.datasources[1]", build 2 · cbp no master_detail → exit 1 at objects.24.sharingModel, build 2 · cbp two required inline → exit 1 at objects.24.fields "2 requiredmaster_detailfields (header,other)", build 2 · second required master via objectExtensions → exit 1 at objectExtensions.1.fields, build 2 · object-grid defaultFilters → exit 1 component-props-invalid (error) at pages[19].regions[1].components[2].properties.defaultFilters, build 1 · email {apiKey:'x'} → exit 1 "email: Unrecognized key(s) on the stackemailblock:apiKey" (prescribes OS_EMAIL_API_KEY), build 2; no arm printed "Validation passed"record.name == "record.typo"0/0 · email {provider:'smtp'} 0/0 · cbp whose only master_detail is required:false 0/0defineStack({...}, { strict: false }), cbp child whose only master_detail omits required):os lintexit 1 "✗ master_detail "qarl_child.header" → qarl_parent declares no required: write true … or false (an optional master)" relationship/master-detail-required at objects[1].fields.header.required;os validate --jsonexit 0 valid:true;os buildexit 0defineStack→ lint 0 / validate 0 / build 0 (the parse writes required:false before lint sees it, as spec/data/controlled-by-parent-master.ts documents); bare object export → lint 1 (same finding) but validate/build exit 1/2 "the default export was not built bydefineStack"; only{ strict: false }gives the clause's three exits.os lintunparsed: inside the showcase's (strict) defineStack config the lint finding never appears (lint exit 0), and a bare export is refused by validate/build. NamedefineStack(x, { strict: false })in steps[2]. Also: arm record["typo"] here replaced the project rule's null guards, so validate reported a second expression-invalid (null<) beside the typo finding — fixture artifact of the edit, not a verdict. HOME/OS_HOME=/tmp/qa3/E/home.platform-core.bare-name-one-holder-refusal · rev 5 · PASS · mixed (api+log) · OWED: fix #33091, #33050, #33049
os package installqa_a → exit 0 installed; qa_b → exit 1 "Install failed (422 PLUGIN_REGISTER_FAILED): … package "com.qa.addr-b" declares the connector "qa_conn", already held by package "com.qa.addr-a" — rename it to "qa_b_qa_conn" …"; GET /api/v1/packages lists com.qa.addr-a ×1, com.qa.addr-b ×0webhookat rev 3) now PASS withconnectorat rev 5.webhooktotool: webhooks are held per namespace since #32577 #33091 repro: pass — webhook qa_hook in two namespaces installs both (409 on the bare read, consistent with feat(plugin-webhooks)!: declared webhooks are held per namespace, each holder dispatched and switched as its own (ADR-0150 child B, webhook family 2/3) #32577); the re-pointed type (connector, the only type left outside the namespace list since tool joined it in feat(objectql, core, metadata)!: tool names held per namespace, and the metadata service keeps each package's tool in its own (package, name) slot (ADR-0150 child B) #33124) gives the 422 and the single boot warning.--no-watch), never the shared tree; its install cache lives in that copy's .objectstack/.platform-core.namespace-object-name-refusal · rev 3 · PASS · mixed (build+api) · OWED: fix #32945
os validateexit 1,objectstack buildexit 2, both "✗ Namespace 'qa_k_case' of package 'com.qa.k-case' equals the object 'qa_k_case' of package 'com.qa.k' … (ADR-0150 D6). Rename the namespace or the object."; each directory alone builds exit 0. Pins (subject 0c2aeb9): cli namespace-object-names 7/0 · spec stack-namespace-object-name 7/0os package installqa_k_case → exit 1 "Install failed (422 PLUGIN_REGISTER_FAILED): Failed to register imported manifest: Namespace 'qa_k_case' of package 'com.qa.k-case' equals the object 'qa_k_case' of package 'com.qa.k' …"; GET /api/v1/packages lists com.qa.k only (0 × com.qa.k-case). Pin objectql registry-namespace-object-name 7/0 (engine)os validateexit 1 "The object 'qa_k_custom' of package 'com.qa.k-custom' is short-named 'custom'. The paired customization package of namespace 'qa_k' takes the namespace 'qa_k_custom' (ADR-0146) …"qa_w→ 422 NAMESPACE_PREFIX (prefix rule fires first); objectshowcase→ 422 NAMESPACE_PREFIX; package create with namespaceqa_k_case(equals installed object) → 422 NAMESPACE_CONFLICT naming both; PUT with empty name → 405 METHOD_NOT_ALLOWED.approvals.ooo-delegation-reroute · rev 8 · FAIL · mixed (api) · OWED: fix #33062
approvals.ooo-delegation-reroute · off-clause probe · security finding — detail withheld, reported to PM.records-forms.multi-currency-invoice · rev 2 · PASS · mixed (api+browser) · OWED: fix #32941
return!c.disabled&&l?.currencyConfig?.currencyMode==='record'&&l.currencyConfig.homeAmount?…space-y-1…[t,VI(...)]): INV-1004 detail shows "$500.00 / Converted at 0.9 on Nov 14, 2026"; Edit dialog: 1 × [data-testid=home-amount-preview] data-state "converted" "≈ $500.00 at 0.9 on Nov 14, 2026"; Invoice Date → 01/15/2026: "≈ $489.13 at 0.92 on Jan 15, 2026"; Currency → JPY: "≈ $2.97 at 151.5 on Jan 15, 2026"; nothing saved (server read after: EUR 450/500/0.9)studio-authoring.dataset-member-vocabulary · rev 2 · PASS · mixed (api+network+dom) · OWED: fix #32943
_and-are folded". Pin spec dataset-member-vocabulary 18/0 (parse layer)studio-authoring.expression-editors · rev 10 · PASS · mixed (screenshot+dom+api+test) · OWED: fix #33100
record.est_hours * 1.1→ "Valid CEL · Result type: Number";record.a + record.b→ "Result type: Unknown — the engine cannot prove a single type. Wrap operands in double() / int() / string() to pin it…"est_hourzonqax_job— did you meanest_hours?"; bare est_hours → ok:false "bare referenceest_hours…"; editor shows the same two messages, textarea aria-invalid=true, no autosave PUT while they stand. RLS USINGquantity * 2 > unit_price→ editor error "RLS using is not lowerable (unsupported operand "*"), so the policy is dropped and grants no access"; engine: the same predicate PUT as draft then POST /meta/permission/qax_rls/publish → 422 INVALID_METADATA rule rls-predicate-unenforceable (publish-drafts outcome refused)record.→ listbox [name,status,quantity,unit_price,est_hours,a,b,f_sibling] (8 = MAX);record.est→ [est_hours];previous.→ field catalog;previous.s→ [status], Enter inserts "previous.status";current_user.→ no listbox;parent.→ no listbox; bareest_hours > 1→ aria-invalid, "bare referenceest_hours…"owner_id == (→ "Unexpected token: EOF" error, held, 0 PUT; formula-field probef_sibling > 5→ "Valid CEL" before save, first save PUT 200, re-read shows cel-server-error "RLS using (INVALID_FIELD / 400): … 'f_sibling', a virtual formula field on 'qax_job'" (draft _diagnostics code rls-predicate-unenforceable); edit beside the guard (policy name) → held, 0 PUT; new guard textf_sibling > 6→ 1 PUT 200; POST /meta/permission/qax_rls/publish → 422 INVALID_METADATA [rls-predicate-unenforceable]; live set stillowner_id == current_user.idowner_id→ "Non-boolean result "user-1" — a row filter should evaluate to true or false."; direct engine ExpressionEngine.evaluate (packages/formula dist, same ctx shape) → true / false / "user-1"cd ui && npx vitest run --maxWorkers=1): celAuthoring.test.ts 40/0 (incl. 'graceful degradation'); CelPredicateField 24/0 · CelTestRunDialog 6/0 · PermissionAdvancedFacets.cel 10/0record.est_hours * 1.1 * (→ aria-invalid, "Unexpected token: EOF", 0 PUT (draft read 404); RLS parse fault 0 PUT; formula-field guard: no PUT for the edit beside, publish 422record.f_sibling * 2→ ok, number, now consistent with runtime. Pins objectql engine-formula-dependency-order 11/0 · lint runtime-gate.object-formula-cycle 5/0 · formula formula-read-order 5/0.record.quantity * record.unit_priceas a proven-number formula, but both the engine (validate_expression inferredType "unknown") and the editor ("Result type: Unknown") read it unknown; onlyrecord.est_hours * 1.1proves Number. The item's predicates userecord.FORMULA_FIELD; the RLS site here binds bare field names (showcase policies are writtenowner == current_user.email). Package created with namespace qax (the card'sxis refused: namespace 2–20 chars). db /tmp/qa3/E/expr.db.studio-authoring.flow-status-matches-runtime · rev 7 · PASS · mixed (api+dom) · OWED: fix #33054
studio-authoring.no-entry-property-matrix · rev 9 · PARTIAL · mixed (api) · OWED: fix #33101
automation.package-flow-override · rev 4 · PASS · mixed (network+api+dom) · OWED: fix #33052
objectstack-fleet commentedon Nov 14, 2026
qa#3 · os-tesla · session_01L9qibzj9DrVWXkq7joYHGB
Close-out 2026-11-14T23:54Z.
All 28 named fix cards' own repros pass at 0c2aeb9; every clause that failed last round passes. The one FAIL row is the withheld security row, handed to the security lane privately.
Checklist-accuracy notes and fixture gaps went to #33353 (comment 6886186625).
objectstack-fleet commentedon Nov 14, 2026
qa#3 · os-tesla · session_01L9qibzj9DrVWXkq7joYHGB
Closed 2026-11-14T23:56Z: the owed retests at 0c2aeb9 are judged (28 fix repros pass); close-out in comment 6886197946.