Repository navigation
fix(platform-objects): decide the hook panel's execution en-echoes per leaf, and pay round 5's cross-panel exclusion - #19530
Conversation
…r leaf Round 6 of #19403 takes the `hook` panel's ten remaining en-echoes — `body.memoryMb`, the hook-level `timeoutMs`, and the three `retryPolicy` keys — and renders each from evidence recorded per leaf. Also rewords `body.capabilities` on BOTH panels that declare HookBodySchema (zh-CN 功能 -> 能力, ja-JP 機能 -> ケイパビリティ), which round 5 recorded rather than improved because rewording is the hook family's act. es-ES already read Capacidades and is unchanged. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NcPSwnmJHczmTu6FG7NMjE
… decisions `pnpm i18n:extract` dropped exactly the 10 decided leaves' provenance rows in each of the three translated locales (30 rows) and added none; the metadata-forms bundles round-tripped byte-identical. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NcPSwnmJHczmTu6FG7NMjE
…harge round 5's exclusion Adds `hook-execution-panel-echo-decisions.test.ts` — one row per decided leaf with its verdict, its reason and the `en` source it was judged against, carrying the echo predicate with a dark control, the population derived from `en`, the provenance second witness, the machine-token guard (now judged on Unicode word boundaries, because this family keeps a bare `N`), the composite blind spot on the hook side, and the #19430 readings asserted against the live HookSchema rather than described. Updates `action-body-panel-echo-decisions.test.ts`: its cross-panel invariant excluded six of thirty pairs because `hook.fields.body.memoryMb` was itself an echo, and said a later round owed it. It is paid — the exclusion set is empty and a `compared` counter keeps the assertion lit. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NcPSwnmJHczmTu6FG7NMjE
@objectstack/platform-objects is `private: false` with `files: ["dist", …]` and the decided values reach `dist` — probed with controls, so a zero in the raw column reads "escaped", not "absent". `skip-changeset` is measurably wrong here. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NcPSwnmJHczmTu6FG7NMjE
📓 Docs Drift Check3 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. What this run could not see
Coarse fallback — 3 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 89f9269559f0d1bcde8786452e630d9df56a76b5 && git checkout 89f9269559f0d1bcde8786452e630d9df56a76b5
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin eec56c37dfc89086658c1659bb2da869dfa08d4f a7ab791e912d271000b9a18d4b905c8d3621688f && git checkout -B drift-repro eec56c37dfc89086658c1659bb2da869dfa08d4f && git merge --no-ff a7ab791e912d271000b9a18d4b905c8d3621688f
node scripts/docs-audit/affected-docs.mjs --json eec56c37dfc89086658c1659bb2da869dfa08d4f |
Part of #19403
Clause-②: no
Round 6 of #19403. The
hookmetadata-form panel's ten remaining en-echoes, decided one leaf at a time, with the reason recorded for each. With them the panel is finished: zero of its 47 string leaves now echoes its English source in all three locales.The family, and why the leaf count did NOT decide it
Re-measured on this branch's base
0e671d20c— the four remaining families, in both counts:seed·mapping·api·doc·book·capability)object.fields.enable.*(+validations)hook.fields.retryPolicy.*+body.memoryMb+timeoutMs← takenreport.fields.drilldown+runtimeFilter+sections.dataset_bindingThis family is third of four by leaves, so the tie-break is written down — in the ledger's header and here. Two of the four reasons are ones no other row can offer:
HookBodySchemachildren × 2 props × 3 locales = 30 pairs and excluded 6 of them, becausehook.fields.body.memoryMbwas itself an en-echo and an unauthored twin carries no evidence. That file asserts the exclusion by name and states that a later round of this card owes it. Decidingbody.memoryMbhere pays it: the exclusion set is empty, 30 of 30 pairs are compared, andmemoryMbis guarded on both panels. Ablation D reds that landed assertion, which is the proof the discharge is real.hookForm's enumerated-but-unwalked children at seven — the fivebody.*plusretryPolicy.maxRetriesandretryPolicy.backoffMs— and closed the five on theactionside only. The tworetryPolicychildren are what was left.body.memoryMbtakes a twin that exists only because round 5 created it;timeoutMstakes an authored twin one level down the same panel at a byte-identicalen;retryPolicy.*has no twin anywhere and is composed from this catalog's authored answers for its separate words.objectandreportwould complete theirs too.And why not the six bare pairs, which lead by leaves: round 5's refusal stands unchanged — only a real panel keeps the DERIVED-POPULATION property with a working dark control, and six unrelated types degenerate the derivation into six one-entry lookups with nothing for the control to exclude.
The ten decisions
Every verdict is
translatein all three locales; every row records the authored leaf its wording came from.enbody.memoryMb.labelMemory Mbbody.memoryMb.helpTextPer-invocation memory cap (MB, max 256)256kept as a numeral (ScriptBodySchema.max(256))timeoutMs.labelTimeout MstimeoutMs.helpTextAbort the hook after N millisecondsNkeptretryPolicy.labelRetry PolicyretryPolicy.helpTextRetry on failure — most useful for async hooksasyncread at the schema: a boolean, not a tokenretryPolicy.maxRetries.labelMax RetriesretryPolicy.maxRetries.helpTextMaximum retry attempts3deliberately not renderedretryPolicy.backoffMs.labelBackoff Mssys_job_queue.fields.backoff_type.label's authored answerretryPolicy.backoffMs.helpTextDelay between retries (ms)1000not renderedWhat was refused. Four of the five labels are the extractor's humanize of a camelCase key, not authored English — exactly where round 5's phantom-translation reading bites.
Memory Mb→Memory (MB)orMax Retries→Max Retries (3)would differ in bytes, pass the echo predicate in all three locales, drop the census by a key and tell a zh-CN author nothing. Every one is rendered into the locale's own writing system instead, and the enumerated verdicts — not the census — are what shows it.The #19430 discipline, and the near-miss this family had to clear
Read at the schema before a word was rendered, and asserted against the live
HookSchemarather than described:timeoutMs.helpTextsays "Abort the hook after N milliseconds", andabortis a legal value ofHookSchema.onError(z.enum(['abort','log'])). The near-miss is real. It is cleared because the key this tooltip describes takes a number — the schema accepts5000and refuses"5000 毫秒"— so no rendered word can land in it, and the schema's own description uses the word as the runtime's verb ("before the hook is aborted"). Rendered.retryPolicy.helpTextnamesasync.HookSchema.asyncisz.boolean().default(false)— acceptstrue, refuses"异步"— so it is not a A metadata-form tooltip spells a strict enum's legal values in translated locales, so the value an author is shown is one the schema refuses #19430 token. Rendered, taking this panel's own authored 异步 / 非同期 / Asíncrono one entry up.retryPolicyis astrictObject, not an enum; its alias map governs KEY spellings, which no label renders. Its defaults are{maxRetries: 3, backoffMs: 1000}and neither tooltip carries a number — asserted both ways.Nand256are kept verbatim, and the token guard now judges Unicode word boundaries rather than substring containment:'Número máximo de reintentos'.includes('N')istrue, so round 5's containment check would have passed a locale that lost the placeholder entirely. That is a control, and ablation E reds it.A second act:
body.capabilitiesreworded on both panelsRound 5 recorded rather than improved that zh-CN 功能 and ja-JP 機能 read "feature" for what is a capability token from the
HookBodyCapabilityenum — and left the reword to the hook family, because both forms declare the same schema key and diverging is the defect the cross-panel invariant guards. This round is the hook family.The replacement is derived, not invented: every authored leaf of the objects catalog whose English names a capability renders it 能力 (zh-CN) and ケイパビリティ (ja-JP), and none of them uses 功能 or 機能. The ledger asserts that derivation over the catalog rather than quoting it. es-ES already read
Capacidades— the same word those leaves use — and is unchanged, which is why the zh-CN and ja-JP bundle diffs are two lines larger than es-ES's. The neighbouring senses (object.sections.capabilities= 功能开关, the feature CHECKBOXES;agent.sections.capabilities= 能力配置) are deliberately untouched and pinned as such.The measurements, each with its control in the same run
0e671d20censtring leaves /.labelleaves.labelleaveshookpanel leaves echoing in all threeEchoes −5 keys, control +5 in each locale, same population, same run. Two counts for two questions — the headline moves by 5 because only labels are counted, while this round decided 5 labels and 5 helpTexts.
hook.fields.__probe__.label).enis untouched.pnpm i18n:extract, never by hand. It dropped exactly the 10 decided leaves' provenance rows in each of the three locales (30 rows, listed in full in the report comment) and added none; the metadata-forms bundles round-tripped byte-identical.capabilitiesreword on the two panels; es-ES needed none.The concurrent PR that held this region
PR #19520 HAD LANDED by the time of the pre-push merge — so the required check was not vacuous, and it passes. Its leaf is
view.fields.userFilters.helpText, and in all three bundles this branch carriesorigin/main's value, not the base's:base != main(the fix moved it) andhead == main(it survived) hold forzh-CN,ja-JPandes-ES. The merge brought its one-line-per-bundle change in cleanly, exactly as the dispatch's five-round measurement predicted. That changeset —19430-user-filters-element-tokens— is this card's own round-2 finding coming back fixed by another seat, so silently reverting it would have been this lane undoing its own filed work.The instrument — five ledgers extended, not rebuilt
hook-execution-panel-echo-decisions.test.tscarries every property the five earlier rounds established, plus two this family added:translate);encatalog, with a dark control naming keys that exist on other types — includingaction's ownbody.memoryMbat a byte-identicalen;*.source-hashes.generated.tscompanions, with its own pattern-matched dark control;ensource pinned equal to the live bundle, for the decisions and the rewords;N;comparedcounter keeping it lit;action-body-panel-echo-decisions.test.tsis updated in the same PR: its exclusion set is emptied, its lit assertion becomes a counted 30, and the prose that quoted the old capability wording now points at the derivation behind the new one.Five ablations, ten assertions, two files
Each ran mutation → run → restore inside one
scripts/ablation-replace.mjsprocess, which proves the mutation landed by blob hash and proves the restore byblob == HEADplus an emptygit diff HEAD. No rebuild is involved: these tests resolve the bundles as sibling sources, not throughdist.zh-CN hook.fields.retryPolicy.labelwith itsenzh-CN: every decided leaf matches its verdict;no leaf on this panel reads its en source…ensource under the pinned rowevery row is pinned to the live en source;the echo predicate can say "echo"zh-CN: no decided leaf is still recorded as an extractor fillbody.memoryMbdifferently on the two panelsthe half NO single-panel pin can see;30 of 30 pairs agree;the invariant can fireNplaceholder from the es-ES tooltipthe machine tokens… are still verbatim;the token predicate can say NOChangeset — measured, not assumed
@objectstack/platform-objectsisprivate: falsewithfiles: ["dist", …], and the decided strings reachdist: each appears in 6 built files, escaped (\uXXXXupper-case hex, and\xNNfor U+0080–U+00FF —Pol\xEDtica de reintentos). A raw un-escaped negative control reads 0 including for the positive controls, so a zero in the raw column means "escaped", not "absent", and a never-written string reads 0 in both columns. ⇒ apatchchangeset;skip-changesetis measurably wrong.Acceptance notes
Zero cards to file, and that is a reading rather than a silence. The leaf that could have carried the known #19430 trap is
hook.fields.timeoutMs.helpText, whoseabortis a realHookSchema.onErrorenum value — it was checked at the schema, found to describe a numeric key, and cleared, with the check asserted in the ledger so a schema change reds it.retryPolicy.helpText'sasyncwas checked the same way and is a boolean. Neither is a defect, and neither is a card.Noted, not filed:
hook.labelisGanchoin es-ES while every es-ES sentence on the panel sayshook(hook.sections.identity.description,hook.fields.condition.helpText,hook.fields.async.helpText, and nowtimeoutMs.helpText, which copies that convention). This is a wording inconsistency inside one panel, not a reproducible defect, not a contract violation, and not a metadata-authoring trap — the author writes neither word. Carrier: 无 (no PR or person is queued to touch this file for it); it belongs to whichever round of 83 metadata-form label keys ship their English source in all three locales (249 leaves) and no pin sees any of them #19403 takes a family that renders the type's own display pair. Dedupe words:es-ES,Gancho,hook.label,metadata-forms,panel vocabulary.permission.fields.systemPermissions.helpTextrenders "system capability keys" as システム機能キー in ja-JP, which is the word this PR just replaced for the hook body's capability tokens — but that leaf is a permission capability, a different sense, and it is authored and outside this family. Recorded so a later round does not read this PR's reword as a sweep. Carrier: 无. Dedupe words:ja-JP,機能,ケイパビリティ,systemPermissions,capability wording.Neither carries
class: a|b|cevidence, so by this round's reporting contract both stay here as prose.Generated by Claude Code