From 1c533f5482abe5650ea117b3bb4ef930f883aebd Mon Sep 17 00:00:00 2001 From: James Maes Date: Fri, 9 Oct 2026 10:42:27 -0500 Subject: [PATCH 1/3] fix(pr): exempt file-licensed packages, accept the security type, and keep the DCO check robust - pr.yml: an `allow-dependencies-licenses` input (package URLs) for packages whose nuspec names a license file, which the dependency graph reports as NOASSERTION; gclo's LibGit2Sharp and Windows SDK packages fail the license check on every version bump otherwise (EX-0003). - pr.yml: the title check accepts the `security` type that policies/sdlc.md lists; sdlc.md lists `style`, which the check already accepted. - pr.yml: the DCO check wrote an empty TSV field for commits whose author email has no GitHub login, and bash's tab IFS then collapsed the columns so every such commit failed as "no Signed-off-by". The login is written as "-" instead. - exceptions/register.md: EX-0003 (gclo's libgit2 and Windows SDK licenses) and EX-0004 (gclo's in-repository release workflow until the shared one ships); EX-0002's current state notes that gclo now ships SHA256SUMS and attestations. - configs/shell: CheckOperator conflicted with PSAlignAssignmentStatement on every aligned hashtable (the settings file itself included); alignment wins. - MAINTAINERS.md: gclo's adoption status. Co-Authored-By: Claude Fable 5.1 Signed-off-by: James Maes --- .github/workflows/pr.yml | 19 ++++++-- MAINTAINERS.md | 2 +- configs/shell/PSScriptAnalyzerSettings.psd1 | 4 +- exceptions/register.md | 53 ++++++++++++++++++++- policies/sdlc.md | 2 +- 5 files changed, 71 insertions(+), 9 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index b029eb8..5c86934 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -30,6 +30,14 @@ on: description: Lowest advisory severity that fails dependency review (low, moderate, high, critical). type: string default: low + allow-dependencies-licenses: + description: >- + Comma-separated package URLs (e.g. pkg:nuget/LibGit2Sharp) whose license the + dependency graph cannot read because the package declares a license FILE + instead of an SPDX expression. They are exempt from the license check only; + each one needs an entry in exceptions/register.md. + type: string + default: "" permissions: {} @@ -47,13 +55,13 @@ jobs: run: | # The title becomes the squash commit subject on main (K22-REPO-22), so it # must be a valid Conventional Commits 1.0 header of at most 100 characters. - pattern='^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\([A-Za-z0-9][A-Za-z0-9._/-]*\))?!?: [^[:space:]].*[^.[:space:]]$' + pattern='^(build|chore|ci|docs|feat|fix|perf|refactor|revert|security|style|test)(\([A-Za-z0-9][A-Za-z0-9._/-]*\))?!?: [^[:space:]].*[^.[:space:]]$' if [[ ${#PR_TITLE} -gt 100 ]]; then echo "::error title=PR title too long::${#PR_TITLE} characters; the limit is 100." exit 1 fi if [[ ! "$PR_TITLE" =~ $pattern ]]; then - echo "::error title=PR title is not a Conventional Commit::Expected '()!: ' with type one of build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test, and no trailing period." + echo "::error title=PR title is not a Conventional Commit::Expected '()!: ' with type one of build, chore, ci, docs, feat, fix, perf, refactor, revert, security, style, test, and no trailing period." printf 'Title was: %s\n' "$PR_TITLE" exit 1 fi @@ -77,7 +85,9 @@ jobs: # Developer Certificate of Origin (https://developercertificate.org/): # each commit needs "Signed-off-by: Name " whose email matches the # commit author (git commit -s). Bot accounts (login ending in [bot]) are - # exempt; Dependabot signs off anyway. + # exempt; Dependabot signs off anyway. An author with no GitHub login (an + # email the account does not list) is written as "-": `read` with a tab + # IFS collapses adjacent tabs, so an empty field would shift the columns. set -euo pipefail failed=0 while IFS=$'\t' read -r sha email login message_b64; do @@ -94,7 +104,7 @@ jobs: failed=1 fi done < <(gh api --paginate "repos/$REPO/pulls/$PR_NUMBER/commits" \ - --jq '.[] | [.sha, .commit.author.email, (.author.login // ""), (.commit.message | @base64)] | @tsv') + --jq '.[] | [.sha, .commit.author.email, (.author.login // "-"), (.commit.message | @base64)] | @tsv') exit "$failed" dependency-review: @@ -113,6 +123,7 @@ jobs: # malicious or vulnerable one is just as dangerous as a runtime one. fail-on-scopes: runtime, development, unknown allow-licenses: ${{ inputs.allow-licenses }} + allow-dependencies-licenses: ${{ inputs.allow-dependencies-licenses }} license-check: true vulnerability-check: true comment-summary-in-pr: never diff --git a/MAINTAINERS.md b/MAINTAINERS.md index a4aac9f..8b85494 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -24,7 +24,7 @@ conformance version in its README once it passes the conformance checker. | --- | --- | --- | --- | | [standards](https://github.com/KofTwentyTwo/standards) | These policies, standards, configs, and reusable workflows | Product | Not yet: rulesets and CI being added | | [AppKit](https://github.com/KofTwentyTwo/AppKit) | Shared foundation packages for Windows desktop apps | Product | Adoption in progress | -| [gclo](https://github.com/KofTwentyTwo/gclo) | Clone and update every repository of a GitHub organization (Windows app and CLI) | Product | Adoption in progress | +| [gclo](https://github.com/KofTwentyTwo/gclo) | Clone and update every repository of a GitHub organization (Windows app and CLI) | Product | Adoption in progress: standards gates, governance files, and the Kingsrook layout are in review (gclo #62); settings and exceptions pending | ### Awaiting classification diff --git a/configs/shell/PSScriptAnalyzerSettings.psd1 b/configs/shell/PSScriptAnalyzerSettings.psd1 index cc9d676..cf3f495 100644 --- a/configs/shell/PSScriptAnalyzerSettings.psd1 +++ b/configs/shell/PSScriptAnalyzerSettings.psd1 @@ -32,7 +32,9 @@ # is not checked either way. CheckOpenParen = $false CheckOpenBrace = $false - CheckOperator = $true + # Kingsrook aligns the `=` of consecutive assignments (PSAlignAssignmentStatement + # below); CheckOperator would then flag every aligned line, so it is off. + CheckOperator = $false CheckPipe = $true CheckSeparator = $true CheckParameter = $true diff --git a/exceptions/register.md b/exceptions/register.md index 64feb06..d88edfb 100644 --- a/exceptions/register.md +++ b/exceptions/register.md @@ -7,6 +7,8 @@ Open and closed exceptions to the KofTwentyTwo standards. The process is in | --- | --- | --- | --- | --- | | [EX-0001](#ex-0001) | Open | K22-REPO-20 (approval count), OSPS-QA-07.01 | All repositories | When a second maintainer joins; reviewed 2027-10-09 | | [EX-0002](#ex-0002) | Open | K22-REL-05 (Authenticode signing of Windows binaries) | Windows desktop apps (gclo, AppKit samples, future apps) | When the Azure Trusted Signing identity is validated, at the latest 2027-04-09 | +| [EX-0003](#ex-0003) | Open | K22-DEP-02 (license allowlist) | gclo | Reviewed yearly, next on 2027-10-09 | +| [EX-0004](#ex-0004) | Open | K22-CI-30, K22-REL-04 (shared release workflow) | gclo | When the shared reusable release workflow ships, at the latest 2027-04-09 | ## EX-0001 @@ -50,8 +52,55 @@ Open and closed exceptions to the KofTwentyTwo standards. The process is in - **Compensating controls:** once the shared release workflow ships, every release asset is listed in `SHA256SUMS` and carries a GitHub build-provenance attestation (`K22-REL-04`), so integrity and origin can be verified with `gh attestation verify` - even without a signature. **Current state:** gclo's existing releases have neither; - they gain them when gclo moves to the shared release workflow. + even without a signature. **Current state:** since v1.0.1-beta.1 every gclo release + asset is listed in `SHA256SUMS` and attested (by gclo's own release workflow, see + EX-0004); releases before that have neither. - **Expires:** when the signing identity is validated and the shared release workflow signs Windows binaries; at the latest 2027-04-09. - **Owner:** the maintainer. + +## EX-0003 + +**gclo ships libgit2 (GPL-2.0 with linking exception) and the Microsoft Windows SDK packages** + +- **Requirements:** `K22-DEP-02` requires shipped dependencies to carry an allowlisted + license; any GPL variant needs a recorded exception. +- **Scope:** `KofTwentyTwo/gclo`: the NuGet packages `LibGit2Sharp` (MIT, bundling the + native `libgit2` under GPL-2.0 *with the linking exception*, which permits linking + from MIT code without GPL obligations), `Microsoft.WindowsAppSDK` (Microsoft + Software License Terms, redistributable runtime), and + `Microsoft.Windows.SDK.BuildTools` (Windows SDK license, build-time only). All three + declare their license as a file, so GitHub's dependency graph reports them as + `NOASSERTION`/`unknown` and the `pr / dependency-review` license check fails on any + change to them. +- **Reason:** there is no alternative git implementation for .NET with libgit2's + maturity, and a WinUI 3 app cannot exist without the Windows App SDK. +- **Risk:** none to users under the linking exception and Microsoft's redistribution + terms; the risk is procedural (the automated license gate cannot evaluate them). +- **Compensating controls:** the three packages are named explicitly in the + `allow-dependencies-licenses` input of `pr.yml`, so every other package still goes + through the allowlist; vulnerability checks still apply to them; their terms are + linked from gclo's README attributions. +- **Expires:** reviewed yearly, next on 2027-10-09. +- **Owner:** the maintainer. + +## EX-0004 + +**gclo releases are built by an in-repository workflow until the shared release workflow exists** + +- **Requirements:** `K22-CI-30` and `K22-REL-04` require releases to be built and + attested by a reusable release workflow from this repository (SLSA Build L3). +- **Scope:** `KofTwentyTwo/gclo` (`.github/workflows/release.yml`). +- **Reason:** this repository does not yet publish a reusable release workflow; the + requirement cannot be met by any caller until it does. +- **Risk:** the provenance's `builder.id` names gclo's own workflow rather than an + isolated one, so a compromise of gclo's repository could alter the build definition + and its attestation together (SLSA Build L2 rather than L3). +- **Compensating controls:** the release job is gated on a protected `v*` tag that + must be on `main`, re-runs the CI gates, uses SHA-pinned actions and no caches, + attests provenance and SBOMs through GitHub's OIDC-based attestation actions, and + publishes immutable releases with `SHA256SUMS`. +- **Expires:** when the shared reusable release workflow ships and gclo calls it; at + the latest 2027-04-09. +- **Owner:** the maintainer. + diff --git a/policies/sdlc.md b/policies/sdlc.md index 2a0160e..bd3abe5 100644 --- a/policies/sdlc.md +++ b/policies/sdlc.md @@ -70,7 +70,7 @@ still-supported older line. [Conventional Commits 1.0](https://www.conventionalcommits.org/en/v1.0.0/): `(): `, with `!` or a `BREAKING CHANGE:` footer for incompatible changes. Allowed types: `feat`, `fix`, `perf`, `refactor`, `docs`, `test`, -`build`, `ci`, `chore`, `revert`, `security`. +`build`, `ci`, `chore`, `revert`, `style`, `security`. *Why:* versions and release notes are derived from history, so history must be machine-readable. *Verified by:* `pr / title` check; commit-msg hook. -- 2.54.0 From 0ed03b9bfd203f3f605c24b139eeebff0033d428 Mon Sep 17 00:00:00 2001 From: James Maes Date: Fri, 9 Oct 2026 10:51:27 -0500 Subject: [PATCH 2/3] docs: add a markdownlint configuration so the docs gate can pass The `docs` job (markdownlint-cli2) failed on `main` itself with 686 findings, 666 of them MD013 line length, which K22-CODE-08 does not limit for prose. The new `.markdownlint-cli2.yaml` turns off MD013, MD033 (the release checklist's `
` block), MD036 (the exceptions register's summary lines) and MD041 (the pull-request template starts at a second-level heading). The remaining findings are fixed in place: fenced blocks get a `text` language, the code-span example no longer has leading/trailing spaces, the maintainer email is an autolink, and multiple blank lines are collapsed. Co-Authored-By: Claude Fable 5.1 Signed-off-by: James Maes --- .markdownlint-cli2.yaml | 12 ++++++++++++ CODE_OF_CONDUCT.md | 9 +-------- architecture/windows-desktop-app.md | 2 +- exceptions/register.md | 1 - policies/README.md | 2 +- standards/coding/README.md | 2 +- 6 files changed, 16 insertions(+), 12 deletions(-) create mode 100644 .markdownlint-cli2.yaml diff --git a/.markdownlint-cli2.yaml b/.markdownlint-cli2.yaml new file mode 100644 index 0000000..b1910bf --- /dev/null +++ b/.markdownlint-cli2.yaml @@ -0,0 +1,12 @@ +# markdownlint-cli2 configuration for the standards repository. +# +# K22-CODE-08 sets no line-length limit for prose, and the templates use +#
blocks and emphasised sub-headings deliberately. +config: + default: true + MD013: false # line length: wrapped prose is a style choice, not a rule + MD033: false # inline HTML: release-checklist uses
/ + MD036: false # emphasis as heading: the exceptions register's summary lines + MD041: false # first-line heading: PULL_REQUEST_TEMPLATE starts at ## +ignores: + - node_modules diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 5a02e94..4e679ce 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -7,7 +7,6 @@ We pledge to make our community welcoming, safe, and equitable for all. We are committed to fostering an environment that respects and promotes the dignity, rights, and contributions of all individuals, regardless of characteristics including race, ethnicity, caste, color, age, physical characteristics, neurodiversity, disability, sex or gender, gender identity or expression, sexual orientation, language, philosophy or religion, national or social origin, socio-economic position, level of education, or other status. The same privileges of participation are extended to everyone who participates in good faith and in accordance with this Covenant. - ## Encouraged Behaviors While acknowledging differences in social norms, we all strive to meet our community's expectations for positive behavior. We also understand that our words and actions may be interpreted differently than we intend based on culture, background, or native language. @@ -22,7 +21,6 @@ With these considerations in mind, we agree to behave mindfully toward each othe 6. Committing to **repairing harm** when it occurs. 7. Behaving in other ways that promote and sustain the **well-being of our community**. - ## Restricted Behaviors We agree to restrict the following behaviors in our community. Instances, threats, and promotion of these behaviors are violations of this Code of Conduct. @@ -42,16 +40,14 @@ We agree to restrict the following behaviors in our community. Instances, threat 3. **Promotional materials**. Sharing marketing or other commercial content in a way that is outside the norms of the community. 4. **Irresponsible communication.** Failing to responsibly present content which includes, links or describes any other restricted behaviors. - ## Reporting an Issue Tensions can occur between community members even when they are trying their best to collaborate. Not every conflict represents a code of conduct violation, and this Code of Conduct reinforces encouraged behaviors and norms that can help avoid conflicts and minimize harm. -When an incident does occur, it is important to report it promptly. To report a possible violation, email the maintainer at james@kof22.com, or use the private "Report content" options GitHub provides. Reports are handled by the maintainer listed in [MAINTAINERS.md](MAINTAINERS.md). +When an incident does occur, it is important to report it promptly. To report a possible violation, email the maintainer at , or use the private "Report content" options GitHub provides. Reports are handled by the maintainer listed in [MAINTAINERS.md](MAINTAINERS.md). Community Moderators take reports of violations seriously and will make every effort to respond in a timely manner. They will investigate all reports of code of conduct violations, reviewing messages, logs, and recordings, or interviewing witnesses and other participants. Community Moderators will keep investigation and enforcement actions as transparent as possible while prioritizing safety and confidentiality. In order to honor these values, enforcement actions are carried out in private with the involved parties, but communicating to the whole community may be part of a mutually agreed upon resolution. - ## Addressing and Repairing Harm If an investigation by the Community Moderators finds that this Code of Conduct has been violated, the following enforcement ladder may be used to determine how best to repair harm, based on the incident's impact on the individuals involved and the community as a whole. Depending on the severity of a violation, lower rungs on the ladder may be skipped. @@ -75,12 +71,10 @@ If an investigation by the Community Moderators finds that this Code of Conduct This enforcement ladder is intended as a guideline. It does not limit the ability of Community Managers to use their discretion and judgment, in keeping with the best interests of our community. - ## Scope This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public or other spaces. Examples of representing our community include using an official email address, posting via an official social media account, or acting as an appointed representative at an online or offline event. - ## Attribution This Code of Conduct is adapted from the Contributor Covenant, version 3.0, permanently available at [https://www.contributor-covenant.org/version/3/0/](https://www.contributor-covenant.org/version/3/0/). @@ -88,4 +82,3 @@ This Code of Conduct is adapted from the Contributor Covenant, version 3.0, perm Contributor Covenant is stewarded by the Organization for Ethical Source and licensed under CC BY-SA 4.0. To view a copy of this license, visit [https://creativecommons.org/licenses/by-sa/4.0/](https://creativecommons.org/licenses/by-sa/4.0/) For answers to common questions about Contributor Covenant, see the FAQ at [https://www.contributor-covenant.org/faq](https://www.contributor-covenant.org/faq). Translations are provided at [https://www.contributor-covenant.org/translations](https://www.contributor-covenant.org/translations). Additional enforcement and community guideline resources can be found at [https://www.contributor-covenant.org/resources](https://www.contributor-covenant.org/resources). The enforcement ladder was inspired by the work of [Mozilla’s code of conduct team](https://github.com/mozilla/inclusion). - diff --git a/architecture/windows-desktop-app.md b/architecture/windows-desktop-app.md index 8cf0023..63d680f 100644 --- a/architecture/windows-desktop-app.md +++ b/architecture/windows-desktop-app.md @@ -24,7 +24,7 @@ Windows services are covered in [Variants](#variants). ## 2. Solution layout -``` +```text .slnx Directory.Build.props quality gate, version prefix, package metadata Directory.Packages.props every package version (central package management) diff --git a/exceptions/register.md b/exceptions/register.md index d88edfb..059bec5 100644 --- a/exceptions/register.md +++ b/exceptions/register.md @@ -103,4 +103,3 @@ Open and closed exceptions to the KofTwentyTwo standards. The process is in - **Expires:** when the shared reusable release workflow ships and gclo calls it; at the latest 2027-04-09. - **Owner:** the maintainer. - diff --git a/policies/README.md b/policies/README.md index c3d99dc..5b0c548 100644 --- a/policies/README.md +++ b/policies/README.md @@ -45,7 +45,7 @@ bold capitals. Every requirement has a stable ID so it can be cited from code, CI output, PRs, and the compliance crosswalks: -``` +```text K22-- ``` diff --git a/standards/coding/README.md b/standards/coding/README.md index 7f69220..04a66c4 100644 --- a/standards/coding/README.md +++ b/standards/coding/README.md @@ -111,7 +111,7 @@ IntelliJ plugin generates both comment forms. (Python, Rust, Swift); review for the rest. **K22-CODE-10 (SHOULD)** Comments inside a type or method body are flower boxes: a line -of `/`, the text between `// ` and ` //` padded so every line is the same length, and a +of `/`, the text between `//` and `//` (one space inside each) padded so every line is the same length, and a closing line of `/`. ```java -- 2.54.0 From 3bd60828b50cb0c33083c0a4551781876aaba9bd Mon Sep 17 00:00:00 2001 From: James Maes Date: Fri, 9 Oct 2026 10:53:36 -0500 Subject: [PATCH 3/3] ci: run the link check from an extracted lychee and skip template placeholders The `docs` job downloaded lychee but ran `./lychee`, which the archive does not contain: it unpacks into `lychee-x86_64-unknown-linux-gnu/`. The binary is now extracted under `RUNNER_TEMP` (so its README and docs are not link-checked) and run from there. With the tool actually running, seven internal links failed: the ADR template's `NNNN-title.md` placeholder and the repository templates' `LICENSE` links, which resolve in an adopting repository rather than here (excluded in `lychee.toml`), and the IntelliJ README's links to a `project/.idea/` directory that is not in the repository yet (now plain text marked "not yet published"). Co-Authored-By: Claude Fable 5.1 Signed-off-by: James Maes --- .github/workflows/ci.yml | 12 ++++++++---- configs/intellij/README.md | 6 +++--- lychee.toml | 9 +++++++++ 3 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 lychee.toml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 81c3c19..e5fd817 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,10 +67,14 @@ jobs: run: | set -euo pipefail archive="lychee-x86_64-unknown-linux-gnu.tar.gz" - curl -fsSLO "https://github.com/lycheeverse/lychee/releases/download/lychee-v${LYCHEE_VERSION}/${archive}" - echo "${LYCHEE_SHA256} ${archive}" | sha256sum --check --strict - tar -xzf "${archive}" - ./lychee --offline --include-fragments --no-progress './**/*.md' + tool="${RUNNER_TEMP}/lychee" + mkdir -p "${tool}" + curl -fsSL -o "${tool}/${archive}" "https://github.com/lycheeverse/lychee/releases/download/lychee-v${LYCHEE_VERSION}/${archive}" + (cd "${tool}" && echo "${LYCHEE_SHA256} ${archive}" | sha256sum --check --strict) + # The archive unpacks into a versioned directory with its own README and + # docs; it is extracted outside the checkout so they are not link-checked. + tar -xzf "${tool}/${archive}" -C "${tool}" + "${tool}/lychee-x86_64-unknown-linux-gnu/lychee" --offline --include-fragments --no-progress './**/*.md' conformance: name: conformance diff --git a/configs/intellij/README.md b/configs/intellij/README.md index 8ec103e..4c507bb 100644 --- a/configs/intellij/README.md +++ b/configs/intellij/README.md @@ -8,9 +8,9 @@ Standards: [Java profile](../../standards/coding/java.md), | File | What it is | Origin | | --- | --- | --- | | [`Kingsrook_Code_Style.xml`](Kingsrook_Code_Style.xml) | IDE code-style scheme: Java, JavaScript, TypeScript, JSON, XML, SQL, Shell, CSS, HTML, Groovy, VTL | Kingsrook (Apache-2.0), unmodified | -| [`project/.idea/codeStyles/`](project/.idea/codeStyles) | The same scheme as a per-project style, committed so the whole team gets it automatically | Derived from the above | -| [`project/.idea/checkstyle-idea.xml`](project/.idea/checkstyle-idea.xml) | CheckStyle-IDEA plugin settings pointing at the published KofTwentyTwo checkstyle config | KofTwentyTwo | -| [`project/.idea/copyright/`](project/.idea/copyright) + [`KofTwentyTwo_Copyright_Profile.xml`](KofTwentyTwo_Copyright_Profile.xml) | Copyright profile that inserts the KofTwentyTwo SPDX header (K22-CODE-24) | KofTwentyTwo | +| `project/.idea/codeStyles/` (not yet published) | The same scheme as a per-project style, committed so the whole team gets it automatically | Derived from the above | +| `project/.idea/checkstyle-idea.xml` (not yet published) | CheckStyle-IDEA plugin settings pointing at the published KofTwentyTwo checkstyle config | KofTwentyTwo | +| `project/.idea/copyright/` (not yet published) + [`KofTwentyTwo_Copyright_Profile.xml`](KofTwentyTwo_Copyright_Profile.xml) | Copyright profile that inserts the KofTwentyTwo SPDX header (K22-CODE-24) | KofTwentyTwo | | [`Kingsrook_Copyright_Profile.xml`](Kingsrook_Copyright_Profile.xml) | QQQ's own Apache-2.0 header, for QQQ-derived code only | Kingsrook, unmodified | | [`live-templates/`](live-templates) | Kingsrook Java and SQL live templates (method, getter/setter/fluent setter, JUnit lifecycle, Liquibase changesets) | Kingsrook, unmodified | diff --git a/lychee.toml b/lychee.toml new file mode 100644 index 0000000..d55bab3 --- /dev/null +++ b/lychee.toml @@ -0,0 +1,9 @@ +# lychee configuration for the docs gate (ci.yml "Link check (internal links)"). +# +# Templates link to files that exist in the repository that adopts them, not +# here: the ADR template's "Superseded by" placeholder and the LICENSE every +# repository ships at its root. +exclude = [ + 'NNNN-title\.md$', + 'templates/repo/LICENSE$', +] -- 2.54.0