Skip to content

chore(claude+oxfmt+deps+kind-config): programmatic-Claude lockdown + sweeper + CLAUDE.md restructure + oxfmt JSDoc + pnpm v11.0.0 GA + logger-guard + auth-rotation-reminder + kind config#630

Open
John-David Dalton (jdalton) wants to merge 17 commits intomainfrom
chore/programmatic-claude-lockdown

Conversation

@jdalton
Copy link
Copy Markdown
Contributor

@jdalton John-David Dalton (jdalton) commented Apr 28, 2026

Summary

  • CLAUDE.md — restructured into fleet-canonical + project-specific sections.
  • .claude/skills/programmatic-claude-lockdown/SKILL.md — fleet-canonical skill.
  • .claude/hooks/stale-process-sweeper/ — fleet-canonical Stop hook reaping orphan vitest/tsgo workers at turn-end.
  • .claude/hooks/logger-guard/ — fleet-canonical PreToolUse(Edit|Write) hook blocking direct stream writes (process.std{err,out}.write, console.*) in source files.
  • .claude/hooks/auth-rotation-reminder/ — fleet-canonical Stop hook for periodic CLI auto-logout.
  • .claude/settings.json — wires the new hooks.
  • pnpm-workspace.yaml — register catalog (@socketsecurity/lib, @types/node) so hook package.jsons resolve via catalog:.
  • package.json — packageManager pnpm@11.0.0-rc.5pnpm@11.0.0 (GA); engines.pnpm >=11.0.0-rc.0>=11.0.0
  • external-tools.json — pnpm version + 6 platform sha256s bumped to v11.0.0 release tarballs.

Why (lockdown)

Following https://code.claude.com/docs/en/agent-sdk/permissions: permissionMode: 'default' in headless contexts falls through to a missing canUseTool callback, which is undefined behavior. The doc's prescribed lockdown recipe is 'dontAsk' paired with tools, allowedTools, and disallowedTools.

Reference impl: socket-lib/tools/prim/src/disambiguate.mts (SDK form). socket-registry/.github/workflows/weekly-update.yml uses the Bash-needing CLI form.

Why (sweeper)

Vitest's worker pool spawns one Node worker per CPU. When the parent runner exits abnormally the workers stay alive holding 80–100 MB each. After a few interrupted runs the host has gigabytes of abandoned processes. The Stop hook reaps them at turn-end.

Why (logger-guard)

Source code uses getDefaultLogger() from @socketsecurity/lib/logger. Direct stream writes bypass color/theme handling, indentation tracking, stream redirection in tests, and counter increments used by spinners. The hook surfaces a Fix: line per hit so the agent can apply the rewrite directly. Pre-commit/pre-push pick up the same rule via scanLoggerLeaks for edits made outside Claude Code; canonical # socket-hook: allow <rule> marker.

Why (auth-rotation-reminder)

Periodically auto-logs out of authenticated CLIs (npm/pnpm/yarn/gcloud/aws-sso/vault/docker/socket); gh stays logged-in by default (Claude Code uses it). 1h throttle, ISO-8601 .claude/auth-rotation.snooze with auto-cleanup via safeDelete. Skip when CI or SOCKET_AUTH_ROTATION_DISABLED set.

Why (CLAUDE.md restructure)

Per Claude Code best-practices: "Bloated CLAUDE.md files cause Claude to ignore your actual instructions." Split into ## 📚 Fleet Standards (byte-identical across the fleet) and ## 🏗️ SDK-Specific.

Fleet block ~8.6 KB. Verbose content moves to load-on-demand references:

  • docs/references/inclusive-language.md
  • docs/references/sorting.md
  • .claude/skills/promise-race-pitfall/SKILL.md

CLAUDE.md size: 22.7 KB → 13.9 KB.

Why (pnpm v11.0.0 GA)

pnpm v11 is now stable. Lockfile shape unchanged from rc.5.

Test plan

  • CI passes
  • stale-process-sweeper hook tests pass
  • logger-guard hook tests pass (12/12)
  • auth-rotation-reminder hook tests pass (6/6)
  • CLAUDE.md fleet block byte-matches socket-repo-template

oxfmt JSDoc formatting

oxfmt 0.37+ formats JSDoc comments. Adopt canonical jsdoc block from socket-repo-template. Verified zero new format violations.

Reference: https://oxc.rs/docs/guide/usage/formatter/config-file-reference.html#jsdoc

blockExoticSubdeps + .mjs->.mts ref sync (added 2026-05-01)

  • pnpm-workspace.yaml: blockExoticSubdeps: true (fleet default — refuses transitive git/tarball subdeps; direct git deps still allowed).
  • Sync .mjs -> .mts references for scripts/sync-scaffolding across hook READMEs, path-guard segments, _shared skill rules, CLAUDE.md, xport-schema header.
  • Adopt "soak window" terminology in security-reviewer + CLAUDE.md tooling block.

socket-repo-template kind config + schema (added 2026-05-03)

  • .socket-repo-template.json declaring kind: "single-package".
  • scripts/socket-repo-template-{schema,emit-schema}.mts + socket-repo-template-schema.json synced byte-identical from socket-repo-template@5ad601c. The TypeBox source defines the per-repo config shape; the emitter regenerates the JSON Schema for IDE autocompletion.
  • Read by socket-repo-template's sync-scaffolding kind-aware checker.

Cascaded from socket-repo-template. CLAUDE.md gains one bullet
alongside the other security 🚨 rules; the skill at
.claude/skills/programmatic-claude-lockdown/SKILL.md holds the
four-flag table (`tools`/`allowedTools`/`disallowedTools`/
`permissionMode: 'dontAsk'`), both recipes (read-only and
Bash-needing), and the never-do list.

Reference impl: socket-lib/tools/prim/src/disambiguate.mts (SDK form);
socket-registry weekly-update.yml uses the Bash-needing CLI form.
pnpm v11 is now stable: https://github.com/pnpm/pnpm/releases/tag/v11.0.0

- package.json: packageManager pin "pnpm@11.0.0-rc.5" → "pnpm@11.0.0";
  engines.pnpm ">=11.0.0-rc.0" → ">=11.0.0".
- external-tools.json: bump version + 6 platform sha256s (darwin
  arm64/x64, linux arm64/x64, win arm64/x64). Hashes computed locally
  from the v11.0.0 release tarballs.

pnpm-workspace.yaml already on the v11 idioms (allowBuilds,
pmOnFail, minimumReleaseAge); lockfile shape unchanged.
@jdalton John-David Dalton (jdalton) changed the title docs(claude): add programmatic-Claude lockdown rule + skill chore(claude+deps): programmatic-Claude lockdown rule + skill + pnpm v11.0.0 GA bump Apr 28, 2026
Reaps orphan vitest/tsgo/type-coverage/esbuild workers at turn-end so
they don't pile up across turns and exhaust system memory. Only kills
processes whose parent has died (true orphans); leaves running
test/build trees alone.

- .claude/hooks/stale-process-sweeper/  (hook + tests + README)
- .claude/settings.json                  (Stop hook block)
- CLAUDE.md                              (Background Bash rule)

Sourced from socket-repo-template (canonical fleet hook).
@jdalton John-David Dalton (jdalton) changed the title chore(claude+deps): programmatic-Claude lockdown rule + skill + pnpm v11.0.0 GA bump chore(claude+deps): programmatic-Claude lockdown + stale-process-sweeper + pnpm v11.0.0 GA bump Apr 30, 2026
…ific layout

Split CLAUDE.md into two clearly-delimited sections:

- `## 📚 Fleet Standards` — wrapped in BEGIN/END FLEET-CANONICAL markers,
  byte-identical across every socket-* repo (sync via socket-repo-template).
- `## 🏗️ SDK-Specific` — repo-owned content: Architecture, Commands,
  Configuration Files, SDK-Specific Patterns, Testing, CI Testing,
  Changelog Management, Debugging, SDK Notes.

Fleet block ~8.6 KB; verbose content moves to references:
- `docs/references/inclusive-language.md`
- `docs/references/sorting.md`
- `.claude/skills/promise-race-pitfall/SKILL.md`

CLAUDE.md 22.7 KB → 13.9 KB.

Joins this PR's programmatic-Claude lockdown additions; the new fleet
block already references the lockdown skill this PR adds.
@jdalton John-David Dalton (jdalton) changed the title chore(claude+deps): programmatic-Claude lockdown + stale-process-sweeper + pnpm v11.0.0 GA bump chore(claude+deps): programmatic-Claude lockdown + stale-process-sweeper + CLAUDE.md restructure + pnpm v11.0.0 GA bump Apr 30, 2026
oxfmt 0.37+ formats JSDoc comments. Adopt the canonical `jsdoc` block
from socket-repo-template; it preserves the existing JSDoc style across
this repo (verified: zero diff under the new config).

Source of truth: socket-repo-template/template/.oxfmtrc.json. Future
updates flow through `scripts/sync-scaffolding.mjs --all --fix`.
@jdalton John-David Dalton (jdalton) changed the title chore(claude+deps): programmatic-Claude lockdown + stale-process-sweeper + CLAUDE.md restructure + pnpm v11.0.0 GA bump chore(claude+oxfmt+deps): programmatic-Claude lockdown + sweeper + CLAUDE.md restructure + oxfmt JSDoc + pnpm v11.0.0 GA Apr 30, 2026
…mplate

- `.git-hooks/_helpers.mts` + `pre-commit.mts` + `pre-push.mts` —
  rename suppression marker `# zizmor: …` → `# socket-hook: allow [<rule>]`
  (legacy form still recognized for one cycle); add doc-aware scan
  heuristic; emit `LineHit.suggested` rewrites alongside hits.
- `CLAUDE.md` — update fleet block npx-rule marker; oxfmt-normalized
  markdown emphasis.
- `docs/references/{inclusive-language,sorting}.md` — re-sync.
- `.claude/skills/path-guard/SKILL.md`, `.claude/agents/security-reviewer.md`
  — sync drift from template.
- `pnpm-lock.yaml` — regenerate after template sync.

Verified: `pnpm run check --all` clean; `pnpm test --all` 565/565 pass.
logger-guard (PreToolUse Edit|Write):
- Blocks direct stream writes (process.std{err,out}.write, console.*)
  in source files; suggests getDefaultLogger() rewrite per hit.
- Path-exempts hooks/, .git-hooks/, scripts/, tests, fixtures,
  external/ vendor/ upstream/.
- Honors `# socket-hook: allow [logger]` opt-out marker.

auth-rotation-reminder (Stop):
- Periodic auto-logout from npm/pnpm/yarn/gcloud/aws-sso/vault/docker/
  socket; gh stays logged-in by default.
- 1h throttle, ISO-8601 .claude/auth-rotation.snooze with auto-cleanup.
- Skip when CI or SOCKET_AUTH_ROTATION_DISABLED set.

pnpm-workspace.yaml: register catalog with @socketsecurity/lib +
@types/node so hook package.json deps resolve via `catalog:`.

Pre-commit/pre-push pick up scanLoggerLeaks for edits made outside
@jdalton John-David Dalton (jdalton) changed the title chore(claude+oxfmt+deps): programmatic-Claude lockdown + sweeper + CLAUDE.md restructure + oxfmt JSDoc + pnpm v11.0.0 GA chore(claude+oxfmt+deps): programmatic-Claude lockdown + sweeper + CLAUDE.md restructure + oxfmt JSDoc + pnpm v11.0.0 GA + logger-guard + auth-rotation-reminder Apr 30, 2026
…-window wording

- pnpm-workspace.yaml: add blockExoticSubdeps: true (fleet default).
  Direct git deps still allowed; transitive ones refused.
- Update sync-scaffolding script references from .mjs to .mts in
  hook READMEs, path-guard segments, _shared skill rules, CLAUDE.md
  fleet-canonical header, and xport-schema.mts file header.
- Adopt "soak window" terminology in security-reviewer + CLAUDE.md
  tooling block, matching how the rest of the fleet refers to pnpm's
  minimumReleaseAge field.
… root manifest

Provenance attestation becomes a property of the package, not a
property of the workflow's --provenance flag. Survives any future
emergency-publish path that bypasses provenance.yml. access: public
also load-bears for first-publish of @Scoped packages on a fresh
npm registry session.

Pre-existing iocraft test failures unrelated; --no-verify per
session-wide authorization.
Working tree is never mutated during publish; the staged copy is
what `npm publish` runs against. Eliminates a class of "interrupted
publish leaves dirty git status" incidents:

- Run `pnpm publish:ci` against the live tree
- Operator hits Ctrl-C mid-publish (or the runner times out)
- Working tree was being modified in-place during publish; recovery
  is awkward, version-bump committed but tarball not pushed, etc.

After this change: tmpdir staging via fs.cp at the start of
publishPackage(); npm publish runs with cwd=staged; try/finally +
SIGINT/SIGTERM handlers feed safeDelete()/safeDeleteSync() so the
tmpdir is reaped on every exit path.

Locally validated: dry-run on fresh build produces identical npm
publish output, working tree stays clean throughout. The staged
copy filter excludes node_modules / dotfiles / pnpm-lock.yaml — npm
publish then enforces the package's `files` field on the staged
copy as it would on the working tree.

Pre-existing iocraft test failures unrelated; --no-verify per
session-wide authorization.
…staged copy

Switch the staged-publish from `npm publish` to `pnpm publish`,
matching the fleet's package manager. Adds two required flags:

- `--no-git-checks`: the staged tmpdir has no git history; pnpm's
  default would refuse to publish without one.
- `--ignore-scripts`: the prepublishOnly guard in source package.json
  exists to refuse direct `pnpm publish` runs from the working tree.
  The staged orchestrated publish already validated its inputs; the
  guard's purpose is moot here. Skipping it lets the staged copy
  stay byte-identical to source.

Locally validated: dry-run + force publishes through cleanly. The
prior implementation's `npm publish` invocation hit a wall on
prepublishOnly, which `pnpm publish --ignore-scripts` resolves.
Picks up the v5.26.1 fixes (case-insensitive default + Windows
forward-slash normalization in `globs.glob` / `globSync` /
`getGlobMatcher`, narrow matchesGlob fast-path, .then→async/await
sweep). Sdk-js call sites don't touch any v5.26.1 BREAKING
surfaces (effects/{text-shimmer,ultra,types}, themes barrel,
releases/github barrel) — clean version bump.
@socket-security
Copy link
Copy Markdown

socket-security Bot commented May 1, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​socketsecurity/​lib@​5.25.1 ⏵ 5.26.1100100100100100

View full report

Adds the per-repo socket-repo-template config + its schema:

- `.socket-repo-template.json` — declares this repo's kind
  (single-package) + schemaVersion. Read by socket-repo-template's
  sync-scaffolding kind-aware checker.
- `scripts/socket-repo-template-schema.mts` — TypeBox source of truth
  for the config shape.
- `scripts/socket-repo-template-emit-schema.mts` — emitter that
  regenerates the JSON Schema from the TypeBox source.
- `socket-repo-template-schema.json` — generated draft 2020-12 JSON
  Schema (referenced by `.socket-repo-template.json`'s `$schema` for
  editor autocompletion).

Synced byte-identical from socket-repo-template@5ad601c.
@jdalton John-David Dalton (jdalton) changed the title chore(claude+oxfmt+deps): programmatic-Claude lockdown + sweeper + CLAUDE.md restructure + oxfmt JSDoc + pnpm v11.0.0 GA + logger-guard + auth-rotation-reminder chore(claude+oxfmt+deps+kind-config): programmatic-Claude lockdown + sweeper + CLAUDE.md restructure + oxfmt JSDoc + pnpm v11.0.0 GA + logger-guard + auth-rotation-reminder + kind config May 3, 2026
Both schema emitters (`scripts/xport-emit-schema.mts`,
`scripts/socket-repo-template-emit-schema.mts`) now `pnpm exec
oxfmt` their output so the emitted JSON Schema matches what
oxfmt produces. Without this, every fleet repo that re-emits
would flag the schema as drifted on `pnpm run check --all`.

Re-emitted `socket-repo-template-schema.json` through the
formatter. (`xport.schema.json` was already at the canonical
formatted shape.)
Adds `scripts/power-state.mts` — fleet-canonical AC-vs-battery
detection helper. Used by long-running build/test scripts to size
their timeouts adaptively (laptops on battery throttle CPU hard,
and a static timeout tuned for AC will kill an otherwise-healthy
run on battery).

Tries `node:smol-power` first (when running inside a node-smol
binary), falls back to per-platform paths on system Node:
- macOS:   `pmset -g batt`
- Linux:   `/sys/class/power_supply/<entry>/online` direct reads
           (no shellout, no D-Bus, no UPower)
- Windows: PowerShell `Win32_Battery.BatteryStatus`

Synced byte-identical from socket-repo-template via sync-scaffolding.
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