diff --git a/.changeset/8801-object-kanban-allow-collapse-retired.md b/.changeset/8801-object-kanban-allow-collapse-retired.md index f897016a3f..39413d0b60 100644 --- a/.changeset/8801-object-kanban-allow-collapse-retired.md +++ b/.changeset/8801-object-kanban-allow-collapse-retired.md @@ -59,17 +59,42 @@ SWIMLANE collapse remains the viewer's alone: `KanbanImpl` collapses a swimlane row when its header button is clicked and persists that set per `swimlaneField`, and no authored key reaches it. -**Migration, in this repository: no authored document changed.** Over every -tracked file, the only occurrences of the name were the two declarations retired -here, one pin, one docs row and two historical changesets — no board, no -example, no fixture authors it, and `@object-ui/plugin-kanban` names it in ZERO -files against firing controls in the same pass (`groupBy` 45 files, -`conditionalFormatting` 8, `quickAdd` 6, `coverImageField` 3). The pin that -moved is `bare-kanban-node-key-retired-8802.test.ts`, whose suite 3 asserted -this arm still ACCEPTED the key; that row is now a refusal assertion, at its -site, with the reason stated — its three sibling rows stay accepting, because -the claim that suite makes (batch #70's refusals were arm-scoped and cannot -cross an arm) is still true and this retirement is not that claim. +**Migration, in this repository: no authored document changed.** No board, no +example and no fixture authors the key. Scanned 2026-09-17 over every tracked +file — with a whitespace-tolerant probe rather than a line-anchored grep, since +the name wraps across lines in prose — every occurrence is the retirement +talking about itself, and they are these: + +- the declarations retired here — `packages/types/src/objectql.ts` and its + mirror `packages/types/src/zod/objectql.zod.ts`; +- the pins that assert the retirement — + `object-kanban-allow-collapse-retired-8801.test.ts` and + `bare-kanban-node-key-retired-8802.test.ts`; +- a comment in `packages/types/src/zod/complex.zod.ts`, recording that the + deleted `retiredZeroReadKanbanKey` helper once carried this spelling on the + SIBLING arm; +- one row of `content/docs/api/schema-reference.md`; +- the `.changeset/` release notes that discuss it — this one, the two + historical entries covering the sibling arm's own spelling, and objectui#9629's + note recording the correction to this paragraph. + +`@object-ui/plugin-kanban` names the key in ZERO files, against live sibling +keys (`groupBy`, `conditionalFormatting`, `quickAdd`, `coverImageField`) firing +as controls on the same walk. ⛔ Their counts are deliberately not written here: +this file publishes VERBATIM into the CHANGELOG at an unknown future date, and a +figure frozen there is derived once and re-derived never. The walk is the +instrument and it re-runs on every test run — the `it` named +"`@object-ui/plugin-kanban` names it in ZERO files, with controls firing in the +same pass", in `object-kanban-allow-collapse-retired-8801.test.ts`. + +The pin that moved is `bare-kanban-node-key-retired-8802.test.ts`, whose suite 3 +asserted this arm still ACCEPTED the key. That stale row is gone, and it was not +replaced by a refusal row in the same place: the refusal belongs to this key's +own pin, which asserts it with the message, the `invalid_type` code and its own +firing controls, so the claim is pinned once rather than in two files. That +suite's accepting rows stay, because the claim it makes (batch #70's refusals +were arm-scoped and cannot cross an arm) is still true and this retirement is +not that claim. ⚠️ This repository's census cannot see a TypeScript consumer outside it that wrote the key. Such a consumer gets a compile error naming the member, which is diff --git a/.changeset/9629-9621-prose-residuals.md b/.changeset/9629-9621-prose-residuals.md new file mode 100644 index 0000000000..d1fec8c299 --- /dev/null +++ b/.changeset/9629-9621-prose-residuals.md @@ -0,0 +1,39 @@ +--- +--- + +Internal only — no published package moves, so this declares no release +(objectui#9629). Three prose corrections to what objectui#9621 left behind, each +named as NON-BLOCKING by that PR's isolated at-tier contract review (VERDICT +PASS). ⛔ None of them is a contract defect, no published face moves in either +direction, and no assertion of either retirement pin was weakened. + +1. **A docblock stopped writing an instrument's answer down.** The + `ObjectKanbanSchema.allowCollapse` tombstone's docblock recorded per-key + control counts as text. It now names the walk that derives them — the `it` + called "`@object-ui/plugin-kanban` names it in ZERO files, with controls + firing in the same pass", in + `packages/types/src/__tests__/object-kanban-allow-collapse-retired-8801.test.ts` + — and names the control keys without their counts, per commandment #9. The + figures it carried had already drifted before they landed, which is the case + that rule calls the dangerous one: a reader who spot-checks a still-plausible + number confirms it and is still wrong. + +2. **A suite title stopped contradicting its own contents.** In + `packages/types/src/__tests__/bare-kanban-node-key-retired-8802.test.ts`, + suite 3 was titled as though the sibling `object-kanban` arm kept every + verdict it ever had, while carrying a row asserting that one of them had + changed. The title now states the claim the suite actually measures: retiring + the bare `kanban` arm moved no verdict on the sibling arm. The restating + refusal row is gone rather than re-titled — it duplicated, in another card's + file, a refusal that `object-kanban-allow-collapse-retired-8801.test.ts` + already asserts together with its message, its `invalid_type` code and its + own firing controls. A comment in its place records why it is absent, so it + is not restored in either direction. + +3. **A changeset enumeration stopped publishing short.** The objectui#8801 + release note listed where the retired name still occurs and omitted a comment + in `packages/types/src/zod/complex.zod.ts`. Re-scanned with a + whitespace-tolerant probe — a line-anchored grep cannot see prose that wraps + mid-name — the paragraph now names each site rather than counting them, and + carries the date it was taken, because that body publishes verbatim into the + CHANGELOG at an unknown future date. Its frontmatter is untouched. diff --git a/packages/types/src/__tests__/bare-kanban-node-key-retired-8802.test.ts b/packages/types/src/__tests__/bare-kanban-node-key-retired-8802.test.ts index 421868b3a8..70474b9889 100644 --- a/packages/types/src/__tests__/bare-kanban-node-key-retired-8802.test.ts +++ b/packages/types/src/__tests__/bare-kanban-node-key-retired-8802.test.ts @@ -27,8 +27,11 @@ * it, and a 20-member census of it. * * ⭐ The one claim inside them that was NOT about the retired arm is carried - * forward here as suite 3: the SIBLING `object-kanban` arm's verdicts must not - * move. That is what turns this from a deletion into a retirement. + * forward here as suite 3: retiring this arm must not move the SIBLING + * `object-kanban` arm's verdicts. That is what turns this from a deletion into + * a retirement. ⛔ It is not the wider claim that those verdicts never move at + * all — `allowCollapse` later moved on that arm's own ruling (objectui#8801), + * which suite 3's comments cover. * * ## ⚠️ The mechanism, which is NOT the passthrough rule * @@ -153,7 +156,7 @@ describe('suite 2 — the refusal is not a validator that turned strict', () => }); }); -describe('suite 3 — the SIBLING `object-kanban` arm keeps every verdict it had', () => { +describe('suite 3 — retiring the bare `kanban` arm moved NO verdict on the SIBLING `object-kanban` arm', () => { // Carried forward from `kanban-arm-batch70-7742.test.ts`, whose `titleField` // pair is the reason this suite exists: the batch #70 refusals were // ARM-SCOPED, so retiring the arm must not move the sibling's answers. @@ -165,24 +168,22 @@ describe('suite 3 — the SIBLING `object-kanban` arm keeps every verdict it had expect(refusals({ type: 'object-kanban', objectName: 'tasks', groupBy: 'status', [key]: value })).toEqual([]); }); - // ⭐ `allowCollapse` LEFT this row, and the distinction is the whole point of - // the suite rather than an exception to it. Its verdict did not move because - // the `kanban` arm retired — that is precisely what this suite denies, and it - // went on being accepted here for a week after objectui#8802 landed. It moved - // because objectui#8801 ruled on THIS arm on its own protocol reading + // ⭐ `allowCollapse` is NOT a row in this suite, and its absence is the point + // rather than an omission. It sat among the accepting rows above until + // objectui#8801 ruled on THIS arm's own protocol reading // (`ComponentPropsMap['object-kanban']` never declared the key; no registered - // board reads it). ⛔ Do not read this line as batch #70 finally reaching the - // sibling: an arm-scoped refusal still cannot cross an arm, and the three rows - // above are still the measurement that says so. - it('REFUSES `allowCollapse` — not inherited from the retired arm, ruled for this one (objectui#8801)', () => { - const found = refusals({ - type: 'object-kanban', - objectName: 'tasks', - groupBy: 'status', - allowCollapse: true, - }); - expect(found.filter((f) => f.path === 'allowCollapse')).not.toEqual([]); - }); + // board reads it) and the key became a refusal. ⛔ Do not read that as batch + // #70 finally reaching the sibling: its verdict did NOT move because the bare + // `kanban` arm retired — an arm-scoped refusal still cannot cross an arm, and + // the three rows above are the measurement that says so. + // + // ⛔ Do not restore it here in either direction. The refusal — with its + // message, its `invalid_type` code, its `.describe()` channel and its own + // firing controls — is asserted by + // `object-kanban-allow-collapse-retired-8801.test.ts`, in the `it` named + // "refuses the value %p at the key's OWN path, with the prescription". + // Restating it here would put one pin in two files, which is the shape that + // let the stale ACCEPTING row survive here for a week after objectui#8802. it('and still REFUSES what it always refused — `groupField`, its own tombstone', () => { // The other half: suite 3 would be vacuous if the sibling arm accepted diff --git a/packages/types/src/objectql.ts b/packages/types/src/objectql.ts index cd6a280fde..22673c6f69 100644 --- a/packages/types/src/objectql.ts +++ b/packages/types/src/objectql.ts @@ -3820,12 +3820,26 @@ export interface ObjectKanbanSchema extends BaseSchema { * * ## Zero read sites, and both unnamed channels terminate * - * `@object-ui/plugin-kanban` names the token in ZERO files — the firing - * controls on the same instrument and the same run are `groupBy` (45 files), - * `conditionalFormatting` (8), `quickAdd` (6) and `coverImageField` (3), so - * the zero is a reading and not a dead grep. A source grep alone cannot - * answer the inertness question, because a renderer may consume a key it - * never names; both such channels were traced to their ends: + * `@object-ui/plugin-kanban` names the token in ZERO files, and that zero is + * a reading rather than a dead grep because live sibling keys fire as + * controls on the same instrument and the same run — `groupBy`, + * `conditionalFormatting`, `quickAdd` and `coverImageField`. + * + * ⛔ Their per-key counts are deliberately NOT written here (AGENTS.md #9). + * A figure in prose is derived once and re-derived never: the four that used + * to stand in this paragraph had already drifted by the time they landed, and + * a reader who spot-checked them would have confirmed a number the population + * underneath had already moved out from under. Point at the instrument + * instead — the walk re-runs on every test run, as the `it` named + * "`@object-ui/plugin-kanban` names it in ZERO files, with controls firing in + * the same pass" in + * `packages/types/src/__tests__/object-kanban-allow-collapse-retired-8801.test.ts`. + * The ZERO above is that test's own assertion rather than a remembered + * reading, which is why it stays here while the control counts do not. + * + * A source grep alone cannot answer the inertness question, because a + * renderer may consume a key it never names; both such channels were traced + * to their ends: * * - the PROP channel — `SchemaRenderer` spreads every non-metadata key as a * React prop, `ObjectKanbanRenderer` destructures `schema` and forwards