You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[finding] VISIBILITY_STRICT_OPTIONS is in @objectstack/spec's public API but its type StrictObjectOptions is not — a published const no consumer can annotate #8213
Restart-when: closed #5082 / the next v18 major-train ADR-0087 removal batch opens — surface this into that batch
Filed unassigned by the domain:spec-surface seat (#6298) from PR #8199's dev report. Recording only — this one wants a decision, not a drive-by fix, which is why it is a finding rather than a follow-up chore.
What
shared/visibility.ts is re-exported wholesale by shared/index.ts, so VISIBILITY_STRICT_OPTIONS is part of the package's public API and is tracked by check:api-surface.
Its type is not. StrictObjectOptions lives in shared/strict-object.ts, which the barrel deliberately omits — as it omits alias-probe.ts and, since PR #8199, editability-boundary.ts.
So an external consumer can import the value and can do nothing with it: they cannot annotate a variable holding it, cannot type a function that takes it, cannot spread it into an options object of the right type. The export is reachable and unusable.
Why it looks accidental rather than intended
visibility.ts carries two different kinds of thing: the runtime helper normalizeVisibleWhen (which genuinely belongs to consumers — it implements the ADR-0089 fold) and the strict-object options table (schema-declaration machinery for use inside this package). The barrel exports the module, so the second rode along with the first. Every neighbouring module holding the same kind of machinery is unbarrelled.
Surfaced while landing PR #8199: that PR needed a sibling options table, and putting it in visibility.ts made check:api-surface red for a docs card. Moving it to an unbarrelled module fixed that and made the card's "nothing observable moves" claim true at the API level too — but it leaves the pre-existing export sitting there as the odd one out.
Why it is not obviously safe to just un-export
Removing it from the barrel is a breaking change to the published surface (check:api-surface counts it as removed/narrowed), even though the plausible number of external consumers is zero — nobody can be using it in a typed way, by the argument above. That combination — technically breaking, practically inert — is exactly the kind of call that should be made deliberately and recorded, not folded into an unrelated PR.
Options, in ascending cost: leave it and note why; un-export it in the next major with an ADR-0087 registry entry; or publish StrictObjectOptions too, if the options table is genuinely meant to be consumer-facing (nothing observed suggests it is).
Routing suggestion
domain:spec — it is a published-surface decision, not a text-face one. Low urgency, zero measured pull. If the answer is "un-export", the follow-through has a retirement process to go through (ADR-0087) and should ride a major.
Triage (routing only, held as finding): accepting the card's own routing argument — this is a published-API-surface decision on @objectstack/spec (un-exporting is check:api-surface-breaking, publishing the type widens the public face) ⇒ domain:spec, not spec-surface. Zero measured pull, existing state is inert-but-reachable; correctly held rather than queued. If graded worth doing, the un-export route rides a major with an ADR-0087 registry entry per the card.
Grading (held as finding, type Task) — 本评论来自分诊座位 Routine.
Held, with a named re-grade trigger. All three dispositions touch the published surface (un-exporting is technically breaking even if practically inert; publishing StrictObjectOptions widens the public face), so the call belongs to the maintainer — but with zero measured pull and no consumer able to use the export in a typed way today, it does not earn a decision-inbox slot now. Leave-and-note is the correct interim state, and this card is the note.
Re-grade trigger: when a v18 major-train ADR-0087 removal batch opens (the #5082 family is the anchor), surface this card into that batch — the un-export-vs-publish decision rides the major with the rest of the retirement registry, where it costs the maintainer one line instead of a standalone ruling.
State-machine migration, maintainer-authorized (2026-08-13, live triage session: 「我授权你先迁标签」; semantics on #8449): graded hold with a named re-grade trigger (surface into the next v18 major-train ADR-0087 removal batch) — finding → pm:on-hold. Verdict, trigger, domain unchanged.
Closed not_planned by the director seat (summon #28 续, session_01GLdRPcbaCBQCTvVmU6YEUY), 2026-09-24T04:00Z, on the maintainer's word — closure review batch 2 of the open domain:spec cards under the restructured triage standard, presented from the business angle in this seat's chat; maintainer verbatim: 「19870 每段要以字母开头 有必要吗?其他同意」.
The roadmap is NORTH-STAR's 路上的功能点 table (「这张表就是路线图,改它即改优先级」); an umbrella over ~16 metadata types waiting for a customer to ask duplicates it. Part A was approved 2026-08-07 (5219867430) and its quick wins were filed separately; Part B's hold (2026-08-09, 5230641358) waited for demonstrated pull — that pull, when it comes, arrives as its own card for that one type, which is the hold's own restart shape. Studio rows on the road today cover objects / fields / lists / forms / pages / docs, not these types. This close supersedes the 2026-08-09 hold, on the maintainer's word.
Its Restart-when: already names the next v18 ADR-0087 removal batch (the #5082 family); 阶段姿态 「按发布批量退役,不一键一卡」 ⇒ the note rides #5082 as a pointer (posted this act), not an open card. Zero pull; an inert export.
Ledger: seat post #12708, this summon's next block.
Activity
hotlong commentedon Aug 12, 2026
Triage (routing only, held as
finding): accepting the card's own routing argument — this is a published-API-surface decision on@objectstack/spec(un-exporting ischeck:api-surface-breaking, publishing the type widens the public face) ⇒domain:spec, not spec-surface. Zero measured pull, existing state is inert-but-reachable; correctly held rather than queued. If graded worth doing, the un-export route rides a major with an ADR-0087 registry entry per the card.Generated by Claude Code
hotlong commentedon Aug 12, 2026
Grading (held as
finding, type Task) — 本评论来自分诊座位 Routine.Held, with a named re-grade trigger. All three dispositions touch the published surface (un-exporting is technically breaking even if practically inert; publishing
StrictObjectOptionswidens the public face), so the call belongs to the maintainer — but with zero measured pull and no consumer able to use the export in a typed way today, it does not earn a decision-inbox slot now. Leave-and-note is the correct interim state, and this card is the note.Re-grade trigger: when a v18 major-train ADR-0087 removal batch opens (the #5082 family is the anchor), surface this card into that batch — the un-export-vs-publish decision rides the major with the rest of the retirement registry, where it costs the maintainer one line instead of a standalone ruling.
Generated by Claude Code
hotlong commentedon Aug 13, 2026
State-machine migration, maintainer-authorized (2026-08-13, live triage session: 「我授权你先迁标签」; semantics on #8449): graded hold with a named re-grade trigger (surface into the next v18 major-train ADR-0087 removal batch) —
finding→pm:on-hold. Verdict, trigger, domain unchanged.Generated by Claude Code
objectstack-fleet commentedon Sep 24, 2026
Closed
not_plannedby the director seat (summon #28 续,session_01GLdRPcbaCBQCTvVmU6YEUY), 2026-09-24T04:00Z, on the maintainer's word — closure review batch 2 of the opendomain:speccards under the restructured triage standard, presented from the business angle in this seat's chat; maintainer verbatim: 「19870 每段要以字母开头 有必要吗?其他同意」.Restart-when:already names the next v18 ADR-0087 removal batch (the #5082 family); 阶段姿态 「按发布批量退役,不一键一卡」 ⇒ the note rides #5082 as a pointer (posted this act), not an open card. Zero pull; an inert export.Ledger: seat post #12708, this summon's next block.