agentsclimarketplace

Ci preflight

Skill The-Artificer-of-Ciphers-LLC/skills-from-the-artificer/ci-preflight

29 drop-in Claude Code skills: cost-tier model routing, debugging (rubber-duck, test-first-bugfix, trust-but-verify), and 24 laws-of-software reference skills. Install with: npx skills add The-Artificer-of-Ciphers-LLC/skills-from-the-artificer --all

Install
npx -y skills add The-Artificer-of-Ciphers-LLC/skills-from-the-artificer --skill ci-preflight

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Run before pushing any branch that adds shipped files, hooks, or platform-specific code. Prevents the CI-whiplash pattern — multiple red pushes that could have been caught locally.

SKILL.md

6.7 KB, as published. Nobody here has run it

CI Preflight

A green CI is not a reward for guessing correctly. It's the outcome of a local gate that already ran.

The three CI-whiplash anti-patterns

This skill exists because these three failures happen repeatedly and all have the same root cause: pushing before checking.


Anti-pattern 1: Missing registration surfaces

What happens: A new shipped file (hook, agent, command, module) passes unit tests but fails integration tests because it wasn't added to one of several whitelists/registries/inventories the repo maintains.

Why it's hard: These surfaces are spread across multiple files with no obvious connection — you find one and miss two others.

Rule: Before pushing any new file that ships to users, run a completeness search.

# Find every place "existing-hook.js" is referenced in the repo
grep -r "gsd-existing-hook" . --include="*.js" --include="*.cjs" --include="*.md" --include="*.json" -l

Use an existing sibling file as the probe: if gsd-existing-hook.js appears in N files, your new hook must appear in the same N files. Missing even one fails CI.

In this repo, adding a new hook requires updating all of:

  • hooks/managed-hooks-registry.cjsMANAGED_HOOKS array
  • scripts/build-hooks.jsHOOKS_TO_COPY array
  • bin/install.js — registration block with fs.existsSync guard
  • get-shit-done/bin/lib/installer-migration-report.cjsBUNDLED_GSD_HOOK_FILES Set
  • docs/INVENTORY.md — headline count + table row
  • docs/INVENTORY-MANIFEST.json — run node scripts/gen-inventory-manifest.cjs --write

The pattern generalises: every repo with drift-guard tests has its own set of registration surfaces. Find them before you write the first line.


Anti-pattern 2: No local test run before pushing

What happens: Tests that would have caught the problem run in CI but not locally. Each failure costs a full CI round-trip (5–15 minutes) instead of a 30-second local run.

Rule: Run the repo's full test command before every push. Not a subset — the full suite.

npm test           # or whatever this repo uses
npm run lint       # catch lint errors before they hit CI

If the full suite is too slow for every push, run npm test:affected (or the repo's equivalent) — but know what it misses.

⚠️ npm test does not always mirror CI's unit scope. In gsd-core specifically, the default npm test (node scripts/run-tests.cjs) selects a different set than CI's unit job — observed in practice reporting fail 0 locally while CI's unit job failed on inventory-counts. Mirror the CI unit job directly before pushing:

npm run test:unit          # mirrors CI's "test (ubuntu, NN)" / "full test" unit scope; catches drift-guard tests npm test can skip

Specific CI gates to run locally before pushing:

npm run lint:changeset     # catches missing/malformed changeset
npm run lint:docs          # catches missing docs update
node scripts/gen-inventory-manifest.cjs  # verify manifest is current
node --test tests/inventory-counts.test.cjs tests/inventory-manifest-sync.test.cjs tests/bug-3628*

When you add a new shipped surface, run the drift-guard tests explicitly — they're fast and catch exactly the "I forgot to update the registry" error.


Anti-pattern 3: Guessing at cross-platform fixes

What happens: A test fails on a platform you can't run locally (Windows). You form a hypothesis, push a fix, it fails again. Repeat 3 times.

Why it's expensive: Each guess costs a full 10-minute Windows CI run. Three guesses = 30 minutes of CI time and a messy commit history.

Rule: Diagnose before fixing. Understand exactly what the platform does differently before writing a single line of code.

Diagnosis checklist for cross-platform path failures:

  1. Read the failure message literally. "Path inside worktree should pass. stderr: (empty)" means the hook is exiting 2 (blocking) when it should pass. The path comparison is producing false negatives, not false positives.

  2. Identify the data sources. List every path-valued variable and its origin:

    • Test-constructed path (via path.join, os.tmpdir, fs.realpathSync)
    • Git-returned path (git rev-parse --show-toplevel output)
    • path.resolve() output
    • fs.realpathSync() output On Windows these can differ in: separator (/ vs \), case (Runner vs runner), 8.3 short name vs long name.
  3. Find the mismatch. On Windows, os.tmpdir() returns C:\Users\RUNNER~1\AppData\Local\Temp (8.3 short name). fs.realpathSync expands to the long name. git --show-toplevel returns whatever form the working tree was registered under. These three can all differ.

  4. Design for sameness, not normalisation. The fix for "two path values that might not match" is usually to ensure they come from the same source rather than normalising disparate sources into a common form. In this PR: comparing two git --show-toplevel outputs (same binary, same format) worked; comparing path.resolve vs realpathSync didn't.

The key insight: Normalisation fights the platform. Sameness of origin avoids the fight entirely.


Pre-push checklist

Run through this before every git push on a branch that changes shipped files:

[ ] npm run test:unit (mirrors CI's unit job — npm test alone can under-cover it; see Anti-pattern 2)
[ ] npm run lint
[ ] If adding a new shipped file:
    [ ] Grepped for an existing sibling to find all registration surfaces
    [ ] Added to every surface the sibling appears in
    [ ] Ran drift-guard tests directly: node --test tests/inventory-*.test.cjs tests/bug-*whitelist*.test.cjs
[ ] If writing cross-platform path code:
    [ ] Listed every path variable and its origin (test-constructed / git / path.resolve / realpathSync)
    [ ] Identified which sources can diverge on Windows (8.3 names, case, separators)
    [ ] Chosen "same source" over "normalise disparate sources"
[ ] No TODOs left in the diff that belong in CI

Quick reference: common drift-guard test patterns in this repo

Test file patternWhat it guards
inventory-countsdocs/INVENTORY.md headline numbers match filesystem counts
inventory-manifest-syncdocs/INVENTORY-MANIFEST.json matches filesystem
bug-3628-bundled-hook-*BUNDLED_GSD_HOOK_FILES matches hooks/ directory
bug-1754-js-hook-guardEvery .js hook has fs.existsSync guard in install.js
managed-hooksmanaged-hooks-registry.cjs matches hooks/ directory

When you add a new hook, run all five before pushing.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.