Living document

The Kopling Charter

Kopling's source of truth — our mission, our beliefs, how we're governed, and the technical choices behind the product, all changed openly as we go. Written for two readers at once: the people building and using Kopling, and any AI assistant helping with it.

Revised 2026-07 · amended openly, not silently
Steward: Daniël Klabbers (luceos) Status: Working draft This page is the sole canonical charter AI working instructions: CLAUDE.md
Part AGovernance — who Kopling is, and how it's run
Section 1

Mission

Kopling exists so human interaction can grow into honest, real relationships — through work, hobbies, friendship, or a stranger's well-intended answer at the right moment.

Why immediacy, structure, and federation matter

Connection is the goal. The rest of this page — including the whole technical stack — exists to serve that goal, not the other way around:

  • Immediacy helps: sharing a moment while it's still happening feels honest, not polished for show.
  • Structure helps: conversations stay easy to follow instead of getting lost.
  • Federation helps: connection doesn't stop at the edge of one community.

Section 2

Doctrine

Our settled beliefs about the product. Every feature is checked against these six.

1

People, not users.

In this charter, in our docs, in our product, and in the UI, we say "people" — because the person behind an account has real emotions, struggles, and hopes. This applies to all writing about Kopling.

2

Engagement is a result, never a target.

Engagement is what happens when people enjoy talking to each other — it's a result, not something we chase with tricks. We won't order feeds to keep people scrolling, send notifications just to pull people back, or reward outrage. We track whether questions get answered and new people feel welcome — not how much time people spend on the site.

3

Small responses should be easy; the connection behind them should be real.

A quick "this is cool" is a real response, and it should be effortless to send. It exists to make the person who posted feel seen — not to become a public score to chase. Getting this right is a priority from day one, not something we bolt on later.

4

Connection includes help given well.

A single honest, fair, well-meant answer from a stranger counts as real connection. Support communities belong in our mission just as much as friend groups do — which is why our mission doesn't use words that imply closeness or a long history together.

5

Moderation deals with harm, not with being human.

Someone venting on a bad day is coping, not breaking a rule — what we act on is harm to other people, not the bad day itself. We assume good intent by default, and we design for the rare exception without treating everyone like a suspect. People who are removed for harm can still come back with dignity. Spam and bots aren't a rare problem — they happen constantly, especially once other communities can connect to ours — so stopping them is part of the core software from day one, not something added later.

6

AI serves people; it never replaces them.

A community works because people show up for each other. AI is never a member of that community — it never pretends to be a person, and it's never used to fake warmth or activity. It's welcome behind the scenes, wherever it genuinely helps: summarizing long threads, translating, helping moderators sort through reports, helping admins write things. Every use is judged by one question: does this actually help the people involved, or does it get in their way? Whenever AI is involved, that's stated plainly. Admins decide how much AI their own community uses. Extensions that make AI pretend to be a person are not allowed in the registry.


Section 3

Governance model

Kopling runs on a BDFL model — "benevolent dictator for life," the same pattern behind Laravel, Linux, and Ghost: one named person holds final say, backed by real public promises. It's a deliberate choice for where the project is today, not a placeholder for something better later — a single decision-maker can commit to a direction and change course without waiting on a vote, which is exactly what a project this early needs.

Two things matter most from here: how a decision actually gets made today, and what happens so the project never depends on one person forever.

How a decision gets made.

Decisions get proposed in public, people get a real window to object, and the final choice — plus the reasons for it — gets written down.

Built to outlive its founder.

Before we reach version 1.0, we'll publish a plan for what happens to the code, the trademark, the extension registry, and the infrastructure if the founder can no longer lead.

The license is the real protection.

The code is free, and stays free. The right to copy it and continue it elsewhere — a "fork" — is the community's real safeguard, and it keeps any leader honest, including this one. We won't quietly make the code closed later, and we won't switch to a license that only looks open.

Money never buys influence.

Sponsors and donors get thanks, visibility, and a voice we genuinely listen to — never control over technical decisions, moderation, or the roadmap. Money and decision-making stay separate, and we publish our finances.

Public by default.

Decisions, the reasons behind them, and the project's money are public. We keep something private only for a short, clearly named reason — someone's personal privacy, an active legal matter, or a security issue before it's fixed — never as a habit.

A steering committee with real power.

We aim to give our Technical Steering Committee real authority once it exists, not just an advisory voice — the final say over the extension API, how breaking changes are handled, and how old features get retired. It starts small and takes on more as the group of contributors grows; it may begin as advisory and later become binding.

Tight control loosens on a real trigger, not a feeling.

Right now decisions move fast and often, while the software is still finding its shape. That's temporary by design: we aim to hand day-to-day control off to a public, two-monthly release cycle with a clear roadmap (Section 7) once the software is stable enough that changes slow down and a Technical Steering Committee has formed. Exact trigger conditions are still open (see Open Questions).



Section 5

Teams & working groups

This section describes the kinds of role in the project — not a list of exactly who holds what today. Who actually holds each role changes constantly, so that list lives in a separate, freely-updatable document, not in a charter that would need editing every time someone joins or steps back.

Kinds of role

This is the authority ladder — how much say a role carries. It's a separate question from what field of work a role is in, which is what Divisions, below, describe. Some of these roles are global — they don't belong to any one division. Others only exist inside a division's team, and mean nothing without one: a "team lead" only means something once you know which team.

Global roles

Founder — filled

  • Holds final say per Section 3 on anything not yet handed to the Technical Steering Committee or a division
  • Accountable for the succession plan and the project's overall direction
  • We aim to hand the extension API, breaking-change policy, and retiring old features (Section 3) to a Technical Steering Committee once one forms — and stop deciding those alone

Technical Steering Committee member empty — not yet formed

  • Holds a named area of responsibility (for example: managing releases, keeping the extension API stable, watching over contributor wellbeing) tied to a clear, checkable goal (Section 3)
  • Decides only within that stated area — never for the whole project alone; project-wide calls stay with the full committee or the founder

Contributor at large — open to anyone

  • Takes on whatever they choose to contribute — code, triage, support, docs, translation, moderation, or review — without holding a named role
  • Is the entry point into the recognition ladder described in Section 6; nothing here is off-limits on purpose, making it the easiest kind of role to step into and out of

Division-specific roles

Team lead empty — no teams yet

  • Coordinates one specific team's work and contributors, once that team has more than one contributor — for example, Lead core dev is this role held by the Core dev team's lead
  • Answers for that team only — never quietly ends up responsible for another team's work, or for undefined work outside any team (Section 7)

Team member empty

  • Takes part in one team's ongoing, defined work, under that team's lead
  • Shares that work rather than permanently owning any one piece of it alone — recurring work rotates between people (Section 7)

Divisions

A division is a field of work, not a level of authority — it's the answer to "what is this role even about." Every standing team (below) sits inside exactly one division. Each team lists its responsibilities: concrete, checkable duties, not a claim about territory — overlap between teams is normal and expected, so drawing hard boundaries would just be dishonest about how the work actually happens. What matters is whether a responsibility got done, since that's the only fair thing to check against (Section 7 covers what happens when it doesn't).

Community

Keeps the people who use Kopling safe, heard, and helped.

Moderation team empty

  • Responds to reports within the community's stated window
  • Applies the harm-not-humanity standard (Section 2, item 5) — acts on harm, not on someone having a bad day
  • Keeps a public log of actions taken, per the transparency promise (Section 8)

Support & Q&A team empty

  • Answers "how do I" questions from people running or using Kopling
  • Triages incoming reports into confirmed bugs and hands those to the Core dev team
  • Keeps response times honest and visible, not silently backlogged

Development

Builds and maintains the software itself.

Core dev team empty — led by Lead core dev

  • Reviews and merges code for kopling/core and the skeleton
  • Owns release-readiness against the release cadence (Section 7)
  • Keeps the Kopling\Extend\* contracts stable across releases

Extension review team empty

  • Reviews registry submissions against the compatibility and signing gate (Section 9, Registry)
  • Flags declared-override conflicts before they reach a live install
  • Keeps registry review turnaround public

Design & UX

Shapes how Kopling looks, feels, and behaves — the shared visual and interaction language every surface builds on.

Design system team empty

  • Owns the <x-k::*> Blade component library — props, behavior, and accessibility contracts (Section 9, Styling)
  • Maintains the daisyUI theme, brand tokens, and runtime CSS-variable theming so admins can re-brand without a rebuild
  • Reviews new and outlet-facing UI for design-system consistency before it ships

Content

Makes Kopling understandable, in people's own language.

Documentation team empty

  • Writes and maintains docs for people running, using, and extending Kopling
  • Keeps docs in step with each release, not trailing behind it

Translation team empty

  • Coordinates translators per locale through the core-owned Weblate/Tolgee pipeline (Section 9, Translations)
  • Keeps language packs current with each release

Growth

Tells people Kopling exists, and keeps it funded.

Promotion & marketing team empty

  • Maintains the public site, social presence, and release announcements
  • Keeps messaging aligned with the brand voice (Section 10)

Sponsorship & partnerships team empty

  • Handles sponsor and donor relations
  • Keeps sponsor involvement within the "money never buys influence" line (Section 3) — visibility and thanks, never control

Empty roles are named, not hidden

A role with nobody in it is an empty seat, not a problem to hide. Right now, every role except founder is empty, and we say so plainly here instead of pretending otherwise. Naming an empty role is what eventually lets the right person step into it — nobody can be recruited for a role they don't know exists.

The Teams and Roles document

Once there's more than one contributor, the specific people holding roles below team lead — and which roles are still empty — will be listed in a separate, living document called Teams and Roles, published on kopl.ing or wherever Kopling's community lives. That list can change any day without ever needing to change this charter.

Standing teams versus working groups

A standing team does ongoing work — like moderation or translation — and continues for as long as that work is needed; it lives inside one of the four divisions above. A working group exists for one specific task with a clear end point (for example, writing the first version of the extension API), closes once that task is done, and doesn't need a permanent division of its own — it can form inside one division or draw people from several. None exist yet — we describe the difference now so the shape is settled before the first one forms.

Role concentration

If one person holds several important roles at once, that's tracked as a risk (Section 7), not praised as efficiency. Right now, the founder holds every role, simply because there's no one else yet. That's stated plainly as something to reduce over time, not as how things are meant to stay.


Section 6

Contributors, recognition & membership

This section states, now, before there's any inner circle to keep people out of, how someone earns standing in the project. It's a clear rejection of closed, invite-only communities: projects that only let a small circle in tend to stop growing, and burn out the few people left inside.

Standing is open and earned

Anyone can earn standing in the project through real contribution. No existing group gets to hand-pick who's allowed to matter.

Contribution is defined broadly

Writing code counts. So does answering questions, writing docs, translating, moderating, and reviewing other people's work. Counting code alone misses most of what actually keeps a project alive, and makes the people doing that other work invisible twice over — once in the work itself, and again when nobody credits it.

Clear, honest criteria

Recognition is based on facts a person can point to in their own history — never on secret rules, and never on an algorithm quietly judging the "quality" of someone's contribution. There's also a simple, human way to appeal if the rules get an edge case wrong — which matters most for someone who doesn't write English as a first language, or who contributes quietly rather than loudly.

Recognition now, voting later — one ladder, not two

Right now, recognition means contributors are named, credited, and thanked publicly — it doesn't yet come with a vote, because there's no elected group to vote for. Once the Technical Steering Committee (Section 3) exists, voting rights will be built on this exact same ladder, decided here rather than invented separately later. Deciding this now means the ladder gets designed once, instead of rebuilt under pressure once elections become real.


Section 7

Sustainable contribution & load distribution

Kopling's health depends on the wellbeing of the people keeping it running — today, mainly its founder; over time, its contributors. These rules protect the project's structure, not any one person's willpower: making rest possible is the project's job, and we say so now, before growth makes it urgent.

A role never means constant availability

Holding a role never means being available all the time. It's normal for anyone's involvement to go up and down — that includes the founder today, and it will include every future contributor.

Activity states

As Kopling grows a contributor base, everyone's standing is described honestly using one of three states: active (the normal state), reduced-activity — a pause anyone can take at any time, no explanation required, that pauses their duties but keeps their role and standing exactly as they were — and emeritus, which permanently honors someone's past work with no ongoing duties attached, and can always be reversed if they come back. Public lists always show who's genuinely active, instead of quietly keeping inactive people listed as if they still were.

Release cadence

Kopling aims to release on a steady, public schedule — maybe every two months, though the exact number isn't fixed yet (see Open Questions). A steady schedule does two useful things. First, it gives an honest, no-blame way to notice when someone has quietly become less active, and move them to reduced-activity or emeritus — as a simple, scheduled check, not as anyone passing judgment. Second, it keeps releases honest: each one ships whatever is actually ready, and anything unfinished waits for the next cycle instead of being rushed. Delays happen no matter how good the plan is, and good code takes the time it takes — the schedule exists to make that normal, not something to feel guilty about.

Role removal isn't the same as stepping back

Reduced-activity and emeritus, above, describe a person's overall standing — always available, no explanation required, never a judgment. A role is a narrower thing: one specific seat, held because a division's team (Section 5) needs it filled, with responsibilities that are concrete and checkable on purpose — not to draw territory, but because a responsibility either got done or it didn't, and that's the only fair thing to check. At the same release-cadence checkpoint used to review activity states, an unmet responsibility gets the same no-blame first move: reduced-activity for that role, no explanation required. If the seat is still unfilled through a full cycle with nobody responding, it's simply named vacant again — the "empty roles are named, not hidden" rule (Section 5) applies here too. Losing a role this way never touches someone's standing on the recognition ladder (Section 6) — that's for what they already contributed, not what they're doing right now. This is deliberately separate from removal for harm (Section 2, item 5), which is about conduct, not output, and follows moderation's own process, not this one.

Bus-factor register

A "bus factor" is a simple way of asking: if one person disappeared tomorrow, how much would the project lose? Kopling keeps an honest, current list of every place where that number is one — a single person holding critical knowledge alone — each with a plan to fix it, whether that means teaching someone else, writing things down, or, when there's genuinely no other option, accepting the risk on the record. Right now, the list has exactly one entry: the whole project. The plan to fix it is the succession plan (Section 4) and the future Technical Steering Committee (Section 3), whose job partly exists to end this on a real timeline, not by accident. Once Kopling has a public home to publish it (Section 8), this register becomes public too.

Ongoing work versus one-off work

Some work never really finishes — responding to security issues, managing releases, sorting incoming reports, keeping dependencies up to date. This kind of work is where burnout usually starts, because there's no natural point where it's "done." Other work — building a new feature — is optional and has a clear finish line. Once more than one person shares the ongoing work, it will rotate through a duty roster: one named person covers it for a fixed period, the schedule is public so any gaps are visible, and nobody outside their turn has any obligation at all. Until then, the founder carries all of it alone — stated here plainly as something that can't stay that way forever, not as how things are meant to work.

Every role has clear edges

Every role in Section 5 comes with a written list of concrete responsibilities — not a vague claim to "everything nobody else is doing," which can never actually be finished, and never lets the person doing it feel done. Work that falls outside every defined role's responsibilities is the Technical Steering Committee's job to assign somewhere, once one exists — it shouldn't just land on whoever feels most responsible for it.

Saying no, and moving slowly, are both fine

Turning down an idea, or simply moving slowly, is normal and legitimate. It reflects badly on nobody — not the person who suggested it, and not the person who said no. Moving slowly and sustainably is better than moving fast and burning out.

Recognizing work nobody sees

Standing under Section 6 counts every kind of work that keeps the project running — not just code. Work that goes unseen and unthanked burns people out faster than work that gets valued.


Section 8

Transparency & decision-making

People trust how Kopling is governed because they can see it happen — not just because we say it's well-meant. Governance that happens out of sight loses that trust no matter how good the decisions actually are. This section explains, concretely, how the "public by default" promise (Section 3) works.

Public is the default

Decisions, the reasons behind them, and the project's money are made and written down in public. We keep something private only for a short, clearly named reason: something about a specific person, an active legal matter, or a security issue before it's fixed. Each of these has a time limit, and once it passes, a public summary follows.

Money moves through a public ledger

Sponsorship and donations aren't just summarized in a periodic report — every individual contribution and every expense is visible from the moment it happens, on the public ledger Kopling uses for money (currently Open Collective). Anyone can see who gave what, and where it went, without waiting for a scheduled report. This is a stronger promise than a report on a schedule (see "How often we report," below), and it's chosen on purpose: real-time visibility is harder to quietly walk back later than a periodic summary would be.

Where governance happens

Day-to-day conversation can happen anywhere. What has to end up public is the record of each decision — what was proposed, why, and what was decided — and that record lives on a real Kopling community, the same way any community's own governance would live on the platform it governs. It's a small but real promise: we use Kopling to govern Kopling, which shows we trust the tool, rather than just saying we do.

Conflict-of-interest register

The moment any group beyond the founder has real authority — a Technical Steering Committee, a team lead, anyone who could personally benefit from a decision — their conflicts of interest go into a register anyone can see. A conflict shared only inside a private meeting is a courtesy, not real accountability; this public register is what makes Sections 6 and 7 mean something once more than one person is involved.

How often we report

Financial reports and major decisions are published on a regular, named schedule. The exact schedule for each type of report isn't fixed yet (see Open Questions) — but committing to a regular schedule, instead of an occasional one, is already decided.


Part BBuilding Kopling — what it's made of, and how it's positioned
Section 9

Technical decisions

Settled architecture. Recurring pattern applied throughout: mainstream tool inside, sovereign Kopling contract outside — so a dependency's major version becomes a Kopling minor, never an ecosystem-wide break.

Backend

Full laravel/framework — never cherry-picked illuminate components. Kopling ships its own skeleton. Two-tier extension API: Kopling\Extend\* contracts + blessed Laravel primitives (Eloquent, collections, validation, events); framework internals stay core-only. Laravel majors adopted on Kopling's schedule.

Content model

The thing people share and gather around is called a Moment — not a "Discussion" or "Topic," and there's no separate "Original Post"/"First Post" concept sitting inside it: a Moment already is the whole thing, the sharing and everything discussed, reacted to, praised, or loathed around it. An individual contribution inside a Moment stays a plain reply — no renaming needed there.

Frontend

htmx 4 + Blade + Alpine. Server is the single source of truth; no build step for extensions. Raw hx-* is not the official API — Kopling Blade components (<x-k::action>) emit it. Core-owned JS islands are custom elements so they survive swaps and morphs.

Portals & permissions

UI is organized into named Portals — Community and Admin today, more addable later (a Moderation portal for large communities, serving the Moderation team of Section 5, is the target proof case) — never "Frontends," which reads as JS-framework terminology in a stack like this one. Permission is never hardcoded to a Portal or to an "admin" flag: every action checks its own named, granular permission, and "Admin"/"Moderator" are conventional bundles of those permissions an admin assigns — not a special case the code treats differently. A Portal is a registrable pattern, not fixed to exactly two. The Admin Portal proves it: it ships as its own extension, bundled by default so every install has one, but an operator can remove it entirely from their composer.json — a CI/CD-deployed install, or a large community running its own moderation-only panel instead. Nothing about "the admin panel" is hardcoded into Core.

Extension surface

"An extension is PHP and templates. Full stop." Named, prioritized outlets across small granular partials; extensions ship routes returning HTML fragments; out-of-band swaps update core regions through the response, never by patching. Outlets compose; overrides don't — overrides require manifest-declared conflict detection.

Editor

Tiptap; ProseMirror JSON is canonical; server-rendered via tiptap-php through a whitelist — the same whitelist doubles as the XSS and federation-sanitization model. Extension nodes ship as a PHP renderer + optional plain ESM file, no bundler required. v1 ships core nodes only; the extension node API waits until proven by 2–3 first-party extensions.

Styling

Tailwind v4 + daisyUI beneath a Kopling-owned Blade component library — the only official styling API (~25–30 components with behavior and accessibility built in). Runtime CSS-variable theming lets admins re-brand without a rebuild.

Identity & data

UUIDv7 everywhere; federated IDs are URIs with the UUID as local component. Every federatable row carries UUID + origin from migration #1 — remote content is first-class, never a shadow table. Non-negotiable: near-impossible to retrofit later.

Federation

ActivityPub with forum-shaped conversation semantics, following the Discourse × NodeBB path. Delivery is a queue problem; remote media caching consumes the storage system below. Federation may ship post-1.0; schema readiness ships day one.

Hosting posture

Graceful degradation: runs anywhere (sync queue, polling/SSE fallback, cron), shines on real infrastructure (Reverb, real queues). Capability detection is first-class — an admin health dashboard names what's degraded and why. Degradation is visible, never silent.

Realtime & mobile

SSE + WebSockets via htmx 4's first-party extensions; pushed fragments render through Blade, so they carry every extension's outlets automatically. PWA-first with Web Push at launch; a Hotwire-Native-style webview shell is the hedge if iOS friction proves costly.

Databases

MySQL, MariaDB, Postgres, SQLite. SQL Server explicitly unsupported — every extra engine taxes every extension author forever. SQLite is strategic: trivial local dev and a genuine small-community tier.

Search

v1 ships database LIKE behind a driver interface. The indexing pipeline — extensions registering searchable content types — is part of the contract from day one, since that's the part that's hard to retrofit.

Storage

Capability-based named filesystems: extensions declare required capabilities (public URL, signed URL, streaming, cloud); admins define named instances and map requests to them. A thin layer over Flysystem.

Registry

kopl.ing, Packagist-protocol-compatible — Composer resolution for free, registry sovereignty retained. Machine-checked compatibility metadata (core constraints, DB engines, declared overrides) and package signing from day one.

Translations

Core-team-owned official infrastructure, never one volunteer's side project. Self-hosted Weblate or Tolgee, SSO'd to kopling.org; an automated pipeline carries strings from the registry to translators and back as installable language packs.

APIs

Webhooks before a JSON API — cheaper, unblocks automation and bridges sooner. The API itself is deliberately deferred, kept cheap later by keeping controllers thin over action classes.

AI

Agentic development can only be acceptable when properly reviewed, use AI as a planning assistant, and toolbox, not a replacement for a developer.


Section 10

Brand & positioning

Kopling's look: Delft blue on a light background, with orange used only for the "follow" and "sponsor" buttons, and a wordmark shaped like a clutch. Its voice: confident but calm, inviting disagreement instead of shutting it down — decisions are published before the code is written, so people can challenge them early.

Plain language for a worldwide audience: Kopling's audience is worldwide, and most people reading this charter, using the docs, or using the product do not speak English as a first language. We use plain, direct words instead of jargon or formal governance language wherever a simple word will do — including in this charter itself. When a technical or legal term genuinely can't be avoided, we explain it in plain words the first time it appears. This isn't about making things simpler for its own sake — it's about not shutting people out. A charter only insiders can understand would quietly recreate the exact elitism Section 6 exists to reject.

We expect to be copied, and that's fine: our license lets anyone copy this whole plan and build it themselves — that's the point of an open license. But the plan was never the hard part to copy. What can't be copied is a multi-decade career spanning enterprise engineering leadership and open source stewardship, the registry and translation infrastructure, and trust earned over time — none of which comes bundled with the code.

Public identity: Daniël Klabbers · github.com/luceos · linkedin.com/in/luceos


Section 11

Open questions

The backlog. Nothing here is decided — reference it, don't assume it.

Governance & legal

Succession plan draft — shortest artifact on this list, hard pre-1.0 deadline, and it forces clarity on what transfers if the founder is unavailable. Recommended next.
Technical Steering Committee bootstrap: initial members, the advisory-to-binding trigger, charter text.
Trademark registration and policy; CLA/DCO mechanics underpinning the no-relicensing promise.
Exact cadence for financial statements and major-decision publication (Section 8).
The precise countable criteria for the contribution ladder (Section 6): thresholds, grant/lapse rules, and resistance to gaming.
Role-concentration cap: how many critical roles one person may hold at once, once Section 5's roles start being populated.
Format and hosting location of the living Teams and Roles document (Section 5).
Appeal process for role removal (Section 7) — the general appeal principle exists (Section 6) but isn't yet mapped to this specific mechanic.
Whether the AI doctrine (Section 2, item 6) joins the public governance commitments as a named seventh, or stays doctrine-only.

Technical

Versioning and stability policy specifics — covered namespaces, deprecation windows, major-version support duration.
The v1 Kopling\Extend\* contract list.
The <x-k::*> component inventory (props, ~25–30 components).
Outlet naming conventions and the outlet map for core views.
Editor facade contract; mentions end-to-end (editor, rendering, notifications, federation).
Registry namespace policy and signing implementation; Weblate vs. Tolgee selection.
Media pipeline specifics; notification system design.
Reaction and acknowledgment mechanics — the principle is settled (Section 2, item 3), the exact mechanism (visible counts vs. author-only warmth) is not.
How admins modify layout and theme interactively from the admin area — the harder, still-open follow-on to the runtime CSS-variable re-theming already settled (Section 9, Styling). Includes per-element customization, not just color: e.g. a support or staffing community (Section 2, item 4) changing what the default "Share A Moment" call-to-action says, looks like, or does — up to replacing it with a custom flow like a "Submit an issue" form instead of the default composer.
The permission taxonomy itself (which named permissions exist, how extensions register new ones) and how Portal registration actually works — the principle (Section 9, Portals & permissions) is settled, the mechanism isn't. Building a real Moderation portal is the target proof case, the same way kopling/reactions proves the extension system before its API freezes.
Anti-abuse v1 scope.

Product & launch

Exact release cadence interval — candidate is every two months, not yet fixed (Section 7).
Wire the landing page: mailing-list endpoint, additional sponsor channels, footer links, domain, founder photo.
Public repository and decision-log location, linked directly from the landing page once it exists.
v1 feature scope cut.
First 2–3 first-party extensions, built before the extension API freezes.

Section 12

Decision log

Abridged. Each row: what was decided, what it beat, and why.

#DecisionOverKey rationale
D1Full Laravel frameworkCherry-picked illuminate; SymfonyAvoids bespoke-kernel maintenance tax; common stack; ecosystem access
D2htmx 4 + Blade + AlpineLivewire; Vue islands; pure BladeServer-rendered is most extensible; avoids build-step disease
D3Component wrapper over raw hx-*Raw htmx as the APIAn htmx major becomes a Kopling minor
D4Tiptap, JSON-canonical, PHP-renderedMarkdown/BBCode; client-rendered HTMLOne whitelist covers XSS and federation; no-build ESM nodes
D5Tailwind v4 + daisyUI under <x-k::*>Raw Tailwind; Basecoat; BootstrapAvoids the JIT trap; runtime theming; behavior lives in components
D6UUIDv7 + origin-aware schemaAuto-increment ints; UUIDv4Index locality; federation-ready URIs; can't retrofit later
D7ActivityPub, forum-shapedAT Protocol; microblog semanticsDiscourse × NodeBB path; direct prior participation
D8Graceful-degradation hostingVPS-only; hosted-onlyServes both small-community and enterprise ends honestly
D9kopl.ing registry, Packagist-compatible, signedRaw Packagist; bespoke protocolFree Composer resolution with retained sovereignty
D104 databases, no SQL ServerEvery engine Laravel supportsEach extra engine taxes every extension author forever
D11Core-owned translations, self-hosted platformBuild a bespoke platform; leave it volunteer-runBus-factor-1 was the actual failure, not the tooling
D12Founder-led + guarantees + TSCCommunity ownership; foundation-firstA single decision-maker moves faster and stays more accountable at this stage than diffuse ownership; TSC is the deliberate path to broadening it over time
D13PWA-first, webview shell as hedgeNative apps; API-first mobileHTML-over-the-wire makes the shell path free later
D14Webhooks before a JSON APIAPI-firstCheaper now; thin action classes keep it cheap later too
D15Connection is the mission; immediacy is a meansImmediacy-first framingImmediacy only matters because it serves authenticity
D16Engagement is a consequence, never a KPIEngagement optimizationOptimizing it manufactures counterfeit enjoyment
D17Moderation addresses harm, not humanity; anti-abuse is core v1Venting-as-violation; spam-as-exceptionBad days are coping, not offending; spam/bots are weather
D18AI serves people, never replaces them — visible, admin-controlledBlanket AI ban; AI as participantThe human following is the actual success condition
D19"People, not users" vocabularyIndustry-default "users"The person behind the account has emotions, struggles, hopes
D20Open and earned standing, never gated by an in-groupClosed-core / invite-only contributor modelClosed pools fail to grow and concentrate burnout on who's left
D21Contribution defined broadly (code, triage, docs, translation, moderation, review)Code-only recognitionFixes the invisible-labor gap; recognition should match what actually sustains the project
D22Roles are kinds, not a fixed org chart; vacancy named openly; specifics live in a separate Teams and Roles documentEnumerating every named role in the charter itselfCharter stays stable; the team page stays current; an unfilled role is a recruitment target, not an embarrassment
D23Voting standing deferred until a TSC exists, but built on the same contribution ladder as recognitionInventing a separate electorate definition laterDesigning one ladder now avoids redesigning it under pressure once elections become real
D24Steady, named release cadence adopted as a principle (candidate: every two months)Release-whenever-ready with no rhythmGives an honest, low-drama signal for activity states; forces ship-what's-finished scope discipline
D25Plain language for a global, largely non-native-English audience, applied to the charter itselfGovernance-register or jargon-heavy draftingInclusion, not simplification for its own sake — avoids recreating elitism through inaccessible language
D26"Moment" as the core content-model noun; "reply" stays a plain, unrenamed word"Discussion"/"Topic" + a separate "Original Post"/"First Post"Continues language the charter already uses for the Immediate principle instead of inventing separate jargon; removing the OP/first-post split entirely — a Moment already is the whole thing — costs nothing since it was never load-bearing
D27Section 5 splits "kinds of role" (authority: founder, TSC, team lead, team member, contributor at large) from "divisions" (field of work: Community, Development, Content, Growth), each with named standing teamsOne flat role list mixing authority and field of work; a large WordPress-style team roster (~20+ Make teams)Authority and field of work are different questions — "team lead" is meaningless without knowing which team; four divisions matches the scale of Rust's ~8 top-level teams, appropriate for a pre-1.0 project with one contributor today
D28Teams are defined by checkable responsibilities, not covers/doesn't-cover boundaries; a role-removal mechanic (the seat goes vacant, not the person) sits in Section 7 alongside reduced-activity/emeritusCovers/doesn't-cover boundary language; no mechanism for an unmet responsibility beyond the general activity-state checkBoundaries imply no overlap, which isn't true in practice — a checkable duty is what's fair to measure; underperformance and burnout need different no-blame responses, and losing a seat shouldn't cost someone standing already earned (Section 6)
D29UI organized into named "Portals" (not "Frontends"), gated by granular per-action permissions instead of a hardcoded admin flag; a Portal is a registrable pattern, not fixed to exactly two"Frontend" terminology; a binary admin-access flag; hardcoding Community/Admin as the only two surfaces foreverA binary admin flag allows no partial admin access; granular per-action permissions matter most for support/staffing communities (Section 2, item 4); proving Portals are generatable via a real Moderation portal mirrors how a first-party extension proves the extension API before it freezes
D30Added a fifth division, "Design & UX", with one team (Design system team)Folding design-system/theming work into Development or GrowthDesign-system and theming work (<x-k::*>, daisyUI, brand tokens) is real, ongoing, and distinct from either building the backend or marketing the product — naming it gives it a real home instead of hiding it inside an unrelated division
D31Extended D28's "checkable responsibilities, not covers/doesn't-cover" language to the Kinds-of-role ladder, and split it into global roles (Founder, TSC member, Contributor at large) versus division-specific roles (Team lead, Team member)Covers/doesn't-cover phrasing surviving only in the authority ladder; one flat list mixing global and division-scoped rolesD28 fixed the language for named teams but missed the ladder itself; grouping by scope makes explicit which roles need a division to mean anything (team lead, team member) and which don't (founder, TSC member, contributor at large)
D32Sponsorship and donations run through Open Collective, chosen specifically because every contribution and expense is public in real time, not only in a periodic reportA private payment processor with only scheduled financial reportsReal-time, per-transaction visibility is a stronger and harder-to-quietly-walk-back promise than a periodic summary; matches "public by default" (Section 3) down at the level of individual money movements, not just aggregate totals
D33Admin Portal ships as its own extension (kopling/admin), bundled by default but removable via composer.json — nothing about it is hardcoded into CoreAdmin panel as a permanent, undetachable part of CoreProves a Portal is genuinely a registrable pattern (D29), not just in theory; lets a CI/CD-deployed install or a very large community drop the admin panel entirely and run their own moderation-only panel with fewer features instead. CannotBeDisabled still stops a signed-in admin from toggling it off inside a live install — a narrower, separate guarantee from an operator's own install-time choice

Amending this charter

This document is meant to be questioned. Read it, challenge it openly, and when something changes, update it on purpose: write down the change, keep the reason, and note what it replaces — never rewrite it quietly.