@flashyos/frontdoor
v0.1.0
Published
frontdoor/1 — a published door: which lanes an organisation opens, what it asks at each, and what it owes in return. Emitted per repository, validated across an estate, verified from the applicant's own domain.
Maintainers
Readme
@flashyos/frontdoor
frontdoor/1 — a published door. An organisation says which lanes it opens,
what it asks at each, and what it owes in return. Served at
/.well-known/frontdoor.json.
What a door is not
A rung buys a reply and a place in a queue. It never buys authority, money, or access. Publishing a file at a domain proves that someone can write to that host. It does not prove an organisation is who it claims to be, and an implementation that treats it as though it did has built an authorisation system out of a doormat.
Where real authority is needed, delegate it and verify the chain — that is what flashyID exists for.
This paragraph is normative. Every door carries it verbatim in notAuthority,
and both the library and the vendored checker reject a door that drops it.
Why it federates
Doors are emitted by each repository and validated together, never rendered
from one central build. An estate of any size runs several stacks — this one
runs Next.js, static generators and hand-written HTML — and a design that
assumes a single build is a design that stops at whichever properties share
one. merge() is what makes the federation checkable.
This mirrors @flashyos/directory, which works the same way and
for the same reason.
The three well-known files
| Path | Answers |
|---|---|
| /.well-known/flashyos.json | Who I am |
| /flashyos.roles.json | How I am governed |
| /.well-known/frontdoor.json | How to reach me |
Use
node scripts/emit-frontdoor.mjs --html # emit the door + the HTML partial
node scripts/emit-frontdoor.mjs --react # emit the door + the React component
node scripts/check-frontdoor.mjs # validate this repository's door
npx flashyos-frontdoor a.json b.json --expect a.com,b.com # validate an estateemit is driven entirely by a per-repo frontdoor.config.json. Nothing
repository-specific belongs in the vendored scripts, and vendor.test.ts fails
if a copy is edited to carry a domain, an org slug or a lane.
Two renderers, not one
A single component cannot serve Next.js, a static generator and hand-written HTML. The emitter produces a framework-free HTML partial and a React component from the same door file, so the two differ in syntax and never in content.
What the estate-wide merge catches
Things no per-repository check can see:
- a live property that publishes no door
- a property opening a lane its class may not — a capital solicitation on a consumer game fails the build
- two properties promising different terms for the same rung, which breaks portable standing: an applicant who climbs at one door arrives at another expecting the same
Licence
Apache-2.0. The estate is the reference implementation, not the only one.
Traversal
traverse() finds organisations worth approaching: filtered by the lane they
open, the capability they declare, and the rung the registry currently lists
them at. A lapsed entry is never a candidate — approaching an organisation on
the strength of a credential it has stopped publishing is exactly the error the
lapse rule exists to prevent.
draft() writes an approach for a person to send. It answers the question the
lane actually asks, and offers the recipient the means to check you back.
Nothing in that module sends anything, and that is deliberate. Consent is
the product: an agent may suggest, and a person approves before anything
reaches a stranger. A test asserts the module exports exactly traverse and
draft and nothing that transmits.
The specification
SPEC.md — frontdoor/1, written for someone who has never seen this estate. Four tests pin it to this implementation, because a specification that describes something the reference implementation does not do is worse than none.
