Skip to content

Commit 113967f

Browse files
committed
chore(sync): cascade fleet updates from socket-repo-template
- New docs/references/agent-delegation.md (CLI-subprocess vs. subagent delegation paths, routing heuristics). - CLAUDE.md fleet block: "Agents & skills" gains pointer to the delegation doc. - socket-hook marker fix: pre-commit/pre-push and the logger-guard hook now accept `//` and `/* */` comment prefixes alongside `#`, so `.ts`/`.mts` files use `// socket-hook: allow logger` naturally. - scanning-quality SKILL.md, security.mts, socket-repo-template-schema pair: byte-identical resync against template. Pre-commit bypassed: pre-commit escalates to a full build that downloads native socket-btm release assets and hits a 403 on the anonymous code path. The build wouldn't validate any of these changes (docs + regex broadening), so --no-verify per user instruction.
1 parent c3b2aec commit 113967f

9 files changed

Lines changed: 95 additions & 11 deletions

File tree

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,11 @@ const LOGGER_LEAK_RE =
6868

6969
const COMMENT_LINE_RE = /^\s*(\*|\/\/|#)/
7070
const JSDOC_TAG_RE = /@(example|param|returns?|see|link)\b/
71-
const SOCKET_HOOK_MARKER_RE = /#\s*socket-hook:\s*allow(?:\s+([\w-]+))?/
71+
// Accept `#`, `//`, or `/*` comment prefixes — same as the git pre-
72+
// commit/pre-push scanners. This hook is invoked on TS/JS edits where
73+
// `// socket-hook: allow logger` is the only natural spelling.
74+
const SOCKET_HOOK_MARKER_RE =
75+
/(?:#|\/\/|\/\*)\s*socket-hook:\s*allow(?:\s+([\w-]+))?/
7276

7377
function isMarkerSuppressed(line: string): boolean {
7478
const m = line.match(SOCKET_HOOK_MARKER_RE)

.claude/hooks/logger-guard/test/logger-guard.test.mts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,28 @@ test('respects bare # socket-hook: allow marker', async () => {
115115
assert.equal(code, 0)
116116
})
117117

118+
test('respects // socket-hook: allow logger marker (slash-slash prefix)', async () => {
119+
const { code } = await runHook({
120+
tool_name: 'Edit',
121+
tool_input: {
122+
file_path: 'src/foo.ts',
123+
new_string: 'process.stderr.write(buf) // socket-hook: allow logger',
124+
},
125+
})
126+
assert.equal(code, 0)
127+
})
128+
129+
test('respects /* socket-hook: allow logger */ marker (block-comment prefix)', async () => {
130+
const { code } = await runHook({
131+
tool_name: 'Edit',
132+
tool_input: {
133+
file_path: 'src/foo.ts',
134+
new_string: 'console.error("a") /* socket-hook: allow logger */',
135+
},
136+
})
137+
assert.equal(code, 0)
138+
})
139+
118140
test('does not flag JSDoc examples', async () => {
119141
const { code } = await runHook({
120142
tool_name: 'Write',

.claude/skills/scanning-quality/SKILL.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ allowed-tools: Task, Read, Grep, Glob, AskUserQuestion, Bash(pnpm run check:*),
99

1010
Perform comprehensive quality analysis across the codebase using specialized agents. Clean up junk files first, then scan and generate a prioritized report with actionable fixes.
1111

12+
## Modes
13+
14+
- **Default (interactive)**`AskUserQuestion` is used to confirm cleanup deletions and to pick scan scope.
15+
- **Non-interactive**`/scanning-quality non-interactive` (or any of the aliases below) skips every `AskUserQuestion` and applies safe defaults: scan scope = all types, cleanup = leave junk files in place (don't delete without confirmation), report-save = yes (`reports/scanning-quality-YYYY-MM-DD.md`). Use this when running headlessly (e.g. `pnpm run fleet-skill scanning-quality`, CI cron, programmatic Claude). The four-flag programmatic-Claude lockdown rule already strips `AskUserQuestion`, so headless runs default to non-interactive automatically — but call it out explicitly so future readers understand the contract.
16+
17+
Detect non-interactive mode via any of: `--non-interactive` argument, `non-interactive` argument, `SCANNING_QUALITY_NONINTERACTIVE=1` env var, or absence of `AskUserQuestion` in the available tool surface.
18+
1219
## Scan Types
1320

1421
1. **critical** - Crashes, security vulnerabilities, resource leaks, data corruption
@@ -46,7 +53,7 @@ Install zizmor for GitHub Actions security scanning, respecting the soak window
4653

4754
### Phase 4: Repository Cleanup
4855

49-
Find and remove junk files (with user confirmation via AskUserQuestion):
56+
Find junk files (interactive mode confirms each batch via `AskUserQuestion`; non-interactive mode lists what was found in the report and leaves them in place — don't delete files without explicit confirmation, even on a clean dirty-tree):
5057
- SCREAMING_TEXT.md files outside `.claude/` and `docs/`
5158
- Test files in wrong locations
5259
- Temp files (`.tmp`, `.DS_Store`, `*~`, `*.swp`, `*.bak`)
@@ -62,7 +69,9 @@ Report errors as Critical findings. Warnings are Low findings. (The fleet's stru
6269

6370
### Phase 6: Determine Scan Scope
6471

65-
Ask user which scans to run using AskUserQuestion (multiSelect). Default: all scans.
72+
In **interactive** mode, ask the user which scans to run via `AskUserQuestion` (multiSelect). Default: all scans.
73+
74+
In **non-interactive** mode, run all scan types — no prompt.
6675

6776
### Phase 7: Execute Scans
6877

@@ -77,7 +86,8 @@ Each agent reports findings as:
7786
- Deduplicate findings across scan types
7887
- Sort by severity: Critical > High > Medium > Low
7988
- Generate markdown report with file:line references, suggested fixes, and coverage metrics
80-
- Offer to save to `reports/scanning-quality-YYYY-MM-DD.md`
89+
- **Interactive**: offer to save to `reports/scanning-quality-YYYY-MM-DD.md` via `AskUserQuestion`.
90+
- **Non-interactive**: save the report unconditionally to `reports/scanning-quality-YYYY-MM-DD.md` (create the directory if missing) so the artifact is visible to the orchestrating runner. If the `Write` tool isn't in the allow list, emit the full markdown to stdout with a leading `=== REPORT MARKDOWN ===` marker so the runner can capture and persist it.
8191

8292
### Phase 9: Summary
8393

.git-hooks/_helpers.mts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,15 @@ const PERSONAL_PATH_PLACEHOLDER_RE =
102102

103103
// Per-line opt-out marker for our pre-commit / pre-push scanners.
104104
//
105-
// Canonical form: # socket-hook: allow
106-
// Targeted form: # socket-hook: allow <rule>
105+
// Canonical form: <comment-prefix> socket-hook: allow
106+
// Targeted form: <comment-prefix> socket-hook: allow <rule>
107+
//
108+
// `<comment-prefix>` is whichever comment style the host file uses —
109+
// `#` for shell / YAML / TOML / Dockerfile, `//` for TS / JS / Rust /
110+
// Go / C-family, or `/*` for the C-block-comment opener. The hook is
111+
// invoked from many file types; pinning to `#` made the marker fail
112+
// silently in `.ts` / `.mts` files (where `// socket-hook: allow` is
113+
// the only sensible spelling) and confused contributors.
107114
//
108115
// The targeted form names a specific rule (`personal-path`, `npx`,
109116
// `aws-key`, etc.) and is recommended for reviewers; the bare `allow`
@@ -113,8 +120,9 @@ const PERSONAL_PATH_PLACEHOLDER_RE =
113120
// Legacy `# zizmor: ...` markers are still recognized for one cycle so
114121
// existing files don't have to be rewritten in the same change that
115122
// renames the marker.
116-
const SOCKET_HOOK_MARKER_RE = /#\s*socket-hook:\s*allow(?:\s+([\w-]+))?/
117-
const LEGACY_ZIZMOR_MARKER_RE = /#\s*zizmor:\s*[\w-]+/
123+
const SOCKET_HOOK_MARKER_RE =
124+
/(?:#|\/\/|\/\*)\s*socket-hook:\s*allow(?:\s+([\w-]+))?/
125+
const LEGACY_ZIZMOR_MARKER_RE = /(?:#|\/\/|\/\*)\s*zizmor:\s*[\w-]+/
118126

119127
function lineIsSuppressed(line: string, rule?: string): boolean {
120128
if (LEGACY_ZIZMOR_MARKER_RE.test(line)) {

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ Full hook spec in [`.claude/hooks/token-guard/README.md`](.claude/hooks/token-gu
165165
- `/scanning-security` — AgentShield + zizmor audit
166166
- `/scanning-quality` — quality analysis
167167
- Shared subskills in `.claude/skills/_shared/`
168+
- **Handing off to another agent** — see [`docs/references/agent-delegation.md`](docs/references/agent-delegation.md) for when to reach for `codex:codex-rescue`, the `delegate` subagent (OpenCode → Fireworks/Synthetic/Kimi), `Explore`, `Plan`, vs. driving the skill CLIs directly. The CLI-subprocess contract used by skills lives in [`_shared/multi-agent-backends.md`](.claude/skills/_shared/multi-agent-backends.md).
168169

169170
#### Skill scope: fleet vs partial vs unique
170171

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Agent delegation
2+
3+
When a task fits one of the patterns below, hand it off instead of doing it in the current session. The point is to get a _different model's_ take or to keep heavy work out of the main context — not to avoid effort. Don't delegate trivial tasks: the round-trip overhead isn't worth it for things you can answer in one or two tool calls.
4+
5+
There are two delegation surfaces in this fleet. They look similar but are used differently.
6+
7+
## Surface 1 — CLI subprocess delegation (skills)
8+
9+
Skills that need multi-model output spawn the agent CLIs (`codex`, `claude`, `kimi`, `opencode`) as subprocesses and fold the results into a report. The contract — backend registry, detection policy, fallback order, attribution — lives in [`_shared/multi-agent-backends.md`](../../.claude/skills/_shared/multi-agent-backends.md). The canonical implementation is [`reviewing-code/run.mts`](../../.claude/skills/reviewing-code/run.mts).
10+
11+
Use this surface when _the skill itself_ is the orchestrator (multi-pass review, parallel scans, fleet-wide runs).
12+
13+
## Surface 2 — Subagent delegation (mid-conversation)
14+
15+
When the _current_ Claude session wants to hand off a single task to another model and consume its result inline, use `Agent(subagent_type=…)`. This is in-conversation delegation, not skill orchestration.
16+
17+
| Subagent | When to use |
18+
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
19+
| `codex:codex-rescue` | You want GPT-5.4's take or a heavyweight async investigation. Best for: hard debugging you're stuck on, second implementation pass on a tricky design, deep root-cause work. Persistent runtime — check progress with `/codex:status`, get output with `/codex:result`. Also exposed as `/codex:rescue` for user-driven invocation. |
20+
| `delegate` | You want a Fireworks / Synthetic / Kimi open model via [OpenCode](https://opencode.ai). Best for: cheap bulk work (classification, summarization, drafting many things), specialist routing (e.g. Qwen-Coder for code-heavy tasks), second opinions from a non-GPT/non-Claude model. Caller specifies the model in the prompt (e.g. `fireworks/qwen3-coder-480b`). Fire-and-forget. **Optional** — only available if the dev has set up the `delegate` agent locally. Skill code must not depend on it. |
21+
| `Explore` | Codebase search / "where is X defined" / cross-file lookups. Different model isn't the point — context isolation is. |
22+
| `Plan` | Implementation strategy for a non-trivial task before writing code. |
23+
| `general-purpose` | Open-ended research that doesn't fit the above. |
24+
25+
## Routing heuristics
26+
27+
- **Stuck after one or two failed attempts**`codex:codex-rescue`. A different family often breaks the deadlock.
28+
- **About to do 20+ similar small operations**`delegate` with a cheap model. Keep the main context clean.
29+
- **Want a sanity check on a non-trivial design or diff**`/codex:adversarial-review` (slash command) _or_ `delegate` to a different family, depending on which perspective is more useful.
30+
- **Big codebase question that'll burn context**`Explore`.
31+
- **Building a multi-pass workflow** → don't use `Agent(...)` ad hoc; write a skill that uses Surface 1.
32+
33+
## When the surfaces overlap
34+
35+
A skill that wants `codex` output should call the CLI (Surface 1) so the result lands in a structured report. A live conversation that wants Codex's opinion on the _current_ problem should use the subagent (Surface 2) so the result flows back into the conversation. Same model, different orchestration.
36+
37+
## Compatibility note
38+
39+
Codex is fleet-wide (the `codex` CLI is a fleet plugin). OpenCode and the `delegate` subagent are **per-developer** — they require local setup outside the repo. Skills that automate work across the fleet must not assume `delegate` exists; humans driving Claude in their own checkout can use it freely.

scripts/security.mts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* @fileoverview Canonical fleet security-scan runner.
2+
* @fileoverview Canonical fleet scanning-security runner.
33
*
44
* Runs the two static-analysis tools the fleet uses for local security
55
* checks before push:

scripts/socket-repo-template-schema.mts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ const ClaudeSchema = Type.Object(
155155
{
156156
includeSecurityScanSkill: Type.Optional(
157157
Type.Boolean({
158-
description: 'Ship `.claude/skills/security-scan/SKILL.md`.',
158+
description: 'Ship `.claude/skills/scanning-security/SKILL.md`.',
159159
}),
160160
),
161161
includeSharedSkills: Type.Optional(

socket-repo-template-schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@
155155
"type": "object",
156156
"properties": {
157157
"includeSecurityScanSkill": {
158-
"description": "Ship `.claude/skills/security-scan/SKILL.md`.",
158+
"description": "Ship `.claude/skills/scanning-security/SKILL.md`.",
159159
"type": "boolean"
160160
},
161161
"includeSharedSkills": {

0 commit comments

Comments
 (0)