From d39380e5d8cb01a47f3100e54216604418cfd384 Mon Sep 17 00:00:00 2001 From: Ethan Arrowood Date: Mon, 20 Jul 2026 16:09:28 -0600 Subject: [PATCH 1/4] Expand repo taxonomy to 9 types and add public repository policy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Taxonomy: replace the catch-all `core` type with `product`, `plugin`, `application`, `library`, and `meta`, keeping `template`, `example`, `guide`, and `snapshot`. Add a classification decision tree, per-type sections with upgrade/testing guidance, and link Plugin/Application to the Harper component reference docs. Policy: add docs/repository-policy.md — the human- and agent-readable reference for managing active public repos (ownership, taxonomy topic, required meta docs, declared Harper version, testing/upgrades) plus a Public Archived section. Cross-link the two docs. Co-Authored-By: Claude Opus 4.8 --- docs/repo-taxonomy.md | 166 +++++++++++++++++++++----------------- docs/repository-policy.md | 98 ++++++++++++++++++++++ 2 files changed, 192 insertions(+), 72 deletions(-) create mode 100644 docs/repository-policy.md diff --git a/docs/repo-taxonomy.md b/docs/repo-taxonomy.md index 8352d46..1c57e17 100644 --- a/docs/repo-taxonomy.md +++ b/docs/repo-taxonomy.md @@ -1,120 +1,142 @@ -# Harper Repo Taxonomy +# Harper Public Repository Taxonomy -Status: **proposed — for team review** -Owner: Ethan +Every **public** repository gets **exactly one type**. The type establishes a baseline maintenance contract: versioning, upgrades, testing, etc. -## Why this exists +These types do not apply to Harper's internal and private repositories; a separate taxonomy system available privately for Harper engineers. -We maintain, upgrade, test, and reference dozens of repos — platform, plugins, templates, examples, guide backings, blog/demo companions — with no shared classification of what each is *for* or what upkeep it is owed. The result is staleness with no signal, a v-upgrade campaign with no defined scope, "is this a template or an example?" confusion, and repos that quietly rot because nothing said whether they were supposed to be kept alive. +The types defined here feed the [public repository policy](repository-policy.md), which sets what every active public repo must commit to. -This taxonomy fixes that by giving **every repo exactly one type**, and each type a clear contract: its maintenance obligation, its test contract, its versioning, and its lifecycle. +> This taxonomy may not be perfect and could change over time. Refinement is expected. If you have something that doesn't cleanly fit, or you see a new classification pattern please share and help improve the system! -## Scope: public-facing repos only +## Types -This taxonomy is for **public-facing repos** — the ones developers consume, which carry the heaviest and most careful maintenance needs. Internal repos sit *outside* it and don't get a type: +| Type | Definition | Examples | Upgrade Commitment | Testing Strategy | +|------|------------|----------|--------------|---------------| +| **Product** | A standalone project users directly interact with | `harper`, `harper-pro`, `studio`, `documentation`, `create-harper`, `symphony`, `skills` | Independent or tracks latest Harper | Unit/Integration/E2E + Matrix of supported runtimes | +| **Library** | Engineered on and used as a dependency | `rocksdb-js`, `integration-testing`, `extended-iterable`, `structon` | Independent or tracks latest Harper | Unit test is usually sufficient; sometimes integration tests too | +| **Plugin** | Harper Plugins; extends Harper functionality | `nextjs`, `astro`, `vite`, `oauth`, `http-cache`, `http-router`, `prerender-plugin`, `acl-connect` | Tracks latest Harper | Integration tests | +| **Application** | Runs on Harper; a deployable, feature-complete first-party app | `status-check`, `image-optimizer`, `risk-query` | Tracks latest Harper | Integration/E2E with Harper latest | +| **Template** | Build from it — a starting point you modify | `harper-ecommerce-template`, `fastify-template`, `template-redirector` | Tracks latest Harper | Smoke/Integration/E2E tests with Harper latest | +| **Example** | Read from it — a worked pattern you study and adapt | `agent-example-harper`, `full-page-caching`, `nextjs-example` | Tracks latest Harper | Integration/E2E with Harper latest | +| **Guide** | Follow it — an example plus narrated Learn content (start → build → end) | `create-your-first-application`, `caching-guide-example` | Tracks latest Harper | Integration/E2E of the final state with Harper latest | +| **Snapshot** | Companion app, example, or benchmark to a blog post, talk, or video | `twilio-sms`, `kafka-v-harper-perf-test` | Frozen | Optional, vs its pinned Harper version only | +| **Meta** | Public, but supports the org rather than being consumed as a product | `.github`, `code-guidelines`, `ai-review-prompts`, `rocksdb-prebuilds`, `github-app` | Independent | Independent | -- **Customer POCs** — proof-of-concept work built for a specific customer. -- **Experimentation / spikes** — research or throwaway repos. -- **Meta repos** — org tooling and process, e.g. `ospo` itself. +### Classification Decision Tree -These may adopt their own light conventions, but they're explicitly out of scope here. +Follow this decision tree to assist with classifying active, public repositories. -## The model in one line +```mermaid +flowchart TD + A{Contains a
config.yaml?} -->|Yes| B{Fully-featured and
meant to be used directly?} + A -->|No| G{A utility used
within other projects?} -A repo's **type** is set by two questions: + B -->|Yes| C{config.yaml has
pluginModule / extensionModule?} + B -->|No| D{A starting point for
the user's own development?} -- **What is it *for*?** (its contract) — build from it, read it, follow it, or freeze it. -- **What upkeep does it owe?** (its maintenance band) — tracked forever, or frozen in time. + C -->|Yes| Plugin([Plugin]) + C -->|No| Application([Application]) -Everything else — how it's tested, where it lives, what version it targets — falls out of the type. + D -->|Yes| Template([Template]) + D -->|"No — reference / learn from it"| E{Multiple steps + a page in the
Documentation Learn section?} -## The 5 types + E -->|Yes| Guide([Guide]) + E -->|No| F{Accompanies a post, video, or talk
published on the Harper website?} -| Type | What it's *for* | Upgrade obligation | Test contract | Lifecycle | -|------|-----------------|--------------------|----------------|-----------| -| **Core** | Platform, plugins, first-party apps — *produces* the versions everyone else consumes (`harper`, `studio`, `nextjs`, `status-check`) | Always current; it *is* the version | Full CI: unit / integration / e2e | Rarely — only if genuinely no longer maintained | -| **Template** | **Build from it** — a starting point you modify into your own thing | Track current Harper | By functional surface: smoke (generic) → e2e (advanced) | Retire only if obsolete | -| **Example** | **Read from it** — a worked pattern you study and adapt | Track current Harper | e2e on the pattern | Retire only if obsolete | -| **Guide** | **Follow it** — an example *plus* narrated Learn content (start → build → end) | Track current Harper | e2e on the final state | Retire only if obsolete | -| **Snapshot** | **A moment in time** — the companion to a blog post, talk, or video | **None — frozen** | Optional, against its **pinned** version only | Archived once its major is past | + F -->|Yes| Snapshot([Snapshot]) + F -->|No| Example([Example]) -**Core / Template / Example / Guide are the "Maintained" world** (track current Harper, tested, referenced ~forever). **Snapshot is the "frozen" world.** That split — maintained vs frozen — is the single most important line in the whole taxonomy. + G -->|Yes| Library([Library]) + G -->|No| H{Standalone product / platform / interface
for direct user interaction?} -## Template has two tiers + H -->|Yes| Product([Product]) + H -->|"No — something else"| Meta([Meta]) -Both are *build-from* (that's what makes them templates), but they differ in scope and home: + classDef type fill:#2a9d8f,stroke:#1d7268,color:#fff; + class Plugin,Application,Template,Guide,Snapshot,Example,Library,Product,Meta type; +``` -- **Generic template** — broad, opinion-light getting-started scaffold. Lives **in create-harper** (`template-vanilla`, `template-react-ts`, `template-react-ssr`, …). Smoke-tested (does it scaffold and boot). This is the curated getting-started menu. -- **Advanced template** — a complex, domain-specific starting point. Non-functional on its own; becomes useful after specific modification (e.g. `template-markdown-prerender` — stand it up, configure instances, deploy for a customer). Lives **standalone**, **e2e-tested** (it ships real logic that must work), and does **not** belong in the generic getting-started menu. +## Products -The lesson: **a template's complexity does not make it an example.** `template-markdown-prerender` is complex *and* build-from → an advanced template. `nextjs-example` is complete *and* read-from → an example. Contract decides the type, not size. +The catch-all for standalone, user-facing projects that aren't a plugin, application, or library — from the platform itself down to developer-facing tools like `create-harper`. If users interact with it directly and it doesn't fit a more specific type, it's a product. -## The rules that decide a type +`harper` is the product that defines the Harper version; every other type's version commitment is measured against it. Products are either independently versioned (own release cadence) or track latest Harper. -1. **Contract decides Template vs Example vs Guide.** Build-from → Template. Read-from → Example. Follow-a-narration → Guide. (Independent of how big or complex it is.) -2. **Functional surface decides the test contract — not the type.** A blank scaffold needs only a smoke test; anything carrying real logic (an advanced template *or* an example) needs e2e. So "Template = smoke" is wrong; test depth scales with what there is to break. -3. **Maintenance obligation decides Maintained vs Snapshot.** Kept current → Maintained. Frozen to a moment → Snapshot. +**Upgrades & testing.** Whether it versions independently or tracks Harper, a product should be validated against the latest and upcoming Harper versions as early as possible — ideally as a pre-release step — so a new Harper release never silently breaks it. Testing is the full stack: unit, integration, and e2e across a matrix of supported runtimes. -## Guide vs Snapshot: the invariant that kills content staleness +## Plugins -Guides and Snapshots both "back content," so the line must be explicit: +A literal Harper [Plugin](https://docs.harperdb.io/reference/v5/components/overview#plugins) or [Extension](https://docs.harperdb.io/reference/v5/components/overview#extensions) component — code that extends the Harper runtime and is installed into a Harper instance. The giveaway is a `config.yaml` declaring `pluginModule:` or `extensionModule:` — including extensions slated to migrate to the plugin API. -- **Guide** backs **canonical Learn-section content** (and, later, possibly Studio-embedded guides). Living, maintained, tracks current Harper. -- **Snapshot** backs a **dated artifact** — a blog post, conference talk, video, dev-rel tutorial. Frozen, version-stamped, eventually archived. +Plugins track latest Harper, moving in lockstep with the runtime API they extend. -> **The invariant: a dated artifact never references a living repo. living ↔ living, frozen ↔ frozen.** +**Upgrades & testing.** Plugins should be upgraded and tested against the latest and upcoming Harper versions as early as possible — ideally as a pre-release step. Integration tests against the latest Harper are the baseline. -If marketing or dev-rel wants to build content around a living Guide/Template/Example, they must **snapshot it first** — clone its current state into a frozen, version-stamped Snapshot companion to the post. The blog points at the snapshot (which never moves); the living repo stays free to evolve because nothing dated depends on its current state. +## Applications -This is the policy that eliminates the entire class of "the tutorial broke because the repo moved." Dev-rel guideline: *making a tutorial? snapshot the repo, stamp the Harper version, date the post. Want something longer-living instead? contribute to the Learn guides.* +A literal Harper [Application](https://docs.harperdb.io/reference/v5/components/applications) component — a feature-complete, deployable first-party app that runs on Harper. Like a plugin it has a `config.yaml`, but *without* `pluginModule`/`extensionModule`, and it is meant to be used directly rather than to extend the runtime. -(Worth making snapshotting trivial — a one-command fork + version-stamp — or people will skip it. Not now, but soon.) +The line against Template is completeness: an application works as-is (perhaps with light configuration); a template is a starting point you build from. -## create-harper's role +**Upgrades & testing.** Applications track latest Harper: upgraded and tested against the latest and upcoming Harper versions as early as possible — ideally as a pre-release step. Integration/e2e against the latest Harper are the baseline. -create-harper is the **standard getting-started UX** and the home of **generic templates only**. Advanced templates and examples live standalone — they are not getting-started options and should not clutter the picker. (create-harper *could* later offer "start from example X" as a convenience; that's a product nicety, explicitly out of scope here.) +## Libraries -Implication for Learn guides: a guide's **start** is *often* create-harper (pick a template), the prose drives the **build**, and the **Guide repo** is the validated **end**. But the start isn't always create-harper output — a guide that builds on an earlier guide starts from that guide's end state instead. So "start = create-harper" is the common case, not a rule. +Code you build *with* — imported as a dependency rather than run. Reserve this for true dependencies (`rocksdb-js`, `integration-testing`, `extended-iterable`). -## Version stamping +Contrast: a library is imported, an application is run, a product is interacted with. Libraries are either independently versioned or track latest Harper. -Every **non-Core** repo records the Harper **major** it targets (minor optional). Core *produces* versions, so this doesn't apply to it. +**Upgrades & testing.** Test against the latest and upcoming Harper versions as early as possible, or as a pre-release step. Unit tests are usually sufficient; add integration tests as necessary. -- For **Snapshots** this is load-bearing — it's the whole "valid as of Harper X" signal. -- For **Maintained** types it records the floor and scopes upgrades. +## Templates -Where it lives: when the repo has a `package.json` (most do), declare it in the **`engines`** or **`devEngines`** field — a standard, tooling-agnostic spot anyone can read without a GitHub login or API. For the rare repo without one, a line in the README. +A starting point users copy and modify into their own project. Two tiers: -## Snapshot lifecycle +- **Generic** — opinion-light getting-started scaffold; lives in `create-harper`; smoke-tested. +- **Advanced** — complex, domain-specific starting point, non/partially-functional until modified / configured (e.g. `template-markdown-prerender`); lives standalone; integration or e2e tested. -A Snapshot built for major X should stay valid across that major's minors (which aim to be non-breaking, even if that's never guaranteed). So: +Complexity doesn't make a template an example — the contract (build-from vs read-from) decides, not size. -- **Frozen but open** during its major's life: content untouched, but issues/PRs stay enabled so a user can land a bug fix. -- **Literally archived when the next Harper major goes GA.** We move the maintained world onto a new major as soon as it ships, so a Snapshot's era ends at the same moment. (Archiving is read-only, not deletion — it stays referenceable for its post.) *Alternative if we want more headroom: wait for the old major's full EOL.* -- A Snapshot going red on a *future* major is **expected, not a failure**, and shouldn't be treated as one. +**Upgrades & testing.** Templates track latest Harper: upgraded and tested against the latest and upcoming Harper versions as early as possible. Test depth follows the tier — smoke for generic, integration or e2e for advanced. -A Snapshot that turns out to be frequently referenced can be **promoted** to a maintained Example/Template and joins the version matrix. +## Examples -## How our repos classify (worked examples) +A complete, worked pattern users read and adapt — reference material, not necessarily something to fork and build on (thought they could). It's functional and tested, but its purpose is to be studied. -- `harper`, `studio`, `nextjs` (the plugin), `status-check` → **Core** -- create-harper `template-vanilla`, `template-react-ts-ssr`, … → **Template (generic)** -- `template-markdown-prerender` → **Template (advanced)**, Maintained (recently upgraded to v5) -- `nextjs-example` → **Example** -- `create-your-first-application`, the caching-guide repos → **Guide** -- benchmark / conference / blog-demo repos → **Snapshot** -- A customer's modified deployment of an advanced template (e.g. internal `markdown-prerender`) → **out of scope** (customer/internal repo), not a duplication problem — that's a template instantiated as intended. +Contrast: a template is built *from*, an example is read *from*, and a guide adds step-by-step narration. -## Type tagging (not naming) +**Upgrades & testing.** Examples track latest Harper: upgraded and tested against the latest and upcoming Harper versions as early as possible. Integration/e2e on the pattern. -Repo names today are inconsistent about type (`template-markdown-prerender` vs `nextjs-example`) — so rather than standardize a naming scheme, **keep names clean and don't encode type in them at all.** Record the type as a **GitHub topic** instead — `template` / `example` / `guide` (Core and Snapshot optional). +## Guides -Topics beat a name prefix: a repo can pick up other taxonomy dimensions later, can change type as it matures without a rename, and names stay autocomplete-friendly when you're working across several example/template repos. +An example paired with narrated Learn content that walks start → build → end, backing a canonical page in the Documentation Learn section. -## Relationship to upgrade planning +A guide is living and tracks latest Harper — that's the line against Snapshot, which freezes to a dated artifact (see [Guide vs Snapshot](#guide-vs-snapshot)). -The upgrade scope is exactly **every Core, Template, Example, and Guide repo** — the Maintained world. Snapshots are explicitly out of scope for forward upgrades by design. Once every repo carries a type + target major, an upgrade campaign's scope is simply "the Maintained types," and each repo's obligation is "meeting its type's contract." +**Upgrades & testing.** Guides track latest Harper: upgraded and tested against the latest and upcoming Harper versions as early as possible. Integration/e2e on the guide's final state. -## Feedback +## Snapshots -This is proposed as **decided** — the aim is alignment, not re-litigation. The spot most open to input is the **Snapshot archive trigger**. Everything else we'll roll with unless there's a strong objection. +A frozen companion to a dated artifact — a blog post, talk, video, or benchmark. Pinned to the Harper version it was built against and never upgraded. + +**Upgrades & testing.** None — a snapshot is never upgraded. Any tests run only against its pinned Harper version. + +- **Frozen but open** during its major's life: content untouched, issues/PRs stay enabled for bug fixes. +- **Archived when the next Harper major goes GA.** Read-only, not deleted — stays referenceable. +- Going red on a *future* major is expected, not a failure. +- A frequently-referenced Snapshot can be **promoted** to a maintained Example/Template. + +### Guide vs Snapshot + +> **A dated artifact never references a living repo. living ↔ living, frozen ↔ frozen.** + +- **Guide** backs canonical Learn content. Living, tracks current Harper. +- **Snapshot** backs a dated artifact (blog, talk, video). Frozen, version-stamped, eventually archived. + +To build content on a living repo, **snapshot it first** — fork its current state into a version-stamped Snapshot and point the post at that. The living repo stays free to evolve; nothing dated depends on its current state. + +## Meta + +Public repositories that support the org or its products rather than being consumed as a product themselves — org profile, CI/build artifacts, process and tooling config. + +**Upgrades & testing.** None enforced. Upgrade and test only as the repo's own needs dictate. \ No newline at end of file diff --git a/docs/repository-policy.md b/docs/repository-policy.md new file mode 100644 index 0000000..501d4cb --- /dev/null +++ b/docs/repository-policy.md @@ -0,0 +1,98 @@ +# Harper Public Repository Policy + +> **Status: work in progress.** This policy is being developed alongside the organization-wide repository cleanup, and refinement is expected. Automated tooling to check and enforce much of what follows is planned; until then, **this document is the human- and agent-readable reference for how Harper's public repositories are managed.** Internal and private repositories are governed by a separate policy defined internally. + +## Why this exists + +Harper's GitHub organization is approaching 500 repositories with no sustained, org-wide management behind them. That has a real cost: + +- **Public repos are AI training surface.** Every public repo is indexed by search engines and ingested by AI models. Stale examples, half-finished implementations, and abandoned demos actively degrade how agents understand and represent Harper. +- **Our repos reflect the engineering organization.** Everything public-facing is exposed surface area that other companies, teams, and developers — human and agentic — evaluate us on. +- **Undefined scope is unmaintainable.** Until we know what each repo is and who owns it, we cannot state our maintenance obligations. The v5 upgrade effort made that painfully clear. + +This policy makes the public estate deliberate: every active public repo has a known purpose, a known owner, and a known maintenance contract. + +## Scope + +This policy applies to **active, public** repositories in the Harper GitHub organization. It does not cover internal or private repositories (separate policy), nor archived repositories — except for the archival process itself (see [Public archived](#public-archived)). + +Its companion is the [repository taxonomy](repo-taxonomy.md), which defines the repository *types* referenced throughout. + +## Requirements for active public repositories + +Every active public repo must meet the following baseline. These are commitments, not suggestions. + +### Ownership and a maintenance commitment + +Every repo has a clear owning team. Public code is a **standing maintenance commitment**, not a one-time contribution — sharing code with no plan to maintain it is not acceptable. If no team will commit to maintaining a repo, it should be archived rather than left to rot. + +Ownership can be transferred, and a creating team need not be the maintaining team — for example, a team ships a repo and OSPO/engineering assumes ongoing maintenance. Any such arrangement must be **explicitly agreed**, not assumed. + +### One taxonomy type, declared as a GitHub topic + +Every repo is classified as exactly one [taxonomy type](repo-taxonomy.md) and records that type as a **GitHub topic** — one of `product`, `plugin`, `application`, `library`, `template`, `example`, `guide`, `snapshot`, or `meta`. Type is never encoded in the repo name; the topic is the source of truth, so a repo can be re-typed as it matures without a rename. + +### Required meta documents + +At minimum, every active public repo carries: + +- **`LICENSE`** — every public repo is licensed. +- **`README`** — states what the repo is, its taxonomy type, the Harper version it targets, and its current status. + +Standard health files (`CONTRIBUTING`, `SECURITY`, `CODE_OF_CONDUCT`) are provided org-wide through the `.github` repo and should not be contradicted per-repo. A fuller required set will be standardized as tooling lands. + +### A declared Harper version + +Every repo that consumes Harper declares the version it targets using standard, machine-readable package metadata — a **`package.json` `dependencies`/`peerDependencies` entry**, or the **`engines`** field — expressed as a **semver specifier**. This lets both people and tooling answer "what Harper does this support?" without cloning and reading source. See the taxonomy's version-stamping guidance for which types declare a floor, a supported range, or a pinned version. + +### Testing and upgrades + +Each repo meets the testing and upgrade contract of its taxonomy type. As a rule, active public repos track the latest Harper release and are tested against the latest and upcoming Harper versions as early as possible. `snapshot` (frozen) and `meta` (nothing enforced) are the exceptions. + +## Public archived + +Archiving is how we retire a repo without erasing it. **Archived is not deleted:** the repo becomes read-only but stays fully readable, its links keep working, and archiving is reversible if we get it wrong. + +### When to archive + +Archive a public repo when it is no longer worth keeping *active* but is still worth keeping *referenceable*: + +- Dormant, with no meaningful recent activity and no owner willing to commit to maintenance. +- Superseded by a newer repo, feature, or first-party capability. +- A `snapshot` whose moment has passed (its Harper major is behind) but which still backs published content. + +### Keep public vs. move internal + +Default to leaving an archived repo **public** when anything external still references it (marketing posts, talks, docs) or when a running system depends on it being publicly cloneable. Move it internal only when nothing external needs it. When in doubt, keep it public and archived — the cost is low and references stay intact. + +### Required archive note + +Every archived repo gets a note at the top of its README explaining its state. For a `snapshot` backing published content: + +```md +> [!IMPORTANT] +> **This repository is archived and read-only.** +> +> It's a point-in-time snapshot built to accompany [](). +> It is pinned to **Harper v** and is preserved for reference. +> It is **not** kept in sync with current releases and may not be supported in latest Harper versions. +> +> For up-to-date guides and reference docs, see the [Harper docs](https://docs.harperdb.io) and join our [Discord](https://discord.com/invite/VzZuaw3Xay). +``` + +Adapt the wording for non-snapshot repos: drop the "accompany" line, and state what supersedes it with a link. + +### Deletion (rare) + +Deletion is reserved for repos with **no reference value at all** — empty or unused forks, never-published experiments, repos that were never public. Deleting a fork that was never consumed anywhere is fine; deleting anything that has been public and referenced is not. Prefer archiving in every other case. + +## Roadmap + +This policy is still being built out. Planned work: + +- Automated checks for the requirements above (topic present, license present, Harper version declared, README shape). +- A standardized required meta-document set. +- An ownership registry and a review cadence. +- A separate internal/private repository policy. + +Spot a repo that doesn't fit, or a gap in this policy? Raise it — this is expected to evolve. From c6813de659726617b8df327fa4300ba99509e723 Mon Sep 17 00:00:00 2001 From: Ethan Arrowood Date: Mon, 20 Jul 2026 16:25:46 -0600 Subject: [PATCH 2/4] Rename repo-taxonomy.md to repository-taxonomy.md Match the repository-policy.md naming and update cross-links. Co-Authored-By: Claude Opus 4.8 --- docs/repository-policy.md | 4 ++-- docs/{repo-taxonomy.md => repository-taxonomy.md} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename docs/{repo-taxonomy.md => repository-taxonomy.md} (100%) diff --git a/docs/repository-policy.md b/docs/repository-policy.md index 501d4cb..202e9aa 100644 --- a/docs/repository-policy.md +++ b/docs/repository-policy.md @@ -16,7 +16,7 @@ This policy makes the public estate deliberate: every active public repo has a k This policy applies to **active, public** repositories in the Harper GitHub organization. It does not cover internal or private repositories (separate policy), nor archived repositories — except for the archival process itself (see [Public archived](#public-archived)). -Its companion is the [repository taxonomy](repo-taxonomy.md), which defines the repository *types* referenced throughout. +Its companion is the [repository taxonomy](repository-taxonomy.md), which defines the repository *types* referenced throughout. ## Requirements for active public repositories @@ -30,7 +30,7 @@ Ownership can be transferred, and a creating team need not be the maintaining te ### One taxonomy type, declared as a GitHub topic -Every repo is classified as exactly one [taxonomy type](repo-taxonomy.md) and records that type as a **GitHub topic** — one of `product`, `plugin`, `application`, `library`, `template`, `example`, `guide`, `snapshot`, or `meta`. Type is never encoded in the repo name; the topic is the source of truth, so a repo can be re-typed as it matures without a rename. +Every repo is classified as exactly one [taxonomy type](repository-taxonomy.md) and records that type as a **GitHub topic** — one of `product`, `plugin`, `application`, `library`, `template`, `example`, `guide`, `snapshot`, or `meta`. Type is never encoded in the repo name; the topic is the source of truth, so a repo can be re-typed as it matures without a rename. ### Required meta documents diff --git a/docs/repo-taxonomy.md b/docs/repository-taxonomy.md similarity index 100% rename from docs/repo-taxonomy.md rename to docs/repository-taxonomy.md From 3140b73734598921616c5567dc3a0b14ce198584 Mon Sep 17 00:00:00 2001 From: Ethan Arrowood Date: Mon, 20 Jul 2026 16:40:58 -0600 Subject: [PATCH 3/4] ethan edits policy --- docs/repository-policy.md | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/docs/repository-policy.md b/docs/repository-policy.md index 202e9aa..8cb4d14 100644 --- a/docs/repository-policy.md +++ b/docs/repository-policy.md @@ -10,13 +10,13 @@ Harper's GitHub organization is approaching 500 repositories with no sustained, - **Our repos reflect the engineering organization.** Everything public-facing is exposed surface area that other companies, teams, and developers — human and agentic — evaluate us on. - **Undefined scope is unmaintainable.** Until we know what each repo is and who owns it, we cannot state our maintenance obligations. The v5 upgrade effort made that painfully clear. -This policy makes the public estate deliberate: every active public repo has a known purpose, a known owner, and a known maintenance contract. +This policy makes the public state deliberate: every active public repo has a known purpose, a known owner, and a known maintenance contract. ## Scope -This policy applies to **active, public** repositories in the Harper GitHub organization. It does not cover internal or private repositories (separate policy), nor archived repositories — except for the archival process itself (see [Public archived](#public-archived)). +This policy applies to **active, public** repositories in the Harper GitHub organization (`@HarperFast`). It does not cover internal or private repositories (separate policy), nor archived repositories — except for the archival process itself (see [Public archived](#public-archived)). -Its companion is the [repository taxonomy](repository-taxonomy.md), which defines the repository *types* referenced throughout. +Its companion is the [repository taxonomy](./repository-taxonomy.md), which defines the repository *types* referenced throughout. ## Requirements for active public repositories @@ -24,30 +24,34 @@ Every active public repo must meet the following baseline. These are commitments ### Ownership and a maintenance commitment -Every repo has a clear owning team. Public code is a **standing maintenance commitment**, not a one-time contribution — sharing code with no plan to maintain it is not acceptable. If no team will commit to maintaining a repo, it should be archived rather than left to rot. +Every repo has a team owner; not individual people. Public code is a **standing maintenance commitment**, not a one-time contribution. Sharing code with no plan to maintain it is not acceptable. You may utilize the snapshot type to share codebases with no intent to maintain it, but they still must strictly follow the public repo policy set forth in this document. Ownership can be transferred, and a creating team need not be the maintaining team — for example, a team ships a repo and OSPO/engineering assumes ongoing maintenance. Any such arrangement must be **explicitly agreed**, not assumed. ### One taxonomy type, declared as a GitHub topic -Every repo is classified as exactly one [taxonomy type](repository-taxonomy.md) and records that type as a **GitHub topic** — one of `product`, `plugin`, `application`, `library`, `template`, `example`, `guide`, `snapshot`, or `meta`. Type is never encoded in the repo name; the topic is the source of truth, so a repo can be re-typed as it matures without a rename. +Every repo is classified as exactly one [taxonomy type](./repository-taxonomy.md) and records that type as a **GitHub topic** — one of `product`, `plugin`, `application`, `library`, `template`, `example`, `guide`, `snapshot`, or `meta`. Type shouldn't be encoded in the repo name; the topic is the source of truth, so a repo can be re-typed as it matures without a rename. + +We do have a number of existing repos with taxonomy types in their names; we'll slowly be working to rename those overtime. ### Required meta documents At minimum, every active public repo carries: - **`LICENSE`** — every public repo is licensed. -- **`README`** — states what the repo is, its taxonomy type, the Harper version it targets, and its current status. +- **`README`** — states what the repo is. -Standard health files (`CONTRIBUTING`, `SECURITY`, `CODE_OF_CONDUCT`) are provided org-wide through the `.github` repo and should not be contradicted per-repo. A fuller required set will be standardized as tooling lands. +Standard health files (`CONTRIBUTING`, `SECURITY`, `CODE_OF_CONDUCT`) are provided org-wide through the `.github` repo. Repositories may provide their own versions of these documents as needed. ### A declared Harper version -Every repo that consumes Harper declares the version it targets using standard, machine-readable package metadata — a **`package.json` `dependencies`/`peerDependencies` entry**, or the **`engines`** field — expressed as a **semver specifier**. This lets both people and tooling answer "what Harper does this support?" without cloning and reading source. See the taxonomy's version-stamping guidance for which types declare a floor, a supported range, or a pinned version. +Every repo that consumes Harper declares the version it targets using standard, machine-readable package metadata — a **`package.json` `dependencies`/`peerDependencies` entry**, or the **`engines`** field — expressed as a **semver specifier**. This lets both people and tooling answer "what Harper version does this support?" without cloning and reading source. ### Testing and upgrades -Each repo meets the testing and upgrade contract of its taxonomy type. As a rule, active public repos track the latest Harper release and are tested against the latest and upcoming Harper versions as early as possible. `snapshot` (frozen) and `meta` (nothing enforced) are the exceptions. +Each repo meets the testing and upgrade contract of its taxonomy type. As a general rule, active public repos track the latest Harper release and are tested against the latest and upcoming Harper versions as early as possible. `snapshot` (frozen) and `meta` (nothing enforced) are the exceptions. + +We may work towards a proper release-gate system to validate Harper versions prior to release by automatically testing prereleases against our set of tested public repos. ## Public archived @@ -58,6 +62,7 @@ Archiving is how we retire a repo without erasing it. **Archived is not deleted: Archive a public repo when it is no longer worth keeping *active* but is still worth keeping *referenceable*: - Dormant, with no meaningful recent activity and no owner willing to commit to maintenance. + - Currently considering a 1 year staleness timing to define "recent activity". May consider different amounts of times for different types. - Superseded by a newer repo, feature, or first-party capability. - A `snapshot` whose moment has passed (its Harper major is behind) but which still backs published content. @@ -65,6 +70,8 @@ Archive a public repo when it is no longer worth keeping *active* but is still w Default to leaving an archived repo **public** when anything external still references it (marketing posts, talks, docs) or when a running system depends on it being publicly cloneable. Move it internal only when nothing external needs it. When in doubt, keep it public and archived — the cost is low and references stay intact. +> We have a number of public archive repos today that serve little purpose (very old HarperDB Custom Functions repos and other things). We likely will change the visibility of these to really reduce any chance of humans or agents getting incorrect information on old HarperDB practices. + ### Required archive note Every archived repo gets a note at the top of its README explaining its state. For a `snapshot` backing published content: @@ -84,7 +91,7 @@ Adapt the wording for non-snapshot repos: drop the "accompany" line, and state w ### Deletion (rare) -Deletion is reserved for repos with **no reference value at all** — empty or unused forks, never-published experiments, repos that were never public. Deleting a fork that was never consumed anywhere is fine; deleting anything that has been public and referenced is not. Prefer archiving in every other case. +Deletion is reserved for repos with **no reference value at all** — empty or unused forks, never-published experiments, repos that were never public. Deleting a fork that was never consumed anywhere is fine; deleting anything that has been public and referenced is not. Prefer archiving by default. ## Roadmap From f54e2e759db671ac84f3863b9a7aec07e9d9b5ff Mon Sep 17 00:00:00 2001 From: Ethan Arrowood Date: Mon, 20 Jul 2026 16:42:27 -0600 Subject: [PATCH 4/4] grammar --- docs/repository-taxonomy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/repository-taxonomy.md b/docs/repository-taxonomy.md index 1c57e17..6295753 100644 --- a/docs/repository-taxonomy.md +++ b/docs/repository-taxonomy.md @@ -2,7 +2,7 @@ Every **public** repository gets **exactly one type**. The type establishes a baseline maintenance contract: versioning, upgrades, testing, etc. -These types do not apply to Harper's internal and private repositories; a separate taxonomy system available privately for Harper engineers. +These types do not apply to Harper's internal and private repositories; a separate taxonomy system is available privately for Harper engineers. The types defined here feed the [public repository policy](repository-policy.md), which sets what every active public repo must commit to.