Skip to content

[finding] The objectstack-i18n reference index routes 5 of its 7 transitive pointers at schemas unreachable from a translation bundle — the closure step in build-skill-references.ts #14565

Description

@os-litant

Out-of-scope by-product of the skills optimization flight on #14315 (audit id I18N-C-03, deferred there by the card's own scope: the generator lives in packages/spec and that flight was shrink-only inside skills/objectstack-i18n/). Filed unassigned. No edit was madereferences/_index.md is generator-owned.

Sibling of #14462 and #14466, which are the same generator (packages/spec/scripts/build-skill-references.ts) and the same customer-visible symptom for other packages. Adjacent, not identical, and the distinction is the fix site: those two are SKILL_MAP — the hand-written core list — being unreconciled with the body. This one's core list is correct; the defect is in the transitive-closure step that walks local import ... from edges out of the core files. Worth triaging as one group; the fix may be one change or two.

Measured at origin/main 53d3689

SKILL_MAP for this package (build-skill-references.ts:159-162) is right:

'objectstack-i18n': [
  'system/translation.zod.ts',
  'ui/i18n.zod.ts',
],

The generated skills/objectstack-i18n/references/_index.md then adds a ## Transitive dependencies section of 7 pointers, of which 5 are unreachable from a translation bundle:

pointer what it is reachable from a bundle?
data/filter.zod.ts the unified Query DSL no
kernel/metadata-protection.zod.ts metadata protection model (ADR-0010) no
shared/expression.zod.ts Expression Protocol no
data/field-value.zod.ts field runtime VALUE-shape contract (ADR-0104 D1) no
shared/suggestions.zod.ts "Did you mean?" utilities no
data/field.zod.ts field types, select options marginal
shared/identifiers.zod.ts snake_case / identifier primitives yes

Why they are unreachable

A translation bundle addresses everything by name string. FieldTranslationSchema (packages/spec/src/system/translation.zod.ts:38-47 at the audit ref) is label / help / placeholder / options — four optional strings and a string map. Nothing in a bundle carries a filter, an expression, a field value, or a protection rule; the object/field/view names are plain map keys validated against metadata by the lint pass, not by importing those schemas.

The pointers arrive because the closure follows any local import out of translation.zod.ts, and that file imports those modules for reasons that never surface in the authorable face.

Why it costs something

_index.md is 549 tokens shipped into every customer session that loads this skill, and its "How to read these" section instructs the agent to Read the source at these paths. Five of seven send it to unrelated schemas — the largest of them, the Query DSL, is a different skill's whole subject. An agent that follows the instruction pays for reading them and comes back with nothing that changes a translation bundle.

Suggested direction (not a decision)

Constrain the closure for this entry — either a per-package transitive allowlist/denylist beside SKILL_MAP, or a reachability rule ("only follow imports that the package's authorable face can actually reach"). The second generalizes to #14462 / #14466; the first does not. Whoever picks this up should read those two cards first.

⛔ Not fixed in #14315 and not to be fixed by hand: the file is generated, and hand-editing it is undone by the next gen:skill-refs.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions