3.5 KiB
| id | ticket | title | created | tags | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| LSN-0030 | pbs-service-facade-reserved-metadata | SDK Service Bodies Over Private Reserved Proxies | 2026-04-03 |
|
Context
PBS originally supported two clear execution shapes for SDK surfaces:
- public service wrappers over reserved hosts such as
Log,Gfx, andAssets; - public builtin roots that lower directly to intrinsics.
The @sdk:input surface exposed a third requirement: keep the public API as a normal service, keep the builtin proxy private, and still allow user code like Input.touch().x() and Input.pad().a().pressed() to compile and lower correctly.
The core pitfall was assuming the public callsite itself still had to lower directly to CALL_INTRINSIC. That assumption forced the public API shape back toward builtin roots and broke the intended service abstraction.
Key Decisions
Executable SDK Service Bodies for Builtin/Intrinsic-Backed Public Services
What:
The accepted model keeps SDK_INTERFACE non-executable by default, but allows a restricted executable subset for SDK service methods. Public callsites such as Input.touch() lower as ordinary callable invocations of imported SDK service methods, while intrinsic lowering happens inside those imported method bodies when they call private reserved proxies such as LowInput.
Why: This preserves the intended product-facing API shape. SDK authors can write ordinary service bodies with locals and intermediate processing instead of exposing private builtin roots or inventing a second-class metadata-only facade system.
Trade-offs:
The compiler must preserve owner/chaining semantics across callable returns, not only across direct intrinsic callsites. It also needs an explicit subset boundary and dedicated diagnostics so the executable exception for SDK_INTERFACE does not silently widen into arbitrary interface execution.
Patterns and Algorithms
- Model the public SDK API as a normal service surface and keep the private reserved proxy internal.
- Let the public user callsite lower as
CALL_FUNCwhen the service method is the correct public abstraction. - Preserve reserved owner metadata on callable returns so chained expressions continue to resolve after the service call boundary.
- Validate executable SDK service bodies against an explicit initial subset instead of inferring support from whatever lowering happens to tolerate.
- Emit dedicated diagnostics for unsupported SDK executable constructs rather than collapsing to a generic unresolved-callee error.
Pitfalls
- Do not assume every intrinsic-backed public SDK surface should lower directly from the public callsite to
CALL_INTRINSIC. - Do not leak private builtin roots into the public API merely because the existing lowering path already understands them.
- Do not add a broad executable mode to all
SDK_INTERFACEdeclarations when only a narrow service-method subset is intended. - Do not rely on old tests that assert direct intrinsic callsites once the accepted model changes to callable public entrypoints plus intrinsic lowering inside imported SDK bodies.
Takeaways
- Preserve the public API shape first, then adapt lowering to it when the abstraction is intentional.
- Owner propagation across callable returns is the critical mechanism that makes service-over-intrinsic wrappers behave like ordinary PBS code.
- A restricted executable subset plus dedicated diagnostics is safer than implicit support for arbitrary interface code.