{
  "@context": [
    "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^8.0.0/components/context.jsonld",
    "https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/components/context.jsonld",
    "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld",
    {
      "rememberedGrantStorage": "RememberedClientGrantStore:_storage",
      "rdfTemplateBaseUrl": "RdfHandlebarsTemplateEngine:_baseUrl",
      "rememberedPromptSource": "RememberedClientPromptFactory:_source",
      "rememberedPromptStore": "RememberedClientPromptFactory:_store",
      "rememberedConsentSource": "RememberedConsentHandler:_source",
      "rememberedConsentStore": "RememberedConsentHandler:_store",
      "rememberedConsentProvider": "RememberedConsentHandler:_providerFactory",
      "scopedRememberedGrantStore": "ScopedPickWebIdHandler:_options_rememberedClientGrantStore"
    }
  ],
  "import": [
    "./cli.json",
    "./resolver.json",
    "./notifications.json"
  ],
  "@graph": [
    {
      "@id": "urn:undefineds:xpod:RememberedClientGrantStore",
      "@type": "RememberedClientGrantStore",
      "rememberedGrantStorage": {
        "@type": "WrappedExpiringStorage",
        "source": {
          "@type": "ContainerPathStorage",
          "relativePath": "/idp/remembered-clients/",
          "source": { "@id": "urn:solid-server:default:KeyValueStorage" }
        }
      }
    },
    {
      "comment": "Retain default account/WebID checks and restore explicitly remembered Desktop grants before consent.",
      "@type": "Override",
      "overrideInstance": { "@id": "urn:solid-server:default:PromptFactory" },
      "overrideParameters": {
        "@type": "RememberedClientPromptFactory",
        "rememberedPromptSource": {
          "@type": "AccountPromptFactory",
          "webIdStore": { "@id": "urn:solid-server:default:WebIdStore" },
          "cookieStore": { "@id": "urn:solid-server:default:CookieStore" },
          "cookieName": { "@id": "urn:solid-server:default:value:accountCookieName" }
        },
        "rememberedPromptStore": { "@id": "urn:undefineds:xpod:RememberedClientGrantStore" }
      }
    },
    {
      "comment": "Keep CSS consent processing and persist the user's explicit remember-app choice.",
      "@type": "Override",
      "overrideInstance": { "@id": "urn:solid-server:default:ConsentHandler" },
      "overrideParameters": {
        "@type": "StatusWaterfallHandler",
        "handlers": [
          {
            "@type": "MethodFilterHandler",
            "methods": [ "GET" ],
            "source": {
              "@type": "ClientInfoHandler",
              "providerFactory": { "@id": "urn:solid-server:default:IdentityProviderFactory" }
            }
          },
          {
            "@type": "MethodFilterHandler",
            "methods": [ "POST" ],
            "source": {
              "@type": "RememberedConsentHandler",
              "rememberedConsentProvider": { "@id": "urn:solid-server:default:IdentityProviderFactory" },
              "rememberedConsentSource": {
                "@type": "ConsentHandler",
                "providerFactory": { "@id": "urn:solid-server:default:IdentityProviderFactory" }
              },
              "rememberedConsentStore": { "@id": "urn:undefineds:xpod:RememberedClientGrantStore" }
            }
          }
        ]
      }
    },
    {
      "comment": "Close the profile-owned RDF authority after writes stop.",
      "@id": "urn:solid-server:default:CleanupFinalizer",
      "@type": "SequenceHandler",
      "handlers": [
        {
          "@type": "FinalizableHandler",
          "finalizable": { "@id": "urn:undefineds:xpod:SolidRdfDataAccessor" }
        }
      ]
    },
    {
      "comment": "Core mode: server or local",
      "@id": "urn:solid-server:default:variable:edition",
      "@type": "Variable"
    },
    {
      "comment": "Whether edge node registry is enabled.",
      "@id": "urn:solid-server:default:variable:edgeNodesEnabled",
      "@type": "Variable"
    },
    {
      "comment": "Durable search intent sink for committed RDF/text source changes.",
      "@id": "urn:undefineds:xpod:RdfSearchIntentSink",
      "@type": "RdfSearchReconciliationIntentSink",
      "identityDbUrl": {
        "@id": "urn:solid-server:default:variable:identityDbUrl",
        "@type": "Variable"
      }
    },
    {
      "comment": "An accessor for a Minio",
      "@type": "MinioDataAccessor",
      "@id": "urn:undefineds:xpod:MinioDataAccessor"
    },
    {
      "comment": "Static Asset Handler for the React UI.",
      "@type": "AppStaticAssetHandler",
      "@id": "urn:undefineds:xpod:AppStaticAssetHandler"
    },
    {
      "comment": "Override root static asset to serve xpod SPA shell page.",
      "@type": "Override",
      "overrideInstance": {
        "@id": "urn:solid-server:default:RootStaticAsset"
      },
      "overrideParameters": {
        "@type": "StaticAssetEntry",
        "relativeUrl": "/",
        "filePath": "./static/app/index.html"
      }
    },
    {
      "comment": "Reserve admin routes for control plane and prevent conflicting pod IDs.",
      "@type": "Override",
      "overrideInstance": {
        "@id": "urn:solid-server:default:IdentifierGenerator"
      },
      "overrideParameters": {
        "@type": "ReservedSuffixIdentifierGenerator",
        "baseUrl": {
          "@id": "urn:solid-server:default:variable:baseUrl",
          "@type": "Variable"
        },
        "reserved": [
          "admin"
        ]
      }
    },
    {
      "comment": "Replace HtmlViewHandler with ReactAppViewHandler - serves single React app for all identity routes.",
      "@type": "Override",
      "overrideInstance": {
        "@id": "urn:solid-server:default:HtmlViewHandler"
      },
      "overrideParameters": {
        "@type": "ReactAppViewHandler",
        "index": { "@id": "urn:solid-server:default:IndexRoute" },
        "htmlFile": "./static/app/auth.html"
      }
    },
    {
      "comment": "Validate CSS account cookies against account storage to avoid stale browser sessions after data resets.",
      "@type": "Override",
      "overrideInstance": {
        "@id": "urn:solid-server:default:IdentityProviderHttpHandler"
      },
      "overrideParameters": {
        "@type": "ValidatingIdentityProviderHttpHandler",
        "providerFactory": {
          "@id": "urn:solid-server:default:IdentityProviderFactory"
        },
        "cookieStore": {
          "@id": "urn:solid-server:default:CookieStore"
        },
        "handler": {
          "@id": "urn:solid-server:default:InteractionHandler"
        },
        "accountStorage": {
          "@id": "urn:solid-server:default:AccountStorage"
        },
        "ValidatingIdentityProviderHttpHandler:_args_externalAccountIssuer": {
          "@id": "urn:solid-server:default:variable:oidcIssuer"
        }
      }
    },
    {
      "comment": "Keep full Solid OIDC and DPoP verification while admitting the configured HTTP loopback IP origin used by the desktop runtime.",
      "@type": "Override",
      "overrideInstance": {
        "@id": "urn:solid-server:default:DPoPWebIdExtractor"
      },
      "overrideParameters": {
        "@type": "ConfiguredLoopbackDPoPWebIdExtractor",
        "originalUrlExtractor": {
          "@id": "urn:solid-server:default:DPoPUrlExtractor"
        },
        "baseUrl": {
          "@id": "urn:solid-server:default:variable:baseUrl",
          "@type": "Variable"
        }
      }
    },
    {
      "comment": "Resolve account WebID ownership through the CSS identity stores without opening a second database connection.",
      "@id": "urn:undefineds:xpod:PodOwnershipResolver",
      "@type": "https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/dist/identity/oidc/PodOwnershipResolver.jsonld#CssPodOwnershipResolver",
      "@context": {
        "webIdStore": "https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/dist/identity/oidc/PodOwnershipResolver.jsonld#CssPodOwnershipResolver_options_webIdStore",
        "podStore": "https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/dist/identity/oidc/PodOwnershipResolver.jsonld#CssPodOwnershipResolver_options_podStore"
      },
      "webIdStore": {
        "@id": "urn:solid-server:default:WebIdStore"
      },
      "podStore": {
        "@id": "urn:solid-server:default:PodStore"
      }
    },
    {
      "comment": "Scope OIDC WebID choices to Pods known by the current storage provider.",
      "@type": "Override",
      "overrideInstance": {
        "@id": "urn:solid-server:default:PickWebIdHandler"
      },
      "overrideParameters": {
        "@type": "ScopedPickWebIdHandler",
        "scopedRememberedGrantStore": { "@id": "urn:undefineds:xpod:RememberedClientGrantStore" },
        "ownershipResolver": {
          "@id": "urn:undefineds:xpod:PodOwnershipResolver"
        },
        "providerFactory": {
          "@id": "urn:solid-server:default:IdentityProviderFactory"
        },
        "storageBaseUrl": {
          "@id": "urn:solid-server:default:variable:baseUrl",
          "@type": "Variable"
        },
        "provisionBaseUrl": {
          "@id": "urn:solid-server:default:variable:oidcIssuer",
          "@type": "Variable"
        }
      }
    },
    {
      "comment": "Expose exact Account-owned WebID/storage pairs; Local retains its storage-root scope.",
      "@id": "urn:undefineds:xpod:AccountStorageBindingsRoute",
      "@type": "RelativePathInteractionRoute",
      "base": {
        "@id": "urn:solid-server:default:AccountIdRoute"
      },
      "relativePath": "bindings/"
    },
    {
      "@id": "urn:undefineds:xpod:AccountStorageBindingsRouter",
      "@type": "AuthorizedRouteHandler",
      "route": {
        "@id": "urn:undefineds:xpod:AccountStorageBindingsRoute"
      },
      "source": {
        "@id": "urn:undefineds:xpod:AccountStorageBindingsHandler",
        "@type": "AccountStorageBindingsHandler",
        "edition": {
          "@id": "urn:solid-server:default:variable:edition",
          "@type": "Variable"
        },
        "podStore": {
          "@id": "urn:solid-server:default:PodStore"
        },
        "storageBaseUrl": {
          "@id": "urn:solid-server:default:variable:baseUrl",
          "@type": "Variable"
        }
      }
    },
    {
      "comment": "Route the authorized bindings resource through CSS's account interaction chain.",
      "@id": "urn:solid-server:default:InteractionRouteHandler",
      "@type": "StatusWaterfallHandler",
      "handlers": [
        {
          "@id": "urn:undefineds:xpod:AccountStorageBindingsRouter"
        }
      ]
    },
    {
      "@id": "urn:solid-server:default:AccountControlHandler",
      "@type": "ControlHandler",
      "controls": [
        {
          "ControlHandler:_controls_key": "bindings",
          "ControlHandler:_controls_value": {
            "@id": "urn:undefineds:xpod:AccountStorageBindingsRoute"
          }
        }
      ]
    },
    {
      "comment": "Preserve exact WebID IRIs only in controlled CSS RDF templates; keep EJS and HTML escaping unchanged.",
      "@type": "Override",
      "overrideInstance": { "@id": "urn:solid-server:default:TemplateEngine" },
      "overrideParameters": {
        "@type": "StatusWaterfallHandler",
        "handlers": [
          {
            "@type": "EjsTemplateEngine",
            "baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" }
          },
          {
            "@type": "RdfHandlebarsTemplateEngine",
            "rdfTemplateBaseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" }
          }
        ]
      }
    },
    {
      "comment": "Override main HTML template to remove CSS default header/footer wrapper.",
      "@type": "Override",
      "overrideInstance": {
        "@id": "urn:solid-server:default:MainTemplateEngine"
      },
      "overrideParameters": {
        "@type": "StaticTemplateEngine",
        "templateEngine": { "@id": "urn:solid-server:default:TemplateEngine" },
        "template": "./templates/main.html.ejs"
      }
    },
    {
      "comment": "Expose the canonical storage URL for remotely provisioned Pods without creating a phantom Cloud Pod.",
      "@type": "Override",
      "overrideInstance": {
        "@id": "urn:solid-server:default:PodStore"
      },
      "overrideParameters": {
        "@type": "ProvisionPodStore",
        "storage": { "@id": "urn:solid-server:default:AccountStorage" },
        "manager": { "@id": "urn:solid-server:default:PodManager" }
      }
    },
    {
      "comment": "Extend PodCreator with provisioning and reconcile the Solid storage binding after CSS creates its native Pod resources.",
      "@type": "Override",
      "overrideInstance": {
        "@id": "urn:solid-server:default:PodCreator"
      },
      "overrideParameters": {
        "@type": "ProvisionPodCreator",
        "baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
        "provisionBaseUrl": {
          "@id": "urn:solid-server:default:variable:oidcIssuer",
          "@type": "Variable"
        },
        "nodeId": {
          "@id": "urn:solid-server:default:variable:nodeId",
          "@type": "Variable"
        },
        "identifierGenerator": { "@id": "urn:solid-server:default:IdentifierGenerator" },
        "relativeWebIdPath": "/profile/card#me",
        "webIdStore": { "@id": "urn:solid-server:default:WebIdStore" },
        "podStore": { "@id": "urn:solid-server:default:PodStore" },
        "resourceStore": { "@id": "urn:solid-server:default:ResourceStore" },
        "identityDbUrl": { "@id": "urn:solid-server:default:variable:identityDbUrl" }
      }
    },
    {
      "comment": "Subgraph query engine wrapping default SPARQL engine (DefaultSparqlEngine defined in profile)",
      "@type": "SubgraphQueryEngine",
      "@id": "urn:undefineds:xpod:SubgraphQueryEngine",
      "engine": {
        "@id": "urn:undefineds:xpod:DefaultSparqlEngine"
      }
    },
    {
      "comment": "Serves subgraph-scoped SPARQL endpoints. `emitter` is the activity emitter the notification stack listens to (css:config/http/notifications/base/listener.json subscribes to urn:solid-server:default:ResourceStore, i.e. the MonitoringStore), so /-/sparql writes notify like store writes.",
      "@type": "SubgraphSparqlHttpHandler",
      "@id": "urn:undefineds:xpod:SubgraphSparqlHttpHandler",
      "queryEngine": {
        "@id": "urn:undefineds:xpod:SubgraphQueryEngine"
      },
      "credentialsExtractor": {
        "@id": "urn:solid-server:default:CredentialsExtractor"
      },
      "permissionReader": {
        "@id": "urn:solid-server:default:PermissionReader"
      },
      "authorizer": {
        "@id": "urn:solid-server:default:Authorizer"
      },
      "updateAuthority": {
        "@id": "urn:undefineds:xpod:MixDataAccessor"
      },
      "emitter": {
        "@id": "urn:solid-server:default:ResourceStore"
      },
      "options_identityDbUrl": {
        "@id": "urn:solid-server:default:variable:identityDbUrl",
        "@type": "Variable"
      },
      "options_usageDbUrl": {
        "@id": "urn:solid-server:default:variable:usageDbUrl",
        "@type": "Variable"
      },
      "options_defaultAccountBandwidthLimitBps": {
        "@type": "Literal",
        "value": 0
      }
    },
    {
      "comment": "Loopback-only runtime-signed hosted Pod data channel for AI Connection resources.",
      "@type": "https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/dist/http/InternalPodDataHttpHandler.jsonld#InternalPodDataHttpHandler",
      "@id": "urn:undefineds:xpod:InternalPodDataHttpHandler",
      "@context": {
        "resourceStore": "https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/dist/http/InternalPodDataHttpHandler.jsonld#InternalPodDataHttpHandler_options_resourceStore",
        "patchBodyParser": "https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/dist/http/InternalPodDataHttpHandler.jsonld#InternalPodDataHttpHandler_options_patchBodyParser",
        "sparqlHandler": "https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/dist/http/InternalPodDataHttpHandler.jsonld#InternalPodDataHttpHandler_options_sparqlHandler",
        "baseUrl": "https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/dist/http/InternalPodDataHttpHandler.jsonld#InternalPodDataHttpHandler_options_baseUrl"
      },
      "resourceStore": {
        "@id": "urn:solid-server:default:ResourceStore"
      },
      "patchBodyParser": {
        "@id": "urn:solid-server:default:PatchBodyParser"
      },
      "sparqlHandler": {
        "@id": "urn:undefineds:xpod:SubgraphSparqlHttpHandler"
      },
      "baseUrl": {
        "@id": "urn:solid-server:default:variable:baseUrl",
        "@type": "Variable"
      }
    },
    {
      "comment": "Tracing handler for request ID and logging. Added to CSS Middleware.",
      "@id": "urn:undefineds:xpod:TracingHandler",
      "@type": "TracingHandler"
    },
    {
      "comment": "Override CSS Middleware to add TracingHandler at the beginning.",
      "@type": "Override",
      "overrideInstance": {
        "@id": "urn:solid-server:default:Middleware"
      },
      "overrideParameters": {
        "@type": "SequenceHandler",
        "handlers": [
          { "@id": "urn:undefineds:xpod:TracingHandler" },
          { "@id": "urn:solid-server:default:ParallelMiddleware" },
          { "@id": "urn:solid-server:default:Middleware_Cors" }
        ]
      }
    }
  ]
}
