GitHub Repository Conventions#
A collection of conventions used for the QuantEcon GitHub organization.
Naming Repositories#
Please use the following naming conventions
Always use characters that do not require the use of
shiftkey (i.e. ‘-’ rather than ‘_’)
Repository types at a glance#
The prefix of a repository name encodes what the repo is for. Use this table to pick the right home for new work; the sections below give the details for each type.
Type |
One-line test |
Lifecycle |
Main author |
Visibility |
|---|---|---|---|---|
|
a published lecture series |
ongoing |
humans |
public |
|
a textbook project |
ongoing |
humans |
private |
|
“we are planning and deciding” — the narrative home for an initiative or program |
goal-scoped — lives and dies with its goal (initiatives end; programs run long) |
humans |
private |
|
“we are measuring” — a living dashboard of facts about a domain |
ongoing — outlives any project |
automation |
public (typically) |
|
“we are operating across a repo family” — a cross-repo tooling bench |
ongoing |
humans |
private |
|
“the org does this on a schedule” — automation that acts |
ongoing |
automation |
public/private |
|
a reusable GitHub Action consumed by other repos’ workflows |
ongoing |
humans |
public |
The four org-level types map onto verbs: project-* decides (plans, records why), workspace-* operates (humans executing across a repo family, by hand), workflow-* automates (machines acting on a schedule), and status-* measures (machines reporting the resulting state).
Choosing a type: four questions#
When a new piece of work needs a repo (or an existing artifact needs a home), ask:
Does it live and die with a goal? Work organized around a goal — an initiative that ends, or a program that runs long →
project-*. Work tied to a domain, repo family or routine that persists regardless of any particular goal →status-*,workspace-*,workflow-*, oraction-*.Who writes most of the commits? Humans writing narrative, plans and decisions →
project-*orworkspace-*. A scheduled collector or bot →status-*orworkflow-*.Who is the audience? The team (candid notes, unannounced plans) → private (
project-*,workspace-*). Anyone, linkable from public pages → public (status-*,action-*).If the repo were deleted, what is lost? Decisions and rationale that exist nowhere else →
project-*. State that a collector can recompute (minus history) →status-*.
project-* vs status-*#
These two are the easiest to confuse, because every project wants a dashboard. The split rule:
status-*holds the numbers;project-*holds the narrative.
A project-* repo answers “what are we doing and why?” — roadmap, decision register, research findings, dated reports. A status-* repo answers “what is true right now?” — coverage, freshness, configuration, health — collected by automation on a cadence.
Three reasons to keep them separate rather than putting the dashboard inside the project repo:
Lifecycle. A project ends (or goes dormant); the domain it worked on still needs monitoring in maintenance mode. The dashboard is precisely the artifact that must survive the project’s archival.
Commit traffic. A nightly collector writes data commits that would drown a project repo’s decision history. Machine-written and human-written repos age differently.
Visibility. Project repos are private (candid planning); dashboards are typically public facts computed from public state, published via GitHub Pages and linkable from anywhere.
Graduation rule. Dashboards typically start life inside a project-* repo as hand-maintained tables — that is fine for incubation. Once the numbers are collected automatically on a cadence, they graduate to a status-* repo. The project repo keeps a narrative layer (interpretation, phase context, campaign notes) that links to the live dashboard rather than duplicating its numbers.
Worked example. The translation program: project-translation (private) holds the i18n roadmap, decision register, research and dated program reports; status-translations (public) holds the collector, the versioned data (data/latest.json + append-only data/history/) and the Pages dashboard tracking coverage and freshness per language edition. Whether the i18n project is one day archived or runs on indefinitely as a program, status-translations continues independently as the maintenance dashboard.
Not project management. status-* repos measure the product (the state of the world); they do not track the work. Work tracking — issues, phases, on-track/at-risk — lives in GitHub Issues/Projects (see meta#332). The curated dashboard hub links out to status-* pages; it does not host their data.
project-* vs workspace-*#
Both are private, human-authored, and can operate across multiple repos — so this is the easiest pair to blur. The test is what the repo is organized around:
A
project-*repo is organized around a goal; aworkspace-*repo is organized around a fleet.
Remove the goal and a project repo is pointless, even though its member repos still exist. Remove the repo family and a workspace is pointless, even if every current initiative is still running. A project can change which repos it touches without changing identity; a workspace can change what work flows through it without changing identity — but never its family.
Lifecycle differences follow from this rather than defining it: goals end (initiatives) or run long (programs), so project-* repos are archived when — and only when — their goal is achieved or absorbed; fleets persist, so a workspace never archives while its family lives.
Overlap is allowed, with a boundary rule. A project repo may carry a minimal command bench (a manifest plus sync) for the repos it is changing — the bench serves the goal, and dies with the project. But the moment the bench becomes the point, or a second initiative wants to use the same bench, it belongs in a workspace-*: the workspace is the shared operating layer that inherits goals from many projects (and from routine maintenance) rather than owning one.
When a family is workspace-ready. A workspace-* earns its existence when the member repos are mature: membership is stable, the repos are structurally homogeneous, coordination tasks recur mechanically, and development happens upstream of the family (e.g. the lecture repos are mature delivery surfaces consuming changes from quantecon-book-theme, mystmd and actions; workspace-lectures coordinates the downstream effects). A family still being actively designed is better served by the owning project repo until it stabilizes.
Lectures#
Name |
Description |
Visibility |
|---|---|---|
lecture-{name} |
A repository that contains an official QuantEcon lecture series |
public |
lecture-{name}.notebooks |
A companion repository that contains notebooks for an official QuantEcon lecture series |
public |
Books#
Name |
Description |
Visibility |
|---|---|---|
book-{name} |
A QuantEcon associated textbook repo |
private |
book-{name}.public |
A QuantEcon textbook companion site |
public |
quantecon-book-{name} |
(optional) A QuantEcon companion software package to support an official textbook project |
public |
Projects#
Name |
Description |
Visibility |
|---|---|---|
project-{name} |
The planning and decision home for a QuantEcon initiative or program (e.g. |
private |
A project-* repo is the durable, human-authored record of an initiative or program that spans multiple repositories: no single code repo can hold the program-level picture, so the project repo is that picture. It holds no production code — engines, actions and content live in their own repos.
Anatomy (reference model: project-translation):
Path |
Role |
|---|---|
|
purpose, repo map, the program at a glance, related repos |
|
the phased plan |
|
immediate actions and the decision register (date, decision, why / alternatives) |
|
dated, verified point-in-time findings (audits, inventories) |
|
dated program status reports |
|
narrative status layer — interpretation and context, linking to the live |
|
session orientation for AI-assisted work |
Lifecycle. Projects are goal-scoped: the repo lives and dies with its goal, not with any repo family. Some goals are initiatives with phases and an intended end state; others are programs that run indefinitely (a translation program coordinates language editions for as long as they exist). Archive the repo when — and only when — the goal is achieved or absorbed into routine maintenance: its decision register remains the historical record, while any dashboard it incubated lives on as a status-* repo and any command bench it carried is retired or promoted to a workspace-*.
Note: some older repos use the dot form project.{name} (e.g. project.lecture-mojo); new project repos use the dash form project-{name}.
Status dashboards#
Name |
Description |
Visibility |
|---|---|---|
status-{domain} |
A long-lived, automatically updated dashboard reporting the current state of a domain (e.g. |
public (typically) |
A status-* repo is a living reporter: data store + collector + static dashboard, named for the domain it measures (not for the project that created it), because it keeps running long after any project ends.
Anatomy (reference models: status-lectures, status-translations):
Path |
Role |
|---|---|
|
the script that computes the numbers, plus |
|
the current snapshot — the versioned data contract that the site and any external consumer read |
|
dated snapshots, append-only — trend views come free later |
|
the dashboard: a static, dependency-free page deployed to GitHub Pages |
|
|
Principles
Domain-scoped, not project-scoped. The repo monitors a thing QuantEcon maintains (lecture builds, translations); it is not a project deliverable and does not close with a project.
Usually public. Most dashboards compute every fact from public GitHub state (no credentials beyond
GITHUB_TOKEN) and publish via Pages so anyone can link to them. This is a norm rather than a hard rule — a dashboard over sensitive facts (e.g. costs) can be private.Machine-written. Commit history is dominated by the collector; humans touch only the collector, config and site.
Data, not narrative. Numbers plus minimal labels. Interpretation, decisions and plans belong in the owning
project-*repo ormeta.Self-contained and relocatable. The static site plus the versioned data contract means the dashboard can move (e.g. under a future reporting hub) by moving files and updating one URL.
Canonical counting rules live here. When a status repo and hand-maintained project notes disagree on a metric, the status repo’s documented rule is canonical for reporting.
Workspaces#
Name |
Description |
Visibility |
|---|---|---|
workspace-{collection} |
A cross-repo development workspace for operating across a collection of related QuantEcon repositories (e.g. |
private |
A workspace-* repo is distinct from project-*: a project-* repo plans and tracks an initiative, whereas a workspace-* repo operates across an existing family of repositories (clone-all, run commands across the set, coordinate multi-repo changes).
Scope and lifecycle. A workspace is scoped to the repo family, not to any initiative — hence workspace-{collection}, never workspace-{project}. It serves two kinds of work equally: routine maintenance sweeps (dependency bumps, config normalization) and the execution of project rollouts (the project decides a change; the workspace is where the multi-repo branch/edit/PR cycle actually happens). Like a status-* repo, it outlives every project that passes through it: it persists as long as the collection does. See project-* vs workspace-* in the decision guide above for the goal-vs-fleet test and the conditions under which a family is workspace-ready.
Graduation rule. The workspace is also where cross-repo procedures are rehearsed by hand; once a procedure becomes routine and mechanical, it graduates into workflow-* or action-* automation — the same incubation relationship project-* has to status-* dashboards.
Anatomy. A workspace holds tooling and configuration only — it never vendors lecture/book content:
Path |
Role |
|---|---|
|
the member repos, in |
|
the runner ( |
|
task entrypoints ( |
|
workspace-scoped Claude Code rules + workspace-only skills |
|
ADRs recording design decisions |
|
the clone target — gitignored; member content is never committed here |
How they work. make sync clones every repo named in manifest.yml into repos/; each cloned repo keeps its own remote, history, and PRs (the workspace never vendors content). bin/foreach runs a command across the whole set. A coordinated change is the same branch in each repo → edit → commit per repo → one PR per repo — there is no aggregate PR — tracked as a workspace issue that links up to the relevant meta issue. make tidy returns every repo to a clean, up-to-date default branch.
Workflows and Actions#
Name |
Description |
Visibility |
|---|---|---|
workflow-{name} |
A repository that runs automation on a schedule for the organization — it acts on the world (e.g. |
public/private |
action-{name} |
A repository that packages a reusable GitHub Action consumed by other repos’ workflows (e.g. |
public |
actions |
Shared reusable actions and workflows for lecture builds (monorepo of small building blocks) |
public |
The test: if the repo’s workflow does the job itself on a cron (backup, report generation), it is a workflow-*; if other repositories reference it in their workflows (uses: QuantEcon/action-x@v1), it is an action-*.
Reserved names#
Singleton repos with an org-wide role:
Name |
Description |
|---|---|
meta |
Cross-repo issues and discussion — proposals start here |
qeps |
QuantEcon Enhancement Proposals — durable records of cross-repo and governance decisions |
dashboard |
Curated presentation hub for stakeholders — links out to |
manual (QuantEcon.manual) |
This manual — operations, style guide, conventions |
grant-admin |
Grant administration |
grant-fundraising |
Proposal development for funding opportunities |
admin, vault, governance |
Private organizational administration and knowledge |
projects |
Private dev-history vault (decisions and rationale across software projects) — not to be confused with the |
Other prefixes in use#
Lighter conventions, listed for completeness:
Name |
Description |
|---|---|
test-{name} |
Disposable test doubles and CI targets for actions/tooling (e.g. |
template-{name} |
Template repositories (e.g. |
contractor-{name} |
Payment artifacts for an individual RA/contractor (private) |
audit.{yyyy-mm}.{topic} |
A dated, point-in-time audit (e.g. |
benchmark.{topic} |
Benchmark datasets and evaluation harnesses (e.g. |