Skip to content

Commit bc64815

Browse files
committed
refactor(path-guard): centralize stage / sibling vocabulary into segments.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.
1 parent 39f8cb7 commit bc64815

4 files changed

Lines changed: 108 additions & 185 deletions

File tree

.claude/hooks/path-guard/index.mts

Lines changed: 6 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -56,77 +56,12 @@
5656

5757
import process from 'node:process'
5858

59-
// "Stage" segments — appearing two or more in the same path.join /
60-
// template literal is a Rule A violation. These come from
61-
// build-infra/lib/constants.mts BUILD_STAGES plus their lowercase
62-
// directory-name siblings used by some builders (yoga's `wasm/`,
63-
// build-infra's `downloaded/`).
64-
const STAGE_SEGMENTS = new Set([
65-
'Final',
66-
'Release',
67-
'Stripped',
68-
'Compressed',
69-
'Optimized',
70-
'Synced',
71-
'wasm',
72-
'downloaded',
73-
])
74-
75-
// "Build-root" segments — at least one must be present together with a
76-
// stage segment to confirm we're constructing a build output path
77-
// rather than something coincidental. Example: `path.join(SRC,
78-
// 'wasm', 'lib')` shouldn't fire (no build root); `path.join(PKG,
79-
// 'build', 'wasm', 'out', 'Final')` should (build root + wasm + out +
80-
// Final).
81-
const BUILD_ROOT_SEGMENTS = new Set(['build', 'out'])
82-
83-
// Mode segments — appearing alongside stage + build-root tightens the
84-
// match further. `'dev'` and `'prod'` alone are too generic; we count
85-
// them as a confirming signal, not a trigger.
86-
const MODE_SEGMENTS = new Set(['dev', 'prod', 'shared'])
87-
88-
// Sibling Socket-fleet packages whose build output is reached via
89-
// `path.join(*, '..', '<name>', 'build', ...)`. Union of all packages
90-
// across the Socket fleet — the hook is byte-identical via
91-
// sync-scaffolding, so listing every fleet package keeps Rule B firing
92-
// in any repo. When a new package joins the workspace, add it here
93-
// and propagate via `node scripts/sync-scaffolding.mjs --all --fix`
94-
// from socket-repo-template.
95-
const KNOWN_SIBLING_PACKAGES = new Set([
96-
// socket-btm
97-
'binflate',
98-
'binject',
99-
'binpress',
100-
'bin-infra',
101-
'build-infra',
102-
'codet5-models-builder',
103-
'curl-builder',
104-
'iocraft-builder',
105-
'ink-builder',
106-
'libpq-builder',
107-
'lief-builder',
108-
'minilm-builder',
109-
'models',
110-
'napi-go',
111-
'node-smol-builder',
112-
'onnxruntime-builder',
113-
'opentui-builder',
114-
'stubs-builder',
115-
'ultraviolet-builder',
116-
'yoga-layout-builder',
117-
// socket-cli
118-
'cli',
119-
'package-builder',
120-
// socket-tui
121-
'core',
122-
'react',
123-
'renderer',
124-
'ultraviolet',
125-
'yoga',
126-
// socket-registry / ultrathink
127-
'acorn',
128-
'npm',
129-
])
59+
import {
60+
BUILD_ROOT_SEGMENTS,
61+
KNOWN_SIBLING_PACKAGES,
62+
MODE_SEGMENTS,
63+
STAGE_SEGMENTS,
64+
} from './segments.mts'
13065

13166
// File-path patterns that are exempt from the hook entirely. Edits to
13267
// these files legitimately need to enumerate path segments.
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Canonical path-segment vocabulary shared by the path-guard hook
2+
// (.claude/hooks/path-guard/index.mts) and gate (scripts/check-paths.mts).
3+
//
4+
// Mantra: 1 path, 1 reference. This module is the *one* place stage,
5+
// build-root, mode, and sibling-package vocabulary is defined. Both
6+
// consumers import from here so they can never drift apart.
7+
//
8+
// Synced byte-identically across the Socket fleet via
9+
// socket-repo-template/scripts/sync-scaffolding.mjs (IDENTICAL_FILES).
10+
// When adding a new stage/build-root/mode/sibling, edit this file in
11+
// the template and re-sync.
12+
13+
// "Stage" segments — Rule A core. Two of these spread via `path.join`
14+
// or interpolated into a template literal is a finding outside a
15+
// canonical `paths.mts`. Sourced from build-infra/lib/constants.mts
16+
// `BUILD_STAGES` plus their lowercase directory-name siblings used by
17+
// some builders.
18+
export const STAGE_SEGMENTS = new Set([
19+
'Compressed',
20+
'downloaded',
21+
'Final',
22+
'Optimized',
23+
'Release',
24+
'Stripped',
25+
'Synced',
26+
'wasm',
27+
])
28+
29+
// "Build-root" segments — at least one must be present together with
30+
// a stage segment to confirm we're constructing a build output path
31+
// rather than something coincidental. Example: a join that yields
32+
// `<root>/<stage>/<lib>` doesn't fire if no build-root segment is
33+
// present; `<root>/build/<stage>/out/<stage>` does.
34+
export const BUILD_ROOT_SEGMENTS = new Set(['build', 'out'])
35+
36+
// Build-mode segments — a stage segment plus one of these is also a
37+
// finding (`build/<mode>/<arch>/out/<stage>` is the canonical shape).
38+
export const MODE_SEGMENTS = new Set(['dev', 'prod', 'shared'])
39+
40+
// Sibling fleet packages (Rule B). Union of all packages across the
41+
// Socket fleet — the gate is byte-identical via sync-scaffolding, so
42+
// listing every fleet package keeps Rule B firing in any repo. When a
43+
// new package joins the workspace, add it here and propagate via
44+
// `node scripts/sync-scaffolding.mjs --all --fix` from
45+
// socket-repo-template.
46+
export const KNOWN_SIBLING_PACKAGES = new Set([
47+
// socket-btm
48+
'bin-infra',
49+
'binflate',
50+
'binject',
51+
'binpress',
52+
'build-infra',
53+
'codet5-models-builder',
54+
'curl-builder',
55+
'ink-builder',
56+
'iocraft-builder',
57+
'libpq-builder',
58+
'lief-builder',
59+
'minilm-builder',
60+
'models',
61+
'napi-go',
62+
'node-smol-builder',
63+
'onnxruntime-builder',
64+
'opentui-builder',
65+
'stubs-builder',
66+
'ultraviolet-builder',
67+
'yoga-layout-builder',
68+
// socket-cli
69+
'cli',
70+
'package-builder',
71+
// socket-tui
72+
'core',
73+
'react',
74+
'renderer',
75+
'ultraviolet',
76+
'yoga',
77+
// socket-registry / ultrathink
78+
'acorn',
79+
'npm',
80+
])

.claude/skills/path-guard/reference/check-paths.mts.tmpl

Lines changed: 11 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ import { fileURLToPath } from 'node:url'
7676

7777
import { parseArgs } from 'node:util'
7878

79+
import {
80+
BUILD_ROOT_SEGMENTS,
81+
KNOWN_SIBLING_PACKAGES,
82+
MODE_SEGMENTS,
83+
STAGE_SEGMENTS,
84+
} from '../.claude/hooks/path-guard/segments.mts'
85+
7986
// Plain stderr/stdout output — no @socketsecurity/lib dependency so
8087
// the gate is self-contained and works in socket-lib itself (which
8188
// would otherwise import itself).
@@ -91,63 +98,10 @@ const __filename = fileURLToPath(import.meta.url)
9198
const __dirname = path.dirname(__filename)
9299
const REPO_ROOT = path.resolve(__dirname, '..')
93100

94-
// Stage segments (Rule A core). Spreading any two of these via
95-
// `path.join` is a finding outside `paths.mts`.
96-
const STAGE_SEGMENTS = new Set([
97-
'Final',
98-
'Release',
99-
'Stripped',
100-
'Compressed',
101-
'Optimized',
102-
'Synced',
103-
'wasm',
104-
'downloaded',
105-
])
106-
107-
const BUILD_ROOT_SEGMENTS = new Set(['build', 'out'])
108-
const MODE_SEGMENTS = new Set(['dev', 'prod', 'shared'])
109-
110-
// Sibling fleet packages (Rule B). Union of all packages across the
111-
// Socket fleet — the gate is byte-identical via sync-scaffolding, so
112-
// listing every fleet package keeps Rule B firing in any repo. When
113-
// a new package joins the workspace, add it here and propagate via
114-
// `node scripts/sync-scaffolding.mjs --all --fix` from
115-
// socket-repo-template.
116-
const KNOWN_SIBLING_PACKAGES = new Set([
117-
// socket-btm
118-
'binflate',
119-
'binject',
120-
'binpress',
121-
'bin-infra',
122-
'build-infra',
123-
'codet5-models-builder',
124-
'curl-builder',
125-
'iocraft-builder',
126-
'ink-builder',
127-
'libpq-builder',
128-
'lief-builder',
129-
'minilm-builder',
130-
'models',
131-
'napi-go',
132-
'node-smol-builder',
133-
'onnxruntime-builder',
134-
'opentui-builder',
135-
'stubs-builder',
136-
'ultraviolet-builder',
137-
'yoga-layout-builder',
138-
// socket-cli
139-
'cli',
140-
'package-builder',
141-
// socket-tui
142-
'core',
143-
'react',
144-
'renderer',
145-
'ultraviolet',
146-
'yoga',
147-
// socket-registry / ultrathink
148-
'acorn',
149-
'npm',
150-
])
101+
// Stage / build-root / mode / sibling-package vocabularies are imported
102+
// from `.claude/hooks/path-guard/segments.mts` (the canonical source).
103+
// Both this gate and the path-guard hook share that single definition
104+
// — Mantra: 1 path, 1 reference.
151105

152106
// File-path patterns that legitimately enumerate path segments.
153107
const EXEMPT_FILE_PATTERNS: RegExp[] = [

scripts/check-paths.mts

Lines changed: 11 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ import { fileURLToPath } from 'node:url'
7676

7777
import { parseArgs } from 'node:util'
7878

79+
import {
80+
BUILD_ROOT_SEGMENTS,
81+
KNOWN_SIBLING_PACKAGES,
82+
MODE_SEGMENTS,
83+
STAGE_SEGMENTS,
84+
} from '../.claude/hooks/path-guard/segments.mts'
85+
7986
// Plain stderr/stdout output — no @socketsecurity/lib dependency so
8087
// the gate is self-contained and works in socket-lib itself (which
8188
// would otherwise import itself).
@@ -91,63 +98,10 @@ const __filename = fileURLToPath(import.meta.url)
9198
const __dirname = path.dirname(__filename)
9299
const REPO_ROOT = path.resolve(__dirname, '..')
93100

94-
// Stage segments (Rule A core). Spreading any two of these via
95-
// `path.join` is a finding outside `paths.mts`.
96-
const STAGE_SEGMENTS = new Set([
97-
'Final',
98-
'Release',
99-
'Stripped',
100-
'Compressed',
101-
'Optimized',
102-
'Synced',
103-
'wasm',
104-
'downloaded',
105-
])
106-
107-
const BUILD_ROOT_SEGMENTS = new Set(['build', 'out'])
108-
const MODE_SEGMENTS = new Set(['dev', 'prod', 'shared'])
109-
110-
// Sibling fleet packages (Rule B). Union of all packages across the
111-
// Socket fleet — the gate is byte-identical via sync-scaffolding, so
112-
// listing every fleet package keeps Rule B firing in any repo. When
113-
// a new package joins the workspace, add it here and propagate via
114-
// `node scripts/sync-scaffolding.mjs --all --fix` from
115-
// socket-repo-template.
116-
const KNOWN_SIBLING_PACKAGES = new Set([
117-
// socket-btm
118-
'binflate',
119-
'binject',
120-
'binpress',
121-
'bin-infra',
122-
'build-infra',
123-
'codet5-models-builder',
124-
'curl-builder',
125-
'iocraft-builder',
126-
'ink-builder',
127-
'libpq-builder',
128-
'lief-builder',
129-
'minilm-builder',
130-
'models',
131-
'napi-go',
132-
'node-smol-builder',
133-
'onnxruntime-builder',
134-
'opentui-builder',
135-
'stubs-builder',
136-
'ultraviolet-builder',
137-
'yoga-layout-builder',
138-
// socket-cli
139-
'cli',
140-
'package-builder',
141-
// socket-tui
142-
'core',
143-
'react',
144-
'renderer',
145-
'ultraviolet',
146-
'yoga',
147-
// socket-registry / ultrathink
148-
'acorn',
149-
'npm',
150-
])
101+
// Stage / build-root / mode / sibling-package vocabularies are imported
102+
// from `.claude/hooks/path-guard/segments.mts` (the canonical source).
103+
// Both this gate and the path-guard hook share that single definition
104+
// — Mantra: 1 path, 1 reference.
151105

152106
// File-path patterns that legitimately enumerate path segments.
153107
const EXEMPT_FILE_PATTERNS: RegExp[] = [

0 commit comments

Comments
 (0)