Skip to content

Mark ui +devlore:root=true and sweep the ui.* call sites #700

Closed

Description

@David-Noble-at-work

Feature: #698 · Epic: #445 · Plan: docs/plans/ui-at-root.md
Depends on: the variadic task — the replacement must accept what the builtin accepted

Add +devlore:root=true to the ui provider and absorb the consequences.

Steps

  1. +devlore:root=true on the provider struct
  2. Regenerate; verify ui announces RoleModule|RoleAction|RoleRoot
  3. Confirm the six names install as top-level globals, and that print and fail resolve to the
    provider rather than to starlark.Universe
  4. 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
  5. 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.

Watch for

Activity

  1. David-Noble-at-work commented on Aug 26, 2026

    @David-Noble-at-work
    ContributorAuthor

    Settled: error keeps 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 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: 231 ui.* 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.

  2. David-Noble-at-work commented on Aug 26, 2026

    @David-Noble-at-work
    ContributorAuthor

    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 231 ui.* call sites must be rewritten.

    2. Defect in the branch this activates (runtime.go:403):

    for m := range module.Methods() {
        snake := op.CamelToSnake(m.Name())
        if refused[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.

  3. David-Noble-at-work commented on Aug 26, 2026

    @David-Noble-at-work
    ContributorAuthor

    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(...).

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

Metadata

Metadata

Labels

Area:ArchitectureSystem architecture and designEpic:StarlarkSurfaceThe Starlark authoring surfacePriority:P2Scheduled, not urgenttaskImplementation work item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions