docs(spec): translation liveness WALK BOUNDARY excepts settingsCommon and states its own boundary - #16567
Merged
huangyiirene merged 1 commit intoSep 7, 2026
Conversation
…n` and states its boundary The `_note` header claimed every translation group is a z.record keyed by target names. Measured off `translationDataShape()`, ten of the eleven are; `settingsCommon` is a fixed strictObject whose one member `sourceLabels` is itself a fixed strictObject keyed by the ADR-0010 resolution layers, a closed set. The sentence now excepts it and states where the walk's one level lands for it (`sourceLabels`, the walker's own `--undrilled` reading), that the layer keys beneath sit below the boundary, and that its blanket verdict is the declared kind (a row of undrilled-containers.baseline.json already). The `datasets` row's "as for every other group here" inherited the same universal by reference and now cites the record groups only. Prose only: no `status` moves, no schema change, no gate verdict change. The summary-count sentence in the same header is untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno
Contributor
📓 Docs Drift Check
What this run could not see
Coarse fallback — 130 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
huangyiirene
marked this pull request as ready for review
September 7, 2026 11:26
huangyiirene
enabled auto-merge
September 7, 2026 11:26
huangyiirene
deleted the
claude/issue-16135-liveness-translation-walk-boundary
branch
September 7, 2026 12:05
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #16135
What changed
packages/spec/liveness/translation.jsononly — two sentences of prose — plus apatchchangeset. Nostatusvalue moves at any nesting level; no schema, export or authorable key moves._noteheader's WALK BOUNDARY sentence:every group is a z.record keyed by target namesbecomesevery group butsettingsCommonis a z.record keyed by target names, followed by two new sentences stating what the boundary IS for that group (below).datasetsrow'sWALK BOUNDARY as for every other group here— the second instance the triage found, which inherited the universal by reference — becomesas for the other RECORD groups here (the header names the one group that is not a record). Its content was already right (datasetsis a record; the drill sees its value shape one level) and is unchanged.The summary-count sentence in the same header (
A BOUNDARY and not a total, deliberately: …, #15775 via PR #16138) is byte-identical to the base — verified by diffing that span of_notebetweenb1b978c8dfand HEAD. #15775 is not addressed here.The choice, and why: option 1 — except
settingsCommonand state its boundaryThe card names three repairs and declines to pick. I took the first; the other two were rejected on measurements, not preference:
settingsCommona declared blanket verdict of its own) is already in place.scripts/liveness/undrilled-containers.baseline.jsoncarriestranslation/settingsCommonas one of its 58 container rows — alongside the seven record groups whose value shapes are undrilled (apps,dashboards,globalActions,metadataForms,objects,pages,settings) — andcheck:liveness --undrilledprintstranslation/settingsCommon 1 key(s): sourceLabels. The blanket verdict was never undeclared; what was wrong was the header's account of WHERE the walk's one level lands for that group. No new pinned artifact is added, so the triage's flip condition is not met: 「⛔ 若承接席在动手后发现某一支要求给settingsCommon新增一条undrilled-containers.baseline.json形状的 blanket verdict(那会新增一个受钉的产物),请在 PR 里说明并把本卡改挂needs-user-decision」— the header now CITES that row rather than creating one.settingsCommonthe boundary differs in KIND — the one level lands on a named member, not on a record's value shape — and the keys beneath it are a closed set rather than author-chosen target names. A reader asking whethertenantis a ledgered key needs exactly that stated, not elided.settingsCommon(sourceLabels), that the layer keys beneath sit below the boundary, who reads them, and that the blanket verdict over them is the declared kind, citing the baseline row. No integer totals were introduced — the discipline spec(liveness): translation.json header says "11 of 12 groups live" while its own props hold 11 groups with 10 live #15775 applied to this header.sourceLabels, looked at rather than assumedRead off
packages/spec/src/system/translation.zod.ts(lines 1198–1218 atb1b978c8df) and probed withsafeParseonTranslationDataSchema:settingsCommonis astrictObjectwith one named member,sourceLabels; catchallnever.sourceLabelsis astrictObjectof exactly five optional strings —env,global,tenant,user,default, the ADR-0010 resolution layers; catchallnever. Its own comment: "The layers are a closed set (ADR-0010 / the settings resolution order), so an unknown one here is a badge that will never render, not a layer the platform is about to grow."safeParse({ settingsCommon: { sourceLabels: { env: 'Env', workspace: 'Workspace' } } })givessuccess: false, codeunrecognized_keysat pathsettingsCommon.sourceLabels, message beginningUnrecognized key(s) on the settings source-badge labels:workspace. Did you meanworkspace→tenant?. The retired spellings (org/workspace→tenant,system→global,fallback→default,environment→env) are declared asaliases, so the rejection points at the layer meant and never accepts them. The legal pair{ env, tenant }parses.resolveSettingsSourceLabel(packages/spec/src/system/i18n-resolver.ts:2570, readssettingsCommon?.sourceLabels?.[source]withsourcetyped to the five-literal union) and objectui'suseSettingsLabel().sourceLabel(apps/console/src/pages/settings/useSettingsLabel.ts:141at objectui51a402f,resolveCommon('sourceLabels.' + source)over every namespace carrying asettingsCommonblock). Both read the five keys as one unit beneath the boundary; no reader addresses a sixth.Eleven-group census, re-taken at
b1b978c8dfOff
TranslationDataSchema— whose shape istranslationDataShape()and nothing else — unwrapping lazy/optional wrappers (the probe script is quoted in the report comment on the issue):records=10 objects=1— the card's reading at1f2a02bastill holds atb1b978c8df.Clause-②:
no— measured, and both gates proven able to go redNo export, no authorable key, no accept-set movement.
check:api-surface:@objectstack/spec public API surface + factory signatures unchanged ✓(exit 0).check:authorable-surface:authorable-defaults/ verified against upstream b1b978c8df15 — 1211 default(s) unchanged, 1585 schemas generated (exit 0). The spec build left the tree clean, so every regenerated artifact is byte-identical.Red-proof on the CHECKED-IN baselines, no rebuild (the mutate-build-check trap the dispatch named is therefore not in play):
api-surface/system.json, row"TranslationDataSchema (const)"removedd1b46c8→a41d189check:api-surfacepublic API changed: 0 breaking (removed/narrowed), 1 added.authorable-surface/system.json, row"system/TranslationData:settingsCommon"removed8539634→56b98a4check:authorable-surface❌ authorable-surface/ is out of date (1 key(s) not recorded).Neither gate rewrote the shard (blob unchanged after the run). Restores:
git checkout HEAD -- PATH, thengit diff HEADempty, blob hash equal to HEAD's, anchor count back to 1,git status --porcelainempty; the script carried anEXIT INT TERMtrap with absolute paths.Verification
Every exit code below was captured by redirect-then-capture, never through a pipe; verdict lines are the gates' own.
pnpm --filter '@objectstack/spec^...' buildmatched no projects (spec has no workspace deps);pnpm --filter @objectstack/spec buildunder the verify lock:VERDICT command-exit 0, tree clean after.pnpm --filter @objectstack/spec check:liveness:✓ every governed-type property at the walk's one-level granularity is classified … every container inheritance is declared …and✓ state-counts.md is current — the same 36 row(s)(exit 0). Read as shape-only, per the dispatch: it caught nothing about the sentence and was not expected to.pnpm --filter @objectstack/spec typecheck(tsc,check:scripts-typecheck,check:test-typecheck) under the lock:VERDICT command-exit 0.VERDICT command-exit 0: specvitest run scripts/liveness scripts/zod-graph.test.ts—Test Files 12 passed (12),Tests 314 passed (314); lintvitest run src/lint-liveness-properties.test.ts src/component-field-specs-liveness.test.ts—Test Files 2 passed (2),Tests 75 passed (75).pnpm check:nul-bytes:OK (scanned 8145 text file(s) … no raw ASCII control bytes); plus a control-character self-scan of both touched files: no hit.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackatdf3ad1c0c2(merge-baseb1b978c8d, 2 paths): 53 families derived, 53 run,--ranreconciliation53 run, 0 NOT-MEASURED, 0 UNRUN. 52 exit 0.check:dual-build-cjs-loadsexit 3PREREQUISITE NOT MET … ⛔ This is NOT a pass: nothing was measured(80 sibling packages have nodist/in this worktree) — declared to CI, not read as red or green.check:dts-closure(40/40 declaration files) andcheck:sourcemap-no-sources-content(52 maps) measured the 4 packages built here (spec, formula, sdui-parser, lint); CI's population is every built package.origin/main, so the same two paths were re-derived from a detached worktree at90e7e6de11— 53 families, none added, none dropped relative to the set run.Affected-package narrowing, declared
turbo ls --affectedfromb1b978c8dflists 76 of 81 packages: spec plus every dependent. Run here: spec (typecheck, and the vitest sets above) and lint (the one runtime reader of the shippedliveness/directory:packages/lint/src/lint-liveness-properties.ts:66). Declared to CI: the two cli unit tests that read the realflowsrow through@objectstack/lint(packages/cli/test/i18n-flow-liveness-gate.test.ts,packages/cli/test/i18n-flow-screen-coverage.test.ts— cli's workspace closure is 49 packages, unbuilt here), and the remaining dependents' suites. Why this is a measurement rather than a skip:git grepover tracked*.ts/*.mts/*.mjs/*.tsxfinds no import ofliveness/translation.json; every reader of the ledger is one of the liveness scripts (run), the lint rule (run), the two cli tests (declared), or a gate (run); and the diff is a string literal in a JSON data file plus a changeset, with everystatusvalue those readers consult untouched.Changeset
Owed and added —
.changeset/translation-liveness-walk-boundary.md,@objectstack/spec: patch.liveness/is in@objectstack/spec'sfilesarray, so the_noteships in the npm tarball, and the same-file precedent (PR #16138 for #15775) carried one. Notskip-changeset.Not touched
validation.json/view.json/state-counts.md(#16542) andmanifest.json/README.md(#16532): untouched, no collision. No per-propstatusmoved. No other ledger's similar wording was harmonised (the triage's ⛔). Draft; not flipped ready, not enqueued.🤖 Generated with Claude Code
Generated by Claude Code