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
spec: ActionParam carry-over declaration — carried from the row, rendered read-only, submitted verbatim (#11753 ruling, spec half) #11992
Spec half of the #11753 ruling (maintainer, 2026-08-25, verbatim 「同意」 on recommendation A; full record = #11753 comment 5404887360). Filed by PM session session_01KWRU3s15AJz7PGW7a7wdCh per the confirmed checklist. Parent: #11753 (tracking).
Pre-measurements FIRST — both named by the parent card, and they gate the design:
Sweep every shipped action's defaultFromRow params bound to JSON-serialized columns — the population this key serves. Report identities, not counts.
Content: add the authorable key to ActionParamSchema (packages/spec/src/ui/action.zod.ts) expressing carry this value through: seed from the row, render as a non-editable summary, submit verbatim. Naming/shape is this leg's design. Measured constraint from the parent: visible is NOT the answer — it omits the param from submission entirely. Exemplar usage: the five clone_permission_set facet params in packages/plugins/plugin-security/src/objects/sys-permission-set.object.ts declare the key.
Discipline: Clause-②: yes (widens the authorable public surface) — contract-review tier; ⛔ spec seat only (packages/spec sole owner; the plugin-security exemplar edit rides the same PR or splits per the seat's judgment).
Acceptance criterion: the schema accepts the new key; the five clone params declare it; a pin asserts a declared carry-over param is still submitted verbatim (#11703's pin 6 — the send-side contract — stays green).
Downstream: the objectui renderer leg is Blocked-by: this card. Cross-repo unlock criterion: the consumer repo must be able to install the change (objectui refresh/pin flow picks it up), not merely see it merged.
Claim: PM loop round R8, wave 5 — ruled spec half of #11753 (maintainer 2026-08-25, verbatim 「同意」 on recommendation A; full record = #11753 comment 5404887360)
Session: session_012xGvxcwPRTJfA7RfjXEYA4
Branch: claude/issue-11992-actionparam-carryover-key
Worktree: objectstack-issue-11992
Domain: domain:spec
File surface: packages/spec/src/ui/action.zod.ts (the carry-over authorable key, name/shape = this leg's design), packages/plugins/plugin-security/src/objects/sys-permission-set.object.ts (the five clone_permission_set exemplar params declare it — riding the same PR per the card's option), tests incl. the #11703 pin-6 stay-green assertion, generated baselines the gates demand, one changeset. Pre-measurements FIRST per the card (objectui ActionParamDialog render feasibility — read-only cross-repo measurement in the local objectui checkout; defaultFromRow-on-JSON-columns population sweep, identities not counts). Stop conditions: renderer surgery needed ⇒ stop and report (fallback B is #11753's to decide, never taken silently).
Container & model: M, mode:subagent, model: claude-fable-5 — clause-② per the card's own discipline line (widens the authorable public surface, contract-review tier); path limb also fires
Clause-②: yes
Serial constraints cleared: batch sibling #12007 (kernel/cli-extension.zod.ts + ADR-0087 registries) — disjoint files. Landing-watch PRs #12611 (contracts + error-code-ledger) and #12612 (identity/eval-user.zod.ts + plugin-security/objects/default-permission-sets.*) — disjoint files; note #12612 touches the SAME plugin-security objects/ directory, different file — merge current origin/main immediately before PR and re-merge if #12612 lands mid-flight. Parked PR #12606 (data/object.zod.ts) disjoint. H17 — no intersection. Downstream objectui renderer leg unlocks on consumer-installable (pin/refresh), not on merge — recorded for the unlock scan.
Dev claim: running as mode:subagent inside PM session session_012xGvxcwPRTJfA7RfjXEYA4 (R8 wave 5, per PM claim comment 5430643723).
Branch: claude/issue-11992-actionparam-carryover-key
Worktree: objectstack-issue-11992
Plan: pre-measurements first (objectui ActionParamDialog read-only-summary feasibility — read-only measurement in the local objectui checkout, zero objectui edits; defaultFromRow-on-JSON-columns population sweep, identities); then the authorable carry-over key on ActionParamSchema (packages/spec/src/ui/action.zod.ts), the five clone_permission_set facet params in packages/plugins/plugin-security/src/objects/sys-permission-set.object.ts declaring it, pins (key parse + describe; #11703 pin 6 stays green untouched), generated baselines, one changeset. Stop conditions honoured: renderer surgery needed ⇒ needs_decision (fallback B is #11753's to decide). Draft PR only (Clause-② contract-review tier).
{
"issue": 11992,
"status": "done",
"branch": "claude/issue-11992-actionparam-carryover-key",
"pr": "https://github.com/objectstack-ai/objectstack/pull/12614",
"premise_still_valid": true,
"summary": "Both pre-measurements pass and gate the design as dispatched. (1) objectui ActionParamDialog CAN carry a read-only-summary render for a param it still submits, no renderer surgery: resolveActionParams seeds defaultFromRow into defaultValue, the dialog seeds its values state from it, and submit serializes from STATE not DOM - so fallback B not taken. (2) Population sweep by identity: the ONLY shipped defaultFromRow params bound to JSON-serialized columns are the five clone_permission_set facets (object_permissions, field_permissions, system_permissions, row_level_security, tab_permissions - Field.textarea, written via JSON.stringify by permissionSetRowFields); all other shipped defaultFromRow params (sys_position.description, sys_account.accountId, sys_invitation.email/role, sys_member.role, sys_oauth_application.client_id x4, sys_organization.name/slug/logo, sys_sso_provider.providerId/domain, sys_team_member.teamId/userId, sys_team.name, sys_user.name/image) bind scalar columns. Implemented: ActionParamSchema.carryOver (closed optional boolean; describe() states all three ruled semantics: seed from row, non-editable summary render, verbatim submission; contrast with visible:false stated), parse-time refine requiring defaultFromRow:true alongside (message names the repair and bodyExtra alternative), aliases readonly/disabled pointing at carryOver, exemplar declarations on the five facet params (description stays editable - prose, not a facet), generated baselines (authorable-surface ui.json + reference docs) regenerated, changeset spec:minor + plugin-security:patch declared per the onSuccess and 11703 precedents. Branch merged current origin/main AFTER landing-watch 12612/12611 landed (disjoint files, clean merge); draft PR at head 3986bafea, clause-2 tier, left DRAFT.",
"tests": "All at final head 3986bafea after spec rebuilt at that head (check-dts-emitted 34/34). Spec pins: vitest run src/ui/action-param-carryover.test.ts + src/shared/alias-integrity.test.ts + src/ui/action-on-success.test.ts, verdict line 'Tests 48 passed (48)'. plugin-security pins: clone-carryover.test.ts + packaged-permission-set-lock.test.ts (11703 pin 6 untouched) + rbac-objects.test.ts, verdict line 'Tests 46 passed (46)'. Typechecks both packages exit 0; spec test program coverage proven by tsc -p tsconfig.test.json --listFiles counting the new test file (1 hit). Reverse verification from committed state, expected direction declared first (RED): observed tsc GREEN - the compile-time gate does not police this surface (tests excluded from tsconfig, no excess-property check on the action literals) - while the strict-parse gate went RED exactly as required: planted carryOverX (mutation proven on disk by anchored grep 0 to 1) failed clone-carryover.test.ts at module load with unrecognized_keys naming carryOverX and suggesting carryOver; restored via git checkout HEAD -- with absolute path, proven by empty git diff HEAD plus grep 0. Gate union derived at 3986bafea via node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack: 45 path-derived + convention families all exit 0 with their own verdict lines (check:authorable-surface, check:generated 'All 14 generated artifacts are up to date', check:liveness green with NO ledger edit - action/params is a RECORDED undrilled container, check:i18n 'OK (9 packages)' after building @objectstack/cli, check:skill-examples '260 prose examples type-check' after building client-react, check:nul-bytes OK, engine-double-contract, where-matcher, cross-package-test-inputs, type-check-coverage structural half, alias/docs/changeset families). Two DECLARED narrowings: check:type-check-debt --re-measure refuses on this worktree (39 deps of OTHER ledger entries unbuilt - designed refusal, NOT MEASURED not red); narrowed measurement: the only entry this diff can move is TEST_DEBT plugin-security, and with tests included in that package's tsconfig program the error count is 13 with and 13 without the new test file (zero lines name it) - delta 0, no upward drift possible; additionally the spec d.ts change is an additive optional key (can only remove excess-property errors). check-dev-prereqs: prerequisite not met (11 unrelated packages studio/connectors unbuilt; it measures checkout build state, not this diff; CI lint builds the workspace first). All verdicts quoted from gate-printed lines, exit codes captured before any pipe.",
"mcp_calls": "4 - claim comment, create PR, PR body readback, this report comment. All card/parent reads via the zero-quota public-page payload channel; no search calls (no issue filed).",
"open_questions": [],
"out_of_scope_findings": ["NOT FILED (this dispatch bars label writes, and the observation class wants the finding label - handing to PM to file): tsc does not police unknown keys on plugin action-param literals - planting carryOverX: true in sys-permission-set.object.ts passed plugin-security typecheck clean (measured 2026-08-26 at head 3986bafea); the enforcement that DOES catch it is ActionParamSchema strict parse at ObjectSchema.create module load (observed red with the alias suggestion). Observation-class typing looseness, mitigated wherever object modules are parse-validated at import; evidence in PR 12614's verification section."]
}
ACCEPT — reviewer of record: spec seat R8, session_012xGvxcwPRTJfA7RfjXEYA4. PR: #12614 (draft, head 3986bafe, 7 files).
Checked against the PR itself: both dispatch-mandated pre-measurements delivered and load-bearing — (1) objectui's ActionParamDialog submits from STATE not DOM, so a read-only render needs no renderer surgery (fallback B correctly not taken, not silently); (2) the JSON-column defaultFromRow population is exactly the five clone facets, by identity. The key design is sound and ruled-shape-faithful: carryOver closed optional boolean; parse-time refine requires defaultFromRow: true with a refusal message that carries the repair AND the bodyExtra alternative; readonly/disabled aliases land on the strict-unknown-key path naming carryOver (pinned); describe() states all three ruled semantics plus the visible: false contrast (pinned by a graph-walking describe test). Exemplar declares the five facets with description pinned as the deliberate non-member — boundary from both sides. #11703 pin 6 (send-side) untouched and green. Reverse verification honest in an unusual direction: tsc stayed GREEN (the compile layer does not police this surface — see the finding below) while the strict-parse gate went red naming the planted key. Generated action.mdx (3 tables) + authorable-surface/ui.json row regenerated; changeset spec:minor + plugin-security:patch with the ADR-0087 not-required annotation reasoned in place. Docs-drift's flagged page (permissions/authorization.mdx, anchored via the facet-name literals) is not falsified — this diff changes dialog rendering contract, not permission semantics.
The dev's out-of-scope observation (tsc does not police unknown keys on plugin action-param literals; enforcement lives in the strict parse at ObjectSchema.create module load) is filed by this seat as a finding card in the same stroke — the dev's dispatch barred label writes, so the filing lands here per the handoff.
Clause-② enqueue gate: path + declaration limbs fire; dispatch tier claude-fable-5 = CONTRACT_REVIEW_TIER — satisfied. Landing path: ready → merge queue once every check on 3986bafe is green; downstream objectui renderer leg unlocks on consumer-installable, per the claim.
Activity
os-zhuang commentedon Aug 26, 2026
Claim: PM loop round R8, wave 5 — ruled spec half of #11753 (maintainer 2026-08-25, verbatim 「同意」 on recommendation A; full record = #11753 comment 5404887360)
Session:
session_012xGvxcwPRTJfA7RfjXEYA4Branch:
claude/issue-11992-actionparam-carryover-keyWorktree:
objectstack-issue-11992Domain:
domain:specFile surface:
packages/spec/src/ui/action.zod.ts(the carry-over authorable key, name/shape = this leg's design),packages/plugins/plugin-security/src/objects/sys-permission-set.object.ts(the fiveclone_permission_setexemplar params declare it — riding the same PR per the card's option), tests incl. the #11703 pin-6 stay-green assertion, generated baselines the gates demand, one changeset. Pre-measurements FIRST per the card (objectuiActionParamDialogrender feasibility — read-only cross-repo measurement in the local objectui checkout;defaultFromRow-on-JSON-columns population sweep, identities not counts). Stop conditions: renderer surgery needed ⇒ stop and report (fallback B is #11753's to decide, never taken silently).Container & model: M,
mode:subagent,model: claude-fable-5— clause-② per the card's own discipline line (widens the authorable public surface, contract-review tier); path limb also firesClause-②: yes
Serial constraints cleared: batch sibling #12007 (kernel/cli-extension.zod.ts + ADR-0087 registries) — disjoint files. Landing-watch PRs #12611 (contracts + error-code-ledger) and #12612 (identity/eval-user.zod.ts + plugin-security/objects/default-permission-sets.*) — disjoint files; note #12612 touches the SAME plugin-security objects/ directory, different file — merge current
origin/mainimmediately before PR and re-merge if #12612 lands mid-flight. Parked PR #12606 (data/object.zod.ts) disjoint. H17 — no intersection. Downstream objectui renderer leg unlocks on consumer-installable (pin/refresh), not on merge — recorded for the unlock scan.Generated by Claude Code
os-zhuang commentedon Aug 26, 2026
Dev claim: running as
mode:subagentinside PM sessionsession_012xGvxcwPRTJfA7RfjXEYA4(R8 wave 5, per PM claim comment 5430643723).Branch:
claude/issue-11992-actionparam-carryover-keyWorktree:
objectstack-issue-11992Plan: pre-measurements first (objectui
ActionParamDialogread-only-summary feasibility — read-only measurement in the local objectui checkout, zero objectui edits;defaultFromRow-on-JSON-columns population sweep, identities); then the authorable carry-over key onActionParamSchema(packages/spec/src/ui/action.zod.ts), the fiveclone_permission_setfacet params inpackages/plugins/plugin-security/src/objects/sys-permission-set.object.tsdeclaring it, pins (key parse + describe; #11703 pin 6 stays green untouched), generated baselines, one changeset. Stop conditions honoured: renderer surgery needed ⇒ needs_decision (fallback B is #11753's to decide). Draft PR only (Clause-② contract-review tier).Generated by Claude Code
Generated by Claude Code
feat(spec): ActionParamSchema.carryOver — seeded from the row, render…
os-zhuang commentedon Aug 26, 2026
os-dev-report
{ "issue": 11992, "status": "done", "branch": "claude/issue-11992-actionparam-carryover-key", "pr": "https://github.com/objectstack-ai/objectstack/pull/12614", "premise_still_valid": true, "summary": "Both pre-measurements pass and gate the design as dispatched. (1) objectui ActionParamDialog CAN carry a read-only-summary render for a param it still submits, no renderer surgery: resolveActionParams seeds defaultFromRow into defaultValue, the dialog seeds its values state from it, and submit serializes from STATE not DOM - so fallback B not taken. (2) Population sweep by identity: the ONLY shipped defaultFromRow params bound to JSON-serialized columns are the five clone_permission_set facets (object_permissions, field_permissions, system_permissions, row_level_security, tab_permissions - Field.textarea, written via JSON.stringify by permissionSetRowFields); all other shipped defaultFromRow params (sys_position.description, sys_account.accountId, sys_invitation.email/role, sys_member.role, sys_oauth_application.client_id x4, sys_organization.name/slug/logo, sys_sso_provider.providerId/domain, sys_team_member.teamId/userId, sys_team.name, sys_user.name/image) bind scalar columns. Implemented: ActionParamSchema.carryOver (closed optional boolean; describe() states all three ruled semantics: seed from row, non-editable summary render, verbatim submission; contrast with visible:false stated), parse-time refine requiring defaultFromRow:true alongside (message names the repair and bodyExtra alternative), aliases readonly/disabled pointing at carryOver, exemplar declarations on the five facet params (description stays editable - prose, not a facet), generated baselines (authorable-surface ui.json + reference docs) regenerated, changeset spec:minor + plugin-security:patch declared per the onSuccess and 11703 precedents. Branch merged current origin/main AFTER landing-watch 12612/12611 landed (disjoint files, clean merge); draft PR at head 3986bafea, clause-2 tier, left DRAFT.", "tests": "All at final head 3986bafea after spec rebuilt at that head (check-dts-emitted 34/34). Spec pins: vitest run src/ui/action-param-carryover.test.ts + src/shared/alias-integrity.test.ts + src/ui/action-on-success.test.ts, verdict line 'Tests 48 passed (48)'. plugin-security pins: clone-carryover.test.ts + packaged-permission-set-lock.test.ts (11703 pin 6 untouched) + rbac-objects.test.ts, verdict line 'Tests 46 passed (46)'. Typechecks both packages exit 0; spec test program coverage proven by tsc -p tsconfig.test.json --listFiles counting the new test file (1 hit). Reverse verification from committed state, expected direction declared first (RED): observed tsc GREEN - the compile-time gate does not police this surface (tests excluded from tsconfig, no excess-property check on the action literals) - while the strict-parse gate went RED exactly as required: planted carryOverX (mutation proven on disk by anchored grep 0 to 1) failed clone-carryover.test.ts at module load with unrecognized_keys naming carryOverX and suggesting carryOver; restored via git checkout HEAD -- with absolute path, proven by empty git diff HEAD plus grep 0. Gate union derived at 3986bafea via node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack: 45 path-derived + convention families all exit 0 with their own verdict lines (check:authorable-surface, check:generated 'All 14 generated artifacts are up to date', check:liveness green with NO ledger edit - action/params is a RECORDED undrilled container, check:i18n 'OK (9 packages)' after building @objectstack/cli, check:skill-examples '260 prose examples type-check' after building client-react, check:nul-bytes OK, engine-double-contract, where-matcher, cross-package-test-inputs, type-check-coverage structural half, alias/docs/changeset families). Two DECLARED narrowings: check:type-check-debt --re-measure refuses on this worktree (39 deps of OTHER ledger entries unbuilt - designed refusal, NOT MEASURED not red); narrowed measurement: the only entry this diff can move is TEST_DEBT plugin-security, and with tests included in that package's tsconfig program the error count is 13 with and 13 without the new test file (zero lines name it) - delta 0, no upward drift possible; additionally the spec d.ts change is an additive optional key (can only remove excess-property errors). check-dev-prereqs: prerequisite not met (11 unrelated packages studio/connectors unbuilt; it measures checkout build state, not this diff; CI lint builds the workspace first). All verdicts quoted from gate-printed lines, exit codes captured before any pipe.", "mcp_calls": "4 - claim comment, create PR, PR body readback, this report comment. All card/parent reads via the zero-quota public-page payload channel; no search calls (no issue filed).", "open_questions": [], "out_of_scope_findings": ["NOT FILED (this dispatch bars label writes, and the observation class wants the finding label - handing to PM to file): tsc does not police unknown keys on plugin action-param literals - planting carryOverX: true in sys-permission-set.object.ts passed plugin-security typecheck clean (measured 2026-08-26 at head 3986bafea); the enforcement that DOES catch it is ActionParamSchema strict parse at ObjectSchema.create module load (observed red with the alias suggestion). Observation-class typing looseness, mitigated wherever object modules are parse-validated at import; evidence in PR 12614's verification section."] }Generated by Claude Code
Generated by Claude Code
os-zhuang commentedon Aug 26, 2026
ACCEPT — reviewer of record: spec seat R8,
session_012xGvxcwPRTJfA7RfjXEYA4. PR: #12614 (draft, head3986bafe, 7 files).Checked against the PR itself: both dispatch-mandated pre-measurements delivered and load-bearing — (1) objectui's
ActionParamDialogsubmits from STATE not DOM, so a read-only render needs no renderer surgery (fallback B correctly not taken, not silently); (2) the JSON-columndefaultFromRowpopulation is exactly the five clone facets, by identity. The key design is sound and ruled-shape-faithful:carryOverclosed optional boolean; parse-time refine requiresdefaultFromRow: truewith a refusal message that carries the repair AND thebodyExtraalternative;readonly/disabledaliases land on the strict-unknown-key path namingcarryOver(pinned); describe() states all three ruled semantics plus thevisible: falsecontrast (pinned by a graph-walking describe test). Exemplar declares the five facets withdescriptionpinned as the deliberate non-member — boundary from both sides. #11703 pin 6 (send-side) untouched and green. Reverse verification honest in an unusual direction: tsc stayed GREEN (the compile layer does not police this surface — see the finding below) while the strict-parse gate went red naming the planted key. Generatedaction.mdx(3 tables) +authorable-surface/ui.jsonrow regenerated; changeset spec:minor + plugin-security:patch with the ADR-0087 not-required annotation reasoned in place. Docs-drift's flagged page (permissions/authorization.mdx, anchored via the facet-name literals) is not falsified — this diff changes dialog rendering contract, not permission semantics.The dev's out-of-scope observation (tsc does not police unknown keys on plugin action-param literals; enforcement lives in the strict parse at
ObjectSchema.createmodule load) is filed by this seat as afindingcard in the same stroke — the dev's dispatch barred label writes, so the filing lands here per the handoff.Clause-② enqueue gate: path + declaration limbs fire; dispatch tier
claude-fable-5=CONTRACT_REVIEW_TIER— satisfied. Landing path: ready → merge queue once every check on3986bafeis green; downstream objectui renderer leg unlocks on consumer-installable, per the claim.Generated by Claude Code
feat(spec): ActionParamSchema.carryOver — seeded from the row, render…
test(spec): the first ui/ file group's test titles state each cited d…