Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

approvals face 2 of 5 (ruling C on objectui#12438): the served sys_approval_request page shows the declared amount and a payload summary with declared labels, field faces and hidden-field trimming, as the inbox side sheet does #12483

Closed

Description

@objectstack-fleet

Filing gate ④: a cross-layer coordination node, filed as ruling 6190549995 on objectui#12438 directs (letter C, the maintainer's 「C (推荐)」, director seat summon #42, items 2–4). It is face 2 of at most 5, second in the ruling's order by pull: "declared amount and payload summary (objectui#11677)".

Parent: objectstack-ai/objectstack#25950 (B1 of the epic). The closing card waits on this one.

Blocked-by: #12482

Serial after face 1 (#12482): both edit the same served page, plugin-approvals' sys-approval-request.page.ts, and the ruling orders the faces by pull.

Reader who acts: the domain:ui seat 1 (the epic's seat, seat post #5560). Once face 1 lands, it dispatches step 1 here, the fit check.

Dedupe (MCP search_issues, scope objectstack-ai/objectui, all states, read 2026-10-15T11:50Z): "approval request served page payload summary declared amount hidden field trim record summary" → 3 results:

None of them is this card.

The face

  • The side sheet shows it today, pinned:

    • the request's declared amount;
    • a payload summary with the declared labels, each field drawn through its field type (not raw stored values), and the object's hidden: true fields trimmed.

    The pins are ApprovalsInboxPage.summaryFaces-11677.test.tsx, ApprovalsInboxPage.hiddenFieldTrim.test.tsx and ApprovalsInboxPage.queueHiddenAmount.test.tsx, all under apps/console/src/pages/system/.

  • The served page does not show it. Its highlights drop record_id (sys-approval-request.page.ts:28 at objectstack c5dd7fce30, per the director's delta 6189625854). Its Details tab draws the request's highlightFields since objectui#12433 (PR fix(plugin-detail): a record:details node with no sections and no fields draws the object's highlightFields (objectui#12433) #12441). Neither summarizes the payload against the target object's declared fields.

Steps (ADR-0060 rule 2; the ruling's item 2, "fit before build")

  1. Fit check, objectui. Size the face against the existing generic blocks first:

    • record:details with explicit sections;
    • the record preview card (RecordPreviewCard, epic A2);
    • the field renderers it already uses, with their field-level security fold.

    A new block is opened only if no existing block can carry it. Report which, with the readings.

  2. Spec row (objectstack domain:spec), only if a declared key is needed.

  3. Served page edit (objectstack plugin-approvals, domain:services).

  4. objectui block or wiring, pinned.

Steps 2 and 3 are filed in objectstack, chained with Blocked-by:, only when step 1 says they are needed.

Acceptance

  • On the served page, the declared amount and the payload summary match the sheet's pins: declared labels, type-aware values, and hidden fields trimmed. A field the caller may not read is never drawn.
  • ⛔ The side sheet is not touched (ADR-0060 rule 3).

Attribution: written by the domain:ui seat 1 in session session_01JZnppgHRp4sREcouhkQYDB, executing ruling 6190549995.

Activity

  1. added
    enhancementNew feature or request
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:workflowApprovals and automation — the work that runs without a person driving it
    and removed on Oct 15, 2026
  2. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (face 2 of ruling 6190549995 on objectui#12438; Blocked-by: objectstack-ai/objectui#12482 met, PR #12497 merged as bcf4df0ffb, landing note 6193955609)
    Session: session_01JZnppgHRp4sREcouhkQYDB
    Account: sunhaolin
    Branch: claude/issue-12483-payload-summary
    Worktree: objectui-issue-12483 (in the cloud session's own container)
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: packages/app-shell/src/views/approval-decision/** (the record:approval_decision panel the served page already mounts, as face 1 used it), the existing generic blocks the fit check names if one carries the face (record:details sections / RecordPreviewCard, field renderers with their field-level security fold), the tests beside each, the console's routed-approvals pin directory apps/console/src/services/ for test files only, the ten packages/i18n packs only if a label is added, and one .changeset/12483-*.md. @objectstack/spec, objectstack plugin-approvals' page, ApprovalsInboxPage (the sheet) and any @object-ui/* export are outside the surface (stop on breach; explain in the report)
    Container & model: L, mode:cloud (a cloud session from create_session, per the maintainer's 「后续 objectui 复杂任务可以用云卡片」 / 「云session」, seat post comment 6193043281), model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui names no path-derived mandate). It is sized L because it is a cross-layer face: the fit check may end in a spec-row and plugin-approvals chain.
    Clause-②: no
    Responsibility: n/a — not a defect card
    Thread-read: none
    Serial constraints cleared: read at objectui main 1c3b0699ab. Face 1 (objectui#12482) has landed. No pm:dispatched claim in the lane names approval-decision/** or ApprovalsInboxPage. Faces 3–5 (objectui#12489, #12490, #12491) are Blocked-by this card in turn.

    • Fit before build (the ruling's item 2). Face 1 measured that the served page's bound request row carries what the panel needs, with no prop and no spec row. Face 2's question is the same for the declared amount and the payload summary: can an existing generic block draw them from what the row already carries (payload_display, the target object's declared fields)? If one can, the face is objectui-only. If not, the dev stops and reports the spec-row shape, and the seat files the chain.
    • Why Clause-②: no: the route draws more of what a declared block already reads. A route that needs a type, prop, export or spec change stops and reports.

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Dispatched as a cloud session: session_01ARrv23Gwbz3Qwdivy7Yt9p, titled 「⚡ domain:ui #12483 approvals face 2: amount and payload summary」. Its outcome branch is claude/issue-12483-payload-summary, and it was created from the seat's create_session at 2026-10-15T14:07Z. The claim 6194012467 is its identity. The seat subscribes to the draft PR when it opens, and archives the session when the PR merges or closes. Anyone taking this card over reads the session's liveness from GitHub output first: the branch, the draft PR and the os-dev-report.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    Posted by the domain:ui seat 1 (session_01JZnppgHRp4sREcouhkQYDB) on behalf of the cloud dev session session_01ARrv23Gwbz3Qwdivy7Yt9p. That session pushed claude/issue-12483-payload-summary @ 7f066d7224 but could not write to GitHub. Its relay dispatch was refused by the egress proxy (403), and its GitHub MCP has no create tool. So its report came back as its last session message. The JSON below is that message, verbatim. The draft PR it asks for is #12533, opened by the seat with the dev's own body text.

    {
      "issue": 12483,
      "status": "blocked",
      "branch": "claude/issue-12483-payload-summary",
      "pr": null,
      "session": "session_01ARrv23Gwbz3Qwdivy7Yt9p",
      "premise_still_valid": true,
      "summary": "The work is done and pushed: branch claude/issue-12483-payload-summary @ 7f066d7, 3 commits on main 1c3b0699ab. The face is objectui-only, Clause-②: no. The record:approval_decision panel now draws RecordSnapshotSummary, a new module-internal part in packages/app-shell/src/views/approval-decision/. It shows the declared amount (the first non-zero type:'currency' field, else the first one) and up to 6 snapshot rows, each under its declared label and drawn through the record page's cell, or with payload_display for a resolved reference. Undeclared keys, system columns, unresolved reference ids, hidden:true fields and FLS-refused fields (withoutDeniedFields) are dropped before the cut. It reads the bound row's payload and payload_display, and gets the target definition from useMetadataItem. There is no page edit, prop, spec row or export, and ApprovalsInboxPage is untouched. BLOCKED on the two GitHub writes only. (1) fleet-write/dispatch.mjs pr_create: the dry-run validated, then the live send got POST /repos/objectstack-ai/objectstack/dispatches -> HTTP 403 from the egress proxy ('repository_dispatch is not permitted for this session type'), so nothing ran. post-stamped.mjs rides the same relay. (2) The fallback GitHub MCP in this session has no create_pull_request and no issue-comment create tool. Its only write tool is update_issue_comment, and add_repo access:push surfaced none. Per os-dev I did not switch to gh or curl. The seat needs to open the draft PR (head claude/issue-12483-payload-summary, base main, assignees [sunhaolin], body = pr_body_for_seat below) and post this JSON as the os-dev-report comment on objectstack-ai/objectui#12483. Fit-before-build readings: record:details sections name the bound object's fields, not the target snapshot inside one JSON value, so using them needs a page edit. RecordPreviewCard reads the LIVE target by id and draws its highlightFields; it is already on the page as the record_id pointer card. The panel already holds the row, so it carries the face. A1 holds: payload, payload_display and payload_labels reach the panel on the real RecordDetailView under ApprovalRecordReads; payload_json does not. A2 holds: 0 extra network reads in the usual case (the same metadata-store definition the pointer card reads), at most 1 by-name read, deduplicated; a row with no snapshot asks nothing. A3 holds: the server redacts per reader, and the client fold is pinned on the served page with a counter-probe. A4 is matched by assertion, except the two boundaries in open_questions.",
      "tests": "At d756d98 (head 7f066d7 adds only a README paragraph): one vitest run of 70 files and 1566 tests, all passed, exit 0. It covered approval-decision/, approval-progress/, every approvalRequestsDataSource.* suite, AppContent.approvalRecordReads, all of apps/console/src/pages/system/ (the ApprovalsInboxPage.* pins, run as the CONTROL), RecordApprovalsPanel*, record-preview/, and 24 census and ratchet suites touching the diff's subjects (product-neutral-renderer.ratchet, no-component-any-cast, no-refresh-key-remount, adr0054-ratchet, defaults-maps-mirror-en-pack, writeRefusalCensus-11583, both spec-symbol-parity, spec-symbol-ledger-app-shell-7265, widget-dom-leak-sweep, registry-inputs-spec-parity, record-approval-decision-arm-12342, iconOnlyButtonCensus-12143, ariaLabelLiteralCensus-12145, machineLocaleCensus-9909, dead-pack-keys-retired-8754, check-eager-closure-budget, check-i18n-call-site-keys, check-control-bytes, check-new-cross-file-line-citations, the three check-vi-mock-*, one-authority-per-exported-name-6273). New pins: apps/console/src/services/approvalRequestsDataSource.servedPageSummary-12483.test.tsx (15 tests, the served page copied whole from objectstack 09dd537193 on the real RecordDetailView) and RecordSnapshotSummary.test.tsx. Ablation: the fix was committed first (e104977). ablation-replace.mjs replaced the RecordSnapshotSummary element in ApprovalDecisionPanel.tsx with a marker comment: anchor 1->0, marker 0->1, blob e3a379ef8512 -> 5edf296385bd. Result: 12 failed and 30 passed. Every summary pin in the console suite went red; the spec parse, the absence CONTROLs, the direct-mount unit suite and face 1's suite stayed green. The tool restored the file: blob equals HEAD, git diff HEAD empty. No build was in between, because the root vitest config aliases @object-ui to source.",
      "gates": "All exit codes were captured before any pipe. Build closure: pnpm turbo run build --filter='@object-ui/console^...' --concurrency=2, exit 0, 34/34 tasks. pnpm --filter @object-ui/app-shell type-check: exit 0. apps/console tsc --noEmit --listFiles: exit 0, with the new pin in the list. The following each exited 0: check:control-bytes, check:new-line-citations (0 new, re-run on 7f066d7), check:test-path-roots, check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape, check:changeset-claims, check:pending-changeset-literals, check:handler-key-reads, check:metadata-write-doors, check:unreferenced-sources, check:i18n-keys, check-changeset-no-major, check-changeset-overwrite, check-changeset-presence (re-run on 7f066d7), check-changeset-fixed. eslint on all changed files: exit 0, 0 findings. NOT MEASURED: check:readme-exports exited 1 locally on a prerequisite (plugin-ai and one other package have no dist; the README paragraph added here has no code fence). Also not measured: pnpm lint, the test shards, Bundle Analysis, check:eager-closure and check:sdui-registration-pins; CI runs them. No PR exists, so there are no PR check-runs to cite.",
      "mcp_calls": "17 — read tools only: issue_read x2 (12483 get + get_comments). Tool-schema loads: ToolSearch x4. claude-code-remote: add_repo x2 (objectstack read; objectui push probe) and read_documentation x1. No GitHub MCP write was made.",
      "api_writes": "0 landed REST writes. 1 refused: POST /repos/objectstack-ai/objectstack/dispatches (fleet-write relay, pr_create), egress-proxy 403, nothing sent on. git push x3 to claude/issue-12483-payload-summary (not REST).",
      "open_questions": [
        {
          "question": "The served page's amount covers less than the sheet's AMOUNT_KEY_RE. On objectstack's showcase, both approval targets (showcase_expense_report total_amount, showcase_invoice total) declare their headline total as Field.summary, a sum of a child currency field. So the sheet leads with them, and the served page shows them as ordinary rows with no lead. Should a declared route cover them?",
          "options": [
            "A: keep currency-only (as built). No new surface, but the two real showcase approvals get no headline amount.",
            "B: also treat a summary field whose summaryOperations is function 'sum' over a currency field as an amount. This reads only declarations, at the cost of one bounded extra metadata read for the child object. It is an objectui-only follow-up card on app-shell, with no spec change.",
            "C: add a declared amount key (on the object or the approval process) in @objectstack/spec, which authors must fill. This goes to the spec and services lanes."
          ],
          "recommendation": "B. Business need: measured, real. Both showcase approval targets carry their total as a summed roll-up, and the sheet's headline and amount sort rely on it. Long-term: it reads declarations only, with no name guess and no new contract surface, and stays contract-first. AI-proofing: it needs no new author action, so there is no declarable-but-unhonoured key; option C adds a key an AI can omit or misspell. Startup focus: B adds no spec surface, while C expands the spec with no named external pull. A stays honest but leaves the measured gap."
        },
        {
          "question": "The sheet FAILS OPEN when the target definition is unavailable: it falls back to raw snapshot rows with server or prettified labels. The served page draws no summary then. Keep it that way?",
          "options": [
            "A: keep it fail-closed (as built, pinned as a CONTROL).",
            "B: mirror the sheet's fallback."
          ],
          "recommendation": "A. Without the declarations there is no declared label, no type-aware face and no hidden:true to honour, so the fallback could show hidden fields (AI-proofing: contract over tolerance). The served page still shows the request's Details tab and the target's record card, so the decision surface is not empty (business). Mirroring the sheet would grow a second tolerant dialect (long-term). B adds surface with no pull (startup focus)."
        }
      ],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed: the neutral summary logic now exists twice, in the inbox sheet (ADR-0060 rule 3, untouched) and in app-shell RecordSnapshotSummary. The sheet's copy goes when the sheet migrates.",
        "carrier: domain:ui seat 1 · noted, not filed: this cloud session cannot use the fleet-write relay ('repository_dispatch is not permitted for this session type', proxy 403), and its GitHub MCP has no PR or comment create tool. A seat dispatching cloud os-dev sessions cannot rely on either write path here."
      ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 1 · session_01JZnppgHRp4sREcouhkQYDB · 2026-10-15T15:17Z

    • Merged: PR feat(app-shell): the served approval request page shows the declared amount and a snapshot summary (objectui#12483) #12533 landed through the merge queue as main 521817ce9d at 2026-10-15T15:15Z. It is an ancestor of origin/main, with first parent 0656b0e3c0.
    • Verified by content: all 7 files the PR changes are blob-identical on 521817ce9d to the accepted head 7f066d7224.
    • Mis-close scan: the PR body's only closing keyword is Fixes objectstack-ai/objectui#12483. The only issue closed with the merge is this card, completed.
    • What now holds (face 2 of ruling 6190549995 on objectui#12438):
      • The served sys_approval_request_detail page's decision panel leads with the request's declared amount: the first type: 'currency' field of the target, with no name guess.
      • Under it, a summary of up to 6 snapshot fields, each under its declared label and drawn through the record page's cell.
      • Hidden fields, FLS-refused fields, system columns, undeclared keys and unresolved reference ids are dropped. With no definition it draws nothing.
    • The chain:
      • claim 6194012467, and the cloud-session note 6194050303;
      • the cloud dev's report 6194901404, posted by the seat because the session could not write;
      • ACCEPT 6194958166.
    • Carried on:
      • objectui#12534: a summed-currency roll-up total also leads. It is the seat's answer B to the dev's open question, and its Blocked-by: objectstack-ai/objectui#12483 is now met.
      • Face 3, objectui#12489 (record-reference states): its Blocked-by: objectstack-ai/objectui#12483 is now met.
      • The closing card objectui#12484 waits on faces 3–5.
    • The cloud session session_01ARrv23Gwbz3Qwdivy7Yt9p is archived in the same act, per the cloud-card rule.
    • Label: pm:dispatched is removed in the same act as this note. The assignee stays, as the record of who drove it.

    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:workflowApprovals and automation — the work that runs without a person driving itdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatenhancementNew feature or requestpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions