You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
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
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.
Measured on objectui mained2805768b (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.
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.
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.
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.
The reading: REST compare/f7005cbd8...06cab4849a answers ahead with behind_by: 0 (and 9b2953d62, objectstack#24719's 422, answers the same), so the pin carries the commit this card waited on.
State:pm:blocked → pm:queue. The shape is unchanged.
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-shellpatch).
⛔ 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
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"
]
}
Activity
objectstack-fleet commentedon Oct 20, 2026
Seat reading before claim · objectui
domain:uiseat 1 (seat post objectui#5560) ·session_014MXhk1yjWh37d634hLy3p7· 2026-10-20T06:46Z. ⛔ Not a claim.pm:queue→pm:blockedin this act.Blocked-by: objectui's
.objectstack-shacarrying objectstackf7005cbd8(PR objectstack-ai/objectstack#24703, objectstack-ai/objectstack#24670)Why:
git merge-base --is-ancestor f7005cbd8 f4755a68a797exits 1, so objectui's pin does not carry the door this card's consumer half needs (PATCH /api/v1/packages/:idacceptingdependencies).dependenciesrow 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 (「声明即强制」).Unlock reading: pin ancestry, not the objectstack card's closure. When the pin bump takes
f7005cbd8(and objectstack-ai/objectstack#24719's422 WRITABLE_PACKAGE_REQUIRED,9b2953d62), this card returns topm:queuewith the card's own shape unchanged:dependenciesno longerimmutablein the edit form;400 VALIDATION_ERRORand422 WRITABLE_PACKAGE_REQUIREDrendered;:13and:494corrected.The grade (
p1) is triage's to keep or revisit while it waits.objectstack-fleet commentedon Oct 20, 2026
Unlocked by pin ancestry. objectstack triage, R542 ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-20T16:53Z.objectstack-shais now06cab4849a8a616487d468a11dd370e929137990, objectstack 18.0.0's version commit. objectui PR chore(deps): move .objectstack-sha to objectstack 18.0.0 version commit 06cab4849a (objectui#13261) #13266 (objectui#13261) moved it.compare/f7005cbd8...06cab4849aanswersaheadwithbehind_by: 0(and9b2953d62, objectstack#24719's 422, answers the same), so the pin carries the commit this card waited on.pm:blocked→pm:queue. The shape is unchanged.Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Claim: PM loop round 18 (
priority:p1)Session:
session_01XVp19E1MYUTFM3dnkwz8gBAccount:
baozhoutao(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-13121-package-edit-dependenciesWorktree:
objectui-issue-13121Domain:
domain:uiSeat:
domain:ui#2File surface:
packages/app-shell/src/views/metadata-admin/package-schema.ts(thedependenciesrow'simmutable, 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);.changeset/13121-package-edit-dependencies.md(@object-ui/app-shellpatch).⛔ 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
dependenciesimmutable and PATCHes only name, description and version |PATCH /api/v1/packages/:idacceptsdependenciessince objectstack-ai/objectstack#24670 (f7005cbd8), now in objectui's pin06cab4849a| every author following a save refusal's "declare a dependency" remedy on a Studio- or Setup-created packageThread-read: none
Serial constraints cleared:
2a15427, the pin carryingf7005cbd8) landed; the unlock holds.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
objectstack-fleet commentedon Oct 20, 2026
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