xtrm-tools 0.7.17 → 0.7.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/.xtrm/config/hooks.json +2 -0
  2. package/.xtrm/config/instructions/agents-top.md +2 -1
  3. package/.xtrm/registry.json +429 -712
  4. package/.xtrm/skills/default/creating-service-skills/scripts/bootstrap.py +82 -156
  5. package/.xtrm/skills/default/creating-service-skills/scripts/scaffolder.py +73 -121
  6. package/.xtrm/skills/default/hook-development/references/patterns.md +1 -1
  7. package/.xtrm/skills/default/last30days/scripts/test-v1-vs-v2.sh +2 -2
  8. package/.xtrm/skills/default/planning/SKILL.md +75 -29
  9. package/.xtrm/skills/default/releasing/SKILL.md +163 -57
  10. package/.xtrm/skills/default/security-pipeline/SKILL.md +192 -0
  11. package/.xtrm/skills/default/security-pipeline/scripts/security-bootstrap.sh +294 -0
  12. package/.xtrm/skills/default/security-pipeline/templates/.githooks/pre-push.template +39 -0
  13. package/.xtrm/skills/default/security-pipeline/templates/.github/workflows/gitleaks.yml +33 -0
  14. package/.xtrm/skills/default/security-pipeline/templates/.github/workflows/osv-scanner.yml +33 -0
  15. package/.xtrm/skills/default/security-pipeline/templates/.github/workflows/semgrep.yml +41 -0
  16. package/.xtrm/skills/default/security-pipeline/templates/.gitleaks.toml +44 -0
  17. package/.xtrm/skills/default/security-pipeline/templates/.pre-commit-config.yaml +67 -0
  18. package/.xtrm/skills/default/security-pipeline/templates/.semgrepignore +46 -0
  19. package/.xtrm/skills/default/security-pipeline/templates/scripts/security-scan.sh +57 -0
  20. package/.xtrm/skills/default/security-pipeline/templates/scripts/semgrep-diff.sh +68 -0
  21. package/.xtrm/skills/default/session-close-report/SKILL.md +167 -6
  22. package/.xtrm/skills/default/sync-docs/SKILL.md +1 -1
  23. package/.xtrm/skills/default/update-xt/SKILL.md +270 -4
  24. package/.xtrm/skills/default/updating-service-skills/scripts/drift_detector.py +22 -0
  25. package/.xtrm/skills/default/using-script-specialists/SKILL.md +7 -5
  26. package/.xtrm/skills/default/using-specialists/SKILL.md +13 -12
  27. package/.xtrm/skills/default/using-specialists-auto/SKILL.md +137 -0
  28. package/.xtrm/skills/default/using-specialists-v2/SKILL.md +14 -21
  29. package/.xtrm/skills/default/using-specialists-v3/SKILL.md +533 -21
  30. package/.xtrm/skills/default/vaultctl/SKILL.md +2 -2
  31. package/CHANGELOG.md +82 -3
  32. package/cli/dist/index.cjs +12425 -3770
  33. package/cli/dist/index.cjs.map +1 -1
  34. package/cli/package.json +9 -3
  35. package/package.json +27 -7
  36. package/packages/pi-extensions/package.json +1 -1
  37. package/.xtrm/skills/default/planning/evals/evals.json +0 -19
  38. package/.xtrm/skills/default/quality-gates/evals/evals.json +0 -181
  39. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/FINAL-EVAL-SUMMARY.md +0 -75
  40. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/edge-case-auto-fix-verification/with_skill/outputs/response.md +0 -59
  41. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/edge-case-mixed-language-project/with_skill/outputs/response.md +0 -60
  42. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/eval-summary.md +0 -105
  43. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/partial-install-python-only/with_skill/outputs/response.md +0 -93
  44. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/python-refactor-request/with_skill/outputs/response.md +0 -104
  45. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/quality-gate-error-fix/with_skill/outputs/response.md +0 -74
  46. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/should-not-trigger-general-chat/with_skill/outputs/response.md +0 -18
  47. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/should-not-trigger-math-question/with_skill/outputs/response.md +0 -18
  48. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/should-not-trigger-unrelated-coding/with_skill/outputs/response.md +0 -56
  49. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/tdd-guard-blocking-confusion/with_skill/outputs/response.md +0 -67
  50. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/typescript-feature-with-tests/with_skill/outputs/response.md +0 -97
  51. package/.xtrm/skills/default/sync-docs/evals/evals.json +0 -89
  52. package/.xtrm/skills/default/test-planning/evals/evals.json +0 -23
  53. package/.xtrm/skills/default/using-specialists/SKILL.safe.md +0 -1082
  54. package/.xtrm/skills/default/using-specialists/SKILL.ultra.md +0 -1082
  55. package/.xtrm/skills/default/using-specialists/evals/evals.json +0 -68
  56. package/.xtrm/skills/default/using-specialists-v3/evals/evals.json +0 -89
  57. package/packages/pi-extensions/.serena/project.yml +0 -130
@@ -1,94 +1,200 @@
1
1
  ---
2
2
  name: releasing
3
3
  description: >-
4
- Cut a release with the canonical xt release prepare/publish flow. Use when the
5
- operator wants to publish a new tag (vX.Y.Z). Prepare drafts CHANGELOG from xt
6
- reports and performs deterministic release-file mutations; publish creates the
7
- annotated tag, pushes commits/tags, and can create a GitHub release.
8
- version: 1.2.0
4
+ Cut a release end-to-end. Promotes the existing [Unreleased] CHANGELOG block
5
+ to a dated [vX.Y.Z] section, bumps the package version, rebuilds dist,
6
+ commits, tags, pushes, and publishes to npm. Optionally dispatches the
7
+ changelog-keeper specialist to fill gaps in [Unreleased] from xt reports
8
+ before promotion.
9
+ version: 2.0.0
9
10
  ---
10
11
 
11
12
  # releasing
12
13
 
13
- Canonical release publication via `xt release prepare` and `xt release publish`.
14
+ End-to-end release skill. Drives the release directly with bash; no `xt release`
15
+ wrapper. Assumes `[Unreleased]` in `CHANGELOG.md` is already populated by the
16
+ `session-close-report` skill (Step 6) across the contributing sessions.
14
17
 
15
18
  ## When to use
16
19
 
17
- The operator wants to cut a release. They say "release it", "ship vX.Y.Z", "cut a tag", or just "release".
20
+ The operator says "release it", "ship vX.Y.Z", "cut a tag", or just "release".
18
21
 
19
- ## How
22
+ ## Preconditions
20
23
 
21
- 1. Determine target version. Default is patch bump from most recent semver tag. Operator may specify `--minor`, `--major`, or explicit version.
24
+ - Working tree clean except whitelisted release artifacts.
25
+ - `CHANGELOG.md` exists with an `[Unreleased]` block.
26
+ - On the publish branch (usually `master`).
27
+ - npm auth set up (`npm whoami` succeeds).
22
28
 
23
- 2. Determine tag range. Default is `<latest-tag>..HEAD`. For backfills, operator names `--from` / `--to` explicitly.
29
+ If the project has no `CHANGELOG.md`, stop and ask the operator.
24
30
 
25
- 3. Prepare release files:
31
+ ## Flow
26
32
 
27
- ```bash
28
- xt release prepare --patch
29
- # or: xt release prepare --minor --from <tag> --to HEAD
30
- ```
33
+ ### 1. Decide version
31
34
 
32
- `prepare` is the canonical path. It builds the xt report bundle, calls the specialists changelog drafting script (`sp script changelog-keeper`), updates release files, rebuilds dist, and enforces the release scope guard.
35
+ ```bash
36
+ git tag --sort=-v:refname | head -3 # last release
37
+ git log <last-tag>..HEAD --oneline | wc -l # commit count since
38
+ ```
33
39
 
34
- Current blocker: until specialists issue `unitAI-dnmcg` lands, `prepare` can fail with `interactive specialists are not allowed` because the changelog drafting specialist is not yet script-compatible. If that happens, do a manual prepare using the same scope rules and then continue with `xt release publish`.
40
+ Default is patch bump. Operator may say `--minor`, `--major`, or specify
41
+ `vX.Y.Z` explicitly. If the in-range work added user-facing surface (new flags,
42
+ new endpoints, new commands), bump minor unless operator says otherwise.
35
43
 
36
- 4. Verify release diff before publishing.
44
+ ### 2. Inspect [Unreleased]
37
45
 
38
- ```bash
39
- git diff --stat HEAD~1 HEAD
40
- git status --short
41
- ```
46
+ ```bash
47
+ sed -n '/## \[Unreleased\]/,/## \[/p' CHANGELOG.md
48
+ ```
42
49
 
43
- Release diff must be limited to release artifacts such as:
44
- - `CHANGELOG.md`
45
- - package manifests / lockfile for version sync
46
- - generated `cli/dist/**` or `dist/**`
50
+ Decision:
47
51
 
48
- 5. Publish:
52
+ - **Populated and complete** (covers the user-facing changes since last tag):
53
+ proceed to Step 3.
54
+ - **Populated but gappy or sparse** (some sessions skipped Step 6, or the
55
+ bullets do not match commits): dispatch `changelog-keeper` to reconcile from
56
+ xt reports, then re-inspect. See "Optional: changelog-keeper dispatch".
57
+ - **Empty** but commits since last tag are pure-internal (refactors,
58
+ doc-only): proceed; the released section will be near-empty.
59
+ - **Empty** but there are user-facing changes: dispatch `changelog-keeper`.
49
60
 
50
- ```bash
51
- xt release publish
52
- # optional GitHub release:
53
- xt release publish --gh-release
54
- ```
61
+ ### 3. Promote [Unreleased] → [vX.Y.Z]
55
62
 
56
- `publish` creates the annotated tag for the current package version, pushes commits and tags, and optionally creates the GitHub release.
63
+ Edit `CHANGELOG.md`:
57
64
 
58
- 6. Confirm:
65
+ - Insert a new empty `## [Unreleased]` block at the top.
66
+ - Rename the previous `[Unreleased]` to `## [vX.Y.Z] — YYYY-MM-DD` (today's
67
+ date).
68
+ - Keep the section bodies (Added / Changed / Fixed / etc.) untouched.
59
69
 
60
- ```bash
61
- git tag --list 'v*' | tail -3
62
- git log --oneline -1
63
- git status --short --branch
64
- ```
70
+ ### 4. Bump version
65
71
 
66
- ## Why this design
72
+ ```bash
73
+ # package.json: "version": "X.Y.Z"
74
+ # package-lock.json: "version" appears at top and inside packages[""]
75
+ ```
76
+
77
+ Edit both. Other lockfiles (bun.lock, pnpm-lock) generally do not encode the
78
+ top-level version — skip unless the project does.
79
+
80
+ ### 5. Build
81
+
82
+ ```bash
83
+ npm run build
84
+ git status --short
85
+ ```
86
+
87
+ Tracked `dist/**` may or may not change (often byte-identical when HEAD
88
+ already had a fresh build).
89
+
90
+ ### 6. Verify release scope
91
+
92
+ ```bash
93
+ git status --short
94
+ git diff --stat
95
+ ```
96
+
97
+ Allowed paths only:
98
+
99
+ - `CHANGELOG.md`
100
+ - `package.json`
101
+ - `package-lock.json` (if tracked)
102
+ - `dist/**` (if tracked)
103
+
104
+ Anything else dirty → stop, fix scope, retry. Stash unrelated untracked files
105
+ (e.g. downstream specialist leakage in `.specialists/user/`) before continuing.
106
+
107
+ ### 7. Commit, tag, push
108
+
109
+ ```bash
110
+ git add CHANGELOG.md package.json package-lock.json dist/ # only what's tracked
111
+ git commit -m "release: vX.Y.Z"
112
+ git tag -a vX.Y.Z -m "Release vX.Y.Z"
113
+ git push origin <branch>
114
+ git push origin vX.Y.Z
115
+ ```
67
116
 
68
- - `xt` owns deterministic release mutation: changelog insertion, version bump, build, scope guard, commit/tag/push.
69
- - The specialist owns only changelog drafting from xt reports through a script-compatible, READ_ONLY surface.
70
- - xt reports are synthesis input, not raw git log + bd query. Reports are pre-curated, signal-rich, written in user-facing language.
71
- - `xt release publish` is intentionally separate so operators can inspect prepared release files before pushing the tag.
117
+ ### 8. Publish to npm
72
118
 
73
- ## Manual fallback while unitAI-dnmcg is open
119
+ ```bash
120
+ npm publish --access public # --access public for scoped packages
121
+ ```
74
122
 
75
- If `xt release prepare` fails on the changelog script compatibility guard:
123
+ ### 9. Refresh global toolchain
76
124
 
77
- 1. Draft the CHANGELOG section manually from `.xtrm/reports/` and recent commits.
78
- 2. Bump package versions and lockfile.
79
- 3. Run `npm run build`.
80
- 4. Commit with `release: vX.Y.Z`.
81
- 5. Run `xt release publish`.
125
+ If this project ships a CLI the operator uses globally:
126
+
127
+ ```bash
128
+ npm i -g <package>@X.Y.Z
129
+ <cli> --version
130
+ ```
131
+
132
+ ### 10. Confirm
133
+
134
+ ```bash
135
+ git tag --list 'v*' | tail -3
136
+ git log --oneline -1
137
+ git status --short
138
+ npm view <package> version
139
+ ```
140
+
141
+ ### 11. Optional: GitHub release
142
+
143
+ ```bash
144
+ gh release create vX.Y.Z --notes "$(sed -n '/## \[vX.Y.Z\]/,/## \[/p' CHANGELOG.md | head -n -1)"
145
+ ```
146
+
147
+ ## Optional: changelog-keeper dispatch
148
+
149
+ When `[Unreleased]` is empty or sparse and user-facing work shipped, file a
150
+ small bead and dispatch `changelog-keeper`:
151
+
152
+ ```text
153
+ TITLE: Fill [Unreleased] from <prev-tag>..HEAD
154
+ PROBLEM: [Unreleased] is missing entries for sessions <list> which shipped user-facing changes; release vX.Y.Z is being cut.
155
+ SUCCESS: [Unreleased] reflects every user-facing change in the range, in Keep-a-Changelog format.
156
+ SCOPE: CHANGELOG.md only.
157
+ REFERENCES: .xtrm/reports/<prev-tag-date>..<today> (filtered to in-range), recent commit subjects.
158
+ NON_GOALS: no version bump, no build, no commit, no tag — skill owns those.
159
+ CONSTRAINTS: edit CHANGELOG.md only; one bullet per change; bead refs in parens; sections Added / Changed / Fixed / Removed / Deprecated / Security; do not invent entries not grounded in reports or commits.
160
+ VALIDATION: diff shows only [Unreleased] body changed; bullets cover the report set.
161
+ OUTPUT: updated CHANGELOG.md with populated [Unreleased].
162
+ ```
163
+
164
+ ```bash
165
+ sp run changelog-keeper --bead <bead-id>
166
+ ```
167
+
168
+ After it returns, re-inspect `[Unreleased]` and proceed to Step 3. Skill — not
169
+ keeper — owns version bump, build, commit, tag, push, publish.
170
+
171
+ ## Why this design
82
172
 
83
- Do not broaden the release diff beyond release artifacts.
173
+ - `session-close-report` already drafts user-facing prose per session and
174
+ appends to `[Unreleased]` (Step 6 of that skill). The release-time work is
175
+ therefore small: promote, bump, build, commit, tag, push, publish.
176
+ - Keeping the deterministic mutations in bash (driven by this skill) avoids
177
+ three failure modes seen with the old `xt release` wrapper: hardcoded
178
+ workspace paths, wrong specialist invocation, and a regex template engine
179
+ that over-greedy-matches `$VAR` patterns inside report prose.
180
+ - The `changelog-keeper` specialist is now CHANGELOG-only and only invoked on
181
+ demand to fill gaps. It does not own commits, tags, pushes, or builds.
84
182
 
85
183
  ## Parallel sessions
86
184
 
87
- Each orchestrator runs this skill in its own session. Specialist commits + tags + pushes atomically. If two sessions try same version, first push wins; second sees remote tag conflict and aborts cleanly. Operator picks next version and retries.
185
+ Two operators racing the same version: first `git push origin vX.Y.Z` wins;
186
+ second sees a non-fast-forward / tag-exists error and aborts. Operator picks
187
+ the next version and retries.
88
188
 
89
189
  ## Don't
90
190
 
91
- - Don't call `sp release prepare` / `sp release publish` as the canonical path. They are deprecated aliases in specialists.
92
- - Don't bypass `xt release publish` for tag/push unless the command itself is broken.
93
- - Don't broaden release diffs with source/docs/config changes. File a separate bead for non-release work.
94
- - Don't pre-stage unrelated files. The release scope guard should see a clean tree except allowed release artifacts.
191
+ - Don't call `xt release prepare` / `xt release publish` retired. See
192
+ `unitAI-g29jv`.
193
+ - Don't broaden the release diff with source/docs/config changes. File a
194
+ separate bead.
195
+ - Don't pre-stage unrelated files. The release scope check should see a clean
196
+ tree except whitelisted release artifacts.
197
+ - Don't invent CHANGELOG entries from `git log -p`. The reports + existing
198
+ `[Unreleased]` are the input.
199
+ - Don't `git push --force` or rewrite tags. If a release ships wrong, cut a
200
+ patch.
@@ -0,0 +1,192 @@
1
+ ---
2
+ name: security-pipeline
3
+ description: Bootstrap a complete security pipeline (Dependabot + OSV + Semgrep + gitleaks + pre-commit hooks + Codex review) on any GitHub repo. Designed for free user-private repos where GitHub Advanced Security is unavailable. Reusable across Python/TypeScript/Go/Rust stacks.
4
+ ---
5
+
6
+ # Security Pipeline
7
+
8
+ Wires a 4-layer security baseline onto any GitHub repo. Originally proven on
9
+ the Mercury infra stack but the templates and bootstrap script are
10
+ project-agnostic — adapt the allowlists and dependabot ecosystems per repo.
11
+
12
+ ## When to use
13
+
14
+ - Setting up security on a new repo (any language)
15
+ - Existing repo has zero/partial security checks
16
+ - User says "set up security pipeline" / "wire dependabot + sast + secret scan"
17
+
18
+ Do NOT use this skill if the repo already has a working `dependabot.yml` AND
19
+ all three workflows (`osv-scanner.yml`, `semgrep.yml`, `gitleaks.yml`).
20
+
21
+ ## Architecture (4 layers)
22
+
23
+ ```
24
+ git commit ──► pre-commit (gitleaks staged, ruff, hygiene) ~1s
25
+ git push ──► pre-push (semgrep diff-only, osv, anti-main) ~30s
26
+ PR opened ──► CI (osv-scanner, semgrep, gitleaks) ~1m
27
+ PR review ──► Codex (semantic AI review, optional) ~2m
28
+ PR merged ──► Dependabot (continuous vuln + version PRs) async
29
+ ```
30
+
31
+ Pre-existing debt is NEVER blocked by the push gate — only NEW findings vs
32
+ `origin/main`. CI does the full-repo authoritative scan.
33
+
34
+ ## Why this stack on free user-private repos
35
+
36
+ GitHub Advanced Security (CodeQL, Dependency Review) needs Org/Enterprise
37
+ + ~$49/user/month. Free substitutes:
38
+
39
+ | GHAS | Free substitute |
40
+ |---|---|
41
+ | CodeQL | Semgrep `p/security-audit` + `p/secrets` + ecosystem packs |
42
+ | Dependency Review | `osv-scanner` action |
43
+ | Secret scanning | Native (free for all repos since 2025) |
44
+ | Push protection | Native (free for all repos since 2025) |
45
+ | Branch protection enforcement | Pre-push hook + `gh pr merge --auto` |
46
+
47
+ ## Quickstart
48
+
49
+ The skill ships with a bootstrap script that detects ecosystems and copies
50
+ templates. From the source repo (where this skill is installed):
51
+
52
+ ```bash
53
+ ./scripts/security-bootstrap.sh /path/to/target/repo
54
+ ```
55
+
56
+ The script:
57
+ 1. Detects ecosystems (`pip`, `pip-pyproject`, `npm`, `docker`, `gomod`,
58
+ `cargo`, `github-actions`)
59
+ 2. Generates a tailored `.github/dependabot.yml`
60
+ 3. Copies the 11 baseline files from `templates/`
61
+ 4. Opens a `feat(security)` PR
62
+ 5. Calls `gh api` to enable Dependabot/secret scanning/push protection
63
+
64
+ ## Manual follow-up after bootstrap
65
+
66
+ The script CAN'T do these — operator walks them per target repo:
67
+
68
+ 1. **Codex Connector** (optional) — install at https://chatgpt.com/codex/cloud/settings/general
69
+ 2. **Branch protection rule** — Settings → Branches → classic rule for `main`
70
+ - Required checks: `OSV scan`, `Semgrep scan`, `Gitleaks scan`
71
+ - On free private repos rules don't enforce server-side; the pre-push hook fills the gap
72
+ 3. **`make install-hooks`** in the target clone (or run `git config core.hooksPath .githooks`)
73
+
74
+ ## Files in `templates/`
75
+
76
+ | Template | Lands at | Purpose |
77
+ |---|---|---|
78
+ | `.github/workflows/osv-scanner.yml` | same path | Vuln scan via OSV.dev |
79
+ | `.github/workflows/semgrep.yml` | same path | SAST (replaces CodeQL) |
80
+ | `.github/workflows/gitleaks.yml` | same path | Secret scan |
81
+ | `.gitleaks.toml` | same path | **Allowlist — adapt per project** (see below) |
82
+ | `.semgrepignore` | same path | **Excludes — adapt per project** (see below) |
83
+ | `.pre-commit-config.yaml` | same path | Two-stage local gate |
84
+ | `.githooks/pre-push.template` | merge into existing `.githooks/pre-push` | Anti-main-push + pre-commit chain |
85
+ | `scripts/semgrep-diff.sh` | same path | Diff-only semgrep for push |
86
+ | `scripts/security-scan.sh` | same path | Local audit (informational) |
87
+
88
+ `.github/dependabot.yml` is NOT in `templates/` — it's generated per-repo from
89
+ detected ecosystems.
90
+
91
+ ## Adapting allowlists per project
92
+
93
+ The shipped `.gitleaks.toml` and `.semgrepignore` contain Mercury-specific
94
+ paths as **examples**. When applying to a non-Mercury repo, prune what
95
+ doesn't apply.
96
+
97
+ ### `.gitleaks.toml` — common allowlist patterns
98
+
99
+ ```toml
100
+ [allowlist]
101
+ paths = [
102
+ '''^\.env$''', # gitignored secrets (no-git scan walks fs)
103
+ '''^\.env\..*''',
104
+ # Project-specific machine-generated dirs (drop what doesn't apply):
105
+ '''^\.beads/.*''', # Mercury-only — issue tracker exports
106
+ '''^\.specialists/.*''', # Mercury-only — specialist runtime state
107
+ '''^\.dolt/.*''', # Mercury-only — Dolt SQL storage
108
+ # Add your own:
109
+ '''^vendor/.*''', # Go vendoring
110
+ '''^node_modules/.*''', # NPM (usually gitignored anyway)
111
+ ]
112
+ ```
113
+
114
+ ### `.semgrepignore` — common patterns
115
+
116
+ ```
117
+ .env
118
+ .env.*
119
+ node_modules/
120
+ vendor/
121
+ **/__pycache__/
122
+ **/test_fixtures/
123
+ package-lock.json
124
+ pnpm-lock.yaml
125
+ yarn.lock
126
+ poetry.lock
127
+ Pipfile.lock
128
+ go.sum
129
+ Cargo.lock
130
+ ```
131
+
132
+ Don't blanket-allowlist findings without a tracked issue explaining why.
133
+ Acknowledged debt should be visible.
134
+
135
+ ## Local install (per-clone, after bootstrap merges)
136
+
137
+ ```bash
138
+ pip3 install --user --break-system-packages pre-commit semgrep
139
+ mkdir -p ~/.local/bin
140
+ curl -sL https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz \
141
+ | tar -xz -C ~/.local/bin gitleaks
142
+ curl -sL https://github.com/google/osv-scanner/releases/download/v2.0.2/osv-scanner_linux_amd64 \
143
+ -o ~/.local/bin/osv-scanner && chmod +x ~/.local/bin/osv-scanner
144
+ git config core.hooksPath .githooks
145
+ chmod +x .githooks/pre-commit .githooks/pre-push 2>/dev/null
146
+ ```
147
+
148
+ Verify: `./scripts/security-scan.sh`.
149
+
150
+ ## Reading Codex feedback on a PR (if Codex is installed)
151
+
152
+ ```bash
153
+ gh pr view <num> --json reviews,comments | python3 -c "
154
+ import json, sys
155
+ d = json.load(sys.stdin)
156
+ for r in d.get('reviews', []):
157
+ if 'codex' in r.get('author',{}).get('login','').lower():
158
+ body = r.get('body', '')
159
+ print('👍 no suggestions' if 'automated review suggestions' in body and len(body) < 1500 else body[:1500])
160
+ "
161
+ ```
162
+
163
+ ## Known pitfalls (encoded in the templates)
164
+
165
+ - **Pre-commit can't install with `core.hooksPath` set** → templates chain
166
+ pre-commit from `.githooks/pre-commit` and `.githooks/pre-push` instead of
167
+ using `pre-commit install`.
168
+ - **Semgrep's pre-commit env breaks on Python 3.13** (`pkg_resources` missing)
169
+ → templates use `language: system` pointing at globally installed semgrep.
170
+ - **`semgrep ci --error` is invalid** → use `semgrep scan --error`.
171
+ - **`actions/dependency-review-action` requires GHAS** → use `osv-scanner` instead.
172
+ - **Gitleaks action needs `pull-requests: write`** to post leak summary on PRs.
173
+ - **Full-repo semgrep at push stage flags pre-existing debt** → use
174
+ `scripts/semgrep-diff.sh` with `--baseline-commit=$(git merge-base HEAD origin/main)`.
175
+ - **`.pre-commit-config.yaml` `default_stages: [pre-commit]`** → otherwise
176
+ ruff/hygiene hooks fire at push too.
177
+ - **Squash-merging while iterating with `git commit --amend`** → verify
178
+ `git log --stat <merge-sha>` after merge; missing files require a follow-up PR.
179
+ - **Auto-merge disabled** → fall back to `gh pr merge --squash --delete-branch`
180
+ after `gh pr checks --watch`.
181
+
182
+ ## Complementary tools (optional, second opinion)
183
+
184
+ - `trivy fs` / `trivy image` — container + IaC scanning
185
+ - `bandit` — Python-specific SAST (Semgrep `p/python` already covers most)
186
+ - `actionlint` — GitHub Actions linter (Semgrep `p/github-actions` covers basics)
187
+
188
+ ## Reference doc
189
+
190
+ Full pipeline narrative + UI screenshots + per-feature rationale lives in
191
+ the Mercury reference at `mercury-infra/SECURITY-PIPELINE.md`, also mirrored
192
+ in `~/second-mind/3-resources/github/SECURITY-PIPELINE.md`.