|
| 1 | +--- |
| 2 | +"@objectstack/cli": patch |
| 3 | +"@objectstack/plugin-approvals": patch |
| 4 | +"@objectstack/plugin-audit": patch |
| 5 | +"@objectstack/plugin-security": patch |
| 6 | +"@objectstack/plugin-sharing": patch |
| 7 | +"@objectstack/plugin-webhooks": patch |
| 8 | +"@objectstack/service-messaging": patch |
| 9 | +"@objectstack/service-realtime": patch |
| 10 | +"@objectstack/service-storage": patch |
| 11 | +--- |
| 12 | + |
| 13 | +chore(i18n): roll the generated-leaf provenance companion out to the remaining bundle sets (#12559) |
| 14 | + |
| 15 | +`os i18n extract --source-hashes` (#11671, maintainer ruling #12069 Option A) |
| 16 | +records, per generated translation leaf, the digest of the source revision that |
| 17 | +leaf is **still a byte copy of** — the one signal that tells a stale fill from a |
| 18 | +real translation once the source has moved and the two stopped being |
| 19 | +distinguishable by value. It shipped opt-in, and exactly one of the nine i18n |
| 20 | +bundle sets opted in. A landed detector, a changeset announcing it and a green |
| 21 | +gate read together as *"generated translation staleness is now caught"*; for |
| 22 | +eight of nine sets it was not, and the thing making it not caught was a single |
| 23 | +absent flag in an extract config — invisible from all three of those surfaces. |
| 24 | + |
| 25 | +**All eight remaining sets now opt in** — `plugin-approvals`, `plugin-audit`, |
| 26 | +`plugin-security`, `plugin-sharing`, `plugin-webhooks`, `service-messaging`, |
| 27 | +`service-realtime`, `service-storage`. Each documents `source-hashes` in its |
| 28 | +extract config and commits three `<locale>.source-hashes.generated.ts` |
| 29 | +companions, produced by the same extract run as the bundles they sit beside |
| 30 | +(`check:i18n` compares them byte-for-byte, so they cannot be written by hand). |
| 31 | +`check:i18n` now reports 7 bundles per set where it reported 4, and 11 for |
| 32 | +`platform-objects` where it reported 8. |
| 33 | + |
| 34 | +**Records count what is currently RECORDABLE, never what is covered.** A record |
| 35 | +is written only for a leaf that *is* right now a byte copy of the current |
| 36 | +source, so a fully translated locale starts with an empty table — which is the |
| 37 | +instrument armed, not an instrument that measures nothing: the entry appears by |
| 38 | +itself on the first extract after a leaf becomes a fill. Measured at this |
| 39 | +commit, per set over its three translated locales: `service-messaging` 289, |
| 40 | +`plugin-approvals` 61, `plugin-security` 33, `plugin-webhooks` 20, |
| 41 | +`plugin-audit` 8, `service-storage` 7, `plugin-sharing` 1 (es-ES only; zh-CN and |
| 42 | +ja-JP are fully translated and start empty), `service-realtime` 0 (all three |
| 43 | +locales fully translated). **419 records written across the eight sets, 0 |
| 44 | +stale.** |
| 45 | + |
| 46 | +**One extractor fix the rollout forced.** `--source-hashes` had one user, and |
| 47 | +that user commits both generated sections, so the interaction with |
| 48 | +`--no-metadata-forms` had never been exercised. The provenance table is computed |
| 49 | +over every generated section the extractor builds; the eight sets here commit no |
| 50 | +metadata-forms bundle, and their `metadataForms` subtree — absent from their |
| 51 | +merge baseline — arrives as a fresh `--fill=default` copy of `en`, so every leaf |
| 52 | +of it was recordable. First measured on `plugin-audit`: **763 records, of which |
| 53 | +2 were its own objects and 761 were digests of the Studio metadata-form baseline |
| 54 | +`@objectstack/platform-objects` owns.** Those records are unreadable in the |
| 55 | +package holding them and would have rewritten all 24 companions on any unrelated |
| 56 | +`*.form.ts` change in `packages/spec` — the cross-package coupling ADR-0029 D8 |
| 57 | +and every `bundle-ownership.test.ts` keep out of committed bundles. The |
| 58 | +companion now covers exactly the sections a run commits, decided by the same two |
| 59 | +predicates that decide the bundle files. `platform-objects` commits both, so its |
| 60 | +three committed companions are byte-for-byte unchanged. |
| 61 | + |
| 62 | +**Grade: `patch`, and behaviour on the day it lands is unchanged for every |
| 63 | +leaf.** A record is written only where a leaf is currently a byte copy of the |
| 64 | +**current** source, so every record written equals the current digest and none |
| 65 | +of them can be stale; the mechanism cannot arrive red. No committed translation |
| 66 | +bundle changed a byte, no public API moved, and no leaf's rendered text changed. |
| 67 | +`narrowToCommittedSections` is new but internal to `@objectstack/cli` — the |
| 68 | +package's entrypoint does not re-export the extractor utils. |
| 69 | + |
| 70 | +**What this does not do**, stated so the boundary is not inferred wrongly a |
| 71 | +second time: these eight sets now *record* provenance. Reading it at serving |
| 72 | +time is `withSourceFallback`, and that is still wired in |
| 73 | +`@objectstack/platform-objects` alone — so a stale fill in one of the eight is |
| 74 | +now recorded and reportable, but not yet substituted at runtime. Tracked |
| 75 | +separately. |
0 commit comments