Skip to content

Add copilot-globals sync mechanism (closes #59)#63

Closed
jamditis wants to merge 1 commit into
masterfrom
feat/copilot-globals-sync
Closed

Add copilot-globals sync mechanism (closes #59)#63
jamditis wants to merge 1 commit into
masterfrom
feat/copilot-globals-sync

Conversation

@jamditis
Copy link
Copy Markdown
Owner

@jamditis jamditis commented May 3, 2026

Summary

Hoists Joe's user-level Copilot-PR-review rules out of every project's .github/copilot-instructions.md (which were pushing 3 repos within bytes of the ~4k silent-truncation cap) into a path-scoped .github/instructions/globals.instructions.md file synced from a single source. Per the GitHub Copilot path-specific instructions docs, the bot reads *.instructions.md files in addition to copilot-instructions.md, with applyTo glob and excludeAgent opt-out support.

Architecture explicitly does not slice any project's CLAUDE.md. CLAUDE.md remains the single source of truth for primary coding assistants (Claude Code, etc.) and is not bound by the 4k Copilot cap.

What's in this PR

File Role
scripts/sync-copilot-globals.py CLI: reads source, writes globals.instructions.md to each subscribed repo. Idempotent. Supports --dry-run, --only NAME, --source PATH, --targets PATH.
scripts/sync-targets.txt Subscribed repos list (initially just tools/).
.github/instructions/globals.instructions.md Generated output. Has applyTo: \"**\" frontmatter so Copilot reads it on every PR.
.github/copilot-instructions.md Globals section removed (was 2886 chars, now 2845). Tightened favicon/OG rule scope to resource-kit/docs/**/*.html.
CLAUDE.md Documents the sync workflow + the rule that CLAUDE.md never gets sliced.

Source file

The script reads from ~/.claude/copilot-globals.md (per-user, not in this repo). Initial content (3kb): writing style, banned words, AI-authorship ban, code-quality basics. The script errors clearly if the source is missing.

Test plan

  • python3 -c \"import ast; ast.parse(open(...).read())\" — syntax clean
  • --help renders the docstring
  • First run creates the file
  • Re-run reports unchanged: ...
  • --dry-run previews without writing
  • --source /tmp/missing.md errors with non-zero exit
  • --only nonexistent errors with non-zero exit
  • wc -c .github/copilot-instructions.md confirms reduction (2886 → 2845)
  • wc -c .github/instructions/globals.instructions.md confirms 3081 chars (well under 4k)
  • No CI configured for tools/ — Copilot bot review covers manual verification

Followups (separate PRs, one per repo)

After this lands, three follow-up PRs add each over-cap repo to sync-targets.txt and slim its .github/copilot-instructions.md:

  • rosen-frontend (currently 3995 chars — 5 chars from cap)
  • class (3993 chars)
  • houseofjawn-bot (3992 chars)

Other repos adopt opportunistically (worth doing on socialsnag, claude-skills-journalism, reroute-nj, cjs2026 too — all close enough to cap that a future rule addition could silently truncate).

Reference

MEMORY.mdreference_copilot_pr_review_reading_scope.md for the underlying constraint, and the verified GitHub Copilot path-specific instructions docs (read 2026-05-02) confirming applyTo / excludeAgent schema.

Hoists Joe's user-level review rules out of every project's
.github/copilot-instructions.md (which were pushing 3 repos past the
4k Copilot-read cap) into a path-scoped .github/instructions/globals.instructions.md
file synced from a single source.

- scripts/sync-copilot-globals.py reads ~/.claude/copilot-globals.md
  (hand-curated source) and writes .github/instructions/globals.instructions.md
  into each repo listed in scripts/sync-targets.txt. Supports --dry-run,
  --only NAME filter, and --source / --targets overrides for testing.
  Idempotent (re-runs report 'unchanged').
- scripts/sync-targets.txt: subscribed repos, one absolute path per line,
  '#' for comments, '~' expansion. Initially just tools/.
- .github/instructions/globals.instructions.md: generated output. Has
  applyTo: "**" frontmatter so Copilot's PR reviewer reads it on every
  PR. Contains writing style, banned words, AI-attribution rule, and
  code-quality basics.
- .github/copilot-instructions.md: removed the now-redundant 'Global
  rules to flag' section (down from 2886 to 2845 chars; ~1700 chars
  freed for project-specific bug classes). Tightened the favicon/OG
  rule to scope to resource-kit/docs/**/*.html (the actual deployed
  surface), exempting _archive/**.
- CLAUDE.md: documents the sync workflow, where the source lives,
  and the explicit rule that no project's CLAUDE.md is sliced for the
  Copilot cap. CLAUDE.md remains single source of truth for primary
  coding assistants.

The next 3 PRs (rosen-frontend, class, houseofjawn-bot) add those
repos to sync-targets.txt and slim their copilot-instructions.md
files the same way.
Copilot AI review requested due to automatic review settings May 3, 2026 00:52
@jamditis
Copy link
Copy Markdown
Owner Author

jamditis commented May 3, 2026

Closing — architecturally superseded by PR #60 (Slim global rules to bot-enforceable subset).

PR #60's merge commit message captured the lesson cleanly: "Copilot's PR review bot enforces code-bug-shaped rules but won't flag English-prose conventions like sentence case or banned words." That's the same constraint memorialized in MEMORY.md → feedback_copilot_review_is_bug_finder_not_style_linter.md.

This PR's premise was that the ~1700 chars of English-prose globals (sentence case, banned words, etc.) needed a sync mechanism to live in a separate path-scoped Copilot-readable file. PR #60 dissolved that premise by removing those rules from Copilot-facing files entirely — they belong in CLAUDE.md (which the primary assistant reads and enforces), not in copilot-instructions.md or globals.instructions.md (which Copilot reads but won't act on for prose conventions).

After PR #60, master's .github/copilot-instructions.md is 2886 chars with only 2 bot-enforceable global rules (AI-attribution, favicon/OG) — well under cap with room to grow.

What to do for the 3 over-cap repos instead

The actual remaining followup is to apply PR #60's pattern to rosen-frontend, class, and houseofjawn-bot — slim each to bot-enforceable rules only, removing the English-prose globals. That's a per-repo slim PR, not a sync mechanism. Filing as a separate issue.

Cleanup

  • ~/.claude/copilot-globals.md and tools/scripts/sync-copilot-globals.py are not needed
  • tools/.github/instructions/globals.instructions.md will not be created on master

Procedural lesson going into MEMORY: when starting work in a repo I haven't touched this session, git fetch && git pull --ff-only before git checkout -b so I don't branch off a stale base and step on freshly-merged work. Filed PR #62 against the same stale base — rebasing now.

@jamditis jamditis closed this May 3, 2026
@jamditis jamditis deleted the feat/copilot-globals-sync branch May 3, 2026 00:55
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Introduces a cross-repo sync mechanism to keep Copilot PR review “global” rules in a single source and distribute them into a path-scoped .github/instructions/*.instructions.md file, reducing pressure on the ~4k truncation cap for .github/copilot-instructions.md.

Changes:

  • Added scripts/sync-copilot-globals.py plus scripts/sync-targets.txt to sync ~/.claude/copilot-globals.md into subscribed repos.
  • Added .github/instructions/globals.instructions.md (with applyTo: "**") and removed the duplicated “globals” block from .github/copilot-instructions.md.
  • Documented the workflow and rationale in CLAUDE.md.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
scripts/sync-targets.txt Adds a subscribed-repo list consumed by the sync script.
scripts/sync-copilot-globals.py Implements the CLI that renders and writes the generated Copilot globals file per repo.
CLAUDE.md Documents the new cross-repo Copilot-globals sync workflow and boundaries.
.github/instructions/globals.instructions.md Adds the generated, path-scoped global Copilot instructions file.
.github/copilot-instructions.md Removes duplicated global rules and links to the generated instructions file.


If REPO arguments are given, they override the targets file.
Default source: ~/.claude/copilot-globals.md
Default targets file: tools/scripts/sync-targets.txt (sibling to this script).
DEFAULT_SOURCE = Path.home() / ".claude" / "copilot-globals.md"
DEFAULT_TARGETS_FILE = Path(__file__).resolve().parent / "sync-targets.txt"
GENERATED_HEADER = (
"<!-- Generated by tools/scripts/sync-copilot-globals.py "

These rules apply to ALL pull requests across Joe's repositories. They live here once and are synced into each subscribed repo's `.github/instructions/globals.instructions.md` by `tools/scripts/sync-copilot-globals.py`. Each project's `.github/copilot-instructions.md` then carries only project-specific bug classes, leaving room under the ~4k-char Copilot read cap for that project's real architecture rules.

The Copilot PR review bot reads this file in addition to `.github/copilot-instructions.md` and the project's `CLAUDE.md` / `AGENTS.md` / `GEMINI.md`. None of those need to restate the rules below.
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.

2 participants