Skip to content

fix(lychee): exclude private constellation repos from the online lane - #58

Merged
kyle-sexton merged 3 commits into
mainfrom
fix/lychee-private-repo-excludes
Jul 7, 2026
Merged

fix(lychee): exclude private constellation repos from the online lane#58
kyle-sexton merged 3 commits into
mainfrom
fix/lychee-private-repo-excludes

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Problem

The online advisory link-check lane (ci-workflows link-check.yml) reports 404 for every link to a private constellation repo (e.g. kyle-sexton/dotfiles, melodic-software/standards). Those links are valid for authenticated collaborators, but the lane's credential is the calling repo's GITHUB_TOKEN, which cannot read any other private repo — GitHub answers 404 by design. Result: rolling tracking issues (e.g. kyle-sexton/provisioning#36) report links that are not broken.

Fix

Add exclude patterns for the currently-private repos to modules/lychee/lychee.toml, with the justification recorded at the suppression site:

  • Listed per repo, not per owner, so links to public siblings (ci-workflows, claude-code-plugins) stay checked.
  • Boundary guard ([/#?]|$) prevents accidental prefix matches (verified: .../dotfiles-other-repo-name is still checked).
  • Offline lane unaffected (it skips URLs entirely).

Verification

  • modules/lychee/lychee.test.sh: 4/4 PASS.
  • Local lychee 0.24.2 run against a sample: private-repo URLs (incl. deep blob/...#anchor paths) excluded; public-repo URLs checked OK; near-miss repo name not excluded.
  • typos clean on the changed file.

Propagation

Consumers adopt this file by copy — repos with a copied modules/lychee/lychee.toml should pull this update. kyle-sexton/provisioning picks it up in the PR that closes its link-checker report issue.

🤖 Generated with Claude Code

https://claude.ai/code/session_017K9RRMdUKD7HLExmHwMXAe


Note

Low Risk
Config-only URL exclusions for known false positives in the online lychee lane; no runtime or auth logic changes.

Overview
The online advisory link-check lane was reporting 404 for URLs to private constellation repos even when those links are valid for collaborators, because the lane only uses the calling repo’s GITHUB_TOKEN, which cannot read other private repos.

This change extends modules/lychee/lychee.toml exclude with regex patterns for specific private repos under kyle-sexton and melodic-software, documented inline at the suppression site. Patterns are per repo (not whole owners), include an optional .git arm for clone URLs, and use a ([/#?]|$) boundary so similarly named public repos still get checked. The offline lane is unchanged.

Reviewed by Cursor Bugbot for commit fd33fd8. Bugbot is set up for automated code reviews on this repo. Configure here.

Links to private GitHub repos are valid for authenticated collaborators,
but the online advisory lane authenticates with the calling repo's
GITHUB_TOKEN, which cannot read any other private repo — GitHub returns
404 and every scheduled run files a tracking-issue report for links that
are not actually broken. Exclude the currently-private repos by name
(not by owner) so links to public siblings remain checked.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017K9RRMdUKD7HLExmHwMXAe
@claude

claude Bot commented Jul 4, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 12s —— View job


PR Review

  • Gather context (diff, lychee.toml, lychee.test.sh)
  • Review changed file
  • Post findings

The fix is correct and well-scoped. A few observations:

Regex correctness

The boundary guard ([/#?]|$) is the right call — it prevents prefix collisions (e.g. .../dotfiles-other-repo does not match) while still catching deep paths (blob/…#anchor), query strings, and bare repo URLs. The https? alternation and escaped . are correct.

Per-repo granularity

Listing repos individually rather than suppressing entire owners (e.g. kyle-sexton/.*) is the better tradeoff. Public siblings (ci-workflows, claude-code-plugins) stay checked. The PR description calls this out and it's the right design.

Self-reference edge case (minor, no action required)

melodic-software/standards is included in the exclude list at lychee.toml#L36. When the online lane runs inside this repo, the GITHUB_TOKEN can actually read self-links — so they'd be suppressed unnecessarily. In practice this is a minor gap: the file is designed as a propagated shared config for consumers that genuinely can't read a private standards repo, and the tradeoff is reasonable. Worth noting for when standards eventually goes public and the entry can be dropped.

Test coverage (acknowledged limitation)

The existing test suite in lychee.test.sh runs lychee in --offline mode, which skips all URLs — so the new patterns can't be exercised automatically. The PR description notes a manual local lychee run verified the patterns. This is an inherent constraint: testing URL-exclude patterns requires a live network run against a private repo, which isn't feasible in CI. No action needed, just noting the coverage gap is structural, not an oversight.

Maintenance comment

The inline comment is clear and actionable:

# Keep in sync with actual visibility: add newly created private repos here;
# drop an entry when its repo goes public.

This is exactly the right thing to record at the suppression site.

Overall: The approach is sound, the regex is correct, and the inline documentation is good. Approved from a review standpoint. The one minor question is whether standards itself should be in the list (since the token can read self-links), but given that this file propagates to consumers, the current choice is defensible.

cursor[bot]
cursor Bot approved these changes Jul 4, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0332962fed

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread modules/lychee/lychee.toml Outdated
HTTPS clone URLs end in .git, so the [/#?]-or-end boundary missed them
and the online lane still probed the private repo (review finding on
this PR). Optional (\.git)? arm added; boundary behavior for near-miss
repo names (dotfiles-extra, standards-archive) verified unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017K9RRMdUKD7HLExmHwMXAe
@claude

claude Bot commented Jul 4, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 28s —— View job


  • Gather context (diff, lychee.toml, test suite)
  • Review changed file
  • Post findings

PR Review

The second commit (865ed13) correctly addresses the Codex P2 finding about .git clone URLs. Here's the full review of the combined diff.

.git arm placement and correctness

The pattern (\.git)?([/#?]|$) has the right structure. The \.git arm sits between the repo name and the boundary guard, which is the only sensible position. A few edge cases verified manually against the final regex:

URL Expected Result
github.com/kyle-sexton/dotfiles excluded ✅ ($ matches)
github.com/kyle-sexton/dotfiles.git excluded ✅ (\.git then $)
github.com/kyle-sexton/dotfiles/blob/main/foo excluded ✅ (/ matches)
github.com/kyle-sexton/dotfiles.git/blob/main/foo excluded ✅ (\.git then /)
github.com/kyle-sexton/dotfiles-other checked ✅ (- not in boundary)
github.com/kyle-sexton/dotfiles.gitkeep checked ✅ (.git matches, then k fails boundary; backtrack: empty matches, . fails boundary — no match)

Inline comment quality

The comment at lychee.toml#L35 explains exactly why \.git is needed:

# The optional \.git arm covers HTTPS clone URLs, which end in a dot and so
# miss the [/#?] boundary.

This is concise and the reasoning is correct.

Self-reference note (carry-over from prior review, no action needed)

melodic-software/standards at lychee.toml#L37 over-suppresses self-links when the online lane runs inside this repo, since the token can read its own repo. Still a reasonable tradeoff for a propagated config — when standards eventually goes public, this entry can be dropped.

Test coverage (acknowledged structural gap)

lychee.test.sh runs with --offline, so URL-based excludes including the .git variants can't be exercised in CI. The manual verification described in the PR description is the best available option here; this is a structural constraint, not an oversight.

Overall: The fix is correct. The Codex P2 feedback has been properly addressed. No issues blocking merge.

cursor[bot]
cursor Bot approved these changes Jul 4, 2026
@claude

claude Bot commented Jul 7, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 59s —— View job


  • Read CLAUDE.md and review guidelines
  • Review the changed file (modules/lychee/lychee.toml)
  • Check test suite
  • Post findings

PR Review

This review covers the final state of the branch after the merge-from-main commit (fd33fd8). The functional change is unchanged from 865ed13 — the merge introduced no conflicts and no drift.

Regex correctness

Both patterns at lychee.toml#L36–37 are structurally correct. Key edge cases verified:

URL Outcome
github.com/kyle-sexton/dotfiles excluded ($ matches)
github.com/kyle-sexton/dotfiles.git excluded (\.git then $)
github.com/kyle-sexton/dotfiles/blob/main/foo#bar excluded (/ matches)
github.com/kyle-sexton/dotfiles-other checked (- not in boundary set)
github.com/kyle-sexton/dotfiles.gitkeep checked (\.git matches, then k fails boundary; no match)
github.com/melodic-software/standards?tab=readme excluded (? matches)

Per-repo granularity

The alternation groups (dotfiles|provisioning|github-iac) and (standards|github-iac|medley) are the right scope. Public siblings (ci-workflows, claude-code-plugins) are still checked. The github-iac repo appears under both owners — correct if both are private.

Inline comment

The comment block at L29–35 explains the root cause, the design decision, the maintenance obligation, and the \.git arm rationale — all in one compact block. No changes needed.

standards self-reference (carry-over, no action required)

melodic-software/standards is listed at L37. When the online lane runs inside this repo, GITHUB_TOKEN can actually read self-links, so they'd be suppressed unnecessarily. The tradeoff is defensible for a propagated shared config — when standards goes public, drop this entry.

Test coverage (structural gap, no action required)

lychee.test.sh runs --offline, so URL-based excludes cannot be exercised in CI. Manual verification described in the PR description is the best available option; this is inherent to the setup, not an oversight.

Overall: The fix is correct, the Codex P2 feedback was properly addressed in 865ed13, and the branch is clean after the merge from main. No issues blocking merge.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Risk: low. Cursor Bugbot completed successfully with no findings requiring human review. Approved; no reviewers assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@kyle-sexton
kyle-sexton merged commit ba6eb0b into main Jul 7, 2026
37 checks passed
@kyle-sexton
kyle-sexton deleted the fix/lychee-private-repo-excludes branch July 7, 2026 03:19
kyle-sexton added a commit that referenced this pull request Jul 7, 2026
…ed (#69)

## Summary

The first fleet-wide sync PRs surfaced three local consumer edits that a
verbatim overwrite would have destroyed — each resolved at the SSOT per
the Track B operating rule (route changes upstream), with the policy
recorded where it applies:

- **typos** (`modules/typos/_typos.toml`): now carries the
constellation-wide union of domain identifiers — provisioning's
`PnPCapabilities`/`FoD`/`BAAs`, dotfiles' `abd` — each annotated. typos
has no config layering, so repo-local exceptions cannot coexist with a
synced file; the file's own comments now state the route-upstream policy
(decided 2026-07-06, superseding the "adopters add them locally"
guidance from the copy-adoption era). Each identifier only skips its
exact token, so the union is inert elsewhere.
- **shellcheck**: removed from `kyle-sexton/dotfiles`' include list. Its
`.shellcheckrc` is a *documented deliberate* minimal divergence (the
SSOT's `require-double-brackets` — verified enabled — would flag the
statusline's intentional `[ ]` graceful-degradation idiom), with SSOT
alignment already tracked as FU4 in that repo. The manifest comment
carries the re-add trigger. Notably dotfiles has no CI shellcheck lane,
so the overwrite would have broken pre-commit hooks *silently*.
- **lychee** (provisioning's private-repo excludes): already upstream as
#58 — no change here.

Merging this re-fires the sync cascade (paths match), refreshing the
open personal sync PRs so their deletions disappear.

## Verification

Manifest parses (yq); typos lane runs in this PR's own CI against the
updated config; SSOT `require-double-brackets` claim verified against
`modules/shellcheck/.shellcheckrc`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01GbDWhcUtduCejgi7mcbMfy

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Config and manifest-only changes for spellcheck and sync scope; no
runtime or auth paths, with typos union entries scoped to exact tokens.
> 
> **Overview**
> Aligns **Track B** distribution with what the first fleet sync would
have overwritten: typos config and the dotfiles **shellcheck** target.
> 
> **typos** (`modules/typos/_typos.toml`) now documents that the synced
file is read-only downstream and holds a **constellation-wide union** of
`[default.extend-identifiers]` (`abd`, `BAAs`, `FoD`,
`PnPCapabilities`), each annotated, replacing the old “adopters extend
locally” guidance.
> 
> **`kyle-sexton/dotfiles`** no longer includes **shellcheck** in
`distribution/sync-manifest.yml`, with a comment that its local
`.shellcheckrc` intentionally diverges (SSOT `require-double-brackets`
vs statusline `[ ]` idiom, FU4) and should be re-added when that
follow-up lands.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
83493e7. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kyle-sexton added a commit that referenced this pull request Jul 7, 2026
## Summary

Closes out the activation checklist record after tonight's completion:
App access fully done and verified (selected-repos flip, public App,
personal-account installation proven by all four kyle-sexton sync legs
minting tokens, local PEM deleted per key-hygiene guidance); both
Layer-1 packages published and public (`biome-config@1.0.1` post-#70,
`tsconfig@1.0.0`); full-fleet Layer-2 rollout merged across both
accounts, with the first fleet pass's consumer customizations routed
upstream (#58, #69). Remaining opens, each with an owner: the read-only
marking (engine feature) and medley#1243 (Layer-1 pilot, in review).

## Verification

markdownlint (module config) + editorconfig-checker clean.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01GbDWhcUtduCejgi7mcbMfy

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Documentation-only status changes with no runtime, auth, or deployment
impact.
> 
> **Overview**
> Updates the **gated activation checklist** in
`config-distribution-plan.md` to reflect work completed 2026-07-06/07.
> 
> **GitHub App + access** is marked fully done: org install limited to
selected repos (API-verified), App public, personal-account install
proven by all four `kyle-sexton` sync legs minting tokens, and the local
private key removed after secrets validation.
> 
> **Layer-1** narrative now states both packages are published and
public (`biome-config@1.0.1`, `tsconfig@1.0.0`), with the open work
narrowed to checking off the parent item when **medley#1243** merges.
> 
> **Layer-2** is recorded as a **full-fleet rollout** across both
accounts (not only org targets), including examples of consumer
customizations routed upstream on the first pass. The only remaining
blocker before closing that item is **read-only marking** (header
comments + consumer CODEOWNERS), called out as an engine feature rather
than a rollout step.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c75c611. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kyle-sexton added a commit that referenced this pull request Jul 7, 2026
)

## Context

A cross-repo audit of the consumers that adopt this catalog's configs by
copy (kyle-sexton/dotfiles, kyle-sexton/provisioning) surfaced two fixes
that appeared to exist downstream without having been propagated to this
SSOT. Verification against `origin/main` showed only one still needs to
land:

1. **lychee private-repo exclusions — already upstream, no change.**
provisioning fixed its scheduled online link-check 404ing on links to
private constellation repos (melodic-software/provisioning#42 context), and
dotfiles just adopted the same fix. This SSOT already carries it via
#58: `modules/lychee/lychee.toml` on `main` is byte-identical to
provisioning's copy (including the later `(\.git)?` clone-URL arm). The
dotfiles copy is actually one revision *behind* — it predates the
`(\.git)?` refinement — so the flow needed there is a re-copy from here,
not a port to here.

2. **PSScriptAnalyzer settings comment — fixed in this PR.** The comment
above the `PSUseDeclaredVarsMoreThanAssignments` entry claimed it
"promotes to Error". That is factually wrong: a PSScriptAnalyzer
settings file cannot re-map a rule's severity; the entry only enables
the rule, and findings surface at the shipped Warning (which the
top-level `Severity` filter already lets block). The comment now states
the actual behavior. Comment-only; no functional change.

The PSSA fix was deliberately **not** forked in the consumers,
preserving byte-parity with this SSOT — it must land here and flow out
via re-copy.

## Verification

- `modules/powershell/powershell.test.sh`: 3/3 PASS.
- `Invoke-ScriptAnalyzer` on the changed file (self-hosted settings):
clean.
- Pre-commit lanes (typos, editorconfig, gitleaks, psscriptanalyzer):
all pass.

## Propagation

After merge, consumers with copied configs should re-vendor:

- **dotfiles** — `PSScriptAnalyzerSettings.psd1` (this fix) *and*
`modules/lychee/lychee.toml` (to pick up the `(\.git)?` arm it is
missing).
- **provisioning** — `PSScriptAnalyzerSettings.psd1` (its lychee copy is
already current).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_011Bh4hQWCEw3ZJoyQ7nhqVH

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Documentation-only comment change in analyzer settings; no runtime or
lint behavior changes.
> 
> **Overview**
> **Comment-only fix** in `PSScriptAnalyzerSettings.psd1` above
`PSUseDeclaredVarsMoreThanAssignments`.
> 
> The old comment said unused variables are promoted to **Error**. That
was wrong: settings files only **enable** rules; they cannot change a
rule’s built-in severity. Findings stay at the rule’s default
**Warning**, and blocking still comes from the file’s top-level
`Severity = @('Error', 'Warning', 'Information')` filter.
> 
> No rule settings or behavior change—downstream repos that vendor this
file should re-copy after merge for parity.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
02a3116. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
kyle-sexton added a commit that referenced this pull request Jul 15, 2026
… style (#124)

## Summary

Codifies six open decisions from the org's issue/PR consistency
assessment into `conventions/process/issue-tracker.md`:

- **#9** `entities-governance-doc-topology-reference-style` — abstracts
the personal-vs-org repo-topology prose (no more named
`melodic-software/github-iac` / `kyle-sexton/github-iac` links); points
at `github-iac`'s `GovernedRepositories.cs` as the sole source of truth
for which repositories are governed and how.
- **#23** `entities-closing-keyword-house-style-convention` — codifies
native GitHub closing keywords (`Closes`/`Fixes`/`Resolves` `#N`) as the
default house style, with `provisioning`'s stricter requirement (native
keyword plus a manual `## Related` section, per decisions #58/#59) as
the one named exception.
- **#25** `naming-issue-title-vocabulary-governance` — codifies issue
titles as free text with no enforced prefix vocabulary (no `[CC]`-style
conventional-commit tags), documenting the existing silence as a
deliberate choice.
- **#45** `entities-assignee-claiming-guidance-relevance` — keeps the
existing assignee-plus-lease claiming guidance but marks it explicitly
deferred, with an activation trigger (required reviewers /
multi-maintainer assignment contention).
- **#48** `metadata-codeowners-adoption` — adds a one-line note that
CODEOWNERS adoption is deferred, contingent on decision #11
(`required_approving_review_count` staying at 0 org-wide) — CODEOWNERS
is inert without required reviews.
- **#49** `comments-codify-human-conventions` — codifies three optional
documented conventions: a 🤖 footer marking bot-authored comments, citing
evidence when closing on it, and a 🔒 marker for claimed issues
(explicitly framed as the lightweight interim signal until #45's
mechanism activates).

Decisions Log:
https://claude.ai/code/artifact/232ecdce-8316-4880-8c0a-dc3c7dcf3a63

## Test plan

- [x] `lefthook run pre-commit` — typos, editorconfig, gitleaks,
markdownlint all pass
- [x] Grepped the file for residual `kyle-sexton`/named `github-iac`
repo references — none remain
- [ ] Human review of tone/placement against the rest of the process
conventions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
kyle-sexton added a commit that referenced this pull request Jul 22, 2026
…ted scope (#247)

No related issue: rule additions decided on melodic-software/medley#1623
and melodic-software/claude-code-plugins#975

## Summary

- Adds the rule that CLI/agent issue creation always passes `--type`
with one of the org's enabled native types (`Task`/`Bug`/`Feature`); the
web-UI issue form already surfaces the Types field so that path can't
skip it. Placed in `conventions/process/issue-tracker.md`'s existing
"The type axis" section.
- Corrects an existing claim in that same paragraph beyond the two
dictated edits: the doc asserted a `no:type` search qualifier exists to
find untyped issues. Empirically disproved against the live org
(`org:melodic-software is:issue is:open no:type` returned the unfiltered
total of 336, identical to the query with no `no:type` clause at all —
GitHub silently drops the unrecognized qualifier rather than erroring).
Replaced with an accurate description: search exposes a positive
`type:"Bug"`-style qualifier per enabled type but no negation for
"untyped"; finding the untyped remainder means comparing per-type counts
against the total, or reading an issue's `type` field (`null` when
unset).
- Reconciles the `## Related` PR-section requirement from
requires-ci-scoped phrasing ("became the org-wide rule when the shared
`pr-issue-linkage` gate generalized it to every requires-ci repository")
to the fleet-wide convention locked in claude-code-plugins#975's Q12
decision — the practice applies org- and account-wide by convention even
where no CI gate exists to check it mechanically (e.g. `songwriting`,
`knowledge-corpus`). Preserves the one-line historical note that it
began as `provisioning`'s stricter convention (decisions log #58/#59).

## Related

- melodic-software/medley#1623
- melodic-software/claude-code-plugins#975
- #173

🤖 Generated with [Claude Code](https://claude.com/claude-code)

KNOWN ISSUE: hosted CI may fail 0-step/2s (billing) — environmental,
note and continue.

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant