Current state
`ms.Resolve[T any](id string) (T, bool)` ships as a stub that always returns `(zero, false)`. See `describe.go:105-118`.
The API shape is locked in so code written today keeps compiling when real resolution arrives — but until then, any module that writes:
```go
if client, ok := ms.Resolveuserclient.Client; ok {
client.Do(...)
} else {
// fallback
}
```
...permanently takes the fallback branch in production with zero signal that resolution is unimplemented.
Scope of the follow-up
Depends on #82 and the eventual catalog work:
- Cross-module client registry — mechanism for a module to expose a typed client, catalog to track per-(workspace, moduleID) → client-pointer bindings, SDK to resolve at call time.
- Replace the stub with real lookup backed by that registry.
- Consider a dev-mode signal until then — e.g. `ms.Resolve` could log a one-time warning when called with an ID that matches a declared `ms.Needs(spec)` dep, to surface the "silently takes fallback" case during local development.
Out of scope here
No changes until the catalog work starts. Flagged during /simplify on PR #87 as a potential trap — documented as intentional-for-v1.
Current state
`ms.Resolve[T any](id string) (T, bool)` ships as a stub that always returns `(zero, false)`. See `describe.go:105-118`.
The API shape is locked in so code written today keeps compiling when real resolution arrives — but until then, any module that writes:
```go
if client, ok := ms.Resolveuserclient.Client; ok {
client.Do(...)
} else {
// fallback
}
```
...permanently takes the fallback branch in production with zero signal that resolution is unimplemented.
Scope of the follow-up
Depends on #82 and the eventual catalog work:
Out of scope here
No changes until the catalog work starts. Flagged during /simplify on PR #87 as a potential trap — documented as intentional-for-v1.