Skip to content

App discovery registries (federated, link-only)

Audience: Agent, integrator, maintainer, registry operator

This document defines an optional EDOS pattern for browsing and resolving hosted apps before a composition host (or similar tool) loads them in an iframe. It is host-agnostic: any environment that embeds EDOS-style hosted UIs MAY implement the same source list and index formats.

Normative capability data remains on each app’s origin in /.well-known/edos-integration.json per HOSTED_APP_CONTRACT.md. Registries are discovery indexes onlylink-only in this revision: index entries MUST NOT embed a full copy of the integration manifest.

Relationship to other contracts

Topic Where it is specified
Integration manifest (capabilities, bootstrap keys, navigation, handshake declaration) HOSTED_APP_CONTRACT.mdauthoritative at app origin
Journal / file postMessage (IFM) IPC.md
Federated registry source list and index JSON This document
Composition-host-specific behavior (default sources, slot schema, fan-out rules) Product docs in the host repo (e.g. elite-dangerous-app-composition) — MUST align with this doc for discovery

Integrators implementing a new hosted app MUST NOT need a registry to conform to HOSTED_APP_CONTRACT.md. Registries are for operator UX (pick an app, browse known publishers) and for caching index metadata — not for replacing per-origin manifests.

Goals

  • Federated sources — Like OS package repositories: multiple independent registry endpoints; the user (or a shipped distribution) chooses which sources to trust.
  • Third-party publishers — Anyone MAY operate a registry server listing only their apps; users add that source explicitly.
  • Link-only indexes — Each index entry points at entryUrl and manifestUrl (or the default well-known manifest on the entry origin). Capabilities are read from the manifest after resolution.
  • Unified mental model — “Tier 1 / 2 / 3” integration levels are deprecated in favor of discovery channels: registry index → origin manifest → runtime handshake → manual URL / host config (see Resolution order).

Non-goals (this revision)

  • A single mandatory global EDOS registry.
  • Embedded manifests inside index files (may be specified later; forbidden in link-only v1).
  • Authentication, signing, or revocation infrastructure (reserved for future revisions).
  • Composition JSON schema, host→app message types, or journal fan-out rules (host product scope).

Definitions

Term Meaning
Composition host A host that loads multiple embedded apps (e.g. dashboard / shell). EDAC (elite-dangerous-app-composition) is the reference consumer.
Registry source A named, user-trusted origin of discovery metadata (label + HTTPS URL of an index).
Index JSON document listing app entries for one source.
Entry One row in an index: stable appId, human metadata, URLs to load UI and fetch manifest.
Effective app id When merging indexes: sourceId + / + appId (see Merging multiple sources).

Federated sources

Source list (host-side configuration)

A composition host SHOULD persist a list of enabled sources. Minimal shape:

{
  "contract": 1,
  "sources": [
    {
      "id": "edos-maintainer",
      "label": "EDOS official",
      "indexUrl": "https://example.edos.howfe.org/edos/discovery/v1/index.json",
      "documentationUrl": "https://docs.edos.howfe.org/"
    }
  ]
}
Field Required Meaning
contract yes Revision of this discovery contract (1 for link-only v1).
sources yes Array of enabled sources.
sources[].id yes Stable id for the source ([a-z0-9][a-z0-9-]*, max 64 chars). Used in effective app ids and collision rules.
sources[].label yes Human-readable name in host UI.
sources[].indexUrl yes HTTPS URL of the index JSON for this source.
sources[].documentationUrl no Link explaining trust scope / publisher.

Rules:

  1. Hosts MUST fetch indexes only over HTTPS.
  2. Adding a source is an explicit user action (or pre-enabled in a distribution the user accepted). Hosts SHOULD show label and documentationUrl before enablement.
  3. Disabling a source MUST NOT delete compositions that already reference apps from it; hosts MAY show stale or unresolved entries until the operator fixes slots.

Merging multiple sources

When building a combined catalog:

  1. Prefix each entry’s appId with its source: effective id = sourceId + / + appId (example: edos-maintainer/elite-dangerous-stellar-scan).
  2. If the same appId appears twice in one index, the index is invalid — registry operators SHOULD deduplicate at publish time.
  3. If two different sources use the same bare appId, they remain distinct after prefixing.
  4. Hosts MAY define display order (e.g. maintainer source first, then alphabetical by label).

Index document (per source)

Discovery URL: each source’s indexUrl MUST return JSON.

Example:

{
  "contract": 1,
  "sourceId": "edos-maintainer",
  "updatedAt": "2026-05-24T12:00:00Z",
  "entries": [
    {
      "appId": "elite-dangerous-stellar-scan",
      "name": "Stellar Scan",
      "entryUrl": "https://edss.howfe.org/",
      "manifestUrl": "https://edss.howfe.org/.well-known/edos-integration.json",
      "documentationUrl": "https://docs.edos.howfe.org/raw/apps/elite-dangerous-stellar-scan.md"
    }
  ]
}

Index — required fields

Field Type Meaning
contract number 1 for this link-only revision.
sourceId string MUST match the source’s id in the host source list.
entries array Zero or more entry objects (empty index is valid).
Field Type Meaning
updatedAt string ISO-8601 timestamp of index publication (informational).
documentationUrl string Publisher-wide documentation for this source.

Entry — required fields

Field Type Meaning
appId string Stable id within the source (often matches workspace folder slug).
name string Human-readable title for catalogs.
entryUrl string HTTPS URL the host loads in an iframe or top-level slot (may include path; query bootstrap added by host per HOSTED_APP_CONTRACT.md).

Entry — recommended fields

Field Type Meaning
manifestUrl string HTTPS URL of the integration manifest. If omitted, hosts MUST derive https://<entry-origin>/.well-known/edos-integration.json from entryUrl.
documentationUrl string Human integration page (capsule, README).
iconUrl string HTTPS URL of an icon for composer UI.
summary string Short description for catalogs.

Entry — forbidden in link-only v1

Field Rule
manifest (inline object) MUST NOT appear. Capabilities MUST be loaded from manifestUrl / well-known path.
Duplicate appId in one index MUST NOT occur.

Unknown top-level and entry fields MUST be ignored by hosts (forward compatibility).

Resolution order (normative for hosts)

When a composition host needs capabilities for a slot (journal opt-in, host messages, bootstrap defaults, navigation views):

  1. Loaded slot URL — If the operator set a concrete entryUrl, use it for bootstrap; still fetch manifest from that origin unless the host caches a recent copy.
  2. Registry entry — If the slot references an effective app id (sourceId/appId), resolve entryUrl and manifestUrl from the merged index (refresh index per host cache policy).
  3. Origin manifest — Fetch and parse /.well-known/edos-integration.json (or explicit manifestUrl). This document is normative for declared capabilities unless superseded by a valid loaded URL per HOSTED_APP_CONTRACT.md — Precedence.
  4. Runtime handshake — Optional edos.handshake after iframe load when manifest is missing, stale, or unreachable — see HOSTED_APP_CONTRACT.md. Handshake MUST NOT grant journal delivery unless capabilities are understood; hosts SHOULD treat handshake as hint and prefer manifest when available.
  5. Manual host configuration — Operator-set flags (e.g. receive journal events, query params) when no declaration exists. Required for arbitrary websites and legacy embeds.

Trust: Journal events and non-IFM host messages MUST only be sent to embeds that opt in via manifest, handshake, or explicit manual configuration — same rule as HOSTED_APP_CONTRACT.md. Registry membership does not imply opt-in.

Manual URL (required host feature)

Composition hosts MUST support adding a slot by pasting an HTTPS URL without a registry entry. Raw websites, internal tools, and one-off links use this path; they may still publish a manifest on their origin if the operator controls it.

Publishing guidance

App maintainers

  1. Publish HOSTED_APP_CONTRACT.md-conformant manifest at /.well-known/edos-integration.json on the production origin.
  2. Ask registry operators to list entryUrl + manifestUrl (or rely on well-known default).
  3. Do not require registry listing for third-party embeds of your app.

Registry operators

  1. Serve index over HTTPS with cache-friendly headers (ETag / Cache-Control recommended).
  2. Keep entries link-only; update updatedAt when the index changes.
  3. Document trust scope at documentationUrl.
  4. TODO: Verify maintainer reference registry URL and deployment host when the first production index ships.

Caching

Hosts MAY cache index and manifest responses. On manifest fetch failure after a cache hit, hosts SHOULD retry once, then fall back to handshake or manual config. Hosts SHOULD NOT use stale manifest data for security-sensitive capabilities without a documented policy.

Reference implementation

EDAC (elite-dangerous-app-composition, host edac.howfe.org) is the first composition host expected to implement this contract. Product phases, schema fields, and D4 planning in that repo MUST follow this document once adopted; until then, EDAC may ship manual slot URLs only.

Conformance checklist

Registry operator

  • [ ] Index is HTTPS, contract: 1, sourceId matches published source id.
  • [ ] Every entry has appId, name, entryUrl; no inline manifest objects.
  • [ ] manifestUrl resolves to a valid integration manifest (or well-known default exists).

Composition host

  • [ ] User can add/remove sources; fetches indexes over HTTPS.
  • [ ] Resolves capabilities per Resolution order.
  • [ ] Supports manual HTTPS URL slots without registry entries.
  • [ ] Does not send journal or host contract messages without opt-in.

Hosted app (unchanged)

Changelog (this document only)

Revision Summary
Initial (2026-05) Federated link-only discovery registries; supersedes “single central registry out of scope” as the only discovery story; resolution order replaces tier 1–3 wording for hosts.