Skip to content

QEP-3: Repository Naming and Types - #7

Draft
mmcky wants to merge 2 commits into
mainfrom
qep-0003
Draft

QEP-3: Repository Naming and Types#7
mmcky wants to merge 2 commits into
mainfrom
qep-0003

Conversation

@mmcky

@mmcky mmcky commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

QEP-3: Repository Naming and Types — Draft for review

Decision deadline: 2026-07-24 (two-week comment window per QEP-1; Core Maintainers decide by lazy consensus at the deadline).

This QEP makes the org's repository namespace a decided standard, exactly parallel to QEP-2 for the label namespace. It was prompted by a real placement question (where should the translation-progress dashboard live?) and by a survey of the full org: of ~245 non-archived repositories, only ~40% follow a documented convention, and the largest family — teaching events, ~55 repos — has no convention at all, in at least eight naming styles.

What it decides

  • Grammar: a dash prefix encodes a repo's type (status-translations); a dot suffix encodes a variant of the same content (.notebooks, .zh-cn, .public). Dots are reserved for variants — new members of the dotted legacy families (audit., benchmark., project.) use dash forms.
  • A normative type registry: content types (lecture-, book-), the four operational types with their verbs (project-* decides / workspace-* operates / workflow-* automates / status-* measures) and their boundary rules (numbers vs narrative; goal vs fleet), plus supporting types (test-, template-, contractor-, audit-, benchmark-).
  • Teaching events get the missing convention: workshop-{name}-{yyyy}, course-{name}-{yyyy}, conference-{name}-{yyyy}, frozen and archived after the event.
  • Exemptions: published packages and forks keep their ecosystem names (QuantEcon.py, GameTheory.jl, mystmd); deployed sites are named by domain (atlas.quantecon.org).
  • Migration & archival policy: new repos must comply; no bulk renames (opportunistic only, riding on active maintenance); concluded events are archived, not renamed. The open lecture-rename proposals PROJECT: Standardize core lecture repo names → lecture-<topic> (drop python) meta#333 and Standardize julia & datascience lecture repo names (lecture-<topic>, drop .myst) meta#334 proceed as the first instances of the rename policy.

Points where input is most useful

  1. The workshop-/course-/conference- three-way split vs a single event- prefix.
  2. Normalizing new audit./benchmark. names to dash form (existing dotted names grandfathered).
  3. The reserved-names list (§4) — anything missing or wrongly included?
  4. The event archival sweep (Rollout §3) — appetite for archiving ~50 concluded event repos in one pass?

The team manual's repository-conventions page (updated July 2026) remains the operational how-to — anatomies, worked examples, decision guide — and will cite QEP-3 as the naming authority on acceptance.

🤖 Generated with Claude Code

Proposes the org repository namespace as a decided standard: naming
grammar (dash prefix = type, dot suffix = variant), a normative type
registry, an ecosystem-name exemption for published packages and forks,
a teaching-events convention (workshop-/course-/conference-{name}-{yyyy})
for the largest unnamed family (~55 repos), and a migration + archival
policy (new repos comply; opportunistic renames; concluded events
archived). Records the taxonomy developed in the team manual and the
boundary rules for project-*/status-*/workspace-*.

Related proposals: QuantEcon/meta#333 and QuantEcon/meta#334 proceed as
first instances of the rename policy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 10, 2026 10:30
@mmcky
mmcky marked this pull request as draft July 10, 2026 10:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This pull request introduces QEP-3, a new draft QuantEcon Enhancement Proposal that standardizes repository naming grammar, defines a type-prefix registry, and documents exemptions plus a migration/archival policy; it also registers the new QEP in the repository’s README index.

Changes:

  • Add draft QEP document: Repository Naming and Types (QEP-3).
  • Update the README index to include QEP-3 with Type: standard, Status: Draft, Version: –.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
README.md Adds QEP-3 to the QEP index table.
qeps/qep-0003-repository-naming-and-types.md New draft QEP defining repo naming grammar, type registry, exemptions, and rollout policy.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +72 to +73
1. Repository names are lowercase and use only characters that need no shift key:
dashes, not underscores; no capitals.
| Suffix | Meaning | Example |
|---|---|---|
| `.notebooks` | notebook companion of a lecture series | `lecture-dp.notebooks` |
| `.{lang}` | translated edition (lowercase IETF tag) | `lecture-python-programming.zh-cn`, `.fa` |
Comment on lines +62 to +63
The repository namespace is org-wide infrastructure, exactly parallel to the label
namespace (QEP-2): every future repository is created against it, and it changes how
Comment on lines +204 to +207
- **Leaving the standard in the team manual only.** Rejected: the manual is private
and describes *how*; the namespace decision needs a public, durable, versioned record
with a decision rule — the same reasoning that made the label set QEP-2. The manual
page stays as the operational guide and cites this QEP.
Two amendments earned by applying the draft to a live placement decision
(where the translation program's command bench should live):

- The project-{name} registry row said flatly "no production code",
  contradicting the boundary rule below that allows a minimal command
  bench; a reader consulting only the table gets the wrong answer. The
  row now points at the boundary rules.
- The bench boundary rule now names the graduation triggers (shared
  across initiatives, or grown beyond minimal to serve routine fleet
  operations) and records that for a long-running program the
  bench-in-project arrangement can be durable, not merely transitional
  - locality of decisions, bench and clones under one root is a
  feature, not a smell.

Context: QuantEcon/project-translation applied the rule 2026-07-14 and
kept its bench in-project after weighing a workspace-translations split.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mmcky

mmcky commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

Field report from applying the draft. The translation program used QEP-3 this week to settle a live placement question — where its cross-repo command bench should live (QuantEcon/project-translation, decision register 2026-07-14). The goal-vs-fleet boundary rule decided it cleanly, and the exercise surfaced two text gaps now amended in 8150620: the project-{name} registry row said flatly "no production code", contradicting the bench allowance in the boundary rule below it (the row now points at the boundary rules), and the bench rule now names its graduation triggers and records that for a long-running program the bench-in-project arrangement can be durable rather than transitional.

For the record — two pre-existing editions don't parse under the §1 grammar. Not an objection to the draft: §5's migration policy (no bulk renames; opportunistic renames riding on active maintenance) is exactly how these resolve once the QEP is accepted. Documenting them here so they're known instances when the meta#333/meta#334 rename batch picks them up:

  • lecture-intro.zh-cn — base lecture-intro does not exist; the synced source is lecture-python-intro (→ lecture-python-intro.zh-cn if renamed).
  • lecture-python.zh-cn — base lecture-python is the legacy repo; the synced source is lecture-python.myst, so this edition follows whatever meta#334 resolves for its source.

One sequencing note for whoever handles them: both editions are the Phase 0 sync-automation targets (action-translation#74). A rename is nearly free before that wiring lands and fiddly after (Pages URLs under github.io don't redirect; target-repo: workflow inputs hardcode names) — so if the rename path is taken, it is cheapest sequenced ahead of Phase 0 execution.

@mmcky

mmcky commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

Field test: a live placement decision run against this draft (+ a proposal to restructure the automation types)

I ran a real placement decision against the draft as a test case — the kind of question the Motivation section says should stop being re-litigated. Two findings: the standard resolved the placement decision cleanly (validation, no text change needed), and pulling on one loose thread (reports-activity) led to a concrete proposal to restructure the automation-type registry while the QEP is still open. (This comment has been edited in place as the analysis developed; it supersedes earlier versions.)

The test case

The reporting/measurement program (QuantEcon/meta#332 — the status/analytics/activity planes, plus the benchmarking programme QuantEcon/meta#335 on the build side) needs a family-level coordination home: the plane taxonomy, the shared reference architecture, the cross-plane result/environment schema, and cross-plane research notes. Two research PRs recently landed in project-analytics (#2, #3) only because no such home exists — one of them says in its own body that it should move if the build plane gets a research home. The candidate names were workspace-reporting vs project-reporting.

Finding 1 — the boundary rules decided it without interpretation

The goal-vs-fleet rule in §2 answers directly: the reporting family is heterogeneous (project-analytics, reports-activity, benchmarks, dashboard), has no manifest + runner, and has no recurring mechanical cross-repo tasks — it fails workspace-readiness on every criterion. It is organized around a goal (one coherent measurement architecture). The "initiative or program" wording and the "programs run long" lifecycle note also did real work here, since this is a program rather than a bounded initiative. Verdict: project-reporting, dash form per §1.4. I'm recording this as evidence the boundary rules are usable in anger; no amendment proposed.

Two smaller items from the same test are repo-README material rather than QEP material, noted for completeness: (a) the project-reportingdashboard boundary should be written down in the repo README (project decides, the reserved singleton presents), and (b) the shared schema spec is a decision record and can live in the project repo, but per "no production code" its validators/collectors belong in cli/actions/skills.

Finding 2 — the automation types need restructuring: reports- is unregistered and workflow-* is weak

reports-activity is the only repository in the org under a reports- prefix, and the prefix appears nowhere in the §2 registry. Inspecting it shows why it ended up with a bespoke name — it is a hybrid of three registered types:

Contents Registered type it matches
action.yml (reusable Action) action-*
six scheduled workflows (weekly-report, monthly-report, news-weekly, news-watch, …) workflow-* (scheduled automation that acts)
reports/ directory of generated outputs closest to status-*'s data role, though narrative documents rather than a latest.json contract

The obvious fix was to rename it into workflow-* — but examining the incumbent shows it has the same disease. workflow-* has exactly one member (workflow-backups), and it names the mechanism rather than the role: every repository in the org has .github/workflows/, so "contains workflows" distinguishes nothing, and it pollutes org search. (Anecdotal but telling: in one working session both names were misremembered — report-activity for reports-activity, workflow-backup for workflow-backups. Prefixes that carry no role signal are hard to recall even for their creator.)

Proposal: replace workflow-* with a two-family automation taxonomy, named for the actor and its effect.

  • reporter-* — observes and narrates. Read-only automation that reads org/web state and writes reports, digests, or dashboard-adjacent narrative. Members and pipeline: reporter-activity (rename of reports-activity), a future reporter-news (the news-watch function), and the weekly read-only routines piloted in Org maintenance automation: weekly Claude Code routines (read-only reporting first) meta#331.
  • task-* — executes. Automation with write access to org resources, executing recurring org chores (the registry wording matters: "executes recurring org chores with write access" — a task-* repo is the machinery that does a chore, not a task tracker; work tracking stays in GitHub Projects per this QEP's architecture). Members and pipeline: task-backups (rename of workflow-backups, writes to S3), the annual event-archival sweep from Rollout §3 (archives repos).

Design rationale, in registry terms:

  • Name the actor and its effect, not the mechanism or the trigger. Mechanism (workflow-) and trigger (scheduled-, cron-) are implementation details visible inside .github/workflows/; trigger-naming also fails structurally, since both families are typically scheduled and either may be event-driven. Effect — observes vs acts — is the durable, governance-relevant property.
  • The split is the read/write permission boundary. reporter-* repos need read scopes plus issue/PR comment; task-* repos need write access to org resources. The org's automation estate becomes triage-able for security review directly from the repo list — the same property that made the meta#331 pilots deliberately read-only.
  • A closed two-way split, not open-ended agent nouns. This parallels the QEP's own workshop-/course-/conference- over event- decision: more reader signal at no grammar cost, without opening the door to a per-role noun zoo (archiver-, syncer-, …) of single-member families.
  • Domain vocabulary is off-limits for type prefixes — the mirror image of §3's ecosystem-name exemption: just as registry names are load-bearing outside the org, mathematical/economic vocabulary is load-bearing inside it. This filter removed the otherwise-attractive agent nouns: operator- (Bellman/transition/linear operators saturate the lectures), agent- (economic agents; plus the AI-agent overload), actor- (actor-critic methods). task- passes precisely because it carries no domain meaning.
  • Verbs framing extends cleanly: project-* decides / workspace-* operates / status-* measures / reporter-* narrates / task-* executes.

Other names considered and rejected on the way, recorded QEP-style so the choices read as decided: routine- (implies cadence; excludes event-driven members), automation-/automate- (verb form is off-pattern; noun form is long and sits confusably next to action-*), bot- (connotes an interactive actor), scheduled-/cron- (name the trigger both families share), job- (echoes Actions' own "jobs"), and registering reports-* as-is (legitimizes a single-member family).

Concretely, if agreed: in §2, remove the workflow-* row and add the reporter-* and task-* rows with the read/write boundary stated; in Rollout, add reports-activityreporter-activity and workflow-backupstask-backups as rename candidates under the §5 opportunistic policy (both repos are actively maintained, so the rename-rides-on-maintenance condition is satisfied), parallel to the existing continuous_time_mcs call-out; in Alternatives, note that reports- and workflow- are deliberately absent from the registry.

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.

2 participants