Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

studio(landing): a read-only package offers no way to start a writable copy — BuilderLanding comments disagree on whether Duplicate applies to read-only packages #11808

Closed

Description

@objectstack-fleet

Filing gate ② — a product decision only the maintainer can make.

Who acts on it: objectui triage → the Studio / app-shell owner. ⛔ Not a claim. Found in a manual browser QA pass of Studio on 2026-10-07; filed one card per finding on the maintainer's word: 「你发现的问题全部提交 issue」, and on the one-card-per-finding question 「覆盖规则,逐条立卡」.

Maintainer quick-read

The Studio landing lists installed packages as "Read-only · browsable" with no way to start a writable copy. Offer one?

Seen

BuilderLanding carries two comments that disagree: one says a read-only code package is "a STARTING POINT, not a dead end — duplicate re-namespaces it into a new writable base"; the one above the Duplicate button says duplicate "only makes sense for writable bases … customizing a code package goes through templates / marketplace install". The button renders for writable packages only.

Options

  • A — Customize a copy on read-only cards (server-side duplicate into a new namespace).
  • B — keep it writable-only and fix the comment; point read-only cards at the marketplace/template route.
  • C — status quo.

Environment

objectstack 879bd38c · examples/app-showcase booted with objectstack dev --ui --seed-admin on an isolated port and SQLite file · objectui 179f6fe9 (HEAD; the framework pin .objectui-sha is a58626c8) served by the console's Vite dev server, perf numbers from a vite build of the same commit · Chromium 141 at 1440×900 · signed in as the seeded platform admin admin@objectos.ai unless stated.

Duplicate check

Dedupe words: read-only package duplicate writable copy · studio landing customize copy

Filed by Claude Code (session session_01D76mrPJrSSdaKRxR2rvrMG) from that QA pass.


Generated by Claude Code

Activity

  1. added
    enhancementNew feature or request
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    on Oct 7, 2026
  2. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    Path: write metadata — starting from an installed package | 缺项 | P3

    Triage: first grade, enhancement · priority:p3 · domain:ui · area:studio · pm:queue. Filed as ②, but an accepted ADR answers it: the body's option B

    Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-07T17:32Z. ⛔ Not a claim, ⛔ not a dispatch.

    Triage: lands in packages/app-shell/src/views/studio-design/BuilderLanding.tsx (the comments at :54 and :133, and the read-only card) ⇒ domain:ui; rationale: a Studio or console surface in objectui. Filed from the browser QA pass of 2026-10-07 (objectstack 879bd38c, objectui 179f6fe9); paths re-read on objectui main 9990f9e122.

    • Why not the decision box: ADR-0070 (Accepted) rules that code or installed packages are read-only and are customized by org overlay where allowOrgOverride allows (0070-package-first-authoring.md:30, ADR-0005). D4's Duplicate clones a base, the ADR's word for a writable package (:80). So the comment at :133 is right and the one at :54 is wrong. Why p3: nothing is lost; the read-only card is a dead end.
    • Direction:
      • correct the :54 comment to D4's reading
      • the read-only card points at the routes that exist: overlay where allowed, and the marketplace or a template
      • ⛔ Duplicating a read-only package into a writable copy (option A) would amend ADR-0070 D4. Triage does not take it; the maintainer can ask for it
    • Clause-②: no. Patch changeset in objectui.
  3. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3
    Session: session_01MgfduSkFrfM3eorB3UGfAU
    Account: os-bill
    Branch: claude/issue-11808-readonly-package-card
    Worktree: objectui-issue-11808
    Domain: domain:ui
    Seat: domain:ui#2
    File surface (line numbers on 340bfab):

    • packages/app-shell/src/views/studio-design/BuilderLanding.tsx:
      • the comment at about :54, corrected to ADR-0070 D4's reading: Duplicate clones a writable base;
      • the comment at about :133–:137;
      • the read-only package card, which points at the routes that exist: org overlay where allowOrgOverride allows it, and the marketplace or a template.
    • Only new or reworded engine.studio.landing.* rows, en and zh, in app-shell's metadata-admin/i18n.ts.
    • The tests beside these, and .changeset/11808-*.md.

    ⛔ Not on it:

    • Duplicating a read-only package into a writable copy. Triage 6043283623 rules that it would amend ADR-0070 D4, and only the maintainer can ask for it.
    • The Duplicate form and isSpecPackageId (objectui#11855, landed 475bda1): left as they are.
    • StudioDesignSurface.tsx, held by other claims.
    • packages/components/src/ui/** and packages/i18n/**.

    Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report).
    Container & model: S, mode:subagent, model: opus (dispatch-gates --tier --repo objectstack-ai/objectui over these paths: no path-derived mandate; default tier)
    Clause-②: no
    Responsibility: objectui app-shell Studio landing: a read-only package's card offers no route forward, and BuilderLanding's comments disagree on whether Duplicate applies to read-only packages | ADR-0070 D4 duplicates a writable base, and read-only packages are customized by org overlay where allowOrgOverride allows | every author who opens /studio with an installed read-only package, seen by the filer's 2026-10-07 browser QA pass
    Thread-read: 6043283623
    Serial constraints cleared: none blocking.

    • objectui#11855 (this seat): landed as 475bda1.
    • objectui#11863: released to triage (pm:retriage). It holds no file.
    • In-flight claims read 2026-10-08T06:55Z: none names BuilderLanding.tsx.
    • Open objectui PRs, read 2026-10-08T06:55Z: none touches it.

    Why Clause-②: no: the comments and the read-only card's guidance change, and no behaviour the ADR rules out is added. No export, prop, route or packages/i18n key changes.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 11808,
    "status": "done",
    "branch": "claude/issue-11808-readonly-package-card",
    "pr": "#11927",
    "session": "session_01MgfduSkFrfM3eorB3UGfAU",
    "premise_still_valid": true,
    "summary": "BuilderLanding's two Duplicate comments now state ADR-0070 D4's reading: Duplicate clones a writable base and is offered on writable bases only, and a read-only package is customized by org overlay (D2, ADR-0005). The STARTING POINT / re-namespaces / 'substance behind Start with a template' wording is gone, and the module doc's 'D4 gate' for writability now reads D2. Each read-only card keeps its browse click and gains 'Customize with an overlay', a link to /apps/setup/metadata?package=PACKAGE_ID (the package's metadata directory, which marks per type whether it accepts an overlay). The read-only section gains one sentence saying why, plus a marketplace link (/apps/setup/system/marketplace, the route Home's 'Start with a template' opens), rendered only when isMarketplaceEnabled(). The copy is four new engine.studio.landing.* rows in en and zh, plus a reworded engine.studio.landing.description, which had said 'browse only'.",
    "hypotheses": {
    "H1": "partly falsified. allowOrgOverride is a metadata-TYPE flag (spec DEFAULT_METADATA_TYPE_REGISTRY: true for view/dashboard/report/translation/email_template, false for object), never a per-package or per-object flag, so no overlay of an object exists. The overlay editor is ResourceEditPage at /apps/setup/metadata/TYPE/NAME; the package-scoped entry is MetadataDirectoryPage at /apps/setup/metadata?package=PACKAGE_ID, the metadata index route in both AppContent branches. Its buildPackageScopeOptions drops only system/cloud, the same scopes parsePackages hides. The marketplace is /apps/setup/system/marketplace, absent when features.marketplace is false (objectui#5504). Home's 'Start with a template' navigates to that same URL. The clause 'card does not offer the overlay where allowOrgOverride is false for the package' has no package-level answer, so the card links to the page that shows the per-type answer. NOT MEASURED in a browser: no backend (the objectstack checkout has no node_modules); measured by route declarations plus the RTL test under a real MemoryRouter.",
    "H2": "falsified for overlay: PkgEntry carries writable only. A per-package 'any overlayable type?' answer needs useMetadataTypes plus useGlobalDiagnostics.packagesByType, one call per package, which the console reads only on the directory page. Not added: no new read, no new endpoint.",
    "H3": "holds: grep -ci 'STARTING POINT|re-namespaces|writable copy' on BuilderLanding.tsx answers 0; every Duplicate/read-only comment states D4's reading."
    },
    "files_changed": [
    "packages/app-shell/src/views/studio-design/BuilderLanding.tsx",
    "packages/app-shell/src/views/metadata-admin/i18n.ts (engine.studio.landing.* rows only, en+zh: 4 added, description reworded)",
    "packages/app-shell/src/views/studio-design/BuilderLanding.readonlyRoutes-11808.test.tsx (new)",
    ".changeset/11808-readonly-package-card.md (new, @object-ui/app-shell patch)"
    ],
    "gates": {
    "head": "1049ee0fb (git rev-parse --short HEAD after the last commit; the remote branch head is the same sha)",
    "results": [
    "pnpm exec vitest run (3 BuilderLanding tests + studio-locale.i18n.test.tsx + packages/core/src/utils/tests/column-identity.ratchet.test.ts + 8 apps/console tests naming BuilderLanding) via os-verify-lock: 'Test Files 13 passed (13)', 'Tests 67 passed (67)', 'VERDICT command-exit 0'",
    "turbo run build --filter=@object-ui/app-shell^... --concurrency=2 via lock: 'Tasks: 28 successful, 28 total', 'VERDICT command-exit 0'",
    "pnpm --filter @object-ui/app-shell type-check (echoed 'tsc --noEmit && tsc -p tsconfig.test.json'; --listFilesOnly lists the new test) via lock: 'VERDICT command-exit 0'",
    "pnpm exec eslint on the 3 touched sources --format json: 3 files, 0 errors, 0 warnings, exit 0; eslint.config.js sets no parserOptions.project, so linting is not type-aware",
    "pnpm check:i18n-keys exit 0 ('Every in-scope call-site key resolves against the en pack')",
    "pnpm check:i18n-designer-parity exit 0 ('Every en row has a zh row, and every shared row carries the same placeholders.')",
    "pnpm check:i18n-drift exit 0 ('Every changed designer-table en value was followed by its zh row.')",
    "pnpm check:i18n-dead-keys exit 0 (report-only; no key from this diff is listed)",
    "node scripts/check-changeset-presence.mjs exit 0 ('this change declares 1 changeset(s): .changeset/11808-readonly-package-card.md')",
    "node scripts/check-changeset-no-major.mjs exit 0 ('No changeset declares a major bump.')",
    "pnpm check:new-line-citations exit 0 ('VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0')",
    "pnpm check:control-bytes exit 0 ('check-control-bytes: OK')",
    "pnpm check:changeset-claims exit 0, pnpm check:pending-changeset-literals exit 0",
    "node scripts/check-vi-mock-specifiers.mjs / check-vi-mock-override-shape.mjs / check-vi-mock-inherit.mjs / check-test-path-roots.mjs, pnpm check:unreferenced-sources: all exit 0 with OK lines"
    ],
    "derivation": "by hand from objectui package.json scripts and .github/workflows check commands, against the diff's files (objectui has no dispatch-gates.mjs); added to the PM lead: i18n-drift, i18n-dead-keys, changeset-claims, pending-changeset-literals, the three vi-mock gates, test-path-roots, unreferenced-sources"
    },
    "tests": "New BuilderLanding.readonlyRoutes-11808.test.tsx, 6 cases, run against the real BuilderLanding with the real initRuntimeConfig. Reverse verification after committing the fix: the base 340bfab BuilderLanding.tsx was written back to disk (overlayPath count 0, STARTING POINT count 1) and the run gave 'Tests 3 failed | 3 passed (6)'. Red: the overlay link and both marketplace cases. Green: the three cases that pin behaviour the base already had. Restored with git checkout HEAD --, proven by blob hash == HEAD blob and an empty git diff HEAD, under a trap.",
    "deviations": [
    "H1's clause 'where allowOrgOverride is false for the package or object, the card does not offer the overlay' is not implemented as written. Its premise is falsified (the flag is type-level), so the card always links to the directory, which shows the per-type answer.",
    "Docs-driven rule (objectui AGENTS.md #2): no content/docs row added, because it is outside the claim's file surface. No existing doc sentence becomes false: the README's 'a read-only package opens in Studio as browse-only' still holds.",
    "Browser verification NOT MEASURED: no backend in the container.",
    "Commit trailers use objectui AGENTS.md's model-free pair (Co-authored-by: Claude, Claude-Session), not the harness reminder's model-named line. The PR body ends with the session-URL footer from os-dev, not the harness's line. Both follow the rule that the harness's attribution reminder yields to the repo rule."
    ],
    "mcp_calls": "0 — no MCP GitHub tool used",
    "api_writes": "3 — each a fleet-write relay POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]: (1) pr_create, i.e. POST /repos/objectstack-ai/objectui/pulls, draft; read-back said 8535 bytes sent, 8535 stored, identical; (2) label-write --assign os-bill, i.e. POST /repos//issues/11927/assignees; read-back matched; (3) this os-dev-report comment, POST /repos//issues/11808/comments. Plus git push of the branch (not REST). Read-only REST: GET issue 11808 and its comments, GET pulls/11927.",
    "open_questions": [
    {
    "question": "Docs-driven rule: should the Studio landing's read-only card get a row in content/docs/guide/console.md, beside 'Package-less Flows in Studio'?",
    "options": [
    "A: the seat adds one row (a read-only package links to its org overlay directory and, where served, the marketplace), extending the claim or as a docs follow-up",
    "B: leave it; no existing doc sentence is false"
    ],
    "recommendation": "A: one row, low cost. AGENTS.md #2 says the change is not done until the docs reflect the code."
    },
    {
    "question": "Should the card hide the overlay link for a package that ships no overlayable type?",
    "options": [
    "A: keep it as is; the link opens the directory, which shows each type locked or overlayable",
    "B: add a per-package read (metadata types registry plus that package's type contributions, one diagnostics call per read-only package) and hide the link when nothing is overlayable"
    ],
    "recommendation": "A: no new read and no N+1 on the landing, and the destination already gives the answer. B is a new read, which the dispatch reserved to the seat."
    }
    ],
    "out_of_scope_findings": [
    "carrier: 承接者:无 · noted, not filed — the builder header's engine.studio.pkg.readonlyHint ('Read-only package — switch to or create a writable package to edit.') in StudioDesignSurface names no overlay route. It is not false, only incomplete: an observation, not a filing class. Not in the PR's Acceptance notes, because the PR body is written once; if the seat wants it there, add one bullet."
    ],
    "cleanup": "worktree /home/user/objectui-issue-11808 removed (node_modules deleted first, plain git worktree remove, no --force); no dev server or background job left running"
    }

  5. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: ACCEPT — PR objectui#11927 · domain:ui seat 2 · 2026-10-08T07:24Z

    Implemented-by: os-dev subagent of session_01MgfduSkFrfM3eorB3UGfAU, branch claude/issue-11808-readonly-package-card, head a8d4e93 (code at 1049ee0, docs patch round on top).
    Reviewed-by: domain:ui seat 2 (session_01MgfduSkFrfM3eorB3UGfAU), against GitHub and the branch diff, not against the report's prose.

    Checklist:

    • PR shape: draft, base main, first line Fixes #11808. No closing keyword sits next to another card. Clause-②: no is at the start of a line. The body was refreshed by the seat to match a8d4e93.

    • Scope: 5 files, all inside the claim:

      • BuilderLanding.tsx;
      • app-shell's metadata-admin/i18n.ts: four new engine.studio.landing.* rows and a reworded engine.studio.landing.description, en and zh;
      • a new test;
      • the changeset;
      • in the patch round, one row of content/docs/guide/console.md. The surface was amended by that file under AGENTS.md's docs-driven rule; no claim or open PR holds it.

      The Duplicate form, isSpecPackageId, StudioDesignSurface.tsx, packages/i18n/** and packages/components/src/ui/** are untouched. Nothing duplicates a read-only package, which is the ADR-0070 D4 line triage drew.

    • Triage direction met:

      • Both Duplicate comments now state D4's reading: Duplicate clones a writable base. The "STARTING POINT / re-namespaces / writable copy" wording is gone (0 hits).
      • Each read-only card keeps its browse click and gains Customize with an overlay, which links to the package's metadata directory (/apps/setup/metadata?package=…).
      • The section links to the marketplace (/apps/setup/system/marketplace, the same route as Home's Start with a template) only when isMarketplaceEnabled().
    • H1 partly falsified, accepted: allowOrgOverride is a metadata-type flag, not a package or object flag, and objects take no overlay. So the card links to the directory page that shows each type's answer, instead of hiding the link per package.

    • H2: PkgEntry carries no overlay fact. No new read or endpoint is added.

    • Q2, the seat's answer: keep the link as it is, rather than adding a per-package read that would cost one request per read-only package on the landing.

    • Clause-②: no holds: no export, prop, route or packages/i18n key. The strings live in app-shell's own table, and check:i18n-drift and the designer parity check pass.

    • Changeset: @object-ui/app-shell: patch. Every sentence was checked against the diff.

    • Evidence:

      • 13 files pass, 67 tests: the BuilderLanding tests, the Studio locale test, the console tests naming BuilderLanding, and the column-identity ratchet.
      • The type-check passes.
      • Reverse check: with the 340bfab blob, 3 of the 6 new pins fail (the overlay link and both marketplace cases), and the 3 pins of existing behaviour stay green. The restore was proven.
      • The docs gates pass on a8d4e93.
      • Not measured in a browser: there is no backend in the container.
    • CI: a8d4e93 is running. The PR lands through the merge queue only when every check on that head is green.

    Out-of-scope note, carrier: none: the builder header's engine.studio.pkg.readonlyHint names no overlay route. It is incomplete, not false.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:studioChanging a running app without code — authoring, publish, docs and the portaldomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatenhancementNew feature or requestpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions