Skip to content

QA run · adr-0146-new-items (7/7) · 322cf906 · 2026-11-02 · 6 PASS / 0 PARTIAL / 1 FAIL / 0 BLOCKED / 0 NOT-RUN #29648

Open

Description

@objectstack-fleet

epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848

QA run record, run on the maintainer's word in direct chat with the epic PM seat, 2026-11-03: 「如果都落地了,就更新最新代码,使用右侧浏览器完整的测试验证」; filing: 「发记录并立卡」. It re-runs the seven ADR-0146 items of #29560 after #29563, #29564, #29566, #29567, #29568 and #29569 landed. The record is text only.

Environment fingerprint

  • Framework: main at 322cf9068f. pnpm install --frozen-lockfile, pnpm build, pnpm console:build. The console is this tree's own build, served at /_console.
  • Boot: objectstack dev --ui --seed-admin on the showcase, port 3781, own file database and OS_HOME, OS_PORT exported. The CLI item ran on a second database and port 3782.
  • Browser: the desktop app's built-in browser pane, driven by hand, one item at a time (sequential).
  • Personas: the seeded admin admin@objectos.ai, and one member made with admin create-user and change-password.
  • The customize legs ran under one uptime (863 s at the check). The boot was then restarted once on purpose, with every customization published.

Scope

Selector: adr-0146-new-items, the same seven ids as #29560, each resolved by id through scripts/checklist-select.mjs.

item revision
platform-core.customization-pair-ensure-door 2
studio-authoring.package-customize-restore-display 2
studio-authoring.package-extension-field-c 2
automation.package-flow-override 2
cli.packageless-overlay-ceremony-and-close 1
studio-authoring.package-customization-counts-and-marks 2
platform-core.setup-metadata-redirects-to-studio 2

Pins named in each item's automated.ref, on the same tree, all exit 0:

package files tests
runtime (with packages-export-base-unchanged-per-type.integration.test.ts) 4 65
objectql 4 65
metadata-protocol 2 41
service-automation 1 16
cli 1 5
ui 13 233

Not run here: the live spec ui/e2e/live/studio-customize-journey.spec.ts.

Per-clause verdicts

platform-core.customization-pair-ensure-door (r2) — PASS

clause verdict evidence
0 pass 201 with showcase_custom, ^0, created: true, writable: true; the pair's manifest agrees.
1 pass 200 with created: false; the pair's read is byte-identical before and after.
2 pass 400 body, 400 query, 400 pair as base, 404 not installed, 409 writable, member 403 PERMISSION_DENIED naming manage_metadata. The list gained only the run's fixture. The member's first call answered PASSWORD_RESET_REQUIRED, a fixture step (change-password), not a verdict.
3 pass 409 starts Delete the customization package "com.example.qa-pair-base.custom" first and names its export; the base still reads 200; pair DELETE 200, then base DELETE 200.
4 pass DELETE of the showcase answers 422 WRITABLE_PACKAGE_REQUIRED with its pair installed; both stay listed.

studio-authoring.package-customize-restore-display (r2) — FAIL

Variants: showcase_ops_dashboard, showcase_hours_by_status, showcase_task.in_progress.

clause verdict evidence
0 pass Customize sent no metadata write on any variant. The first edit sent one ensure (201, then 200), then the draft PUT naming package=com.example.showcase.custom with overrides: {package:'com.example.showcase', basedOn:'0.1.0'} and no _ keys. No write named the base.
1 pass The bare, base-named, list and /layers effective reads carry the edit and agree; /layers code is unchanged from step 1.
2 pass As the member: the dashboard and report show the edited label, and the task list drops Due Date, with no server restart. After restore, read as the admin: the dashboard shows its shipped title and the task list has Due Date again. The report's restored render was not opened; its reads equal the baseline.
3 pass studio-override-chip reads the overrides sentence naming ObjectStack Showcase; its title names 0.1.0.
4 fail The pair's export carries each override with its block. The base's export carries the view byte-identical, but the dashboard and the report are absent: dashboards 3 → 2, reports 4 → 3. Reproduction below.
5 pass Cancel deleted nothing. Confirm sent the two DELETEs at the pair, 200 each. All four reads and the base export then equal step 1 byte for byte, for every variant.
6 pass Every variant offers Customize on the read-only base; clauses 0–3 and 5 hold on each. The dashboard and report fail clause 4 only.

studio-authoring.package-extension-field-c (r2) — PASS

clause verdict evidence
0 pass The preview reads region__c; one ensure, then the extension draft PUT with exactly {extend, fields: {region__c: {type:'text', label:'Region'}}}; no object PUT. tier__c joined the same extension with no second ensure.
1 pass The object read lists both beside the shipped fields; the pair's extension read returns them; a task created with both values reads back EMEA / Gold.
2 pass A label edit saves fieldPatches: {assignee: {label: 'Assignee QA'}} alone; required is disabled; field-base-patch-only names the whitelist.
3 pass note__c outside the pair and plain_note in the pair each answer 400 VALIDATION_ERROR located in issues; neither is stored.
4 pass The hint names region__c as taken; add-field-create is aria-disabled.

automation.package-flow-override (r2) — PASS

clause verdict evidence
0 pass Customize sent nothing; one ensure, then the flow draft PUT at the pair under the base's name with the block; no toggle and no ledger write.
1 pass _status has one row; the bare read serves the override; the next change started exactly one run, stepping start, then the renamed node.
2 pass Stronger than the steps: a base run paused at manager_review, then an override renaming that node to manager_review_pin was published, then the request was approved. The run completed on start, manager_review, needs_exec, exec_review (skipped). The next run took manager_review_pin.
3 pass The switch posted {enabled:false} and {enabled:true}, 200 each. Off: no run. On: the next run took the override's node. The ledger row has package_id com.example.showcase. One switch is drawn.
4 pass Two DELETEs at the pair, 200 each; the chip is gone; the bare read has no overrides key; the next run took the base's manager_review.
5 pass After the restore, New similar answered 200 with status obsolete and packageId com.example.showcase.custom; the console opened the copy, Added, in the pair. See the second finding below for New similar while the override is live.

cli.packageless-overlay-ceremony-and-close (r1) — PASS

clause verdict evidence
0 pass Exit 0, apply: false, rows: []; row and pair counts unchanged.
1 pass The staged row reads movable, pair com.example.showcase.custom; nothing written.
2 pass {"error":"confirmation_required","hint":"pass --yes"}, exit 1; the row unchanged.
3 pass Moved with overrides {package, basedOn:'0.1.0'}; no package-less row remains; after a boot the bare read serves the staged label and /layers code stays the shipped one; a re-run lists nothing.
4 pass The package-less PUT and DELETE and the base-named PUT each answer 403 naming the pair; the item is unchanged after each; the declared PUT into the pair answers 200.

The first staging wrote the body as a BLOB (sqlite readfile), and that move failed spec validation with the row kept. That was the run's own staging error, corrected with CAST(... AS TEXT), not a verdict.

studio-authoring.package-customization-counts-and-marks (r2) — PASS

clause verdict evidence
0 pass Served counts 4 overrides, 2 extensions, 1 switched off; the card reads 6 customized, 1 switched off; the pair link opens the pair's Data, the switched-off link the Automations pillar.
1 pass The directory total reads 6. Dashboard list: one row marked Customized, the filter leaves 3 → 1. Flow list: Customized and Added marked, the filter leaves 33 → 2.
2 pass The landing asks the read-only base only, with a writable card present. A writable package's area asks, answers zero and draws no total, mark or filter. The pair id answers 400 VALIDATION_ERROR naming its base.

platform-core.setup-metadata-redirects-to-studio (r2) — PASS

clause verdict evidence
0 pass Each URL's first history entry is its /studio/~all/metadata/... target. The lists stay on ~all (#29566 holds), confirmed on full load for /apps/setup/metadata/object.
1 pass ?package= opens the leg, then the Data pillar; ?scope=environment keeps the cross-package leg; ?review=1 and #fields survive the redirect.
2 pass Datasource list, item and alias settle on Setup with no /studio entry; the list shows showcase_external; metadata-edit-datasource renders.
3 pass The bookmark lands on /studio/~all/metadata/flow (33 rows), and with a package on its Automations pillar.

Chains were read from a history.pushState / replaceState hook with client-side navigation, plus full loads for the list, the datasource and the bookmark.

Reproduction rules

  1. A published dashboard or report override drops the item from the base's export (restore-display, clause 4; product defect). Reproduced before and after a restart.
    1. On a fresh showcase, GET /api/v1/packages/com.example.showcase/export: dashboards[] holds showcase_ops_dashboard.
    2. POST /api/v1/packages/com.example.showcase/ensure-customization; PUT /api/v1/meta/dashboard/showcase_ops_dashboard?mode=draft&package=com.example.showcase.custom with the item and overrides: {package:'com.example.showcase', basedOn:'0.1.0'}; POST /api/v1/packages/com.example.showcase.custom/publish-drafts.
    3. Repeat step 1's read. Expected: the item byte-identical to step 1. Actual: absent. The same happens with report showcase_hours_by_status. View showcase_task.in_progress stays. Removing the override brings the item back.
  2. New similar on a flow with a live override is refused (off-clause; product defect). Reproduced twice in Studio and once over the API. Publish an override of showcase_budget_approval, then POST /api/v1/automation/showcase_budget_approval/clone with {name:'showcase_budget_approval_copy', label:'x'}. Expected: a switched-off copy in the pair (ADR-0146 D4). Actual: 403 NOT_OVERRIDABLE, "declares an override of 'com.example.showcase', which ships no flow named 'showcase_budget_approval_copy'". After Restore the same call answers 200.

Derived

  • PASS (6), FAIL (1): studio-authoring.package-customize-restore-display, clause 4.
  • PARTIAL, BLOCKED and NOT-RUN: none. No fixture gaps.
  • packages-export-base-unchanged-per-type.integration.test.ts is green while clause 4 fails live: on its harness the per-package layer lists both documents, and on the showcase boot it does not hold the base's.

Off-clause observations, not extracted

  • At a 1024 px wide pane, the selected customized row in the flow rail showed only its mark, with the name squeezed out.
  • At the same width, the item header's more menu (if-item-more, auto-item-more) sits under the right panel until the panel is collapsed.
  • GET /api/v1/meta/object/showcase_task/layers: code.fields.assignee.label reads the patched label, not the shipped one.
  • The clone's notice sentence "The copy is switched off…" renders in English in a zh-CN console.

Links back: #29560, #28579, #28236.

Activity

  1. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848
    2026-11-02T23:52Z

    Close-out of this run.

    Extracted: #29649 · studio-authoring.package-customize-restore-display · acceptance[4]
    Extracted: #29650 · automation.package-flow-override · off-clause

    Assertion defects: none. Coverage gaps: none. The four off-clause observations in the body are not extracted.

    This record stays open until #29649 and #29650 land and the owed items are re-judged. #29560 covered the same seven ids; its Superseded-by: line is not written yet, because that close was not part of the instruction to this seat.

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