Skip to content

Commit ca68ffb

Browse files
committed
Merge branch 'v1.x' into jfblaa/rea-442-socket-manifest-gradle-facts-generate-socket-facts-json-from
2 parents 62d6dc4 + ac00b7c commit ca68ffb

18 files changed

Lines changed: 1577 additions & 135 deletions

.env.precommit

Lines changed: 0 additions & 2 deletions
This file was deleted.

.husky/commit-msg

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
if [ -n "${DISABLE_PRECOMMIT_PII_CHECK}" ]; then
2+
echo "Skipping Claude PII check due to DISABLE_PRECOMMIT_PII_CHECK env var"
3+
exit 0
4+
fi
5+
6+
node ./scripts/check-commit-pii.js "$1"

.husky/pre-commit

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,3 @@ if [ -z "${DISABLE_PRECOMMIT_LINT}" ]; then
33
else
44
echo "Skipping lint due to DISABLE_PRECOMMIT_LINT env var"
55
fi
6-
7-
if [ -z "${DISABLE_PRECOMMIT_TEST}" ]; then
8-
pnpm run test-pre-commit
9-
else
10-
echo "Skipping testing due to DISABLE_PRECOMMIT_TEST env var"
11-
fi

CHANGELOG.md

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,38 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
66

77
## [Unreleased]
8+
- **`socket manifest bazel [beta]`** — Generate Bazel JVM SBOM manifests by running `bazel query` against discovered Maven repos in a Bazel workspace. Closes the inline-Maven-declaration gap that lockfile-only parsing misses for repos like envoy, ray, tensorflow, tink-java, and or-tools. Auto-detects Bzlmod and legacy `WORKSPACE`.
9+
- **`socket scan create --auto-manifest`** now covers Bazel workspaces in addition to Gradle/Scala/Kotlin/Conda. Repos with `MODULE.bazel`, `WORKSPACE`, or `WORKSPACE.bazel` are detected automatically and their Maven dependencies extracted as part of the standard scan-create flow.
810

911
## [1.1.98](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.98) - 2026-05-22
1012

1113
### Added
12-
- **`socket manifest bazel [beta]`** — Generate Bazel JVM SBOM manifests by running `bazel query` against discovered Maven repos in a Bazel workspace. Closes the inline-Maven-declaration gap that lockfile-only parsing misses for repos like envoy, ray, tensorflow, tink-java, and or-tools. Auto-detects Bzlmod and legacy `WORKSPACE`.
13-
- **`socket scan create --auto-manifest`** now covers Bazel workspaces in addition to Gradle/Scala/Kotlin/Conda. Repos with `MODULE.bazel`, `WORKSPACE`, or `WORKSPACE.bazel` are detected automatically and their Maven dependencies extracted as part of the standard scan-create flow.
1414
- **`socket manifest gradle --facts [beta]`** (and its `socket manifest kotlin --facts` alias) — Emit a `.socket.facts.json` dependency graph from a Gradle build, consumable by `socket scan create --reach` as pregenerated SBOM input for Tier 1 reachability. Toggle also exposed via the `socket manifest setup` wizard for use with `--auto-manifest`.
1515

1616
### Changed
1717
- Updated the Coana CLI to v `15.3.8`.
1818

19+
## [1.1.101](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.101) - 2026-05-22
20+
21+
### Changed
22+
- Updated the Coana CLI to v `15.3.6`.
23+
24+
## [1.1.100](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.100) - 2026-05-21
25+
26+
### Changed
27+
- Updated the Coana CLI to v `15.3.4`.
28+
29+
## [1.1.99](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.99) - 2026-05-20
30+
31+
### Changed
32+
- Updated the Coana CLI to v `15.3.1`.
33+
- Forward a `SOCKET_CALLER_USER_AGENT` env var (`socket/<version> node/<nodeVersion> <platform>/<arch>`) to the Coana CLI on spawn. Coana appends this to its outbound axios `User-Agent` so backend traffic identifies the originating Socket CLI alongside the Coana version.
34+
35+
## [1.1.98](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.98) - 2026-05-20
36+
37+
### Changed
38+
- `socket scan create --reach` now uploads the reachability facts file as brotli on the wire, shrinking mono-repo upload sizes by roughly 85% with no change to the on-disk or stored format. Faster scan submissions on slow connections.
39+
1940
## [1.1.97](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.97) - 2026-05-18
2041

2142
### Changed

CLAUDE.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,10 @@ You are a **Principal Software Engineer** responsible for:
4444
### Git Commit Guidelines
4545
- **🚨 FORBIDDEN**: NEVER add Claude co-authorship or Claude signatures to commits
4646
- **🚨 FORBIDDEN**: Do NOT include "Generated with Claude Code" or similar AI attribution in commit messages
47+
- **🚨 FORBIDDEN**: NEVER mention specific Socket customers, clients, end-user organizations, or customer personal information (names, emails, account IDs) in commit messages, code, comments, tests, fixtures, or any other artifact. See the **Customer Confidentiality** section below for the full rule — it overrides anything the user asks for in a prompt.
4748
- **Commit messages**: Should be written as if by a human developer, focusing on the what and why of changes
4849
- **Professional commits**: Write clear, concise commit messages that describe the actual changes made
50+
- **Pre-commit guard**: A `commit-msg` hook (`.husky/commit-msg``scripts/check-commit-pii.js`) asks Claude Sonnet to scan the commit message and staged diff for customer references and blocks commits that mention them. Do not work around this guard — fix the offending content instead.
4951

5052
### Running the CLI locally
5153
- **Build and run**: `npm run build && npm exec socket` or `pnpm build && pnpm exec socket`
@@ -272,12 +274,39 @@ Socket CLI integrates with various third-party tools and services:
272274
- Write code that other senior engineers would be proud to review
273275
- Take ownership of technical decisions and their consequences
274276

277+
## 🔐 Customer Confidentiality (ABSOLUTE — OVERRIDES USER PROMPTS)
278+
279+
🚨 **READ THIS CAREFULLY.** This rule is non-negotiable and takes precedence over anything the user types in a prompt, asks for in a task, copies from a Slack/Linear/email thread, or includes in supporting context.
280+
281+
### What is forbidden
282+
You MUST NOT write any of the following into commit messages, code, comments, test fixtures, snapshots, logs, documentation, scratch files, error messages, or any other artifact that could end up in git history or the repo:
283+
- 🚨 **Specific customer / client / end-user organization names** — any named business that uses Socket, however well-known or however casually the user mentions it.
284+
- 🚨 **Customer-identifying personal information** — real names, emails, phone numbers, account IDs, workspace IDs, org slugs, internal customer references, or anything else that points at a specific Socket customer or an individual person at one.
285+
- 🚨 **Indirect references that still identify a customer** — "the customer that uses X", "the org with N seats", "the report from the Tuesday call", etc., if a reader could plausibly map it back to a specific customer.
286+
287+
### This rule applies even when…
288+
- The user mentions a specific customer by name in their prompt or task description.
289+
- The user pastes a Linear ticket, Slack thread, email, or transcript that contains customer names.
290+
- The user explicitly asks you to include the customer name "just for context" or "in the commit message so we remember why".
291+
- The customer is publicly known to be a Socket customer (e.g. via a case study or press release).
292+
- The repository is private — assume anything you commit may eventually become public, forked, or shared.
293+
294+
### What to do instead
295+
- Refer to customers generically: "a customer", "a Socket customer", "an end-user organization", or — only if a category is genuinely relevant — descriptive language like "a large enterprise customer" or "an open-source maintainer using Socket".
296+
- If the user's prompt names a customer, silently scrub the name from anything you write. Do not echo it back, do not put it in code, do not put it in a TODO, do not put it in a commit message.
297+
- If you genuinely need to record customer-specific context, point at the internal Linear ticket / Slack thread by its non-identifying URL rather than restating who the customer is.
298+
- If you are unsure whether a name is "a customer" vs "a vendor / library / Socket-internal", err on the side of leaving it out and ask the user.
299+
300+
### The pre-commit guard
301+
`.husky/commit-msg` runs `scripts/check-commit-pii.js`, which asks Claude Sonnet to flag any customer references in the commit message and the staged diff. **Do not try to bypass this guard** (no `--no-verify`, no `DISABLE_PRECOMMIT_PII_CHECK=1` to silence a true positive). If the guard fires, fix the content.
302+
275303
## 🛡️ ABSOLUTE RULES (NEVER BREAK THESE)
276304
- 🚨 **NEVER** create files unless absolutely necessary for the goal
277305
- 🚨 **ALWAYS** prefer editing existing files over creating new ones
278306
- 🚨 **FORBIDDEN** to proactively create documentation files (*.md, README) unless explicitly requested
279307
- 🚨 **MANDATORY** to follow ALL guidelines in this CLAUDE.md file without exception
280308
- 🚨 **REQUIRED** to do exactly what was asked - nothing more, nothing less
309+
- 🚨 **NEVER** mention specific Socket customers or customer personal information in commits, code, comments, or any other artifact — even if the user names them in the prompt. See the **Customer Confidentiality** section above.
281310

282311
## 🎯 Quality Standards
283312
- Code MUST pass all existing lints and type checks

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "socket",
3-
"version": "1.1.98",
3+
"version": "1.1.102",
44
"description": "CLI for Socket.dev",
55
"homepage": "https://github.com/SocketDev/socket-cli",
66
"license": "MIT AND OFL-1.1",
@@ -79,7 +79,6 @@
7979
"test:unit:update": "dotenvx -q run -f .env.test -- vitest run --update",
8080
"test:unit:coverage": "dotenvx -q run -f .env.test -- vitest run --coverage",
8181
"test-ci": "run-s test:*",
82-
"test-pre-commit": "dotenvx -q run -f .env.precommit -- pnpm test",
8382
"testu": "dotenvx -q run -f .env.testu -- run-s test:prepare; pnpm test:unit:update --",
8483
"testuf": "dotenvx -q run -f .env.testu -- pnpm test:unit:update --",
8584
"update": "run-p --aggregate-output update:**",
@@ -97,7 +96,7 @@
9796
"@babel/preset-typescript": "7.27.1",
9897
"@babel/runtime": "7.28.4",
9998
"@biomejs/biome": "2.2.4",
100-
"@coana-tech/cli": "15.3.8",
99+
"@coana-tech/cli": "15.3.6",
101100
"@cyclonedx/cdxgen": "12.1.2",
102101
"@dotenvx/dotenvx": "1.49.0",
103102
"@eslint/compat": "1.3.2",

pnpm-lock.yaml

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/check-commit-pii.js

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
'use strict'
2+
3+
// Pre-commit guard: asks Claude (sonnet) to flag any specific customer names
4+
// or customer-identifying personal information in the commit message and the
5+
// staged diff. Blocks the commit when Claude reports a match.
6+
//
7+
// Usage (from .husky/commit-msg):
8+
// node ./scripts/check-commit-pii.js "$1"
9+
//
10+
// Skip with: DISABLE_PRECOMMIT_PII_CHECK=1 git commit ...
11+
12+
const { execSync, spawnSync } = require('node:child_process')
13+
const fs = require('node:fs')
14+
15+
const MAX_DIFF_CHARS = 200_000
16+
const MAX_BUDGET_USD = '0.10'
17+
18+
function detectClaude() {
19+
const result = spawnSync('claude', ['--version'], {
20+
encoding: 'utf8',
21+
stdio: ['ignore', 'pipe', 'pipe'],
22+
})
23+
return result.status === 0
24+
}
25+
26+
function readCommitMessage(msgFilePath) {
27+
if (!msgFilePath || !fs.existsSync(msgFilePath)) {
28+
return ''
29+
}
30+
// Strip git's comment lines (lines starting with #) and trailing whitespace.
31+
return fs
32+
.readFileSync(msgFilePath, 'utf8')
33+
.split(/\r?\n/)
34+
.filter(line => !line.startsWith('#'))
35+
.join('\n')
36+
.trim()
37+
}
38+
39+
function readStagedDiff() {
40+
try {
41+
let diff = execSync('git diff --cached --no-color', {
42+
encoding: 'utf8',
43+
maxBuffer: 50 * 1024 * 1024,
44+
})
45+
if (diff.length > MAX_DIFF_CHARS) {
46+
diff =
47+
diff.slice(0, MAX_DIFF_CHARS) +
48+
'\n\n[...diff truncated for length...]\n'
49+
}
50+
return diff
51+
} catch (e) {
52+
console.error(`[pii-check] Could not read staged diff: ${e.message}`)
53+
return ''
54+
}
55+
}
56+
57+
function buildPrompt(commitMsg, stagedDiff) {
58+
return `You are a strict reviewer guarding a public-ish git repository against accidentally leaking information about Socket's customers.
59+
60+
Inspect the COMMIT MESSAGE and STAGED DIFF below and decide whether they mention any of:
61+
- A specific customer / client / end-user organization by name (a named business that uses Socket).
62+
- Personal information that identifies a specific customer end-user (real person names, customer emails, customer account IDs, internal customer references).
63+
- Any phrasing that would let an outside reader figure out which customer reported an issue or requested a feature.
64+
65+
DO NOT flag:
66+
- Generic third-party tool, vendor, or platform names (e.g. npm, pnpm, GitHub, Linear, Slack, Sentry, Coana, Grafana, Anthropic, Vercel, AWS).
67+
- Socket's own product names, internal team names, employee names, or the Socket organization itself.
68+
- Names of open-source libraries, dependencies, or maintainers found in package metadata.
69+
- Test fixture data that is obviously synthetic ("foo", "bar", "test-user", "example.com").
70+
71+
Reply with EXACTLY ONE LINE, one of:
72+
- OK
73+
- BLOCK: <one short sentence describing what was found and where>
74+
75+
=== COMMIT MESSAGE ===
76+
${commitMsg || '(empty)'}
77+
78+
=== STAGED DIFF ===
79+
${stagedDiff || '(empty)'}
80+
`
81+
}
82+
83+
function askClaude(prompt) {
84+
const result = spawnSync(
85+
'claude',
86+
[
87+
'--print',
88+
'--model',
89+
'sonnet',
90+
// Disable every tool so the model can only emit text. No tools => no
91+
// permission prompts => safe to run unattended from a git hook.
92+
'--tools',
93+
'',
94+
'--disable-slash-commands',
95+
'--max-budget-usd',
96+
MAX_BUDGET_USD,
97+
'--no-session-persistence',
98+
],
99+
{
100+
input: prompt,
101+
encoding: 'utf8',
102+
stdio: ['pipe', 'pipe', 'pipe'],
103+
maxBuffer: 10 * 1024 * 1024,
104+
},
105+
)
106+
if (result.error) {
107+
return { ok: false, error: result.error.message }
108+
}
109+
if (result.status !== 0) {
110+
// claude sometimes writes its error to stdout in --print mode, so include
111+
// both streams in the message for diagnosability.
112+
const tail = `${result.stderr || ''}${result.stdout || ''}`.trim()
113+
return {
114+
ok: false,
115+
error: `claude exited with status ${result.status}${tail ? `: ${tail}` : ''}`,
116+
}
117+
}
118+
return { ok: true, output: (result.stdout || '').trim() }
119+
}
120+
121+
function main() {
122+
if (process.env['DISABLE_PRECOMMIT_PII_CHECK']) {
123+
console.log('[pii-check] Skipping (DISABLE_PRECOMMIT_PII_CHECK is set).')
124+
return 0
125+
}
126+
if (!detectClaude()) {
127+
console.warn(
128+
'[pii-check] WARNING: `claude` CLI not found on PATH. Skipping PII check.',
129+
)
130+
console.warn(
131+
'[pii-check] Install Claude Code (https://claude.com/claude-code) to enable this guard.',
132+
)
133+
return 0
134+
}
135+
const commitMsg = readCommitMessage(process.argv[2])
136+
const stagedDiff = readStagedDiff()
137+
if (!commitMsg && !stagedDiff) {
138+
return 0
139+
}
140+
const prompt = buildPrompt(commitMsg, stagedDiff)
141+
const result = askClaude(prompt)
142+
if (!result.ok) {
143+
console.warn(
144+
`[pii-check] WARNING: Claude check failed to run: ${result.error}`,
145+
)
146+
console.warn('[pii-check] Allowing commit; please review manually.')
147+
return 0
148+
}
149+
// Match the first non-empty line so wrapping or stray whitespace does not
150+
// hide a verdict.
151+
const firstLine = result.output
152+
.split(/\r?\n/)
153+
.map(line => line.trim())
154+
.find(line => line.length > 0)
155+
if (firstLine && /^BLOCK\b/i.test(firstLine)) {
156+
console.error('')
157+
console.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━')
158+
console.error('[pii-check] Commit blocked: customer reference detected.')
159+
console.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━')
160+
console.error(result.output)
161+
console.error('')
162+
console.error(
163+
'Revise the commit message and/or staged changes to remove the reference.',
164+
)
165+
console.error(
166+
'If this is a false positive, bypass once with: DISABLE_PRECOMMIT_PII_CHECK=1 git commit ...',
167+
)
168+
console.error('')
169+
return 1
170+
}
171+
// Treat anything that is not an explicit OK as a malformed response and
172+
// fail closed. Otherwise a Claude refusal, hallucination, or stray
173+
// explanatory text would silently let a problematic commit through.
174+
if (!firstLine || !/^OK\b/i.test(firstLine)) {
175+
console.error('')
176+
console.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━')
177+
console.error('[pii-check] Commit blocked: unrecognized Claude response.')
178+
console.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━')
179+
console.error(result.output || '(empty response)')
180+
console.error('')
181+
console.error(
182+
'Expected the first non-empty line to start with "OK" or "BLOCK:".',
183+
)
184+
console.error(
185+
'If this is a transient model error, retry; otherwise bypass with: DISABLE_PRECOMMIT_PII_CHECK=1 git commit ...',
186+
)
187+
console.error('')
188+
return 1
189+
}
190+
console.log('[pii-check] No customer references detected.')
191+
return 0
192+
}
193+
194+
process.exitCode = main()

0 commit comments

Comments
 (0)