Skip to content

Diff viewer: Group Files by Kind is a setting, so the toggle sticks - #23653

Merged
teamleaderleo merged 5 commits into
feat-cmux-nextfrom
cmux/diff-groupbykind-setting
Oct 22, 2026
Merged

teamleaderleo merged 5 commits into
feat-cmux-nextfrom
cmux/diff-groupbykind-setting

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

What

The toolbar's Group files by kind reset itself on every reopen. The page persists a display
option by sending diff.<key> to the host; the host refuses a diff.* key it has no schema row
for (DiffPrefKey.accepts), and saveViewerPrefs swallows that refusal on purpose — so the one
option with no row silently never persisted. It was kept session-local and off by default for
exactly that reason (2026-10-20 review of #22951).

This gives it the row, through the whole new-setting checklist:

  • diff.groupByKind in DiffViewerSettingsSchema — a toggle in Settings → General → Diff
    Viewer, with keywords (group, kind, tests, generated, order, sort).
  • Agent-settable with the rest of the diff page's looks: SettingsSchema+AgentPolicy unions
    DiffViewerSettingsSchema.keys whole, so the row is covered by that decision rather than by a
    new one.
  • DiffPrefKey.booleans, so the host accepts the write at all.
  • Titled in all 21 locales in CmuxNextSettings/Localizable.xcstrings (en translated, the rest
    needs_review, as every sibling row in that table is).
  • On the page: groupByKind moves into defaultDiffViewerOptions with the other schema-backed
    defaults, is sanitized and persisted like them, and setOption no longer skips it.

It stays off by default

The familiar order is the order the diff arrived in. Now that the toggle lasts past the tab,
turning the grouping on is the reader's to make; whether it becomes the default is a separate
change with its own argument, not a side effect of giving it a row.

Red then green

  • bun test test/viewer-prefs-host-keys.test.ts — the new case fails against the old host list
    (expect(accepted.has("groupByKind")).toBe(true) receives false) and passes with the change.
    It asserts both halves, because either one alone is the silent bug again: the host accepts the
    key, and the page actually persists it.
  • test/diff-option-defaults.test.ts holds every key of defaultDiffViewerOptions to the
    exported schema, so it reads { key: "groupByKind", value: undefined } until
    schemas/settings/settings-schema.json has the new row. That export is a Mac swift test
    (regenerate-settings-exports.sh); no lane regenerates it by hand, so the cmux-next PR autofix
    generates it and pushes it to this branch, and that test turns green on the autofix head. If the
    autofix does not run, the fleet export step produces the same commit.

Observed / Not run

Ran and saw, on this head:

  • bun test test/viewer-prefs-host-keys.test.ts test/diff-option-defaults.test.ts — 6 pass, and
    the one expected red above (the missing exported row).
  • webviews/bun run check — exit 0. scripts/web-lint.sh — passed.
    scripts/cmux-next/prepush-gate.py — no new violations.
  • scripts/cmux-next/check-l10n.sh — 135 tables, 8,030 keys, 21 languages, 0 errors.

Only read, not run here: Swift compilation (Linux host) — the fleet compile receipt covers it; and
the settings export, which needs a Mac and is the autofix's job.

The exports, and who has to say yes

A new setting is the descriptor plus everything derived from it. The second commit adds those six
files — docs/mdm/com.manaflow.cmux.json, .plist, managed-preferences.md,
schemas/settings/settings-schema.json, schemas/defaults/cmux-next.json and the source stamp
schemas/settings-export/settings-schema.sources.sha256 — and they come from the sanctioned
producer, not from an editor: the PR autofix run of the previous head
(39660516674, artifact
pr-autofix-patch), which runs scripts/cmux-next/regenerate-settings-exports.sh on a Mac and
rewrites the defaults snapshot from what it produced. That workflow cannot push here: its push job
is gated github.event_name != 'pull_request' (cmux-next-pr-autofix.yml:559) while its only
trigger is pull_request, so the artifact is all of its output and the lane commits it. The base
merge in this branch touches no CmuxNextSettings source (git diff over that directory and
schemas/, docs/mdm is empty), so the stamp the Mac computed matches the tree it lands on.

This PR needs a human. Adding a key adds a line to schemas/defaults/cmux-next.json, and
defaults_guard.py counts an added default as a default change, so
cmux-next-defaults-guard.yml holds until a call owner from the base's
.github/defaults-call-owners.json (lawrencecchen, austinywang, teamleaderleo) other than the
author approves this head. No label and no agent review clears that; I have not added and will not
add risk:human-ok. The other three follow-ups of #22951 carry no default and do not wait on this.

Capture

The Settings page is a webview that renders one row per schema row, straight from the exported JSON
(webviews/src/pages/settings/schema.ts:3), so committing the exports is what makes the row appear
— and the gallery shows it without a Mac. Base vs this head, live from both builds:
https://cmux-lawrences-mac-mini.tail137216.ts.net:18796/compare/cmux-diff-groupbykind-setting/?entry=pages.settings
(tailnet only.) The Diff Viewer group gains Group Files by Kind, off, below Expand Unchanged
Lines; nothing else on the page moves.

No capture: both surfaces this touches are webviews, where the gallery above is the evidence this
repository asks for, and a Mac tour would add nothing — the diff viewer's own toggle is unchanged
pixel for pixel (only where its value is kept changed), and the native files here draw nothing.

Review, and what it does not do

An independent review passed the whole diff, including the generated files: it recomputed the two
source hashes and ran sha256sum --check over all 272 stamp entries, ran defaults_guard.py check-stamp and check-fresh (both exit 0), checked the row lands in exactly the two places
settings-schema.json keeps a row and is field-for-field its siblings' shape, and confirmed the
two exports with no diff.* key are rightly absent from the diff. It traced the round trip
(toolbar toggle -> cmux.diff.prefs.set -> DiffPrefKey.accepts -> SettingsDiffPrefs.setPref ->
pagePrefs() -> seeded options) and ran the webview suites green.

Two of its notes are worth having here:

  • The row's section is appearance, like every other Diff Viewer row, but the page draws that
    whole group under General -- so it is Settings → General → Diff Viewer, which is what this
    description now says.
  • Changing it in Settings does not reach a diff tab that is already open: webviews/src/diff/page.ts
    applies only colors from the cmux.diff.prefs stream. That is true of every diff toggle today
    and this PR does not change it, but now that the key has a Settings row, a reader can toggle it
    there and see nothing until the tab is reopened. A follow-up, not this PR.

The ui-rules test that is red here fails on webviews/src/pages/apps/AppsPage.tsx, which this
branch does not touch: a base finding.

Changelog

Fixed: "Group files by kind" in the diff viewer is now a setting (General → Diff Viewer), so turning it on lasts past the tab instead of resetting on every reopen.

🤖 Generated with Claude Code

Agent session: big-red


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Makes the diff viewer's "Group files by kind" toggle persist past the tab instead of resetting on every reopen.

The toggle never stuck because the host refuses diff.* keys it has no schema row for, and saveViewerPrefs silently drops that refusal. This gives groupByKind its schema row and the full new-setting treatment.

  • Adds diff.groupByKind (Settings → General → Diff Viewer), agent-settable and titled in all 21 locales.
  • Host accepts the key via DiffPrefKey.booleans; the page sanitizes and persists it like the other schema-backed defaults.
  • Regenerates the settings exports (MDM manifests, settings-schema.json, defaults snapshot) and refreshes the export stamp after merging base.
  • Stays off by default — the familiar order is the order the diff arrived in, and grouping is the reader's to enable.

Written for commit 2dadcf8. Summary will update on new commits.

View guided diff Turn on auto-fix

The toolbar's "Group files by kind" reset itself on every reopen. The page
persists a display option by sending `diff.<key>` to the host, the host refuses
a `diff.*` key it has no schema row for (DiffPrefKey.accepts), and
saveViewerPrefs swallows that refusal on purpose -- so the one option with no
row silently never persisted. It was kept session-local and off by default for
exactly that reason (2026-10-20 review of #22951).

This gives it the row: `diff.groupByKind`, a toggle in Settings > Appearance >
Diff Viewer, agent-settable with the rest of the diff page's looks (it is in
DiffViewerSettingsSchema, which SettingsSchema+AgentPolicy unions whole), in
DiffPrefKey.booleans so the host accepts the write, and titled in all 21
locales.

On the page, `groupByKind` moves into `defaultDiffViewerOptions` with the other
schema-backed defaults, is sanitized and persisted like them, and `setOption` no
longer skips it.

It stays off by default. The familiar order is the order the diff arrived in,
and now that the toggle lasts past the tab, turning it on is the reader's to
make; whether it becomes the default is a separate, reviewable change.

Red then green: `bun test test/viewer-prefs-host-keys.test.ts` fails its new
case against the old host list ("expect(accepted.has(\"groupByKind\")).toBe(true)"
receives false) and passes with it. `test/diff-option-defaults.test.ts` holds
every key of `defaultDiffViewerOptions` to the exported schema, so it stays red
until the Mac settings export regenerates schemas/settings/settings-schema.json
for the new row; that commit follows.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15cc0-fc9d-7382-af90-51f8726825bd&host=big-red
@teamleaderleo

teamleaderleo commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator Author

Owned by orphan-sweep on air-blue · session

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 2dadcf8: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr23653 -f ref=cmux/diff-groupbykind-setting -f platform=macos -f backend_mode=local

Passes: CI passes on 2dadcf85a2.

CI passes on 2dadcf85a2 (run 39706573345 attempt 1).

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base 5363032; does not block

CI fast guards passes on 7723b8f3cd (run). This covers only the fast guards, not CI: CI's result is ci-status.

Gallery before/after for 2dadcf8: 16 states rendered, 1 images differ, 1514 more touched states not rendered. Images are in the run's artifact, not on this public PR.

gh run download 39706573307 -R manaflow-ai/cmux -n gallery-advisory-23653-2dadcf85a297c8fd75235beb9a9cf46353868ff4 (then read gallery-review.json)

States
State Theme Status Diff Picked by
pages.diff/small-split Apple System Colors Light unchanged 0% own App.tsx
pages.diff/small-split Apple System Colors unchanged 0% own App.tsx
pages.diff/unified Apple System Colors Light unchanged 0% own App.tsx
pages.diff/unified Apple System Colors unchanged 0% own App.tsx
pages.diff/deleted Apple System Colors Light unchanged 0% own App.tsx
pages.diff/deleted Apple System Colors unchanged 0% own App.tsx
pages.diff/many-files Apple System Colors Light unchanged 0% own App.tsx
pages.diff/many-files Apple System Colors unchanged 0% own App.tsx
pages.diff/word-diff Apple System Colors Light unchanged 0% own App.tsx
pages.diff/word-diff Apple System Colors unchanged 0% own App.tsx
pages.diff/word-diff-split Apple System Colors Light unchanged 0% own App.tsx
pages.diff/word-diff-split Apple System Colors unchanged 0% own App.tsx
pages.diff/big-review Apple System Colors Light unchanged 0% own App.tsx
pages.diff/big-review Apple System Colors unchanged 0% own App.tsx
pages.diff/collapsed-files Apple System Colors Light changed 0% own App.tsx
pages.diff/collapsed-files Apple System Colors unchanged 0% own App.tsx
agent-pane.chat-width/standard Apple System Colors Light unchanged 0% names App.tsx
agent-pane.chat-width/standard Apple System Colors unchanged 0% names App.tsx
agent-pane.chat-width/wide Apple System Colors Light unchanged 0% names App.tsx
agent-pane.chat-width/wide Apple System Colors unchanged 0% names App.tsx
agent-pane.chat-width/wide-blocks Apple System Colors Light unchanged 0% names App.tsx
agent-pane.chat-width/wide-blocks Apple System Colors unchanged 0% names App.tsx
agent-pane.composer-floats/scrolled-to-end Apple System Colors Light unchanged 0% names App.tsx
agent-pane.composer-floats/scrolled-to-end Apple System Colors unchanged 0% names App.tsx
agent-pane.composer-floats/composer-grown Apple System Colors Light unchanged 0% names App.tsx
agent-pane.composer-floats/composer-grown Apple System Colors unchanged 0% names App.tsx
agent-pane.diff-panel/last-turn Apple System Colors Light unchanged 0% names App.tsx
agent-pane.diff-panel/last-turn Apple System Colors unchanged 0% names App.tsx
agent-pane.diff-panel/toolbar Apple System Colors Light unchanged 0% names App.tsx
agent-pane.diff-panel/toolbar Apple System Colors unchanged 0% names App.tsx
agent-pane.diff-panel/tree-selection Apple System Colors Light unchanged 0% names App.tsx
agent-pane.diff-panel/tree-selection Apple System Colors unchanged 0% names App.tsx

Pick other states with a Gallery: entry.id, entry.id/variant line in the PR body.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-2k8md created for this PR by the cmux coordinator.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next crash-class rules / cmux-next crash-class rules is red on 8 of 8 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@blacksmith-sh

blacksmith-sh Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Found 11 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmp01tfr5no/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmporkpynit/summary-fail.json (live):/summary-fail.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs
convention violations found (ERROR lines above)./
convention violations found (ERROR lines above).
View Logs
nightly cmux-tui resolve/nightly cmux-tui resolve View Logs
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules)/
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules)
View Logs
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules) (job='web-bundles')/
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules) (job='web-bundles')
View Logs

...and 1 more test failures. View all on Blacksmith

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

teamleaderleo and others added 2 commits October 21, 2026 12:43
A new setting is two things: the descriptor in `DiffViewerSettingsSchema`, and the
exports every other consumer reads from it -- the MDM manifests, the portable
`settings-schema.json`, the defaults snapshot, and the source stamp that proves
the exports match the sources that produced them. Only the descriptor was in
this branch, so `cmux-next generated files` and the defaults guard were red on a
tree whose exports did not name `diff.groupByKind`.

These six files come from the sanctioned producer, not from an editor: the PR
autofix run of this head (39660516674, `pr-autofix-patch`), which runs
`scripts/cmux-next/regenerate-settings-exports.sh` on a Mac and then rewrites
the defaults snapshot from the exports it produced. That workflow cannot push to
a pull request branch -- its push job is gated `github.event_name !=
'pull_request'` (cmux-next-pr-autofix.yml:559) while its only trigger is
`pull_request` -- so the artifact is the whole of its output and the lane commits
it. The base merge in this branch touches no `CmuxNextSettings` source, so the
stamp the Mac computed still matches the tree it lands on.

The diff is the one key and nothing else: the row in the Diff Viewer group, its
plist and JSON manifest entries, its line in the managed-preferences table, its
`false` in the defaults snapshot, and the two source hashes that changed
(`DiffViewerSettingsSchema.swift` and `CmuxNextSettings/Localizable.xcstrings`).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15cc0-fc9d-7382-af90-51f8726825bd&host=big-red
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Default changes

This pull request changes 1 default at 2dadcf85a297 (what everyone gets without configuring anything):

  • setting.diff.groupByKind: (none) -> false (a new setting, off by default: passes on its own)

Every change is a new setting that defaults to off, the behavior from before it existed.

Regenerate the snapshot with python3 scripts/ci/defaults_guard.py snapshot.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Check classification on 7723b8f3cd94, all five reds:

  • cmux-next defaults guard / defaults guard — this PR's, and only a person clears it. Adding a
    key adds a line to schemas/defaults/cmux-next.json, and defaults_guard.py counts an added
    default as a default change, so it holds for an approving review on this head from a call owner in
    the base's .github/defaults-call-owners.json (lawrencecchen, austinywang, teamleaderleo),
    author excluded. No label and no agent review substitutes, and I have not added risk:human-ok.
  • cmux-next / cmux-next checks — base: the Tier routing finding described above; test(next): route tests read expected targets from the graph (Tier routing base red) #23668 owns
    the fix. (Package conventions lint on ChiefWorkspaceName.swift is in the warn tier.)
  • gallery health / health (1) and (2) — base: pages.settings#import and
    #import-customized ("the stage reported an error"), red on the base tip in run
    39662387466, plus
    agent-pane.url-chip#pull-request-lines-by-kind, a state broken since cmux NEXT: one pull request card for every pull request cmux mentions #22951 that PR card: a red the base already has reads "also red on base" #23644 repairs.
    None of the three is a Settings or diff-viewer state this PR touches.
  • cmux-next PR autofix / action exports (Mac) — failed at Set up runner, before any step of
    this PR's tree ran: an infrastructure refusal, not a result. Its earlier run on the previous head
    is what produced the exports now committed here.

So the only thing between this and a merge is the defaults call.

Settings export stamp: base's stamp, with the merged digests for the two
sources this branch changes (DiffViewerSettingsSchema.swift and the
CmuxNextSettings catalog). The sources base left stale stay stale as on
base, so the base autofix still regenerates them after the merge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15cfc-663f-7650-b9f7-64d198c6b88b&host=Air-Blue
@cursor

cursor Bot commented Oct 22, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 22, 2026 00:51 — with GitHub Actions Inactive
@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 22, 2026

@teamleaderleo teamleaderleo left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (subagent, correctness first): SHIP at 38eab2d

Independent subagent review (fresh context) of the merged head. Nothing blocking.

  • Swift: diff.groupByKind row matches its siblings (toggle, default false, .appearance); DiffPrefKey.booleans gains the key, which is all accepts/sanitized/setPref need; agent policy picks it up via DiffViewerSettingsSchema.keys.
  • Webview round trip: defaultDiffViewerOptions carries groupByKind: false, sanitizeViewerPrefs accepts it only as a boolean, App.tsx now persists every key except collapsed; coherent with base's App.tsx/Toolbar.tsx after the merge.
  • Exports vs base: only diff.groupByKind lines plus two stamp lines (DiffViewerSettingsSchema.swift and the CmuxNextSettings catalog, digests verified against HEAD); no base lines reverted. xcstrings: +131/-0, valid JSON, 21 locales like siblings; check-l10n.sh 0 errors; localization ratchet exit 0.
  • defaults_guard.py check exit 0 (a new setting that defaults to off); check-stamp --base exit 0 (only base-stale sources warned).
  • Not superseded: base still keeps groupByKind session-local.
  • Fleet compile: cmux-ci compile-check --ref 38eab2da27c7ac6f1f2f8ec639c3b55f752f6108 --app passed (job 0ab41537ae982378dc6b3212).

Non-blocking follow-ups: skills/cmux-customization/references/viewer-types.md:14 does not list diff.groupByKind (already omits two other diff keys); palette-eval / palette-ranker corpus fixtures have no entry for the new setting (nothing checks them against the schema).

Settings export stamp: base's stamp, with the merged digests for the two
sources this branch changes (DiffViewerSettingsSchema.swift and the
CmuxNextSettings catalog).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15cfc-663f-7650-b9f7-64d198c6b88b&host=Air-Blue

@teamleaderleo teamleaderleo left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (subagent, correctness first): SHIP at 2dadcf8

Independent subagent review (fresh context) of the head after the second base merge. No findings.

  • git diff origin/feat-cmux-next HEAD (base 5363032): only this PR's 13 files; outside the stamp, the change lines are identical to the earlier SHIP head 38eab2d. No base lines reverted; xcstrings +131/-0, valid JSON, 21 locales like settings.diff.expandUnchanged; exports parse (plutil -lint OK) and are purely additive.
  • Round trip: DiffPrefKey.booleans gains groupByKind (feeds accepts/sanitized; setPref finds the new schema row); webview sanitizes, seeds and persists it; defaultDiffViewerOptions default false matches the schema.
  • Stamp: the two changed entries equal sha256 of those files at HEAD; nothing else differs from base. defaults_guard.py check-fresh, check-stamp --base, check all exit 0 (new setting off by default).
  • Not superseded: base keeps groupByKind session-local.
  • Fleet compile: cmux-ci compile-check --ref 2dadcf85a297c8fd75235beb9a9cf46353868ff4 --app passed.

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

This branch was previously deployed

4 inactive deployments
ci-routing-agent — 2dadcf85 Deployed Oct 22, 2026 by github-actions[bot]
artifacts — 2dadcf85 Deployed Oct 22, 2026 by teamleaderleo
sentry-dsyms — 2dadcf85 Deployed Oct 22, 2026 by teamleaderleo
cmux-tui-merge-tree — 2dadcf85 Deployed Oct 22, 2026 by teamleaderleo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant