Skip to content

docs(skills): objectstack-i18n lists every top-level translation group and the nested form, tab and approval keys - #26388

Merged
os-zhuang merged 2 commits into
mainfrom
claude/project-thread-mu5kbd
Oct 27, 2026
Merged

os-zhuang merged 2 commits into
mainfrom
claude/project-thread-mu5kbd

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Warren · project thread
Fixes #26296
Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:skills/objectstack-i18n/SKILL.md 的对象子键表补上表单视图自己的 title(_views)和表单分区条目的 label / placeholder / helpText(_sections.{section}.fields);顶层分组清单补齐 picklists、reports、positions、permissions,并各用一行写明页面 page:tabs 条目标签与审批步骤标签的键路径,以及 os i18n extract --no-objects-only 会把它们一并生成。评测文件加两道题(报表 + 权限集 + 岗位 + 选项列表;四个嵌套键)。评测文件 token 天花板按你的裁决从 1004 提到 1451。
  • 为什么改:18.2 的翻译包多了 reports、positions、permissions 分组和这几个嵌套键,技能里的清单读起来像是完整的,AI 作者照着写 zh-CN 包就会漏掉报表、岗位和权限集,而且没有任何提示。
  • 风险与回滚:只改一份已发布技能的文字、它的评测文件和棘轮脚本里的一行天花板数;不发包、不改代码、不改 schema。回滚 = revert 本 PR 的一个提交。
  • 先看:① skills/objectstack-i18n/SKILL.md L169–L181(顶层分组清单与两条嵌套键);② 同文件 L163、L165(_views 的 title、_sections 的 fields);③ scripts/check-skills-token-ratchet.mjs L657–L667(天花板行 1004 → 1451 与引用的裁决)。
  • 两分钟验证:node scripts/check-skills-token-ratchet.mjs,预期退出 0,且印出 bundles-locales-coverage.json is 1451 tokens (ceiling 1451; headroom 0) 与 SKILL.md is 5282 tokens (ceiling 6333; headroom 1051)。
  • 需要你做的:批准(Tier H,skills/** 为对外发布面;席位不会 ready、不会入队)。

What changes

skills/objectstack-i18n/SKILL.md (503 → 512 lines; 5028 → 5282 tokens, headroom 1305 → 1051, no ceiling moved):

  • _views.{view_name} row: adds title — a form view's own heading, translated only where the form authors one; a list view has none (translation.zod.ts 303–320).
  • _sections.{section_name} row: adds fields.{field_name} with the label, placeholder, helpText an entry overrides for that form alone, and says why the spelling is helpText here and help one row up (translation.zod.ts 455–490: each spells what its source does).
  • Top-level group list: now names every group the per-app bundle declares — picklists (pre-18.0, previously unlisted), reports, positions, permissions added, each with the one line an author needs (reports / positions / permissions hold label + description by name; picklists holds label + options by stored value, inherited by every field referencing the picklist; permissions is spelled as the stack's permissions[]).
  • One line each for the two keys that sit deeper than their group's label: pages.{page}.components.{tabs_id}.items.{value}.label (keyed by the item's value; no value, no key) and flows.{flow}.approvals.{node_id}.label, plus the scaffold that writes them: os i18n extract --no-objects-only — every group above but messages and settingsCommon, which the extractor never emits — (the default --objects-only emits only objects / globalActions; packages/cli/src/utils/i18n-extract.ts 63–131 lists the walk).

skills/objectstack-i18n/evals/bundles-locales-coverage.json (55 → 75 lines; 1004 → 1451 tokens):

  • The --objects-only warning paragraph names the dataset, report, picklist, position and permission coverage kinds os i18n check reports beside the six it listed (review item 3).
  • Eval 6 — the card's acceptance eval: a report, a permission set, a position and a picklist; negative pins permissionSets and the singular report: { alias.
  • Eval 7 — the four nested keys (form title, section entry placeholder, page:tabs item, approval step); negative pins stepLabel and an object-level _tabs.overview key.

scripts/check-skills-token-ratchet.mjs: the eval file's CEILINGS row 1004 → 1451 (+447, the measured size of the two prompts), with the ruling quoted on the row.

Package reading (SKILL.md + references/**/*.md + rules/**/*.md): 533 → 542 lines (references/_index.md 30 → 30, generated, unchanged). Authored tokens 6032 → 6733.

Nothing is removed: the card names no stale line, and the line that existed (the group list) is extended, not replaced.

Why

The skill's enumerated lists read as complete. The bundle gained reports, positions and permissions as top-level groups, the section entry overrides, the form view title, the page tab item and the approval step label, and none of them was taught — so an AI author shipping a zh-CN pack from this page leaves reports, positions and permission sets in English, and nothing reports a missing key (audit row I1–I5 of the skills gap audit; priority:p1, 18.2 headline rows).

The token ceiling

The eval file sat at zero headroom (1004 / 1004) under the shrink-only check-skills-token-ratchet. The maintainer ruled on the seat thread's decision card, question 「skills 修复卡的教学和 eval 都撞 token 天花板,怎么付?」, tap label verbatim and untranslated:

「A:先削重复,余额按实测提高」

Paid down first: the eval file carried no duplicated content to delete (five prompts, five distinct surfaces — bundle authoring, a new locale, the translation item, a plugin's generated bundle, the --objects-only diagnosis), so the remainder is the whole addition, 447 tokens, and the row is pinned at the measurement with zero headroom. SKILL.md needed no raise (1075 tokens of headroom remain). Arithmetic: evals +447 (ceiling +447), SKILL.md +254 (ceiling +0); bundle +701, ceilings +447.

Tests

No package is touched, so no package test or typecheck is owed. The gate script edited (check-skills-token-ratchet.mjs) carries its own --self-test, which ran green on the final tree; no *.test.* file names that script (git grep -l check-skills-token-ratchet -- '*.test.*' returns nothing).

Ratchet and self-test on 6181b12
node scripts/check-skills-token-ratchet.mjs                 :: exit 0
  ✓ skills/objectstack-i18n/SKILL.md is 5282 tokens (ceiling 6333; headroom 1051)
  ✓ skills/objectstack-i18n/evals/bundles-locales-coverage.json is 1451 tokens (ceiling 1451; headroom 0)
  ✓ 81 authored bundle file(s) within their ceilings; 10 generator-owned file(s) measured, not ratcheted.
node scripts/check-skills-token-ratchet.mjs --self-test     :: exit 0
  ✓ check-skills-token-ratchet self-test: 79 cases pass.
node -e "JSON.parse(readFileSync('skills/objectstack-i18n/evals/bundles-locales-coverage.json'))"  :: JSON ok

Acceptance notes

  • The --objects-only warning paragraph in the same file (L394–L398 before this PR) still lists the coverage kinds as app, navigation, dashboard, widget, page and flow; os i18n check also reports report, picklist, position and permission buckets (packages/cli/src/utils/i18n-coverage.ts 356–384, 450–454). Fixed in this PR at the review's suggestion (rework 6181b122, inside SKILL.md's headroom; now L402–406).
  • The spec line references in the card body (translation.zod.ts:602-608, 724, 1140-1143) do not match origin/main at 756220c; the readings used here are reports 1161–1168, positions 1698–1705, permissions 1721–1728, picklists 902–911, _views.title 320, tab items 1353–1359, approvals 1668–1680, _sections.fields 476–490.
  • The card's「:165 adds fields.FIELD (label, placeholder, helpText)」is right as written: under _sections.SECTION.fields.FIELD the canonical key is helpText (help is the alias); only the object-level fields.FIELD spells it help. No duplicate object-level fields row was added.
  • skip-changeset: the skills package carries no package.json; scripts/** ships in no package's files[].

Verification

Derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack on the final tree (6181b12), every command run with its exit code captured before any pipe, reconciled with --ran.

Reconciliation: 52 derived, 51 green, 1 NOT MEASURED (exit 3)
✓ dispatch-gates --ran: 52 derived famil(ies) accounted for — 51 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3).

Green (exit 0): check-ci-filter-parity, check-closing-keyword-parity (+ self-test), check-comment-mask-corpus, check-declaration-mirrors (+ self-test), check-doc-route-spelling --advisory (+ self-test), check-dts-emitted --self-test, check-scripts-symbol-anchors (+ self-test), check-self-test-wired (+ self-test), check-self-test-workflow-commands (+ self-test), check-skills-token-ratchet (+ self-test), check-whole-set-label-write (+ self-test), ci/assert-turbo-remote-cache --self-test, ci/prune-turbo-cache --self-test, pm/bare-root-worklist --self-test, spec check:skill-docs, check:agent-test-spelling, check:bash32-floor, check:cli-command-ids, check:corpus-claim-drift, check:cross-package-test-inputs, check:doc-authoring, check:driver-memory-census, check:entry-guard, check:gitlink-declared, check:merge-driver, check:nul-bytes, check:parse-guard, check:pm-dispatch-gates, check:pm-governed-merges, check:pm-skill-id-lint, check:pnpm-filter-targets, check:pnpm-flag-spellings, check:ratchet-remedy-authority, check:refd-timer-probe, check:role-word, check:skill-compatibility, check:skill-frame-sync, check:skill-identifier-liveness, check:watch-hint-literal, lint check:doc-formula-expressions, check:dts-closure, check:lean-entry-closure, check:sourcemap-no-sources-content (the four after building the closures they read, under the shared verify lock).

NOT MEASURED locally (exit 3, PREREQUISITE NOT MET: it reads every workspace package's built dist, which a fresh worktree does not have; this diff touches no package, so no whole-tree build is owed and CI runs it on a built tree): check:dual-build-cjs-loads.

check:skill-refs is not in the derived set: references/_index.md is generated from the SKILL.md frontmatter and the schema exports, neither of which moved, and the file is byte-identical to origin/main.

Human Minimum

Each item is one rule from
CONTRIBUTING.md › Human Minimum,
which links the AGENTS.md text that states it.

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (No schema or runtime file is touched.)
  • 2. Every name I added uses the casing for its kind. (Only eval fixture names, all snake_case machine names.)
  • 3. No formatter ran (none did); pnpm lint is the repo-level scan CI's Lint & Repo Gates owns — not run locally.
  • 4. One issue, one branch off an up-to-date main (756220c), one pull request.
  • 5. A change that publishes carries a changeset — this one publishes nothing (skip-changeset); both declaration lines are filled in above.
  • 6. packages/spec touched: no.
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English (the 维护者速读 brief is Chinese by the repo's communication rule for maintainer-facing summaries).
  • The Before Submitting list in CONTRIBUTING.md is done. (Every item holds except pnpm lint, which is not run locally; the change reaches no package test, updates the documentation it is about, publishes nothing, carries nothing unrelated, and touches no auth surface.)

Generated by Claude Code

…ted keys the bundle gained since 18.0

The object sub-key table gains a form view's own `title` under `_views`
and the section entry overrides (`label`, `placeholder`, `helpText`)
under `_sections.{section}.fields`; the top-level group list now names
every group the per-app bundle declares (`picklists`, `reports`,
`positions`, `permissions` added), with one line each for a `page:tabs`
item label and an approval step label and the scaffold that writes them.

Two eval prompts cover the new teaching (a report, a permission set, a
position and a picklist; the four nested keys). The eval file sat at zero
token headroom with nothing duplicated to delete, so its ratchet row
rises by exactly the measured addition under the maintainer's ruling
quoted on the row.

Claude-Session: https://claude.ai/code/session_01JQwxbXbFVr7jEKWyQKnPm9
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Reviewed at 2026-10-27T02:10Z · PR #26388 (card #26296, skills/objectstack-i18n) · independent contract review at the ceiling tier; nothing below is the dispatch order's, the seat's or the dev's conclusion.

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 76220ce3c8fc008ee27c697c0c9984c38df41341
Local-runs: probe — the ratchet's own measure ceil(utf8 bytes / 4) (minus the stamp line on SKILL.md) recomputed over the four git show blobs of the two skill files on origin/main and on the head; a byte count, nothing built, run or re-run
Scope: skills/objectstack-i18n/SKILL.md, skills/objectstack-i18n/evals/bundles-locales-coverage.json, scripts/check-skills-token-ratchet.mjs + packages/spec/src/system/translation.zod.ts, packages/spec/src/stack.zod.ts, packages/cli/src/utils/i18n-extract.ts, packages/cli/src/commands/i18n/extract.ts, packages/cli/src/utils/i18n-coverage.ts, packages/spec/liveness/translation.json, skills/objectstack-i18n/references/_index.md, .github/workflows/lint.yml, .claude/agents/os-dev.md, .github/PULL_REQUEST_TEMPLATE.md

Readings: PR read over REST at 2026-10-27T02:05Z — draft: true, mergeable_state: clean, head 76220ce3, base ref main (base sha abb90460), labels documentation / size/s / skip-changeset, assignee os-warren, reviewers hotlong + os-zhuang requested. Check-runs on 76220ce3 read once at 2026-10-27T02:05Z: 50 runs, none in progress; every non-skipped run success — Type Check · source gates (carries check-skills-token-ratchet + its self-test, check:skill-docs, check:skill-refs, check:ratchet-remedy-authority), Type Check · consumer gates (carries check:skill-examples), Lint · ESLint, Lint · repo & tooling gates, Lint · docs & code guards, Lint & Repo Gates, Check Changeset, Governed Surface Queue Guard, Part-of PR must not also close its card, The card this PR closes must claim this branch, No other open PR may claim the same issue, Build Core, Test Core 1–8/8; the UI, docs, dogfood-shard and opt-in runs skipped (filter). Lane correction confirmed by reading lint.yml on origin/main: the ratchet and the two skill checks live in Type Check · source gates, not the Lint lanes. Diff against the merge-base 756220c4 is exactly the three files of the file list (+41/−4); references/_index.md is byte-identical.

① Derived judgments

(a) Every new sentence against the spec and the CLI on origin/main (translation.zod.ts is the spec; i18n-extract.ts is what os i18n extract writes).

  • _views.{view_name} row gains title — RIGHT. translation.zod.ts 304–320 declares title on _views as a form view's heading, applied only where the form authors one; a list view carries none (318: the key over one resolves nothing). The row's parenthetical restates exactly that.
  • _sections.{section_name} row gains fields.{field_name} with label, placeholder, helpText — RIGHT, and the spelling note is right: 476–490 declare the three keys with helpText canonical and help as the alias (483), while the object-level FieldTranslationSchema (119–125) spells it help with helpText as the alias (122). The dispatch order's "Correction A" (teach help, name helpText as alias) was wrong for this nested row; the dev read the schema and withdrew it, which is the correct reading. No duplicate object-level fields row was added.
  • Top-level group list — COMPLETE. appTranslationDataShape() declares, in order: objects 888, picklists 902, apps 914, messages 931, globalActions 954, dashboards 968, datasets 1100, reports 1161, pages 1210, flows 1571, positions 1698, permissions 1721, metadataForms 1776, settingsCommon 1807 — fourteen; settings (1884) is the platform-only fifteenth, which the skill already refuses by name. The head's list names all fourteen (thirteen beside objects); no group is omitted. picklists was never listed before and is a real per-app group, so adding it is inside "lists every top-level group" (Wanted), not beyond it.
  • picklists (label, options by stored value — every field referencing the picklist inherits them) — RIGHT (894–911).
  • reports, positions, permissions hold label + description by name — RIGHT (1161–1168, 1698–1705, 1721–1728). "permissions (permission sets, spelled as the stack's permissions[])" — RIGHT: stack.zod.ts:808 permissions: z.array(PermissionSetSchema), and the spec comment at 1710–1713 says the group is spelled as the stack spells the collection; permissionSets is an alias the door rewrites (1958).
  • pages.{page}.components.{tabs_id}.items.{value}.label "(by the item's value; an item without one has no key)" — RIGHT (1353–1359, the describe at 1359 says exactly that).
  • flows.{flow}.approvals.{node_id}.label — RIGHT (1668–1680; keyed by the approval node's FlowNode.id).
  • "os i18n extract --no-objects-only scaffolds every group above, both keys included" — WRONG for two of the thirteen groups the sentence points at. The walk surface (i18n-extract.ts 63–129) and the walk itself (1620–1630 walkReports / walkPicklists / walkSecurityCatalog, 1314 the page:tabs items, 2237 approvals.NODE.label, 2271–2306 metadataForms into its companion module) write objects, globalActions, apps, dashboards, datasets, reports, picklists, pages, flows, positions, permissions, metadataForms — and NOTHING for messages (free-form ids; zero ['messages' emission in the file) or settingsCommon (zero hits in i18n-extract.ts and commands/i18n/extract.ts). --no-objects-only maps to kind: 'stack' (2705–2722), whose payload is stackAuthoredSubtree(data) (2559–2562) — everything the walk harvested minus metadataForms — so the module an author gets holds no messages and no settingsCommon skeleton. The liveness ledger gates nothing today (packages/spec/liveness/translation.json carries no top-level authorWarn; the flows warn was dropped 2026-10-05), so the twelve walked groups and both nested keys ARE scaffolded; "every group above" is the overclaim. The card's Wanted asks for "a pointer to the scaffold if it writes them" — the pointer is right for the two keys and for reports / positions / permissions / picklists; the word "every" makes the sentence false for two groups in the same list, and this audit exists because that list "read as complete". FAIL item; the fix is one clause (e.g. "scaffolds every group above but messages and settingsCommon, both keys included"), a few tokens inside SKILL.md's 1075-token headroom, no ratchet row moves.
  • The spec-line citations in the PR body (translation.zod.ts 303–320, 455–490, 902–911, 1161–1168, 1353–1359, 1668–1680, 1698–1705, 1721–1728; i18n-extract.ts 63–131) all resolve on origin/main at b33dd25b; the card body's 602-608 / 724 / 1140-1143 were stale, as the dev's deviation says (724 is the PER_APP_SETTINGS_PLATFORM_ONLY message that lists the groups, not the declarations).

(b) Cuts — none. The diff deletes nothing beyond the three lines it respells (_views row, _sections row, the group list's closing line), and every clause of each survives in its replacement. Shared Acceptance "nothing is removed beyond the stale lines this card names" holds; ruling A's "cut duplicates first" was applied to the raised file and found nothing to cut (judged below).

(c) Ratchet rows. The script's measure is Math.ceil(Buffer.byteLength(text,'utf8') / 4) with the stamped version: line excluded on SKILL.md only (header 44–113, TOKEN_CONVENTION, stampLine). Recomputed over the blobs: evals/bundles-locales-coverage.json 4016 bytes → 1004 on origin/main (= the old row), 5802 bytes → 1451 on the head (= the new row): pinned AT the measurement, zero headroom, no smuggled budget. SKILL.md 20131 − 20 → 5028 on main, 21050 − 20 → 5258 on the head, ceiling 6333 untouched (headroom 1305 → 1075) — the body's and report's numbers are exact. Arithmetic: evals +447, SKILL +230, bundle +677, ceilings +447 — consistent in the row comment, the body and the report. The raise rule (header 127–129: the other direction "lands only in a PR whose body quotes a maintainer ruling authorizing it") is met: the PR body quotes the tap 「A:先削重复,余额按实测提高」 verbatim and names the card it was tapped on; the row comment carries the same quotation (the script itself reads no comment and no body; check-ratchet-remedy-authority only anchors SHRINK testimony near the CEILINGS declaration, and the new rows sit inside the map, below the doc comment, so the anchor is undisturbed — green on the head). Ruling A's duplicate-cut first: read the five existing prompts on origin/main — bundle authoring, a new locale, the translation item, a plugin's generated bundle, the --objects-only diagnosis — five distinct surfaces, no restated teaching; the dev's "no duplicate content to cut" is right, so the remainder is the whole addition and the raise is exactly it. No max-len rule exists in eslint.config.mjs on origin/main; Lint · ESLint is green on the head. One row touched, inside the amended claim surface (CEILINGS rows of skills/objectstack-i18n/ files this PR touches); no logic, no other row.

(d) Evals. Ids 6 and 7 are unique and sequential after 1–5; the file parses; must_contain strings all appear in each expected_output; must_not_contain strings (permissionSets, report: {, stepLabel, _tabs.overview) are the real wrong spellings (permissionSets and report are aliases the door rewrites, 1958; stepLabel is the approvals alias, 1675). Eval 6's expected_output names permissionSets inside its own "never …" clause — the same pattern 22 existing prompts across the skills use (e.g. objectstack-data id 2 names many_to_many in its expected output while forbidding it), and no runner reads these files (the ratchet row comment at 590 and a repo-wide grep: no script reads must_contain), so it is consistent with the file's shape. Eval 6 IS the card-specific acceptance (a report and a permission set, plus a position and a picklist); eval 7 covers the four nested keys. Every new teaching has a prompt. No README or SKILL.md index counts prompts.

(e) Wanted lines — all met: :169-172 lists every group (14/14); :163 adds title; :165 adds fields.FIELD (label, placeholder, helpText); one line each for the tab item and approval step paths plus the scaffold pointer (the pointer being the sentence faulted in (a)). Line 1 of SKILL.md untouched (PR #25640's). Nothing outside the claim + amendment surface. Whole-file and whole-package before/after counts (503 → 510, 55 → 75, package 533 → 540, tokens 6032 → 6709) are in the body and exact.

(f) PR body. Line 1 is the harness attribution HTML comment, line 2 the _Requested by_ line, line 3 Fixes #26296, lines 4–5 Clause-②: no / Metadata-protocol: none line-initial — the shape os-dev.md 323 exempts on origin/main ("harness 自写的 PR 正文首行归属注释原样留、只报;Fixes 紧随其后"), and the dev reports it in deviations. No parser requires Fixes on line 1: check-closing-target-claim / check-closing-keyword-parity / check-partof-closing-keyword read keywords anywhere, and all three card-relation check-runs are green. ## 维护者速读 carries the six labels in order; 需要你做的 = exactly one action (批准, Tier H); 先看 = three files naming the risky hunk (the ceiling row); 两分钟验证 = one command with the expected sight, which matches the script's print format REL is N tokens (ceiling C; headroom H). (896). English sections What changes / Why / Tests / Acceptance notes / Verification with details blocks — the relative order os-dev.md asks for holds, Why inserted from the new PULL_REQUEST_TEMPLATE. One inconsistency to patch: the body's Verification says 52 derived, 47 green, 5 NOT MEASURED, while the report (6431884295) says 51 green, 1 NOT MEASURED after the closure build; the dev names it in deviations and did not PATCH the body (one write at pr_create).

(g) Report. os-dev-report 6431884295 on the card at 2026-10-27T02:01Z carries deviations (8), line_budget, out_of_scope_findings (2), files_changed; no rules_retired (the os-dev.md template on the head declares neither field; the order asked for the three it carries). Branch = the claim's claude/project-thread-mu5kbd; mcp_calls: 0; writes = pr_create through the relay + the report through post-stamped; assignee and skip-changeset written by the relay. The --objects-only paragraph observation (SKILL.md 401–405 lists six coverage kinds; i18n-coverage.ts 356–386 and 440–455 also report dataset, report, picklist, position, permission buckets) is read as INCOMPLETE, not false: the paragraph says "also demands … keys" without claiming the list is exhaustive, and eval 5 mirrors it; a one-clause tighten for the lane, not this card.

② Semver level

skip-changeset is right: skills/objectstack-i18n/ carries no package.json (SKILL.md, evals/, references/ only); scripts/check-skills-token-ratchet.mjs ships in no package's files[] (the root is @objectstack/spec-monorepo, private: true). Check Changeset is green on the head. Clause-②: no and Metadata-protocol: none are line-initial and right (the skill teaches keys the protocol already carries; no schema moves).

③ Boundary flags

  • Base: the PR's base sha abb90460 is an ancestor of origin/main (tip b33dd25b, three commits newer); the merge-base with the head is 756220c4. None of 756220c4..origin/main touches scripts/check-skills-token-ratchet.mjs or skills/objectstack-i18n/** (git log over those paths is empty), so the ratchet row and the skill rebase cleanly; mergeable_state: clean.
  • The dispatch order's premise check had the help / helpText alias direction reversed for the nested _sections.SECTION.fields.FIELD row (true only for the object-level row). The dev caught it by reading the schema. A 收班简报 note for the premise-check method (read the nested shape, not the neighbouring row), not a card.
  • The --objects-only paragraph's six-kind list (above, ①(g)): a note for the domain:skills lane; not filed, not blocking.
  • The report's mcp_calls and deviations fields name model ids (the thread's switch history); the commit trailer pair and the PR carry none, as os-dev.md requires. Nothing to do on this PR; a note that the report template's mcp_calls line invites it.
  • Body/report Verification mismatch (①(f)): patch the body's paragraph to the report's reading, or leave the report as the authority and say so in the seat's 席位核对.

Seat to-do before the maintainer's hand:

  1. FAIL item ①(a): respell SKILL.md line 176 so the scaffold sentence names the two groups the walk does not write — e.g. "os i18n extract --no-objects-only scaffolds every group above but messages and settingsCommon, both keys included." Inside SKILL.md's headroom; no ratchet row moves; eval 6's "scaffolds all four" stays true. Re-measure SKILL.md and update the body's SKILL.md token reading (5258 → the new count) and the package total.
  2. Patch the body's Verification paragraph to the report's 51-green / 1-NOT-MEASURED reading (or state in 席位核对 that the report governs).
  3. Optional, same file, same PR or the lane's next: tighten the --objects-only paragraph's six-kind list to "… and the other authored groups" or name the five further buckets.

Implemented-by: claude/project-thread-mu5kbd
Reviewed-by: session_01LqKsGyMNFwwnbF5FTAqyPn (independent contract-review subagent)

VERDICT: FAIL — ①(a): the new sentence "os i18n extract --no-objects-only scaffolds every group above" is false for messages and settingsCommon, two groups in the list it points at; everything else on this head passes.


Generated by Claude Code

…old does not write

The scaffold sentence said `os i18n extract --no-objects-only` writes every
top-level group; the extractor emits nothing for `messages` (free-form ids)
or `settingsCommon`, so the sentence now excepts those two. The
`--objects-only` warning also names the dataset, report, picklist, position
and permission buckets `os i18n check` reports beside the six it listed.

Claude-Session: https://claude.ai/code/session_01JQwxbXbFVr7jEKWyQKnPm9
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Reviewed at 2026-10-27T02:37Z · PR #26388 (card #26296, skills/objectstack-i18n) · re-review of the rework head after record 6432019825 (FAIL on 76220ce3, one item) · independent contract review at the ceiling tier; nothing below is the dispatch order's, the seat's or the dev's conclusion.

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 6181b1226d52ee92fa71bd47f59f4598e3ffe3b5
Local-runs: probe — the ratchet's own measure ceil(utf8 bytes / 4) (minus the stamp line) recomputed over the git show blob of SKILL.md on this head; a byte count, nothing built, run or re-run
Scope: skills/objectstack-i18n/SKILL.md, skills/objectstack-i18n/evals/bundles-locales-coverage.json, scripts/check-skills-token-ratchet.mjs + packages/cli/src/utils/i18n-extract.ts, packages/cli/src/commands/i18n/extract.ts, packages/cli/src/utils/i18n-coverage.ts, packages/spec/src/system/translation.zod.ts, skills/objectstack-i18n/references/_index.md, .claude/agents/os-dev.md

Readings: PR read over REST at 2026-10-27T02:35Z — draft: true, head 6181b122, mergeable_state: clean, base main, body last written 2026-10-27T02:34Z (the seat's patch), labels documentation / size/s / skip-changeset. 6181b122 is ONE commit on 76220ce3 on claude/project-thread-mu5kbd, fast-forward, no force; its trailer pair is the model-free one. Check-runs on 6181b122 read once at 2026-10-27T02:35Z: 52 runs, none in progress; 37 success, 15 skipped (the UI / docs / dogfood-shard / opt-in filter), nothing else — Type Check · source gates (token ratchet + self-test, check:skill-docs, check:skill-refs, check:ratchet-remedy-authority), Type Check · consumer gates (check:skill-examples), the five Lint lanes, Lint & Repo Gates, Check Changeset, Governed Surface Queue Guard, the three card-relation guards, Build Core, Test Core 1–8/8 and the aggregates all green. Dev rework report 6432294868 on the card at 2026-10-27T02:32Z read in full.

Blob comparison, 76220ce3 → 6181b122: skills/objectstack-i18n/evals/bundles-locales-coverage.json 1c300fe0 = 1c300fe0, scripts/check-skills-token-ratchet.mjs e4b14d45 = e4b14d45, skills/objectstack-i18n/references/_index.md ce2cbeff = ce2cbeff — identical; only SKILL.md moved (b4e1c1b1 → ce287a2e, +4/−2, two hunks). Every judgment of record 6432019825 on the three unchanged blobs carries over by reference: ①(b) no cuts, ①(c) the ratchet row 1451 pinned at the measurement with ruling A quoted on the row and in the body, ①(d) evals 6 and 7, ①(g) report shape, ② semver. Only what follows was re-judged.

① Derived judgments

(a) The two respelled sentences against the CLI on origin/main (tip c51aed4f).

  • SKILL.md 179–180: "os i18n extract --no-objects-only scaffolds every group above but messages and settingsCommon, both keys included" — RIGHT, and now exact. Re-read i18n-extract.ts on the current origin/main: the walk (surface comment 63–129; walkReports / walkPicklists / walkSecurityCatalog 1620–1630; page:tabs items 1314; approvals.NODE.label 2237; metadataForms 2271–2306 into its companion module) emits the twelve groups objects, globalActions, apps, dashboards, datasets, reports, picklists, pages, flows, positions, permissions, metadataForms, and kind: 'stack' (what --no-objects-only selects, 2705–2722) renders stackAuthoredSubtree(data) — the harvested tree minus metadataForms, which the companion carries. Zero emissions for messages or settingsCommon in i18n-extract.ts and in commands/i18n/extract.ts (grep count 0 in each). Those two are therefore exactly the groups of the list above that the scaffold never writes — no third one is missing from the exception and neither of the two is walked. The liveness ledger gates no top-level translation group today, so the twelve really are written. Both nested keys are walked (1314, 2237). Eval 6's "scaffolds all four" (reports, permissions, positions, picklists) stays true.
  • SKILL.md 402–406: the --objects-only warning now says os i18n check also demands app, navigation, dashboard, widget, dataset, report, picklist, page, flow, position and permission keys — RIGHT and exact against i18n-coverage.ts COVERAGE_SOURCE (331–389) and SOURCE_SURFACE (437–457): the buckets are object, field, option, section, view, action, globalAction (the objects / globalActions subtree the default extract writes), then app, navigation, dashboard, widget, dataset, report, picklist, page, flow, position, permission (the eleven, in the file's own order), and metadataForm (the three registry kinds collapsed; hidden unless --include-platform, and written by the extract's companion module, so rightly not in a list of what the default extract leaves unscaffolded). No bucket invented, none of the authored ones missing. Eval 5's six remain a true subset; its assertions are unchanged.
  • Everything else in SKILL.md is byte-for-byte the 76220ce3 text (the diff is the two hunks above), so ①(a)'s other readings — _views.title, _sections.fields.FIELD.{label,placeholder,helpText} with the helpText / help split, the fourteen-group list (appTranslationDataShape keys 888–1807), picklists inheritance, reports / positions / permissions label + description, permissions[] spelling, the tab-item and approval-step paths — carry over by reference.

(b) Cuts — none in the rework (+4/−2 is two respellings; every clause of each replaced line survives).

(c) Ratchet. SKILL.md on 6181b122: 21145 bytes − 20 (stamp line) → ceil(21125 / 4) = 5282 tokens, ceiling 6333 unchanged, headroom 1051 — the body's and report's readings are exact. The eval file and the ratchet script are the 76220ce3 blobs (1451 / 1451), so no row moved in the rework and nothing further is owed under ruling A. Type Check · source gates green on the head is the gate verdict.

(d) Evals — file identical to 76220ce3; carried over.

(e) Wanted lines — unchanged from the first record, all met; the scaffold pointer the card asked for is now true. Line counts on the head: SKILL.md 512, evals 75, package 542 (512 + 30), as the body and report state. Line 1 of SKILL.md untouched. Nothing outside the claim + amendment surface.

(f) PR body (the seat's patch, read at 2026-10-27T02:35Z) against the head: the nine amendments the dev listed in 6432294868 body_amendments have all landed — 503 → 512 lines / 5028 → 5282 / headroom 1051; the scaffold bullet's "every group above but messages and settingsCommon" clause; the new paragraph bullet; package 533 → 542 / 6032 → 6733; Why's +254 / +701; 先看 ① L169–L181 and 两分钟验证 5282 / 1051 (matching the script's print format); Tests "on 6181b12"; Verification 51 green / 1 NOT MEASURED with the four closure gates moved to green; the Acceptance-notes bullet now "fixed in this PR". Lines 1–5 unchanged (harness attribution comment, _Requested by_, Fixes #26296, the two declaration lines). Two residual nits, neither blocking: the new "--objects-only warning paragraph" bullet sits under the evals-file heading though it describes SKILL.md; and the Why section's "SKILL.md needed no raise (1075 tokens of headroom remain)" still carries the 76220ce3 headroom (1051 now). Note the dev did not write the body (os-dev.md's one-write rule) and named the conflict in deviations; the seat's patch is the right carrier.

(g) Report 6432294868 — carries rework_of, files_changed, deviations (4), body_amendments (9), line_budget, out_of_scope_findings; mcp_calls: 0; writes = one push + the report through post-stamped; no model id in it this time. Branch = the claim's.

② Semver level

Unchanged and right: skip-changeset (no package.json under skills/objectstack-i18n/; the ratchet script ships in no package's files[]); Clause-②: no / Metadata-protocol: none line-initial. Check Changeset green on 6181b122.

③ Boundary flags

  • origin/main moved under the PR (tip c51aed4f): two sibling skills PRs landed their own CEILINGS rows in scripts/check-skills-token-ratchet.mjs (a66c9ff4 objectstack-api, 7c70f91c objectstack-data). A read-only git merge-tree --write-tree origin/main 6181b122 merges clean (exit 0, no conflict) — the rows are in different map positions — and GitHub reports mergeable_state: clean. No commit on main since the merge-base touches skills/objectstack-i18n/**.
  • The two body nits in ①(f) — a bullet under the wrong file heading, one stale headroom number in Why — are the seat's 席位核对 or a later body touch; they do not misstate the head's measurements where the ratchet reads them (the Tests block and 两分钟验证 are right).
  • The earlier flags (the dispatch order's reversed alias direction for the nested _sections row; the first report naming model ids) stand as 收班简报 notes; nothing new.

Seat to-do: none blocking. Optional on the next body touch — move the paragraph bullet under the SKILL.md heading and change "1075 tokens of headroom remain" to 1051.

Implemented-by: claude/project-thread-mu5kbd
Reviewed-by: session_01LqKsGyMNFwwnbF5FTAqyPn (independent contract-review subagent)

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读

改了什么:skills/objectstack-i18n/SKILL.md 的对象子键表补上表单视图的 title(_views)和分区字段条目的 label / placeholder / helpText(_sections.{section}.fields);顶层分组清单补齐 picklists、reports、positions、permissions,各一行写明页面 page:tabs 条目标签与审批步骤标签的键路径,并说明 os i18n extract --no-objects-only 会生成它们(messages、settingsCommon 除外——首轮复核抓到的一句,返工已改);--objects-only 警告段补齐 os i18n check 的全部覆盖桶。评测文件加两题;评测文件天花板按你的裁决 A 从 1004 提到 1451(五条旧夹具无重复可削)。
为什么改:18.2 的翻译包多了 reports、positions、permissions 分组和这几个嵌套键,技能清单读起来像完整的,AI 作者照着写 zh-CN 包会漏掉报表、岗位和权限集。
风险与回滚:只改一份已发布技能的文字、它的评测文件和棘轮一行;不发包、不改代码;回滚 = revert 本 PR。
先看:① SKILL.md L169–L181(分组清单、两条嵌套键、scaffold 一句);② L163、L165(_views 的 title、_sections 的 fields);③ 棘轮 L657–L667(1004 → 1451 与引用的裁决)。
两分钟验证:node scripts/check-skills-token-ratchet.mjs 预期退出 0,印出 bundles-locales-coverage.json is 1451 tokens (ceiling 1451; headroom 0) 与 SKILL.md is 5282 tokens (ceiling 6333; headroom 1051)。
需要你做的:批准(Tier H,skills/** 是发布面;席位不 ready、不入队)。
席位意见:同意落地。本 PR 走了两轮:首轮 FAIL(scaffold 一句对 messages/settingsCommon 不成立),返工一行并顺手补齐覆盖桶后二轮 PASS。

席位核对

ACCEPT · domain:skills#2 · session_01LqKsGyMNFwwnbF5FTAqyPn · 2026-10-27T02:41Z — seat review of record for #26296 on head 6181b122, against GitHub, not the report's own account. Published surface skills/** ⇒ Tier H: the record of this tier is the independent ## Contract review at comment 6432361974 (Served-tier: CONTRACT_REVIEW_TIER, head 6181b122, VERDICT: PASS, one declared probe — the ratchet's byte measure over the SKILL.md blob; superseding the FAIL record 6432019825 on 76220ce3; drafted by a reviewer other than the implementer, the card thread's dev). This seat adds the landing read; ⛔ the seat does not ready, arm or enqueue a Tier H PR.

  1. Shape. Base main, mergeable_state: clean at the reviewer's read; two commits (76220ce3 + the one-file rework); body lines 1–2 the harness attribution block, line 3 Fixes #26296 (os-dev.md 323's exemption), Clause-②: no, Metadata-protocol: none line-initial (kind none ⇒ no Skills-docs: line owed); ## 维护者速读 six labels in order, then What changes / Why / Tests / Acceptance notes / Verification / Human Minimum with folds; the seat patched the body at 2026-10-27T02:34Z with the dev's nine amendments (token readings 5282/1051, package 542/6733, bundle +701, the scaffold clause, the coverage-kind bullet, Verification 51 green / 1 NOT MEASURED, head 6181b122), read back identical. Files: SKILL.md (+14/−5 net), evals/bundles-locales-coverage.json (+20), scripts/check-skills-token-ratchet.mjs (+11/−1, one row) — the claim's surface (6430939407) as amended at 2026-10-27T01:26Z; line 1 of SKILL.md untouched. Labels documentation, size/s, skip-changeset — right, no package.json under skills/objectstack-i18n. Branch claude/project-thread-mu5kbd, named by the claim. Model: the thread switched to the ceiling tier on the maintainer's own words before its first edit.
  2. Record, measured. Round one (6432019825, FAIL): the scaffold sentence claimed os i18n extract --no-objects-only writes every listed group; i18n-extract.ts emits twelve and nothing for messages / settingsCommon. Round two (6432361974, PASS): git diff 76220ce3 6181b122 is SKILL.md only, +4/−2 (L179–180 the exception clause; L402–406 the coverage list); evals, ratchet script and _index.md blobs identical across the heads, so their judgments carry over; the two excepted groups are exactly the ones never emitted; the eleven coverage kinds match i18n-coverage.ts COVERAGE_SOURCE / SOURCE_SURFACE exactly; every other new sentence true of translation.zod.ts (_views.title 304–320, fields.FIELD.{label,placeholder,helpText} 476–490 with help an alias, group list 14/14, permissions[] spelling stack.zod.ts:808, tab items keyed by value, approvals.NODE.label 1668–1680); ratchet row pinned at the measurement (5802 B → 1451, headroom 0), SKILL.md 5282 under 6333; evals 6/7 sequential, eval 6 the card's acceptance eval; git merge-tree against origin/main clean. The seat re-read git diff 76220ce3 6181b122 and reads the same.
  3. Gates, pinned to head 6181b122. 52 check-runs, 37 success and 15 skipped, none in progress or red (reviewer's read 2026-10-27T02:35Z): Type Check · source gates (ratchet + self-test, skill-docs, skill-refs), Type Check · consumer gates (skill-examples), the Lint lanes, Check Changeset, Governed Surface Queue Guard, the three card-relation guards, Build Core, Test Core 1–8.
  4. Accepted deviations. (a) Surface widened to the CEILINGS row — the seat's amendment under ruling A. (b) The dev did not patch the body after the rework (os-dev.md: the dev writes it once) and listed the amendments in the report; the seat applied them. (c) The dispatch order's premise note had the help/helpText alias direction reversed for the nested row; the dev taught the canonical helpText — right. (d) check:dual-build-cjs-loads NOT MEASURED locally; CI green. (e) Two body nits left as is: the coverage-kind bullet sits under the evals heading; Why still says 1075 tokens of headroom (now 1051).
  5. Carrier. Nothing to file. 收班简报: the order's alias-direction slip (premise reads should quote the zod describe, not the dev's memory); the os-dev-report named served models by id (the ban's letter covers commit and PR).
  6. Landing. Tier H ⇒ this record and the contract review are on the head; the PR waits for a GOVERNED_APPROVERS approval. os-zhuang approved, readied and armed auto-merge at 2026-10-27T02:40Z (after the PASS record 6432361974 at 02:37Z this time); the queue lands it on that hand — ⛔ nothing for the seat to ready, arm or enqueue. On MERGED the seat closes the card with the landing record.

Generated by Claude Code

Merged via the queue into main with commit 5507225 Oct 27, 2026
53 checks passed
@os-zhuang
os-zhuang deleted the claude/project-thread-mu5kbd branch October 27, 2026 03:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants