Repository navigation
docs: add a front door for outside contributors - #15263
Conversation
cmux had no start-here page, no code of conduct and no security policy, so someone arriving from a link had to infer from CONTRIBUTING.md whether they could contribute at all without a Mac. That is the first question a student or a drive-by contributor asks, and the answer (yes, CI builds for you) was not written down anywhere. - docs/start-here.md: how to pick an issue from the triage labels, what is fixable without a Mac, what CI runs for you, and what happens after you open a pull request. - CONTRIBUTING.md: point at start-here up top, describe what CI runs so nobody thinks they need a build farm, and say how review and merge actually work (squash, main is nightly, fix forward, contributors get credit). - CODE_OF_CONDUCT.md: be nice, assume the best, and an address that reaches a human. - SECURITY.md: report privately by email, with the scope a terminal needs (escape sequences and file names that run code count; a command you typed does not). - Issue and pull request templates: an optional area dropdown so auto-triage starts from the reporter's own answer, contact links that route first-timers and security reports away from the bug form, and a pointer to start-here for a first pull request. Depends on manaflow-ai#15228, which adds docs/triage.md. These docs link it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Warning Review limit reachedNext included review available in 1 minute. View limit detailsLimit details: You’ve used all 10 included reviews currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Repository: manaflow-ai/cmux/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (11)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
All contributors have signed the CLA ✍️ ✅ |
Review found three statements a new contributor could disprove in ten minutes. `CLI/` is 215 Swift files and no Cargo.toml, and CLI changes route to the macOS lanes, so telling a Mac-less reader "the CLI is Rust, Python and TypeScript" pointed them at the one thing they cannot build. The app and the `cmux` CLI are Swift; cmux-tui, the SDKs and the repo tooling are the portable part. "About a third of open issues are needs-triage" was arithmetic about a label that did not exist yet. The label searches are also thin until the backfill runs, so the page now says so instead of promising a full pile. CI corrections: static checks run on every pull request but the Linux guards are conditional; `verify-local.py` runs the checks your diff touches and `--all` is the full recipe; and a `cmuxUITests/` diff fails `suite-coverage` until a maintainer records it with `no-full-ci`, which a fork cannot do for itself. Also: - README links start-here, which is the page's whole reason to exist. - `.github/contributor/welcome.md` sent every first-time contributor to a "Review Trigger" block that the PR template no longer has. - Dropdown wording: relays belong to cloud not remote, cli covers cmux-tui and the SDKs, and fonts are terminal rather than appearance. - `verify-local.py` treats CODE_OF_CONDUCT.md and SECURITY.md as prose, so editing them stops selecting the entire static recipe. - start-here says `web/` is Linux-testable but BUSL and needs a CLA. - SECURITY.md covers the RC channel, and stops promising release notes and an acknowledgment the inbox may not deliver. - House style: no em dashes, no "real" as emphasis, American spelling. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Review subagent ran against 6be4ef4, correctness-first, with instructions to verify every factual claim against the workflows rather than read the prose. 18 findings. Fixed in 50e3101. Review: three blockers, all of them the docs claiming something this repo does not do.
Fixed:
Left:
The review also independently confirmed the claims I most wanted checked: no Mac is needed for the default checks ( |
The issue forms in manaflow-ai#15263 add a dropdown asking which part of cmux an issue is about, with the area labels as the options. Nothing read it. `pick_areas` discards body-only evidence on purpose (one passing mention of `ssh` in a paragraph is not an area) and `auto_triage.py` only ever passed the title and body to `classify`, so the reporter's explicit answer was thrown away. Concretely: reporter picks `sidebar`, title is "Wrong item highlighted after reorder", and the issue came out `needs-triage` with the answer sitting right there in the body. `form_area` parses the rendered form, takes the label before the first parenthesis, treats "Not sure" and `_No response_` as no answer, and outranks every inference below it. Picking off a list of the real labels is better evidence than a regex over prose, and reading it is the only thing that makes the dropdown worth having. This also removes a way the dropdown could make triage worse. The chosen option's parenthetical lands inside the scored body window, so `remote (cmux ssh, tunnels, relays)` used to add points to cli and cloud as well and could swing a 3-3 title tie to an area the reporter did not pick. An explicit answer now short-circuits scoring, so the hint text cannot perturb anything. Nine tests, including one that asserts every one of the 22 areas is reachable through the dropdown, so an option whose wording drifts away from its label fails rather than silently falling back to guessing. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
start-here said `needs-triage` is "the largest pile by a distance". Measured against the backlog after the triage pass, that is not true: `S3: minor` holds 739 open issues and `needs-triage` holds 539. It is the largest pile of issues nobody has routed yet, which is a different and more useful claim, so say that and give the number. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Bugbot is paused — on-demand spend limit reachedBugbot uses usage-based billing for this team and has hit its on-demand spend limit. A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue. |
The issue forms in #15263 add a dropdown asking which part of cmux an issue is about, with the area labels as the options. Nothing read it. `pick_areas` discards body-only evidence on purpose (one passing mention of `ssh` in a paragraph is not an area) and `auto_triage.py` only ever passed the title and body to `classify`, so the reporter's explicit answer was thrown away. Concretely: reporter picks `sidebar`, title is "Wrong item highlighted after reorder", and the issue came out `needs-triage` with the answer sitting right there in the body. `form_area` parses the rendered form, takes the label before the first parenthesis, treats "Not sure" and `_No response_` as no answer, and outranks every inference below it. Picking off a list of the real labels is better evidence than a regex over prose, and reading it is the only thing that makes the dropdown worth having. This also removes a way the dropdown could make triage worse. The chosen option's parenthetical lands inside the scored body window, so `remote (cmux ssh, tunnels, relays)` used to add points to cli and cloud as well and could swing a 3-3 title tie to an area the reporter did not pick. An explicit answer now short-circuits scoring, so the hint text cannot perturb anything. Nine tests, including one that asserts every one of the 22 areas is reachable through the dropdown, so an option whose wording drifts away from its label fails rather than silently falling back to guessing. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* triage: severity and area labels, with rules in the repo
1775 open issues carry no severity or area vocabulary, so "what is badly
broken in the terminal" is not a question the tracker can answer. This adds
the vocabulary, the rules that assign it, and the tooling that keeps both
honest.
- `.github/labels.json` is the label manifest, and `scripts/ci/sync_labels.py`
applies it. The sync never deletes, so the CI plumbing labels that are not
in the manifest survive it.
- `scripts/ci/triage_rules.py` holds one copy of the severity and area rules.
The severity vocabulary already existed inside `triage-radar.py`; the radar
now imports it from here rather than keeping a second copy that can drift
from what the labels say.
- `scripts/ci/auto_triage.py` labels one issue (what the workflow calls) or
walks the backlog (`--backfill`, no comments, with a receipt that
`--revert` can undo). It skips any issue that already has a triage label,
which is how a human overrides it: change the labels and they stay changed.
- `.github/workflows/auto-triage.yml` runs it on `opened` and `reopened` only,
so the bot gets one turn per issue and cannot argue back.
- `docs/triage.md` says what each label means, which rule assigns it, and why
`good first issue` is applied by a person and never by a keyword.
Severity is for things that are broken; a feature request gets an area and no
severity, because calling an unbuilt feature `S3` is a priority claim that a
keyword rule has no business making.
Testing: `python3 tests/test_triage_rules.py` (30 tests: severity ordering,
title-only cosmetic and security rules, area ties, override detection, comment
shape, workflow permissions, and a guard that the rules can only emit labels
the manifest defines) and `python3 tests/test_triage_radar.py` (11 tests,
unchanged, green after the refactor). `actionlint` clean on both new
workflows. `python3 scripts/verify-local.py`: 14/15 selected checks passed.
Rules were tuned against all 1775 open issues offline: 2 S1, 318 S2, 749 S3,
5 S4, 701 with no severity (feature requests and RFCs), and 575 that match no
single area and stay `needs-triage`. No labels were applied by this commit.
## Changelog
none
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* triage: fix the severity gate, and make the receipt honest
Review findings on the first pass of this PR, all confirmed by reproduction.
The bug-or-feature gate only recognised words that mean failure, so most
cosmetic and performance reports got no severity at all: both the S3 and the S4
example in docs/triage.md produced no label, and the bot told those reporters
their issue read as a feature request. Severity now follows from the rules
themselves, with the word list used only when no rule matched. Titles that ask
for work ("Add ...", "perf: ...", "iOS: refactor ...") still get no severity,
which is the part the word list was there to protect.
The other half is the receipt. It was written in batches of 25, so a pass that
died to a 5xx, a rate limit or the job timeout left up to 24 labels applied with
nothing recording them. Rows are now flushed as they happen. A dry run wrote a
receipt byte-identical to a real one, and --revert would act on it and strip
labels a human had since applied by hand; dry-run rows are marked and --revert
refuses them. Rows carry the repo, so a receipt from a fork cannot be reverted
against main by accident.
Also:
- 403 is no longer assumed to be a rate limit. A permission failure fails now
instead of sleeping through the job timeout, and a primary rate limit waits
for x-ratelimit-reset rather than a fixed 180s ladder.
- --revert only tolerates a 404 that says the label is gone. Every other 404
(wrong repo, deleted issue, token that cannot see the repo) stops the pass
rather than reporting a clean run that removed nothing.
- --limit must be 1 or more. It used to treat 0 as "no limit", so "00" typed
into the dispatch form started an unbounded pass over the backlog.
- sync_labels.py matches existing labels case-insensitively. GitHub label names
are case-insensitively unique, so an existing "Area: cloud" made the sync
take the create path and fail on a 422, leaving the rest of the manifest
unsynced.
- classify() no longer scores areas twice or runs the NIGHTLY patterns over an
untruncated body for a value nothing reads.
- docs/triage.md says what the code does, including the word-list caveat, the
reopen gap, and that two areas need both words in the title.
18 new tests, including every documented severity example.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* triage: let a title name its own area
Running the backfill over the 1788 open issues surfaced a systematic miss.
`Cloud: Codex TUI garbled again after restoring a Cloud workspace` landed on
`needs-triage`: the title mentions Codex and a workspace, those tie, and a tie
wider than two areas gives up. The word `Cloud` right at the front, which is
the reporter telling us the answer, counted for nothing.
Ten of the twenty-two area patterns could not be matched by their own name at
all, because they want a qualifier on purpose (`area: cloud` scores on "cloud
machine", never a bare "cloud") and a scope prefix never supplies one.
So a title that opens with an area now declares it. A scope prefix (`Cloud:`,
`perf:`, `CI:`) wins outright; a bare leading subject (`Terminal jitters when
toggling between tabs`) applies only when scoring found no area in the title,
which keeps `Sidebar, splits, ssh and the iOS app all need a rethink` on
`needs-triage` instead of reading an enumeration as a declaration. `nightly`
and `install` are deliberately not area names: they say where a bug happens,
not what owns it.
Also fixes --dry-run in sync_labels.py silently skipping the comparison when
only GITHUB_TOKEN was set, which is how it had been getting run.
Measured over all 1788 open issues: 126 area outputs change, 42 of them
rescued from `needs-triage` (539 left, down from 581) and 84 narrowed from a
two-area guess to the declared one. No issue loses its area. A new test asserts
every area is reachable by its own name, so this cannot regress quietly.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* triage: read the area the reporter picked on the issue form
The issue forms in #15263 add a dropdown asking which part of cmux an issue is
about, with the area labels as the options. Nothing read it. `pick_areas`
discards body-only evidence on purpose (one passing mention of `ssh` in a
paragraph is not an area) and `auto_triage.py` only ever passed the title and
body to `classify`, so the reporter's explicit answer was thrown away.
Concretely: reporter picks `sidebar`, title is "Wrong item highlighted after
reorder", and the issue came out `needs-triage` with the answer sitting right
there in the body.
`form_area` parses the rendered form, takes the label before the first
parenthesis, treats "Not sure" and `_No response_` as no answer, and outranks
every inference below it. Picking off a list of the real labels is better
evidence than a regex over prose, and reading it is the only thing that makes
the dropdown worth having.
This also removes a way the dropdown could make triage worse. The chosen
option's parenthetical lands inside the scored body window, so
`remote (cmux ssh, tunnels, relays)` used to add points to cli and cloud as
well and could swing a 3-3 title tie to an area the reporter did not pick. An
explicit answer now short-circuits scoring, so the hint text cannot perturb
anything.
Nine tests, including one that asserts every one of the 22 areas is reachable
through the dropdown, so an option whose wording drifts away from its label
fails rather than silently falling back to guessing.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* ci: keep the word macOS out of a Linux runs-on comment
Two guards failed on `labels-sync.yml`, both on the same trailing comment:
runs-on: ubuntu-24.04 # github-hosted-required: no macOS dependency
`test_ci_macos_xcode_selection.py` decides a job is macOS with
`"macos" in runs_on_line.lower()`, so the comment made a Linux job look like a
Mac one and the job was reported as building on the image's default Xcode.
`test_ci_self_hosted_guard.sh` scans runner-selection lines for `macOS` and
`ARM64` case-sensitively, because those are GitHub's self-hosted auto labels,
so the same three words read as a fleet label.
Both are matching a comment rather than a label, which is a little coarse, but
the comment was also saying the wrong thing: every other use of
`github-hosted-required` gives the reason the job must be GitHub-hosted, and
"no macOS dependency" is a reason it does not need a Mac, which is not the same
claim. Replaced with the actual reason.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* ci: run labels-sync validation when its own workflow changes
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(ci): correct triage loss and area provenance
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The issue forms in manaflow-ai#15263 add a dropdown asking which part of cmux an issue is about, with the area labels as the options. Nothing read it. `pick_areas` discards body-only evidence on purpose (one passing mention of `ssh` in a paragraph is not an area) and `auto_triage.py` only ever passed the title and body to `classify`, so the reporter's explicit answer was thrown away. Concretely: reporter picks `sidebar`, title is "Wrong item highlighted after reorder", and the issue came out `needs-triage` with the answer sitting right there in the body. `form_area` parses the rendered form, takes the label before the first parenthesis, treats "Not sure" and `_No response_` as no answer, and outranks every inference below it. Picking off a list of the real labels is better evidence than a regex over prose, and reading it is the only thing that makes the dropdown worth having. This also removes a way the dropdown could make triage worse. The chosen option's parenthetical lands inside the scored body window, so `remote (cmux ssh, tunnels, relays)` used to add points to cli and cloud as well and could swing a 3-3 title tie to an area the reporter did not pick. An explicit answer now short-circuits scoring, so the hint text cannot perturb anything. Nine tests, including one that asserts every one of the 22 areas is reachable through the dropdown, so an option whose wording drifts away from its label fails rather than silently falling back to guessing. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Merge receipt for |
4e0f7d2 fix(bash): keep $? for PROMPT_COMMAND hooks after cmux's (manaflow-ai#15255) ae49bf5 fix(examples): show custom description in Project Worktrees sidebar (manaflow-ai#15256) a9a229d Add cross-provider token usage accounting for agent transcripts (manaflow-ai#15332) 860619f Add a .worktreeinclude reader for seeding new worktrees (manaflow-ai#15413) 3edbd83 Clear the stale Needs input badge when Claude's permission is decided in the terminal (manaflow-ai#15170) 9ed9294 CodeRouter: hold capacity errors on the same model instead of failing fast (manaflow-ai#15310) 56d4547 docs: add a front door for outside contributors (manaflow-ai#15263) 799f906 fix(ci): recognize GUI token acquisition failures (manaflow-ai#15449) f118d43 ci: age parked builds by measured reuse distance (manaflow-ai#15616) 1f6744d ci: harden overflow switch recovery (manaflow-ai#15617) 9987778 Predicted echo: remote terminals only, withdraw on pasted and sent input (manaflow-ai#15211) d9e199b Subtle selection follow-ups: group header hairline, no focus re-render for legacy rows, cmux.json test (manaflow-ai#15195) c13afe1 test: cover UTF-8 workspace create commands (manaflow-ai#15622) e76a660 fix: preserve Claude remote-control names on restore (manaflow-ai#15619) 900f248 feat: expose cmux-owned scratch metadata in session listing (manaflow-ai#15615) b5604fa ci: say why compiled-product reuse refused an artifact (manaflow-ai#15553) # Conflicts: # .github/workflows/ci-cloud-overflow-probe.yml
Summary
cmux had no start-here page, no code of conduct and no security policy. Someone arriving from a link had to read CONTRIBUTING.md and infer whether they could contribute at all without a Mac. That is the first question a student or a drive-by contributor asks, and the answer (yes, CI builds and tests for you) was not written down anywhere.
This is the docs half of the contributor front door. The triage half is #15228.
docs/start-here.md(new): how to pick an issue from the triage labels, what is fixable without a Mac,python3 scripts/verify-local.pyas the one local check that always works, what CI runs for you, what happens after you open a pull request, and a short note for a class or a group working through issues together.CONTRIBUTING.md: a pointer to start-here and the code of conduct at the top; a "Finding something to work on" section; a "What CI runs for you" section that spells out static checks, routed tests, and the label-gated macOS suite, so nobody concludes they need a build farm; and "How review and merge work" under Pull Requests (squash merges,mainis what NIGHTLY builds from, fix forward rather than revert, contributors getCo-authored-bycredit).CODE_OF_CONDUCT.md(new): be nice, assume the best, what we do not accept, scope, and an address that reaches a human. 53 lines, no adopted-framework boilerplate.SECURITY.md(new): report privately by email rather than in a public issue, what to include, what happens next, and a scope section written for a terminal. Escape sequences, file names, branch names and agent output that run code are in scope; a command you typed is not. Also states there is no backport branch.areadropdown on both bug and feature forms, first option "Not sure", so auto-triage can start from the reporter's own answer instead of guessing from prose.blank_issues_enabled: falseplus contact links routing first-timers to start-here, questions to Discussions and Discord, and vulnerabilities to SECURITY.md.Why SECURITY.md is in this PR
The security contact link needed a target.
repos/manaflow-ai/cmux/private-vulnerability-reportingreports{"enabled": false}, so the GitHub advisory form would have 404'd for anyone who clicked it. Email is the honest answer today. Recommendation: turn on private vulnerability reporting in repo settings, and I will repoint the contact link and the SECURITY.md instructions at the advisory form. Until then this is what works.Testing
python3 scripts/verify-local.py: 14/15 checks passed; the unrun one is native compilation, which no file in this PR affects.config.ymlparse as YAML, and the inserted dropdown isrequired: falsewith 23 options on each.docs/triage.mdandscripts/ci/triage_rules.py. Those land in triage: severity and area labels, with the rules in the repo #15228.No app code, no runtime behavior, no UI. Nothing here is dogfoodable, so there is no before/after capture to attach.
Merge order
Merge after #15228.
docs/start-here.mdandCONTRIBUTING.mdlinkdocs/triage.md, which #15228 adds. Landing this first leaves three broken links onmain.Changelog
none
Demo Video
Not applicable; docs only.
Checklist
Behavior changes have added or updated tests, or Testing says why not
UI, settings, menu, schema, help-text or user-facing docs change: localization audited, and the result is stated above
Contributor-facing repository markdown and GitHub issue forms. Neither is localized: no
String(localized:)call sites, no catalog entries, and GitHub renders both from the repo in English only. No catalog change needed.New or changed v2 socket method allowlisted for
cmux ssh: n/aiOS connectivity, auth, lifecycle, workspace action, terminal I/O or mobile RPC contract change: n/a
User-facing docs updated if needed
Reviewed with a subagent before merge (cmux-review), and all bot and human review comments resolved
Team calls
The code of conduct wording is a team-visible call. It and the label taxonomy from #15228 go to #13742 with a recommendation; I am not merging either ahead of that.
🤖 Generated with Claude Code
Summary by cubic
Adds a front door for outside contributors: a start-here page that explains what can be fixed without a Mac, what CI runs for them, and how review and merge work, plus a code of conduct and security policy.
docs/start-here.mdand additions toCONTRIBUTING.mdcover picking issues, the portable parts of the tree,verify-local.py, CI coverage, and what happens after a PR opens;README.mdlinks the page.CODE_OF_CONDUCT.mdandSECURITY.md; vulnerabilities are reported by email because private vulnerability reporting is not enabled.areadropdown, and contact links route first-timers, questions, and security reports away from the bug form.needs-triageis the largest unrouted pile rather than the largest overall.The new docs link
docs/triage.md, added in a separate PR, so land this one after that.Written for commit c900f97. Summary will update on new commits.