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
stdlib: pub-mark sweep for io/math/option/result/testing (follow-up to #505) #508
PR #505 closed the pub-visibility gap in stdlib/string.affine (18 fns made pub) and stdlib/collections.affine (22 fns made pub). The same gap exists in 5 other stdlib modules — they have /// doc-comment public-API intent but missing pub keywords.
Inventory (counted 2026-05-31)
Module
pub fns
private fns (likely-meant-to-be-pub)
stdlib/io.affine
0
15
stdlib/math.affine
0
36
stdlib/option.affine
1
35
stdlib/result.affine
0
24
stdlib/testing.affine
0
26
Total: 136 likely-pub-intent fns currently unreachable from consumers.
Why
Same root cause as #505: /// doc-comment convention was applied broadly when the modules were first written, but the pub keyword from ADR-011 wasn't retroactively added to every doc-commented fn. Discovered while porting migration/shared/PortNames.affine in idaptik (standards#279) — string::starts_with was the first surfaced casualty.
Scope
Per module: add pub to every fn whose body has a /// doc comment. Leave module-private helpers (those that don't have ///) alone. Cross-check with each module's consumer surface — anything called by option from result, etc., needs reachability.
Per-module gates likely needed:
option.affine — many fns depend on each other; need topological pub order.
math.affine — likely all 36 are pub-intent (pure math fns).
testing.affine — 26 fns; these are the assertion DSL consumers use.
io.affine + result.affine — straightforward.
Test plan
dune runtest 354/354 pass after each module edit
Smoke: write one consumer file per module that uses a representative fn and runs check
Once landed, idaptik migration/shared/ + panll migration/modules/ can use more stdlib surface without local re-impl
Estate impact
Unblocks future ports in the standards#252 ReScript→AffineScript campaign and the standards#254 JS→AffineScript campaign — both have STEP-4 bindings dependencies (#446 umbrella). Each port that currently hand-rolls a stdlib equivalent (because it can't reach the canonical one) accumulates drift; closing the pub gap eliminates the local-helper pattern as a default.
Refs
affinescript#505 — the precedent (string + collections)
standards#279 — STEP 8 megaport that surfaced this
Activity
feat(stdlib): pub-mark sweep — io/math/option/result/testing (closes #…