Release 0.14.0: public /docs user guide (DOCS.md served at /docs)
Ships DOCS.md and the /docs route — a plain-prose translation of SPEC.md for users, distinct from the binding spec. Originating need was the admin-vs-owner role distinction on /admin/users (§6.1); response is a single guide that covers the framework's user-facing surfaces end-to-end (roles, proposing, branches, PRs, graduation, notifications). Mirrors /philosophy: markdown file at repo root + sibling backend loader + MarkdownPreview render. No schema migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,605 @@
|
||||
# Using the RFC app
|
||||
|
||||
This is the user-facing guide to the Wiggleverse RFC framework — how to
|
||||
read what's here, propose a new RFC, contribute to one that already
|
||||
exists, and understand who is allowed to do what.
|
||||
|
||||
This guide describes the framework. Individual deployments brand and
|
||||
configure themselves independently — the name in the header and the
|
||||
corpus the RFCs are about belong to the deployment, not to this
|
||||
document.
|
||||
|
||||
For the *why* of the framework, read the [philosophy](/philosophy).
|
||||
For the binding technical contract, see `SPEC.md` in the repository.
|
||||
|
||||
---
|
||||
|
||||
## Reading without signing in
|
||||
|
||||
You can read the catalog and every public RFC without an account.
|
||||
Anonymous visitors can:
|
||||
|
||||
- Browse the catalog of super-drafts and active RFCs.
|
||||
- Open any RFC and read its canonical body.
|
||||
- Read any public branch — its diff and its chat thread.
|
||||
- Read any pull request — its diff, its conversation, its review
|
||||
comments.
|
||||
- Read the discussion that has accumulated on an RFC's main view.
|
||||
|
||||
Reading is open by design. The framework's claim is that the *argument
|
||||
behind a definition* is the evidence that the definition was earned,
|
||||
and an argument that disappears behind a sign-in wall stops carrying
|
||||
that evidence.
|
||||
|
||||
What you cannot do without an account: chat, propose a new RFC,
|
||||
create a branch, open a PR, drop a flag, or post on a discussion
|
||||
thread. Every write affordance is replaced with a sign-in prompt.
|
||||
|
||||
---
|
||||
|
||||
## Signing in
|
||||
|
||||
While the framework is in private beta, only invited email addresses
|
||||
can complete sign-in. If your email is on the allowlist, the
|
||||
"Sign in" button in the header completes the flow and lands you on
|
||||
the catalog with full read and write access. If your email is not on
|
||||
the allowlist, you'll be sent to a short "pending" page explaining
|
||||
the gate.
|
||||
|
||||
Once you have an account, you're a **contributor** by default — the
|
||||
role that grants every write affordance the app exposes, scoped by
|
||||
the per-RFC and per-branch rules described below.
|
||||
|
||||
---
|
||||
|
||||
## Proposing a new RFC
|
||||
|
||||
A new RFC begins as a proposal. The "+ Propose new RFC" button at
|
||||
the bottom of the catalog opens a small modal that collects four
|
||||
things:
|
||||
|
||||
- **Title.** The word, concept, or topic this RFC would define.
|
||||
- **Slug.** A kebab-cased identifier derived from the title. It is
|
||||
the entry's stable handle from this moment until it graduates;
|
||||
collisions with existing entries or open proposals are caught
|
||||
inline.
|
||||
- **Pitch.** One or two paragraphs answering *why this RFC is
|
||||
needed*. This becomes the body of the entry.
|
||||
- **Tags.** Optional. The AI suggests tags from the pitch; you can
|
||||
accept, dismiss, or type your own.
|
||||
|
||||
Submitting the modal does one concrete thing: it opens a pull
|
||||
request against the framework's meta repository, adding one new
|
||||
file under `rfcs/`. There is no other Git artifact and no other
|
||||
side-effect. You are returned to the **pending-idea view** for the
|
||||
new proposal.
|
||||
|
||||
A pending idea is publicly readable but not yet a super-draft. The
|
||||
catalog surfaces it in a "Pending ideas" disclosure at the bottom
|
||||
of the list. A conversation can accumulate on the pending-idea view
|
||||
before it is admitted — contributors can argue, in public, about
|
||||
whether the entry belongs in the catalog at all.
|
||||
|
||||
Three outcomes are possible:
|
||||
|
||||
- **Merge.** An admin or owner merges the proposal PR. The entry
|
||||
becomes a super-draft and graduates from the "Pending ideas"
|
||||
section into the main catalog. Any conversation that accumulated
|
||||
on the pending-idea view migrates with it.
|
||||
- **Decline.** An admin or owner declines, attaching a written
|
||||
comment. You see the comment on your next visit, along with a
|
||||
one-click affordance to revise and re-propose.
|
||||
- **Withdraw.** You can withdraw your own proposal at any time. The
|
||||
entry will not appear in any default view; the conversation that
|
||||
accumulated stays attached to the closed PR as historical record.
|
||||
|
||||
You are automatically the first owner of any RFC you propose. The
|
||||
claim flow described under [Roles & permissions](#roles--permissions)
|
||||
is for *other* contributors to add themselves as owners later, not
|
||||
for the proposer.
|
||||
|
||||
---
|
||||
|
||||
## What a super-draft is
|
||||
|
||||
A super-draft is an entry that has been admitted to the catalog but
|
||||
does not yet have its own dedicated repository. Most of the
|
||||
argument that shapes a definition happens here. The framework
|
||||
assumes — and the philosophy explicitly invites — that many
|
||||
super-drafts will not survive the argument, and that is fine. The
|
||||
entries that do survive earn their place in the catalog by being
|
||||
defensible in public.
|
||||
|
||||
Opening a super-draft from the catalog gives you the same surface
|
||||
an active RFC uses:
|
||||
|
||||
- The canonical body in the centre, read-only by default.
|
||||
- A chat thread on the right where the public conversation lives.
|
||||
- A breadcrumb dropdown listing any in-flight edit branches and
|
||||
any open body-edit PRs against this entry.
|
||||
- A "Start Contributing" affordance that cuts a fresh edit branch
|
||||
and lands you in contribute mode.
|
||||
|
||||
Edits to a super-draft body propagate through pull requests against
|
||||
the meta repository — there is no dedicated RFC repository yet.
|
||||
|
||||
---
|
||||
|
||||
## What an active RFC is
|
||||
|
||||
An active RFC is an entry that has been **graduated**. It has its
|
||||
own dedicated repository, an integer `RFC-NNNN` identifier, and a
|
||||
canonical body file (`RFC.md`) inside that repository. The catalog
|
||||
distinguishes super-drafts and active RFCs at a glance.
|
||||
|
||||
Opening an active RFC gives you:
|
||||
|
||||
- `main` — the canonical body, always read-only. Changes to `main`
|
||||
arrive exclusively through pull requests.
|
||||
- A breadcrumb listing every open branch and pull request on this
|
||||
RFC.
|
||||
- A per-branch chat thread on the right. Each branch has its own
|
||||
conversation, including `main` itself.
|
||||
- A "Start Contributing" affordance: on `main` it cuts a new branch
|
||||
and lands you on it in contribute mode; on any other branch you
|
||||
already have push access to, it flips that branch into
|
||||
contribute mode.
|
||||
|
||||
---
|
||||
|
||||
## Discussion vs contribution
|
||||
|
||||
The framework draws an explicit distinction between two surfaces
|
||||
that other tools tend to conflate:
|
||||
|
||||
- **Discussion** is what the RFC is *for*. The chat thread on an
|
||||
RFC's main view is the place for "what about this part?" or
|
||||
"have we considered…?" questions that don't yet warrant proposing
|
||||
a specific edit. Posting on a discussion thread does not create
|
||||
any Git artifact; the conversation lives in the app database.
|
||||
- **Contribution** is how an RFC *changes*. Editing the canonical
|
||||
body requires opening a branch and, eventually, a pull request.
|
||||
The pull request is the place a specific proposed change is
|
||||
reviewed and merged.
|
||||
|
||||
Reading both surfaces is open to anonymous visitors. Posting on
|
||||
either requires a contributor account.
|
||||
|
||||
---
|
||||
|
||||
## Working on a branch
|
||||
|
||||
Contribute mode flips one branch into edit-enabled. The centre
|
||||
column splits: a markdown source pane on the left, a live-rendered
|
||||
preview on the right. Fenced `mermaid` blocks render as diagrams in
|
||||
the preview.
|
||||
|
||||
Two kinds of edits accumulate on a branch:
|
||||
|
||||
- **AI-proposed changes.** You ask the AI a question or request a
|
||||
revision in the branch's chat. When the AI proposes a concrete
|
||||
edit, that edit appears as a *change card* in a panel below the
|
||||
chat — not yet applied to the document. You can **accept**,
|
||||
**decline**, or **edit before accepting**. Accepting produces
|
||||
one commit on the branch with the original text, the proposed
|
||||
text, and the AI's reason recorded in the commit body.
|
||||
- **Manual edits.** Typing directly into the source pane buffers
|
||||
locally and flushes as a single commit on an idle window, a
|
||||
branch switch, or an explicit "Save now" button. Manual edits
|
||||
also appear as change cards in the same panel — same evidence
|
||||
shape, different author.
|
||||
|
||||
Every accepted change is one commit. The framework does not
|
||||
support squash-merges or fixup-style cleanups: the per-change
|
||||
commit granularity is the framework's evidence unit, and
|
||||
collapsing it would erase what was earned.
|
||||
|
||||
### Discuss mode vs contribute mode
|
||||
|
||||
A branch defaults to discuss mode — read-only, with chat enabled.
|
||||
AI proposals still appear in chat, but they are *buffered* rather
|
||||
than applied; a single CTA invites you to flip the branch into
|
||||
contribute mode if you want to act on them. The toggle is an
|
||||
*intent* affordance, not a permission one. If you don't have push
|
||||
access to the branch, the toggle is disabled with a sign-in or
|
||||
request-access path.
|
||||
|
||||
`main` is special: contribute mode is never available there. The
|
||||
"Start Contributing" button on `main` always cuts a new branch.
|
||||
|
||||
### Flags
|
||||
|
||||
Anywhere you can read, you can drop a flag. A flag is the
|
||||
lightweight "I'm pointing at this, it's a problem" gesture — a
|
||||
single short declarative statement anchored to a passage. Creating
|
||||
a flag requires a contributor account but does not require push
|
||||
access to the branch: any signed-in contributor who can read a
|
||||
passage can point at it and say it's wrong.
|
||||
|
||||
Flags don't block PR merges by design — making them a merge gate
|
||||
would re-create the failure mode where contributors hastily "resolve"
|
||||
threads to unblock a button. Flags are prominent on PR headers but
|
||||
non-blocking.
|
||||
|
||||
### Branch visibility
|
||||
|
||||
A new branch is publicly readable by default. The branch creator
|
||||
can flip a branch to private, in which case only the creator, any
|
||||
explicit grantees, and the RFC's per-RFC owners and arbiters can
|
||||
read it. Owners and arbiters can flip it back.
|
||||
|
||||
**Opening a PR makes the branch fully public.** If your branch is
|
||||
currently private, the "Open PR" affordance asks you to confirm
|
||||
this before submitting. There is no concept of a private PR — the
|
||||
framework's evidence claim depends on the argument being readable.
|
||||
|
||||
### Who can push to a branch
|
||||
|
||||
Every branch has one of three contribute modes:
|
||||
|
||||
- **`just-me`** (default) — only the branch creator can push.
|
||||
- **`specific`** — only the branch creator and explicitly granted
|
||||
contributors can push.
|
||||
- **`any-contributor`** — any signed-in contributor can push.
|
||||
|
||||
The branch creator and the RFC's per-RFC owners and arbiters can
|
||||
change this setting at any time.
|
||||
|
||||
### Branch hygiene
|
||||
|
||||
A branch with no associated PR auto-closes after 30 days of
|
||||
inactivity. A closed branch is deleted from the Git host 60 days
|
||||
later. Closed branches remain in the catalog under a "show closed"
|
||||
filter — closing is a state, not a censorship event. The chat
|
||||
attached to a closed or deleted branch is preserved as historical
|
||||
record.
|
||||
|
||||
Owners and arbiters can *pin* a branch to disable the auto-close
|
||||
timer if the work is paused but legitimately ongoing.
|
||||
|
||||
---
|
||||
|
||||
## Opening and reviewing a pull request
|
||||
|
||||
A pull request is the deliberate "ready for review" gesture for
|
||||
work that has accumulated on a branch. The "Open PR" affordance is
|
||||
available on any branch with at least one commit ahead of `main`.
|
||||
|
||||
The PR creation modal collects two AI-drafted fields, both editable
|
||||
before submit:
|
||||
|
||||
- **Title.** A one-line description of the change, in spec voice.
|
||||
- **Description.** Two to four sentences pulling from the branch
|
||||
chat, written for an arbiter.
|
||||
|
||||
There is no reviewer picker. The RFC's arbiters are the implicit
|
||||
reviewer set.
|
||||
|
||||
### The PR review page
|
||||
|
||||
The review page shows the diff, the branch's compressed chat
|
||||
(messages that produced accepted changes are expanded, the rest is
|
||||
behind a "Show full conversation" toggle), and the review-comment
|
||||
surface inline below the chat.
|
||||
|
||||
Review comments are not a separate concept from chat — they live in
|
||||
the same thread, anchored to a range in the diff. The framework's
|
||||
claim is that the disagreement an arbiter raises about a proposed
|
||||
change is the same *kind* of thing as the disagreement that
|
||||
produced the proposed change in the first place, and the two should
|
||||
share a surface.
|
||||
|
||||
Each PR records a per-user seen-cursor. New diff hunks and new
|
||||
conversation messages since your last visit render with a subtle
|
||||
accent. The cursor advances on view; you do not have to mark
|
||||
anything as read.
|
||||
|
||||
### Merging a PR
|
||||
|
||||
Per-RFC owners and arbiters can merge; app-wide admins and owners
|
||||
also retain this capability. The merge produces a no-fast-forward
|
||||
commit on `main`, preserving every per-acceptance commit as an
|
||||
individually reachable node in `main`'s history.
|
||||
|
||||
Merge is hard-blocked **only** by Git-level conflicts with `main`.
|
||||
Open review threads, pending change-cards, unresolved chat threads,
|
||||
and open flags do not block merge by design.
|
||||
|
||||
### Conflicts with main
|
||||
|
||||
A conflict surfaces on the PR page as a read-only banner. A "Start
|
||||
resolution branch" affordance cuts a fresh branch off `main`'s
|
||||
current tip, replays the work into it (asking the AI to resolve
|
||||
unambiguous conflicts, surfacing the rest for you), and opens a new
|
||||
PR. The original PR auto-closes when the resolution PR merges.
|
||||
|
||||
Fixup commits on the existing branch are not supported. Per-change
|
||||
commit granularity is the framework's evidence unit; admitting
|
||||
"fix merge conflict with main" commits would dilute it.
|
||||
|
||||
---
|
||||
|
||||
## Graduation: super-draft → active RFC
|
||||
|
||||
Graduation is the moment a super-draft becomes a canonical entry
|
||||
in the catalog. It is initiated by an app-wide admin, an app-wide
|
||||
owner, or one of the RFC's per-RFC owners or arbiters from the
|
||||
super-draft's page.
|
||||
|
||||
Two preconditions block the action:
|
||||
|
||||
- **The super-draft must have at least one owner.** The proposer
|
||||
is automatically the first owner; if they have stepped away, any
|
||||
contributor can use the "Claim ownership" affordance to add
|
||||
themselves.
|
||||
- **No open body-edit PRs against the super-draft's entry.** An
|
||||
open body-edit PR would attempt to re-introduce a body to a
|
||||
frontmatter-only entry after graduation runs. Merge or withdraw
|
||||
them first.
|
||||
|
||||
When the dialog confirms, the framework runs a transactional
|
||||
sequence: create a fresh Git repository for the RFC, seed it with
|
||||
the super-draft's body as `RFC.md`, update the meta-repo entry to
|
||||
`state: active` with the integer ID and the new repository's URL,
|
||||
auto-merge that update. If any step fails partway, the sequence
|
||||
rolls back — the half-created repository is deleted and the
|
||||
unmerged update is abandoned. The dialog shows each step in flight
|
||||
and tells you exactly what happened.
|
||||
|
||||
The chat thread on the super-draft moves to the new repository's
|
||||
`main` chat at graduation. Edit-branch chats from the super-draft
|
||||
phase stay attached to their original branches on the meta repo
|
||||
and surface from the new RFC view under a "Pre-graduation history"
|
||||
section.
|
||||
|
||||
Graduation is not reversible. The path forward from an active RFC
|
||||
is withdrawal, not back to super-draft.
|
||||
|
||||
---
|
||||
|
||||
## Withdrawing and reopening
|
||||
|
||||
An active RFC or a super-draft can be withdrawn by the proposer
|
||||
(for a super-draft they proposed) or by an admin or owner. A
|
||||
withdrawn entry stays in the catalog as a historical record but is
|
||||
hidden from default views. The entry is filterable back in.
|
||||
|
||||
An admin or owner can reopen a withdrawn entry back into the
|
||||
super-draft state. The history is preserved across the transition.
|
||||
|
||||
---
|
||||
|
||||
## AI in the chat
|
||||
|
||||
The chat on every RFC, super-draft, branch, and PR has an AI
|
||||
participant by default. The framework treats the AI as one voice
|
||||
among many in a public argument — not an oracle, and not a
|
||||
co-author whose name lands on commits.
|
||||
|
||||
You invoke the AI by writing into the chat composer and submitting.
|
||||
Each message can pick a model from the picker (the option list is
|
||||
configurable per RFC). The AI responds in the chat; when its
|
||||
response includes a concrete change to the document, that change
|
||||
appears as a card you can accept, decline, or edit.
|
||||
|
||||
When you accept an AI's proposed change, the commit's
|
||||
`On-behalf-of:` trailer names *you*, not the AI. The AI's authorship
|
||||
survives only as evidence — the original proposal in the commit body
|
||||
and the message that produced it in the chat record. The framework
|
||||
is explicit about this: AI participation produces evidence; it does
|
||||
not produce authorship.
|
||||
|
||||
Two configuration knobs scope AI participation per RFC:
|
||||
|
||||
- **Which models are available.** The meta-repo entry's frontmatter
|
||||
carries an optional `models:` list. Absent means the RFC inherits
|
||||
whatever models the deployment is provisioned to run. An empty
|
||||
list (`models: []`) opts the RFC out of AI entirely — every AI
|
||||
surface is absent rather than disabled-but-present.
|
||||
- **Whose credentials pay.** By default the deployment operator's
|
||||
API credentials cover AI calls on every RFC. A `funder:`
|
||||
frontmatter field can name a single contributor whose registered
|
||||
credentials pay for AI calls on this RFC instead. The named
|
||||
contributor must explicitly consent from their settings page;
|
||||
either side can revoke at any time.
|
||||
|
||||
Per-RFC AI configuration is edited through the meta-repo PR flow
|
||||
that governs the rest of the entry's frontmatter — by the RFC's
|
||||
per-RFC owners and arbiters, or by app-wide admins or owners.
|
||||
|
||||
---
|
||||
|
||||
## Notifications
|
||||
|
||||
The framework's public-async work model produces signals that
|
||||
shouldn't all reach you the same way. Five surfaces compose:
|
||||
|
||||
- **In-app inbox.** The durable triage surface. One mental space
|
||||
across every RFC you have any relationship to, with per-RFC and
|
||||
per-category filters. Reachable from the inbox icon in the
|
||||
header.
|
||||
- **Badges.** Ambient pull-ins. A single integer beside the inbox
|
||||
icon (count of unread notifications). A small binary dot on
|
||||
individual catalog rows for watched RFCs with unseen activity.
|
||||
No per-row counts and no per-section counts.
|
||||
- **Toasts.** Transient mid-session signals. Used only for your own
|
||||
actions completing, and for events arriving on the view you're
|
||||
currently looking at.
|
||||
- **Email.** The single channel that escapes the app. Opt-in per
|
||||
category, conservative defaults. One-click unsubscribe per
|
||||
category.
|
||||
- **Digest.** Aggregation for activity on watched RFCs you haven't
|
||||
triaged through any other channel.
|
||||
|
||||
### Watch states
|
||||
|
||||
Every RFC has one of three implicit relationship states for you:
|
||||
|
||||
- **Watching.** You receive structural signals for the RFC.
|
||||
- **Following.** You receive only churn-grade signals (new
|
||||
commits, new chat messages on threads you didn't participate
|
||||
in). This is a lighter relationship than watching.
|
||||
- **Muted.** You receive no signals for the RFC. The mute is
|
||||
per-RFC and self-imposed; it does not affect what others see
|
||||
or what reaches you on *other* RFCs.
|
||||
|
||||
Watch states transition automatically based on your participation,
|
||||
with explicit overrides available from each RFC's header and from
|
||||
the notification settings page.
|
||||
|
||||
### Email categories
|
||||
|
||||
Four categories with distinct defaults:
|
||||
|
||||
- **Personal-direct events** — default on. Signals where you are
|
||||
the named subject. The contract is that when your name is on the
|
||||
action, the framework reaches out of band.
|
||||
- **Watched-RFC structural events** — default off. PR opened on a
|
||||
watched RFC, PR merged, graduation, withdrawal. Inbox and badges
|
||||
carry these by default; the email toggle is opt-in.
|
||||
- **Watched-RFC churn** — permanently off, by design. Per-commit
|
||||
and per-message email is intentionally not offered. The digest
|
||||
aggregates this activity weekly.
|
||||
- **Admin-actionable events** — default on for admins and owners,
|
||||
unused for contributors.
|
||||
|
||||
### Quiet hours
|
||||
|
||||
You can set a daily window during which email notifications are
|
||||
held. Messages held during the window are released at window end —
|
||||
bundled into a single "Activity while you were away" email if a
|
||||
threshold accumulated, otherwise sent individually.
|
||||
|
||||
---
|
||||
|
||||
## Roles & permissions
|
||||
|
||||
Authorization in this framework is owned by the app itself, not by
|
||||
the Git host. The Git host sees only a single bot account — every
|
||||
commit, every PR, every merge passes through it on a user's behalf
|
||||
— and the *app* decides which users are authorized to ask the bot
|
||||
to do which things.
|
||||
|
||||
### The four app-wide roles
|
||||
|
||||
Each role is a strict superset of the one below it.
|
||||
|
||||
1. **Anonymous.** Anyone who has not signed in. Can read public
|
||||
RFCs, public branches, and public PRs; cannot chat, propose,
|
||||
create branches, or open PRs.
|
||||
|
||||
2. **Contributor.** The default role for any authenticated
|
||||
account. Adds everything anonymous can do, plus: propose new
|
||||
RFCs, create branches on any RFC repository, open PRs from
|
||||
branches they have push access to, post on chat anywhere they
|
||||
can read, claim ownership of unclaimed super-drafts.
|
||||
|
||||
3. **Admin.** Adds the ability to act on any RFC, anywhere in the
|
||||
framework. Concretely: merge any PR on any RFC, graduate any
|
||||
super-draft, set branch visibility on anyone's behalf, withdraw
|
||||
or reopen any entry, write-mute or restore any contributor,
|
||||
grant or revoke the **admin** role.
|
||||
|
||||
4. **Owner.** Adds two capabilities admin does not have: grant or
|
||||
revoke the **owner** role itself, and disable an account
|
||||
entirely. The framework names a single "owner zero" at
|
||||
bootstrap.
|
||||
|
||||
The practical difference between admin and owner is narrow but
|
||||
load-bearing: admin is the operational tier — it does the day-to-
|
||||
day moderation and stewardship work; owner is the tier that
|
||||
controls the admin tier. Disabling an account and creating other
|
||||
owners are owner-only because they affect the framework's chain of
|
||||
authority itself.
|
||||
|
||||
The app refuses to let the last owner demote themselves silently —
|
||||
losing the last owner would leave nobody able to grant the role
|
||||
back. Role changes are recorded in an append-only `permission_events`
|
||||
log; an admin's own admin/users page shows the log of who promoted,
|
||||
demoted, or muted whom.
|
||||
|
||||
### Per-RFC delegated authority
|
||||
|
||||
The four roles above are framework-wide. Within an individual RFC,
|
||||
the meta-repo entry's frontmatter names two additional groups:
|
||||
|
||||
- **`owners:`** — contributors elevated for this RFC. They can
|
||||
grant push access on any branch in the RFC, merge any PR on the
|
||||
RFC, change branch visibility, and withdraw the RFC.
|
||||
- **`arbiters:`** — contributors with merge authority for this RFC.
|
||||
Functionally similar to per-RFC owners for merge decisions; the
|
||||
distinction matters in some configuration paths.
|
||||
|
||||
Per-RFC owners and arbiters are **not** app-wide admins. Their
|
||||
elevated powers are scoped strictly to the RFC named in the
|
||||
frontmatter. This is what lets the framework distribute work
|
||||
without putting one person on the hook for every action.
|
||||
|
||||
The proposer of an RFC is automatically the first per-RFC owner.
|
||||
Additional per-RFC owners are added through a "Claim ownership"
|
||||
PR against the meta repository; app-wide admins or owners merge
|
||||
it.
|
||||
|
||||
### Per-branch contribute grants
|
||||
|
||||
Within an RFC, the branch creator and the RFC's per-RFC owners
|
||||
and arbiters can grant push access to specific contributors on a
|
||||
specific branch — `specific` contribute mode, described under
|
||||
"Working on a branch."
|
||||
|
||||
### The write-mute
|
||||
|
||||
An app-wide admin or owner can **mute** a contributor. A muted
|
||||
account retains read access and keeps its existing branches, but
|
||||
cannot create new branches, open new PRs, propose new RFCs, or
|
||||
post chat. This is a moderation tool, distinct from removing the
|
||||
account; restoring is the reverse gesture.
|
||||
|
||||
The write-mute applies only to contributors. Promoting a user to
|
||||
admin or owner is the way to remove a user's write-restriction in
|
||||
the structural sense; the write-mute is for *retaining* an account
|
||||
while removing its ability to act.
|
||||
|
||||
Every mute and every restore is recorded in `permission_events`.
|
||||
|
||||
### Three different "mutes"
|
||||
|
||||
The word "mute" appears in three structurally distinct places.
|
||||
They share a word and nothing else.
|
||||
|
||||
- **Write-mute.** Admin-imposed. Removes a contributor's ability
|
||||
to post or push. Described above.
|
||||
- **Per-RFC notification mute.** Self-imposed. Sets your watch
|
||||
state on a specific RFC to *muted* — you stop receiving signals
|
||||
for that RFC, in inbox, badges, and email. Does not affect what
|
||||
others see.
|
||||
- **Per-user notification mute.** Self-imposed. Suppresses
|
||||
notifications produced by a specific other user, anywhere in
|
||||
the framework. Notification-volume only — it does not affect
|
||||
what you can read.
|
||||
|
||||
A write-muted contributor continues to receive notifications
|
||||
normally, so they can triage what they can't act on, and so a
|
||||
restore lands cleanly.
|
||||
|
||||
### Audit trail
|
||||
|
||||
Every gesture that changes app state — role changes, mutes,
|
||||
graduations, withdrawals, grant changes — is recorded in
|
||||
append-only logs the app maintains. Git commit history is for
|
||||
code archaeology; the app's audit log is the accountability
|
||||
record. An admin's page surfaces both `permission_events` (the
|
||||
role/mute log) and `actions` (the state-transition log) for
|
||||
review.
|
||||
|
||||
---
|
||||
|
||||
## Where to learn more
|
||||
|
||||
- The framework's *why* lives in [the philosophy
|
||||
document](/philosophy).
|
||||
- The binding technical contract — section numbers (`§n.n`)
|
||||
referenced throughout this guide — is in `SPEC.md` in the
|
||||
framework's source repository.
|
||||
- Deployment operators have their own recipe in
|
||||
`docs/DEPLOYMENTS.md`.
|
||||
Reference in New Issue
Block a user