| <!-- SPDX-License-Identifier: Apache-2.0 |
| https://www.apache.org/licenses/LICENSE-2.0 --> |
| |
| <!-- START doctoc generated TOC please keep comment here to allow auto update --> |
| <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> |
| **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* |
| |
| - [TODO: `<Project Name>` — project manifest](#todo-project-name--project-manifest) |
| - [Identity](#identity) |
| - [Repositories](#repositories) |
| - [Mailing lists](#mailing-lists) |
| - [Tools enabled](#tools-enabled) |
| - [CVE tooling](#cve-tooling) |
| - [GitHub project board](#github-project-board) |
| - [Mail sources](#mail-sources) |
| - [Backend declaration](#backend-declaration) |
| - [Per-backend config](#per-backend-config) |
| - [Issue-template fields](#issue-template-fields) |
| - [Security workflow configuration](#security-workflow-configuration) |
| - [CVE authority](#cve-authority) |
| - [Governance](#governance) |
| - [Security inbox](#security-inbox) |
| - [Forwarders](#forwarders) |
| - [Mail provider](#mail-provider) |
| - [Archive system](#archive-system) |
| - [Project metadata](#project-metadata) |
| - [Tracker](#tracker) |
| - [Scope detection](#scope-detection) |
| - [Release process](#release-process) |
| - [Roster](#roster) |
| - [Product](#product) |
| - [Pointers to sibling files](#pointers-to-sibling-files) |
| |
| <!-- END doctoc generated TOC please keep comment here to allow auto update --> |
| |
| <!-- SPDX-License-Identifier: Apache-2.0 |
| https://www.apache.org/licenses/LICENSE-2.0 --> |
| |
| # TODO: `<Project Name>` — project manifest |
| |
| This is the **project configuration** for `TODO: <project-name>`. |
| Every skill under [`../../.claude/skills/`](../../skills/) |
| reads the project name from `<project-config>/project.md` and then loads this manifest to resolve project-specific identity, |
| repositories, mailing lists, and references to the other files in |
| this directory. |
| |
| Grep for `TODO` to see every field you still need to fill in: |
| |
| ```bash |
| grep -n TODO projects/<name>/project.md |
| ``` |
| |
| ## Identity |
| |
| | Key | Value | |
| |---|---| |
| | `organization` | TODO: the organization whose defaults this project inherits — e.g. `ASF` ([`organizations/ASF/`](../../organizations/ASF/)). Default `independent` ([`organizations/independent/`](../../organizations/independent/)). See [`organizations/README.md`](../../organizations/README.md). | |
| | `project_name` | TODO: e.g. `Apache Foo` | |
| | `vendor` | TODO: e.g. `Apache Software Foundation` | |
| | `short_name` | TODO: e.g. `Foo` | |
| | `product_family_url` | TODO: e.g. `https://foo.apache.org/` | |
| |
| The `vendor` / `project_name` pair is what lands in the `vendor` and |
| `product` fields of the CVE 5.x record the CVE-JSON generator |
| produces. |
| |
| ## Repositories |
| |
| | Key | Value | Purpose | |
| |---|---|---| |
| | `tracker_repo` | TODO: e.g. `foo-s/foo-s` | Private security tracker (this repo) | |
| | `tracker_repo_url` | TODO | | |
| | `tracker_default_branch` | TODO: e.g. `main` | Default PR target for the tracker repo | |
| | `tracker_project_board_url` | TODO: URL of the GitHub Project V2 board, if any | Security board | |
| | `upstream_repo` | TODO: e.g. `apache/foo` | Public codebase where fixes land | |
| | `upstream_repo_url` | TODO | | |
| | `upstream_default_branch` | TODO: e.g. `master` (older default) or `main` | Upstream's default branch — what `<default-branch>` resolves to. Distinct from `tracker_default_branch` (the security tracker repo's PR target) | |
| | `upstream_agents_md_url` | TODO: `https://github.com/<upstream>/blob/main/AGENTS.md` | Conventions this repo mirrors | |
| | `upstream_contributing_docs_url` | TODO | | |
| | `upstream_genai_disclosure_anchor` | TODO: URL + anchor for the project's Gen-AI disclosure guideline | | |
| | `upstream_security_policy_url` | TODO: `https://github.com/<upstream>/security/policy` | | |
| |
| ## Mailing lists |
| |
| | Key | Value | Notes | |
| |---|---|---| |
| | `security_list` | TODO: e.g. `security@foo.apache.org` | Inbound reports; **not** publicly archived | |
| | `private_list` | TODO: e.g. `private@foo.apache.org` | PMC escalation; **not** publicly archived | |
| | `users_list` | TODO: e.g. `users@foo.apache.org` | Public advisories end up here; publicly archived | |
| | `dev_list` | TODO: e.g. `dev@foo.apache.org` | Release `[RESULT][VOTE]` threads; publicly archived | |
| | `announce_list` | TODO: e.g. `announce@apache.org` | Cross-project announcement list; publicly archived | |
| | `commits_list` | TODO: e.g. `commits@foo.apache.org` | Publicly archived | |
| |
| Only URLs on publicly archived lists may appear in CVE `references[]` as |
| `vendor-advisory`; see `../../AGENTS.md` and |
| [`security-model.md`](security-model.md). |
| |
| The foundation-wide security forwarding address (e.g. `security@apache.org` |
| for ASF projects) is org-level — inherited from your organization's |
| `security_inbox.foundation_security_address`. Do not declare it here. |
| |
| ## Tools enabled |
| |
| | Capability | Tool | Adapter directory | Config knobs declared here | |
| |---|---|---|---| |
| | Issue tracking + project board | `github` | [`../../tools/github/`](../../tools/github/) | `tracker_repo`, `upstream_repo`, `github_project_board_*`, `issue_template_fields` | |
| | Source control (VCS) | `github` (Git) — replaceable with a non-Git VCS | [`../../tools/github/source-control.md`](../../tools/github/source-control.md) | `upstream_repo`, `default_branch`; for a non-Git VCS declare the sibling tool + its working-copy URL | |
| | Inbound email / drafts | `<one or more mail-source backends>` | [`../../tools/mail-source/contract.md`](../../tools/mail-source/contract.md) (abstract) + per-backend adapter dirs (`tools/gmail/`, `tools/ponymail/`, `tools/mail-source/imap/`, `tools/mail-source/mbox/`, ...) | See [Mail sources](#mail-sources) below — declare each backend's role (primary / preferred-for-`<op>` / fallback / optional) and `mandatory` flag | |
| | CVE allocation + record mgmt | *org-level* — inherited from `organizations/<org>/organization.md → cve_authority.tool`; for ASF: `vulnogram` ([`tools/cve-tool-vulnogram/`](../../tools/cve-tool-vulnogram/)), for independent: `mitre-form` | — | override in [CVE authority](#cve-authority) only if this project differs from its org | |
| | Project metadata (rosters / people / releases) | *org-level* — inherited from `organizations/<org>/organization.md → project_metadata.kind`; for ASF: `apache-projects` ([`tools/apache-projects/`](../../tools/apache-projects/)), for independent: `none` | — | override in [Project metadata](#project-metadata) only if this project differs from its org | |
| | Release comms | TODO: the backend that carries release announcements — for ASF: `dev_list` / `announce_list` / `users_list`; for GitHub Releases leave blank | — | whichever release-comms keys the org default or per-project override declares | |
| |
| To replace a tool (e.g. swap GitHub issues for JIRA), declare an |
| alternate tool in the table above, add a `tools/<name>/` adapter |
| directory, and make sure the values the generic skills need are still |
| reachable from this manifest. |
| |
| ## CVE tooling |
| |
| The CNA tool, allocation URL, record URL template, and allocation gate are |
| **org-level** — inherited from your organization's `cve_authority` and |
| `governance` blocks (see |
| [`organizations/ASF/organization.md`](../../organizations/ASF/organization.md) |
| for ASF defaults, |
| [`organizations/independent/organization.md`](../../organizations/independent/organization.md) |
| for the GitHub-native baseline). Override a key in the |
| [Security workflow configuration → CVE authority](#cve-authority) block only |
| if this project's CNA setup genuinely differs from its organization. |
| |
| For **ASF adopters**, fill in the per-project CNA queue fields below — each |
| ASF project has its own queue slug and org UUID, so these are not org-level: |
| |
| | Key | Value | |
| |---|---| |
| | `asf_org_id` | TODO: project's CNA org UUID — e.g. `f0158376-9dc2-43b6-827c-5f631a4d8d09` | |
| | `cna_private_owner` | TODO: e.g. `foo` (CNA_private.owner — the project slug inside the ASF CNA queue) | |
| | `cna_private_projecturl` | TODO: e.g. `https://foo.apache.org/` | |
| | `cna_private_userslist` | TODO: e.g. `users@foo.apache.org` | |
| |
| ## GitHub project board |
| |
| If the project uses a Projects V2 board for its security-issue view, |
| declare the node IDs below. Fetch with the introspection query in |
| [`../../tools/github/project-board.md`](../../tools/github/project-board.md#introspection--re-fetch-the-option-ids). |
| If the project does not run a board, leave the table blank — skills |
| treat missing board config as *"no board reconciliation"*. |
| |
| | Key | Value | |
| |---|---| |
| | `project_board_url` | TODO | |
| | `project_board_number` | TODO | |
| | `project_board_node_id` | TODO | |
| | `status_field_node_id` | TODO | |
| |
| **`Status` column → option-ID mapping** (re-fetch if any write |
| returns `not found`): |
| |
| | Column | Option ID | |
| |---|---| |
| | `Needs triage` | TODO | |
| | `Assessed` | TODO | |
| | `CVE allocated` | TODO | |
| | `PR created` | TODO | |
| | `PR merged` | TODO | |
| | `Fix released` | TODO | |
| | `Announced` | TODO | |
| |
| ## Mail sources |
| |
| The skills treat every supported mail backend the same way — |
| through the abstract operations defined in |
| [`../../tools/mail-source/contract.md`](../../tools/mail-source/contract.md). |
| The adopter declares which backends are configured, what *role* |
| each plays, and whether any are *mandatory*. The skill's resolution |
| rule (see the contract) then picks the right backend per operation |
| at run time. |
| |
| ### Backend declaration |
| |
| One row per configured backend. **Exactly one** row carries |
| `role: primary`. Multiple rows may carry `preferred for <op>` to |
| override the primary for specific operations. `fallback` rows are |
| tried in order when no preferred / primary backend supports the op. |
| `mandatory: yes` means the skill **refuses to run** when that |
| backend is unavailable; `no` means the skill continues with the |
| remaining backends (and skips ops that no available backend supports). |
| |
| | Backend | Role | Mandatory | Notes | |
| |---|---|---|---| |
| | TODO: `gmail` | TODO: e.g. `primary` | TODO: `yes` / `no` | TODO: e.g. "Triager Gmail account subscribed to `<security-list>` and `<private-list>`" | |
| | TODO: `ponymail` | TODO: e.g. `fallback` or `preferred for thread_url` | TODO: `yes` / `no` | TODO: e.g. "Read-only archive backstop; install per [`tools/ponymail/tool.md`](../../tools/ponymail/tool.md)" | |
| | TODO: *(add more rows as needed — `imap`, `mbox`, project-specific adapter)* | | | | |
| |
| > **Mail backend selection is org-level.** The `mail_provider` block in |
| > your organization manifest sets the primary and fallback backends |
| > (for ASF: `primary: gmail-mcp`, `fallback: ponymail`; for independent: |
| > `primary: none`, `fallback: none`). Only declare backends here that |
| > override or extend what the organization manifest provides. For ASF |
| > projects where PonyMail is the inherited fallback, declare it here only |
| > to change its `mandatory` flag or role for this specific project; the |
| > backend itself is already wired by the organization. Install PonyMail per |
| > [`../../tools/ponymail/tool.md`](../../tools/ponymail/tool.md#keeping-the-checkout-current). |
| |
| Reference adapter docs: |
| [`tools/gmail/tool.md`](../../tools/gmail/tool.md) (full read+write), |
| [`tools/ponymail/tool.md`](../../tools/ponymail/tool.md) (read-only ASF archive), |
| [`tools/mail-source/imap/README.md`](../../tools/mail-source/imap/README.md) (stub), |
| [`tools/mail-source/mbox/README.md`](../../tools/mail-source/mbox/README.md) (read-only offline archive — stub). |
| |
| ### Per-backend config |
| |
| Per-backend values the generic recipes substitute in. Only fill in |
| the rows for backends declared above; leave the rest blank or |
| remove the row. |
| |
| | Key | Backend | Value | |
| |---|---|---| |
| | `security_list_domain` | `gmail` | TODO: e.g. `security.foo.apache.org` — Gmail `list:` operator uses the domain form | |
| | `ponymail_private_search_url_template` | `ponymail` | TODO | |
| | `ponymail_public_search_url_template` | `ponymail` | TODO | |
| | `ponymail_api_url_template` | `ponymail` | TODO | |
| | `ponymail_thread_url_template` | `ponymail` | `https://lists.apache.org/thread/<hash>?<list>` | |
| | `imap_host` | `imap` | TODO: e.g. `imap.example.org` | |
| | `imap_account` | `imap` | TODO: e.g. `security-triage@example.org` | |
| | `imap_security_list_folder` | `imap` | TODO: e.g. `INBOX.security-list` | |
| | `imap_drafts_folder` | `imap` | TODO: e.g. `Drafts` (or leave blank to declare `create_draft` unsupported on this adapter) | |
| | `mbox_archive_path` | `mbox` | TODO: e.g. `/srv/audit/security-list-2024.mbox` | |
| |
| ## Issue-template fields |
| |
| The skills' body-field roles map to the following concrete `###` |
| headings in the project's issue template (the concrete YAML file lives in the |
| adopter's `<upstream>` repo; the generic role → field contract is in The generic role → GitHub-field |
| contract lives in |
| [`../../tools/github/issue-template.md`](../../tools/github/issue-template.md); |
| the concrete names below are what skills read and write for this |
| project. |
| |
| | Role (generic) | Field name | Template type | Required? | |
| |---|---|---|---| |
| | `issue-description` | TODO | `textarea` | TODO | |
| | `public-summary` | TODO | `textarea` | TODO | |
| | `affected-versions` | TODO | `input` | TODO | |
| | `security-thread` | TODO | `input` | TODO | |
| | `public-advisory-url` | TODO | `input` | TODO | |
| | `reporter-credit` | TODO | `input` | TODO | |
| | `pr-with-fix` | TODO | `input` | TODO | |
| | `cwe` | TODO | `input` | TODO | |
| | `severity` | TODO | `dropdown` | TODO | |
| | `cve-tool-link` | TODO | `input` | TODO | |
| |
| ## Security workflow configuration |
| |
| Skills resolve every workflow knob from the three-layer chain |
| `project.md → organizations/<org>/organization.md → framework default` |
| (see [`AGENTS.md` § Configuration resolution order](../../AGENTS.md#configuration-resolution-order)). |
| The **organization** you named under *Identity* supplies the org-wide |
| defaults — the CNA tool, the governance gate, the mail / forwarder / |
| archive backends, the project-metadata source, and the release-manager |
| lookup cascade. For an ASF project these resolve to the Vulnogram / |
| PonyMail / `apache-projects-mcp` / ASF-security values in |
| [`organizations/ASF/organization.md`](../../organizations/ASF/organization.md); |
| `organization: independent` inherits the GitHub-native baseline in |
| [`organizations/independent/organization.md`](../../organizations/independent/organization.md). |
| |
| **Declare below only what is specific to this project.** Each block that |
| is purely org-level says so and shows nothing — copy the matching key |
| from the organization manifest down into that block only to override it |
| (the project value wins). The blocks that every adopter fills in keep |
| their per-project keys. |
| |
| ### CVE authority |
| |
| Org-level — inherited from your organization's `cve_authority` block |
| (CNA tool, allocate / record / source-tab URLs, state mapping, |
| propagation, allocation-email flag, reviewer channel). Override a single |
| key here only if this project's CNA setup differs from its organization. |
| |
| ### Governance |
| |
| Org-level except the escalation contact: the allocation gate, gate |
| label, release-vote gating, private governance list, and roster URL are |
| inherited. Declare this project's escalation contact: |
| |
| ```yaml |
| governance: |
| # GitHub handle (or external contact) the skills cc / @-mention when |
| # escalating beyond the security team. |
| # Consumed by: security-issue-sync, pr-management-triage. |
| escalation_contact: "@<escalation-contact>" |
| ``` |
| |
| ### Security inbox |
| |
| Org-level except the concrete address: the inbox `kind`, the foundation |
| security address, the `has_forwarder_relay` flag, and the list filter are |
| inherited. Declare this project's inbound address: |
| |
| ```yaml |
| security_inbox: |
| # The concrete inbound address / channel ID / form URL for this project. |
| # Consumed by: security-issue-import, security-issue-sync, canned-responses. |
| address: <security-list> |
| ``` |
| |
| ### Forwarders |
| |
| Org-level — inherited from your organization's `forwarders` block (which |
| relay adapters are enabled and their per-adapter detect / credit rules). |
| Override here only to enable an extra relay this project uses. |
| |
| ### Mail provider |
| |
| Org-level — inherited from your organization's `mail_provider` block |
| (primary + fallback mail backends). Override here only if this project |
| reads mail from a different backend than its organization. |
| |
| ### Archive system |
| |
| Org-level — inherited from your organization's `archive_system` block |
| (public-archive backend + URL templates). Override here only if this |
| project's advisories surface on a different archive than its organization. |
| |
| ### Project metadata |
| |
| Org-level — inherited from your organization's `project_metadata` block |
| (roster / people / releases backend + whether it is mandatory). Override |
| here only if this project uses a different metadata source. |
| |
| ### Tracker |
| |
| The tracker `platform`, `board`, `visibility`, and `skill_url_template` |
| are org-level defaults — override them here only if this project differs |
| (e.g. a project that runs its security tracker publicly sets |
| `visibility: public`). Declare this project's per-tracker vocabulary: |
| |
| ```yaml |
| tracker: |
| # Whether the reporter can see the tracker issue once opened. |
| reporter_has_access: false |
| |
| # Whether the tracker drives a board / kanban view. |
| project_board_enabled: true |
| |
| # Body-field heading names — role -> the concrete `###` heading in this |
| # project's issue template. Skills refer to these by role. |
| # Consumed by: every skill that reads/writes the issue body. |
| body_fields: |
| cve_link: "CVE tool link" |
| mailing_thread: "Mailing list thread URL" |
| affected_versions: "Affected versions" |
| |
| # Tracker labels — role -> the concrete label name in this project. |
| # Consumed by: security-issue-triage, security-issue-sync, pr-management-triage. |
| labels: |
| security_marker: "security" |
| needs_triage: "needs triage" |
| pr_open: "pr created" |
| pr_merged: "pr merged" |
| cve_allocated: "cve allocated" |
| not_cve_worthy: "not cve worthy" |
| # Label on the single open "rejected without tracker" ledger issue |
| # (see below). NOT the security_marker label. |
| rejections_ledger: "rejections-ledger" |
| ``` |
| |
| #### Rejected-without-tracker ledger |
| |
| The `security-issue-import` skill sometimes rejects a report with a |
| canned reply **without creating a tracker** (the disposition lives only |
| on the mail thread). To keep those rejections countable, the team |
| records each one as a comment on a single dedicated **ledger issue** in |
| `tracker_repo`: one **open** issue, labelled with the |
| `tracker.labels.rejections_ledger` value (default `rejections-ledger`) |
| and **not** carrying the security-marker label. |
| |
| Adopters who want the *rejected without tracker* dashboard stat must: |
| |
| 1. **Create the ledger issue** once in `tracker_repo` and label it |
| `rejections-ledger` (keep it open; the skills resolve it via |
| `gh issue list --repo <tracker> --state open --label |
| rejections-ledger`). |
| 2. **Set the dashboard knob.** Point |
| `security-tracker-stats.md → rejections_ledger_label` (or the |
| `rejections_ledger_label:` key in the renderer's YAML overlay) at the |
| same label. Set it to `null` to disable the stat — then no ledger |
| issue is needed. |
| |
| Each rejection comment carries a machine-parseable block |
| (`<!-- rejection v1 -->` with `date:` / `reporter:` / `canned:` / |
| `thread:` / `summary:` lines); a one-time historical backfill is a |
| single `<!-- rejection-backfill v1 count: N -->` comment. The |
| `security-tracker-stats-dashboard` renderer parses these and excludes the |
| ledger issue from all tracker classification. Closes handled by |
| `security-issue-invalidate` are **not** ledger entries. |
| |
| ### Scope detection |
| |
| Per-project — whether this project distinguishes scope sub-products, and |
| the label → sub-product map: |
| |
| ```yaml |
| scope_detection: |
| # When false, every issue maps to the single product in the `product` block. |
| # Consumed by: security-issue-triage, generate-cve-json, security-issue-sync. |
| enabled: true |
| |
| # Scope label -> sub-product: tracker label -> CVE product / packageName |
| # / upstream path-prefix the skill uses to confirm a PR touches that scope. |
| labels: |
| <scope-label>: |
| product: "<Product Name>" |
| packageName: "<package-name>" |
| path_prefix: "<path-prefix-regex>" |
| <secondary-scope-label>: |
| product: "<Secondary Product Name>" |
| packageName: "<secondary-package-name>" |
| path_prefix: "<secondary-path-prefix-regex>" |
| ``` |
| |
| ### Release process |
| |
| The release-manager lookup cascade and artifact registries are org-level |
| and inherited. Declare this project's stale milestones and changelog |
| fragment tool: |
| |
| ```yaml |
| release_process: |
| # Milestones the skills treat as "stale" (overdue for re-targeting) — |
| # exact milestone-name matches. |
| # Consumed by: security-issue-sync, pr-management-triage. |
| stale_milestones: |
| - "<stale-milestone-1>" |
| - "<stale-milestone-2>" |
| |
| # Whether the upstream repo uses a changelog-fragment tool, and which one. |
| # Consumed by: security-issue-fix, issue-fix-workflow. |
| newsfragments: |
| enabled: true |
| tool: <fragment-tool> |
| ``` |
| |
| ### Roster |
| |
| The roster `source` is org-level and inherited. Declare this project's |
| bare-name → handle map and release managers: |
| |
| ```yaml |
| roster: |
| # Mailing-list threads reference contributors by first name; this binds |
| # those to GitHub handles for @-mentions. |
| # Consumed by: security-issue-sync, pr-management-mentor. |
| bare_name_handles: |
| # Example (replace with your project's contributors): |
| "<FirstName>": "@<handle>" |
| |
| # Release-manager handles, current first. Keep in sync with release-trains.md. |
| # Consumed by: security-issue-sync, security-issue-fix. |
| release_managers: |
| # Example (replace with your project's release managers): |
| - "@<handle>" |
| ``` |
| |
| ### Product |
| |
| Per-project — the product identity used in CVE records, advisories, and |
| title normalization: |
| |
| ```yaml |
| product: |
| # Human-readable product name — lands in the CVE record's `product` field. |
| # Consumed by: generate-cve-json, canned-responses templating. |
| name: <ProjectShortName> |
| |
| # Package-name shape for the primary artifact (PyPI / npm / Maven). |
| # Consumed by: generate-cve-json, canned-responses templating. |
| package_name: <package-name> |
| |
| # Regex matched against changed paths in an upstream PR to confirm |
| # "this PR really touches the product" — a backstop in the fix flow. |
| # Consumed by: security-issue-fix, pr-management-triage. |
| code_pointer_path_prefix: "<code-path-prefix-regex>" |
| |
| # Prefixes the title-normalization skill strips from an inbound subject |
| # when building a CVE title (matched at the start, case-insensitively). |
| # Consumed by: title-normalization, generate-cve-json, canned-responses. |
| subject_prefix_strip: |
| - "[SECURITY]" |
| - "[Security Report]" |
| - "Re:" |
| - "Fwd:" |
| - "<vendor>:" |
| - "<vendor> <product>:" |
| |
| # Prefix the affected-versions extractor strips to leave the bare version. |
| # Consumed by: security-issue-sync, generate-cve-json. |
| affected_version_extract_prefix: "<ProjectShortName>" |
| ``` |
| |
| ## Pointers to sibling files |
| |
| - [`release-trains.md`](release-trains.md) — fast-moving release state, release-manager attribution, security-team roster. |
| - [`milestones.md`](milestones.md) — milestone naming conventions. |
| - [`scope-labels.md`](scope-labels.md) — scope label → CVE product mapping. |
| - [`security-model.md`](security-model.md) — Security-Model URL + anchors. |
| - [`title-normalization.md`](title-normalization.md) — CVE title strip cascade. |
| - [`fix-workflow.md`](fix-workflow.md) — fork / toolchain / commit-trailer specifics. |
| - [`naming-conventions.md`](naming-conventions.md) — project-specific editorial rules. |
| - [`canned-responses.md`](canned-responses.md) — reporter-facing reply templates. |
| - [`skill-sources.md`](skill-sources.md) — trusted external skill sources this project pulls skills from (the install gate). |
| - [`README.md`](README.md) — project file index + onboarding checklist. |