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
Mark ui +devlore:root=true and sweep the ui.* call sites #700
Confirm the six names install as top-level globals, and that print and fail resolve to the
provider rather than to starlark.Universe
Sweep the call sites. Root placement removes the ui provider global, so every ui.note(...)
becomes note(...) — across star/extensions, cmd/star/extensions, and cmd/devlore-test/devloretest/data
make check, make test-race, make test-scenario
Test the thing that is easy to assume
That print resolves to the provider is the whole point of the change, and it is invisible — a script
calling print("x") looks identical either way. Assert it directly: a test that captures the narrator
and proves a bare print(...) reaches it, so a future regression that quietly restores the builtin
fails loudly instead of silently going back to stderr.
All six methods take their natural globals — error, fail, note, print, succeed, warn.
A predeclared name cannot be assigned over at module scope, so error = compute() in a script is a resolve error rather than a shadow. Accepted: script authors adopt err for the variable, which is the convention Go authors already follow for exactly the same reason — the language took error first.
That convention needs writing down where authors will meet it: the ui design doc, and the resolve-error path if it can carry a hint.
Scale note for the sweep: 231ui.* call sites across .star files need rewriting to bare names. The 64 print( and 85 fail( sites need no edits — they become provider-backed by resolution.
Two findings from reading placeModule (pkg/op/starlarkbridge/runtime.go:334).
1. The sweep is mandatory. The root path installs each method as its own top-level entry and never sets predeclared[module.Name()]. ui.note() stops resolving — this is a replacement, not an addition. All 231ui.* call sites must be rewritten.
2. Defect in the branch this activates (runtime.go:403):
form:=rangemodule.Methods() {
snake:=op.CamelToSnake(m.Name())
ifrefused[snake] {
return// <- abandons every method not yet placed
}
...
predeclared[snake] =attr
}
return should be continue. One refused method silently drops every method the loop has not yet reached, and because it ranges over module.Methods(), which ones survive depends on iteration order rather than on what the runtime admits.
Never fired: no provider has been RoleModule|RoleRoot, and ui claims deterministic on all six so a hermetic runtime refuses none. Putting ui at root arms it.
Note this is the second defect found in this same unexercised branch — the assertion on line 419 was inverted until #677 step 6 added tests. Fixing it here, with a test that refuses one method of a root provider and asserts the others still surface.
Design docs updated with the signature rationale — docs/architecture/3.5.16-ui-provider.md gains two sections:
Root placement: owning print and fail — the resolver mechanism, the six globals, the fact that root replaces rather than adds, and the error/err convention
Why the signature is (msg string) — double interpretation, the toGoInto type loss, the call-site survey, and the residual cost
The status companion now records that root placement is designed-not-landed, and states the consequence plainly: until it lands, the uniformity the architecture document claims holds for ui.print(...) but not for a bare print(...).
Activity
David-Noble-at-work commentedon Aug 26, 2026
Settled:
errorkeeps the global name.All six methods take their natural globals —
error,fail,note,print,succeed,warn.A predeclared name cannot be assigned over at module scope, so
error = compute()in a script is a resolve error rather than a shadow. Accepted: script authors adopterrfor the variable, which is the convention Go authors already follow for exactly the same reason — the language tookerrorfirst.That convention needs writing down where authors will meet it: the
uidesign doc, and the resolve-error path if it can carry a hint.Scale note for the sweep: 231
ui.*call sites across.starfiles need rewriting to bare names. The 64print(and 85fail(sites need no edits — they become provider-backed by resolution.David-Noble-at-work commentedon Aug 26, 2026
Two findings from reading
placeModule(pkg/op/starlarkbridge/runtime.go:334).1. The sweep is mandatory. The root path installs each method as its own top-level entry and never sets
predeclared[module.Name()].ui.note()stops resolving — this is a replacement, not an addition. All 231ui.*call sites must be rewritten.2. Defect in the branch this activates (
runtime.go:403):returnshould becontinue. One refused method silently drops every method the loop has not yet reached, and because it ranges overmodule.Methods(), which ones survive depends on iteration order rather than on what the runtime admits.Never fired: no provider has been
RoleModule|RoleRoot, anduiclaimsdeterministicon all six so a hermetic runtime refuses none. Puttinguiat root arms it.Note this is the second defect found in this same unexercised branch — the assertion on line 419 was inverted until #677 step 6 added tests. Fixing it here, with a test that refuses one method of a root provider and asserts the others still surface.
David-Noble-at-work commentedon Aug 26, 2026
Design docs updated with the signature rationale —
docs/architecture/3.5.16-ui-provider.mdgains two sections:printandfail— the resolver mechanism, the six globals, the fact that root replaces rather than adds, and theerror/errconvention(msg string)— double interpretation, thetoGoIntotype loss, the call-site survey, and the residual costThe status companion now records that root placement is designed-not-landed, and states the consequence plainly: until it lands, the uniformity the architecture document claims holds for
ui.print(...)but not for a bareprint(...).docs(ui): one string is the correct contract for the narration method…
Providers claim what they guarantee, and a type-checked pass holds th…