diff --git a/CLAUDE.md b/CLAUDE.md index de15a38..09255e8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -57,9 +57,11 @@ if it's clean, push a fresh commit to force GitHub to recompute the merge ref. ## Workflow Planning follows the convention in [`planning/README.md`](planning/README.md) — -its **Quick path** is authoritative. Pick a lane (Full = `design.md` + `plan.md`, -Lightweight = `change.md`, Tiny = conventional commit), create a bundle under -`planning/changes/YYYY-MM-DD.NN-/` from `planning/_templates/`, and run +its **Quick path** is authoritative. Pick a lane (Full = a change file from the +design template, Lightweight = a change file from the change template, Tiny = +conventional commit), create the change file at +`planning/changes/YYYY-MM-DD.NN-.md` from `planning/_templates/`, keep the +executor's plan in git-ignored scratch (`.superpowers/`), and run `just check-planning` before pushing. The applied convention version is in `planning/.convention-version`; update it via the canonical repo's `APPLY.md`. @@ -68,5 +70,5 @@ Lightweight = `change.md`, Tiny = conventional commit), create a bundle under `architecture/` (repo root) is the living truth about what this repo does now — one file per capability plus `glossary.md`, no frontmatter, authored lazily. **When a change alters a capability's behavior, update the matching -`architecture/.md` in the same PR.** The change bundle in +`architecture/.md` in the same PR.** The change file in `planning/changes/` stays as the *why*. diff --git a/architecture/README.md b/architecture/README.md index 5485b7c..d801d7b 100644 --- a/architecture/README.md +++ b/architecture/README.md @@ -6,7 +6,7 @@ language). These files carry **no frontmatter** and are dated by git. **Promotion rule:** when a change alters a capability's behavior, hand-edit the matching `architecture/.md` in the **same PR** as the code — the edit -rides in the same diff and is reviewed with it. The change bundle in +rides in the same diff and is reviewed with it. The change file in `planning/changes/` stays as the *why*; this directory stays *true*. Capability files and `glossary.md` are authored **lazily** — each appears when the diff --git a/planning/.convention-version b/planning/.convention-version index 524cb55..227cea2 100644 --- a/planning/.convention-version +++ b/planning/.convention-version @@ -1 +1 @@ -1.1.1 +2.0.0 diff --git a/planning/README.md b/planning/README.md index 4797e51..164786a 100644 --- a/planning/README.md +++ b/planning/README.md @@ -3,7 +3,7 @@ This repo's planning home, following the portable two-axis convention from [`lesnik512/planning-convention`](https://github.com/lesnik512/planning-convention) (applied version in [`.convention-version`](.convention-version)). `architecture/` -(repo root) holds the living truth about what the system does now; the bundles in +(repo root) holds the living truth about what the system does now; the change files in [`changes/`](changes/) record how it got there. To update the convention itself, re-run that repo's `APPLY.md` flow. @@ -15,25 +15,22 @@ re-run that repo's `APPLY.md` flow. **1. Choose a lane — first matching rule wins:** 1. Any of: needs design judgment · new file/module · public-API change · - cross-cutting or multi-file · non-trivial test design → **Full** - (`design.md` + `plan.md`) + cross-cutting or multi-file · non-trivial test design → **Full** (design template) 2. Purely mechanical: typo · dep bump · linter/formatter/CI tweak · - mechanical rename · single-line config → **Tiny** (no bundle, conventional + mechanical rename · single-line config → **Tiny** (no change file, conventional commit) 3. Small-but-real, none of the above: ≲30 LOC net · ≤2 files · no new file · - no public-API change · one straightforward test → **Lightweight** - (`change.md`) + no public-API change · one straightforward test → **Lightweight** (change template) -Ambiguous between two? Take the heavier. A `change.md` that outgrows its lane -splits into `design.md` + `plan.md`. +Ambiguous between two? Take the heavier. A lightweight change file that outgrows its lane is rewritten from the design template. -**2. Create the bundle** (Full / Lightweight only): -`planning/changes/YYYY-MM-DD.NN-/`, where `.NN` is a zero-padded -intra-day counter. Copy the matching template from +**2. Create the change file** (Full / Lightweight only): +`planning/changes/YYYY-MM-DD.NN-.md`, where `.NN` is a zero-padded +intra-day counter — copied from the matching template (design or change) in [`_templates/`](_templates/). **3. Ship in the implementing PR:** hand-edit the affected -`architecture/.md`, finalize the bundle's `summary:` to the +`architecture/.md`, finalize the change file's `summary:` to the realized result, and run `just check-planning` before pushing. ## Conventions @@ -49,14 +46,14 @@ realized result, and run `just check-planning` before pushing. - **`architecture/` (repo root) — the present.** One file per capability, plus a single `glossary.md` (the ubiquitous language); living prose, updated in the same PR that ships the change. The truth home. -- **`planning/changes/` — the past-and-pending.** One folder per change, +- **`planning/changes/` — the past-and-pending.** One file per change, kept in place after ship. A change **promotes** its conclusions into the affected `architecture/.md` by hand **in the implementing PR, alongside the code** — the edit rides in the same diff and is reviewed with it, never applied as a separate post-merge step. That hand-edit is what keeps `architecture/` -true; the bundle stays in `changes/` as the *why*. +true; the change file stays in `changes/` as the *why*. ### Glossary @@ -78,9 +75,9 @@ Keep it a glossary, not a spec — no implementation detail. A change that introduces or sharpens a term updates `glossary.md` in the same PR, the same way a behavior change promotes into a capability file. -### Change bundles +### Change files -A change is a folder `changes/YYYY-MM-DD.NN-/`: +A change is a file `changes/YYYY-MM-DD.NN-.md`: - `YYYY-MM-DD` — proposal date; `.NN` — zero-padded intra-day counter (`.01`, `.02`, …) that breaks same-date ties so the timeline sorts stably. @@ -89,25 +86,44 @@ A change is a folder `changes/YYYY-MM-DD.NN-/`: `summary` is written when the change is created (the intent one-liner) and **finalized at ship** to state the realized result — set in the implementing PR, alongside the code and the `architecture/` promotion. No post-merge -bookkeeping, no folder move. `date` and `slug` are never written — they are -read from the bundle's directory name. +bookkeeping, no file move. `date` and `slug` are never written — they are +read from the file name. ### Three lanes | Lane | Artifacts | Use when | |------|-----------|----------| -| **Full** | `design.md` + `plan.md` | design judgment; new file/module; public-API change; cross-cutting/multi-file; non-trivial test design | -| **Lightweight** | `change.md` | small-but-real: ≲30 LOC net, ≤2 files, no new file, no public-API change, single straightforward test | +| **Full** | one change file from the design template | design judgment; new file/module; public-API change; cross-cutting/multi-file; non-trivial test design | +| **Lightweight** | one change file from the change template | small-but-real: ≲30 LOC net, ≤2 files, no new file, no public-API change, single straightforward test | | **Tiny** | none — conventional commit | typo, dep bump, linter/formatter/CI tweak, mechanical rename, single-line config | -Heavier lane wins on ambiguity. A `change.md` that outgrows its lane splits -into `design.md` + `plan.md`. +Heavier lane wins on ambiguity. A lightweight change file that outgrows its lane is rewritten from the design template. + +### Plans are ephemeral + +The executable plan — task checklists, embedded code, commit sequences, +whatever the executor needs — is a working artifact, not history. Keep it out +of `changes/` and out of version control (git-ignored scratch, e.g. +`.superpowers/`). Once the change ships, the diff and the PR are the record +of execution; a committed plan duplicates them. `check-planning` rejects +anything in `changes/` that is not a flat change file. + +### Lean specs + +The change file is the single home of a change's rationale: + +- The PR body summarizes and links to the change file — it never restates it. +- Rejected alternatives live in `decisions/` and are referenced, not retold. +- Show a sketch when the design needs code; never the full diff-to-be. +- Delete template sections that don't apply — an empty section is ceremony. +- Most designs fit well under ~700 words; length must buy information. ### Artifacts at a glance -- **`design.md`** — the spec: the *thinking* (why, design, trade-offs, scope). -- **`plan.md`** — the plan: the *sequencing* (the executor's task checklist). -- **`change.md`** — both, condensed, for the lightweight lane. +- **design template** — the spec: the *thinking* (why, design, trade-offs, + scope); the change file it produces is the single home of rationale (see + [Lean specs](#lean-specs)). +- **change template** — the condensed spec for the lightweight lane. - **`releases/.md`** — per-release user-facing notes. - **`audits/-.md`** — findings from a code/docs/bug-hunt sweep; spawns fix changes. @@ -121,11 +137,10 @@ Templates live in [`_templates/`](_templates/). ### Frontmatter -`date` and `slug` are **derived from the directory / file name** — never +`date` and `slug` are **derived from the file name** — never repeated in frontmatter. So: -- `design.md` / `change.md`: `summary` (single line) only. -- `plan.md`: **no frontmatter** — its identity is the bundle directory. +- `changes/*.md`: `summary` (single line) only. - `decisions/*.md`: `status` (accepted|superseded), `summary`, and optional `supersedes` / `superseded_by`. - Files in `architecture/` carry **no** frontmatter — living prose, dated by git. diff --git a/planning/_templates/change.md b/planning/_templates/change.md index d4c8962..5aa7e81 100644 --- a/planning/_templates/change.md +++ b/planning/_templates/change.md @@ -5,8 +5,8 @@ summary: One line — shown in the generated index. Written at creation; finaliz # Change: One-line capitalized title **Lane:** lightweight — ≲30 LOC net, ≤2 files, no new file, no public-API -change, a single straightforward test. If it outgrows this, split into -`design.md` + `plan.md`. +change, a single straightforward test. If it outgrows this, rewrite it from +the design template. ## Goal diff --git a/planning/_templates/design.md b/planning/_templates/design.md index d63e22d..17dbee1 100644 --- a/planning/_templates/design.md +++ b/planning/_templates/design.md @@ -4,6 +4,10 @@ summary: One line — shown in the generated index. Written at creation; finaliz # Design: One-line capitalized title + + ## Summary One paragraph. What changes, at the level a reader needs to decide if this @@ -12,37 +16,23 @@ spec is worth reading in full. ## Motivation Why now. What is broken or missing. Concrete observations / numbers, not -abstract complaints. Link to memory entries or earlier specs when relevant. - -## Non-goals - -What is deliberately out of scope and (when nontrivial) why. Each item is -a sentence; one line each. +abstract complaints. ## Design -### 1. - What changes, in enough detail that a reader who has not seen the codebase -can follow. Code samples / diagrams welcome. +can follow. Sketches and interface fragments welcome; never the full +diff-to-be. Reference rejected alternatives in `decisions/` instead of +retelling them. -### 2. - -... - -## Operations - -Out-of-repo steps (DNS, infra, external account changes). Omit if none. - -## Out of scope +## Non-goals -Already covered above under Non-goals if appropriate. Repeat-list of -explicitly-excluded follow-ups belongs here when the list is long. +What is deliberately out of scope and (when nontrivial) why. One line each. ## Testing -How we know it landed correctly. New pytest? Smoke check on live URL? -Lint pass? Be specific. +How we know it landed correctly. Be specific: the command and the expected +signal. ## Risk diff --git a/planning/_templates/plan.md b/planning/_templates/plan.md deleted file mode 100644 index 132d720..0000000 --- a/planning/_templates/plan.md +++ /dev/null @@ -1,46 +0,0 @@ -# — implementation plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use -> superpowers:subagent-driven-development (recommended) or -> superpowers:executing-plans to implement this plan task-by-task. Steps -> use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** One sentence — what shipping this plan achieves. No design -rationale; link to the spec for that. - -**Spec:** [`design.md`](./design.md) - -**Branch:** `feat/my-change` (or `fix/`, `chore/`, etc.) - -**Commit strategy:** Per-task commits / single commit / squash on merge. -Whichever fits. - ---- - -### Task 1: - -**Files:** -- Modify: `path/to/file.py` -- Create: `path/to/new.py` - -One sentence on what this task accomplishes. No deeper reasoning — that's -in the spec. - -- [ ] **Step 1: ** - - Run / edit / verify command. Expected output. - -- [ ] **Step 2: ** - - ... - -- [ ] **Step 3: Commit** - - ```bash - git add path/to/file.py - git commit -m ": " - ``` - ---- - -### Task 2: ... diff --git a/planning/changes/2026-06-24.01-promotion-strategy/design.md b/planning/changes/2026-06-24.01-promotion-strategy.md similarity index 100% rename from planning/changes/2026-06-24.01-promotion-strategy/design.md rename to planning/changes/2026-06-24.01-promotion-strategy.md diff --git a/planning/changes/2026-06-24.02-org-community-health-defaults/change.md b/planning/changes/2026-06-24.02-org-community-health-defaults.md similarity index 100% rename from planning/changes/2026-06-24.02-org-community-health-defaults/change.md rename to planning/changes/2026-06-24.02-org-community-health-defaults.md diff --git a/planning/changes/2026-06-24.02-org-community-health-defaults/plan.md b/planning/changes/2026-06-24.02-org-community-health-defaults/plan.md deleted file mode 100644 index e758333..0000000 --- a/planning/changes/2026-06-24.02-org-community-health-defaults/plan.md +++ /dev/null @@ -1,709 +0,0 @@ -# Org Community-Health Defaults Implementation Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Add org-wide default community-health files to the `modern-python/.github` repo so every repo in the org that lacks its own gets a CONTRIBUTING guide, Code of Conduct, security policy, support routing, issue/PR templates, and funding config — lifting community-health coverage from ~25% to ~90% org-wide in one PR. - -**Architecture:** GitHub serves *default* community-health files from a special `.github` repo in the org. Files placed at the **root** or in **`.github/`** of `modern-python/.github` apply to every repo in the org that does not define its own. This repo also builds the public website from `docs/` via MkDocs, so community-health files must go at the repo root or under `.github/` — **never under `docs/`**, which would publish them to the site. No code, no tests in the traditional sense; each task ends with a concrete verification (YAML parses, MkDocs still builds, file lands at a path GitHub recognizes). - -**Tech Stack:** GitHub community-health defaults, GitHub issue *forms* (YAML schema), Markdown, MkDocs Material (existing site build), `uv` (runs the build). - -## Global Constraints - -- **Repo:** this is `modern-python/.github`. Default community-health files here apply org-wide. Place them at the repo **root** or in **`.github/`** only — never in `docs/` (that directory is the published MkDocs site). -- **Branch:** do this work on a dedicated branch `chore/org-community-health`, cut from `main` (NOT stacked on `docs/promotion-strategy`). One PR. -- **Brand casing (verbatim):** `modern-di`, `that-depends`, `Litestar` (never "LiteStar"), `FastStream`, `FastAPI`, `Typer`, `SQLAlchemy`, `PostgreSQL`. -- **Tooling vocabulary:** projects use `uv` (packaging), `ruff` (lint/format), `ty` (type check), `uv_build` (build backend); most repos expose tasks behind a `justfile`. -- **Security & CoC contact:** use GitHub **private vulnerability reporting** (repo/org → Security → "Report a vulnerability"). Do **not** invent or publish a personal email address. -- **Org Discussions URL:** `https://github.com/orgs/modern-python/discussions` (org-level Discussions must be enabled — see Task 8 manual step). -- **Docs site:** `https://modern-python.org`. -- **Commit footer (every commit):** - ``` - Co-Authored-By: Claude Opus 4.8 (1M context) - ``` -- **No "Generated with Claude Code" lines in commits** (org convention). - ---- - -## File Structure - -Files created (all in `modern-python/.github`): - -``` -.github/ - ISSUE_TEMPLATE/ - bug_report.yml # bug issue form - feature_request.yml # feature issue form - config.yml # disable blank issues; route questions to Discussions/docs - PULL_REQUEST_TEMPLATE.md # default PR template - FUNDING.yml # sponsor button config (optional input) -CONTRIBUTING.md # org-wide contributor guide (root) -CODE_OF_CONDUCT.md # Contributor Covenant 2.1 (root) -SECURITY.md # vulnerability reporting policy (root) -SUPPORT.md # where to get help (root) -``` - -Modified: - -``` -docs/index.md # fix "LiteStar" -> "Litestar" casing (lines ~60, ~66) -``` - ---- - -## Task 1: Issue forms + PR template - -**Files:** -- Create: `.github/ISSUE_TEMPLATE/bug_report.yml` -- Create: `.github/ISSUE_TEMPLATE/feature_request.yml` -- Create: `.github/ISSUE_TEMPLATE/config.yml` -- Create: `.github/PULL_REQUEST_TEMPLATE.md` - -**Interfaces:** -- Produces: org-default issue chooser (Bug / Feature) plus two contact links (Discussions, Docs); a default PR template. Consumed by GitHub's new-issue and new-PR UI on every org repo without its own templates. - -- [ ] **Step 1: Create the bug report form** - -Create `.github/ISSUE_TEMPLATE/bug_report.yml`: - -```yaml -name: Bug report -description: Report a defect in a modern-python project -labels: ["bug"] -body: - - type: markdown - attributes: - value: | - Thanks for filing a bug. Fill in the sections below so we can reproduce it quickly. - - type: input - id: project - attributes: - label: Affected project - description: Which repository / package is this about? - placeholder: e.g. modern-di, that-depends, httpware - validations: - required: true - - type: input - id: version - attributes: - label: Versions - description: Package version, Python version, and OS. - placeholder: e.g. modern-di 1.2.0, Python 3.12, macOS 14 - validations: - required: true - - type: textarea - id: what-happened - attributes: - label: What happened? - description: A clear description of the bug and what you expected instead. - validations: - required: true - - type: textarea - id: repro - attributes: - label: Minimal reproduction - description: The smallest snippet or steps that reproduce the problem. - render: python - validations: - required: true - - type: textarea - id: logs - attributes: - label: Logs / traceback - description: Paste any relevant traceback. Automatically formatted as code. - render: shell - validations: - required: false -``` - -- [ ] **Step 2: Create the feature request form** - -Create `.github/ISSUE_TEMPLATE/feature_request.yml`: - -```yaml -name: Feature request -description: Suggest an idea or improvement for a modern-python project -labels: ["enhancement"] -body: - - type: input - id: project - attributes: - label: Target project - description: Which repository / package would this affect? - placeholder: e.g. modern-di, lite-bootstrap - validations: - required: true - - type: textarea - id: problem - attributes: - label: Problem - description: What problem are you trying to solve? What's the use case? - validations: - required: true - - type: textarea - id: proposal - attributes: - label: Proposed solution - description: What would you like to happen? Include API sketches if relevant. - validations: - required: true - - type: textarea - id: alternatives - attributes: - label: Alternatives considered - description: Other approaches you've weighed, if any. - validations: - required: false -``` - -- [ ] **Step 3: Create the issue chooser config** - -Create `.github/ISSUE_TEMPLATE/config.yml`: - -```yaml -blank_issues_enabled: false -contact_links: - - name: Question / usage help - url: https://github.com/orgs/modern-python/discussions - about: Ask questions and get help in GitHub Discussions. - - name: Documentation - url: https://modern-python.org - about: Browse the docs — your question may already be answered. -``` - -- [ ] **Step 4: Create the PR template** - -Create `.github/PULL_REQUEST_TEMPLATE.md`: - -```markdown -## Summary - - - -## Changes - - -- - -## Checklist - -- [ ] Lint and format pass (`ruff`) -- [ ] Type check passes (`ty`) -- [ ] Tests pass and new behavior is covered -- [ ] Docs updated if behavior or public API changed -- [ ] Repo metadata stays consistent across the three surfaces (GitHub description, pyproject `description`, profile blurb) if this touches packaging -``` - -- [ ] **Step 5: Verify the YAML parses** - -Run: -```bash -python -c "import yaml; [yaml.safe_load(open(f)) for f in ['.github/ISSUE_TEMPLATE/bug_report.yml','.github/ISSUE_TEMPLATE/feature_request.yml','.github/ISSUE_TEMPLATE/config.yml']]; print('YAML OK')" -``` -Expected: `YAML OK` (no traceback). - -- [ ] **Step 6: Commit** - -```bash -git add .github/ISSUE_TEMPLATE .github/PULL_REQUEST_TEMPLATE.md -git commit -m "chore: add org-default issue forms and PR template - -Co-Authored-By: Claude Opus 4.8 (1M context) " -``` - ---- - -## Task 2: CONTRIBUTING.md - -**Files:** -- Create: `CONTRIBUTING.md` (repo root) - -**Interfaces:** -- Produces: the "Contributing" link GitHub surfaces on every org repo's new-issue/new-PR pages and the repo sidebar. - -- [ ] **Step 1: Create CONTRIBUTING.md** - -Create `CONTRIBUTING.md`: - -```markdown -# Contributing to Modern Python - -Thanks for your interest in contributing! These guidelines apply across all -repositories in the [`modern-python`](https://github.com/modern-python) org -unless a repository overrides them with its own `CONTRIBUTING.md`. - -## Ways to contribute - -- **Report bugs** and **request features** via the issue templates. -- **Ask questions** in [GitHub Discussions](https://github.com/orgs/modern-python/discussions). -- **Improve docs** — typo fixes and clarifications are very welcome. -- **Send pull requests** — see the workflow below. - -## Development setup - -Projects use [`uv`](https://github.com/astral-sh/uv) for packaging, -[`ruff`](https://github.com/astral-sh/ruff) for lint/format, -[`ty`](https://github.com/astral-sh/ty) for type checking, and `uv_build` as the -build backend. Most repos expose tasks behind a `justfile`. - -```bash -# Clone your fork, then from the repo root: -uv sync # install dependencies into a local venv -just --list # see available tasks (lint, test, etc.) where a justfile exists -``` - -## Pull request workflow - -1. Fork the repository and create a topic branch from `main`. -2. Make your change. Keep it focused — one logical change per PR. -3. Run lint, type check, and tests locally before pushing: - ```bash - uv run ruff check . && uv run ruff format --check . - uv run ty check - # run the project's test command (often `just test` or `uv run pytest`) - ``` -4. Update docs if you changed behavior or public API. -5. Open the PR using the template. Link the issue it resolves. - -## CI note - -GitHub occasionally type-checks a stale `refs/pull//merge` after a push, so a -PR can show an old lint/test failure that no longer matches the branch. Confirm -by running the failing check locally at the branch HEAD with the pinned tool -version; if it's clean, push a fresh commit to force GitHub to recompute the -merge ref. - -## Code of Conduct - -By participating you agree to abide by our -[Code of Conduct](CODE_OF_CONDUCT.md). -``` - -- [ ] **Step 2: Verify brand casing** - -Run: -```bash -grep -n "LiteStar" CONTRIBUTING.md || echo "casing OK" -``` -Expected: `casing OK`. - -- [ ] **Step 3: Commit** - -```bash -git add CONTRIBUTING.md -git commit -m "docs: add org-wide CONTRIBUTING guide - -Co-Authored-By: Claude Opus 4.8 (1M context) " -``` - ---- - -## Task 3: CODE_OF_CONDUCT.md - -**Files:** -- Create: `CODE_OF_CONDUCT.md` (repo root) - -**Interfaces:** -- Produces: the Code of Conduct GitHub links from every org repo; referenced by `CONTRIBUTING.md` and `SECURITY.md`. - -- [ ] **Step 1: Create CODE_OF_CONDUCT.md (Contributor Covenant 2.1)** - -Create `CODE_OF_CONDUCT.md` with the Contributor Covenant 2.1 text below. The -enforcement-contact paragraph is customized to use GitHub's private reporting -(no email is published). - -```markdown -# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, caste, color, religion, or sexual -identity and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our -community include: - -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -* Focusing on what is best not just for us as individuals, but for the overall - community - -Examples of unacceptable behavior include: - -* The use of sexualized language or imagery, and sexual attention or advances of - any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email address, - without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, and will communicate reasons for moderation -decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official email address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement through GitHub's -private reporting (open the relevant repository's **Security** tab and choose -**Report a vulnerability**, which routes confidentially to the maintainers) or -by privately contacting a maintainer. All complaints will be reviewed and -investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the -reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series of -actions. - -**Consequence**: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or permanent -ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including -sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within the -community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 2.1, available at -[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. - -Community Impact Guidelines were inspired by -[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. - -For answers to common questions about this code of conduct, see the FAQ at -[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at -[https://www.contributor-covenant.org/translations][translations]. - -[homepage]: https://www.contributor-covenant.org -[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html -[Mozilla CoC]: https://github.com/mozilla/diversity -[FAQ]: https://www.contributor-covenant.org/faq -[translations]: https://www.contributor-covenant.org/translations -``` - -- [ ] **Step 2: Commit** - -```bash -git add CODE_OF_CONDUCT.md -git commit -m "docs: add Contributor Covenant Code of Conduct - -Co-Authored-By: Claude Opus 4.8 (1M context) " -``` - ---- - -## Task 4: SECURITY.md + SUPPORT.md - -**Files:** -- Create: `SECURITY.md` (repo root) -- Create: `SUPPORT.md` (repo root) - -**Interfaces:** -- Produces: the "Security policy" and "Support" links GitHub surfaces org-wide. SECURITY.md is referenced by the CoC enforcement channel. - -- [ ] **Step 1: Create SECURITY.md** - -Create `SECURITY.md`: - -```markdown -# Security Policy - -## Reporting a vulnerability - -Please **do not** open a public issue for security problems. - -Report vulnerabilities privately using GitHub's built-in private reporting: -open the affected repository's **Security** tab and choose -**"Report a vulnerability"**. This routes confidentially to the maintainers. - -Please include: - -- the affected project and version, -- a description of the vulnerability and its impact, -- steps to reproduce or a proof of concept, if available. - -We aim to acknowledge reports within a few days and will keep you informed as we -investigate and prepare a fix. Once a fix is released, we're happy to credit you -in the release notes unless you prefer to remain anonymous. - -## Supported versions - -Unless a repository states otherwise, security fixes target the **latest -released version** on PyPI. Upgrading to the latest release is the recommended -way to receive fixes. -``` - -- [ ] **Step 2: Create SUPPORT.md** - -Create `SUPPORT.md`: - -```markdown -# Support - -Need help with a `modern-python` project? Here's where to go: - -- **Documentation:** start at [modern-python.org](https://modern-python.org) and - the project's own docs site (linked from each repo). -- **Questions & usage help:** ask in - [GitHub Discussions](https://github.com/orgs/modern-python/discussions). -- **Bugs & feature requests:** open an issue in the relevant repository using the - provided templates. -- **Security issues:** see [SECURITY.md](SECURITY.md) — please report privately, - not in a public issue. - -Please search existing issues and discussions before opening a new one — your -question may already be answered. -``` - -- [ ] **Step 3: Verify casing across both files** - -Run: -```bash -grep -n "LiteStar" SECURITY.md SUPPORT.md || echo "casing OK" -``` -Expected: `casing OK`. - -- [ ] **Step 4: Commit** - -```bash -git add SECURITY.md SUPPORT.md -git commit -m "docs: add org-wide security policy and support routing - -Co-Authored-By: Claude Opus 4.8 (1M context) " -``` - ---- - -## Task 5: FUNDING.yml (optional — needs one input) - -**Files:** -- Create: `.github/FUNDING.yml` - -**Interfaces:** -- Produces: the org-wide "Sponsor" button. **Requires one human input:** the GitHub Sponsors handle (or other funding platform). If the maintainer does not want a sponsor button, **skip this task entirely** and note the skip. - -- [ ] **Step 1: Decide** - -If the maintainer wants a sponsor button, get the GitHub Sponsors username (e.g. `lesnik512`) or other platform handle. If not, skip to "Commit (skip)" below and do not create the file. - -- [ ] **Step 2: Create FUNDING.yml (only if a handle was provided)** - -Create `.github/FUNDING.yml`, replacing `` with the real handle: - -```yaml -# Org-wide funding sources. Uncomment and fill the platforms you use. -github: [] -# ko_fi: -# custom: ["https://modern-python.org"] -``` - -- [ ] **Step 3: Verify YAML parses (only if created)** - -Run: -```bash -python -c "import yaml; yaml.safe_load(open('.github/FUNDING.yml')); print('YAML OK')" -``` -Expected: `YAML OK`. - -- [ ] **Step 4: Commit (or record skip)** - -If created: -```bash -git add .github/FUNDING.yml -git commit -m "chore: add org-wide funding config - -Co-Authored-By: Claude Opus 4.8 (1M context) " -``` -If skipped: no commit; note "FUNDING.yml skipped — no sponsor handle" in the PR description. - ---- - -## Task 6: Fix Litestar casing in docs/index.md - -**Files:** -- Modify: `docs/index.md` (the two `LiteStar` occurrences, ~lines 60 and 66) - -**Interfaces:** -- Produces: brand-consistent docs landing page. Independent of the community-health files; rides along in this PR as Phase 0 hygiene. - -- [ ] **Step 1: Confirm the occurrences** - -Run: -```bash -grep -n "LiteStar" docs/index.md -``` -Expected: two lines (the `litestar-sqlalchemy-template` description and the `modern-di-litestar` line). - -- [ ] **Step 2: Fix the casing** - -Replace both `LiteStar` with `Litestar` in `docs/index.md`. After editing, run: -```bash -grep -n "LiteStar" docs/index.md || echo "casing OK" -``` -Expected: `casing OK`. - -- [ ] **Step 3: Commit** - -```bash -git add docs/index.md -git commit -m "docs: fix Litestar casing on the landing page - -Co-Authored-By: Claude Opus 4.8 (1M context) " -``` - ---- - -## Task 7: Verify the site still builds - -**Files:** none (verification only) - -**Interfaces:** -- Consumes: all files added above. Confirms the root/`.github` community-health files do not leak into or break the published MkDocs site (which builds only from `docs/`). - -- [ ] **Step 1: Build the docs site** - -Run: -```bash -uv run mkdocs build --strict -``` -Expected: build succeeds; output in `site/`. No errors. (Root-level `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, etc. are outside `docs/` and must NOT appear in `site/`.) - -- [ ] **Step 2: Confirm community files did not get published** - -Run: -```bash -ls site/CONTRIBUTING* site/CODE_OF_CONDUCT* 2>/dev/null && echo "LEAK — investigate" || echo "no leak" -``` -Expected: `no leak`. - ---- - -## Task 8: Open the PR (+ manual org settings) - -**Files:** none (integration + PR) - -**Interfaces:** -- Consumes: the full branch. Produces the PR that ships org-wide defaults. - -- [ ] **Step 1: Push the branch** - -```bash -git push -u origin chore/org-community-health -``` - -- [ ] **Step 2: Open the PR** - -```bash -gh pr create --title "chore: add org-wide community-health defaults" --body "$(cat <<'EOF' -Adds default community-health files to the org \`.github\` repo so every repo -without its own inherits them: CONTRIBUTING, Code of Conduct (Contributor -Covenant 2.1), SECURITY (private vulnerability reporting), SUPPORT, issue forms -(bug/feature) + chooser, PR template, and FUNDING. Also fixes \`Litestar\` -casing on the docs landing page. - -Implements Phase 0 (foundation hygiene) of the promotion strategy -(\`../2026-06-24.01-promotion-strategy/design.md\`). - -Note: org-level Discussions must be enabled for the issue-chooser "Question" -contact link to resolve (see manual step). - -🤖 Generated with [Claude Code](https://claude.com/claude-code) -EOF -)" -``` - -- [ ] **Step 3: Manual org settings (maintainer action — record in PR)** - -These are GitHub UI actions the maintainer performs; note them in the PR as a checklist: -- Enable **org-level Discussions**: Org → Settings → Discussions (so the issue-chooser "Question" link resolves). Pick a source repo if prompted. -- Confirm the new defaults appear on a repo that has none (e.g. open the new-issue page on `db-retry` — it should show the Bug/Feature chooser). - -- [ ] **Step 4: Verify defaults propagate** - -After merge, run: -```bash -gh api repos/modern-python/db-retry/community/profile --jq '.health_percentage' -``` -Expected: a value well above the pre-change ~25% (the inherited CoC/Contributing/Security/templates count toward the score). - ---- - -## Self-Review - -**Spec coverage (Phase 0 portion):** -- Org-wide `.github` defaults — Tasks 1–5 (CONTRIBUTING, CoC, SECURITY, SUPPORT, ISSUE_TEMPLATE, PR template, FUNDING). ✅ -- `LiteStar`→`Litestar` casing in `docs/index.md` — Task 6. ✅ -- Enable Discussions — Task 8 manual step. ✅ -- **Deferred to later plans (not in this plan, by design):** cross-repo PyPI metadata fixes (`that-depends`, `db-retry`, `eof-fixer`, `faststream-redis-timers`), the `faststream-outbox` readthedocs link, and all Phase 1/2 positioning + README content (those repos aren't in this workspace, and positioning is gated on Phase 1 research + maintainer sign-off). These become **Plan 2 (metadata hygiene sweep)** and **Plan 3 (positioning + READMEs)**. - -**Placeholder scan:** The only intentional human input is the FUNDING.yml handle (Task 5), explicitly gated with a skip path — not a silent placeholder. No "TBD"/"handle edge cases"/"similar to" anywhere; every file's full content is inline. - -**Type/name consistency:** File paths are consistent throughout (`.github/ISSUE_TEMPLATE/`, root-level docs). Cross-references resolve: `CONTRIBUTING.md`→`CODE_OF_CONDUCT.md`; `SUPPORT.md`→`SECURITY.md`; CoC enforcement→private reporting (matches `SECURITY.md`). Org Discussions URL identical in config.yml, CONTRIBUTING, SUPPORT. diff --git a/planning/changes/2026-06-27.01-community-channels/design.md b/planning/changes/2026-06-27.01-community-channels.md similarity index 100% rename from planning/changes/2026-06-27.01-community-channels/design.md rename to planning/changes/2026-06-27.01-community-channels.md diff --git a/planning/changes/2026-06-28.01-org-favicon-social-card/design.md b/planning/changes/2026-06-28.01-org-favicon-social-card.md similarity index 100% rename from planning/changes/2026-06-28.01-org-favicon-social-card/design.md rename to planning/changes/2026-06-28.01-org-favicon-social-card.md diff --git a/planning/changes/2026-06-28.01-org-favicon-social-card/plan.md b/planning/changes/2026-06-28.01-org-favicon-social-card/plan.md deleted file mode 100644 index 01a922d..0000000 --- a/planning/changes/2026-06-28.01-org-favicon-social-card/plan.md +++ /dev/null @@ -1,714 +0,0 @@ -# Org Favicon + Social Card Implementation Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Replace the org's snake-based brand mark with the approved pinwheel icon (favicon/avatar) and Jost wordmark social card, generated by the `brand/build/` Python toolchain. - -**Architecture:** A small deterministic generator. `tokens.py` holds the palette; `text.py` outlines Jost glyphs to SVG paths (so assets render without the font); `geometry.py` emits the icon, favicon, wordmark lockup and card compositions as concrete-color SVG strings; `render.py` writes every SVG to `brand/org/` and rasterizes PNGs via `rsvg-convert`. The old snake system (geometry/render/tokens, `brand/projects/**`, stale `brand/org/*`) is removed. - -**Tech Stack:** Python 3.11+, `fonttools` (glyph outlining + variable-font instancing), `rsvg-convert` (librsvg) for PNGs, `pytest`, `ty`, `uv`. Font: **Jost** (SIL OFL). - -## Global Constraints - -- **Palette (exact hex):** Green-ink `#356852`, Green-surface `#2f5e4a`, Gold-light `#c98a00`, Gold-dark `#f0b528`, Cream `#f4f1e8`. -- **Two-color pairing:** top-left snake + `MODERN` use the structure color (green `#356852` on cream / cream `#f4f1e8` on green); bottom-right snake + `PYTHON` use gold (`#c98a00` on cream / `#f0b528` on green). -- **Fixed copy:** wordmark is always `MODERN` / `PYTHON` (two lines); card URL is always `modern-python.org`; **no tagline**. -- **Typeface:** Jost weight 400, **outlined to SVG paths** at build time (assets must render with no font installed). Jost + its OFL license vendored under `brand/build/fonts/`. -- **Lockup geometry is authoritative** (540×250 space): snakes `M138 122 L138 50 L210 50` (struct) and `M402 128 L402 200 L330 200` (gold), stroke 8, `butt`/`miter`; heads `rect 202.5,42.5,15,15 rx3` and `322.5,192.5,15,15 rx3`; `MODERN` baseline 126, `PYTHON` baseline 166 (gap 40), both size 50, centered x=270, **`fit_width=210`**. -- **Card composition (1280×640):** `` bg, then the lockup embedded `translate(235,108) scale(1.5)`, then URL outlined at x=640 baseline 575 size 34. **Square (640×640):** lockup `translate(50,195)`, no URL. -- **Icon (100×100):** standard — snakes `M30 60 L30 30 L60 30` / `M70 40 L70 70 L40 70` stroke 8, heads `54.5,24.5,11,11 rx2` / `34.5,64.5,11,11 rx2`, core `circle 50,50 r6`, `rx20`. Favicon (bold) — snakes `M26 66 L26 26 L66 26` / `M74 34 L74 74 L34 74` stroke 11, heads `58,20,14,14 rx2` / `28,66,14,14 rx2`, core `r7`, `rx18`. All on green surface: bg `#2f5e4a`, struct `#f4f1e8`, gold/core `#f0b528`. -- **No CSS variables** — every emitted SVG uses concrete colors (no `var()`, no `