Skip to content

feat: populate the org defaults for mzizi-dev - #1

Merged
Bryan Fawcett (bryanfawcett) merged 5 commits into
mainfrom
claude/org-defaults
Sep 11, 2026
Merged

Bryan Fawcett (bryanfawcett) merged 5 commits into
mainfrom
claude/org-defaults

Conversation

@bryanfawcett

Copy link
Copy Markdown
Contributor

What this changes

Turns this repo from a one-line README into the org's actual defaults: CODEOWNERS, PR and issue templates, SECURITY.md / CONTRIBUTING.md / CODE_OF_CONDUCT.md / SUPPORT.md, three reusable workflows, versioned ruleset JSON, and ORG_STANDARDS.md.

Why

GitHub falls back to this repo for any repo in the org lacking its own community-health files. Until now it held # .github, so eight of the nine repos inherited nothing. mzizi-registry is the only repo with its own — and two of its files are broken (gaps 1 and 2 below), so review routing and the security-report path currently work in zero repos.

Everything was verified before it was written down

ORG_STANDARDS.md describes the CI that actually runs per repo today, read off the API, and lists twelve things that do not. Claims checked rather than assumed: merge settings on all nine repos, every workflow file, org and repo rulesets, branch protection, org membership and teams, secret-scanning and private-vulnerability-reporting state per repo, action tag→SHA resolutions, gitleaks' licence, and nyuchi/.github's Rust reusable.

One correction to the brief: the org has two members — @bryanfawcett (admin) and @michellellawson (member) — not one. There are no teams, which is why CODEOWNERS names users, not a @mzizi-dev/... handle.

The reusable workflows

Rust-first, not npm-first.

  • reusable-rust-ci.yml — fmt / clippy / test, plus a target input and a separate clippy-on-target boolean. Two of the three Rust repos ship as WASM (mzizi-console in a browser, mzizi-api-gateway on workerd), and code can pass every native check and fail to compile for the target that ships. The two repos need different answers — mzizi-console lints on the host then checks wasm32; mzizi-api-gateway must lint against wasm32 because the worker crate's API is cfg'd for it — so one knob would have forced them onto the same wrong answer. A working-directory input covers mzizi, whose crate is in compiler/.
  • reusable-gitleaks.yml — runs the MIT binary directly; gitleaks/gitleaks-action requires a paid licence for org repos. Defaults to 8.21.2, the version every repo already runs, so adopting it changes no behaviour.
  • reusable-pr-title-lint.yml — Conventional Commits on the PR title.

Third-party actions are pinned by commit SHA, not tag. Resolutions recorded in ORG_STANDARDS.md so a reader can tell a pin from a guess.

No repo calls these yet, deliberately — publishing and adopting at once would move nine repos with no baseline. This repo's own ci.yml dogfoods two of the three by local path (uses: ./...), so a change to a reusable is tested by the PR that makes it, not by the already-merged copy.

Merge-only

Reflected throughout, per mzizi/MIGRATION.md §1.1 — "Squash discards the per-commit reasoning this project depends on." The docs also get specific about a consequence that is easy to miss: every repo is merge_commit_message=PR_TITLE, so the PR title is the merge commit body, not its subject — which changes what the title lint is actually guarding.

Rulesets are NOT applied

github-rulesets/*.json are reviewable proposals; the apply command is in each file's _comment. Note the org-wide one deliberately omits required_linear_history: that rule blocks merge commits, and a merge commit is the only merge this org permits. mzizi-registry's existing ruleset has exactly that combination today — gap 4.

Gaps documented rather than fixed

They live in other repos or need an admin decision. Highlights:

  1. mzizi-registry's CODEOWNERS names @nyuchi/core — wrong org, and nyuchi has no core team. It assigns nobody, and it overrides this repo's.
  2. Private vulnerability reporting is off on six of eight public repos; SECURITY.md routes around it to mzizi.
  3. mzizi-registry's ruleset requires linear history while the repo allows only merge commits — the next merge-button merge there should be rejected.
  4. Secret scanning and push protection are on for two of eight public repos; Dependabot security updates are off on all nine.
  5. mzizi-registry filters PR triggers on [main] alone, so stacked PRs above the bottom layer get zero checks.

Full list with evidence in ORG_STANDARDS.md.

Checks

  • actionlint clean on all five workflow files.
  • Both ruleset JSON files parse and carry the API's required keys (there is a CI job for this).
  • Every issue-form and Dependabot YAML parses.
  • The rulesets parse step was executed locally, not just eyeballed.

🤖 Generated with Claude Code

Until now this repo held a one-line README, so the eight other repos in
the org inherited nothing: no CODEOWNERS, no issue or PR templates, no
security policy, and no shared CI. Only `mzizi-registry` had any of those,
and it has them locally, which means they cover one repo out of nine.

Everything here was read off the GitHub API before it was written down.
ORG_STANDARDS.md describes the CI that actually runs in each repo today
and lists twelve things that do not exist, rather than describing the
intended state as if it were the current one.

Three reusable workflows, chosen for what this org actually is — Rust
first, not npm first:

  - reusable-rust-ci.yml takes a `target` input and a separate
    `clippy-on-target` boolean. Two of the three Rust repos ship as WASM
    (mzizi-console in a browser, mzizi-api-gateway on workerd) and code
    can pass every native check and still fail to compile for the target
    that ships. The two repos need different answers — mzizi-console
    lints on the host and checks wasm32, mzizi-api-gateway must lint
    against wasm32 because the `worker` crate's API is cfg'd for it — so
    one knob would have forced them onto the same wrong answer.

  - reusable-gitleaks.yml runs the MIT binary directly. The
    gitleaks/gitleaks-action wrapper needs a paid licence for org repos.

  - reusable-pr-title-lint.yml enforces Conventional Commits on the PR
    title.

Third-party actions are pinned by commit SHA, not tag; a tag can be moved
to point at different code. The resolved versions are recorded in
ORG_STANDARDS.md so a future reader can tell a pin from a guess.

No repo calls these yet. Publishing and adopting in one change would move
nine repos with no baseline to compare against; adoption is a small PR per
repo, and this repo's own ci.yml dogfoods two of the three by local path
so a change to a reusable is tested by the PR that makes it.

github-rulesets/*.json are proposals and are NOT applied. Note that the
org-wide one deliberately omits `required_linear_history`: that rule
blocks merge commits, and a merge commit is the only merge this org
permits. mzizi-registry's existing ruleset has exactly that combination
today, which is gap 4.

The docs reflect the merge-only convention throughout, per MIGRATION.md
§1.1 — "Squash discards the per-commit reasoning this project depends on".

One correction to the brief this was written against: the org has two
members, @bryanfawcett (admin) and @michellellawson (member), not one.
There are no teams, which is why CODEOWNERS names users.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
"is the second workflow" told a reader nothing. It dispatches to a
held-out runner named by a repo variable, and it is fork-guarded — both
worth knowing, because the held-out task set is withheld on purpose
(MIGRATION.md §5: "withheld so the benchmark measures the language rather
than memorisation") and a reader who does not know that might reasonably
try to make the dispatch target public.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
actionlint's shellcheck pass failed on `cargo test $EXTRA` with SC2086.
The word splitting was intentional — test-args is an argument list — but
the unquoted form also glob-expands, which was not intentional, so the
warning was correct and the original comment defending the line was
wrong.

`read -ra` splits and does not glob. An empty input yields an empty
array, which is safe under `set -u` from bash 4.4 onward; ubuntu-latest
ships bash 5.

Worth recording how this got through: actionlint was run locally before
pushing and reported clean, because shellcheck is not installed on this
machine and actionlint silently skips the shellcheck rules when the
binary is missing. A clean local actionlint is therefore weaker evidence
than it looks. The CI job, which runs on a runner that has shellcheck,
is the one that counts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The settings sweep behind those two rows iterated eight repos and missed
mzizi-site, so the counts were taken over a sample that did not include
it. mzizi-site has has_wiki false and an Apache-2.0 licence, which moves
wikis to four-off/five-on and licences to seven-of-nine.

Small numbers, but this page's whole claim is that it reports what is
there rather than what is expected, so an off-by-one from an incomplete
sweep is exactly the defect it should not have.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This repo pins third-party actions by SHA, but GitHub has an org setting
that enforces it (`sha_pinning_required`) and it is false. A convention
that only lives in review comments is weaker than one the platform
checks, so the setting belongs in the gap list next to the convention.

Noting honestly that it cannot simply be switched on: every existing
workflow in the org uses floating tags, so enabling it would break them
all until they are pinned.

The same endpoint shows `default_workflow_permissions: write`, which
gives every workflow a read-write token by default. Recorded alongside
it because it is the same one-line admin decision and the same argument.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@bryanfawcett
Bryan Fawcett (bryanfawcett) merged commit 5c5d790 into main Sep 11, 2026
5 checks passed
@bryanfawcett
Bryan Fawcett (bryanfawcett) deleted the claude/org-defaults branch September 11, 2026 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant