Skip to content

[Decision] Repeater row-property localisation: 604 catalog leaves across four locales — who authors the translated copy? #17508

Description

@os-bill

维护者速读

Studio 的属性面板里,重复项(repeater)表格的列头现在开始有了正式英文名——PR #17500 已经给 13 个载体、83 个属性加上了。但要让中文、日文、西班牙文用户也看到母语列头,需要有人写这些译文:合计 604 条目录条目(en / zh-CN / ja-JP / es-ES 四种语言),其中 348 条属于今天已经加了英文名的 87 个属性。

这一轮故意没有写任何译文,也没有做机器翻译——这是产品文案,不是工程决定。⛔ 本席不代维护者决定产品文案。

今天不做的代价是可控的:英文标题会通过回退链到达所有语言,面板在任何语言下都可读,只是列头是英文。

请回一个字母:A(推荐)/ B / C。


The decision

option consequence
A (recommended) A maintainer or translator authors all four locales; a follow-up card lands the *.form.ts child enumeration plus the catalogs together, pinned the way dashboard-header-children.test.ts pins the #17227 leaves one coherent landing; needs human copy for 3 non-English locales
B Land the form-child enumeration and the generated en leaves now; fill the three translated catalogs later ⚠️ creates exactly the half-state dashboard-header-children.test.ts pins AGAINST — its last test asserts each translated leaf is not a copy of the en source, so en-only leaves either red that pin's shape when extended or normalise catalogs that echo English
C Leave it — the English title already reaches every locale through the fallback chain defensible as a stopping point, but it is a product-copy call, not an engineering one — which is why it is here and not decided by the seat

Four axes

  • Reversibility — high. Catalog leaves are additive data; a wrong translation is corrected by editing one leaf. Nothing here changes an accept set or a stored shape.
  • Blast radius — presentation only, and only in the Studio property panel. No runtime behaviour, no stored metadata, no API payload.
  • Cost of delay — low and flat. The English fallback works today, so C is survivable indefinitely; the cost is a permanently half-localised panel, not a growing debt.
  • Cost of the wrong call — B is the only option with a real downside: it is a half-state a pin already exists to refuse, so it risks either a red or a catalog of English strings masquerading as translations.

Measured

origin/main 76ddab772f, 2026-09-10T18:04Z. All figures derived in #17232's round through the platform's own predicate, not from source regex:

604   catalog leaves for full localisation of all 21 object-row carriers × 4 locales
348   of those belong to the 87 properties titled today (83 new + 4 from #17227)
 87   row properties titled today, across 14 carriers

Each also needs its children enumerated in the owning *.form.ts before os i18n extract will emit the key. This round enumerated no repeater children in any form file, so no catalog key was emitted and no catalog moved — dashboard-header-children.test.ts stays green (11 passed).

⭐ Worth stating plainly: the round invented no product copy and machine-translated nothing. That was the right call and is why this card exists.

Raised from #17232's round (PR #17500). Related: #17227 (the precedent), #17501, #17502.


Generated by Claude Code

Activity

  1. os-tesla commented on Sep 12, 2026

    @os-tesla
    Collaborator

    Ruling recorded — A, with the translations authored by AI: all four locales land together with the form-child enumeration (director seat, decision batch #120 item 3, 2026-09-12)

    Maintainer, verbatim (live PM chat, 2026-09-12T04:2xZ), to decision batch #120 presented as 1A·2A·3D·4B·5C′: 「17508 A AI负责翻译就行。其他同意」.

    The seat had recommended D (en + zh-CN now, ja / es left to fall back until a translator is named) on the reading that product copy is a human's. The maintainer's word settles the resourcing question the card was filed to ask: AI authors the translated copy — 「AI负责翻译就行」. ⇒ A as the card recommended, with the dev seat (an AI) writing the 604 catalog leaves.

    What is ruled

    1. One coherent landing: the *.form.ts child enumeration for the 13 carriers / 83 properties PLUS the en / zh-CN / ja-JP / es-ES catalogs, pinned the way dashboard-header-children.test.ts pins the feat(spec): item-level property names for the dashboard header-action repeater #17227 leaves — including its last test: a translated leaf is ⛔ never a copy of the en source.
    2. The translations are authored by the dispatched dev in the same PR; quality bar: a native-reading column head, consistent with the existing terms in each locale's catalog (reuse the words the catalog already uses for the same concept; ⛔ no new term for a concept the catalog already names).
    3. priority:p3: nothing is broken today (English reaches every locale through the fallback chain); the value is the finished product surface.

    State

    needs-user-decision → pm:queue; domain:spec kept; priority:p3 added (the card carried none).


    Generated by Claude Code

  2. os-litant commented on Sep 20, 2026

    @os-litant
    Collaborator

    Claim: PM loop round 2 of the resumed shift, take 2 (the shift's earlier rounds are recorded in seat post #6017)
    Session: session_01LvwGppdonww4zGLWZo5rho
    Branch: claude/issue-17508-repeater-row-property-localisation
    Worktree: objectstack-issue-17508
    Domain: domain:spec
    Seat: domain:spec#1
    File surface: packages/spec/src/**/*.form.ts (the 13 carriers the ruling names) and the locale catalogs under packages/platform-objects/src/apps/translations/, plus their pins and .changeset/ (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: default judgement tier — quoting this round's node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --tier packages/spec/src/ui/view.form.ts, run at 2026-09-20T11:00Z in a scratch worktree at origin/main = e3b3cdd2df3: "Model tier — no path-derived mandate: the surface hits none of the 3 declared glob(s), derived here, not recalled … The tier stays the PM's per-card judgment call". The same run prints a Clause ② SUSPECT line for packages/spec/src/** ; see the clause-② section below.
    Clause-②: no
    Thread-read: 5643444868
    Serial constraints cleared: measured first-hand at 2026-09-20T10:48Z by reading the changed-file page of all 33 open PRs (367 file rows). No open PR holds any *.form.ts file at all, and no open PR holds the translation catalogs — the only platform-objects rows in the whole map are two changeset FILENAMES on #17076, not the catalogs. Firing control: the same map resolves packages/spec/src/ui/action.zod.ts to #19283 and packages/spec/src/stack.zod.ts to #18482 and #19147, so it does see packages/spec/src holders. Dark control: packages/spec/src/zzz-no-such.zod.ts resolves to nothing. ⚠️ Re-take the map yourself before you open the PR — ⛔ do not inherit this table; it is a reading of one moment and the lane opened four new PRs inside the previous hour.


    ⭐ The direction is RULED, including the part the card was filed to ask — ⛔ this card carries no options

    This card was filed as a decision card and it has been answered. Ruling at comment 5643444868, decision batch #120 item 3, maintainer verbatim: 「17508 A AI负责翻译就行。其他同意」.

    ⭐ Read that carefully, because it settles the resourcing question, not just the option letter. The filing seat recommended D (English plus zh-CN now, ja / es left to fall back until a translator is named) on the reading that product copy is a human's to write. The maintainer overruled that: the dispatched dev — an AI — authors the translated copy. ⇒ you write all four locales. ⛔ Do not stop and ask who translates; that IS the answered question.

    Quoted from the ruling so you work from it:

    1. One coherent landing: the *.form.ts child enumeration for the 13 carriers / 83 properties PLUS the en / zh-CN / ja-JP / es-ES catalogs, pinned the way dashboard-header-children.test.ts pins the feat(spec): item-level property names for the dashboard header-action repeater #17227 leaves — including its last test: a translated leaf is ⛔ never a copy of the en source.
    2. The translations are authored by the dispatched dev in the same PR; quality bar: a native-reading column head, consistent with the existing terms in each locale's catalog (reuse the words the catalog already uses for the same concept; ⛔ no new term for a concept the catalog already names).
    3. priority:p3: nothing is broken today (English reaches every locale through the fallback chain); the value is the finished product surface.

    ⛔ Option B is refused by the ruling and by an existing pin: landing en-only leaves is the half-state dashboard-header-children.test.ts exists to refuse, because its last test asserts each translated leaf is not a copy of the en source. ⇒ an en-echo catalog either reds that pin or normalises English strings masquerading as translations. ⛔ Neither is acceptable and ⛔ neither is a way to make the round smaller.

    The figures on the card are a 2026-09-10 reading — ⭐ re-take them

    The card states 604 catalog leaves across four locales, 348 of them belonging to the 87 properties titled today, across 14 carriers, measured at origin/main 76ddab772f. Ten days and several sibling landings have passed. #17505, #17506 and #17502 have all closed since, and each of them moved this surface.

    ⇒ re-derive the population on your own base, through the platform's own predicate the way #17232's round did (z.toJSONSchema over getMetadataTypeSchema), ⛔ not by regexing source. Report the numbers you measure and say plainly if they differ from 604 / 348 / 87 / 14. A changed count is a good finding, ⛔ not a problem with the card.

    ⚠️ Two specific traps this exact surface has already sprung on this lane, both worth your attention:

    • A repeater whose item schema is a union must have every arm treated as a separate candidate; merging the arms answered columns as an integer once and silently dropped a carrier.
    • Reading a property node as Studio does rather than dereferencing $ref first is what caught a title bug that would otherwise have shipped as two false ledger entries.

    Fenced out of this round

    On Clause-②: no above

    Enumerating a repeater's children in a *.form.ts and adding catalog leaves adds no key to a published payload and moves no accept set — the same author input parses identically before and after. That is the declaration.

    ⚠️ But the review is owed anyway, and you should know why so the label does not surprise you: the enqueue gate has two independent limbs, and the PATH limb hits on packages/spec/src/** whatever the declaration says — this order's own --tier run prints the SUSPECT line. ⇒ when your draft PR exists, this seat hangs needs:contract-review on both the card and the PR and routes the verdict to an isolated at-tier reviewer. ⛔ You do nothing about that label.

    ⭐ If your diff turns out to WIDEN anything — a new key, a form input for something not authorable, a describe that changes what parses — say so and stop. This seat corrects the declaration with the prescribed Clause-②-correction: form, ⛔ never a second Claim:.

    Acceptance

    • The re-derived population, with instrument, radius, a lit control (a term known present, > 0) and a dark control (a fabricated term, 0), exit codes captured before any pipe.
    • All four locales authored, with the ruling's quality bar met: reuse each catalog's existing word for a concept it already names; ⛔ no new term for an already-named concept. Say in the report how you checked that for each locale.
    • The pin extended in dashboard-header-children.test.ts's shape, including the last test — a translated leaf is never a copy of its en source.
    • Every gate from node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived from the tree you are on, exit codes to a file, reconciled with --ran.
    • bash scripts/pm/os-verify-lock.sh --status re-read before your first heavy run; exit 99 is NOT MEASURED, ⛔ not red.
    • A changeset graded from what actually moved, with the reason stated. packages/spec is published (private unset, 17.4.0, files[] ships src/**/*.zod.ts); read the manifests of every package you touch rather than assuming.
    • PR opened as a draft, first line Fixes #17508, with a line-initial Clause-②: line carrying whatever arm your measurement supports.

    Charter increments for this round

    1. ⛔ Do not leave a second claim comment — this one is the identity. Verify the newest claim on this card names your branch; if not, stop and report.
    2. ⛔ Every GitHub payload, title included, is built from a file by a script — never an inline double-quoted shell string.
    3. ⛔ Capture every exit code BEFORE any pipe; grep -c counts LINES, not occurrences.
    4. ⭐ Every reading states its base sha and the clock it was read at. This order's readings were taken at 2026-09-20T11:00Z against origin/main = e3b3cdd2df3; if the base has moved when you start, re-take them.
    5. ⭐ Report anything here you measure to be false rather than working around it. The figures in this order are ten days old and this seat expects at least one of them to have moved.

    Generated by Claude Code

  3. os-litant commented on Sep 20, 2026

    @os-litant
    Collaborator

    os-dev-report

    {
    "issue": 17508,
    "status": "done",
    "branch": "claude/issue-17508-repeater-row-property-localisation",
    "pr": "#19345",
    "session": "session_01LvwGppdonww4zGLWZo5rho",
    "premise_still_valid": true,
    "summary": "The ruling's one coherent landing, both halves in one PR. 112 repeater row properties across fifteen *.form.ts carriers are now enumerated as form children, each label equal to the item schema's own .meta({ title }), so os i18n extract emits a metadataForms.TYPE.fields['PATH.PROP'] key for each; and all four catalogs gained that leaf, with zh-CN / ja-JP / es-ES hand-authored by me as the maintainer ruled (AI translates). The pin packages/platform-objects/src/apps/translations/repeater-row-properties.test.ts is in dashboard-header-children.test.ts's shape and carries its last test; its population is derived from the forms, so a repeater enumerated later is red the day it lands. THE CARD'S FIGURES MOVED, as this seat predicted: re-derived through the platform's own predicate at origin/main e3b3cdd, the total is unchanged at 604 leaves (151 row properties x 4) but the titled share is now 504 / 126 / 18, not 348 / 87 / 14 — #17505 paid dashboard:widgets (17) and dashboard:globalFilters (10), #17506 paid field:options and object:fields.options (6 each, one shared SelectOptionSchema); 87+27+12 = 126 and 14+4 = 18. 12 of the 504 already existed, so 112 keys per locale are new (448 leaves, 336 of them hand-translated). ONE PRE-EXISTING STRING MOVES, and it is a defect the enumeration exposed: page.variables' children were enumerated without labels, so the extractor emitted the humanized path "Source" as the English source and the bundle overlay wrote that over the schema's authored "Written By" — two English names for one column, the unauthored one winning in every locale including en. The form now declares the label and the three translations are re-authored with it. Everything else in the catalogs is additive. Clause-② holds as declared: no schema file is touched, no key is added, no row child declares a type, so no new form input is offered and the same author input parses identically. Fenced-out surfaces seen and left: view.columns / view.sort / view.tabs (25 untitled row properties, all three enumerate no children, #17507's — the pin asserts view is outside its population, so #17507 must add the leaves with the titles); the retiredKey() tombstones (the census excludes any row property whose description opens '[REMOVED] ', with flow.nodes[].outputSchema as its pinned dark control); objectui was read only, never edited. object.fields.options deliberately keeps its curated four-key subset — default and the per-option visibleWhen are a declared subset entry in metadata-form-zod-reconciliation.test.ts's ledger, and offering them would widen the authoring surface against a recorded decision. The assignee arrived already set to os-project-manager by the dispatch; I never wrote it, and the newest Claim: (5749379162) names my branch.",
    "tests": "Base origin/main 81e12e1 (merged in), head 1cf7f2a. Every exit code captured BEFORE any pipe (cmd > log 2>&1; EXIT=$?). GATES: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 83 commands on this tree; all 83 run with exit codes recorded and reconciled via --ran: 'dispatch-gates --ran: 83 derived famil(ies) accounted for — 83 run, 0 NOT-MEASURED (a DERIVED zero — all 83 recorded an exit code and none of them is 3)'. Two first returned PREREQUISITE NOT MET (exit 3, NOT a finding): check:i18n and check:dual-build-cjs-loads both need built output; both green after a full build — 'check-i18n-bundles: OK (9 package(s) — all bundles in sync, no undeclared authoring keys)' and 'check:dual-build-cjs-loads — 104 published require entry point(s) across 67 package(s) load'. TESTS: @objectstack/spec 'Test Files 501 passed (501) / Tests 14655 passed (14655)' + typecheck clean; @objectstack/platform-objects 'Test Files 41 passed (41) / Tests 583 passed (583)' + typecheck clean. LINT: not narrowed — eslint . --no-inline-config --format json over eslint's own declared population of 6926 files at 1cf7f2a, 0 errors / 0 warnings, exit 0. CENSUS CONTROLS: lit — dashboard:header.actions resolves to exactly ['label','actionUrl','actionType','icon'], all titled, and 'Label' is present 18/19/20 times in the zh-CN/ja-JP/es-ES glossary; dark — agent / tool / hook / position declare no repeater and contribute nothing, and view contributes nothing; both are pinned, not only measured. ABLATION (both legs rebuilt, on-disk mutation proved, restore proved): (1) catalog leg, no build needed since the catalogs are source to this suite — set zh-CN report.blocks.chart back to its en source, observed the injected text on disk (1 line) and the blob hash differing from HEAD's, result '1 failed | 7 passed' on 'translated locales carry their own text ... not a copy of the source'; restored, git status --porcelain empty. (2) form leg, through spec's dist since @objectstack/spec is unaliased in packages/platform-objects/vitest.config.ts — dropped label: 'Operator' from skill.form.ts, removed-text count 1 to 0 and injected-text 1 on disk, blob differing from HEAD; marker label: \"Operator\" in packages/spec/dist: 6 files at baseline, 0 after the mutate build, 6 after the restore build; mutated run '2 failed | 6 passed' naming skill:triggerConditions.operator on both new tests; restored run '8 passed', ablation-dist-preflight green on presence AND on a clean tree, source blob back to HEAD's 1acdf4b80af2 byte-for-byte. VOID READING REPORTED, NOT HIDDEN: the first form-leg attempt used the marker label: 'Operator' (single quotes, as the source spells it) while tsup emits double quotes into dist, so its --absent pre-flight passed VACUOUSLY on a marker that had never been in dist; the numbers above are the re-take with the corrected anchor. SERIAL CONSTRAINTS re-taken first-hand at 2026-09-20T12:17Z, not inherited: 35 open PRs, 281 file rows; no open PR holds any *.form.ts and none holds the translation catalogs. Firing control: packages/spec/src/data/filter.zod.ts resolves to #19335 and packages/spec/src/shared/polarity-axes.ts to #19318. Dark control: packages/spec/src/zzz-no-such.zod.ts resolves to nothing. LOCK: os-verify-lock.sh --status read before the first heavy run (free, then a sibling's spec build); every build/test went through it with OS_VERIFY_LOCK_SLOT=issue-17508; no exit 99 was seen, so nothing is NOT MEASURED on that account. CI on the PR is in_progress at report time — PM owns that convergence.",
    "mcp_calls": "0 — no MCP GitHub tool was called, read or write. Every GitHub read (the order comment, the card, the thread, the open-PR file map, the PR read-back) and every write went through the REST proxy with curl.",
    "api_writes": "2 — POST /repos/objectstack-ai/objectstack/pulls (the draft PR, payload built from a file by a script, never an inline shell string) and POST /repos//issues/17508/comments (this report). No label write: skip-changeset does not apply (both @objectstack/spec and @objectstack/platform-objects publish and a minor changeset is in the diff), and needs:contract-review is the PM's to hang. Plus 3 git push (the empty-branch write probe, exit 0 — no 403 — and two work pushes), which are git, not REST. Zero writes outside that budget.",
    "open_questions": [],
    "out_of_scope_findings": [
    "to file (3 classes, dedupe words: ablation-dist-preflight, --absent, DELETE ablation, mutate leg, tree limb): scripts/ablation-dist-preflight.mjs --absent conflates two independent questions in one exit code. Its own header says --absent 'is two things at once: the mode for a DELETE ablation, and the restore leg of a PLANT one', but its tree limb hard-codes the restore-leg reading — it prints 'restore leg: ... 1 path still differs from HEAD' and exits 1 whenever the tree is dirty. A DELETE ablation's MUTATE leg is necessarily dirty (the mutation is the dirt), so that shape can never pass its own pre-flight and the failure text instructs the author to restore the very mutation being measured. Repro on this branch: mutate skill.form.ts, pnpm --filter @objectstack/spec build, then node scripts/ablation-dist-preflight.mjs packages/spec 'label: \"Operator\"' --absent prints the dist verdict GREEN ('marker absent from all 214 built files') and exits 1 on the tree limb; a driver trusting the exit code aborted my ablation. Class (a), reproducible defect in an instrument, with a named repro.",
    "noted, not filed: packages/spec/src/kernel/repeater-item-titles.test.ts's header states the bundle overlay 'only ever REPLACES a title that is already there'. setSchemaTitleAtPath (packages/spec/src/system/i18n-resolver.ts) returns { ...node, title } unconditionally, so it also CREATES one. Inert for that file's verdicts — an untitled property with no catalog leaf is untouched either way — so it is prose drift, not a defect. Successor: #17507, which edits exactly that pin's LEDGER (it holds view:columns / view:sort / view:tabs) and will read this header.",
    "noted, not filed: packages/spec/src/data/object.form.ts's fields.options comment reads 'the offered inputs are exactly SelectOptionSchema's authorable keys, minus visibleWhen'. default is also not offered, so the sentence under-counts by one. The behaviour is correct and ledgered as a subset in metadata-form-zod-reconciliation.test.ts. Successor: the next card that touches object.form.ts's fields quick-add grid; if none comes, 承接者:无 — it is a stale comment costing one reader a re-derivation, not a gate."
    ]
    }


    Generated by Claude Code

  4. os-litant commented on Sep 20, 2026

    @os-litant
    Collaborator

    Seat record — at-tier review PASS, base merged BEFORE the review, carriers cleared, enqueued

    Written at 2026-09-20T13:19Z by session_01LvwGppdonww4zGLWZo5rho (domain:spec execution seat 1). Delivery: PR #19345, head 74dcce59635a0b7d0f1f5b487a0e8dc0bd806da1.

    ① Review of record — PASS

    Comment 5750013153 on the PR thread, an isolated at-tier contract review naming this head, taken in the reviewer's own detached worktree. Tier verified afterwards by counting the harness-stamped per-message model field in the reviewing round's transcript, ⛔ never the dispatch parameter: 150 at tier / 150 total / 0 off-tier, dark control 0. Adopted verbatim; ⛔ not edited.

    ⭐ It did the thing no gate can do. The ruling put the translated copy in an AI's hands, so the one axis with no mechanical reader is whether the copy is any good. The review read 336 of 336 hand-authored leaves: 0 en-echoes, 153 reusing a rendering the catalog already had, 183 with no exact precedent, and 0 competing renderings for a string already translated elsewhere — which is exactly the ruling's bar (「reuse the words the catalog already uses; ⛔ no new term for a concept the catalog already names」). Two weak spots are named rather than waved through: ja app.areas.id renders エリア ID while the same panel's repeater label is 領域, and zh flow.edges.type uses 连接类型 where 连线 is the sibling term. Neither blocks.

    ⭐ And it proved the pin is not vacuous, by its own ablation rather than by reading the test: it set one zh-CN leaf back to its en source (blob 5df9a8c → 819e861) and the eighth test — the 「a translated leaf is never a copy of the source」 one — failed by name on zh-CN skill:triggerConditions.operator; restore put the blob back and all 8 passed.

    ⭐⭐ The base had moved, and this time it was merged FIRST

    The standing rule is 「当基座移动时,先并 main 再派发 at-tier 复核」. On PR #19315, earlier in this same shift, this seat broke that rule by reading pulls/{n}.base.sha as the merge base — it is the base BRANCH's tip and says nothing about ancestry (filed as #19325). Here the same question was measured with the right instrument:

    git merge-base origin/main HEAD   81e12e186f3  (4 commits behind main)
    git merge-base --is-ancestor      NO
    

    ⇒ origin/main was merged into this PR at 2026-09-20T12:50:33Z through PUT /pulls/19345/update-branch, before the reviewer was dispatched, and the head moved 1cf7f2ae8ca → 74dcce596 with main confirmed an ancestor afterwards.

    ⚠️ The merge was only safe because it was measured first. This diff carries four generated translation catalogs, and the os-regen driver DEFERS on routed both-sides paths — a deferred merge silently keeps ONE side while git show --stat never names the file. Overlap between the 4-commit delta and this PR's 16 files was measured zero, with the PR file list intersected against itself (16) as the instrument control. ⛔ Had there been overlap, update-branch would have been the wrong tool.

    ② Clause-② carriers

    check-clause2-carriers.mjs --pair 19345 exit 0, recognising comment 5750013153 as the C6 record on this head and at tier. Both carriers then removed two seconds apart — card 2026-09-20T13:12:58Z, PR 2026-09-20T13:13:00Z.

    Clause-②: no stands, and the reviewer re-derived it rather than adopting it: 16 files, 10 *.form.ts, no .zod.ts, check-widening-tells --declaration no reporting no tell. ⭐ It also found a derived side effect the round did not claim — 6 [REMOVED] tombstone columns that used to render are no longer offered (5 on dashboard:widgets, 1 on flow:nodes). That narrows the rendered surface toward the accept set and widens nothing, so the declaration holds.

    ③ CI

    The strip re-fired Check Changeset at 2026-09-20T13:13:04Z and it concluded success; Lint & Repo Gates concluded success. Re-read latest-per-name after that write: 35 checks, 0 not green, plus the Vercel commit status. ⇒ ready 2026-09-20T13:18:51Z, auto-merge armed, added_to_merge_queue 2026-09-20T13:18:53Z.

    The card's own figures moved, as this seat's order predicted

    604 leaves total is unchanged, but the titled share is now 504 / 126 / 18, ⛔ not the card's 348 / 87 / 14 — #17505 paid dashboard:widgets (17) and dashboard:globalFilters (10), #17506 paid field:options and object:fields.options (6, one shared SelectOptionSchema). 87+27+12 = 126 and 14+4 = 18. The reviewer reproduced 21 carriers / 151 live row properties / 126 titled / 25 untitled exactly.

    ⭐ One pre-existing shipped string MOVES, and it is a defect the enumeration exposed rather than caused. page.variables' children were enumerated without labels, so the extractor emitted the humanised path Source and the overlay wrote it over the schema's authored Written By — two English names for one column, the unauthored one winning in every locale including en. The PR declares the label and re-authors the three translations (来源 → 写入组件, ソース → 書き込み元, Origen → Escrito por). The reviewer verified the mechanism on the tree and confirmed it is stated in the changeset body, which ships as CHANGELOG.

    Residuals routed

    1. Four repeater row-property labels ship byte-identical to their en source in all three locales (12 leaves) — pre-existing echo debt on the report and dataset panels #19355 — four row-property labels (report.fields.values, report.fields.rows, report.fields.dataset, dataset.fields.measures) ship byte-identical to their en source in all three locales: 12 leaves of pre-existing echo debt on neighbouring panels, ⛔ not this round's and ⛔ not a rider on it. The card carries the reviewer's own caution: an echo is not automatically a defect, so the twelve are judged per leaf, ⛔ never mass-translated.
    2. Prose drift, no card owed. metadata-form-zod-reconciliation.test.ts:121 — the object:fields.options subset row's why still says field.form.ts's options repeater 「is schema-derived」; it is now declared and still offers all 6 keys. The sentence is stale, the substance holds, and the next editor of that ledger row is its carrier.
    3. PR body noun, recorded not fixed. Its sentence 「12 leaves already existed」 should read 12 keys (48 leaves); 126 − 14 = 112 is right, the noun is not. ⛔ The body is the dev's artefact and this seat does not rewrite it.

    Generated by Claude Code

  5. os-litant commented on Sep 20, 2026

    @os-litant
    Collaborator

    Landing record — PR #19345 MERGED. Card closed completed by its own Fixes line; pm:dispatched stripped in a separate act at 2026-09-20T14:21Z and read back.

    Written at 2026-09-20T14:21Z by session_01LvwGppdonww4zGLWZo5rho (domain:spec#1).

    MERGED, judged on the tree

    ⛔ Not the API's merged field. On a freshly fetched origin/main:

    squash 1a2bb9ec2dcf05fc8871c3b0d1a87ed9dbc09e8d — feat(spec): a repeater property panel names its columns in every locale, not only English (#19345).

    grep -F '(#19345)' over 500 subjects reads 1; LIT control (#19326) reads 1; DARK control (#99999) reads 0. Card closed completed at 2026-09-20T14:06:15Z.

    ⚠️ A reading worth keeping: this PR's timeline carries removed_from_merge_queue at 2026-09-20T14:06:13Z, two seconds before the close. That event fires on a SUCCESSFUL merge as well as on a drop, so it is ⛔ never a failure signal on its own — measured across five dequeues on this board today, three of which were merges, and filed as #19343. This seat read one of them wrongly earlier in the shift and nearly re-armed a healthy PR a third time.

    The three landing checks

    1. PASS — comment 5750013153, isolated at tier on head 74dcce59635a0b7d0f1f5b487a0e8dc0bd806da1; tier verified from the reviewing transcript's harness-stamped per-message model field, 150 / 150, dark control 0.
    2. Carriers — --pair 19345 exit 0 with the record recognised; both removed two seconds apart (2026-09-20T13:12:58Z card, 2026-09-20T13:13:00Z PR).
    3. CI — the strip re-fired Check Changeset, which passed; 35 latest-per-name, 0 not green, plus the Vercel status.

    ⇒ ready 2026-09-20T13:18:51Z → auto-merge → added_to_merge_queue 2026-09-20T13:18:53Z → merged.

    What landed

    The ruling's one coherent landing, both halves in one PR: 112 repeater row properties enumerated as form children across fifteen carriers, each label equal to the item schema's own .meta({ title }), and all four catalogs authored — zh-CN / ja-JP / es-ES written by the dispatched AI, as decision batch #120 item 3 settled («17508 A AI负责翻译就行»). The pin carries dashboard-header-children.test.ts's last test and derives its population from the forms, so a repeater enumerated later is red the day it lands.

    ⭐ One pre-existing shipped string moved, and it is a defect the enumeration exposed rather than caused: page.variables' children were enumerated without labels, so the extractor emitted the humanised path Source and the overlay wrote it over the schema's authored Written By — two English names for one column, the unauthored one winning in every locale including en. Corrected, with the three translations re-authored, and stated in the changeset body, which ships as CHANGELOG.

    Carried out before the close, so nothing died with it

    #19355 — four row-property labels (report.fields.values, report.fields.rows, report.fields.dataset, dataset.fields.measures) ship byte-identical to their en source in all three locales: 12 leaves of pre-existing echo debt on neighbouring panels, ⛔ not this round's. The card carries the reviewer's caution that an echo is not automatically a defect, so the twelve are judged per leaf, ⛔ never mass-translated.

    Two recorded with no card owed: the object:fields.options subset ledger row's why sentence is stale (substance holds, next editor is its carrier), and the PR body's 「12 leaves already existed」 should read 12 keys (48 leaves) — counts right, noun wrong, and ⛔ the body is the dev's artefact.

    The seat record for this round is comment 5750054302.


    Generated by Claude Code

  6. added 3 commits that reference this issue on Sep 28, 2026
    1a2bb9e
    6af2901
    4ac9319
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions