Mossland Verified Links — the official link registry for https://links.moss.land.
This repository is the verified-links registry for the Mossland ecosystem: the
canonical list of official Mossland domains, ecosystem apps, developer resources,
and third-party market references. Anything not listed here should be treated as
unofficial. It is deployed with AWS Amplify and served at https://links.moss.land.
The page is KR-primary, bilingual (Korean lead, English support) and its core job is anti-phishing: telling a visitor which domains are genuinely Mossland's.
ecosystem-registry.json is the single source of
truth. Each service is keyed by a stable id and carries name, domain,
url, tier, status and passportEligible (required), plus optional
section, stampType/stampClass, labelKo/label, chip and more (see
ecosystem-registry.schema.json for the
contract). The same file also holds the classification rubric and its
rubricVersion. Other Mossland properties (moss.land, Passport, City, WA) can
fetch it cross-origin (CORS *) to verify "is this a real Mossland domain?" and
to drive Passport ecosystem stamps.
index.html, embed.html, llms.txt, and sitemap.xml are generated from
the registry. Do not edit them by hand — edit the registry (or the
template/CSS in build/) and rebuild:
node build/generate.mjsCI enforces this, it is not just convention.
.github/workflows/registry.yml runs on every
push and pull request: it validates the registry against the schema and fails
the build if the committed pages are not byte-identical to a fresh generator
run. Check locally before pushing:
node build/generate.mjs && git diff --exit-code # projection is clean
python .github/scripts/validate-registry.py # registry contract + rubricThe validator needs pip install "jsonschema[format-nongpl]".
The generator is pure Node (no dependencies) and idempotent. Amplify re-runs it
on deploy, but with || true — so what actually ships is the committed output,
and the CI check at merge time is what guarantees it matches the registry.
| File | Role |
|---|---|
ecosystem-registry.json |
Source of truth — every service and its fields, plus the classification rubric / rubricVersion that drives the chips and legend |
ecosystem-registry.schema.json |
JSON Schema (draft 2020-12) contract for the registry |
assurance/RUBRIC.md |
Rubric changelog, precedence table, and version-bump rules (the rubric itself is data in the registry) |
build/generate.mjs |
Generator — renders index.html + embed.html + llms.txt + sitemap.xml from the registry, deriving chips and legend from the registry's rubric |
build/style.css |
Stylesheet, inlined into the generated HTML |
index.html |
Generated public page (do not edit by hand) |
embed.html |
Generated chrome-less kiosk view for embedding in play.wa / Mossverse |
llms.txt |
Generated AI-readable summary (llmstxt.org format, English) |
sitemap.xml |
Generated (lastmod from the registry's generatedAt) |
robots.txt |
Static crawl directives (points to the sitemap + machine files) |
favicon.svg, apple-touch-icon.png, og.png |
Icons + 1200×630 social card |
amplify.yml |
Amplify build (runs the generator) and artifact list |
customHttp.yml |
Amplify response headers (CSP, HSTS, COOP, CORS for the registry, UTF-8 charset for .txt/.xml, etc.) |
.github/ |
CI and templates — workflows/registry.yml (schema + projection checks), workflows/assurance.yml (assurance validator), scripts/validate-registry.py, issue forms and the PR template |
AGENTS.md |
Read first. Agent/contributor instructions, build commands, and conventions |
AGENTIC_ASSURANCE.md |
How this repo adopts the OpenDevs Agentic Assurance Profile; §7 defines the material-change workflow |
.agentic-assurance/adoption.yaml |
The pinned upstream profile, adopted profile set, and named human owner |
assurance/ |
As-built system spec, invariants, claims, defeaters, residuals, threat model, and bound evidence |
SECURITY.md |
Vulnerability reporting — never a public Issue |
LICENSE |
MIT |
The page renders five sections (section field), in order:
- 공식 / Official — canonical Mossland domains (Website, Disclosure) plus official off-domain channels (Medium, X).
- 참여 / Participation — things you actively use: Passport (featured), Agora, Mossverse.
- 생태계 / Ecosystem — the broader service family: intelligence (Alpha, Signal Map, Media), showcase (City, NPC, Recipe), and the experimental governance stack (MOSS.AO, Algora, BRIDGE, Governance Monitor).
- 개발자 / Developers — the GitHub orgs. Machine artifacts (registry JSON, llms.txt, sitemap) are demoted to a small footer link row, not cards.
- 시세·거래소 / Markets — third-party price trackers and exchanges.
Color carries the meaning; each service's specifics live in its one-line role, not the chip. There are seven chips:
| Chip | Color | Meaning | Driven by |
|---|---|---|---|
공식 |
green on sand — the only filled chip | Verified Mossland domain or official channel | default |
베타 |
green outline | Official service in open beta | tier: official_beta or status: beta |
인텔리전스 |
teal outline | Mossland AI intelligence & data | tier: intelligence |
쇼케이스 |
purple outline | Experiential demo & world showcase | tier: showcase |
실험 |
amber outline | Experimental / not-yet-finished (not an official product) | tier: labs, or explicit chip: "실험" |
제3자 |
grey outline | Third-party, not verified by Mossland | owner: "third-party" / tier: third_party |
자료 |
muted | Developer data file | artifact: true |
This table is a convenience summary, not the source of truth. The rubric is declared as data in
ecosystem-registry.jsonunderrubric, versioned byrubricVersion, andbuild/generate.mjsrenders both the chips and the on-page legend from it. Nothing checks this table against the rubric, so if they ever disagree, the registry wins — seeassurance/RUBRIC.mdfor the changelog, the full precedence table, and the version-bump rules.Changing what a chip or
stampClassmeans requires bumpingrubricVersionperRUBRIC.md§3, and counts as a material change underAGENTIC_ASSURANCE.md§7. No check can catch a missed bump: Passport relies on it to know whenstampClassmeanings moved.This table has drifted before — until 2026-07-18 it claimed "five chips" and omitted
인텔리전스and쇼케이스, which the page had been rendering all along. That drift is what motivated moving the rubric into data.
Key rule: the amber 실험 stage is decoupled from operational status.
offline/paused are uptime, not a stage — a service is 실험 because it is
experimental, set via tier: labs (auto) or an explicit chip: "실험" on a
non-labs service (e.g. media, which is live but still data-seeding).
tier(official,official_beta,registry,companion,intelligence,showcase,world,runtime,labs,developer,channel,third_party) is the service's nature; it drives the chip and Passport logic. Chip derivation is data-driven (never keyed on service id). Notecompanionis in the schema enum but has no entry in the registry'stiersglossary and no service uses it — dead, pending a decision to define or drop it.- Sections are presentation, separate from
tier. Each service renders in onesection; the optionalextraSectionsarray can render it in more (the mechanism exists but is currently unused — Passport/Agora live in 참여 only). third_partyandchannelentries arepassportEligible: falseby contract. Both are pinned by the schema'sallOf, and CI rejects a violation (INV-PASSPORT-001): exchange and price links and off-domain channels (Medium, X) never back a Passport stamp.- Empty-but-live services (e.g. Media: live but 0 data) get an explicit
chip: "실험"while empty; drop the chip once real data appears and it falls through to its tier chip — formedia(tier: intelligence) that is인텔리전스, not베타, because인텔리전스outranks베타in the precedence order (seeassurance/RUBRIC.md§4.1). - Always ground descriptions in the live site. Several labels were corrected
by actually rendering each service (many are client-side SPAs whose homepage is
an empty shell — check
/aboutor render with JS), not by guessing.
Contributors and agents: read
AGENTS.mdfirst. This repo adopts the OpenDevs Agentic Assurance Profile (AGENTIC_ASSURANCE.md). Adding a service is routine. Changing what the registry means — a tier or chip's semantics,passportEligible,stampClass, the rubric, or thecustomHttp.ymlheaders — is a material change under §7, which means reading and updating the affected artifacts inassurance/as part of the same change.
- Edit
ecosystem-registry.json(add/modify a service object). Base thelabelKo/labelon what the live site actually says it is. Bumpversionfor any change to the service set, and refreshgeneratedAtwhen you have re-verified the links — it renders as the page's 최종 확인 date and the sitemap'slastmod. - If the entry needs a
stampClassor chip the registry'srubricdoes not already declare, add it there too and bumprubricVersionperassurance/RUBRIC.md§3 — CI fails on an undeclaredstampClassor an orphan chip. - Run
node build/generate.mjs. - Validate locally:
git diff --exit-code(after regenerating) andpython .github/scripts/validate-registry.py. - Commit the registry change and the regenerated
index.html,embed.html,llms.txt, andsitemap.xml. CI re-runs the generator and fails the build if they differ. - Open a pull request using the PR template. Registry edits are curation
judgements about which domains are genuinely Mossland's, so they are
reviewed — not pushed straight to
main. That review is the human control behindINV-PHISH-001, the anti-phishing invariant.
Never open a public Issue for a suspected vulnerability — including a listed domain that is not genuinely Mossland's, or a missing official domain. Both are security issues for an anti-phishing registry.
Use GitHub's Report a vulnerability button under the repository's Security
tab. See SECURITY.md for scope and what a useful report
contains.
MIT — see LICENSE.