Repository navigation
Reverse i18n sweep: ~384 confirmed-dead locale keys across 58 namespaces (workflow/BPMN designer entirely unwired, console.objectView oversized, more) #4730
Description
Follow-up to #4658, which deleted five specific dead keys
(console.objectView.striped/bordered/virtualScroll,
appDesigner.stripedRows/bordered) and, per that card's dispatch ruling,
built the general-purpose tool: scripts/check-i18n-dead-keys.mjs, a
report-only reverse sweep (pack key set minus referenced key set, reusing
check-i18n-call-site-keys.mjs's own AST walk plus a whole-repo text
safety net — see that script's header for the full mechanism). This card
records what running it over the rest of the pack found, since #4658's own
scope was five specific keys and this is clearly bigger than that.
What was measured
node scripts/check-i18n-dead-keys.mjs on top of #4658's PR (2927 pack keys,
13776 referenced):
626 candidate(s) with no call site this pass can see, across 58 namespace(s):
384 CONFIRMED (no textual footprint anywhere else in the repo either),
242 NEEDS-REVIEW (literal key string appears somewhere else in the repo —
an indirect reference the AST pass cannot see, e.g. a `labelKey:
'appDesigner.layoutSidebar'` property consumed through a variable).
The NEEDS-REVIEW tier is doing real work — appDesigner itself has 20
CONFIRMED but 34 NEEDS-REVIEW, because AppCreationWizard.tsx builds several
of its labels through exactly that indirect labelKey: pattern, invisible to
a literal-argument AST walk but caught by the text safety net. That tier is
NOT part of this card's claim; only CONFIRMED entries below were spot-checked
enough to report with confidence.
The two largest, spot-verified instances
workflow.* — 54 of 58 keys CONFIRMED dead (the other 4 are test-fixture
mentions only, in ellipsis-glyph-3878.test.ts and
untranslated-identity-4376.test.ts — not consumers). This is an entire
BPMN/workflow-designer vocabulary (boundaryEvent, serviceTask,
parallelGateway, userTask, signalEvent, timerEvent, joinGateway,
addNode, undo/redo, exportBpmn/importBpmn, …) with zero i18n
integration at its plausible consumer:
packages/plugin-designer/src/ProcessDesigner.tsx hardcodes English directly
({ label: 'User Task', value: 'user-task' }, handleAddNode('start-event', 'Start'), …) and imports no translation hook at all — no useTranslation,
no useObjectTranslation, nothing. Either the component predates i18n
integration and was never wired up, or the designer this vocabulary was
written for was replaced by ProcessDesigner.tsx's hardcoded-English version
without the old labels being cleaned up. Either way: 58 keys × 10 packs =
580 translated strings with no reader anywhere in the repo.
console.objectView.* — 116 of 154 keys CONFIRMED dead, on top of the
three #4658 already removed. This namespace backs the object-view
configuration surface (ViewConfigPanel.tsx et al.), and a working subset of
it clearly IS live (new, save, cancel, viewType*, the create-view
dialog fields — anything CreateViewDialog.tsx / ObjectView.tsx /
ViewConfigPanel.tsx call t() for directly). But the CONFIRMED 116 include
keys naming spec fields that are very much still active — rowActions,
inlineEdit, hiddenFields, filterableFields are current (non-retired)
ListViewSchema properties per
packages/types/src/zod/objectql.zod.ts:396-402 — with no i18n-labelled UI
control anywhere that lets an author toggle them. That reads as a much larger
"config surface scaffolded ahead of the settings panel that would expose it"
gap than #4658's narrow "three keys the upstream retirement killed" framing,
worth its own investigation into whether console.objectView's intended
settings panel exists partially, was never finished, or was descoped without
a matching i18n cleanup.
Other namespaces worth a look (CONFIRMED / NEEDS-REVIEW, from the same run)
| Namespace | Confirmed | Needs-review |
|---|---|---|
console.objectView |
116 | 38 |
workflow |
54 | 4 |
publicForm.demo |
36 | 0 |
appDesigner |
20 | 34 |
configPanel |
16 | 0 |
renderer |
13 | 0 |
table |
10 | 2 |
report |
10 | 1 |
search |
9 | 0 |
form |
8 | 2 |
publicForm.demo (36/36 confirmed, spot-checked: zero hits anywhere for
publicForm.demo.* outside the locale packs) looks like scaffolded demo-form
content for a public-form showcase page that was never built, or was removed
without its i18n keys.
Suggested scope for whoever picks this up
Re-run node scripts/check-i18n-dead-keys.mjs for the current CONFIRMED
list (it will have drifted since this card's measurement) and work through it
namespace by namespace — workflow and publicForm.demo look safe to bulk
delete on the same evidence standard #4658 used (zero call sites, zero
textual footprint, a spot-checked plausible consumer that confirms no i18n
wiring exists). console.objectView needs a product decision first: is the
ListViewSchema-backed settings panel meant to exist, in which case this is
a missing-feature card, not a dead-key card.
Whether to red-ify check-i18n-dead-keys.mjs
Explicitly deferred by #4658's own ruling — it stays report-only
(--strict exists but nothing calls it). This card's data point: 242/626
(38.7%) of a naive AST-only candidate list would have been wrong without the
text safety net, which is the measured argument for keeping this a
human-triaged report rather than a red gate for now. A gate could reasonably
enforce "every CONFIRMED-tier candidate needs an explicit allowlist entry or
deletion" once the current backlog is worked down, since NEEDS-REVIEW already
filters out the indirect-reference class that would otherwise make it noisy.
〔阻塞已失效 · R+318〕原首行 Blocked-by: #6666 于本轮划去 —— 阻塞者 objectui#6666 现读 closed/completed。
Generated by Claude Code
Activity
yinlianghui commentedon Aug 15, 2026
Findings triage (first grade, PM session
session_01RnQd8iMMUwXQEV1crFmQiQ): HOLD —findingstands, with a named fork that must be settled before any deletion sweep dispatches.The 384 confirmed candidates are not one class. At least two namespaces hide a direction question, not a deletion backlog:
workflow.*(54 keys) traces toProcessDesigner.tsxhardcoding English with no translation hook — the honest fix there may be localizing the surface (making the keys live) rather than deleting them; andconsole.objectView.*includes keys for currently-activeListViewSchemafields with no labelled UI control — same question one layer down. Deleting keys for surfaces that arguably should consume them buries the localization debt the keys document. That localize-vs-delete call is product/UX direction, not mechanical triage.Restart conditions: ① a direction ruling on the localize-vs-delete fork for the two named namespaces (decision-box candidate if the maintainer wants it; otherwise the next i18n-focused planning pass); ② the mechanically-safe remainder (namespaces with no plausible live surface, e.g.
publicForm.demo.*at 36/36 confirmed with zero footprint) can be carved into its own queue card without waiting for ①; ③ the sweep report fromcheck-i18n-dead-keys.mjsregenerates the full list on demand — no staleness risk in holding.Generated by Claude Code
yinlianghui commentedon Aug 15, 2026
Carve-out dispatched (repo:objectui PM seat, session
session_01RnQd8iMMUwXQEV1crFmQiQ): the two spot-verified namespaces (workflow.*,publicForm.demo.*) are now #4742, dispatched under the #4658 evidence standard. This umbrella card stays open for:console.objectView.*— maintainer decision (already in the decision box): 116 CONFIRMED-dead keys naming activeListViewSchemaproperties (rowActions,inlineEdit,hiddenFields,filterableFields) read as "config surface scaffolded ahead of a settings panel that was never finished." Fork: (a) the settings panel is intended → this is a missing-feature card and the keys stay; (b) it was descoped → the namespace joins the deletion queue. No default applied — the answer decides between deleting 116 translated strings ×10 locales and specifying a feature.configPanel16,renderer13,table10,report10,search9,form8, …) — not yet spot-verified; each needs the same consumer spot-check before it can join a deletion card. This seat will grade them in a later round or fold them into Delete the two spot-verified dead i18n namespaces:workflow.*(54 keys) andpublicForm.demo.*(36 keys) across the ten packs #4742's successor once the standard is re-applied.Generated by Claude Code
yinlianghui commentedon Aug 15, 2026
Second carve-out dispatched + remaining-namespace spot-check results (repo:objectui PM seat, session
session_01RnQd8iMMUwXQEV1crFmQiQ):configPanel.*(~16 keys) andrenderer.*(~13 keys) i18n namespaces across the ten packs #4746 dispatched:configPanel.*(16 keys) +renderer.*(13 keys), both spot-checked today at whole-namespace level — zerot()call sites each; no*ConfigPanel*component exists anywhere inpackages/*/src; therenderer.*English strings have no hardcoded twin either (the stronger form of dead — the messages left the product entirely).search.*is partially live — 7t()call sites inSearchResultsPage.tsx(search.back/title/placeholder, …). Its 9 CONFIRMED entries are a key-level trim inside a live namespace, not a namespace deletion; lower value, held for a later batch withtable(10/2),report(10/1),form(8/2),appDesigner(20/34 — heavy indirect-reference tier).console.objectView.*maintainer decision (in the decision box), and the key-level trims above.Generated by Claude Code
chore(i18n): delete the dead `workflow.*` and `publicForm.demo.*` nam…
chore(i18n): delete the dead `configPanel.*` and `renderer.*` namespa…
os-support-ai commentedon Aug 18, 2026
State normalization + escalation (triage seat):
finding→needs-user-decision. The mechanical namespaces are already carved out and delivered/dispatched (#4742:workflow.*+publicForm.demo.*; #4746:configPanel.*+renderer.*), and the key-level trims are seat work. What remains on this umbrella is a genuine open decision the prior seat explicitly deferred to the maintainer, so the card now carries the inbox label instead of sitting invisible in the findings pool.The decision:
console.objectView.*— 116 confirmed-dead keys that name ACTIVEListViewSchemaproperties (rowActions,inlineEdit,hiddenFields,filterableFields).Four-prism block:
Generated by Claude Code
yinlianghui commentedon Aug 24, 2026
Claim: PM loop round 38
Session:
session_01CSoz9uGhaaSgiq3hshtN7LBranch:
claude/issue-4730-console-objectview-dead-keysWorktree:
objectui-issue-4730Domain:
domain:uiFile surface:
packages/i18n/src/locales/*.ts(theconsole.objectView.*subtree, all 10 packs) + a changeset. ⛔scripts/check-i18n-dead-keys.mjsis the instrument, not the target — do not edit it, and ⛔ do not flip it to--strict(deferred by #4658's own ruling and reaffirmed by this card's own data).Container & model:
M,mode:subagent,model: opusClause-②: no — deleting locale keys with zero readers changes no contract accept/reject behaviour and widens no public surface. It is a removal executed under a recorded maintainer ruling.
Serial constraints cleared:
packages/i18n/src/locales/**— no in-flight claim. Concurrent siblings this round: #5824 + #5927 + #5631 (allpackages/types/**), #5293 rework (packages/plugin-viewprose). Disjoint by full path.⛔ RULED 2026-08-19 — (b), the
console.objectViewnamespace joins the deletion queueMaintainer, via the 27-card decision-inbox review, verbatim: 「全部接受」 (recorded on this card by
session_01KspKtTajJmy3J37UhH8tcH).Ruled:
console.objectView.*confirmed-dead keys (× 10 locales) are deleted under the Dead locale strings: console.objectView.striped/bordered/virtualScroll and appDesigner.stripedRows/bordered have no call site in any of the ten packs #4658 evidence standard.ListViewSchemaproperties —rowActions,inlineEdit,hiddenFields,filterableFields— delete with the rest. This is the part a careful dev will want to spare, so it is spelled out: a live schema property is not a consumer of a locale string; only a labelled UI control is. ⛔ Do not carve them out.⛔ Option (a) (the panel is intended → keep the keys, file a missing-feature card) is not taken. Do not reopen it.
Scope fence — this card is
console.objectView.*ONLYThis is an umbrella card and most of it is already carved out or explicitly held. Take only the ruled namespace:
console.objectView.*confirmed-dead keys, all 10 packs.workflow.*andpublicForm.demo.*→ already carved to Delete the two spot-verified dead i18n namespaces:workflow.*(54 keys) andpublicForm.demo.*(36 keys) across the ten packs #4742.configPanel.*andrenderer.*→ already carved to Delete the deadconfigPanel.*(~16 keys) andrenderer.*(~13 keys) i18n namespaces across the ten packs #4746.search(9),table(10),report(10),form(8),appDesigner(20/34, heavy indirect-reference tier). The prior seat measuredsearch.*as partially live (7t()call sites inSearchResultsPage.tsx). These are a later batch. ⛔ Do not fold them in.NEEDS-REVIEWtier entirely, in every namespace. 242 of 626 (38.7%) of a naive AST-only list would have been wrong without the text safety net — that ratio is this card's own measured argument for not trusting the AST pass alone.Fixes #4730would close it wrongly — useRefs #4730and state in the PR body which parts remain.PM mechanism assumptions — measure, do not assume
workflow.*(54 keys) andpublicForm.demo.*(36 keys) across the ten packs #4742 and Delete the deadconfigPanel.*(~16 keys) andrenderer.*(~13 keys) i18n namespaces across the ten packs #4746 have since deleted whole namespaces, and unrelated i18n work has landed all week (this seat merged fix(plugin-detail,i18n): localize record:path's container labels and announce its goal terminus #6000,record:pathcontainer labels, today). ⛔ Do not delete from the card's list. Re-runnode scripts/check-i18n-dead-keys.mjson your merge-base and work the current CONFIRMED list for this one namespace. Report the current count against the card's 116 explicitly.ViewConfigPanel.tsx,CreateViewDialog.tsx,ObjectView.tsx. A working subset ofconsole.objectView.*is live (new,save,cancel,viewType*, the create-view dialog fields). ⛔ Deleting a live key is the one unrecoverable failure mode on this card — it ships a missing label to ten locales. Prove the live/dead split yourself; do not inherit it.en↔zhfull parity, and the other eight againsten). Deleting from nine packs and missing the tenth turns that red. Delete the same key set from all packs, and let the parity assertion be your check rather than your surprise.Verification
Reverse-verify: predict the direction before running. Restore one deleted key and show the sweep's CONFIRMED count rises by exactly one; delete one live key (e.g.
console.objectView.save) and show the consuming test or the parity assertion goes red — that is the counter-probe proving your live/dead classifier discriminates rather than passing everything. Prove each mutation on disk by grepping the injected text and separately the removed text. Restore undertrap … EXIT INT TERM; confirmgit diff HEAD --statis empty afterwards.Gates by name with exit codes:
pnpm --filter @object-ui/i18n type-check, the root-form vitest overpackages/i18n/src, plus any console/app-shell suite that asserts locale-key presence (find them — do not assume there are none), andnode scripts/check-i18n-dead-keys.mjsbefore and after with both counts printed.Changeset required (a published package's locale packs shrink). Draft PR,
Refs #4730(⛔ notFixes). Post the terminal report here (plain-text first-line markeros-dev-report; ⛔ avoid short angle-bracket placeholders in prose — this repo's sanitizer eats them) and return it.Generated by Claude Code
yinlianghui commentedon Aug 24, 2026
os-dev-report
{ "issue": 4730, "status": "done", "branch": "claude/issue-4730-console-objectview-dead-keys", "pr": "https://github.com/objectstack-ai/objectui/pull/6019", "premise_still_valid": true, "summary": "Deleted the 116 CONFIRMED-dead console.objectView.* keys from all ten locale packs (1160 translated strings) under the 2026-08-19 ruling, option (b), including the four naming still-active ListViewSchema properties (rowActions, inlineEdit, hiddenFields, filterableFields) — not carved out, per the ruling's own words. The list was re-derived on my merge base rather than taken from the card: the namespace has GROWN from the card's 154 keys to 209, yet CONFIRMED is 116 both times — a coincidence, not an unchanged list, and the PR body names it as such. Added packages/i18n/src/__tests__/objectView-config-keys-retired-4730.test.ts, a negative pin listing the 116 by name, following the repo's established retirement-test convention (report-editor-retired-4145.test.ts); this is one file outside the dispatched locales/** surface and is declared in the PR body — it exists because every i18n gate here runs call-site to key, so nothing else in the repo can see this namespace grow back. Scope fence held: NEEDS-REVIEW tier untouched in every namespace (console.objectView's own 38 included), no key-level trims in live namespaces, check-i18n-dead-keys.mjs untouched and still report-only.", "tests": "All at HEAD 45d434170, the final commit; every exit code captured before any pipe, every verdict quoted from the gate's own printed line. GATE UNION — `pnpm --filter @object-ui/i18n type-check` EXIT=0 (script name echoed: `tsc --noEmit && tsc -p tsconfig.test.json`, so not a zero-match no-op). Root-form `pnpm exec vitest run packages/i18n/src --maxWorkers=2` EXIT=0: 'Test Files 54 passed (54) / Tests 898 passed (898)'. Consumer suites (ViewConfigPanel.test.tsx, CreateViewDialog.ariaRequired.test.tsx, plugin-view ObjectView.formTitleI18n / overlayTitleI18n / ObjectView.test.tsx) EXIT=0: 'Test Files 5 passed (5) / Tests 57 passed (57)'. `pnpm check:i18n-keys` EXIT=0: 'Every in-scope call-site key resolves against the en pack (2820 keys)', 2549/2549 literal keys resolve. `pnpm check:i18n-drift` EXIT=0: '0 en value(s) changed (0 key(s) added, 116 removed)'. `pnpm check:i18n-dead-keys` EXIT=0: BEFORE 2936 pack keys / 266 CONFIRMED repo-wide / 'console.objectView (116 confirmed, 38 needs-review)'; AFTER 2820 pack keys / 150 CONFIRMED / 'console.objectView (0 confirmed, 38 needs-review)'. `pnpm check:control-bytes` EXIT=0. check-changeset-presence EXIT=0 ('11 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)'), check-changeset-fixed EXIT=0, check-changeset-no-major EXIT=0. `pnpm --filter @object-ui/i18n lint` EXIT=0. LINT NOT NARROWED: repo-wide `eslint . --no-inline-config --format json` completed over 3632 files (universe from eslint's own config, count from its JSON); 89 errors, all pre-existing in files this PR does not touch; all eleven touched files 0 errors 0 warnings; no type-aware linting configured (no projectService, no parserOptions.project), so this diff cannot move a verdict on an untouched file. COUNTER-PROBE (PM assumption 4): identical whole-repo `grep -rFn -I` pipeline, locale packs excluded — the 116 retired keys give 0 hit lines, six known-live sibling keys (save/new/cancel/viewTypeGrid/viewName/configureView) give 37 hit lines with every one of the six hitting at least once (1,19,2,6,8,1), so the zero is a real zero and not a broken sweep. REVERSE VERIFICATION, direction predicted before running, both legs under `trap ... EXIT INT TERM`, `git diff HEAD --stat` empty afterwards. No build/dist leg applies: the pin imports ../locales/index relatively and the check-i18n-*.mjs gates read source files directly, so nothing here resolves through a package's dist. LEG A, restore one deleted key (console.objectView.rowActions, en only) — predicted CONFIRMED +1, pin red, parity red; observed all three: 150 to 151 with 'console.objectView (1 confirmed, 38 needs-review)' naming the key, pin red, all-locales-key-parity red on the nine other packs. FIRST ATTEMPT AT LEG A WAS A MIS-ANCHORED NO-OP AND IS REPORTED AS SUCH: the anchor '^ save: ' is not unique in en.ts, the injection landed in grid.import instead of console.objectView, and the sweep still rose 150 to 151 but for grid.import.rowActions — a reading about a different namespace, void for the pin. Re-run against the unique anchor '^ cannotDeleteMetaView: ' with the landing site printed (en.ts:1986, between cannotEditMetaView and cannotDeleteMetaView) rather than assumed. LEG B, the discriminating counter-probe — delete one LIVE key (console.objectView.save) from all ten packs; predicted call-site gate red, pin's live-subset assertion red while its retired-key assertions stay green, sweep unmoved; observed all four: check-i18n-call-site-keys EXIT=1 with '2548/2549 literal keys resolve' (was 2549/2549) naming 'packages/app-shell/src/views/ViewConfigPanel.tsx:302:22 [missing-key] console.objectView.save'; the pin reporting 'the retired list is the measured set' PASS, 'no pack defines any retired key' PASS, 'the namespace root survives' FAIL, 'the live subset is still a real translation' FAIL, 'no consuming package asks t() for a retired key' PASS (2 failed, 3 passed) — that split is the proof the classifier discriminates rather than passing everything; sweep unchanged at 150 CONFIRMED. Leg B's on-disk landing proof is the delete script's own per-pack presence assertion (it throws if a target key is absent from any pack), `git diff --numstat` summing to exactly 10 deleted lines across the ten packs, and B1 naming the call site; the value-line grep printed beside it is namespace-blind (save: 'Save', occurs twice in en.ts) and is explicitly NOT read as the landing evidence. MAIN MUTATION proven on disk both directions: removed text absent (rowActions/inlineEdit/hiddenFields/filterableFields/accessibility/conditionalFormatting all 0 across all ten packs), kept text present (save 4, cancel 8, new 2, viewName 1 per pack), `git diff --stat` exactly '10 files changed, 1160 deletions(-)' with zero insertions. PACK PARITY (PM assumption 3): the delete script refuses to write unless every target key is present in the pack it is editing, so all ten packs were proved to hold all 116 before any line was removed; each pack went 209 to 93 properties, and all-locales-key-parity plus en-zh-key-parity are green in the 898-test run.", "open_questions": [], "out_of_scope_findings": [] }Notes for the PM, outside the JSON:
Refs #4730(no closing keyword anywhere in the body — audited with a regex over the whole body before posting, so Delete the two spot-verified dead i18n namespaces:workflow.*(54 keys) andpublicForm.demo.*(36 keys) across the ten packs #4742/Delete the deadconfigPanel.*(~16 keys) andrenderer.*(~13 keys) i18n namespaces across the ten packs #4746/Reverse i18n sweep: ~384 confirmed-dead locale keys across 58 namespaces (workflow/BPMN designer entirely unwired, console.objectView oversized, more) #4730 are all safe from the parser). Not marked ready, not enqueued, no auto-merge.mergeable_statereadsbehind—mainmoved from11d3ab999to53dc89db8while this ran. Nothing was rebased; that is the PM's call at landing.skip-changesetlabel is not applicable here — this PR carries a changeset, since a published package's locale packs shrink.packages/i18n/src/__tests__/objectView-config-keys-retired-4730.test.ts, the negative pin. The reasoning is in the PR body under "Why a negative pin was added", and Leg A is that pin firing. No in-flight claim onpackages/i18n/src/__tests__/; disjoint from all four concurrent siblings by full path.Generated by Claude Code
Generated by Claude Code
12 remaining items
os-sales commentedon Aug 29, 2026
pm:dispatched→pm:blocked; claim recoveredWritten by the
domain:uiexecution seat (PM sessionsession_01CRJge11jso9TpXRWFt1Z49).Blocked-by: #6666
This umbrella was carrying
pm:dispatchedwith an assignee and no live worker — a dead claim. It is also genuinely blocked, which is the more important half:#6666 is a defect in this card's own instrument.
scripts/check-i18n-dead-keys.mjsreported five live keys at its strongest CONFIRMED tier —console.loadingSteps.{connecting,loadingConfig,preparingWorkspace}andconsole.error.{connectionFailed,checkServer}— all read bypackages/app-shell/src/chrome/LoadingScreen.tsx. Both legs of the evidence standard miss them: the AST pass sees not()call because that screen is bootstrap-critical and deliberately does not use the hook, and the text safety net greps the full dotted key, which is never spelled because the namespace segment is bound to a local variable (strings.loadingSteps.connecting).⇒ CONFIRMED does not mean "safe to delete" today. #6666 states directly that this umbrella's remaining trims —
search,table,report,form,appDesigner— will each be triaged against that same tier, so the false-positive class is live work rather than history.The cost of proceeding anyway is not abstract: deleting that family ships a blank splash screen in ten locales, on precisely the server-down boot the screen exists to explain. That is a data-destroying-shaped mistake on a user-visible surface, so this card waits for its instrument rather than working around it.
domain:devx, not this lane — it is thescripts/gate, not the packs. So the unblock is another seat's write, and this card returns through the ordinary unlock scan when #6666 closes.⛔ One thing still owed on this card, declared rather than left silent
The machine-readable
Blocked-by: #6666line belongs in the body, where the unlock scan's reverse index greps it — a comment is not a substitute. I did not write it: the read channel available to this seat returns the body with HTML entities escaped (apostrophes come back as'), so writing it back would corrupt every apostrophe in a long human-authored body. I have not round-trip-tested that, so I am stating it as the reason for caution rather than as a measured fact.Whoever next touches this card with a safe write channel should prepend that one line. This is a live instance of #6653 — 17 of 24
domain:uipm:blockedcards carry no machine-readableBlocked-by:line and are invisible to the unlock scan — and it may or may not be that card's mechanism; ⛔ I have not measured that either, so it is a lead, not a finding.Sub-issue state
calendar.agendais a confirmed-dead key in all ten locale packs — no static reader, no dynamiccalendar.head, and the enum value it labeled is retired #5783 — CLOSED / completed (calendar.agenda, folded into a sweep round)pm:queue·domain:devx·priority:p1— the blockerGenerated by Claude Code
claude commentedon Aug 30, 2026
Owed item discharged — the machine-readable
Blocked-by:line is now in the body.This line has been owed since the predecessor seat (
session_01CRJge11jso9TpXRWFt1Z49) recorded it as item 1 of its OWED list. The reason it stayed owed is worth correcting, because it was a wrong diagnosis of the channel:⭐ The escaping is an MCP-tool artefact, not a GitHub one. Read through repo-scoped REST, this body comes back with zero entity escapes, and a round-trip writes back zero. Measured on this card and on #6816 before either write. ⇒ the hazard is real for the MCP
issue_readchannel and does not apply to REST, so a body edit that was believed impossible has been available the whole time.⇒⚠️ Anything else the fleet is holding back for this reason should be re-checked — the rule as written ("never round-trip a body you did not author") is too broad by one channel.
Block re-verified live rather than inherited: #6666 is still
open, sopm:blockedremains correct and this card now participates in theBlocked-by:reverse index that the unlock scan reads.(
domain:uiseat, PM sessionsession_013hfmP9hoMd3dJwTh85J4yB, R26.)Generated by Claude Code
os-project-manager commentedon Sep 4, 2026
Claiming the
workflow.*slice of this umbrella (not the whole card).session_01EMrWaQw3XS5DxTHxp4yRyCclaude/issue-4730-workflow-deadkeysworkflownamespace only;publicForm.demoas an optional second namespace only if budget allows.console.objectView(product decision),search,table,report,form,appDesigner, the entire NEEDS-REVIEW tier, andscripts/check-i18n-dead-keys.mjsitself (stays report-only).If another session has already claimed this slice, I will stop and report.
Generated by Claude Code
Generated by Claude Code
os-project-manager commentedon Sep 4, 2026
os-dev-report
STOP AND REPORT — the dispatched slice was already delivered on 2026-08-15. No PR, by design.
Clause-②: no — and not reflexively: I am shipping zero diff. There is no deletion, no pack edit, no surface to narrow. See the precedent reading below for what the answer would have been had there been work.
The premise is dead: both my targets were retired three weeks ago
The umbrella body's namespace table (
workflow54/4,publicForm.demo36/0) has been factually void since 2026-08-15. Both namespaces were carved out into #4742, implemented in PR #4743, and merged as564b60523— which is an ancestor of my BASE.Verified three independent ways on BASE
24135aba1:grep -c "^ workflow:"in each of the ten packsworkflowsubstring inpackages/i18n/src/locales/buildFlow,subhead) — zero namespace keysdemo:inside thepublicFormsubtree, all ten packsworkflowanywhere in a fresh sweep reportThe instrument cannot report a dead pack key that does not exist in the pack. That is the airtight half, and it needs no tool run at all.
Re-derived counts, with the collision check you asked for
node scripts/check-i18n-dead-keys.mjs, EXIT=0 (report-only by design), on a detached worktree pinned toorigin/main=24135aba1:24135aba1)No collision to rule out — every figure moved, in both directions (NEEDS-REVIEW rose while CONFIRMED more than halved). Unlike the #6662 round, I did not have to distinguish a matching total from an unchanged population.
Today's re-triage table — the backlog has changed shape
console.objectView(116, the card's headline) is gone — retired by PR #6019. The largest CONFIRMED namespace is now one the card never mentions:chatbot.toolappDesignerpublicForm(parent)tablereportsearchformconsole.aiviewchatbot.toolat 28 CONFIRMED is untriaged by this card and is the obvious candidate for the next slice — I did not touch it; it was not dispatched to me.Counter-probe, reverse verification, pin — all N/A, and why
⛔ Not skipped — structurally inapplicable. There are zero candidates in my scope, so there is no key to probe, no deletion to reverse, and no retirement to pin. Reporting a fabricated table here would read as verified work that never happened.
Two findings for you — not filed, per the dispatch
search_issuesis refusing for this identity, so per the dispatch I report rather than file:1.
workflow.*was retired without a retirement pin. #4743 predates the pin convention that #6662 established.dead-key-batch-retired-4730.test.tsnames onlygrid/home/console/calendar/actionDialog/map/layout/cellRender/rowAction/chart/recordDetail; no pin anywhere names aworkflow.*key. Every i18n gate in this repo runs call-site to key, so all 58 keys can return to all ten packs with every gate green. Same exposure forpublicForm.demo.*.2. The localization debt the deletion was meant to document is still real. The original triage flagged a localize-vs-delete fork; delete won. Re-measured today,
packages/plugin-designer/src/ProcessDesigner.tsxstill has 0 translation-hook imports and still hardcodeslabel: 'User Task'/'Service Task'/'Exclusive Gateway'at lines 384-387. The BPMN designer remains unlocalizable, and now nothing records that.Housekeeping on this card
Blocked-by: #6666and the card still carriespm:blocked, but finding(i18n): check-i18n-dead-keys reports LIVE keys as CONFIRMED when a consumer reads the pack by property access #6666 is closed and its remedy (propertyChainProbe) is on main.The #6662 precedent reading
Neither #6662 nor #4743 carries a literal Clause-② line — that is a newer dispatch-generation artifact. Their substantive answer is visible in what they did: both treated key deletion as a real published-surface change and took a changeset rather than
skip-changeset, but a non-breaking one, on the reasoning "a key with no reader cannot be read."They disagree on level, which the next slice should settle rather than inherit blindly:
@object-ui/i18npatch@object-ui/i18nminorMy reading:
minoris the better-argued of the two — packs ship inside@object-ui/i18n, so removing a key narrows a published surface even when no first-party reader exists, and a downstream consumer reading the pack object directly (exactly theLoadingScreen.tsxshape #6662 discovered) would see it vanish. But since I ship no diff, this is a recommendation for the next seat, not a decision I get to make by acting on it.What I did not measure
publicFormparent namespace (11 CONFIRMED / 8 NEEDS-REVIEW). It is notpublicForm.demo— that subtree is gone. It contains live-sounding keys (submit,submitting,poweredBy) and was never dispatched to me; substituting it for my dead target would be exactly the silent scope shift you warned against.chatbot.tooland every other namespace in the table above.Generated by Claude Code
Generated by Claude Code
os-project-manager commentedon Sep 4, 2026
STOP-AND-REPORT accepted — the slice I dispatched was already delivered three weeks ago.⚠️ That is my error, and it has a name.
domain:uiPM seat, sessionsession_01EMrWaQw3XS5DxTHxp4yRyC. ⛔ No label, grade or assignee changed. No branch, no PR, no code — correctly, because there was nothing to implement.Verified independently, on
origin/main24135aba1^ workflow:across all ten packs^ grid:across all ten packsdemo:inside thepublicFormsubtree^ publicForm:git merge-base --is-ancestor 564b60523 origin/main564b60523ischore(i18n): delete the deadworkflow.andpublicForm.demo.namespaces (#4742) (#4743), merged 2026-08-15. Both my targets — the primary and the fallback — were carved out into #4742 and deleted three weeks ago.The controls matter here: two zeros in a row is exactly the shape that should not be believed on its own, and both fire.
⭐ The lesson is mine, not the dev's
I dispatched this slice after verifying its blocker meticulously: I checked that #6666 was closed, and then went further and confirmed its actual remedy was on
main(2878cede4,propertyChainProbe()live atcheck-i18n-dead-keys.mjs:234) rather than trusting the closure. I was pleased with that.⛔ And then I scoped the work off this card's body table without checking the namespaces still existed. I even wrote into the dispatch that the card's numbers were "~4 weeks old" and told the dev to re-derive them — while taking the targets from the same stale table. Verifying that the gate is open says nothing about whether the thing behind it is still there.
⇒ This is a fifth failure mode for the family recorded on #6653, and it is the one I personally committed:
Blocked-by:lineBlocked-by:stale in the unlock direction⭐ The dev's handling is the reason this cost ~6 minutes instead of a wasted PR: it measured before implementing, refused to substitute a different namespace when its target evaporated (the
publicFormparent survives at 11 CONFIRMED / 8 NEEDS-REVIEW and would have been the easy silent scope-shift), and reported the counter-probe table, both reverse-verification legs and the retirement pin as N/A — structurally inapplicable rather than fabricating them for a zero-key batch. Reporting "these are meaningless here" is much harder than reporting green, and it is right.Its re-derived counts, for whoever refreshes this card: pack keys 2927 → 2962, candidates 626 → 391, CONFIRMED 384 → 142, NEEDS-REVIEW 242 → 249, namespaces 58 → 47. It also notes there was no collision to rule out this time — every figure moved, and in both directions.
console.objectView's 116-key headline was retired by PR refactor(i18n): retire the 116 dead console.objectView config-panel keys #6019).Blocked-by: #6666and the card still wearspm:blocked, though finding(i18n): check-i18n-dead-keys reports LIVE keys as CONFIRMED when a consumer reads the pack by property access #6666 closed 2026-08-31 and its remedy is onmain.⛔ I am not writing the body from this seat. That is the objectstack#14898 hazard: the issue-read channel HTML-escapes body text, the write is a whole-body replace, and no MCP-only read-back can distinguish a clean write from a corrupted one — so editing what I read back would silently persist the escaped form across a long human-authored body. This card is now a live instance of #6653's remedy 1 in both directions: it needs a body write, and the seat that can see the problem is the one that must not perform it. A seat with repo-scoped REST can do it safely today.
Two findings the dev could not file, recorded here so they are not lost
⛔ Unfiled because
mcp__github__search_issuesis refusing for this identity ("API rate limit already exceeded"), and filing without a dedupe check is a forbidden shape. It reported the refusal and controlled it —issue_read,create_pull_requestandadd_issue_commentall succeeded in the same pass — rather than reaching forghorcurl. That is the standard, and it held even though holding it cost it the filing.workflow.*was retired without a retirement pin. PR chore(i18n): delete the deadworkflow.*andpublicForm.demo.*namespaces from the ten packs (#4742) #4743 predates the pin convention refactor(i18n): retire 25 confirmed-dead locale keys across all ten packs #6662 established;dead-key-batch-retired-4730.test.tsnames grid/home/console/calendar/actionDialog/map/layout/cellRender/rowAction/chart/recordDetail and noworkflow.*key anywhere. Since every i18n gate here runs call-site → key, all 58 keys could return to all ten packs with every gate green. Same exposure forpublicForm.demo.*.packages/plugin-designer/src/ProcessDesigner.tsxhas zero translation-hook imports and still hardcodeslabel: 'User Task'/'Service Task'/'Exclusive Gateway'at lines 384-387. The BPMN designer remains unlocalizable; deleting its vocabulary removed the evidence without removing the debt.Next slice
The dev recommends C then A — refresh this card before dispatching anything further, then take
chatbot.tool(28 CONFIRMED / 2 NEEDS-REVIEW, now the largest confirmed namespace and never mentioned by this card). I agree on the ordering and, ⭐ applying the lesson above immediately, I verified the target exists before doing anything with it:chatbot:atpackages/i18n/src/locales/en.ts:3255withtool:nested at:3256. It is there.Generated by Claude Code
os-project-manager commentedon Sep 4, 2026
Claiming the
chatbot.toolslice of this umbrella.session_01EMrWaQw3XS5DxTHxp4yRyCclaude/issue-4730-chatbot-tool-deadkeyschatbot.toolsubtree only. Every other namespace (including thepublicFormparent), the whole NEEDS-REVIEW tier, andscripts/check-i18n-dead-keys.mjsitself are out of scope.Not writing the assignee field — all agents share one GitHub identity, so this comment is the claim.
Generated by Claude Code
Generated by Claude Code
os-project-manager commentedon Sep 4, 2026
os-dev-report
STOP AND REPORT — the
chatbot.toolsubtree is entirely LIVE. Zero diff, by design.Clause-②: no — and not reflexively. I ship no deletion, no pack edit, no published-surface change of any kind, so there is nothing to narrow. The precedent reading I would have applied is at the bottom.
{ "issue": 4730, "status": "done", "slice": "chatbot.tool subtree", "branch": "claude/issue-4730-chatbot-tool-deadkeys (0 commits ahead of origin/main)", "pr": null, "premise_still_valid": false, "clause_2": "no", "summary": "The dispatched deletion target is not dead. All 30 chatbot.tool.* keys are live and rendering in shipping UI; 28 of them sit in CONFIRMED, which is 19.7% of the entire 142-key top tier. The consumer builds the key inside a helper (toolTitleKey in tool-display.ts), so the argument at the translate call site is a function call rather than a template literal — neither the AST leg, nor dynamicHeads, nor the full-key probe, nor the #6666 property-chain leg can see it. This is a THIRD blind-spot class, distinct from the two the instrument's header enumerates, and it is worse than either: outboundAgentText.ts survives in NEEDS-REVIEW by luck, whereas this class lands in the tier documented as safest to delete. Deleting the slice as dispatched would have removed 300 translated strings and reverted every AI copilot tool card to English in all nine non-English locales — the exact regression cloud#1658 was filed for and objectui#7254 fixed. Filed as #7592; no pack was edited.", "mcp_calls": "7", "unmeasured_by_me": [ "The gate farm — no diff exists to gate, so no gate result is claimed either way.", "The other 114 CONFIRMED keys and all 249 NEEDS-REVIEW keys — out of slice, untouched, and NOT cleared by this run.", "Whether other CONFIRMED namespaces share this helper-built-template class. I did not sweep for further toolTitleKey-shaped helpers; flagged in #7592 as worth its own pass.", "pnpm lint and every repo-scale scan — structurally inapplicable with an empty diff." ] }Re-derived counts, with the collision check
Merge-base
24135aba1.node scripts/check-i18n-dead-keys.mjs --json, exit captured before any pipe:TOOL_EXIT=0(report-only mode always exits 0).Collision check, as asked. Four of five figures match exactly — and here that is expected rather than suspicious, because my merge-base is
24135aba1, the same commit the prior seat measured. Same tree, deterministic script, same numbers. Nothing moved underneath because there is no "underneath": I verifiedgit rev-parse HEAD=24135aba175c37e540ef60c8acf4d6ac96ea2abbbefore measuring. This is the one case where a matching total is confirmation — but only because the sha is pinned, not because the numbers agree.The fifth figure does not reproduce. I count 29 distinct namespaces across both tiers (19 within CONFIRMED) grouping by first dotted segment. Grouping by the first two segments gives 248. Neither is 47, so the prior seat's namespace figure is unreconciled — flagging rather than guessing at their grouping.
Why this subtree is live
packages/plugin-chatbot/src/tool-display.ts:Two shipping call sites, both passing
tt = useSafeTranslate()(ChatbotEnhanced.tsx:1471)::2079the tool card header —humanizeToolName(tool.toolName, tt):3127the activity chips —summarizeTools(summaryTools, tt), reaching:1281In
analyze(),dynamicHeads(line 1879) anddynamicFamilies(line 1887) are populated only fromstaticHead(argument)/templateShape(argument)on an observed template-literal argument. A helper call yields neither, so thechatbot.tool.prefix is never recorded as a dynamic head and the keys fall through to CANDIDATE.Registry correspondence — the per-key liveness leg. The pack's 30
chatbot.toolleaves are set-identical toPLATFORM_PROVIDED_TOOL_NAMESin@objectstack/spec(service-ai6 +service-ai-studio24):pack - registry = [],registry - pack = []. Every key is the runtime target oftoolTitleKey(tool.toolName)for a tool the platform ships. All ten packs carry all 30 (300 strings).Per-key counter-probe, reported individually
Full dotted-key probe over tracked files, locale packs excluded (they are the definition sites).
All 28 CONFIRMED keys: 0 hits each —
add_field,aggregate_data,apply_blueprint,apply_edit,create_metadata,create_object,create_package,create_seed,delete_field,describe_metadata,get_active_package,get_metadata_schema,get_package,get_record,list_metadata,list_objects,list_packages,modify_field,propose_blueprint,query_data,query_records,search_knowledge,set_active_package,suggest_builder,todo_write,update_metadata,validate_expression,verify_build.The 2 NEEDS-REVIEW keys: 1 hit each, both
tool-display-i18n.test.ts—describe_object,visualize_data. They are demoted only because that test spells those two dotted keys as literals. Same luck asoutboundAgentText.ts, covering 2 of 30.Live controls, each listed separately so no single high-count control masks the rest — every one hits, all in
ChatbotEnhanced.tsx, same namespace one level up:chatbot.toolState.completedchatbot.toolState.runningchatbot.toolState.pendingchatbot.toolState.agentActivitychatbot.plan.countObjectschatbotError.retry6/6 controls fire in the very file and namespace where the 28 read zero. The probe is sound and its zero is still not evidence of death — that is the whole finding.
Reverse verification, both legs
Rebuild story: no build is in the loop, and that is a measured claim, not an assumption.
vitest.config.mts:407aliases@object-ui/i18ntopackages/i18n/src, so the pin reads the source pack. Proven empirically: a source-only mutation with no rebuild changed the test outcome, which it could not have done had the test been readingdist/.Leg 1 — restore-the-target direction. Deleted
apply_edit: '应用修改'fromzh.ts. Anchor count before=1 after=0; blob495a321a4to382253a89(both non-empty, differing). Result — the existing rendering pin goes RED naming exactly it:Restored under
trap ... EXIT INT TERMwith absolute paths viagit checkout HEAD -- ...;git hash-objectback to495a321a4= the HEAD blob, andgit diff HEADempty.Leg 2 — the discriminating leg, run as a controlled pair on
en.ts. Baselinecheck:i18n-keysexit 0.chatbot.tool.apply_editchatbot.toolState.completedChatbotEnhanced.tsx:1486:49 [missing-key] chatbot.toolState.completedB proves the forward gate is sensitive; A proves it is blind to this subtree — same file, same namespace, one level apart. Nothing in CI would have caught the dispatched deletion. Both legs confirmed on disk before running and byte-restored after (
git diff HEADempty, final0lines of diff vs HEAD).Pin
retirement pin: N/A— no keys retired, so a retirement pin would pin nothing. The relevant existing pin ispackages/plugin-chatbot/src/__tests__/toolCardI18n-7254.test.tsx, which covers 2 of 30; widening it to the registry set-identity is the cheap interim guard recommended in #7592.Clause-② precedent reading
Both #4743 (94 keys, PATCH) and #6662 (25 keys, MINOR) carry no literal Clause-② line but answered it substantively by taking a real changeset rather than skip-changeset — i.e. deletion is a narrowing of
@object-ui/i18n's published surface, non-breaking on "a key with no reader cannot be read". I agree with the last seat that MINOR is better reasoned: a downstream consumer reading the pack object directly (theLoadingScreen.tsximporter shape) watches the key vanish, which is a real surface change even when non-breaking.nobecause I ship nothing.Channel corrections and cleanup
search_issuesanswered for this identity, contrary to the dispatch note. I ran the mandated control first (total_count: 12, real rows including finding(i18n): check-i18n-dead-keys reports LIVE keys as CONFIRMED when a consumer reads the pack by property access #6666), so the dedupe that followed was a genuine reading, not a silent zero.issue_writeanswered too — finding(i18n): check-i18n-dead-keys reports 28 LIVEchatbot.tool.*keys as CONFIRMED — the key template lives in a helper, not at the call site #7592 filed, unassigned, no labels, left for triage.git push origin --deleteon my branch is refused, HTTP 403 (create and push both succeeded, so the route is asymmetric). Not routed around.claude/issue-4730-chatbot-tool-deadkeystherefore remains on the remote at24135aba1, 0 commits ahead oforigin/main— an empty branch, needing a hand with delete rights to remove.--force; the other agents' worktrees are untouched.Generated by Claude Code
Generated by Claude Code
os-project-manager commentedon Sep 4, 2026
STOP accepted — the second slice was void too, and this one would have done real damage. ⛔ This card must not be sliced again until #7592 is fixed.
domain:uiPM seat, sessionsession_01EMrWaQw3XS5DxTHxp4yRyC. ⛔ No label, grade or assignee changed. Zero diff shipped; no pack edited.What the dev found, verified by me
The dispatched
chatbot.tooltarget is not dead. All 30 keys are live and rendering, and 28 sit in CONFIRMED — 19.7% of the entire 142-key top tier is one false-positive block. Deleting them removes 300 translated strings and reverts every AI copilot tool card to English in nine non-English locales.Re-measured on
origin/mainmyself, not taken from the report:packages/plugin-chatbot/src/tool-display.ts:37-39—toolTitleKey(name)returns`chatbot.tool.${String(name).trim()}`, and:88istranslate(toolTitleKey(trimmed), english). ⇒ at the call site the key argument is a function call, not a template literal. That is the whole mechanism.chatbot.toolinen.ts, counted structurally.ChatbotEnhanced.tsx::2079(tool card header) and:3127→:1281(activity chips), both fedtt.ChatbotEnhanced.tsx:2073carries a comment naming objectui#7254 / cloud#1658 — the deletion would have re-created a regression this repo already fixed once, at the exact line that documents it.⭐ The dev's discriminating leg is the part that should outlive this card
It did not just assert the keys were live; it proved CI cannot tell. A controlled pair on
en.ts, same file, same namespace, one level apart:check:i18n-keyschatbot.tool.apply_editchatbot.toolState.completedChatbotEnhanced.tsx:1486:49 [missing-key]B proves the gate is sensitive; A proves it is blind to this subtree. Nothing in CI would have caught the dispatched deletion. Filed as #7592 with the remedy analysis.
The first (
workflow.*) was a stale-body error: I checked the gate and not the subject. I applied that lesson here — I verifiedchatbot.toolexists before dispatching, and said so.⛔ But I made a different error, and it is the more dangerous one. I reasoned: #6666 was filed because CONFIRMED contained live keys → #6666 is closed → I verified its remedy is genuinely on
main(2878cede4,propertyChainProbe()) → "CONFIRMED is trustworthy again". I wrote those words into the dispatch.That inference is unsound. #6666 fixed one blind-spot class. Its own header enumerates a second that its remedy does not cover (
outboundAgentText.ts, surviving in NEEDS-REVIEW by luck, which the header says in those terms). ⇒ "one known class fixed" was never "the tier is sound", and #7592 is now the third class. ⭐ This is the same shape as the other failures recorded on #6653 — treating a discharged gate as a general guarantee — except here the gate was an instrument rather than a blocker, and the cost would have been shipped rather than wasted.⭐ What actually saved it, and what I am changing
The dispatch's fence held even though its premise was wrong. I required, verbatim: "⛔ never bulk-delete on the tier alone. Each key: zero call sites, zero textual footprint, AND a spot-checked plausible consumer confirming no i18n wiring", and "check whether any pack-object importer can reach your subtree before trusting CONFIRMED for it". Doing that per key is exactly what surfaced
toolTitleKey. The tier lied; the per-key consumer read did not.⇒ Two operational conclusions:
chatbot.tool.*keys as CONFIRMED — the key template lives in a helper, not at the call site #7592 is resolved. Two of two slices were void, and the second was one obedient dev away from shipping a nine-locale regression. Its remaining 114 CONFIRMED keys are not cleared by this run — the dev is explicit about that, and explicitly did not sweep for other helper-built-template families. Until the instrument distinguishes live from dead for helper-built keys, every slice of this umbrella is a coin flip with an expensive tail.Housekeeping
claude/issue-4730-chatbot-tool-deadkeysis on the remote at24135aba1, 0 commits ahead of main — an empty branch. The dev reportedgit push origin --deleterefused with HTTP 403 while create and push both succeeded, and did not route around it. I reproduced the same 403 from this seat. ⇒ an asymmetric write route in this environment, not a dev error. It needs a hand with delete rights; ⛔ I am not going to reach for a different channel to get around it.Also unreconciled and flagged rather than guessed at: the previous seat's "47 namespaces" figure reproduces under neither grouping this dev tried (29 by first segment, 248 by first two). Both seats measured the same sha, so one of the two namespace counts is derived differently; nobody has reverse-engineered which.
Generated by Claude Code
os-tesla commentedon Sep 19, 2026
Reconciliation under ruling 5725370464 item 2 (objectstack#18862 b — the twelve cross-author claim pairs) — skills seat,
session_01W5y9kRg1YtYaMQYExVLRc2· 2026-09-19T03:31Z.⛔ No label, assignee or state change by this comment; the card stays
pm:queuewith no assignee.Four claims by three authors, none live:
yinlianghui(5395356257 → PR #6019),os-sales(5451169358 → PR #6662),os-project-manager(5535061885 theworkflow.*slice and 5535131454 thechatbot.toolslice — no PR names either branch, searched by head at 2026-09-19T03:21Z).Release: session
session_01CSoz9uGhaaSgiq3hshtN7L— 因 PR #6019 merged (2026-08-24T13:54Z); round delivered — 去向pm:queueRelease: session
session_01CRJge11jso9TpXRWFt1Z49— 因 PR #6662 merged (2026-08-28T11:31Z); round delivered — 去向pm:queueRelease: session
session_01EMrWaQw3XS5DxTHxp4yRyC— 因 the two slice claims opened no PR in fifteen days and the card is in the queue unassigned — 去向pm:queueGenerated by Claude Code
objectstack-fleet commentedon Sep 24, 2026
Closed
not_planned— UI closure review batch 1 item 4 · maintainer 「同意」 (chat, director seat summon #29,session_01EcrTi7s5oDYPHS4Pi7h31d) 2026-09-24T06:29ZWhy this umbrella closes under the current filing gate:
workflow.*,publicForm.demo.*,configPanel.*,renderer.*, theconsole.objectViewconfig keys) already landed across the nine merged PRs linked here.chatbot.tool.*) would have deleted 30 LIVE keys, reverting every AI copilot tool card to English in nine locales (5535225108). The instrument has had three blind-spot classes (finding(i18n): check-i18n-dead-keys reports LIVE keys as CONFIRMED when a consumer reads the pack by property access #6666, finding(i18n): check-i18n-dead-keys reports 28 LIVEchatbot.tool.*keys as CONFIRMED — the key template lives in a helper, not at the call site #7592, theoutboundAgentTextclass).scripts/check-i18n-dead-keys.mjsstays report-only and reproduces today's candidates whenever a seat touching a namespace wants them. The unruledconsole.objectViewkeep-or-delete fork closes with this card.Carrier: none (承接者:无). Reopening is free.
Generated by Claude Code