Skip to content

metadata forms: one row each for object.access, object.highlightFields, object.requiredPermissions, object.searchableFields and permission.adminScope (#19332 flight G1a) #20349

Description

@objectstack-fleet

Part of #19332 — flight G1a of ruling 5861442317 (batch #229 item 3, letter A, maintainer 「同意」).

Filed by the domain:spec seat 4 (session_01CiCTczDo7tGhafXjf61dUJ, seat post #18917). It is an in-scope sub-issue of an in-flight card, so it inherits the parent's domain:spec and priority:p2. The parent carries the ledger flight (claim 5861529325). This card exists so that flight G1a can run beside the ledger flight under its own claim.

What

An author who opens the Studio form for an object or a permission set cannot see or set five live settings that the platform honours once they are written in code. Each gets one form row, mirroring a row a registered form already has, with the four-locale catalogue rows in the same PR.

key form
object.access packages/spec/src/data/object.form.ts
object.highlightFields object.form.ts
object.requiredPermissions object.form.ts
object.searchableFields object.form.ts
permission.adminScope packages/spec/src/security/permission.form.ts

The ruling, quoted (G1)

G1 (21 keys …) — one form row each, mirroring a row a registered form already has (code/expression, json, string-tags, composite, textarea, plain), with the four-locale catalogue rows in the same PR. Union-typed values take json, never string-tags (which reads a stored map as an empty array and overwrites it); field-name lists are free text and a misspelling is refused loudly at parse.

Execution parameters: G1 and G2 land as form-row flights (G1: object + permission, then field + action; …) … Every flight is Clause-②: no (form face and ledger text). Confidence gaps carried: action.description's authors NOT MEASURED; no browser run of the objectui repeater face …

The objectui widget bounds (string-tags reads a non-array as []; field-multi binds nothing on an object draft) are the dev's reading at the .objectui-sha pin and are carried as the premise the first flight re-checks.

This is the first form flight, so it re-checks that premise.

Acceptance

Order

G1b (field.* and action.*, 16 keys) follows this flight. G2's two flights and #19333 item 2 follow as the parent's ruling orders them.

Dedupe words: metadata form row object.access highlightFields searchableFields · permission.adminScope form row

Activity

  1. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01CiCTczDo7tGhafXjf61dUJ
    Account: os-sales (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-20349-g1a-object-permission-rows
    Worktree: objectstack-issue-20349
    Domain: domain:spec
    Seat: domain:spec#4 (seat post #18917)
    File surface:

    Ruling carried: 5861442317 · batch #229 item 3 · letter A · maintainer 「同意」 (G1, quoted in this card's body). This is the first form flight, so it re-checks the ruling's carried premise on objectui's widget bounds at the .objectui-sha pin.

  2. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Release: clock-out, round stopped before its PR

    domain:spec seat 4 (session_01CiCTczDo7tGhafXjf61dUJ), 2026-09-28T03:31Z. Clock-out on the maintainer's word in the seat session, verbatim: 「当前任务处理完,合并后就下班」, then 「快没token了」. The dev run was stopped mid-round. Only the pushed branch head below counts; nothing local survives. pm:dispatched → pm:queue in this act, with os-sales unassigned. The next claimant re-claims under the full protocol and re-measures on the day's main.

    State. The branch is claude/issue-20349-g1a-object-permission-rows, remote head bc1d395d3. There is no PR yet. When stopped, the dev was updating the platform-objects echo-decision pins, after the five rows and the catalogues. Its completeness and its re-check of the ruling's objectui widget-bound premise are NOT MEASURED; read the branch against claim 5861551344.

    Next. Finish the flight:

    The later flights stay as the parent's ruling 5861442317 orders them: G1b, then G2a and G2b.

    domain:spec seat 4 · #18917 · session_01CiCTczDo7tGhafXjf61dUJ


    Generated by Claude Code

  3. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01ARcDurZ5j34RdqsGgc4jgH
    Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-20349-g1a-object-permission-rows
    Worktree: objectstack-issue-20349
    Domain: domain:spec
    Seat: domain:spec#4 (seat post #18917)
    Ruling-ref: 5861442317
    File surface: the surface of the released claim 5861551344, continued from the branch's pushed head bc1d395d3 (release 5862816545). The branch is re-used; its commits are UNVERIFIED hand-over, re-read hunk by hunk.

    Ruling carried: 5861442317 · batch #229 item 3 · letter A · maintainer 「同意」: G1 rows, the objectui widget-bound premise re-checked in this first form flight, Clause-②: no.

    domain:spec seat 4 · #18917 · session_01ARcDurZ5j34RdqsGgc4jgH


    Generated by Claude Code

  4. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 20349,
      "status": "done",
      "branch": "claude/issue-20349-g1a-object-permission-rows",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/20405",
      "session": "session_01ARcDurZ5j34RdqsGgc4jgH (subagent run; the parent PM session's id, as CLAUDE_CODE_REMOTE_SESSION_ID resolves it)",
      "premise_still_valid": true,
      "summary": "Resumed branch head bc1d395d3 into worktree objectstack-issue-20349, reread every hunk and reverified it all. object.form.ts now has one row each for highlightFields and searchableFields (string-tags, in Basics), access (a composite over a declared default select) and requiredPermissions (json, the union), both in Advanced. permission.form.ts has one json row for adminScope. The four-locale catalogue rows are in, and the platform-objects echo pins are updated. Hand-over, per acceptance item. The five rows (7ce01726): complete, kept; every help-text claim was checked against its runtime reader. Catalogue rows and re-extract (3820f4a7, 3ae44a78): complete, kept; after the merge, check:i18n reports all 9 packages in sync, so the catalogues regenerate byte-for-byte. Echo pins (abbf9c7f): already complete; the platform-objects suite is green with no further pin edit. Changeset: half-done; it lacked the Clause-② line, and this run added it (353e708a). Merge: origin/main 15bf186f5 merged with os-regen-merge.sh as e505f724; no conflict, and check:generated is green with no regeneration. Ruling premise, re-checked by reading objectui f8a9d0fb0 source (no browser): both halves HOLD. widgets.tsx:1290 reads a non-array as an empty array, and add/remove write it back. ResourceEditPage.tsx:889-893 takes the field catalogue from interfaceConfig.source, data.object, object or objectName, and the object type declares none of the four. Residue, measured with the reconciliation test's own helper block: 28 at 15bf186f5, 23 on the head src; exactly the five keys removed and none added. Assumption 3 confirmed. Draft PR #20405 is open. CI was in progress when this report was written.",
      "tests": "All through scripts/pm/os-verify-lock.sh (slot issue-20349), each VERDICT command-exit 0. For the two wrapper scripts, each inner exit was recorded separately, and all were 0. Commands and their real lines: pnpm --filter @objectstack/spec test = 'Test Files 557 passed (557) / Tests 16497 passed | 1 todo (16498)'. pnpm --filter @objectstack/spec test:repo = 'Test Files 35 passed (35) / Tests 634 passed (634)'. pnpm --filter @objectstack/platform-objects test = 'Test Files 55 passed (55) / Tests 911 passed (911)'. pnpm --filter @objectstack/spec typecheck: exit 0 (check:test-typecheck OK: 53 files, 255 errors, 142 signatures held by the ledger). pnpm --filter @objectstack/platform-objects typecheck: exit 0 (1 file, 3 errors, 2 signatures held). Downstream readers of the form registry: lint src/validate-predicate-path-refs.test.ts = 1 file, 54 tests passed; cli unit test/i18n-coverage.test.ts = 1 file, 20 tests passed. Builds: spec build exit 0; the i18n closure build (turbo, cli + 9 packages) = 'Tasks: 59 successful, 59 total'. pnpm check:i18n: 'check-i18n-bundles: OK (9 package(s) — all bundles in sync, no undeclared authoring keys)'. spec check:generated: 'All 15 generated artifacts are up to date'. Residue probe: the reconciliation test file copied whole, plus one appended probe block; scratch only, never committed. Before tree = 15bf186f5; after tree = the same tree with object.form.ts and permission.form.ts restored from 353e708a (git diff vs 353e708a over packages/spec/src = 0 lines). Each probe run: 1 file, 58 tests passed. Lit control field.accept was present in both; dark control object.zzFabricated20349 was absent in both. No ablation: no guard or gate was added.",
      "mcp_calls": "0 — no MCP GitHub tool was called",
      "api_writes": "3 — all through the fleet-write relay (repository_dispatch, executed as objectstack-fleet[bot]): (1) pr_create = POST /repos/objectstack-ai/objectstack/pulls (draft; relay run 36393424556, success); (2) label-write assign = POST /repos/objectstack-ai/objectstack/issues/20405/assignees [os-warren] (relay run 36393508455, success; read-back matches); (3) this os-dev-report comment = POST /repos/objectstack-ai/objectstack/issues/20349/comments. Plus 2 git pushes (e505f724, 353e708a), which are not REST. Reads were direct REST GETs only.",
      "gates": {
        "derived_by": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 353e708a (identical to the list derived at e505f724)",
        "derived": 85,
        "ran": 85,
        "exit_nonzero_final": 0,
        "not_measured": 0,
        "unrun": 0,
        "ran_verdict": "✓ dispatch-gates --ran: 85 derived famil(ies) accounted for — 85 run, 0 NOT-MEASURED (a DERIVED zero — all 85 recorded an exit code and none of them is 3).",
        "first_run_nonzero": [
          "pnpm check:dual-build-cjs-loads :: exit 3 (PREREQUISITE NOT MET: nine packages had no dist/). Rerun on the same tree once the dist/ directories existed :: exit 0, '104 published require entry point(s) across 66 package(s) load'. The ran.list records the rerun's code."
        ],
        "partial_notes": [
          "pnpm --filter @objectstack/spec run check:entry-nameability exit 0, printing its standing 'NOT MEASURED: no callable export on @objectstack/spec/api-assembled, @objectstack/spec/qa'. That line is independent of this diff."
        ],
        "ci_at_report": "head 353e708a: 32 check runs — 12 success, 3 skipped, 17 in_progress, 0 failure"
      },
      "line_budget": {
        "changed_lines": 188,
        "additions": 182,
        "deletions": 6,
        "files": 9,
        "human_merge_threshold": 5000,
        "verdict": "under",
        "skills_budget": "n/a — no skills/** path"
      },
      "files_changed": [
        ".changeset/20349-object-permission-form-rows.md",
        "packages/platform-objects/src/apps/translations/en.metadata-forms.generated.ts",
        "packages/platform-objects/src/apps/translations/es-ES.metadata-forms.generated.ts",
        "packages/platform-objects/src/apps/translations/ja-JP.metadata-forms.generated.ts",
        "packages/platform-objects/src/apps/translations/zh-CN.metadata-forms.generated.ts",
        "packages/platform-objects/src/apps/translations/object-collapsed-sections-echo-decisions.test.ts",
        "packages/platform-objects/src/apps/translations/object-lifecycle-panel-echo-decisions.test.ts",
        "packages/spec/src/data/object.form.ts",
        "packages/spec/src/security/permission.form.ts"
      ],
      "deviations": [
        "Worktree created from the remote branch, with no empty-branch push, as the dispatch ordered (rule-1 deviation by order).",
        "The residue probe ran in a second scratch worktree at 15bf186f5, not in the issue worktree. The after-tree was that worktree with the two form files restored from 353e708a. This kept the gate run's change set free of untracked files. The worktree was removed cleanly afterwards.",
        "check:dual-build-cjs-loads is recorded in ran.list with its rerun exit 0; its first run exited 3 (prerequisite)."
      ],
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: #19333 item 2 (the zodOnly wiring; edits metadata-form-zod-reconciliation.test.ts) · noted, not filed — a dark-control comment there reads 'object.access is authorable and no form offers it', and that is stale after this PR. Its assertions (ruled-class admission) still hold. The file is the ledger, which is outside this flight's surface.",
        "carrier: #19333 item 2 · noted, not filed — nothing pins the ruling's 'union values never take string-tags' across the registry. A future edit could flip requiredPermissions back to string-tags with no test turning red. Not a defect today.",
        "carrier: 承接者:无 · noted, not filed — objectui's nested-form face cannot unset an object key. Once adminScope is touched, clearing every sub-field leaves an empty object, and the parse refuses it loudly (businessUnit is required). Loud, generic to every nested-form row.",
        "carrier: PM (ruling text) · noted, not filed — the ruling says a misspelt field-name entry 'is refused loudly at parse'. It is refused at the object publish door and by os validate: validateObjectFieldRefs and validateSearchableFields at error, runtimeTypes including object. The Zod parse does not judge field names. The changeset and the PR body say so."
      ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: ACCEPT · PR #20405 at head 353e708aa7808c39a649d8254cf2895a59f9f648 · 2026-09-28T08:21Z

    domain:spec seat 4 (session_01ARcDurZ5j34RdqsGgc4jgH), reviewer of record under claim 5864511529. The readings below were taken on GitHub or on the tree by this seat.

    check reading
    Shape Draft, base main. Body line 1 Fixes #20349; line 2 names the parent without a closing verb (Flight G1a of #19332); Clause-②: no stands alone.
    Scope 9 files, +182/−6: two form files, four generated catalogues, two echo-decision pins, the changeset. It matches the claim.
    Changeset @objectstack/spec minor and @objectstack/platform-objects patch, Clause-②: no, on the #19673 (408ca2e36) precedent. Its prose correctly places the misspelt-field-name refusal at the publish door and os validate, not at the Zod parse.
    Contract review At-tier record PASS 5866196177, same head. It checks every row's widget against its schema shape and the ruling (requiredPermissions, the one union, takes json), and every help-text claim against its runtime reader. It re-read the objectui widget premise at the pin (both halves hold), and derives the reconciliation residue 28 → 23 exactly.
    CI at this head 32 success, 3 skipped, all on the roster (check-expected-skips.mjs --pr 20405, exit 0). mergeable_state: clean. origin/main is 6 commits past the merge base and touches none of this PR's files, so the generated catalogues need no re-sync.
    Governed / size Not governed, 188 changed lines.

    Out-of-scope findings:

    Landing next: ready + auto-merge through the relay. At MERGED, this card closes by Fixes, and #19332's G1b becomes the next flight.

    domain:spec seat 4 · #18917 · session_01ARcDurZ5j34RdqsGgc4jgH


    Generated by Claude Code

  6. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #20405 → main 7db1332f19e8c4fabbed1f0cb3d62e577e4295bb · 2026-09-28T08:47Z

    domain:spec seat 4 (session_01ARcDurZ5j34RdqsGgc4jgH), landing record for claim 5864511529. ACCEPT 5866208907 on the at-tier PASS 5866196177. Queue path: ready at 08:21Z, added_to_merge_queue at 08:23Z, merged at 08:46Z.

    domain:spec seat 4 · #18917 · session_01ARcDurZ5j34RdqsGgc4jgH


    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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions