Skip to content

fix(plugin-webhooks,plugin-audit,plugin-security): re-translate the object leaves that contradict their current en source - #20684

Merged
objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/issue-20653-plugin-bundle-leaves
Sep 29, 2026
Merged

objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/issue-20653-plugin-bundle-leaves

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #20653

Clause-②: no

What changed

A translated leaf in a plugin's src/translations/{ja-JP,es-ES,zh-CN}.objects.generated.ts that a translator wrote by hand keeps its value when its en source changes later. This PR measures that set in the four plugin bundles the card names (plugin-webhooks, plugin-audit, plugin-approvals, plugin-security), then re-translates the leaves whose meaning now contradicts the current en: 18 leaves, six paths in all three locales (ja-JP 6, es-ES 6, zh-CN 6). The triage-ordered leaf, sys_webhook.fields.definition_json.help, is the first commit.

  • Values only. No key is added or dropped, no en file is edited, and no provenance companion (*.source-hashes.generated.ts) changes: the repo's own tooling was run and writes nothing (measured below).
  • .changeset/20653-stale-authored-plugin-bundle-leaves.md: @objectstack/plugin-webhooks, @objectstack/plugin-audit, @objectstack/plugin-security, each patch. @objectstack/plugin-approvals has no change and is not named.
  • No new gate, per triage. No test pins any of the old or new strings.
  • Scope per the claim: the four plugin bundles only. The platform-objects metadata-forms leaves are the engine lane's card, i18n(platform-objects): authored ja-JP / es-ES / zh-CN metadata-forms leaves contradict their moved en source (the metadata-forms half of #20653) #20666, which remains open and is not touched here.

The measurement (base 6bff748bb, before any edit)

Instrument

PR #20652's condensed instrument, ported with one change: the bundle directory comes from argv instead of the platform-objects constant. Population = every string leaf of the locale's objects bundle, minus echoes of the current en and paths recorded in *.source-hashes.generated.ts; last edit = the first-parent commit where the parsed value last changed; a leaf is a candidate when en at that commit differs from en today. Meaning is then judged by hand. Full history (the clone is not shallow: git rev-parse --is-shallow-repository answers false).

Four widening checks ran beside it:

  • Carve-out continuity. These bundles were carved out of packages/platform-objects/src/apps/translations/ at 44045721c (ADR-0029 D8: webhooks, approvals, security) and be1b9165f (K2: audit). The condensed walk starts at the carve-out, so it dates every carried leaf there and reads the en of that day. The widened walk replays the platform-objects file's first-parent history (from its birth at 6bacbced2, the horizon fix(platform-objects): re-translate the object leaves that contradict their current en source #20652 covered) before the plugin file's own. It re-dated every candidate the condensed walk had dated at a carve-out commit (for example definition_json.help, to 7bb92056e) and changed no candidate set.
  • Merge side. For a leaf last edited by a merge commit, en is also read at the second parent. 0 hits.
  • Penultimate edit. For each non-candidate, en at its previous edit, and whether en moved in the last-edit commit itself. Every flag where en moved EARLIER than the last edit was read by hand: sys_webhook.fields.method.help, sys_position.fields.name.help and sys_position._actions.clone_position.params.name.helpText already say what en says; es-ES sys_position._actions.deactivate_position.confirmText differs by rewording only; es-ES sys_position.description contradicts (it was edited at 4ea921ca8, after en moved, and kept the old framing), so it is re-translated.
  • Retired terms and renamed keys. A leaf carrying the locale's word for project or department where en at the same path does not carry the English term; the locale's word for role or RBAC anywhere in the four bundles; and a leaf whose path was born at its last edit while the same value sat under a sibling path of the same object that disappeared in that commit (a renamed key). One path, found by both the term scan and the renamed-key check: sys_activity.fields.environment_id.help. The key was renamed from project_id at 944f18758 with the value carried, so the since-last-edit instrument dates it at the rename, where en already said Environment, and cannot see it.

Known-positive control

plugin-webhooks sys_webhook.fields.definition_json.help, line 72 of all four bundles. The source has said "Credentials are NOT stored here" since 160294963 (the custom headers moved onto the encrypted channel, after e3a6f6e7e moved the signing secret), and the en bundle since 8af76aebf. The three translations were last edited at 7bb92056e, when en said "full headers/auth/retry/payload config". The ported instrument flags it in all three locales. A1 held: the port is live before anything is counted.

Counts per bundle (ja-JP / es-ES / zh-CN)

bundle authored leaves candidates, before contradicting, before widening checks, before re-translated candidates, after contradicting after widening after
plugin-webhooks 41 / 40 / 40 3 / 3 / 3 2 / 2 / 2 0 / 0 / 0 2 / 2 / 2 1 / 1 / 1 0 0
plugin-audit 102 / 100 / 102 3 / 3 / 3 2 / 2 / 2 1 / 1 / 1 (environment_id.help) 3 / 3 / 3 1 / 1 / 1 0 0
plugin-approvals 113 / 112 / 134 17 / 17 / 16 0 / 0 / 0 0 / 0 / 0 0 17 / 17 / 16 0 0
plugin-security 179 / 179 / 179 7 / 5 / 7 1 / 0 / 1 0 / 1 / 0 (es-ES sys_position.description) 1 / 1 / 1 6 / 5 / 6 0 0

The before candidate counts equal the #20539 dev's raw counts exactly (A2). After = at 5444bb130, both instruments: each after-candidate set is exactly the before set minus the re-translated paths (0 added), the echo counts are unchanged (no new value equals its en leaf), and the term scan and renamed-key check return 0. The penultimate-edit flags after are the before set minus es-ES sys_position.description, plus the 14 re-translated leaves that were candidates (their last edit is now this PR, after en moved), which is the expected shape.

The judgment rule

As in PR #20652. A leaf contradicts the current en when a reader who acts on it would believe something about the current field or object that en now says is false: en now denies what the leaf asserts; the object was re-modelled, so the leaf describes a different thing; or the leaf names the record's entity by a term a rename retired from it. Added detail, narrowing, rewording, punctuation and title-casing are not contradictions.

Re-translated (18): before and after, with the en each now matches

(ja-JP / es-ES / zh-CN, in each bundle's existing terms: 署名シークレット / カスタムヘッダー / アウトボックス / ケイパビリティ; secreto de firma / cabeceras personalizadas / outbox / capacidades / entorno; 签名密钥 / 自定义请求头 / 发件箱 / 授权能力 / 环境.)

plugin-webhooks · sys_webhook.fields.definition_json.help: said the JSON carries the full headers / auth / retry / payload config. en says the opposite, on a security field. en: 「Serialised Webhook JSON (see @objectstack/spec/automation/webhook) — timeout and the rest of the authored envelope. Credentials are NOT stored here: the signing secret lives in the encrypted signing_secret field and the custom headers in the encrypted headers_secret field.」

  • ja-JP: 「シリアライズされた Webhook JSON(@objectstack/spec/automation/webhook 参照)— ヘッダー/認証/リトライ/ペイロード設定を含む」 → 「シリアライズされた Webhook JSON(@objectstack/spec/automation/webhook 参照)— タイムアウトなど、作成されたエンベロープの残りの設定。認証情報はここには保存されません。署名シークレットは暗号化された signing_secret フィールドに、カスタムヘッダーは暗号化された headers_secret フィールドに保存されます。」
  • es-ES: 「JSON serializado de Webhook (consulte @objectstack/spec/automation/webhook): configuración completa de cabeceras/auth/reintentos/payload.」 → 「JSON serializado de Webhook (consulte @objectstack/spec/automation/webhook): el tiempo de espera y el resto del envelope definido. Las credenciales NO se almacenan aquí: el secreto de firma se guarda en el campo cifrado signing_secret y las cabeceras personalizadas, en el campo cifrado headers_secret.」
  • zh-CN: 「序列化的 Webhook JSON(参见 @objectstack/spec/automation/webhook)——包含完整的 headers/auth/retry/payload 配置」 → 「序列化的 Webhook JSON(参见 @objectstack/spec/automation/webhook)——超时及所编写信封的其余配置。凭据不存储在此处:签名密钥保存在加密的 signing_secret 字段中,自定义请求头保存在加密的 headers_secret 字段中。」

plugin-webhooks · sys_webhook.description: said an HTTP connector plugin executes the webhook. 69f1dfd5c replaced that executor in the source with the webhook auto-enqueuer and the shared HTTP outbox (service-messaging), and no HTTP connector plugin exists in the tree (packages/plugins, packages/services). The leaf also omitted the defineStack({ webhooks }) door, which is additive. en: Outbound HTTP webhook subscription. Declared in code via defineStack({ webhooks }) / defineWebhook() (materialized into rows on boot) or authored directly in the Studio editor; dispatched by the webhook auto-enqueuer onto the shared HTTP outbox.

  • ja-JP: 「送信 HTTP Webhook サブスクリプション。defineWebhook() またはスタジオエディタで作成し、HTTP コネクタプラグインが実行します。」 → 「送信 HTTP Webhook サブスクリプション。コードでは defineStack({ webhooks }) / defineWebhook() で宣言する(起動時に行として実体化)か、スタジオエディタで直接作成します。Webhook 自動エンキューアが共有 HTTP アウトボックスへディスパッチします。」
  • es-ES: 「Suscripción saliente de Webhook HTTP. Se crea mediante defineWebhook() en código o con el editor de Studio; la ejecuta el plugin del conector HTTP.」 → 「Suscripción saliente de Webhook HTTP. Se declara en código mediante defineStack({ webhooks }) / defineWebhook() (materializada en filas al arrancar) o se crea directamente con el editor de Studio; el encolador automático de webhooks la despacha al outbox HTTP compartido.」
  • zh-CN: 「外发 HTTP Webhook 订阅。可在代码中通过 defineWebhook() 编写,或在 Studio 编辑器中维护;由 HTTP 连接器插件执行。」 → 「外发 HTTP Webhook 订阅。可在代码中通过 defineStack({ webhooks }) / defineWebhook() 声明(启动时物化为数据行),或直接在 Studio 编辑器中编写;由 Webhook 自动入队器分发到共享的 HTTP 发件箱。」

plugin-audit · sys_activity.fields.environment_id.label: the v5.0 rename project to environment ships no alias. en: Environment

  • ja-JP: 「プロジェクト」 → 「環境」
  • es-ES: 「Proyecto」 → 「Entorno」
  • zh-CN: 「项目」 → 「环境」

plugin-audit · sys_activity.fields.environment_id.help: same rename; found by the term scan and the renamed-key check, invisible to the since-last-edit instrument. en: Environment context (multi-environment deployments)

  • ja-JP: 「プロジェクトコンテキスト(マルチプロジェクトデプロイメント)」 → 「環境コンテキスト(マルチ環境デプロイメント)」
  • es-ES: 「Contexto del proyecto (implementaciones multiproyecto).」 → 「Contexto del entorno (implementaciones multientorno).」
  • zh-CN: 「项目上下文(多项目部署)」 → 「环境上下文(多环境部署)」

plugin-audit · sys_audit_log.fields.user_id.label: 7fe7e85d6 gave sys_audit_log its own actor principal field (label Actor; ADR-0014 D2) and relabelled the strict sys_user lookup user_id from Actor to User, because a service-token action leaves user_id null and records the principal in actor. The leaves still called user_id the actor: es-ES showed two fields both labelled 「Actor」, and ja-JP (操作者 beside 実行者) and zh-CN (执行人 beside 操作者) showed two synonyms. en: User

  • ja-JP: 「操作者」 → 「ユーザー」
  • es-ES: 「Actor」 → 「Usuario」
  • zh-CN: 「执行人」 → 「用户」

plugin-security · sys_position.description: the ADR-0090 P1 commit (6d83431cf) changed en from "Role definitions for RBAC access control" to capability distribution; the translations were find-replaced role to position and kept "for RBAC access control" (ADR-0090: capability = permission_set, distribution = position, and the word role is retired from UI copy). en: Position definitions for capability distribution (ADR-0090)

  • ja-JP: 「RBAC アクセス制御のためのポジション定義」 → 「ケイパビリティ配分のためのポジション定義(ADR-0090)」
  • es-ES: 「Definiciones de puesto para el control de acceso RBAC」 → 「Definiciones de puesto para la distribución de capacidades (ADR-0090)」
  • zh-CN: 「用于 RBAC 访问控制的岗位定义」 → 「用于分发授权能力的岗位定义(ADR-0090)」

The two closest calls on this side are sys_webhook.description and sys_audit_log.fields.user_id.label; the reasons are above.

Stale but not contradicting (listed, left as written)

bundle · path locales what en did
webhooks · sys_webhook.fields.triggers.help all three Condensed to "(bulk_* deliver a count, not a record)" when the en bundle began tracking its source (8af76aebf). The leaf's longer "bulk_update / bulk_delete fire on predicate writes and deliver a count" is still true (the field's own source comment says the same).
audit · sys_audit_log.fields.user_id.help all three Widened "null for system actions" to "null for non-user / service actions — see actor". The leaf is narrower, not false.
approvals · sys_approval_request.fields.status.options.* (5), sys_approval_action.fields.action.options.* (12) 17 / 17 / 16 Moved from the machine value to a title (pending to Pending, request_info to Request Info, ooo_substitute to Out-of-Office Substitution). Every leaf already carried the meaning. Triage: not a contradiction.
security · sys_position.fields.managed_by.help, sys_capability.fields.managed_by.help, sys_permission_set.fields.managed_by.help all three Added the unified tri-state wording and the legacy aliases, or reworded. The leaves' platform / package / admin reading is still true.
security · sys_capability.description all three Added the ADR-0066 citation and named the two referencing keys.
security · sys_position._actions.deactivate_position.confirmText ja-JP, zh-CN (es-ES via the penultimate check) Dropped "with the position".
security · sys_permission_set.fields.name.help all three Added that the name is the set's metadata identity and cannot be renamed (clone instead). The leaf does not claim it can. This is the closest call among the leaves left alone.

Dispatch hypotheses, measured

  • A1 held. The ported instrument flags the known positive in all three locales, and its counts at 6bff748bb are 3/3/3, 3/3/3, 17/17/16 and 7/5/7.
  • A2 held as a lead. The raw counts reproduce exactly. Meaning judged per candidate: 5 of the 30 / 28 / 29 candidates contradict in ja-JP / zh-CN, 4 in es-ES, plus one term-scan leaf per locale and one penultimate-edit leaf in es-ES. The named likely positive (sys_activity.fields.environment_id.label) is a positive in all three locales (es-ES 「Proyecto」 too).
  • A3 held: values only. node scripts/check-i18n-bundles.mjs --write --filter=plugin-NAME for webhooks, audit, security and approvals printed regenerated for each; the files were rewritten on disk and git status --porcelain stayed empty, so the tooling owes no companion or en change. Control (a commit-first ablation through scripts/ablation-replace.mjs): with ja-JP sys_webhook.fields.definition_json.help set to the en string, check-i18n-bundles --filter=plugin-webhooks goes red, plugins/plugin-webhooks DRIFTED (1); the tool restored it (blob 88583c2ea5f9 == HEAD, git diff HEAD empty).
  • A4 held. Each changed plugin ships the new values in dist (built at 5444bb130). plugin-webhooks: the built chunk dist/translations-KQ72WOMS.js, the module the plugin's kernel:ready hook imports, was imported and its served value (after withSourceFallback) read at each path: 6 of 6 equal the HEAD source and differ from the base, and 3 unchanged-leaf controls equal. plugin-audit and plugin-security inline their bundles: each locale's object literal was cut out of dist/index.mjs and dist/index.js and read by path: 24 of 24 rows equal the HEAD source and differ from the base, and 12 controls equal. A plain byte grep was not a usable reading here: esbuild escapes non-ASCII text, and the old short labels are shared by other fields.

Verification (all at 5444bb130, after merging origin/main at 9a4b2bb38)

The merge brought PR #20658, a comment-only edit that includes plugin-security/src/translations/index.ts, a file this PR does not edit.

  • Build: turbo run build --filter=@objectstack/cli... --filter=@objectstack/plugin-webhooks... --filter=@objectstack/plugin-audit... --filter=@objectstack/plugin-security..., 59/59 tasks, VERDICT command-exit 0.
  • pnpm --filter test, for the three changed plugins: plugin-webhooks 13 files / 160 tests passed; plugin-audit 25 files / 363 tests passed; plugin-security 147 files / 3202 passed, 23 skipped (the translation tests bundle-ownership.test.ts and position-rename-consistency.test.ts included). typecheck for the three: exit 0, each check:test-typecheck: OK.
  • Gates: node scripts/pm/dispatch-gates.mjs --commands (no paths) derived 57 commands against the real diff; the dispatch-time list had 56, and the one added is pnpm check:logger-receiver-detach. All 57 exit 0. --ran printed "57 derived famil(ies) accounted for — 57 run, 0 NOT-MEASURED". pnpm check:dual-build-cjs-loads first refused with exit 3 (nine packages outside this diff had no dist/). Those were built and the gate re-ran: exit 0.
  • The four roster families printed outside the runnable list: node scripts/check-changeset-fixed.mjs, pnpm check:authz-resolver, pnpm check:error-code-casing, pnpm check:filter-alias-parity, all exit 0.
  • Named in the verdicts: check:i18n "OK (9 package(s) — all bundles in sync, no undeclared authoring keys)"; check:i18n-stale-fill "OK (10 bundle set(s) — no new stale fills, 0 baselined)"; check:nul-bytes OK.
  • Lint, narrowed to the nine edited bundles: eslint --no-inline-config --format json read 9 files, 0 errors, 0 warnings. ESLint#isPathIgnored answers false for all nine, read from the repo's own config. The config enables no type-aware linting (no parserOptions.project; eslint.config.mjs states it at lines 327-328), so a change to string values in these files cannot move the verdict on any other file. The full pnpm lint is left to CI.

Acceptance notes

  • position-rename-consistency.test.ts matches the retired term as \brole?s?\b / \brol(es)?\b / 角色 / ロール. None of those matches the acronym RBAC, which is how sys_position.description kept "for RBAC access control" in all three locales under a green ADR-0090 guard. This PR fixes the values; the test's blind spot remains. It is outside this card's file surface and is not changed here.
  • The since-last-edit instrument cannot see a leaf whose KEY was renamed with its value carried (here project_id to environment_id). The renamed-key check above covers that shape. i18n(platform-objects): authored ja-JP / es-ES / zh-CN metadata-forms leaves contradict their moved en source (the metadata-forms half of #20653) #20666 runs the same instrument on the metadata-forms bundles and may want the same check.
  • Instrument sources and outputs were run from the session scratchpad; the widened instrument is the condensed one plus the four checks described above.

Generated by Claude Code

…dict their current en source

sys_webhook.fields.definition_json.help told a ja-JP / es-ES / zh-CN admin
that the JSON carries the full headers / auth / retry / payload config;
en says credentials are NOT stored there (signing_secret and headers_secret
are the encrypted fields). sys_webhook.description named an HTTP connector
plugin as the executor; en names the webhook auto-enqueuer and the shared
HTTP outbox. Values only.

Claude-Session: https://claude.ai/code/session_01XY5uCwTjZj7884yYtyur4H
Co-authored-by: Claude <noreply@anthropic.com>
…r current en source

sys_activity.fields.environment_id.label / .help still named the retired
v5.0 term project (ja-JP / es-ES / zh-CN), where en says Environment; the
v5.0 rename ships no alias. sys_audit_log.fields.user_id.label still called
the sys_user lookup the actor, where en relabelled it User when the object
gained its own `actor` principal field (ADR-0014 D2): es-ES showed two
fields labelled "Actor", ja-JP / zh-CN two synonyms. Values only.

Claude-Session: https://claude.ai/code/session_01XY5uCwTjZj7884yYtyur4H
Co-authored-by: Claude <noreply@anthropic.com>
…its current en source

The ja-JP / es-ES / zh-CN leaves still described positions as definitions
"for RBAC access control": the ADR-0090 P1 rename replaced the word role
and kept the old framing. en says positions distribute capability
(ADR-0090: capability = permission_set, distribution = position). The
es-ES leaf was edited after en moved, so only the penultimate-edit check
sees it. Values only.

Claude-Session: https://claude.ai/code/session_01XY5uCwTjZj7884yYtyur4H
Co-authored-by: Claude <noreply@anthropic.com>
…rity for the re-translated leaves

Claude-Session: https://claude.ai/code/session_01XY5uCwTjZj7884yYtyur4H
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tooling labels Sep 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 3 package(s): @objectstack/plugin-audit, @objectstack/plugin-security, @objectstack/plugin-webhooks, touching 4 documentable anchor(s).

13 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/automation/webhooks.mdx (via sys_webhook (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/deployment/environment-variables.mdx (via sys_position (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/deployment/production-readiness.mdx (via sys_audit_log (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/kernel/runtime-services/audit-service.mdx (via sys_activity (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects), sys_audit_log (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/permissions/authorization.mdx (via sys_position (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/permissions/delegated-administration.mdx (via sys_position (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/permissions/positions.mdx (via sys_position (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/permissions/record-view-auditing.mdx (via sys_audit_log (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/permissions/system-context.mdx (via sys_position (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/plugins/packages.mdx (via sys_activity (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects), sys_audit_log (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/protocol/backward-compatibility.mdx (via sys_position (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/protocol/kernel/config-resolution.mdx (via sys_audit_log (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/ui/setup-app.mdx (via sys_activity (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects), sys_audit_log (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))

⛔ 9 release-owned page(s) also name something this change touched. These are read-only:

  • content/docs/releases/index.mdx (via sys_audit_log (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects), sys_position (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/releases/v13.mdx (via sys_position (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/releases/v14.mdx (via sys_activity (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects), sys_audit_log (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects), sys_position (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/releases/v15.mdx (via sys_position (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/releases/v16.mdx (via sys_activity (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects), sys_webhook (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/releases/v17/17-0.mdx (via sys_audit_log (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/releases/v17/17-1.mdx (via sys_audit_log (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects), sys_position (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/releases/v17/17-2.mdx (via sys_position (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/releases/v17/17-5.mdx (via sys_audit_log (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects), sys_webhook (symbol, a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • the SDK route bridge reached 54 of 206 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 22 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 139bef809cda0084d56544bce1e6c58783da1a8e → packageMentionDocs.

Which tree this was computed on

This run read content/docs from ed20046e47d58f22f8eb01c455f6fadd81f7a773 — the merge of head 5444bb130b1ed024c63208e0880796e116643b96 into base 139bef809cda0084d56544bce1e6c58783da1a8e, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin ed20046e47d58f22f8eb01c455f6fadd81f7a773 && git checkout ed20046e47d58f22f8eb01c455f6fadd81f7a773
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 139bef809cda0084d56544bce1e6c58783da1a8e 5444bb130b1ed024c63208e0880796e116643b96 && git checkout -B drift-repro 139bef809cda0084d56544bce1e6c58783da1a8e && git merge --no-ff 5444bb130b1ed024c63208e0880796e116643b96

node scripts/docs-audit/affected-docs.mjs --json 139bef809cda0084d56544bce1e6c58783da1a8e

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 139bef809cda0084d56544bce1e6c58783da1a8e → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review September 29, 2026 17:13
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Sep 29, 2026
Merged via the queue into main with commit 7184436 Sep 29, 2026
36 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-20653-plugin-bundle-leaves branch September 29, 2026 17:33
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 tooling

Projects

None yet

2 participants