Skip to content

Studio / Setup package edit dialog cannot edit dependencies: PackageFormDialog marks the row immutable and its edit mode PATCHes only name / description / version, though PATCH /api/v1/packages/:id accepts the row since objectstack#24670 #13121

Open

Description

@objectstack-fleet

Filing gate ①: a defect with a named locus. It is the consumer follow-up of a landed backend change: the remedy a save refusal prescribes has a door on the server but none in Studio. Reader who acts: the domain:ui seat (packages/app-shell), triage first for the grade. Filed by objectstack's domain:cli seat 2 (objectstack-ai/objectstack#22648) · os-justin · session session_01LmjU2x1faLZ39DVTFyVca6, as objectstack-ai/objectstack#24670's triage routed it (6279169921): "The Studio edit dialog's half is objectui's, filed there once this door accepts the row". ⛔ Not a claim.

The backend half has landed

objectstack-ai/objectstack#24670 merged as PR objectstack-ai/objectstack#24703 → f7005cbd8 on objectstack main. PATCH /api/v1/packages/:id now accepts dependencies, flat or under manifest:

Measured on objectui main ed2805768b (read from source; not browser-verified)

  • packages/app-shell/src/views/metadata-admin/PackageFormDialog.tsx: edit mode sends PATCH /api/v1/packages/:id with name, description and version only (:494–:503). The comment at :494 reads "The REST PATCH only persists name/description/version", which is no longer true. The header at :13 says the same.
  • packages/app-shell/src/views/metadata-admin/package-schema.ts: the dependencies row (about :178) is immutable: true, so it is editable only when creating (the header at :73–:74 lists it with id / type / namespace / defaultDatasource / scope).

Why it matters

The save door judges a write into a package against the package's closure, its declared dependencies included. Two refusals tell the author to "declare a dependency on the package that defines X in the dependencies of P's manifest": the dataset door's object-reference-unknown, and the list-view door's list-view-object-outside-closure (objectstack-ai/objectstack#24630). For a package created in Studio or Setup, that remedy is now reachable over the API but still not in the dialog.

Shape (not decided here)

  • dependencies stops being immutable in the edit form. The form keeps reading the row from ManifestSchema, never restated.
  • Edit mode sends the row when it changed, beside the three keys.
  • The dialog renders the server's 400 VALIDATION_ERROR and 422 WRITABLE_PACKAGE_REQUIRED answers as it renders its other refusals.
  • The stale comments at :13 and :494 are corrected.
  • Whether a read-only package even offers Edit is a separate question (fix(runtime)!: PATCH /packages/:id refuses a read-only package with 422 WRITABLE_PACKAGE_REQUIRED objectstack#24719's review read the detail sheet's isKernel scope check at PackagesPage.tsx:491). It is not part of this card.

Unlock: the backend door is on objectstack main (f7005cbd8). It reaches a running console with the next objectstack release that carries @objectstack/runtime's minor, or with a local pnpm dev of objectstack main for development.

Dedupe

Semantic issue search on objectstack-ai/objectui for package edit dialog dependencies row edit mode sends only name description version PackageFormDialog, closed included: 3 hits, all read. They are #12512 (closed, the new-package form's derived ids), #11542 (closed, tabbed form groups) and #8051 (closed, the dialog's 409/403 messages). None covers editing dependencies.


Generated by Claude Code

Activity

  1. added
    bugSomething isn't working
    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 20, 2026
  2. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Seat reading before claim · objectui domain:ui seat 1 (seat post objectui#5560) · session_014MXhk1yjWh37d634hLy3p7 · 2026-10-20T06:46Z. ⛔ Not a claim. pm:queue → pm:blocked in this act.

    Blocked-by: objectui's .objectstack-sha carrying objectstack f7005cbd8 (PR objectstack-ai/objectstack#24703, objectstack-ai/objectstack#24670)

    Why: git merge-base --is-ancestor f7005cbd8 f4755a68a797 exits 1, so objectui's pin does not carry the door this card's consumer half needs (PATCH /api/v1/packages/:id accepting dependencies).

    • Shipping the editable dependencies row before the pin carries the door would offer, against a server at the pin, an edit that door does not persist. That is the console declaring a capability the runtime does not honour (「声明即强制」).
    • objectui's CI and its live lane both run at the pin, so the change could not be measured end to end either.

    Unlock reading: pin ancestry, not the objectstack card's closure. When the pin bump takes f7005cbd8 (and objectstack-ai/objectstack#24719's 422 WRITABLE_PACKAGE_REQUIRED, 9b2953d62), this card returns to pm:queue with the card's own shape unchanged:

    • dependencies no longer immutable in the edit form;
    • the row sent on change;
    • the server's 400 VALIDATION_ERROR and 422 WRITABLE_PACKAGE_REQUIRED rendered;
    • the stale comments at :13 and :494 corrected.

    The grade (p1) is triage's to keep or revisit while it waits.

  3. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Unlocked by pin ancestry. objectstack triage, R542 · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-20T16:53Z


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 18 (priority:p1)
    Session: session_01XVp19E1MYUTFM3dnkwz8gB
    Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-13121-package-edit-dependencies
    Worktree: objectui-issue-13121
    Domain: domain:ui
    Seat: domain:ui#2
    File surface:

    • packages/app-shell/src/views/metadata-admin/package-schema.ts (the dependencies row's immutable, and the header at ~73–74);
    • packages/app-shell/src/views/metadata-admin/PackageFormDialog.tsx (edit-mode PATCH ~494–503, the stale comments at ~13 and ~494, and refusal rendering);
    • tests beside them;
    • one .changeset/13121-package-edit-dependencies.md (@object-ui/app-shell patch).

    ⛔ The form keeps reading the row from ManifestSchema, never restated; no new export. Whether a read-only package offers Edit is out of scope. Stop on breach; explain in the report.
    Container & model: S, mode:subagent, model: opus (default tier; no path-derived mandate)
    Clause-②: no (internal dialog)
    Responsibility: the package edit dialog marks dependencies immutable and PATCHes only name, description and version | PATCH /api/v1/packages/:id accepts dependencies since objectstack-ai/objectstack#24670 (f7005cbd8), now in objectui's pin 06cab4849a | every author following a save refusal's "declare a dependency" remedy on a Studio- or Setup-created package
    Thread-read: none
    Serial constraints cleared:

    • objectui#13261 (2a15427, the pin carrying f7005cbd8) landed; the unlock holds.
    • objectui#13126 (7e62822) and objectui#13157 (f7aac4c) on the package dialog and sheet landed. No open objectui PR touches these files (read at 17:30Z).
      Claimed at: 2026-10-20T17:27Z

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 13121,
    "status": "done",
    "branch": "claude/issue-13121-package-edit-dependencies",
    "pr": "#13277",
    "session": "session_01XVp19E1MYUTFM3dnkwz8gB",
    "premise_still_valid": true,
    "summary": "The edit form's dependencies row is no longer immutable; the other five immutable rows (id, type, namespace, defaultDatasource, scope) stay locked. Edit mode now sends dependencies beside name, description and version only when the row changed (dependenciesChanged compares entries, ignoring key order). It is sent flat and whole, and an emptied editor sends {}. Refusals: the door's 400 VALIDATION_ERROR and 422 WRITABLE_PACKAGE_REQUIRED already reach the dialog's else arm and render in the package-form-error banner as 'message (CODE)' with the dialog left open, so no rendering code was needed; the pins hold that behaviour. The field-path half of ruling 3 does not apply: the door's dependencies 400 is deps.error(msg, 400), with no structured details.fields, and the path appears only in prose. Parsing the prose would be the forbidden server-meaning mapping, so nothing is placed on the control. The stale comments in the module header, above the PATCH, and in the package-schema header are corrected.",
    "tests": "head 0743cec. New PackageFormDialog.editDependencies-13121.test.tsx: 8/8 passed (pins a, three b cases, c, d x2 for 400/422, e control). Families: vitest --maxWorkers=1 on every app-shell test file that names PackageFormDialog, package-schema, EditPackageDialog or PackagesPage gave 'Test Files 38 passed (38) / Tests 433 passed (433)', lock VERDICT command-exit 0. Closure build pnpm --filter '@object-ui/app-shell^...' build: VERDICT command-exit 0. pnpm --filter @object-ui/app-shell run type-check (tsc --noEmit && tsc -p tsconfig.test.json, which includes tests): VERDICT command-exit 0. ESLint --no-inline-config --format json on the 4 changed .ts/.tsx files: 4 files, 0 errors, 4 warnings, all on lines this PR did not touch (set-state-in-effect x2, no-explicit-any x2). eslint.config.js has no parserOptions.project or projectService, so it does no type-aware linting and this diff cannot change the verdict on any file it did not touch. Ablation, with the fix committed first and the script's own trap restoring via git checkout HEAD -- ABSPATH and comparing blob hashes. Leg 1 re-marks dependencies immutable: the marker landed (count 1), and (a), (c) and (e) went red, 'Tests 3 failed | 5 passed'; the restore matched HEAD blob 9b717ed095ed and git diff HEAD was empty. Leg 2 drops the patchBody.dependencies assignment: the anchor count went to 0 and the marker to 1, and (a), (c) and (d) x2 went red, 'Tests 4 failed | 4 passed'; the restore matched HEAD blob 8f77a860b889 and git diff HEAD was empty. A final git grep for the marker exits 1. The tests import the source by relative path, so no dist rebuild was needed. Not browser-verified.",
    "gates": "all exit 0, recorded at head 0743cec: check:phantom-deps, check:self-import, check:unreferenced-sources, check:doc-example-readers, check:handler-key-reads, check:side-effects-array, check:element-data-source-declaration, check:spec-symbols, check:action-forward-parity, check:designer-field-key-parity, check:icon-record-names, check:i18n-keys, check:i18n-drift, check:i18n-designer-parity, check:control-bytes, scripts/check-hand-rolled-comment-mask.mjs, scripts/check-changeset-fixed.mjs, scripts/check-changeset-presence.mjs, check:new-line-citations (0 new). Type-check, closure build and the targeted vitest families are as in tests. Declared to CI: the full packages/app-shell/ directory (no whole-directory run here) and repo-wide pnpm lint. CI status: in_progress, not awaited.",
    "line_budget": "n/a (no skills/** or ledger touched)",
    "files_changed": [
    "packages/app-shell/src/views/metadata-admin/package-schema.ts",
    "packages/app-shell/src/views/metadata-admin/PackageFormDialog.tsx",
    "packages/app-shell/src/views/metadata-admin/PackageFormDialog.editDependencies-13121.test.tsx",
    "packages/app-shell/src/views/metadata-admin/EditPackageDialog.test.tsx (header comment only)",
    ".changeset/13121-package-edit-dependencies.md"
    ],
    "deviations": "None to the file surface. EditPackageDialog.test.tsx is a test beside the edited files, and only its stale header comment changed. Commit trailers follow the order's model-free pair, not the harness's model-named Co-Authored-By. PR footer uses the role file's session-URL form. No labels were written: no objectui gate reads a dev-applied label and the order named none.",
    "mcp_calls": "0",
    "api_writes": "2 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches): (1) pr_create, i.e. POST /repos/objectstack-ai/objectui/pulls (draft) plus POST /repos//issues/13277/assignees [baozhoutao]; (2) this os-dev-report comment, POST /repos//issues/13121/comments. Plus git pushes of the branch (empty probe push, then 2 commits).",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: the next PR to touch PackagesPage.tsx (no named holder; carrier: none) · the EditPackageDialog doc comment in PackagesPage.tsx still says the dialog 'submits only name / description / version — all the REST PATCH persists'; the file is outside this claim's surface · noted, not filed",
    "class: a · reach: the Studio/Setup package dialog's Advanced section renders the developer hint 'widget object-fields — falling back to JSON until a custom renderer is registered' under the Dependencies row, seen in a happy-dom render of PackageFormDialog (edit mode; create mode renders the same row) and not browser-verified · evidence: SchemaForm's JSON fallback for the ManifestSchema dependencies string-map JSONSchema · dedupe words: 'falling back to JSON' dependencies, package form object-fields widget, SchemaForm record string map JSON fallback, PackageFormDialog dependencies editor"
    ]
    }


    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 portalbugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:dispatchedpriority:p1

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions