Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Org-wide default owners.
#
# GitHub falls back to this file for any repo in `mzizi-dev` that does not
# ship its own `.github/CODEOWNERS`. Today that is EVERY repo except
# `mzizi-registry` — and that repo's own file is broken (see the note at the
# bottom), so in practice nothing in this org has working review routing
# until this file lands.
#
# The org has two members: @bryanfawcett (admin) and @michellellawson
# (member). There are no teams, so owners are named as users. A team handle
# here would resolve to nobody and CODEOWNERS would silently do nothing —
# which is exactly the failure `mzizi-registry` is in.
#
# GitHub applies the LAST matching pattern, so the catch-all must stay at the
# top. Add narrower rules BELOW it, never above.

* @bryanfawcett

# ---------------------------------------------------------------------------
# Narrower rules
# ---------------------------------------------------------------------------
# These paths are named individually because they are the ones where an
# unreviewed change is expensive, not because they are the ones that change
# most. Paths are matched against the repo the PR is opened in, so a pattern
# that does not exist in a given repo simply never matches there.

# The compiler and the primitive corpus in `mzizi-dev/mzizi`. Bundu
# Foundation IP, and the artefact every other repo is downstream of.
/compiler/ @bryanfawcett
/primitives/ @bryanfawcett
/examples/ @bryanfawcett

# The charter and the migration plan are the two documents that decide what
# this project is. They should not drift by accident.
/CHARTER.md @bryanfawcett
/MIGRATION.md @bryanfawcett

# Anything that changes what CI runs, or what may merge. A PR that edits its
# own gate should be read by a human before it lands.
/.github/workflows/ @bryanfawcett
/.github/CODEOWNERS @bryanfawcett
/github-rulesets/ @bryanfawcett

# Deployment configuration for the two Workers (`mzizi-api-gateway`,
# `mzizi-console`). `wrangler.jsonc` carries the custom-domain routes; a
# wrong edit here takes a hostname down rather than failing a build.
/wrangler.jsonc @bryanfawcett

# Secrets policy and the allowlist that decides what gitleaks ignores.
/.gitleaks.toml @bryanfawcett
/SECURITY.md @bryanfawcett

# ---------------------------------------------------------------------------
# Known defect this file does NOT fix
# ---------------------------------------------------------------------------
# `mzizi-dev/mzizi-registry` ships its own `.github/CODEOWNERS`, which takes
# precedence over this one for that repo. Every rule in it names
# `@nyuchi/core` — a team in the `nyuchi` org, not this one. Verified
# 2026-09-11: the `nyuchi` org's teams are docs, maintainers, marketing,
# mukoko, nyuchi-open-projects, platform and security. There is no `core`
# team, and a team from another org cannot own code here in any case. That
# file therefore assigns no reviewers at all. Fixing it is a PR against
# `mzizi-registry`, not this repo — see ORG_STANDARDS.md, "Known gaps".
87 changes: 87 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: Bug report
description: Something behaves differently from what the docs, the charter or the code claim.
labels: ["bug"]
body:
- type: markdown
attributes:
value: >
Do not use this form for a security vulnerability. Report those
privately — see the "Security vulnerability" link on the previous
screen, or SECURITY.md.

- type: dropdown
id: component
attributes:
label: Component
options:
- mzizi — the language, compiler or `mz` CLI
- mzizi-registry — the component registry / mzizi.dev
- mzizi-console — app.mzizi.dev (Astro + Dioxus WASM)
- mzizi-api-gateway — api.mzizi.dev (workers-rs)
- mzizi-site — mzizi.dev
- mzizi-docs — docs.mzizi.dev
- agent-tools — MCP server, fundi, CLI, skills
- org / CI / governance
- other or not sure
validations:
required: true

- type: textarea
id: what
attributes:
label: What happened
description: >
Paste the exact error text, compiler diagnostic or response body.
Redact any key or token — this is a public issue.
validations:
required: true

- type: textarea
id: expected
attributes:
label: What you expected instead
description: And, if you can, what made you expect it — a doc line, a charter claim, a type signature.
validations:
required: true

- type: textarea
id: repro
attributes:
label: Steps to reproduce
placeholder: |
1. cargo run --bin mz -- check examples/connectivity_bar.mz
2. ...
validations:
required: true

- type: input
id: version
attributes:
label: Version or commit
description: >
The git SHA you are on, or the released version. "main" on its own is
not enough — main moves.
placeholder: e.g. 5404607, or mz 0.1.0
validations:
required: false

- type: input
id: toolchain
attributes:
label: Rust toolchain and target
description: >
Output of `rustc -vV`, plus the target if it is not the host. A bug
that only appears on wasm32-unknown-unknown is a different bug from
one that appears natively, and the distinction is usually the whole
answer.
placeholder: e.g. rustc 1.90.0 (stable), target wasm32-unknown-unknown
validations:
required: false

- type: checkboxes
id: hygiene
attributes:
label: Before you submit
options:
- label: This report contains no API key, token or credential.
required: true
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
blank_issues_enabled: true
contact_links:
- name: Security vulnerability
url: https://github.com/mzizi-dev/mzizi/security/advisories/new
about: >
Report privately. Never open a public issue for a vulnerability. This
link goes to the `mzizi` repo because private reporting is enabled
there; see SECURITY.md for which other repos accept it today.
- name: Documentation
url: https://docs.mzizi.dev
about: The Mzizi framework docs — language reference, runtime guides, agent surfaces.
- name: Component registry
url: https://mzizi.dev
about: Components, design tokens, and the registry API.
- name: Org standards, CI and governance
url: https://github.com/mzizi-dev/.github/blob/main/ORG_STANDARDS.md
about: What CI actually runs in each repo today, and the known gaps.
- name: Contributing
url: https://github.com/mzizi-dev/.github/blob/main/CONTRIBUTING.md
about: How to open a PR here, including why this org is merge-only.
60 changes: 60 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Feature request
description: Propose a change in behaviour, a new capability, or a language change.
labels: ["enhancement"]
body:
- type: dropdown
id: component
attributes:
label: Component
options:
- mzizi — the language, compiler or `mz` CLI
- mzizi-registry — the component registry / mzizi.dev
- mzizi-console — app.mzizi.dev
- mzizi-api-gateway — api.mzizi.dev
- mzizi-site — mzizi.dev
- mzizi-docs — docs.mzizi.dev
- agent-tools — MCP server, fundi, CLI, skills
- org / CI / governance
- other or not sure
validations:
required: true

- type: textarea
id: problem
attributes:
label: The problem
description: >
What is hard or impossible today? Describe the situation, not the
solution. If you already know the solution, it still helps to write
the problem down first — it is the part that outlives the proposal.
validations:
required: true

- type: textarea
id: proposal
attributes:
label: Proposed change
validations:
required: true

- type: textarea
id: thesis
attributes:
label: Fit with the charter
description: >
Mzizi's stated single sharp edge is "a Rust framework whose syntax,
type system, and compiler feedback loop are designed for machine
authorship" (mzizi/CHARTER.md §1). Proposals that make the language
better for a human typing, at the cost of an agent iterating against
the compiler, are the ones that need the most argument. Say which
side of that line this falls on.
validations:
required: false

- type: textarea
id: alternatives
attributes:
label: Alternatives considered
description: Including "do nothing" — say why that is worse.
validations:
required: false
46 changes: 46 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
## What this changes

<!-- One or two sentences. The Conventional Commit type lives in the PR
title; this is the part a reviewer reads first. -->

## Why

<!-- The reasoning the diff cannot express. If it closes an issue, say
"Closes #123". If it follows another PR, link it.

This section matters more here than in most orgs. mzizi-dev is
MERGE-ONLY — squash and rebase merging are disabled on all nine repos,
because "squash discards the per-commit reasoning this project depends
on" (mzizi/MIGRATION.md §1.1). Your individual commits survive on main
forever. Write them, and this, for the person reading them in a year. -->

## Commits

- [ ] Each commit is a coherent step with a message that says *why*, not
just *what*. They are not going to be squashed away.
- [ ] No "fix typo" / "address review" commits left in the history — fold
them into the commit they belong to before requesting review.

## Checks

- [ ] CI is green on this PR.
- [ ] PR title follows Conventional Commits (`feat:`, `fix:`, `docs:`, …),
subject lowercase and imperative, no trailing period.
- [ ] `cargo fmt --check` and `cargo clippy -- -D warnings` pass locally for
any crate touched.

## WASM

<!-- Delete if this touches no Rust that ships to a browser or to workerd. -->

- [ ] `cargo check --target wasm32-unknown-unknown --all-targets` passes.

> `mzizi-console` ships as WASM in the browser and `mzizi-api-gateway` ships
> as WASM on workerd. Code can pass a native `cargo check` and still fail to
> compile for either. A native-only pass is not evidence.

## Deployment

<!-- Does this need a `wrangler deploy`, a secret set, a DNS change, or a
version bump anywhere downstream? "No" is a fine answer — say it
explicitly rather than leaving the section blank. -->
25 changes: 25 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Dependabot for THIS repo only.
#
# A `dependabot.yml` in the org `.github` repo is NOT inherited by other
# repos — unlike CODEOWNERS, issue templates and SECURITY.md, Dependabot has
# no org-wide fallback. Each repo needs its own file. See
# `dependabot.example.yml` beside this one for a starting point to copy.
#
# The only thing here is a Cargo.toml-free repo of workflows, so
# github-actions is the only ecosystem that applies.

version: 2
updates:
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 5
commit-message:
# Conventional Commits, to match the PR title lint. Dependabot
# capitalises the word after the prefix ("ci: Bump ..."), which the
# subject pattern rejects — that is why the lint workflow skips
# dependabot PRs rather than the pattern being loosened.
prefix: ci
labels:
- dependencies
81 changes: 81 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# CI for this repo.
#
# It also dogfoods what this repo publishes: the `secrets` job calls
# `reusable-gitleaks.yml` by LOCAL path (`uses: ./...`) rather than by
# `@main`. A local reference resolves against the commit under test, so the
# reusable workflow is exercised on the PR that changes it — a `@main`
# reference would run the already-merged copy and tell you nothing.

name: CI

on:
push:
branches: [main]
pull_request:
# Not just main. Stacked pull requests target the branch below them in
# the stack, and a filter of [main] silently gives every layer but the
# bottom one zero checks — a green PR with nothing run looks identical to
# a passing one.
branches: [main, "claude/**"]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
actionlint:
name: actionlint
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v5

# The prebuilt binary straight from the upstream release — no
# third-party action, no Go toolchain, no install script piped to a
# shell.
- name: Install and run actionlint
env:
ACTIONLINT_VERSION: 1.7.12
run: |
set -euo pipefail
curl -fsSL -o actionlint.tar.gz \
"https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz"
tar -xzf actionlint.tar.gz actionlint
chmod +x ./actionlint
./actionlint -color

rulesets:
name: rulesets parse
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v5

# These files are applied with `gh api --input`. A JSON syntax error
# would only surface at the moment someone tries to change what can
# merge across nine repos, which is the worst possible time to find it.
- name: Every ruleset is valid JSON with the fields the API requires
run: |
set -euo pipefail
for f in github-rulesets/*.json; do
echo "checking $f"
python3 - "$f" <<'PY'
import json, sys
path = sys.argv[1]
with open(path) as fh:
data = json.load(fh)
for key in ("name", "target", "enforcement", "conditions", "rules"):
if key not in data:
sys.exit(f"{path}: missing required key {key!r}")
if data["target"] not in ("branch", "tag", "push"):
sys.exit(f"{path}: unexpected target {data['target']!r}")
PY
done

secrets:
name: secret scan
uses: ./.github/workflows/reusable-gitleaks.yml
Loading