Skip to content

Field Designer save path needs a regression pin: the PUT body must be the object BODY, never the response envelope #4546

Description

@yinlianghui

Follow-up accepted from #4271 / PR #4545's census, filed for the pool (unassigned).

What #4545 found and fixed by side effect: plugin-designer/MetadataFieldsPage.tsx read raw.fields for display and then wrote client.save('object', name, {...state.raw, fields: nextFields}). Under the pre-#4545 contract breach, state.raw was the RESPONSE ENVELOPE ({type, name, item, ...protection fields}), so a Field Designer save persisted the envelope as the object body — a data-corruption path, not just an empty render. The contract repair in #4545 heals it (raw is now the unwrapped body), but nothing PINS the save path's wire shape specifically.

The ask: a focused regression pin on that save path — assert the PUT body is the object body (carries fields, does NOT carry type/name-as-envelope-identity or the protection envelope keys) driving a real MetadataClient over a real-server-shaped fetch, per the pattern PR #4545's suite established (nothing mocks get(); doubles written against the server shape, not the docblock). Rationale for a dedicated pin: this was the highest-severity consumer in the census (silent corruption on a routine save), and the defect class — a test double written against documentation rather than the wire — is exactly what let it hide inside 3,628 green tests.

Small card: one test file in plugin-designer, no product change expected. Refs: #4271, PR #4545.


Generated by Claude Code

Activity

  1. self-assigned this
    on Aug 13, 2026
  2. yinlianghui commented on Aug 13, 2026

    @yinlianghui
    CollaboratorAuthor

    CLAIM — session_017Qqyix2QcnpUC9XeYVDzx3, branch claude/issue-4546-field-designer-save-pin. Dispatching a dev agent now.

    PM ruling (delegated decision authority; maintainer veto window open — record objections here): the card is its own ruling — a focused regression pin, no product change expected:

    1. One test file in plugin-designer driving MetadataFieldsPage's save path with a REAL MetadataClient over a real-server-shaped fetch (the fix(data-objectstack): MetadataClient.get() honors its unwrapped-body contract — the field permission matrix lives (#4271) #4545 pattern: nothing mocks get(), doubles written against the wire, not the docblock). Assert the PUT body is the object BODY — carries fields, does NOT carry the envelope identity keys (type/name-as-envelope) or the protection envelope fields.
    2. Red-first here means proving the pin DISCRIMINATES: show it red against the pre-fix(data-objectstack): MetadataClient.get() honors its unwrapped-body contract — the field permission matrix lives (#4271) #4545 behavior (simulate by feeding the fetch double's get() answer through the old envelope shape un-unwrapped — e.g. compile the pin against a locally-reverted metadata-client in the red run, or assert on a captured body that the envelope-corruption shape FAILS the pin). The pin must be demonstrably capable of catching the permission-matrix-edit-loop: the field-level half of the permission matrix is dead for every object (MetadataClient.get() does not unwrap the envelope) #4271 corruption, not just green on today's code — direction checked, verbatim output in the report.
    3. If measurement reveals the save path today still sends anything envelope-shaped (premise inversion — fix(data-objectstack): MetadataClient.get() honors its unwrapped-body contract — the field permission matrix lives (#4271) #4545 should have healed it), STOP and report.
    4. Changeset: none expected (test-only; use the presence gate's own verdict — empty-frontmatter only if the gate demands a file). Never major.

    Mutual exclusion: plugin-designer untouched by all in-flight (#4527-p2 app-shell, #4541 plugin-grid, #4553 plugin-gantt, #4533 CelPredicateField). data-objectstack read-only. No gate — #4545 is on main.


    Generated by Claude Code


    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

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions