mirror of
https://github.com/ModernRelay/omnigraph.git
synced 2026-06-09 01:35:18 +02:00
governance: external contribution model (issues/discussions/RFCs/PRs) (#143)
Formalize the public contribution surface. Maintainers keep a separate internal process and are exempt from the intake gates; everyone stays bound by review, CODEOWNERS, and branch protection. Model: - Issues = problem reports only (bug form + config.yml redirects ideas to Discussions and disables blank issues). - Discussions = ideas + RFC incubation. - RFCs = anyone (incl. external) authors docs/rfcs/NNNN-*.md; a maintainer merging it is acceptance. Distinct from the maintainer-internal docs/dev/rfc-00N-* track. - PRs = link an `accepted` issue or accepted RFC, or use the trivial fast-lane (typos/docs/deps). Enforced softly to start (template + review). Adds GOVERNANCE.md, rewrites CONTRIBUTING.md, adds docs/rfcs/ (README + template), .github issue/PR/discussion templates. Wires docs/rfcs/ into the doc-link checker (excluded like releases; linked from docs/dev/index.md). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c7365bf8ef
commit
343f1f17ed
10 changed files with 406 additions and 8 deletions
34
.github/DISCUSSION_TEMPLATE/rfc.yml
vendored
Normal file
34
.github/DISCUSSION_TEMPLATE/rfc.yml
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
labels: ["rfc"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Use this to **incubate an RFC** — socialize a design and reach rough
|
||||
consensus before writing the formal document. When it's ready, graduate
|
||||
it into a pull request that adds `docs/rfcs/NNNN-title.md`
|
||||
(see [docs/rfcs/README.md](../blob/main/docs/rfcs/README.md)); a
|
||||
maintainer merging that PR is acceptance.
|
||||
|
||||
For a plain feature request or open-ended idea, use the **Ideas**
|
||||
category instead. For bugs, open an [Issue](../../issues/new/choose).
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: Problem / motivation
|
||||
description: What needs solving, and why is it worth the long-run cost?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: sketch
|
||||
attributes:
|
||||
label: Proposed direction (sketch)
|
||||
description: A rough shape of the design. Detail comes later in the RFC document.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: invariants
|
||||
attributes:
|
||||
label: Invariants touched
|
||||
description: Which items in docs/dev/invariants.md does this affect or risk? Any deny-list brush?
|
||||
validations:
|
||||
required: false
|
||||
55
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
55
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
name: Bug report
|
||||
description: Report a reproducible problem or wrong behavior in OmniGraph.
|
||||
title: "bug: <short summary>"
|
||||
labels: ["bug", "needs-triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Issues are for **reporting problems** — concrete, reproducible bugs.
|
||||
For ideas, feature requests, or questions, please use
|
||||
[Discussions](../../discussions) instead.
|
||||
For a security vulnerability, follow [SECURITY.md](../../blob/main/SECURITY.md) — do **not** file it here.
|
||||
|
||||
A maintainer will triage this; once labelled **`accepted`** it's open for a pull request
|
||||
(see [GOVERNANCE.md](../../blob/main/GOVERNANCE.md)).
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: What happened
|
||||
description: What went wrong, and what you expected instead.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: repro
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Minimal steps, commands, schema/query, or a failing snippet.
|
||||
placeholder: |
|
||||
1. omnigraph init ...
|
||||
2. omnigraph ...
|
||||
3. observed: ... / expected: ...
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: Output of `omnigraph --version` (or the engine/crate version) and how you installed it.
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: environment
|
||||
attributes:
|
||||
label: Environment
|
||||
description: OS, architecture, and storage backend (local FS / S3 / RustFS / MinIO).
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Logs / output
|
||||
description: Relevant error text or logs. Will be rendered as code.
|
||||
render: shell
|
||||
validations:
|
||||
required: false
|
||||
13
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
13
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Issues are for problem reports only. Disable blank issues so everything is
|
||||
# routed: bugs through the form, everything else to Discussions / SECURITY.md.
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 💡 Idea, feature request, or RFC
|
||||
url: https://github.com/ModernRelay/omnigraph/discussions
|
||||
about: Propose features and designs in Discussions. RFCs graduate from there into a docs/rfcs/ pull request.
|
||||
- name: ❓ Question or help
|
||||
url: https://github.com/ModernRelay/omnigraph/discussions
|
||||
about: Ask in Discussions — questions are not tracked as Issues.
|
||||
- name: 🔒 Security vulnerability
|
||||
url: https://github.com/ModernRelay/omnigraph/blob/main/SECURITY.md
|
||||
about: Report security issues privately per SECURITY.md — never as a public Issue.
|
||||
29
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
29
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<!--
|
||||
Thanks for contributing! See CONTRIBUTING.md and GOVERNANCE.md.
|
||||
A substantive PR needs a backing accepted issue or accepted RFC.
|
||||
Maintainers: your internal process applies; the link requirement below
|
||||
is for external contributions.
|
||||
-->
|
||||
|
||||
## What & why
|
||||
|
||||
<!-- One or two sentences: what this changes and why. -->
|
||||
|
||||
## Backing issue / RFC
|
||||
|
||||
<!-- Pick one. A substantive change needs (1) or (2). -->
|
||||
|
||||
- [ ] Fixes an **accepted** issue: Closes #
|
||||
- [ ] Implements / is an **accepted** RFC: <link to docs/rfcs/NNNN-*.md>
|
||||
- [ ] **Trivial fast-lane** (typo / docs / dependency bump / comment / one-line CI) — no issue/RFC required
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Change is focused (one logical change)
|
||||
- [ ] Tests added/updated for behavior changes (or N/A)
|
||||
- [ ] Public docs updated if user-facing surface changed (or N/A)
|
||||
- [ ] Reviewed against [docs/dev/invariants.md](../blob/main/docs/dev/invariants.md) — no Hard Invariant weakened, no deny-list item hit (or justified)
|
||||
|
||||
## Notes for reviewers
|
||||
|
||||
<!-- Anything that helps review: tradeoffs, follow-ups, areas of risk. -->
|
||||
|
|
@ -1,10 +1,29 @@
|
|||
# Contributing
|
||||
|
||||
Small bug fixes and documentation improvements are welcome directly through pull
|
||||
requests.
|
||||
Thanks for your interest in OmniGraph. This page is the practical how-to; the
|
||||
rules and decision authority behind it live in [GOVERNANCE.md](GOVERNANCE.md).
|
||||
|
||||
For larger changes, please open an issue or design discussion first so the
|
||||
proposed direction is clear before implementation starts.
|
||||
## Start in the right place
|
||||
|
||||
| I want to… | Go to | Notes |
|
||||
|---|---|---|
|
||||
| **Report a bug** or wrong behavior | **[Open an Issue](../../issues/new/choose)** | Concrete and reproducible. A maintainer triages it; once labelled **`accepted`** it's open for a PR. |
|
||||
| **Suggest a feature / share an idea / ask** | **[Start a Discussion](../../discussions)** | Ideas and questions live here, not in Issues. |
|
||||
| **Propose a design / RFC** | **An RFC pull request** | Anyone can author one — see [docs/rfcs/README.md](docs/rfcs/README.md). A maintainer merging it is acceptance. |
|
||||
| **Fix something / implement a change** | **A pull request** | Must link an `accepted` issue or an accepted RFC — unless it's trivial (below). |
|
||||
| **Report a security vulnerability** | **[SECURITY.md](SECURITY.md)** | Do **not** open a public Issue. |
|
||||
|
||||
### When can I just open a PR?
|
||||
The **trivial fast-lane** — open directly, no prior issue/RFC needed: typo and
|
||||
wording fixes, doc corrections, dependency bumps, comment fixes, obvious
|
||||
one-line CI tweaks. Anything more substantial needs a backing `accepted` issue
|
||||
or accepted RFC first, so the *why* is agreed before the *how* is reviewed. A PR
|
||||
that turns out to be non-trivial will be redirected — that's about process, not
|
||||
the merit of the change.
|
||||
|
||||
> **Maintainers (ModernRelay team)** follow a separate internal process and are
|
||||
> not bound by the intake rules above. Everyone is bound by review, CODEOWNERS,
|
||||
> branch protection, and CI.
|
||||
|
||||
## Development
|
||||
|
||||
|
|
@ -49,6 +68,11 @@ CI runs both.
|
|||
|
||||
## Pull Requests
|
||||
|
||||
- keep changes focused
|
||||
- include tests for behavior changes when practical
|
||||
- update public docs when the user-facing surface changes
|
||||
- **Link the backing issue or RFC** (`Closes #123`, or reference the RFC) — or
|
||||
mark the PR as trivial per the fast-lane.
|
||||
- Keep changes focused; one logical change per PR.
|
||||
- Include tests for behavior changes when practical.
|
||||
- Update public docs when the user-facing surface changes.
|
||||
|
||||
New to the codebase? Read [AGENTS.md](AGENTS.md) — the architecture map and the
|
||||
always-on invariants every change is reviewed against.
|
||||
|
|
|
|||
106
GOVERNANCE.md
Normal file
106
GOVERNANCE.md
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
# Governance
|
||||
|
||||
This document describes how **external contributions** to OmniGraph are
|
||||
proposed, accepted, and merged. It exists so an outside contributor can answer,
|
||||
without asking: *where does my report/idea/change go, who decides, and what has
|
||||
to happen before code lands?*
|
||||
|
||||
> **Scope.** This governs the public contribution surface — Issues,
|
||||
> Discussions, RFCs, and pull requests from people outside the ModernRelay
|
||||
> team. **Maintainers operate under a separate internal process** and are not
|
||||
> bound by the intake gates below. Everyone, maintainer or not, is still bound
|
||||
> by the universal gates: branch protection on `main` and CODEOWNERS review
|
||||
> (see [docs/dev/branch-protection.md](docs/dev/branch-protection.md) and
|
||||
> [docs/dev/codeowners.md](docs/dev/codeowners.md)).
|
||||
|
||||
## Roles
|
||||
|
||||
| Role | Who | Authority |
|
||||
|---|---|---|
|
||||
| **Maintainer** | The code owners in [`.github/CODEOWNERS`](.github/CODEOWNERS) (generated from [`.github/codeowners-roles.yml`](.github/codeowners-roles.yml)) | Validate issues, accept/reject RFCs, review and merge PRs, set direction. Final decision authority. |
|
||||
| **Contributor** | Anyone else | Report problems (Issues), propose ideas (Discussions), author RFCs, and open pull requests. |
|
||||
|
||||
Decision authority rests with the maintainers. CODEOWNERS is the single source
|
||||
of truth for who that is; this document does not duplicate the list.
|
||||
|
||||
## The three channels
|
||||
|
||||
Each channel has one job. Using the right one is the first thing we ask of a
|
||||
contribution.
|
||||
|
||||
| Channel | Purpose | Not for |
|
||||
|---|---|---|
|
||||
| **[Issues](../../issues)** | **Report a problem** — a bug, a regression, a documented behavior that's wrong. Something concrete and reproducible. | Feature requests, ideas, questions, or design proposals (→ Discussions). |
|
||||
| **[Discussions](../../discussions)** | **Propose and explore** — new ideas, feature requests, questions, and the incubation of RFCs. | Bug reports (→ Issues). |
|
||||
| **Pull requests** | **Land a sanctioned change** — a fix for a *validated* issue, an *accepted* RFC, or a trivial change (see fast-lane). | Substantive change with no backing issue/RFC — it will be redirected. |
|
||||
|
||||
## How a change becomes mergeable
|
||||
|
||||
```
|
||||
┌─────────── bug ───────────┐ ┌──────── idea / feature ────────┐
|
||||
▼ │ ▼ │
|
||||
Issue (problem report) │ Discussion (idea / RFC incubation) │
|
||||
│ │ │ │
|
||||
maintainer triage │ rough consensus │
|
||||
│ │ │ graduate │
|
||||
▼ │ ▼ │
|
||||
label: accepted ──────────┐ │ RFC PR (docs/rfcs/NNNN-*.md) │
|
||||
│ │ │ │ │
|
||||
│ │ │ maintainer review │
|
||||
▼ ▼ │ ▼ │
|
||||
Pull request ◀──────────┴──────────│── merged == accepted │
|
||||
(links the issue or the accepted RFC) ◀───────┘ (implementation PRs reference it) │
|
||||
│
|
||||
review + CODEOWNERS + branch protection
|
||||
▼
|
||||
merged
|
||||
```
|
||||
|
||||
### Issues → validated
|
||||
A new issue starts unlabeled. A maintainer triages it and, if it's a real,
|
||||
in-scope problem, applies the **`accepted`** label. **Only `accepted` issues are
|
||||
open for a contributor PR.** This prevents the "I fixed an issue you hadn't
|
||||
agreed was a problem" rejection. Want to fix something? Get the issue accepted
|
||||
first, or pick one already labelled `accepted` / `help wanted`.
|
||||
|
||||
### Discussions → RFCs → accepted
|
||||
Ideas and feature requests start in **Discussions**. Anyone — including external
|
||||
contributors — may then **author an RFC** by opening a pull request that adds
|
||||
`docs/rfcs/NNNN-title.md` (see [docs/rfcs/README.md](docs/rfcs/README.md)). The
|
||||
RFC is reviewed as code; **a maintainer merging it is the act of acceptance**
|
||||
(it becomes the durable decision record). Implementation PRs then reference the
|
||||
accepted RFC.
|
||||
|
||||
Authoring an RFC is open to everyone; **accepting one is a maintainer
|
||||
decision.** Maintainers may also decline an RFC, with rationale, by closing it.
|
||||
|
||||
### Pull requests → sanctioned
|
||||
A contributor PR must do one of:
|
||||
1. link a maintainer-**`accepted`** issue it fixes, or
|
||||
2. be (or reference) an **accepted RFC**, or
|
||||
3. qualify for the **trivial fast-lane**.
|
||||
|
||||
**Trivial fast-lane** — these may be opened directly, no prior issue/RFC:
|
||||
typo and wording fixes, documentation corrections, dependency bumps, comment
|
||||
fixes, and obviously-correct one-line CI tweaks. When in doubt, open an Issue or
|
||||
Discussion first; a PR that turns out to be non-trivial will be asked to.
|
||||
|
||||
A substantive PR with no backing issue/RFC will be closed with a pointer to the
|
||||
right channel — not as a judgment of the idea, but to keep design discussion
|
||||
where it's reviewable.
|
||||
|
||||
## What maintainers do *not* gate
|
||||
Maintainers' own changes do not pass through the intake gates above — the team
|
||||
runs a separate internal process. The universal gates (review, CODEOWNERS,
|
||||
branch protection, CI) apply to everyone. Enforcement of the intake rules is, to
|
||||
start, **by convention and review** (PR template + labels); an automated check
|
||||
keyed to author association may be added later if volume warrants.
|
||||
|
||||
## Code of conduct & security
|
||||
- Conduct: [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).
|
||||
- Security issues are **not** public Issues — see [SECURITY.md](SECURITY.md).
|
||||
|
||||
## Changing this document
|
||||
Governance changes the same way code does: a pull request, reviewed by
|
||||
maintainers. This file describes the external surface; the internal maintainer
|
||||
process is intentionally out of scope here.
|
||||
|
|
@ -51,6 +51,18 @@ constraints. User-facing behavior should still be documented through
|
|||
| Install and deployment packaging | [install.md](../user/install.md), [deployment.md](../user/deployment.md) |
|
||||
| Release history | [releases/](../releases/) |
|
||||
|
||||
## Contribution & Governance
|
||||
|
||||
| Area | Read |
|
||||
|---|---|
|
||||
| How to contribute (external) | [CONTRIBUTING.md](../../CONTRIBUTING.md) |
|
||||
| Governance model, roles, decision authority | [GOVERNANCE.md](../../GOVERNANCE.md) |
|
||||
| Public contribution RFC track | [rfcs/](../rfcs/) |
|
||||
|
||||
The `docs/rfcs/` track is the **public, externally-authorable** RFC process. The
|
||||
maintainer/internal RFCs below (`rfc-00N-*.md`) are a separate, team-owned
|
||||
track; don't conflate the two.
|
||||
|
||||
## Active Implementation Plans
|
||||
|
||||
Working documents for in-flight feature work. Removed when the work lands.
|
||||
|
|
|
|||
54
docs/rfcs/0000-template.md
Normal file
54
docs/rfcs/0000-template.md
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
# RFC NNNN: <title>
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Status** | Proposed |
|
||||
| **Author(s)** | <your name / handle> |
|
||||
| **Discussion** | <link to the originating Discussion, if any> |
|
||||
| **Implementation** | <issue/PR links, filled in as work lands> |
|
||||
|
||||
> Status is maintained by maintainers: `Proposed` while the PR is open,
|
||||
> `Accepted` on merge, `Declined` on close, `Superseded by NNNN` later.
|
||||
|
||||
## Summary
|
||||
|
||||
One paragraph: what this changes, in plain terms.
|
||||
|
||||
## Motivation
|
||||
|
||||
What problem does this solve, and why is it worth the ongoing cost? Tie it to a
|
||||
concrete need (a Discussion, a recurring issue, a user request). Per the
|
||||
project's first principle, argue the *long-run liability*, not just the
|
||||
short-term convenience.
|
||||
|
||||
## Guide-level explanation
|
||||
|
||||
Explain the change as you'd teach it to a user or contributor: new commands,
|
||||
syntax, API shapes, behavior. Examples first.
|
||||
|
||||
## Reference-level design
|
||||
|
||||
The precise design: data structures, IR/AST/planner changes, storage/format
|
||||
impact, migration path, error behavior. Enough that a reviewer can find the
|
||||
holes.
|
||||
|
||||
## Invariants & deny-list check
|
||||
|
||||
Which Hard Invariants in [../dev/invariants.md](../dev/invariants.md) does this
|
||||
touch? Does it brush against any deny-list item — and if so, why is this the
|
||||
justified exception? State explicitly that no invariant is weakened, or which
|
||||
Known Gap moves.
|
||||
|
||||
## Drawbacks & alternatives
|
||||
|
||||
What does this cost, what did you reject, and why. "Do nothing" is a valid
|
||||
alternative to weigh.
|
||||
|
||||
## Reversibility
|
||||
|
||||
Is this reversible? On-disk/wire/format and substrate choices are near-permanent
|
||||
and demand more evidence; a CLI flag or doc is cheap to undo. Say which this is.
|
||||
|
||||
## Unresolved questions
|
||||
|
||||
What's deliberately left open for review to settle.
|
||||
66
docs/rfcs/README.md
Normal file
66
docs/rfcs/README.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# RFCs
|
||||
|
||||
Substantial changes to OmniGraph — new user-facing surface, format or protocol
|
||||
changes, anything irreversible or cross-cutting — go through a lightweight RFC
|
||||
so the design is agreed *as reviewable code* before implementation starts. This
|
||||
is the public RFC track, open to **anyone, including external contributors**.
|
||||
|
||||
This complements the always-on review bar in
|
||||
[../dev/invariants.md](../dev/invariants.md): the invariants say *what every
|
||||
change must respect*; an RFC says *why this particular change is worth making and
|
||||
how*.
|
||||
|
||||
> **Two tracks, don't conflate them.** This `docs/rfcs/` directory is the
|
||||
> **public contribution** track (anyone authors; maintainers accept). The
|
||||
> maintainer-internal RFCs under `docs/dev/rfc-00N-*.md` are a separate,
|
||||
> team-owned track for in-flight internal work. If you're an outside
|
||||
> contributor, you're in the right place here.
|
||||
|
||||
## When you need one
|
||||
|
||||
- **RFC required:** new query/schema/CLI/HTTP surface; on-disk or wire-format
|
||||
changes; a new substrate dependency; anything the deny-list in
|
||||
[../dev/invariants.md](../dev/invariants.md) flags; anything irreversible
|
||||
("reversibility shapes evidence demand").
|
||||
- **RFC not required:** bug fixes for an `accepted` issue, and the trivial
|
||||
fast-lane (typos, docs, deps) — see [../../CONTRIBUTING.md](../../CONTRIBUTING.md).
|
||||
|
||||
If you're unsure, start a [Discussion](../../../discussions); a maintainer will
|
||||
tell you whether it needs an RFC.
|
||||
|
||||
## Lifecycle
|
||||
|
||||
```
|
||||
Discussion (incubate, get rough consensus)
|
||||
│ graduate
|
||||
▼
|
||||
RFC pull request → adds docs/rfcs/NNNN-title.md (Status: Proposed)
|
||||
│
|
||||
maintainer review ──▶ changes requested / declined (PR closed, with rationale)
|
||||
│
|
||||
▼
|
||||
merged == Accepted (the merged file is the durable decision record)
|
||||
│
|
||||
▼
|
||||
Implementation PR(s) reference the accepted RFC
|
||||
```
|
||||
|
||||
- **Author:** anyone. **Acceptance:** a maintainer decision, performed by
|
||||
merging the RFC PR. Declining is closing it with rationale.
|
||||
- The merged RFC *is* the accepted record — there is no separate sign-off step.
|
||||
- Later reversals don't edit history: supersede with a new RFC that links back
|
||||
and flip the old one's `Status` to `Superseded`.
|
||||
|
||||
## Numbering & naming
|
||||
|
||||
- File: `docs/rfcs/NNNN-kebab-title.md`, where `NNNN` is the next free
|
||||
zero-padded integer (`0001`, `0002`, …). `0000-template.md` is reserved.
|
||||
- Pick the number when you open the PR; if it collides with another in-flight
|
||||
RFC, the second to merge bumps theirs.
|
||||
|
||||
## Status values
|
||||
|
||||
`Proposed` (open PR) · `Accepted` (merged) · `Declined` (closed) ·
|
||||
`Superseded by NNNN` · `Implemented` (set once the work lands, optional).
|
||||
|
||||
Copy [0000-template.md](0000-template.md) to start.
|
||||
|
|
@ -34,10 +34,15 @@ PY
|
|||
canonical=()
|
||||
while IFS= read -r line; do
|
||||
canonical+=("$line")
|
||||
done < <(find docs -type f -name '*.md' ! -path 'docs/releases/*' ! -path 'docs/internal/*' | sort)
|
||||
done < <(find docs -type f -name '*.md' ! -path 'docs/releases/*' ! -path 'docs/internal/*' ! -path 'docs/rfcs/*' | sort)
|
||||
if [[ -d docs/releases ]]; then
|
||||
canonical+=("docs/releases/")
|
||||
fi
|
||||
# RFCs are a growing collection (like releases): represent the directory, not
|
||||
# every per-RFC file. The dir must be linked from an audience index.
|
||||
if [[ -d docs/rfcs ]]; then
|
||||
canonical+=("docs/rfcs/")
|
||||
fi
|
||||
|
||||
linked=()
|
||||
for index_file in "${index_files[@]}"; do
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue