feat: open Limrun uploaded apps - #2110
Conversation
Size Report
npm unpacked components
Startup median (7 runs, lower is better):
Top changed chunks:
Top changed packed files
|
|
Not ready. [P1] Fail closed when mapping an uploaded asset to the installed app. [P2] Preserve request cancellation through sessionless catalog lookup. Exact-head Coverage has two owner-action failures: |
82cb7cb to
dbfa651
Compare
|
Addressed in dbfa651 after rebasing onto current main:
Local static gates and exact ratchets pass. The affected suite produced changing unrelated load failures across two runs; all 3,753 tests passed on the first run before teardown noise, and the second run's two timed-out interaction-contract files passed 16/16 immediately in isolation. Fresh exact-head CI is running. |
dbfa651 to
24bdcd0
Compare
|
Re-reviewed It is not merge-ready yet:
Main compatibility is clean. |
|
Addressed at exact head Live Limrun evidence:
Size rationale is updated in the PR body for exact-head Size CI: +6.3 kB npm unpacked (+6.0 kB raw JS, +3.3 kB gzip, +2.4 kB tarball), entirely under JS/dist. About 3.4 kB raw is the three lazy provider-owned feature chunks ( Exact-head CI is now fully green, including iOS Smoke. |
|
Follow-up size audit at |
|
Reviewed exact head 32309bb: clean and ready for human review. The delta from the live-tested behavior head is a behavior-preserving relocation of the two app-preinstall functions into session-allocation; exact-head checks are fully green. Discovery remains allocation-free, exact uploaded-name selection precedes allocation, identity resolution fails closed, and cancellation is threaded. Size rationale and planted-red coverage are sufficient. Residual: live Limrun evidence is stamped at 265259c, but the current byte-equivalent relocation plus exact-head package/platform CI does not warrant a device rerun. |
|
Provider-independence follow-up at |
|
Added a structural guard for provider-independent commands in Why the existing layering gate instead of an Oxlint plugin:
Failure-direction evidence: a planted |
|
Re-reviewed current exact head 024404d (the helper-triggered 599619f was superseded). This head is not ready: Lint & Format has a real owner-action failure at packages/provider-limrun/src/app-catalog.ts:98 (use replaceAll), and the new command-provider structural guard is bypassable by destructuring/aliasing verification.provider before comparing it. Its planted test covers only direct member expressions, so the claimed no-provider-branch guarantee is false. Strengthen the owning declaration/rule and plant alias/destructuring red. The prior iOS form-input failure is unrelated to this delta and likely runtime-shaped, but current-head iOS remains authoritative. ready-for-human should be removed until lint and guard validity are fixed. |
|
Follow-up The planted-red proof used the existing Validation: |
|
Re-reviewed exact head 27f67c3: still blocked. The lint finding is not fixed—app-catalog.ts still uses replace(/.../g); the new commit edits obsolete .oxlintrc.json, which main deleted in favor of oxlint.config.ts. The provider guard is also unchanged and remains bypassable through alias/destructuring; the new provider-package import restriction does not catch literal comparisons without imports, and no planted alias regression was added. GitHub reports CONFLICTING, so only CodeQL ran. Rebase current main, fix config at its owning file, use replaceAll, strengthen/test the provider identity boundary, then run full exact-head CI. |
|
Cleanup follow-up: removed the custom R71 AST scan and its dedicated test/wiring (102 lines). It only recognized selected comparison/switch syntax, so expanding it would become a partial data-flow linter with ongoing false-positive/false-negative cost. The retained boundary is the built-in Oxlint |
20621de to
69e7ee8
Compare
|
Addressed the still-relevant findings at rebased head |
|
Reviewed exact head P1 — provider-independent commands are still not enforced. The latest commit deletes R71 and its regression test instead of closing the alias/destructuring bypass. The replacement Please enforce this at an owning interface—either a complete structural rule with planted alias/destructuring red proof, or a type/API design that prevents command code from obtaining provider identity. Do not narrow the guarantee to import-only without explicit maintainer approval. The production route, fail-closed identity resolution, live Limrun evidence, size rationale, mergeability, and exact-head CI otherwise look good. |
|
Addressed the remaining provider-identity boundary at exact head
Planted-red proof: a temporary command copied Validation: focused connection/provider/state tests passed 77/77; format, lint, typecheck, layering, fallow, build, package, and integration-node passed in the full affected run. The broad related shard twice hit the same unrelated No docs or skills changed: this is enforcement and internal ownership only. |
|
Exact head |
|
Reviewed exact head P1 — sessionless Derive this exemption from the trusted semantic deferred-catalog capability (or otherwise restrict it to the catalog-owning provider) before admission. Plant negative tests proving unknown, proxy, and WebDriver provider values remain lease-rejected and never bind a device. The new provider-identity lint does close direct, alias, computed, and destructuring reads; exact-head CI and the remaining Limrun route look good. |
|
Addressed the tenant admission bypass at exact head |
|
Addressed the architecture concern at exact head I re-reviewed the first fix against the provider-runtime and daemon-admission seams and replaced it rather than keeping the raw ID plumbing:
Evidence:
Exact-head GitHub CI is running. |
|
Final architecture audit at exact head
Exact-head CI is fully green across Size, static/architecture gates, coverage, integration, CodeQL, and Android/iOS/Linux/macOS smoke tests. GitHub reports the PR |
|
Independent review found one security contract to resolve before approval: sessionless Otherwise the implementation is cohesive: |
|
Size follow-up at
I did not take the larger-looking reductions: merging the catalog with allocation still saves only about 403 raw bytes while making pre-allocation The fresh tenant comment is valid and requires an explicit security-policy decision before it can be called addressed. The Limrun runtime has one daemon-wide API key. Therefore both sessionless The 1,000-item observation is also accurate, but Limrun SDK 0.24.5 exposes Validation: focused capability/connection tests pass 23/23. The full affected run passed format, lint, typecheck, layering, DI seams, fallow, build, package, integration-node, macOS coverage, and all 3,956 related assertions; it then reported the known unrelated Apple-runner late-import teardown in |
|
Re-review at The tenant finding remains intentionally unresolved, so this is still not merge-ready: both sessionless The 1,000-item catalog limit also remains a minor follow-up. With no provider pagination, do not simulate it locally; choose an incomplete-result/warning contract or obtain upstream pagination support. |
Summary
Let Limrun users discover and launch previously uploaded app assets through the existing app workflow without adding a provider-specific flag or public API.
connect limrunremains handshake-only and does not allocate an instanceagent-device appslists compatible uploaded assets for the selected platformagent-device open <exact-uploaded-asset-name>allocates with LimruninitialAssets, resolves an exact installed identity, and launches itappskeeps its existing installed-app behavior; unmatched open targets preserve the existing pathThe implementation keeps provider asset discovery, preinstallation, and identity mapping in the Limrun owner while reusing the normal CLI, daemon, lifecycle, and JavaScript command paths. Production commands ask semantic connection-policy capabilities instead of inspecting provider identities or importing provider implementations. Oxlint enforces both boundaries.
Size rationale
Exact-head Size CI measures +6.4 kB npm unpacked (+6.1 kB raw JS, +3.1 kB gzip, +2.6 kB tarball). The packed growth is split across:
app-catalog.js, 1.4 kB) and allocation plus fail-closed installed-identity resolution (session-allocation.js, 2.0 kB)appsdaemon route, capability-driven deferred selection, provider-owned app-reference resolution, trusted catalog admission, CLI help, declarations, and the provider-independence enforcement follow-upThe largest per-file movements are chunk relocation rather than additive feature size:
device-session.jsappears at +10.8 kB whilesrc.jsfalls 10.8 kB. The +6.4 kB aggregate is the authoritative net result after those moves. The final admission hardening deepens the existing composed catalog with side-effect-free capability admission and authoritative listing; it adds no parallel owner registry or eager provider dependency. The latest capability-owner cleanup removes 41 production lines and 221 emitted bytes by replacing seven shallow predicates with the existing capability projection.A counterfactual size audit tested broader coalescing: one Limrun app chunk would save only another 403 raw bytes over the chosen layout while making pre-allocation
appsload a 17.4 kB allocation/platform chunk. Keeping catalog lookup separate avoids that runtime regression. The remaining Limrun modules are loaded lazily, preserving the provider runtime's 29-module eager closure. A smaller device-inventory seam was rejected because installed-app inventory requires allocation and cannot represent uploaded assets; resolving in the CLI would duplicate provider authentication and asset semantics outside their owner. A new Limrun-only command or flag was also avoided so local and remote app discovery keep the same workflow.Validation
Live Limrun verification at behavior head
265259cc62:connectcalls verified access while reportingleaseAllocated: false; pre-allocationappslisted uploaded filenames without creating an instancecom.callstack.agentdevicelab.apkascom.callstack.agentdevicelabin 6.15s wall time, returned a healthyandroid-helper0.20.11-dev snapshot, clicked the Catalog ref, and verified the Catalog screeneasagentdevice.app.zipasdev.expo.easagentdevicein 4.64s wall time, returned the Development Build snapshot, clicked INFO, and verified the information screenLEASE_NOT_FOUND; both exact instance IDs were then queried directly and returned 404, and both local connection profiles were disconnectedCurrent rebased head
2e6bf6bec8:origin/main; GitHub reports the PR mergeable with no conflicts.leaseProviderreads in both production command roots, plus connection-result.providerreads in CLI commandsappCatalog; plantedbogus,proxy, andbrowserstackcases failed before the fix and now reject without catalog, runtime-fact, or device-bind accessapps: []authoritatively without device accesssession-replay-repair-transaction.test.tspasses 17/17 alone with one workerSecurity policy decision pending from review: the daemon-wide Limrun credential makes uploaded assets account-scoped today. Both
appsand exact-name selection duringopenmust share any future tenant entitlement; gating listing alone would not close the boundary. The 0.24.5 SDK asset endpoint exposes onlylimitandnameFilter, with no cursor or offset, so catalogs beyond the current 1,000-item request cannot be completely paginated client-side.This touches 49 files. Scope spans the existing
appscommand, Limrun provider runtime, shared provider contracts, daemon routing and admission, tests, CLI help, and the existing lint configuration; it does not add a command family, public API, or flag.