Browse Source

feat(skills): Add github-ops — GitHub remote operations skill (v2.4.6)

Companion to git-ops (local) and push-gate (pre-push safety). Owns
gh repo create, repo metadata (description / homepage / topics /
visibility), gh release create, README "Recent Updates" enforcement,
and package metadata audit. Three modes: new (first publish), update
(subsequent release), audit (read-only checklist).

Bundles four reference docs codifying conventions for 0xDarkMatter
repos: release strategy (default minor on feat:, patch on fix:-only,
never auto-major), README "Recent Updates" style (claude-mods
per-version blocks vs flarecrawl table), private-by-default repo
visibility, and the audit checklist with topic-derivation rules.

Trims git-ops Release Workflow to stop at the local tag — remote
half (push, gh release create, repo metadata) now delegates to
github-ops, preserving the local/remote skill boundary.

Bumps plugin.json 2.4.5 → 2.4.6, skill count 70 → 71, adds
v2.4.6 entry to README Recent Updates.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0xDarkMatter 1 month ago
parent
commit
cf48ddf656

+ 3 - 2
.claude-plugin/plugin.json

@@ -1,7 +1,7 @@
 {
   "name": "claude-mods",
-  "version": "2.4.5",
-  "description": "Custom commands, skills, and agents for Claude Code - session continuity, 23 expert agents, 70 skills, 3 commands, 6 rules, 4 hooks, 13 output styles, modern CLI tools",
+  "version": "2.4.6",
+  "description": "Custom commands, skills, and agents for Claude Code - session continuity, 23 expert agents, 71 skills, 3 commands, 6 rules, 4 hooks, 13 output styles, modern CLI tools",
   "author": "0xDarkMatter",
   "repository": "https://github.com/0xDarkMatter/claude-mods",
   "license": "MIT",
@@ -70,6 +70,7 @@
       "skills/file-search",
       "skills/find-replace",
       "skills/git-ops",
+      "skills/github-ops",
       "skills/go-ops",
       "skills/introspect",
       "skills/iterate",

+ 8 - 6
README.md

@@ -18,10 +18,13 @@ Built on the [Agent Skills specification](https://agentskills.io/specification)
 
 From Python async patterns to Rust ownership models, from AWS Fargate deployments to Craft CMS development - claude-mods provides the specialized knowledge and tools that transform Claude from a general-purpose assistant into a domain expert who understands your stack, remembers your workflow, and ships production code.
 
-**23 agents. 70 skills. 13 styles. 4 hooks. 6 rules. One install.**
+**23 agents. 71 skills. 13 styles. 4 hooks. 6 rules. One install.**
 
 ## Recent Updates
 
+**v2.4.6** (April 2026)
+- 🐙 **`github-ops` skill** - GitHub remote operations companion to `git-ops` (local) and `push-gate` (pre-push safety). Owns `gh repo create`, repo metadata (description / homepage / topics / visibility), `gh release create`, and the README "Recent Updates" section convention. Three modes: `new` (first publish — audit, scaffold Recent Updates, create private-by-default repo, push, set topics, cut release), `update` (subsequent release — bump version per strategy, update Recent Updates + CHANGELOG, tag, push, release), `audit` (read-only checklist scoring LICENSE / README / package metadata / GitHub state). Bundles four reference docs codifying release strategy (default minor, never auto-major), Recent Updates style (claude-mods per-version blocks vs flarecrawl table), private-by-default visibility, and the full audit checklist with topic-derivation rules. Trims `git-ops` Release Workflow to stop at the local tag; remote half delegates here.
+
 **v2.4.5** (April 2026)
 - 🗄️ **`leveldb-ops` skill** - Read and decode Chromium/Electron LevelDB stores (Local Storage, IndexedDB, Session Storage). Pure-Python via `ccl_chromium_reader` (GitHub-only, not on PyPI) — `plyvel` skipped because Windows wheels don't exist and MSVC compile fails. Ships three reusable scripts (`dump_localstorage.py`, `dump_indexeddb.py`, `extract_keys.py`) and two reference docs: `chromium-format.md` (on-disk layout, append-only semantics, locking quirks per OS) and `claude-desktop-state.md` (full state map for Claude Desktop v1.3109.0 — origin keys, account-binding distinctions, sidebar mutation recipes, MCP iframe partitioning). Codifies the safety pattern (copy-then-delete-LOCK) and the append-only gotcha (last-write-wins per `script_key`). Triggers on Electron app forensics, IndexedDB decoding, "where does the desktop app cache X" questions.
 
@@ -29,11 +32,10 @@ From Python async patterns to Rust ownership models, from AWS Fargate deployment
 - 🔁 **`/iterate` enhancements** - Configurable throughput vs. atomicity tradeoff. New `Batch: N` argument applies N independent changes per iteration; on regression the loop bisects (cherry-pick replay) to identify the culprit, keeping good commits and dropping bad ones — preserves the "git as memory" guarantee while lifting the throughput ceiling. New stop conditions: `Until: <value>` (target metric) and `Stagnation: N` (consecutive no-improvement cap), OR'd with existing `Iterations` cap. New `Branch: auto|<name>|current` for branch isolation — `auto` derives `iterate/<slug-from-goal>` from the Goal text. New `iterate/best` git tag floats forward to the highest-metric commit, surviving any later regression. Always-summarize-on-exit rule — overnight runs interrupted in the morning now produce a final block before yielding control. Skill grew 243 → 356 lines.
 
 **v2.4.3** (April 2026)
-- 🌳 **Worktree-aware `git-ops`** - Folded the briefly-considered `git-status` skill straight into `git-ops` rather than ship a third sibling. T1 inline now exposes `scripts/status.sh` (rich repo overview: HEAD, sync, tree, worktrees, branches, optional PR) and `scripts/worktree-survey.sh` (per-worktree triage table — categorises each as `(trunk)` / `PRUNABLE` / `has WIP` / `unpushed` / `in-flight` / `GHOST` / `ORPHAN` and detects drift between git registration and `.claude/worktrees/` filesystem). New "Worktree Operations" section maps every worktree concern to a tier: T1 survey, T2 create/land/prune-clean, T3 remove (preflight per worktree). Survey-first discipline enforced before any prune recommendation.
-- 🛡️ **`push-gate` skill** - Hard pre-push safety gate. Gitleaks + regex layer secret scan, forbidden-file check, divergence check, dirty-tree refusal, explicit confirm before push. Refuses on any secret hit — no bypass flag. Distinct semantics from `git-ops`: gate, not orchestrator.
-- 📌 **`rules/worktree-boundaries.md`** - Hard rule promoted from user-global into the plugin: never `rm -rf .claude/worktrees/`, never `git add -A` when worktree gitlinks are untracked, never decide another session's worktree is orphaned. Cross-project worktrees are not yours to clean up.
-- 📬 **`auto-skill` visibility fix** - Stop hook's `systemMessage` JSON only reaches Claude, not the user — ~80 suggestions vanished silently in a week. Now also appends to `~/.claude/auto-skill/pending.log`, surfaced at next `/sync` under a "Skill Suggestions" section. Plus a harness whitelist on Gate 1: loading `sync`, `save`, `introspect`, `auto-skill`, `setperms`, or `tool-discovery` no longer disqualifies the session (they're meta/bootstrap, not domain recipes).
-- 🐛 **`push-gate` regex bugs fixed** - Two bugs that blocked every invocation: (1) `\.\.\.'` patterns embedded `'` inside a bash single-quoted string, leaving an orphan `)` that grep rejected; (2) push-gate scanned its own `secret-patterns.txt` corpus and flagged every shape it knew about. Both repaired.
+- 🌳 **Worktree-aware `git-ops`** - T1 inline `scripts/status.sh` (rich repo overview) and `scripts/worktree-survey.sh` (per-worktree triage). New "Worktree Operations" tier mapping; survey-first discipline before any prune.
+- 🛡️ **`push-gate` skill** - Pre-push safety gate. Gitleaks + regex secret scan, forbidden-file check, divergence check, dirty-tree refusal, explicit confirm. Refuses on any hit — no bypass.
+- 📌 **`rules/worktree-boundaries.md`** - Never `rm -rf .claude/worktrees/`, never `git add -A` when worktree gitlinks are untracked, never decide another session's worktree is orphaned.
+- 📬 **`auto-skill` visibility fix** - Stop hook's `systemMessage` only reaches Claude — ~80 suggestions vanished silently in a week. Now also appended to `~/.claude/auto-skill/pending.log`, surfaced at next `/sync`.
 
 **v2.4.1** (April 2026)
 - 🎭 **13 output styles** - Added 8 daemon personalities from Forma: Atlas (strategic advisor), Coach (momentum builder), Harbour (calm stability), Meridian (chief of staff), Noir (hard-boiled detective), Roast (honest friend), Sage (measured precision), Scout (lateral thinker). Standardised all frontmatter to Title Case names and unquoted descriptions.

+ 6 - 2
skills/git-ops/SKILL.md

@@ -237,6 +237,8 @@ The last-resort inline path should only be used for simple T2 operations (single
 
 ### Release Workflow
 
+`git-ops` owns the **local** half of releases only — analysing commits, generating CHANGELOG content, creating the local tag. The **remote** half (push, `gh release create`, repo metadata) belongs to the `github-ops` skill.
+
 When user asks to "create a release", "bump version", or "tag a release":
 
 1. **Inline (T1):** Check current version and commits since last tag
@@ -248,10 +250,12 @@ When user asks to "create a release", "bump version", or "tag a release":
 2. **Determine version bump:**
    - `feat:` commits -> minor bump
    - `fix:` commits -> patch bump
-   - `BREAKING CHANGE:` or `!:` -> major bump
+   - `BREAKING CHANGE:` or `!:` -> requires explicit user approval (never auto-major)
    - Or use version specified by user
 
-3. **Dispatch to git-agent (T2):** Tag, push tag, create GitHub release with generated notes
+3. **Dispatch to git-agent (T2):** Generate CHANGELOG content + create local tag.
+
+4. **Hand off to `github-ops`** for the remote half: push commits, push tag, create the GitHub release with notes, update repo metadata if warranted. Do not call `gh release create` from git-ops — that crosses the local/remote boundary. See `skills/github-ops/SKILL.md` mode `update`.
 
 ### Changelog Generation
 

+ 260 - 0
skills/github-ops/SKILL.md

@@ -0,0 +1,260 @@
+---
+name: github-ops
+description: "GitHub remote operations — repo creation, metadata (description/homepage/topics), releases, README 'Recent Updates' enforcement. Companion to git-ops (local) and push-gate (pre-push safety). Three modes: new (first publish), update (subsequent release), audit (read-only checklist). Triggers on: push to github, publish repo, ship release, cut release, gh release, set topics, repo description, github metadata, recent updates section, audit github repo, repo visibility, make repo public, gh repo create."
+license: MIT
+allowed-tools: "Read Write Edit Bash Glob Grep"
+metadata:
+  author: claude-mods
+  related-skills: git-ops, push-gate, ci-cd-ops
+---
+
+# GitHub Ops
+
+GitHub-side operations skill. Owns everything that talks to `api.github.com` via `gh` CLI: repo creation, metadata configuration, releases, and the conventions that govern how 0xDarkMatter repos present on GitHub.
+
+Sits alongside two related skills:
+
+```
+LOCAL                          BRIDGE              REMOTE (GitHub)
+─────                          ──────              ───────────────
+git-ops                        push-gate           github-ops  (this skill)
+```
+
+| Concern | Owner |
+|---|---|
+| Commits, branches, local tags, rebases, worktrees, stash | `git-ops` |
+| Pre-push secret scan + dirty-tree refusal + confirm | `push-gate` |
+| `gh repo create`, push to remote, tag push | **`github-ops`** |
+| Repo description / homepage / topics / visibility | **`github-ops`** |
+| `gh release create` + release notes | **`github-ops`** |
+| README "Recent Updates" section maintenance | **`github-ops`** |
+| Package metadata audit (pyproject/package.json ↔ GH topics ↔ tag ↔ version) | **`github-ops`** |
+| Issues / PRs / Actions / secrets | **`github-ops`** (future) |
+
+## Hard rules
+
+1. **Visibility defaults to private.** Pass `--private` to `gh repo create` unless the user has explicitly said "public" / "make it public" for this specific repo. See `references/repo-visibility.md`.
+2. **Major version bumps require explicit approval.** Default to minor; patch for fix-only ranges. Never auto-suggest a 1.0.0 from `BREAKING CHANGE:` markers — surface and ask. See `references/release-strategy.md`.
+3. **Always run `push-gate` before any push to a remote.** No exceptions. If push-gate refuses, do not proceed — fix the cause and re-run.
+4. **Delegate local git operations to `git-ops`.** Don't reimplement commit/tag/push logic. github-ops orchestrates the GitHub-side calls (`gh`) and the README/CHANGELOG edits; git-ops handles git itself.
+5. **README "Recent Updates" updates on every release.** This is the one README touch that always happens, regardless of how minor the release. See `references/readme-recent-updates.md` for the canonical claude-mods style.
+6. **Never push without confirming visibility decision.** When creating a new repo, surface visibility as a flippable line in the plan ("creating as **private** — say 'public' to flip"), not buried in flag soup.
+
+## Three modes
+
+### Mode `new` — first publish of a repo
+
+Triggered by: "publish to github", "create repo on github", "push to github" (when no `origin` remote exists), "ship this repo".
+
+```
+1. Audit (run mode `audit` checklist; abort on critical fail)
+   - LICENSE present?
+   - README has tagline + install + quickstart?
+   - pyproject.toml / package.json has description, keywords, license, repository URL?
+   - At least one tag exists (typically v0.1.0)?
+   - CHANGELOG.md has an entry for the latest tag?
+
+2. Add "Recent Updates" section to README if missing
+   - Use claude-mods style by default (see references/readme-recent-updates.md)
+   - Place after Quickstart, before deep "why this exists" sections
+   - For first release, single bullet block describing the initial extraction
+   - Commit via git-ops with: docs: Add Recent Updates section
+
+3. Surface the publish plan to user, with visibility as a flippable line:
+   "Creating as **private** at github.com/<org>/<repo> — say 'public' to flip"
+   Wait for explicit confirmation.
+
+4. Create the repo:
+   gh repo create <org>/<repo> --private --source=. --remote=origin \
+     --description "<derived from package metadata or asked>" \
+     --homepage "<homepage URL or omit>"
+   (NEVER pass --push; we want push-gate to run between)
+
+5. Run push-gate preflight:
+   bash $HOME/.claude/skills/push-gate/scripts/preflight.sh origin main
+   On any non-zero exit: stop, report, do not push.
+
+6. Push main + tags:
+   git -C <repo> push -u origin main
+   git -C <repo> push origin --tags
+
+7. Set topics (derived from package keywords + language + frameworks):
+   gh repo edit <org>/<repo> --add-topic <t1> --add-topic <t2> ...
+   Aim for 6–12 topics. See references/metadata-checklist.md for derivation.
+
+8. Create the release for the latest tag:
+   gh release create <tag> --title "<tag> — <one-line headline>" \
+     --notes "$(extract from CHANGELOG.md)"
+
+9. Verify:
+   gh repo view <org>/<repo>
+   gh release view <tag>
+   Report URL to user.
+```
+
+### Mode `update` — subsequent release
+
+Triggered by: "ship a release", "cut a release", "release v0.X.Y", "publish update".
+
+```
+1. Audit current state vs last release:
+   git -C <repo> log $(git describe --tags --abbrev=0)..HEAD --oneline
+   Categorise commits by Conventional Commits prefix.
+
+2. Determine version bump (see references/release-strategy.md):
+   - Any feat: → minor (default)
+   - Only fix:/chore:/docs:/perf:/style:/test: → patch
+   - Any BREAKING CHANGE: or !: → STOP, ask user, never auto-major
+
+3. Update CHANGELOG.md:
+   New section for the new version with categorised changes (Added/Changed/Fixed/Removed).
+   Delegate the file edit + commit to git-ops with: docs: CHANGELOG for v<N>
+
+4. Update README "Recent Updates":
+   Prepend a new version block (claude-mods style) at the top of the section.
+   Trim oldest if section exceeds 7 versions.
+   Bullets per change, emoji + bold tagline + 1-3 sentence prose.
+   See references/readme-recent-updates.md for the emoji vocabulary.
+
+   For minor: update Recent Updates AND scan diff for new commands/config/install steps;
+              touch README body sections only if found.
+   For patch: update Recent Updates ONLY (single bullet); no body changes unless asked.
+
+5. Commit README + CHANGELOG via git-ops:
+   docs: Recent Updates + CHANGELOG for v<N>
+
+6. Create local tag via git-ops:
+   git tag -a v<N> -m "v<N>"
+
+7. Run push-gate preflight on origin <branch>.
+
+8. Push commits + tag:
+   git push origin <branch>
+   git push origin v<N>
+
+9. Create GitHub release:
+   gh release create v<N> --title "v<N> — <headline>" \
+     --notes "$(extract CHANGELOG section for v<N>)"
+
+10. Verify:
+    gh release view v<N>
+    Report URL to user.
+```
+
+### Mode `audit` — read-only checklist
+
+Triggered by: "audit github repo", "is this repo ready to publish", "check repo metadata", "score this repo".
+
+Read-only — produces a report without making changes. See `references/metadata-checklist.md` for the complete checklist; the SKILL enforces these:
+
+```
+LOCAL FILE CHECKS
+  [ ] LICENSE file present + matches metadata
+  [ ] README has: tagline, install, quickstart, license link
+  [ ] README has "Recent Updates" section near top
+  [ ] CHANGELOG.md present and has entry for latest tag
+  [ ] pyproject.toml / package.json: description, keywords, license, repository URL, homepage
+  [ ] Latest tag matches version in package metadata
+
+GITHUB STATE CHECKS (skip if no remote)
+  [ ] Repo description is set
+  [ ] Repo homepage is set (or explicitly N/A)
+  [ ] At least 3 topics
+  [ ] Topics align with package keywords
+  [ ] Default branch is main (not master)
+  [ ] Latest tag has a corresponding release
+  [ ] Release notes match CHANGELOG entry
+```
+
+Output: per-row pass/fail/warn, then a summary score and list of fixes. Fixes are suggested but not applied — the user decides whether to run mode `new` or mode `update` to act on them.
+
+## Conventions enforced (load reference files for detail)
+
+| Convention | File | Default |
+|---|---|---|
+| Release strategy | `references/release-strategy.md` | minor on `feat:`, patch on `fix:`-only, major requires approval |
+| README Recent Updates style | `references/readme-recent-updates.md` | claude-mods per-version blocks (alternate: flarecrawl table) |
+| Repo visibility default | `references/repo-visibility.md` | `--private` unless user says "public" |
+| Metadata audit checklist | `references/metadata-checklist.md` | full source-of-truth for mode `audit` |
+
+## Git authorship
+
+For 0xDarkMatter repos, set repo-local config before any commit work:
+
+```bash
+git -C <repo> config user.name "0xDarkMatter"
+git -C <repo> config user.email "0xDarkMatter@users.noreply.github.com"
+```
+
+Verify with `git -C <repo> config user.name`. If a commit was made under a different identity *before* publish (no push has happened), rewrite via:
+
+```bash
+git -C <repo> rebase --root --exec 'git commit --amend --reset-author --no-edit'
+```
+
+After history rewrite, re-create any tags so they point at the new SHAs:
+
+```bash
+git -C <repo> tag -d v0.1.0
+git -C <repo> tag -a v0.1.0 -m "..."
+```
+
+This is safe pre-publish only. After push, treat history as immutable and set authorship correctly going forward.
+
+## Delegation pattern
+
+```
+github-ops           git-ops              push-gate
+─────────            ───────              ─────────
+mode `new`:
+  audit
+  edit README   ───► commit (T2)
+                                          preflight (before push)
+  gh repo create
+                ───► push -u origin main
+                ───► push --tags
+  gh repo edit (topics)
+  gh release create
+  verify
+
+mode `update`:
+                ───► CHANGELOG edit + commit (T2)
+  edit Recent Updates
+                ───► commit (T2)
+                ───► tag (T2)
+                                          preflight (before push)
+                ───► push (T2)
+                ───► push tag (T2)
+  gh release create
+  verify
+```
+
+When invoking git-ops T2 operations, dispatch to git-agent with a one-shot prompt — no need to load the full git-ops orchestrator state for these mechanical steps.
+
+## Future expansion (not yet implemented)
+
+- **Issues** — `gh issue create/list/comment/close` workflows
+- **PRs** — `gh pr` operations (note: git-ops T2 currently owns PR creation; could migrate or stay split — decide on first need)
+- **Actions** — workflow file scaffolding, `gh workflow` operations
+- **Secrets** — `gh secret set/list/delete` (with secure handling)
+- **Branch protection** — `gh api` calls for protection rules
+- **Social preview** — image upload via `gh api`
+- **Org-level** — teams, repo templates
+
+When adding any of the above, keep the boundary discipline: anything talking to `api.github.com` belongs here, anything purely local belongs to `git-ops`.
+
+## Files
+
+| File | Role |
+|---|---|
+| `SKILL.md` | This file — modes, rules, delegation |
+| `references/release-strategy.md` | Version bump policy |
+| `references/readme-recent-updates.md` | "Recent Updates" section format + emoji vocabulary |
+| `references/repo-visibility.md` | Private-by-default policy |
+| `references/metadata-checklist.md` | Audit checklist source of truth |
+| `scripts/` | (empty; reserved — extract patterns into scripts when they repeat across uses) |
+| `assets/` | (empty; reserved for README templates / snippets) |
+
+## Why no scripts yet
+
+Initial implementation uses inline `gh`, `jq`, `git -C` calls rather than wrapping them in scripts. Once usage reveals patterns that repeat verbatim across invocations (CHANGELOG extraction is the most likely candidate), extract those into `scripts/` and reference them here. Premature script extraction obscures what the skill is actually doing.

+ 83 - 0
skills/github-ops/references/metadata-checklist.md

@@ -0,0 +1,83 @@
+# Metadata Checklist
+
+Source of truth for mode `audit`. Ordered by criticality.
+
+## Critical (mode `new` aborts on fail)
+
+| Check | How |
+|---|---|
+| LICENSE file present | `[ -f LICENSE ]` |
+| LICENSE matches package metadata | grep license field in pyproject.toml/package.json, compare to LICENSE header |
+| README.md present | `[ -f README.md ]` |
+| README has tagline | first non-empty paragraph is < 200 chars and not a heading |
+| README has install section | `grep -iE '^##\\s+(install|installation|getting started|quickstart)' README.md` |
+| Package metadata file present | `pyproject.toml` (Python) OR `package.json` (Node) OR `Cargo.toml` (Rust) etc. |
+| Package metadata: description set | `jq -r .description` / `tomlq` equivalent |
+| Package metadata: license set | match SPDX identifier |
+| At least one tag | `git tag -l \| head -1` |
+
+## Important (mode `new` warns; mode `update` requires)
+
+| Check | How |
+|---|---|
+| README has "Recent Updates" section | `grep -iE '^##\\s+recent updates' README.md` |
+| CHANGELOG.md present | `[ -f CHANGELOG.md ]` |
+| CHANGELOG has entry for latest tag | `grep -E "^##?\\s*\\[?v?$(latest_tag)" CHANGELOG.md` |
+| Package version matches latest tag | strip `v` prefix from tag, compare to package version field |
+| Package metadata: keywords ≥ 3 | for topic derivation |
+| Package metadata: repository URL | so install instructions work post-publish |
+| Default branch is `main` | `git symbolic-ref refs/remotes/origin/HEAD` (post-push) or local `git branch --show-current` (pre-push) |
+
+## GitHub state (skip if no remote yet)
+
+| Check | How |
+|---|---|
+| Repo description set | `gh repo view --json description` |
+| Repo homepage set OR explicitly N/A | `gh repo view --json homepageUrl` |
+| ≥ 3 topics | `gh repo view --json repositoryTopics` |
+| Topics align with package keywords | set comparison; warn on divergence |
+| Latest tag has a release | `gh release view <tag>` exit code |
+| Release notes present (not empty) | `gh release view <tag> --json body` |
+| Release notes match CHANGELOG entry | substring match (allow formatting differences) |
+
+## Topic derivation
+
+For a fresh publish without explicit topics, derive 6–12 from:
+
+1. **Language** — `python`, `typescript`, `rust`, `go` (from primary language)
+2. **Package keywords** — direct copy from `pyproject.toml` `[project] keywords` or `package.json` `keywords`
+3. **Frameworks** — detected from dependencies (e.g. `react`, `fastapi`, `django`, `astro`, `vue`)
+4. **Domain** — from README headings or package description (e.g. `cli`, `agents`, `ai`, `automation`, `mcp`, `claude-code`)
+5. **Pattern** — recognisable shapes (`job-queue`, `orchestrator`, `daemon`, `headless`, `worktree`)
+
+Cap at 12 (GitHub's limit is 20 but >12 dilutes signal). Validate each topic against GitHub's rules: lowercase, alphanumeric + hyphens, ≤ 50 chars, must start with a letter or number.
+
+## Output format
+
+For mode `audit`, present results as:
+
+```
+GITHUB-OPS AUDIT — <repo path>
+
+CRITICAL
+  ✓ LICENSE present (MIT)
+  ✓ README has tagline + install + quickstart
+  ✗ pyproject.toml missing 'description' field
+
+IMPORTANT
+  ✓ Recent Updates section present
+  ✓ CHANGELOG has entry for v0.1.0
+  ⚠ Package keywords: only 2 (recommend ≥ 3 for topic derivation)
+
+GITHUB STATE
+  - skipped (no origin remote)
+
+SCORE: 8/11 (1 critical, 1 warning)
+
+NEXT ACTIONS
+  1. Add 'description' to pyproject.toml [project] section
+  2. Add 1+ keyword to pyproject.toml
+  Then: re-run audit, or run mode `new` to publish
+```
+
+Critical fails block publish. Warnings surface but don't block. GitHub state checks skipped pre-publish.

+ 130 - 0
skills/github-ops/references/readme-recent-updates.md

@@ -0,0 +1,130 @@
+# README "Recent Updates" Section
+
+Every published 0xDarkMatter repo's README has a **"Recent Updates"** section as a first-class element near the top.
+
+**Why:** Visitors immediately see velocity + what's new without clicking through to CHANGELOG.md. Surfaces project liveness and recent capability adds at a glance.
+
+**Canonical example (DEFAULT style):** https://github.com/0xDarkMatter/claude-mods
+**Alternate (denser, table-based):** https://github.com/0xDarkMatter/flarecrawl
+
+## Default style — claude-mods
+
+Per-version blocks with emoji-prefixed bullets. Use this unless the project's release cadence is so high (multiple per day) that the table style is justified.
+
+```markdown
+## Recent Updates
+
+**v2.4.3** (April 2026)
+
+*   🌳 **Worktree-aware `git-ops`** - Folded the briefly-considered `git-status` skill straight into `git-ops` rather than ship a third sibling. T1 inline now exposes `scripts/status.sh` (rich repo overview...)
+*   🛡️ **`push-gate` skill** - Hard pre-push safety gate. Gitleaks + regex layer secret scan, forbidden-file check, divergence check...
+*   📌 **`rules/worktree-boundaries.md`** - Hard rule promoted from user-global into the plugin: never `rm -rf .claude/worktrees/`...
+
+**v2.4.1** (April 2026)
+
+*   🎭 **13 output styles** - Added 8 daemon personalities from Forma: Atlas (strategic advisor), Coach (momentum builder)...
+
+[View full changelog →](https://github.com/0xDarkMatter/<repo>/commits/main)
+```
+
+### Style rules
+
+- Version header: `**v2.4.3** (Month YYYY)` — bold version, month-year in parens (NOT ISO date)
+- Each change is a bulleted item under the version
+- Bullet prefix: relevant **emoji** + **bold tagline** (often a skill name in backticks like `` `push-gate` skill `` or a capability label)
+- Followed by ` - ` and a **1–2 sentence** prose description with concrete details (file names, flag names, key counts, links to references)
+- Multiple bullets per version is normal and good — one bullet per discrete change
+- 5–7 most recent versions visible; link "View full changelog →" at the bottom to the commits view
+- External references (other tools, articles, posts) get inline markdown links
+
+### Length discipline
+
+Each bullet should be **scannable in one breath** — roughly 30–60 words after the bold tagline. If a bullet runs longer:
+
+- Drop parenthetical category lists ("(`PRUNABLE` / `WIP` / `GHOST` / `ORPHAN`)") — these belong in skill docs, not release notes
+- Drop sub-features ("Plus a harness whitelist on Gate 1: ...") — split into a separate bullet or omit
+- Drop bug fixes from feature releases unless they're the headline — move to a `🐛` bullet only if user-visible
+
+Rule of thumb: a release block of 4 bullets averaging 40 words each (~160 words total) reads cleanly. A block of 5 bullets averaging 80 words each (~400 words) becomes a wall and visitors skim past it.
+
+Long bullets erode the value of the section — visitors should see velocity at a glance, not have to read paragraphs to extract what shipped.
+
+## Alternate style — flarecrawl (table)
+
+Only use when the project ships so frequently that the per-version block format would dominate the README.
+
+```markdown
+## Recent Updates
+
+| Version | Date | Changes |
+| --- | --- | --- |
+| **v0.22.0** | 2026-04-21 | **Secure credential storage.** OS keyring via `flarecrawl[secure]`. Auto-migrates legacy plaintext config.json. 1112 tests |
+| **v0.21.0** | 2026-04-20 | **Auth + crawl fixes.** `--browser-cookies` on scrape/interact/design (was videos-only). `--session` on crawl. `--ignore-robots` made actionable |
+
+For older releases, see [CHANGELOG.md](CHANGELOG.md).
+```
+
+Table style uses ISO dates (YYYY-MM-DD) since it's denser. One row per version, summary in single cell with bold tagline lead.
+
+## Update cadence
+
+- **Patch** release: single-bullet block describing the fix
+- **Minor** release: 2–6 bullets covering each shipped change
+- **Major** release: lead with the breaking change, then enhancements
+
+Update on **every** release regardless of size. This is the one README touch that always happens.
+
+## Placement in README
+
+- After the hero/tagline + quick install or quickstart
+- Before the deep "Why this exists" / feature comparison sections
+- High enough to be visible without scrolling on a typical browser
+
+## Trim policy
+
+When the section grows past ~7 versions, trim oldest version blocks atomically with adding the new one (same commit). CHANGELOG.md keeps the full history.
+
+## Emoji vocabulary
+
+Used consistently across claude-mods. Pick the closest match for each bullet; introducing new emoji is fine when no existing one fits.
+
+| Emoji | Meaning |
+|---|---|
+| 🚀 | launch / major capability |
+| 🔄 | refactor / rename |
+| 🛠️ | tooling |
+| 🛡️ | security / safety |
+| 🌳 | worktree / structural |
+| 📌 | rule / policy |
+| 📬 | messaging / inter-process |
+| 🎭 | personalities / styles |
+| 🐛 | bug fix |
+| 🆕 | new addition |
+| 📚 | docs |
+| 🎯 | architecture / pattern |
+| 🎨 | design / generative |
+| 📐 | spec / standards |
+| 🔍 | introspection / observability |
+| 🔧 | config / settings |
+| 🗑️ | removal |
+| 🔁 | loop / iteration |
+| ⚡ | performance |
+| 📦 | packaging / distribution |
+| 🧪 | tests |
+| 🔌 | integration / plugin |
+
+## Adding the section to a new repo (mode `new`)
+
+For first publish (only v0.1.0 exists), generate a single block summarising the initial release:
+
+```markdown
+## Recent Updates
+
+**v0.1.0** (Month YYYY)
+
+*   🚀 **Initial release** - <one-paragraph summary of what shipped, including key counts (LOC, tests), capability headlines, and any notable provenance>
+
+[View full changelog →](https://github.com/<org>/<repo>/commits/main)
+```
+
+Place it between Quickstart and the deep "why this exists" sections.

+ 67 - 0
skills/github-ops/references/release-strategy.md

@@ -0,0 +1,67 @@
+# Release Strategy
+
+Default version-bump policy for github-ops mode `update`.
+
+| Change type | Bump | Example |
+|---|---|---|
+| New feature, capability, command, integration | **minor** (default) | 0.1.0 → 0.2.0 → 0.3.0 |
+| Bug fix, small QoL tweak, doc-only fix, dep bump | **patch** | 0.2.0 → 0.2.1 → 0.2.2 |
+| Breaking change / 1.0.0 promotion | **major** — REQUIRES EXPLICIT APPROVAL | never auto-suggest |
+
+## Decision logic (apply in order)
+
+```
+1. Inspect commits since last tag:
+   git log $(git describe --tags --abbrev=0)..HEAD --oneline
+
+2. Categorise by Conventional Commits prefix:
+   feat:     → feature signal
+   fix:      → fix signal
+   chore: docs: style: perf: test: refactor: → housekeeping signal
+   BREAKING CHANGE: in body, or !: in subject → breaking signal
+
+3. Decide bump:
+   IF any breaking signal:
+     STOP. Surface to user with the breaking commits listed.
+     Ask explicitly: "These changes look breaking. Bump to v<next-major>.0.0,
+     or treat as v<current-major>.<next-minor>.0 with breaking-change notes?"
+     NEVER auto-major.
+
+   ELSE IF any feature signal:
+     bump = minor
+     New version = bump <current>.<minor + 1>.0
+
+   ELSE (only housekeeping/fix signals):
+     bump = patch
+     New version = <current>.<minor>.<patch + 1>
+```
+
+## README touch policy by bump
+
+| Bump | README "Recent Updates" | README body sections |
+|---|---|---|
+| patch | **always** update (single-bullet block) | skip unless explicitly asked |
+| minor | **always** update (multi-bullet block) | scan diff for new commands/config/install steps; touch only if found |
+| major | **always** update (lead with breaking change) | always update (and major needs approval anyway) |
+
+The "Recent Updates" section is the one README touch that always happens. Body changes for minor/major are conditional — checked against the diff, not assumed.
+
+## Rationale
+
+User-stated preferences for 0xDarkMatter repos (codified 2026-04-26):
+- Most work is feature-shaped, so minor is the default — predictable cadence
+- Patches reserved for genuine fixes — preserves signal of what a patch means
+- Pre-1.0 stays pre-1.0 until explicitly promoted — no accidental "this is stable" signal
+- Treat `BREAKING CHANGE:` markers as a signal to ask, not as authorization to bump major
+
+## Mapping to standard semver-from-commits
+
+Aligns with the conventional-commits semver mapping with one explicit override: major bump is gated behind user approval even when breaking-change markers are present in commits. Everything else matches the standard mapping.
+
+## Edge cases
+
+- **Empty range** (no commits since last tag): refuse to release; nothing to ship.
+- **Mixed feat + fix**: minor (feat dominates).
+- **Only chore/docs**: patch (treat as housekeeping release).
+- **First release** (no prior tag): default to v0.1.0, ask for confirmation.
+- **Tag exists for current HEAD already**: refuse (already released this commit).

+ 38 - 0
skills/github-ops/references/repo-visibility.md

@@ -0,0 +1,38 @@
+# Repo Visibility Default
+
+When publishing a new repo to GitHub, **default to private**. Public is opt-in only.
+
+## Why
+
+User-stated preference (codified 2026-04-26): wants control over what's published openly. Private-by-default prevents accidental public exposure of work-in-progress, unfinished projects, or material that needs review before going public.
+
+## Application rules
+
+- `gh repo create` → always pass `--private` unless the user has **explicitly** said "public" / "make it public" / "publish openly" for *this specific repo*.
+- Existing private → public flips also require explicit approval. Use:
+  ```bash
+  gh repo edit <org>/<repo> --visibility public --accept-visibility-change-consequences
+  ```
+- "Push to GitHub" / "publish this" / "ship it" alone = **private**.
+- Even if a repo is going to the 0xDarkMatter org and other repos there are public, do not infer this one should be public.
+- When proposing the publish plan, surface the visibility decision as a **flippable line** the user can read and react to:
+
+  > Creating as **private** at github.com/0xDarkMatter/<repo> — say 'public' to flip.
+
+  Not buried in a flag soup.
+
+## Per-repo override
+
+If a user says "make this one public" for a specific repo, treat that as authorization for that single repo. It does not change the default for future repos. Always ask again on the next new repo.
+
+## What private mode loses
+
+For visibility, list these in the publish plan so the user can make an informed call:
+
+- No public README rendering on github.com (still works for the repo owner)
+- No public clone/star/fork
+- GitHub Actions still works but minutes count against private quota
+- Releases are private
+- Issues/PRs are private
+
+If any of these matter for the project's purpose (e.g. a skill plugin that needs public install URLs, a portfolio piece), the user will likely flip to public — but that's their call to surface.