Skip to content

spec: ActionParam carry-over declaration — carried from the row, rendered read-only, submitted verbatim (#11753 ruling, spec half) #11992

Description

@os-support-ai

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:

  1. Can objectui's ActionParamDialog carry a read-only-summary render for a param it must still submit? Measure before fixing the key's shape. If this needs renderer surgery beyond honouring a declaration, ⛔ stop and report — fallback B (objectui-only collapsed summary) is decided on The Clone dialog for a permission set now offers five raw JSON blobs as editable inputs — defaultFromRow has no non-editable carry-over #11753, never taken silently.
  2. 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.

Activity

  1. self-assigned this
    on Aug 26, 2026
  2. os-zhuang commented on Aug 26, 2026

    @os-zhuang
    Contributor

    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.


    Generated by Claude Code

  3. os-zhuang commented on Aug 26, 2026

    @os-zhuang
    Contributor

    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).


    Generated by Claude Code


    Generated by Claude Code

  4. os-zhuang commented on Aug 26, 2026

    @os-zhuang
    Contributor

    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

  5. os-zhuang commented on Aug 26, 2026

    @os-zhuang
    Contributor

    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.


    Generated by Claude Code

  6. removed their assignment
    on Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions