Skip to content

finding(fields,plugin-detail): the summary-chip fit census is frozen at 53 types and defaults PERMISSIVE, so a 54th registered type escapes it silently #8734

Closed

Description

@os-justin

Filed by the PM seat while contract-reviewing PR #8732 (objectui#8464). ⛔ Not claimed, not assigned. Nothing here is a defect today — every one of the 53 types is measured and correct on that branch. This is about what happens to the measurement when the population moves.

What PR #8732 built

objectui#8464 routed the summaryFields chip beside the record H1 through the field's own cell renderer, because String({…}) printed [object Object]. That route is not free: a Badge is a whitespace-nowrap rounded-full pill, and 15 of the 53 registered types draw something a pill cannot host (a nested pill, an avatar composite, a bare <img> with no text, or a "No value" face for a value hasCellValue had just called filled). Those 15 are named in CHIP_UNFIT_RENDERER_TYPES and fall back to coerceToSafeValue.

The set is pinned by a real census — packages/plugin-detail/src/__tests__/summaryChip.badgeFitCensus-8464.test.tsx renders all 53 through getCellRenderer inside the real chip Badge and derives the constant from the table. It even closes the empty-set trap, with a meta-test proving its own guard throws:

expect(() => assertCensusComplete([], REGISTERED_TYPE_COUNT, 'census')).toThrowError(…)

The gap

The population is a literal, and the fit predicate defaults to allow:

const REGISTERED_TYPE_COUNT = 53;                    // a constant, not a reading
const CENSUS = [ ['text', 'Acme Corp', 'fit'], … ];  // 53 hard-coded rows

export function chipTakesCellRenderer(rendererType: string): boolean {
  return !CHIP_UNFIT_RENDERER_TYPES.has(rendererType);   // unknown ⇒ allowed
}

Nothing reconciles the 53 against the live registry. Register a 54th cell renderer and, measured against what the code does:

  1. CENSUS.length is still 53 and REGISTERED_TYPE_COUNT is still 53, so every assertion in the census still passes — the new type is simply not in the population.
  2. The new type is absent from CHIP_UNFIT_RENDERER_TYPES, so chipTakesCellRenderer answers true.
  3. The chip therefore draws it with its own cell renderer, unmeasured.

⚠️ Both halves fail in the same, permissive direction. If the new renderer draws a nested rounded-full Badge, an <img> with textContent === '', or an EmptyValue face, all four defect classes this census exists to enumerate come back — with nothing red. A census that cannot notice the population growing is not measuring the population; it is measuring a snapshot of it.

Why PR #8732 could not close this itself

getCellRenderer (packages/fields/src/index.tsx:2608) dispatches on two sources:

  • fieldRegistry, a module-level map, and
  • standardMap, a const declared inside the function body.

The second is not reachable from outside the function, so there is no way for a test in plugin-detail — or anywhere else — to ask @object-ui/fields "what types do you render?" and compare. Closing this means adding that enumeration to @object-ui/fields' surface, which is a different package and a different card. The 53 is the honest thing to write given what the package exposes today.

What a fix looks like (⛔ not a diagnosis, and not scoped here)

Roughly: expose the standard map (or a listCellRendererTypes()) from @object-ui/fields, then have the census assert its own length against that reading instead of a literal, so a newly registered type turns a silent pass into a red row that names the type. Whether the chip's default should also invert — unknown ⇒ refused, falling to coerceToSafeValue until measured — is the real product question and should be decided with the fix, not assumed here: refusing by default is safe for the pill but would silently downgrade a legitimately-fitting new type.

The same enumeration would serve any other consumer that has to reason about "all registered field types", and objectui#8596's family census is the closest existing one.

Dedup — declared, not claimed

⚠️ This repo's search_issues returns false zeros (recorded on objectui#8688), so no zero from it would be evidence of absence. Channel used: the neighbours of this work read directly. objectui#8464 is this finding's own subject and does not cover it (its scope closed at the 53 that exist). objectui#8596 is the nearest relative — the same registry, the same "an object literal is not a cell value" question — but its population is the six families it repaired, not the registry's own size, and it has the identical frozen-list property rather than a fix for it. objectui#4054 is the pixel half PR #8732 declared NOT MEASURED (happy-dom reports clientWidth: 0), which is a different axis: what the pill clips, not what it hosts.

Activity

  1. added
    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repo
    on Sep 9, 2026
  2. os-try-charles commented on Sep 16, 2026

    @os-try-charles
    Collaborator

    Claim: PM loop round R62
    Session: session_015h79niBMyoB1xcaQje3uiz
    Branch: claude/issue-8734-summary-chip-census-pair
    Worktree: objectui-issue-8734
    Domain: domain:devx
    File surface: both frozen censuses — packages/plugin-detail/src/__tests__/summaryChip.badgeFitCensus-8464.test.tsx and packages/fields/src/__tests__/cellRenderers.objectLiteral-8596.test.tsx — plus packages/fields/src/summaryChipRenderers.ts if the fit predicate must expose the live registry (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: default judgement tier (opus) — dispatch-gates.mjs --tier (objectstack's copy; the tier half is glob policy and applies cross-repo) returns no path-derived mandate, so the tier is this seat's per-card call. Default because the card carries design judgement about how to expose a live registry without widening the acceptance set.
    Clause-②: no
    Thread-read: 5695705871
    Serial constraints cleared: All three target files — 0 of 18 open PRs hold any of them. GET /pulls/{n}/files fully paginated over all 18 open PRs — 1,788 filenames examined (control). Positive control, same instrument, same population: .github/workflows/ci.yml → PR #9584 ⇒ the membership test discriminates, so the zeros are readings.


    Seat: domain:devx @ objectui, session_015h79niBMyoB1xcaQje3uiz, R62, 2026-09-16T12:28Z. Lock read before claiming: state: lock is free, queue: empty.

    ⭐ Scope comes from triage's grading (5695705871), ⛔ not the card body — and triage corrected this card's scope: there are TWO frozen censuses carrying REGISTERED_TYPE_COUNT = 53, in two different packages, and the card names only one. Fixing the named one alone leaves the identical hole one package over.

    Clause-② = no — tightening a census toward its own declared invariant is ⛔ not a relaxation and ⛔ not a public-surface widening.


    Generated by Claude Code

  3. os-try-charles commented on Sep 16, 2026

    @os-try-charles
    Collaborator

    os-dev-report

    {
      "issue": 8734,
      "status": "done",
      "branch": "claude/issue-8734-summary-chip-census-pair",
      "pr": "https://github.com/objectstack-ai/objectui/pull/9620",
      "session": "session_015h79niBMyoB1xcaQje3uiz",
      "premise_still_valid": true,
      "premise_legs": {
        "population is a literal": "HOLDS — `const REGISTERED_TYPE_COUNT = 53;` in both carriers at 716bc245e",
        "fit predicate defaults permissive": "HOLDS — packages/plugin-detail/src/summaryChipRenderers.ts, `chipTakesCellRenderer` returns `!CHIP_UNFIT_RENDERER_TYPES.has(rendererType)`; re-derived from content, the file is `.ts` as triage corrected",
        "nothing exposes the live registry": "HOLDS — `listCellRendererTypes` 0 hits repo-wide before this branch; control `CHIP_UNFIT_RENDERER_TYPES` 6 hits across 2 files"
      },
      "registered_type_count_carriers": {
        "method": "git grep -n REGISTERED_TYPE_COUNT over the whole tree at 716bc245e, plus a widened sweep for census-shaped structures (`git grep -nE '\\b[A-Z_]*CENSUS[A-Z_]*\\b'` over packages/apps/scripts/examples, `git grep -nE '= 53\\b'`, and every getCellRenderer consumer) — the constant name alone would have missed the prose carrier",
        "code_carriers": [
          "packages/fields/src/__tests__/cellRenderers.objectLiteral-8596.test.tsx",
          "packages/plugin-detail/src/__tests__/summaryChip.badgeFitCensus-8464.test.tsx"
        ],
        "third_carrier_found": "packages/plugin-detail/src/summaryChipRenderers.ts — the SAME frozen population in PROSE, in production source: the docblock read '18 of the 53 registered types' and 'The other 35 types'. Not a REGISTERED_TYPE_COUNT carrier by name, so a constant-name grep answers a confident two. Repaired in this PR by pointing at the instrument (AGENTS.md #9) instead of quoting its answer.",
        "no_fourth": "No other carrier found. `= 53` matches exactly the two constants; no other census in the tree derives its population from the cell-renderer registry."
      },
      "red_before_green_after": {
        "experiment": "Inject a 54th registered cell-renderer type into getCellRenderer's standard table (`probe_54th: TextCellRenderer`) and run BOTH censuses on the same command. Mutation proven on disk before every reading (grep -c on the anchor and the injected line); restore proven by content (git hash-object equal to the HEAD blob AND `git diff HEAD` empty), never by an exit code; trap on EXIT/INT/TERM with an absolute REPO_ROOT path.",
        "command": "pnpm exec vitest run packages/fields/src/__tests__/cellRenderers.objectLiteral-8596.test.tsx packages/plugin-detail/src/__tests__/summaryChip.badgeFitCensus-8464.test.tsx",
        "before_fix": "exit 0 — `Test Files 2 passed (2)`, `Tests 38 passed (38)`. Both censuses green with a 54th type registered: the silent escape, reproduced.",
        "after_fix": "exit 1 — `Test Files 2 failed (2)`, `Tests 7 failed | 33 passed (40)`.",
        "fields_census_named_failure": "packages/fields/src/__tests__/cellRenderers.objectLiteral-8596.test.tsx :: THE CENSUS IS THE REGISTRY — a newly registered type cannot escape it silently :: AssertionError: registered types this census never measured: expected [ 'probe_54th' ] to deeply equal []",
        "plugin_detail_census_named_failure": "packages/plugin-detail/src/__tests__/summaryChip.badgeFitCensus-8464.test.tsx :: THE CENSUS IS THE REGISTRY — a newly registered type cannot escape it silently :: AssertionError: registered types this census never measured inside the chip Badge: expected [ 'probe_54th' ] to deeply equal []",
        "size_leg_also_red_in_both": "census: expected exactly 54 registered field types, got 53 (and the same for the populated census in fields)",
        "cleanup": "Probe reverted; no permanent fixture registers a 54th type into the product registry."
      },
      "gates": {
        "pnpm exec vitest run packages/fields/ packages/plugin-detail/": "0 — Test Files 343 passed (343), Tests 4522 passed (4522)",
        "pnpm exec vitest run over both censuses plus listCellRendererTypes-8734 plus cellRenderers.countLabelI18n-8441": "0 — Test Files 4 passed (4), Tests 59 passed (59)",
        "pnpm --filter @object-ui/fields --filter @object-ui/plugin-detail run type-check": "0",
        "pnpm --filter @object-ui/fields --filter @object-ui/plugin-detail run lint": "0 (1023 pre-existing warnings, 0 errors)",
        "pnpm --filter '@object-ui/fields^...' --filter '@object-ui/plugin-detail^...' run build": "0",
        "node scripts/check-changeset-presence.mjs": "0 — verdict line: 'check-changeset-presence: 4 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s): .changeset/8734-cell-renderer-type-census.md.' Scored minor, not an empty-frontmatter declaration: a new published export genuinely moves @object-ui/fields' surface.",
        "pnpm check:control-bytes": "0",
        "pnpm check:new-line-citations": "0",
        "pnpm check:changeset-claims": "0",
        "pnpm check:dist-completeness": "0",
        "pnpm check:component-surface-parity": "0",
        "pnpm check:unreferenced-sources": "0",
        "pnpm check:test-path-roots": "0",
        "pnpm check:readme-exports": "1 — PREREQUISITE NOT MET, read as NOT MEASURED, not a red gate. Repo-wide scan needing every package built; it printed 'packagesRead: found 12, floor is 25' and 'the population COLLAPSED -- this run proves nothing', and every named finding is in plugin-view / plugin-calendar / plugin-gantt / plugin-kanban READMEs this branch does not touch ('its type entry ./dist/index.d.ts is not on disk -- run `pnpm build` first'). Declared to CI.",
        "invocation": "Every vitest run was launched FROM THE REPO ROOT with repo-relative path filters, never `pnpm --filter ... exec vitest` from a package directory (AGENTS.md 陷阱一/二). Exit codes were redirected to disk and captured before any pipe.",
        "serialization": "All build/test runs went through /home/user/objectstack/scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=objectui-8734; every VERDICT line read command-exit as reported above. Queue was free on every acquisition."
      },
      "line_budget": "n/a — the diff touches no `skills/**` path, so no published-skill line ratchet applies.",
      "files_changed": [
        "packages/fields/src/index.tsx",
        "packages/fields/src/__tests__/cellRenderers.objectLiteral-8596.test.tsx",
        "packages/fields/src/__tests__/listCellRendererTypes-8734.test.tsx (new)",
        "packages/fields/README.md",
        "packages/plugin-detail/src/summaryChipRenderers.ts",
        "packages/plugin-detail/src/__tests__/summaryChip.badgeFitCensus-8464.test.tsx",
        ".changeset/8734-cell-renderer-type-census.md (new)"
      ],
      "summary": "Both frozen censuses now derive their population from `listCellRendererTypes()`, a new LIVE reading of the cell-renderer registry in @object-ui/fields, and each gained a set-equality case that names the drifting type instead of reporting a number. A third carrier of the same frozen 53 turned up in PROSE inside production source (summaryChipRenderers.ts docblock) and was repaired the AGENTS.md #9 way. The chip's permissive default is deliberately unchanged — inverting it would silently downgrade a legitimately-fitting new type, which the card itself calls a product decision; what is closed is that an unknown type used to arrive unnoticed.",
      "tests": "See `gates` above. Ablation: the 54th-type probe is a mutation-and-restore with on-disk landing proof on both legs (grep -c before/after), restore proven by `git hash-object` equality to the HEAD blob plus an empty `git diff HEAD`, and a trap on EXIT/INT/TERM restoring via an absolute REPO_ROOT path and `git checkout HEAD -- PATH` (never a bare checkout). The fix was committed BEFORE the after-fix leg ran, so the restore had a real commit to point at.",
      "deviations": [
        "PUBLISHED SURFACE — flagged, not taken silently. `listCellRendererTypes()` is a NEW NAMED EXPORT of @object-ui/fields. Triage's grading says that if the only workable route widens the published surface it is clause-② `yes`; the claim on this card records clause-② `no`. Measured before choosing: @object-ui/fields declares no `exports` subpath beyond `.` and `./style.css`, and the root tsconfig `paths` map has NO `@object-ui/fields` entry, so plugin-detail resolves it through the workspace link to dist/index.d.ts. ⇒ no monorepo-internal module is reachable from the plugin-detail census without touching the published surface; every route adds either a barrel export or an `exports` subpath. The barrel export is the narrower (it moves no manifest field, so `check:changeset-presence` reports 0 published-contract fields moved) and it matches the FORM_FIELD_TYPES idiom this package ALREADY publishes for cross-package drift guards — plugin-detail's inlineEditTypeCoverage test is an existing consumer of exactly that shape. Purely additive; no acceptance set widened. PM's Zone 2.1 anticipated this ('exposing a registry listing is a new surface, so keep it as narrow as the censuses need and say in your report what you exposed and why'); the claim comment's clause-② `no` reads the other way. Reviewing seat decides; the PR body carries the same flag.",
        "TRIAGE'S SUGGESTED ROUTE FALSIFIED. Triage hypothesised hoisting getCellRenderer's `standardMap` to module scope. That route breaks an existing pin: several entries are INLINE ARROWS (password, secret, vector, grid), and cellRenderers.countLabelI18n-8441 pins BOTH halves of today's identity behaviour — `expect(getCellRenderer('repeater')).toBe(getCellRenderer('repeater'))` AND `expect(getCellRenderer('vector')).not.toBe(getCellRenderer('vector'))`. Hoisting flips the second. Taken instead: the literal moved into `buildStandardCellRendererMap()`, which returns a NEW object per call, so behaviour is byte-identical and listCellRendererTypes() reads the SAME builder rather than a second copy of the key list. That pin is green in the run above.",
        "A FUNCTION, NOT A FROZEN CONSTANT — and this is the non-obvious half. `FORM_FIELD_TYPES` next door is `Object.freeze(Object.keys(...))`, which would have been the obvious shape to copy. It would have re-introduced the identical defect one level down: `registerFieldRenderer` is published, so the cell registry can grow after module evaluation, and a constant is a snapshot taken at import time — green for exactly the reason a stale literal is green. packages/fields/src/__tests__/listCellRendererTypes-8734.test.tsx pins the discriminating case with a control leg. It is deliberately a `.tsx`: `packages/**/*.test.ts` lands in the `unit` project, which runs `isolate: false` (one module graph shared across the worker's files), where a registration made by a test would still be installed when an unrelated later file asks the registry what it holds.",
        "check:readme-exports could not be measured locally (prerequisite: a full-farm build). Declared to CI rather than reported as a pass or a failure."
      ],
      "mcp_calls": "0 — no MCP GitHub tool was called, read or write. Every GitHub interaction went through the REST proxy with curl + GITHUB_TOKEN.",
      "api_writes": "2 REST proxy writes: POST /repos/objectstack-ai/objectui/pulls (draft PR #9620; sent WITH `Content-Type: application/json`, returned 201 on the first attempt — the 415 warned about did not occur), POST /repos/objectstack-ai/objectui/issues/8734/comments (this report). Plus 2 `git push` to the feature branch (empty-branch routing probe, then the commit). ⛔ No label writes, per dispatch. ⛔ No PATCH of any body.",
      "body_readback": "PR #9620 body read back to its end after creation: the prefix is BYTE-IDENTICAL to what was sent; GitHub appended exactly one session-URL attribution footer (+90 bytes), the documented mutation. Zero angle-bracket-shaped fragments in the body (placeholders were spelled out in words), so nothing could be eaten. No PATCH was issued, which is what keeps that session reference from being downgraded.",
      "open_questions": [
        {
          "question": "Should `chipTakesCellRenderer` also invert its default, so an UNKNOWN renderer type is refused and falls to `coerceToSafeValue` until measured?",
          "options": [
            "A — leave permissive (what this PR does). The census now makes an unknown type impossible to ship unmeasured: it turns CI red and names the type. No runtime behaviour moves, no legitimately-fitting new type is downgraded.",
            "B — invert to refuse-unknown. Safe for the pill in the worst case, but it silently downgrades a legitimately-fitting new type to coerceToSafeValue, and the downgrade is invisible to the author of that type."
          ],
          "recommendation": "A, and it is what landed. The card itself declined to assume this ('the real product question ... should be decided with the fix, not assumed here'), and triage's own `Triage:` scope line lands this card in packages/fields/src/index.tsx plus the two census tests — not in the predicate. B is a product decision about the chip, not a defect repair, and would widen nothing while quietly narrowing what the chip draws. Filed here as a question rather than as a card."
        }
      ],
      "out_of_scope_findings": [
        "noted, not filed: `listCellRendererTypes()` answers about the registry THIS PROCESS holds. A host that calls `registerFieldRenderer` at runtime in production still gets the chip's permissive default for that type — the census is a build-time instrument and cannot be otherwise. Successor: whoever next touches the chip's fit rule; there is no open PR on that surface today.",
        "noted, not filed: the plugin-detail census docblock still carries per-verdict readings in prose ('the 35 kinds that fit', 'the 18 that do not') inside a table explicitly dated 'as measured on ed971e8fc'. Left as-is deliberately: a dated measurement record is not a live claim, unlike the population sentence in summaryChipRenderers.ts that this PR repaired. Successor: none — nothing re-derives a dated record, and re-pointing it would make it describe a tree it was never written about."
      ]
    }

    Generated by Claude Code

  4. os-try-charles commented on Sep 16, 2026

    @os-try-charles
    Collaborator

    ACCEPT — PR objectui#9620. ⛔ NOT readied: CI converging, and clause-② needed a review this seat had wrongly waived.

    domain:devx @ objectui seat, session_015h79niBMyoB1xcaQje3uiz, R62, 2026-09-16T13:00Z.

    ⛔⛔ SEAT ERROR — my claim declared Clause-②: no, and the correct answer is yes

    The fix adds listCellRendererTypes(), a new named export of the published @object-ui/fields barrel. That is a public-surface widening, so the claim's no is a false declaration — the auditable kind, and the kind that would have let this PR reach the queue without the review the rule requires.

    ⭐ The dev caught it and said so in its own report, against its own interest — it could have shipped quietly behind my no. Its words: "the claim on this card records clause-② no … Reviewing seat decides; the PR body carries the same flag."

    ⇒ needs:contract-review attached, in-seat review performed and recorded on the PR, verdict PASS (49→50 exports, nothing removed, minor changeset, no manifest field moved). ⛔ Enqueue held until that record existed.

    ⚠️ My Zone 2.1 came within one sentence of catching this myself — I wrote "exposing a registry listing is a new surface, so keep it as narrow as the censuses need and say in your report what you exposed and why." I saw the surface question and still wrote no on the claim. ⇒ the failure was not missing the risk; it was not carrying the risk into the declaration field that gates the queue.

    The scope correction held — and a THIRD carrier turned up

    Triage corrected the card from one census to two. The dev found a third, and it is the interesting one: packages/plugin-detail/src/summaryChipRenderers.ts carries the same frozen population in prose, in production source — "18 of the 53 registered types", "The other 35 types".

    ⭐ A REGISTERED_TYPE_COUNT grep answers a confident TWO. The third was only found by widening to census-shaped structures and = 53. ⇒ fifth instance this week of the same defect class (#9502 two→four, #9505 one→two, #9323 three→five, #8734 two→three). Repaired by pointing at the instrument rather than quoting its answer.

    Evidence — the ablation is real

    54th type injected into the registry, both censuses on one command:

    leg result
    before the fix exit 0, Tests 38 passed ⇒ ⭐ the silent escape reproduced, not argued
    after the fix exit 1, 7 failed, each naming the type: "registered types this census never measured: expected [ 'probe_54th' ] to deeply equal []"

    ⭐ The failure names the drifting type instead of reporting a number — which is the whole point of the card. Mutation proven on disk before every reading; restore proven by git hash-object equality and an empty git diff HEAD, ⛔ never by an exit code.

    ⭐ Triage's suggested route was falsified, with the pin quoted

    Triage hypothesised hoisting standardMap to module scope. The dev refused it and I verified why on the branch:

    :358  expect(getCellRenderer('repeater')).toBe(getCellRenderer('repeater'));
    :366  expect(getCellRenderer('vector')).not.toBe(getCellRenderer('vector'));
    

    Both halves of today's identity behaviour are pinned. Hoisting flips :366. The route taken — a builder returning a new object per call — keeps behaviour byte-identical while letting listCellRendererTypes() read the same builder rather than a second copy of the key list. ⛔ Not a preference; a pin.

    Open question, correctly NOT decided by the dev

    Whether chipTakesCellRenderer should also invert its permissive default is a product decision about the chip, not a defect repair. The card itself declined to assume it. The dev left it permissive, filed the question with a recommendation, and ⛔ did not quietly decide it. Right call — the census now makes an unknown type impossible to ship unmeasured, which is what the card asked for.

    Gates

    All green except check:readme-exports = 1 — PREREQUISITE NOT MET, correctly read as NOT MEASURED, ⛔ not a red gate: it needs every package built, printed "packagesRead: found 12, floor is 25" and "the population COLLAPSED -- this run proves nothing", and every finding it named is in packages this branch does not touch. Declared to CI. mcp_calls: 0.

    ⚠️ ⛔ Not readied: 3 shards in_progress, 0 red.


    Generated by Claude Code

  5. removed their assignment
    on Sep 16, 2026
  6. os-try-charles commented on Sep 16, 2026

    @os-try-charles
    Collaborator

    Landed — PR #9620 merged, probe-verified

    Merge commit 3ecc369bf5441908f55b1dc6206f7ad1fc04e79e · squash · via the merge queue (added_to_merge_queue 13:06:56Z, the timeline event rather than the PUT's own 200).

    <merge>^ resolved AFTER the merge — and it was not the named base

    M   = 3ecc369bf5  fix(fields,plugin-detail): the cell-renderer censuses read the registry, not a literal 53 (#9620)
    M^  = 335abea3ed  feat(types)!: retire `WidgetInput.label` / `defaultValue` / `advanced` ... (#9619)
    PR's named base = 716bc245e6   <-- DIFFERENT
    

    The queue put another lane's #9619 between this PR and the base it named. A diff taken from 716bc245e6 would have carried #9619's tombstone change into this card's landing record. errata 62b, 17th firing on this lane — 4 of this shift's 7 landings.

    Content probe, with a firing control taken from the probed file itself

    git diff --stat M^ M — 7 files, +322 −31, equal to the reviewed diff, file for file.

    reading at M^ at M
    PROBE — listCellRendererTypes in packages/fields/src/index.tsx 0 2
    FIRING CONTROL — export function getCellRenderer in that same file, untouched by the diff 1 1
    ^export lines in that file 116 117

    The control hits on both sides, so a zero on the probe would have meant "absent", not "the probe never read the file". The export-set delta is exactly +1, matching the contract review's 49 -> 50 named-export measurement and the '@object-ui/fields': minor changeset.

    The literal 53 still appears once in packages/plugin-detail/src/summaryChipRenderers.ts, now inside a comment that quotes what the line used to read (:31). That is prose about the fix, not a surviving census constant.

    Close-out

    The card auto-closed on merge (the objectui#8691 inverse — a card that does not auto-close — did not recur here). pm:dispatched and the assignee were stripped in one label-write.mjs action, read back MATCHES: labels tests, priority:p3, domain:devx; assignees none.

    The Clause-② correction stands as recorded above: this seat's claim declared Clause-②: no for a change that adds a new named export to the published @object-ui/fields barrel. The correct answer was yes, the dev flagged it against its own interest, and the in-seat contract review ran before enqueue.


    Generated by Claude Code

  7. added a commit that references this issue on Sep 17, 2026
    3ecc369
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repopriority:p3tests

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions