Skip to content

chore(scaffolding): adopt token-guard + path-guard from socket-repo-template#621

Closed
John-David Dalton (jdalton) wants to merge 9 commits intomainfrom
paths-rollout
Closed

chore(scaffolding): adopt token-guard + path-guard from socket-repo-template#621
John-David Dalton (jdalton) wants to merge 9 commits intomainfrom
paths-rollout

Conversation

@jdalton
Copy link
Copy Markdown
Contributor

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

Summary

Propagates the path-guard infrastructure and token-hygiene → token-guard rename from socket-repo-template@bb21ab5.

Mantra: 1 path, 1 reference. Every build/test/runtime path is constructed exactly once; everywhere else references the constructed value.

Three-level enforcement

  • CLAUDE.md rule — mantra section (will land on next CLAUDE.md sync from template).
  • Hook (.claude/hooks/path-guard/) — PreToolUse on Edit/Write of .mts/.cts files. Blocks new path duplications at edit time.
  • Gate (scripts/check-paths.mts) — whole-repo scan; runs after lint/type/validate steps in pnpm run check --all.

What's new

  • .claude/hooks/path-guard/ — new mandatory PreToolUse hook + tests.
  • .claude/hooks/path-guard/segments.mts — single canonical source of STAGE_SEGMENTS, BUILD_ROOT_SEGMENTS, MODE_SEGMENTS, KNOWN_SIBLING_PACKAGES. Imported by both hook and gate so they can never drift.
  • .claude/hooks/token-guard/ — renamed from token-hygiene (same behavior, new name aligns with the *-guard family). Word-boundary match for sensitive env names.
  • .claude/skills/path-guard/ — invokable /path-guard skill (audit-and-fix, check, install modes).
  • .claude/skills/_shared/path-guard-rule.md — canonical rule snippet.
  • scripts/check-paths.mts — the gate.
  • .github/paths-allowlist.yml — narrow-exemption allowlist (empty starter).
  • .claude/settings.json — wires path-guard on Edit|Write, token-guard on Bash.
  • scripts/check.mts — invokes check-paths.mts after the existing file-size validation step.
  • package.json — adds check:paths script.

Detection improvements

  • Template-literal path detection: hook + gate now flag template-string build paths like `${PKG}/build/${mode}/${arch}/out/Final/...` that were previously invisible to a path.join-only scanner.
  • Drift-resistant allowlist: replaces ±2-line tolerance with exact-line OR snippet_hash match. snippet_hash is a 12-char SHA-256 prefix of the whitespace-normalized snippet, surviving reformatting but invalidated by any content-changing edit.
  • --show-hashes flag: print the hash for each finding when authoring an allowlist entry.
  • Centralized vocabulary: stage / build-root / mode / sibling-package sets live in segments.mts — the hook and gate import from one source, eliminating drift.
  • Paren-balanced parser: handles nested function-call args inside path.join/path.resolve.
  • Multi-line YAML reasons: allowlist supports | and > block scalars.

Verification

node scripts/check-paths.mts --quiet  # exit 0 — no findings

Gate runs clean against socket-sdk-js on first scan.

Companion propagations

Repo Commit
socket-btm 0960ee27
socket-repo-template bb21ab5
socket-tui 8a0ab67
socket-sdxgen f4fd9c6
ultrathink e77b1e849
socket-packageurl-js dcf5d12

Test plan

  • gate runs clean (node scripts/check-paths.mts exits 0)
  • CI passes

…emplate

Propagated via sync-scaffolding from socket-repo-template@cfba1e6.
Three-level enforcement of "1 path, 1 reference":

  1. CLAUDE.md rule (mantra-driven; lands on next CLAUDE.md sync)
  2. Hook (.claude/hooks/path-guard/) — PreToolUse on Edit/Write of
     .mts/.cts files; blocks new path duplications at edit time
  3. Gate (scripts/check-paths.mts) — whole-repo scan; runs as part
     of pnpm check via runParallel.

Renames token-hygiene → token-guard fleet-wide.

Hook package.jsons drop the @socketsecurity/lib catalog devDep so
they install cleanly in repos without a 'default' catalog entry.

Gate runs clean against socket-sdk-js on first scan.

Companion fleet propagations: socket-cli #1280; socket-btm 360d469d;
socket-tui 79dc1ca; socket-lib 5153ddd; socket-sdxgen ef8e39f;
ultrathink 1534b406d; socket-packageurl-js e720bc1.
…, multi-line YAML (sync from template@fbadb76)
…te literal detection

Sync from socket-repo-template@000943d. Hook + gate now flag template-
literal build paths; allowlist replaces ±2 line tolerance with exact-line
OR snippet_hash match. New --show-hashes flag prints SHA-256 prefix for
allowlist entries that survive reformatting.
…ents.mts

Sync from socket-repo-template@bb21ab5. Mantra: 1 path, 1 reference.
The hook and gate now both import STAGE_SEGMENTS, BUILD_ROOT_SEGMENTS,
MODE_SEGMENTS, and KNOWN_SIBLING_PACKAGES from a single canonical
.claude/hooks/path-guard/segments.mts so they can no longer drift on
what counts as a build-output path.
Format check-paths.mts (Gap 2 sync), CLAUDE.md (sync drift), and
xport.schema.json (sync drift) so CI lint passes.
@jdalton
Copy link
Copy Markdown
Contributor Author

bugbot run

@jdalton
Copy link
Copy Markdown
Contributor Author

bugbot run

John-David Dalton (jdalton) added a commit that referenced this pull request Apr 27, 2026
…y/ scope)

Consolidates PR #621 (path-guard infra) and #622 (.sh→.mts hook
conversion) into this branch. Resolves the modify/delete conflict
on .git-hooks/{commit-msg,pre-push} by accepting the .mts versions
— the env allowlist tweak from #620 is already covered in
commit-msg.mts via shouldSkipFile and the precommit allowlist.

Also renames internal hook packages to drop the @socketsecurity/
scope (hook-path-guard, hook-token-guard, hook-check-new-deps) —
they're private:true and never published.
@jdalton
Copy link
Copy Markdown
Contributor Author

Superseded by #620 (consolidated). All commits and Bugbot fixes from this branch are now in #620.

@jdalton John-David Dalton (jdalton) deleted the paths-rollout branch April 27, 2026 00:59
John-David Dalton (jdalton) added a commit that referenced this pull request Apr 27, 2026
Consolidates the work previously split across PRs #620 (env allowlist),
#621 (path-guard infra), and #622 (.sh→.mts hook conversion) into a
single commit on chore/harden-env-allowlist.

What's included:

  Env allowlist + .cache/ + CLAUDE.md
  - Drop NODE_COMPILE_CACHE-equivalent stale env entries
  - Allow .env.precommit at any depth in commit-msg hook
  - Skip hook scripts in scanners (they contain the literal regex)
  - Exclude .cache/** in tsconfig.check.json
  - Propagate CLAUDE.md sorting + open-PR + paths + inclusive-language
    rules; Set constructor sort rule; don't-revert-untouched rule;
    replace whitelist/blacklist with allowlist/denylist

  Path-guard infra (.claude/hooks/path-guard/, scripts/check-paths.mts,
  .github/paths-allowlist.yml, .claude/skills/path-guard/)
  - Mantra: 1 path, 1 reference. PreToolUse hook on Edit|Write blocks
    multi-stage build paths constructed inline; companion gate runs
    in pnpm check
  - Template-literal path detection
  - Drift-resistant allowlist via exact-line OR snippet_hash match
  - --show-hashes CLI flag for authoring allowlist entries
  - Centralized vocabulary in segments.mts (hook + gate share one
    source for stage / build-root / mode / sibling-package sets)
  - Paren-balanced parser handles nested function-call args
  - Multi-line YAML reasons (| and > block scalars)

  Token-guard renamed from token-hygiene
  - Word-boundary match for sensitive env names (no more false
    positives on substring matches inside identifiers)
  - Step 1 (ALWAYS_DANGEROUS) now gates on hasRedaction so
    'env | sed s/=.*/=<redacted>/' (the suggested fix) actually passes

  .sh → .mts hook conversion (Node 25+)
  - .git-hooks/_helpers.mts (was _helpers.sh) — exports
    filterAllowedApiKeys + scanners for personal paths, AWS keys,
    GitHub tokens, private keys, AI attribution
  - .git-hooks/{commit-msg,pre-commit,pre-push}.mts (were .sh)
  - _helpers.mts hard-fails at module load if Node < 25 (relies on
    stable type stripping, no flag)
  - Husky shims invoke node directly

  Hook package rename
  - Drop @socketsecurity/ scope from internal hook packages
    (hook-path-guard, hook-token-guard, hook-check-new-deps); they
    are private:true and never published to npm

  Dep
  - Add @sinclair/typebox 0.34.49 to devDependencies (used by
    scripts/xport-schema.mts)
John-David Dalton (jdalton) added a commit that referenced this pull request Apr 27, 2026
Consolidates the work previously split across PRs #620 (env allowlist),
#621 (path-guard infra), and #622 (.sh→.mts hook conversion) into a
single commit on chore/harden-env-allowlist.

What's included:

  Env allowlist + .cache/ + CLAUDE.md
  - Drop NODE_COMPILE_CACHE-equivalent stale env entries
  - Allow .env.precommit at any depth in commit-msg hook
  - Skip hook scripts in scanners (they contain the literal regex)
  - Exclude .cache/** in tsconfig.check.json
  - Propagate CLAUDE.md sorting + open-PR + paths + inclusive-language
    rules; Set constructor sort rule; don't-revert-untouched rule;
    replace whitelist/blacklist with allowlist/denylist

  Path-guard infra (.claude/hooks/path-guard/, scripts/check-paths.mts,
  .github/paths-allowlist.yml, .claude/skills/path-guard/)
  - Mantra: 1 path, 1 reference. PreToolUse hook on Edit|Write blocks
    multi-stage build paths constructed inline; companion gate runs
    in pnpm check
  - Template-literal path detection
  - Drift-resistant allowlist via exact-line OR snippet_hash match
  - --show-hashes CLI flag for authoring allowlist entries
  - Centralized vocabulary in segments.mts (hook + gate share one
    source for stage / build-root / mode / sibling-package sets)
  - Paren-balanced parser handles nested function-call args
  - Multi-line YAML reasons (| and > block scalars)

  Token-guard renamed from token-hygiene
  - Word-boundary match for sensitive env names (no more false
    positives on substring matches inside identifiers)
  - Step 1 (ALWAYS_DANGEROUS) now gates on hasRedaction so
    'env | sed s/=.*/=<redacted>/' (the suggested fix) actually passes

  .sh → .mts hook conversion (Node 25+)
  - .git-hooks/_helpers.mts (was _helpers.sh) — exports
    filterAllowedApiKeys + scanners for personal paths, AWS keys,
    GitHub tokens, private keys, AI attribution
  - .git-hooks/{commit-msg,pre-commit,pre-push}.mts (were .sh)
  - _helpers.mts hard-fails at module load if Node < 25 (relies on
    stable type stripping, no flag)
  - Husky shims invoke node directly

  Hook package rename
  - Drop @socketsecurity/ scope from internal hook packages
    (hook-path-guard, hook-token-guard, hook-check-new-deps); they
    are private:true and never published to npm

  Dep
  - Add @sinclair/typebox 0.34.49 to devDependencies (used by
    scripts/xport-schema.mts)
John-David Dalton (jdalton) added a commit that referenced this pull request Apr 27, 2026
…rap + cascade

Consolidated PR — combines the original work from #620, #621, #622
plus follow-up commits (private-name rule, socket-registry pin
cascades) into a single squashed commit.

Includes:

- env allowlist + .cache/ + CLAUDE.md hygiene (restore .cache/**
  exclude in tsconfigs; propagate CLAUDE.md sorting/open-PR/paths/
  inclusive-language/Set-sort/don't-revert-untouched/private-name
  rules; replace whitelist/blacklist with allowlist/denylist)
- path-guard infra (PreToolUse hook + scripts/check-paths.mts gate +
  .github/paths-allowlist.yml + /path-guard skill — enforces
  "1 path, 1 reference" so multi-stage build paths are constructed
  exactly once)
- token-guard hook (renamed from token-hygiene; word-boundary match
  for sensitive env names; ALWAYS_DANGEROUS gates on hasRedaction so
  redacted env dumps pass)
- .sh -> .mts hook conversion on Node 25+ (stable type stripping;
  _helpers.mts hard-fails at module load if Node < 25; husky shims
  invoke node directly)
- internal hook package rename (drop @socketsecurity/ scope from
  hook-path-guard, hook-token-guard, hook-check-new-deps; private,
  never published)
- xport lock-step manifest (scripts/xport.mts +
  scripts/xport-schema.mts + scripts/xport-emit-schema.mts +
  xport.schema.json)
- bootstrap-from-registry (scripts/bootstrap-from-registry.mts
  downloads zero-dep Socket packages from npm registry into
  node_modules/ via preinstall hook, solving fresh-clone
  chicken-and-egg)
- socket-registry pins cascaded to ceab1e26 (picks up the
  @socketsecurity/lib bootstrap move from the install action into
  setup, so consumers calling only setup also benefit)
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.

1 participant