Repository navigation
Studio: a cloned packaged flow reaches no Studio surface — Studio is routed per package, and the clone is correctly package-less (moved from objectstack-ai/objectstack#21332) #11553
Description
Activity
- addedbugSomething isn't workingSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seatarea:studioChanging a running app without code — authoring, publish, docs and the portalChanging a running app without code — authoring, publish, docs and the portaland removed
on Oct 3, 2026 objectstack-fleet commented
on Oct 3, 2026 ContributorAuthorMore actionsClaim: PM loop round 1
Session:session_01FjqrwXPfSMkSfkKYDSRkN2
Account:os-zhuang(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-11553-studio-packageless-flows
Worktree:objectui-issue-11553
Domain:domain:ui
Seat:domain:ui#1
File surface: the Studio arm of triage's ruling (5946433961on objectstack-ai/objectstack#21332, quoted in this card's body). Read at objectuiorigin/maind0c0c7fe9, as leads:apps/console/src/components/StudioRoute.tsx:studioRoutes(/studio,/studio/:packageId,/studio/:packageId/:tab) andStudioLanding, for a route and a home entry for package-less (org/install-owned) flows;packages/app-shell/src/views/studio-design/**: the Automations pillar's rail and the surface that opens a flow, so a package-less flow is listed and opens editable, and the deep link to it opens that flow and not another;packages/app-shell/src/views/metadata-admin/i18n.ts: new strings only;- tests beside each, and one
@object-ui/app-shellchangeset (plusapps/consoleif it ships).
⛔ The clone is not moved into a package (ADR-0126 §7.1). ⛔ No objectstack-side change. The dev stops on a breach and explains it in the report.
Container & model:M,mode:subagent,model: opus(default judgment tier;dispatch-gates --tier --repo objectstack-ai/objectuiprinted "no path-derived mandate" forStudioRoute.tsx,StudioDesignSurface.tsxandmetadata-admin/i18n.ts)
Clause-②: no
Why no: a new console surface for flows the server already serves; no accept set moves and no published contract input or type widens.
Thread-read: none
Serial constraints cleared: read 2026-10-03T15:17Z.- objectui#10202 (the director's Studio picklist epic card, claim
5967957684, no PR yet) owns the picklist page and its registry entry underpackages/app-shell/src/views/metadata-admin/**, and the object designer's field editor. This card touches only new keys inmetadata-admin/i18n.tsthere, which is text-mergeable. ⛔ Not the registry, not the field inspector. - objectui#11546 (p3, a read-only flow canvas opens no node inspector) is a different mechanism, not this card, and not dispatched.
- Open PRs: objectui#11556, feat(plugin-form): record:line_items publishes every key of its 17.6.0 spec row, each by measurement (objectui#11536) #11557, fix(plugin-detail): record:details edit mode edits a markdown field in a multi-line textarea (objectui#11541) #11559, test(plugin-form): object-form
fieldsfixtures name fields as strings; the{ name }row pins a stored read the declared member refuses (objectui#11550) #11560, docs(skills): the page-builder guide's object-form example names its fields; a per-form override goes on a section entry (objectui#11550) #11561 (this seat) and docs(skills): type three marked fences' schema as SchemaRendererProps['schema'] (objectui#11543) #11558, feat(types,react,core,plugin-dashboard)!: a node slot and SchemaRenderer'sschemaprop take the declared-node union, V1; the dashboard producers name declared nodes and an envelope's object-metric retires (objectui#11466) #11512, feat(cli):objectui validateandobjectui checkjudge through the strict authoring face (objectui#5250, slice A) #11069 (others) touch neitherStudioRoute.tsxnorstudio-design/**. - This seat's in flight: objectui#11550 (
plugin-form, the skills guide) is disjoint.
Generated by Claude Code
objectstack-fleet commented
on Oct 3, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 11553, "status": "done", "branch": "claude/issue-11553-studio-packageless-flows", "pr": "https://github.com/objectstack-ai/objectui/pull/11565", "session": "session_01FjqrwXPfSMkSfkKYDSRkN2 (mode:subagent of the PM seat; Claude-Session trailer on every commit)", "premise_still_valid": true, "summary": "Studio now has one reserved scope for flows that belong to no package: /studio/~org/automations. It is served by the same StudioDesignSurface with packageId null, and `~` is outside every package-id alphabet. Its Automations rail lists flows whose served _packageId names no package, plus package-less drafts, and opens them editable; edits save package-less drafts. The header count, the pending-changes sheet and Publish cover package-less flow drafts only, and Publish promotes each by reference through publishDraft, because the package batch door cannot reach them. The scope is reachable from Studio's home (shown even with no writable package) and from the package switcher. The console route gets the bare /studio/~org leg. A ?surface=flow:NAME link no longer opens the first flow when the named one is not in the rail: from a package pillar a package-less flow is opened in the package-less scope, and a flow found nowhere is reported on the canvas. The read-only package arm is unchanged, and the objectui#11124 pins stay green. Premise re-verified at origin/main d0c0c7fe9: PM hypotheses 1, 2, 4 and 5 hold as written. Hypothesis 3 also holds: the home listed packages only. No objectstack-side change; the clone is not moved into a package.", "tests": "Final head 4831c5a. (1) `pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/views/studio-design/`: Test Files 88 passed (88), Tests 521 passed (521). (2) `pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/preview/ apps/console/src/components/`: Test Files 50 passed (50), Tests 562 passed (562). (3) `pnpm --filter @object-ui/app-shell type-check` (tsc --noEmit plus tsconfig.test.json): exit 0, 0 error TS. `pnpm --filter @object-ui/console type-check`: exit 0, 0 error TS, after `pnpm --filter @object-ui/app-shell build` (dist completeness 978 files) and building the five console plugin deps. (4) Dependency build: `pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build` gave VERDICT command-exit 0 (29 packages). (5) eslint on the 13 changed TS/TSX files: exit 0, 0 errors; per-file warnings equal base d0c0c7fe9 (17/2/1/0). New pins: StudioDesignSurface.packageLessFlows-11553.test.tsx (12), studioScope.test.ts (9), packageSurfaces.test.ts (+4), BuilderLanding.orgScope-11553.test.tsx (2), StudioRoute.test.tsx (+2). Ablations: each mutation was made on committed code with ablation-replace.mjs in WRAP mode (anchor x1 to x0, blob changed, restore proven: blob equals HEAD and git diff HEAD is empty). The tests import ./StudioDesignSurface from source, so no dist was involved. A1 deep-link fallback back to items[0]: 1 red ('a link naming a flow no rail holds opens no other flow'). A2 package-less redirect removed: 1 red ('the measured link, through the showcase pillar'). A3 package-less loader swapped for the package loader: 9 red. A4 publish arm disabled: 1 red. A5 header count unfiltered: 1 red. A6 sheet include dropped: 1 red. A7 (at 4831c5a) readOnly back to pkgWritable === false: 2 red, including the switcher-from-read-only-package pin. Expected direction (turn red) was observed in every case. CI on the PR: in_progress when this report was written (19 of 42 check runs completed). Not run locally: repo-wide pnpm lint and the full test shards (declared to CI); no browser check.", "mcp_calls": "0", "api_writes": "3 REST writes, each through the fleet-write relay (a POST /repos/objectstack-ai/objectstack/dispatches packing ONE action): (1) pr_create, POST /repos/objectstack-ai/objectui/pulls, draft, read back identical (10193 bytes); (2) label-write --assign os-zhuang, POST /repos/objectstack-ai/objectui/issues/11565/assignees, read back matching (labels left as labeler.yml set them); (3) this os-dev-report comment via post-stamped.mjs, POST /repos/objectstack-ai/objectui/issues/11553/comments. git push is not counted. No label written; card assignee untouched.", "open_questions": [], "out_of_scope_findings": [ "carrier: none (承接者:无) · noted, not filed · Setup › Packaged automation's clone result says 'Edit the copy in Studio' but links nowhere; studioOrgScopePath({ type: 'flow', name }) can now produce a direct link (packages/app-shell/src/views/setup/PackagedAutomationPage.tsx is outside this card) · in PR Acceptance notes", "carrier: none (承接者:无) · noted, not filed · the same deep-link fallback mechanism remains in the Interfaces rail (cur ?? deepLinked ?? firstLeaf) and the Data rail (c ?? deepLinked ?? items[0]): a ?surface= link naming an item the rail does not hold opens the first item; not measured through a public door, so no class (a) claim · dedupe words: studio deep link surface fallback first item, resolveSurfaceDeepLink items[0], surface param opens another · in PR Acceptance notes", "carrier: none (承接者:无) · noted, not filed · a host that mounts StudioDesignSurface with its own aiSlot (cloud edition) and reads :packageId itself would see ~org as a package id in this scope; not measured, no such host in this repo · in PR Acceptance notes" ], "gates": [ { "command": "pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build", "exit": 0, "verdict": "os-verify-lock: VERDICT command-exit 0" }, { "command": "pnpm --filter @object-ui/app-shell type-check", "exit": 0, "verdict": "0 error TS (tsc --noEmit plus tsc -p tsconfig.test.json)" }, { "command": "pnpm --filter @object-ui/app-shell build", "exit": 0, "verdict": "dist completeness: 1 package(s) complete (978 emitted files verified)" }, { "command": "pnpm --filter @object-ui/console type-check", "exit": 0, "verdict": "0 error TS (tsc --noEmit plus tsc -b tsconfig.node.json --force)" }, { "command": "pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/views/studio-design/", "exit": 0, "verdict": "Test Files 88 passed (88), Tests 521 passed (521)" }, { "command": "pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/preview/ apps/console/src/components/", "exit": 0, "verdict": "Test Files 50 passed (50), Tests 562 passed (562)" }, { "command": "eslint --format json (13 changed TS/TSX files)", "exit": 0, "verdict": "0 errors; warnings equal base per file" }, { "command": "pnpm check:i18n-keys", "exit": 0, "verdict": "Every in-scope call-site key resolves against the en pack" }, { "command": "pnpm check:i18n-drift", "exit": 0, "verdict": "No designer-table en value changed in this range." }, { "command": "pnpm check:i18n-dead-keys", "exit": 0, "verdict": "report, exit 0" }, { "command": "pnpm check:i18n-designer-parity", "exit": 0, "verdict": "Every en row has a zh row, and every shared row carries the same placeholders." }, { "command": "pnpm check:control-bytes", "exit": 0, "verdict": "check-control-bytes: OK" }, { "command": "pnpm check:new-line-citations", "exit": 0, "verdict": "VERDICT new-cross-file-line-citations: 0 new citation(s)" }, { "command": "pnpm check:changeset-claims", "exit": 0, "verdict": "report-only, exit 0" }, { "command": "pnpm check:pending-changeset-literals", "exit": 0, "verdict": "exit 0" }, { "command": "pnpm check:spec-symbols", "exit": 0, "verdict": "exit 0" }, { "command": "pnpm check:readme-exports", "exit": 0, "verdict": "check-readme-exports: OK (563 real, 0 fabricated; 0 unbuilt after building plugin-ai and cli)" }, { "command": "pnpm check:unreferenced-sources", "exit": 0, "verdict": "OK Every shipped source file in every covered package is reachable." }, { "command": "pnpm check:test-path-roots", "exit": 0, "verdict": "check-test-path-roots: OK" }, { "command": "pnpm check:vi-mock-specifiers / check:vi-mock-inherit / check:vi-mock-override-shape", "exit": 0, "verdict": "OK x3" }, { "command": "pnpm check:metadata-write-doors", "exit": 0, "verdict": "OK 17 metadata write door(s) derived" }, { "command": "pnpm check:handler-key-reads / check:self-import / check:phantom-deps / check:esm-specifiers", "exit": 0, "verdict": "OK x4" }, { "command": "pnpm check:doc-fences / check:doc-types", "exit": 0, "verdict": "OK x2" }, { "command": "node scripts/check-changeset-presence.mjs", "exit": 0, "verdict": "13 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)" }, { "command": "node scripts/check-changeset-no-major.mjs / check-changeset-overwrite.mjs / check-changeset-fixed.mjs / check-doc-links.mjs", "exit": 0, "verdict": "OK x4" }, { "command": "grep -naP control-byte scan over changed files", "exit": 1, "verdict": "no match (grep exit 1 = clean)" }, { "command": "repo-wide pnpm lint, full vitest shards, check:eager-closure, browser check", "exit": null, "verdict": "NOT MEASURED: declared to CI (repo-wide/heavy); browser check optional per brief, not run" } ], "files_changed": [ ".changeset/11553-studio-package-less-flows.md", "apps/console/src/components/StudioRoute.tsx", "apps/console/src/components/StudioRoute.test.tsx", "content/docs/guide/console.md", "packages/app-shell/README.md", "packages/app-shell/src/index.ts", "packages/app-shell/src/preview/DraftChangesPanel.tsx", "packages/app-shell/src/views/metadata-admin/i18n.ts", "packages/app-shell/src/views/studio-design/BuilderLanding.tsx", "packages/app-shell/src/views/studio-design/BuilderLanding.orgScope-11553.test.tsx", "packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx", "packages/app-shell/src/views/studio-design/StudioDesignSurface.packageLessFlows-11553.test.tsx", "packages/app-shell/src/views/studio-design/packageSurfaces.ts", "packages/app-shell/src/views/studio-design/packageSurfaces.test.ts", "packages/app-shell/src/views/studio-design/studioScope.ts", "packages/app-shell/src/views/studio-design/studioScope.test.ts" ], "deviations": [ "File surface extended within @object-ui/app-shell beyond the claim's list: preview/DraftChangesPanel.tsx (an optional include predicate, so the package-less scope's sheet reviews only what its Publish ships; package hosts unchanged) and src/index.ts (exports STUDIO_ORG_SCOPE_SEGMENT, STUDIO_ORG_SCOPE_PILLAR and studioOrgScopePath for the console route). The README and content/docs guide rows are required by AGENTS.md commandment #2. All are named in the PR body.", "The route shape was chosen, not escalated: the ruling settles the Studio arm and a rail or home entry, and the brief's suggested route names a reserved segment in one StudioDesignSurface. The segment spelling ~org was picked as collision-proof (outside MANIFEST_ID_PATTERN and PACKAGE_ID_RE, pinned by test).", "The package-less Publish is per-draft by reference (publishDraft), not all-or-nothing: no batch door exists for drafts bound to no package. Same door as Home's publish-all for package-less drafts; failures named per draft.", "Built extra packages for gate preconditions: five console plugin deps (gantt, map, markdown, timeline, tree) for console type-check, and plugin-ai and cli for check:readme-exports.", "The PM's write-pace notice arrived mid-run; the writes were made after the window reopened (write-pace --status said the next write may go). No write was refused or retried.", "Worktree removed after the PR was opened (node_modules first; git worktree remove without --force succeeded on a clean tree)." ], "line_budget": "n/a (no skills/** touched)" }
Generated by Claude Code
objectstack-fleet commented
on Oct 3, 2026 ContributorAuthorMore actionsSeat review of PR objectui#11565 at head
4831c5aef(dev report5971094215): content ACCEPT;Clause-②corrected toyes; the at-tier contract review is owed before readydomain:uiseat 1 ·session_01FjqrwXPfSMkSfkKYDSRkN2· 2026-10-03T16:33Z. Reviewed against GitHub, not the report.The correction, owned by this seat
- Claim
5970497214declaredClause-②: no. The delivered route exports three new names from@object-ui/app-shell's entry (STUDIO_ORG_SCOPE_SEGMENT,STUDIO_ORG_SCOPE_PILLAR,studioOrgScopePath; the changeset declaresminorfor them). It also gives the package-less scope a Publish path. That widens a published package's public surface, sonowas the wrong declaration. - It is corrected to
yeson the PR body's line, and on this card here. The seat should have declaredyesunder 「拿不准 ⇒ 按yes」, since the route was not chosen at claim time. - ⇒
needs:contract-reviewis hung on the PR, and an isolated at-tier review runs before ready.
Shape and surface
- Draft, base
main. The first line isFixes #11553, with no other closing keyword. - 16 files, +1109 / −42, no governed path.
- Claim amended here:
preview/DraftChangesPanel.tsx(an optionalincludepredicate; package hosts are unchanged),src/index.ts(the three exports),packages/app-shell/README.mdandcontent/docs/guide/console.md(docs-driven rows). All are accepted.
The ruling, carried out (Studio arm,
5946433961)- One reserved scope
/studio/~org/automations, served by the SAMEStudioDesignSurfacewithpackageId === null.~is outsideMANIFEST_ID_PATTERNandPACKAGE_ID_RE(pinned instudioScope.test.ts). ⛔ The clone is not moved into a package, and objectstack is unchanged. - The rail lists flows whose served
_packageIdnames no package (sys_metadatais read as none), plus package-less drafts, and opens them editable.readOnly = packageId !== null && pkgWritable === false, so the read-only package arm is unchanged, and objectui#11124's pins stay green. - Publish in the scope promotes each package-less flow draft by reference (
publishDraft), the door Home's publish-all uses. It is not all-or-nothing; failures are named. The server's write gate stays the authority. - Deep link: a
?surface=flow:naming a flow the rail does not hold no longer opens the first flow. From a package pillar a package-less flow opens in the scope; a flow found nowhere is reported. - Reach: from Studio's home ("Not in a package", shown even with no writable package) and from the package switcher.
- Ablations A1–A7 each turned the predicted pins red, and each was restored by blob hash.
Changeset prose (checked against the diff)
minorfor@object-ui/app-shellandpatchfor@object-ui/console✓. Each bullet matches a hunk: the scope, the rail filter, the publish-by-reference, the deep link, read-only unchanged, the bare/studio/~orgleg ✓.Out-of-scope (all three are in the PR's Acceptance notes, ⛔ not filed)
- Setup › Packaged automation's "Edit the copy in Studio" links nowhere.
studioOrgScopePathcan now build that link, andPackagedAutomationPage.tsxis outside this card. - The same first-item deep-link fallback in the Interfaces and Data rails. It was not measured at a door, so no class (a) claim.
- A cloud host reading
:packageIditself: not measured, and no such host is in this repo.
Generated by Claude Code
- Claim
objectstack-fleet commented
on Oct 3, 2026 ContributorAuthorMore actionsLanded and verified by content: closed
completedby PR objectui#11565 ·domain:uiseat 1 ·session_01FjqrwXPfSMkSfkKYDSRkN2· 2026-10-03T17:05Z.-
The merge: PR objectui#11565 went through the merge queue to
mainasf624f278dat 2026-10-03T17:03Z, after an at-tier contract review PASS on its head (5971232861). -
Content check on
mainf624f278dagainst its first parentb0bf413ca:mainparent studioScope.ts:STUDIO_ORG_SCOPE_SEGMENT = '~org'1 0 (no file) studioScope.ts:export function studioOrgScopePath1 0 (no file) StudioDesignSurface.tsx:packageId !== null && pkgWritable === false1 0 StudioRoute.tsx:STUDIO_ORG_SCOPEmentions (the~orgleg)4 0 app-shellsrc/index.ts:studioOrgScopePathexport1 0 The changeset
11553-studio-package-less-flows.mdis in the tree. -
No other card closed in that window.
-
Carried, not filed (Acceptance notes on the PR,
5971250027): the Setup clone-result link, the first-item?surface=fallback in the Interfaces and Data rails, and the per-item publish door's missing spelling for the unbound draft row. Each needs a measured reach before it becomes a card. -
pm:dispatchedis removed in the same act.domain:ui,area:studio, the type and the priority stay.
Generated by Claude Code
-
- added a commit that references this issue
on Oct 3, 2026 - added a commit that references this issue
on Oct 7, 2026
Filed by the triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015,
session_01AavokzJ5DndAwitDXvKy4U). It moves objectstack-ai/objectstack#21332 here, where the fix lands. That card came from QA run objectstack-ai/objectstack#21330 (checklist clauseautomation.packaged-flow-clone-contract, acceptance[6]). Its Studio half is what row B1 of the objectstack-ai/objectstack#12438 acceptance run still waits on. ⛔ Not a claim, ⛔ not a dispatch.Graded here:
bug·priority:p2·domain:ui·area:studio·pm:queue.What fails
ADR-0126 §7.1 makes a clone of a packaged flow "an ordinary org/install-owned flow". §1.3 and the Setup › Packaged automation page promise that it is edited in Studio. On objectstack 17.6.0, with the console at the pin, the clone is created, survives a restart and dispatches. No Studio surface lists or opens it.
Measured on the stock showcase, as admin, in objectstack-ai/objectstack#21332 and re-measured in the objectstack-ai/objectstack#12438 run (B1,
5968206129, console built at pin89cad75d5570):flow-clone.tsstrips provenance on purpose./api/v1/meta/flow?package=…) omits it. The bare list includes it.Where (read at
origin/main7121221fae)apps/console/src/components/StudioRoute.tsx(about:153–:160): every Studio route is keyed by:packageId.packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx(header docblock,:6): it is routed as/studio/:packageId/{data|automations|interfaces}, so its Automations pillar shows one package's flows.Ruling (triage's,
5946433961on the source card; overturnable by the maintainer)The Studio arm, not the package arm.
Why p2. ADR-0126 promises that a clone is edited in Studio, and the clone is unreachable there. The engine half works, and nothing is lost.
Done when: this lands, and objectstack's
.objectui-shacarries it. objectstack-ai/objectstack#12438's seat then re-runs B1 on a console built at that pin.Not this card: objectui#11546 (a read-only canvas opens no node inspector), which is a different mechanism.