RE-01record 1
{
"id": "RE-01",
"rank": 1,
"repo": "backstage/backstage",
"evidence_class": "observed",
"license": "Apache-2.0 (spdx via gh api)",
"source": "gh api repos/backstage/backstage + repository documentation",
"observed": "2026-08-27",
"claim": "Host shell whose entire purpose is absorbing third-party plugin UI into one nav. RouteRef indirection means a plugin declares a routing TARGET, never a URL; ExternalRouteRef is bound in app-config.yaml so plugin A links to plugin B without depending on it. NavItemBlueprint was REMOVED as a breaking change in v1.51.0 - nav is now auto-discovered from PageBlueprint title/icon, so nav and routes cannot drift.",
"limitations": "Crash isolation only, not security isolation: one React tree, one bundle, donor CSS and globals fully in play. Extensions must all be in a single React element tree, so an intermediate wrapper silently breaks discovery. composability.md is banner-marked legacy.",
"disposition": "steal",
"rationale": "The nearest OSS analogue to Actionist's exact problem, and the source of the single most reusable idea found: donors must never hardcode host URLs."
}
RE-02record 2
{
"id": "RE-02",
"rank": 2,
"repo": "luigi-project/luigi (source at SAP/luigi)",
"evidence_class": "observed",
"license": "Apache-2.0 (spdx via gh api)",
"source": "gh api repos/luigi-project/luigi (source at SAP/luigi) + repository documentation",
"observed": "2026-08-27",
"claim": "The purest OSS host shell: the host declares every navigation node (pathSegment, label, icon, category, children, viewUrl) and the donor contributes NO chrome whatsoever. virtualTree lets a node accept arbitrary child paths without enumerating them - the clean fix for a donor with its own deep router. Host holds the OIDC session; donor calls LuigiClient.getToken().",
"limitations": "isolateView defaults to FALSE, so same-domain nodes reuse one iframe and share a JS context unless opted out per node. iframe modal confinement applies. WC mode is documented only for non-complex micro frontends from trusted sources.",
"disposition": "steal",
"rationale": "The direct OSS embodiment of Option 1 and the cleanest documented answer to donor authentication in the entire survey."
}
RE-03record 3
{
"id": "RE-03",
"rank": 3,
"repo": "marmelab/react-admin",
"evidence_class": "observed",
"license": "MIT (spdx via gh api)",
"source": "gh api repos/marmelab/react-admin + repository documentation",
"observed": "2026-08-27",
"claim": "The best-documented sub-path donor found. docs/Routing.md covers three cases: hash routing works unchanged; createBrowserRouter needs opts.basename; nested inside a host route you use <Admin basename='/admin'>. Docs state plainly that serving the admin from the sub path is your responsibility. <Admin layout={...}> replaces the entire shell, so a pass-through layout yields chrome-free content.",
"limitations": "None material - MIT and cooperative.",
"disposition": "steal",
"rationale": "The reference implementation of host route + basename + replaced layout. This is the exact absorption pattern, already worked and documented by someone else."
}
RE-04record 4
{
"id": "RE-04",
"rank": 4,
"repo": "umijs/qiankun",
"evidence_class": "observed",
"license": "MIT (spdx via gh api)",
"source": "gh api repos/umijs/qiankun + repository documentation",
"observed": "2026-08-27",
"claim": "v3 replaced the 2.x isolation flags with sandbox.styleIsolation built on native CSS @scope, defaulting to false. Its docs are the most honest in the corpus: styleIsolation is 'a one-way boundary' that does not stop host styles entering; the JS sandbox is explicitly 'not a security boundary for running untrusted code' and reads fall through to the host; and a menu, dialog or tooltip portaled to document.body falls outside the scope root so the donor's scoped selectors will not match it.",
"limitations": "Requires native @scope with no polyfill; @font-face stays global; cross-origin stylesheets need CORS or are dropped. All 2.x guidance is obsolete.",
"disposition": "study",
"rationale": "Supplies the two constraints that eliminate whole option families: one-way CSS isolation and unstyled portaled modals. Worth reading precisely because it documents its own limits."
}
RE-05record 5
{
"id": "RE-05",
"rank": 5,
"repo": "module-federation/core",
"evidence_class": "observed",
"license": "MIT (spdx via gh api)",
"source": "gh api repos/module-federation/core + repository documentation",
"observed": "2026-08-27",
"claim": "Runtime code sharing with negotiated shared dependencies. singleton defaults to FALSE so duplication is the silent default, and even singleton:true is defeated by a missing trailing slash ('react-dom' does not intercept react-dom/client, loading a second React). Ships a Bridge subsystem explicitly for framework isolation, ensuring React contexts and component trees between applications are isolated.",
"limitations": "No CSS isolation story at all.",
"disposition": "study",
"rationale": "The Bridge is the vendor conceding that sharing one React tree across a donor boundary is unreliable - which prices every option that assumed otherwise."
}
RE-06record 6
{
"id": "RE-06",
"rank": 6,
"repo": "smapiot/piral",
"evidence_class": "observed",
"license": "MIT (spdx via gh api)",
"source": "gh api repos/smapiot/piral + repository documentation",
"observed": "2026-08-27",
"claim": "The clearest self-registration model: registerPage(route, Component) with one component per page, and registration is ownership-scoped so pilet B cannot unregister pilet A's page. registerMenu/registerTile live in piral-menu/piral-dashboard rather than core; menu items go into global state and are rendered by the app shell's Menu component.",
"limitations": "Isolation is NONE, verified by negative evidence - the pilet spec contains zero occurrences of iframe, sandbox or isolat. Donors must be fully trusted.",
"disposition": "study",
"rationale": "The reference design for nav registry injection (Option 2), including the ownership-scoping detail that prevents donors trampling each other."
}
RE-07record 7
{
"id": "RE-07",
"rank": 7,
"repo": "single-spa/single-spa",
"evidence_class": "observed",
"license": "MIT (LICENSE BODY read - gh api reports NOASSERTION)",
"source": "gh api repos/single-spa/single-spa + repository documentation",
"observed": "2026-08-27",
"claim": "The most widely deployed host-shell router. Apps export bootstrap/mount/unmount; the host owns activity functions. single-spa-layout adds a router with base as a URL PREFIX rather than an exact match, and layout elements are static with no way to force re-render. Unlike qiankun it imposes no one-routing-app limit. navigateToUrl is the cross-app nav primitive.",
"limitations": "No CSS isolation whatsoever. Its docs state it deviates from the browser's default history behaviour in some cases. Docs themselves recommend a monolith for small teams.",
"disposition": "study",
"rationale": "The textbook demonstration that spdx_id is not a rights answer - and the primitive most likely to underpin any microfrontend option Actionist chooses."
}
RE-08record 8
{
"id": "RE-08",
"rank": 8,
"repo": "refinedev/refine",
"evidence_class": "observed",
"license": "MIT (spdx via gh api)",
"source": "gh api repos/refinedev/refine + repository documentation",
"observed": "2026-08-27",
"claim": "Headless by construction - no chrome to strip. routerProvider adapts to the HOST's router rather than owning routing; data, auth and access control are provider interfaces.",
"limitations": "Documents NO basename/basePath of its own; sub-path behaviour is inherited from whichever router is plugged in. Claiming Refine supports a basename would be inference, not citation.",
"disposition": "steal",
"rationale": "Proves the cheapest absorption is the donor that never had a shell, and models the provider-adapter shape a well-behaved donor should take."
}
RE-09record 9
{
"id": "RE-09",
"rank": 9,
"repo": "nocobase/nocobase",
"evidence_class": "observed",
"license": "NocoBase License Agreement (LICENSE.txt BODY read; gh api reports NOASSERTION)",
"source": "gh api repos/nocobase/nocobase + repository documentation",
"observed": "2026-08-27",
"claim": "Plugin-registered nav registry very close to Actionist's target, with runtime path substitution via APP_PUBLIC_PATH/API_BASE_PATH at container start rather than build time. BUT the licence incorporates Apache-2.0 while stating its supplementary terms prevail on conflict, and Section 5.2 forbids removing or changing NocoBase branding on the interface except the main logo in the upper left corner; Section 5.4 forbids public no-code/low-code SaaS.",
"limitations": "Technically partial donor-chrome capability, but stripping the branding is a licence violation rather than an engineering task. Legal interpretation is not this run's to make.",
"disposition": "hold",
"rationale": "The exact ELv2-class trap this project has already been burned on: an Apache badge over terms that forbid the specific operation absorption requires."
}
RE-10record 10
{
"id": "RE-10",
"rank": 10,
"repo": "directus/directus",
"evidence_class": "observed",
"license": "MSCL-1.0-GPL (LICENSE BODY read; gh api reports NOASSERTION)",
"source": "gh api repos/directus/directus + repository documentation",
"observed": "2026-08-27",
"claim": "High-profile donor candidate whose licence changed under everyone's feet. Now Monospace Sustainable Core License v1.0, Copyright 2026 Monospace Inc., granting use only for a Permitted Purpose defined as anything other than a Competing Use, forbidding you to move, change, disable or circumvent the licence key functionality, and granting GPL-3.0 only on the FOURTH ANNIVERSARY. PUBLIC_URL is documented for link generation, not sub-path serving; ROOT_REDIRECT defaults to ./admin with no documented way to relocate it.",
"limitations": "Not permissive and not copyleft - source-available with anti-circumvention. Whether consultancy use is a Permitted Purpose is a lawyer's call.",
"disposition": "hold",
"rationale": "Included precisely because any prior register recording Directus as BSL or GPL is stale, and a stale rights claim in a client deliverable is the expensive kind of error."
}