@chrono-meta/fh-gate 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/challenger.md +169 -0
- package/AGENTS.md +160 -0
- package/CATALOG.md +256 -0
- package/CHEATSHEET.md +367 -0
- package/CLAUDE.md +331 -0
- package/CONTRIBUTING.md +198 -0
- package/LICENSE +21 -0
- package/README.md +60 -7
- package/bin/fh-goal.js +9 -0
- package/bin/fh-run.js +9 -0
- package/docs/banner.png +0 -0
- package/docs/codex-compat.md +123 -0
- package/docs/pillars.svg +70 -0
- package/knowledge/shared/harness-core/fh_integration_contract.md +45 -28
- package/package.json +31 -6
- package/plugins/fh-commons/README.md +37 -0
- package/plugins/fh-commons/agents/quench-challenger.md +373 -0
- package/plugins/fh-commons/skills/convergence-loop/SKILL.md +155 -0
- package/plugins/fh-commons/skills/deliberation/SKILL.md +288 -0
- package/plugins/fh-commons/skills/mcp-circuit-breaker/SKILL.md +196 -0
- package/plugins/fh-commons/skills/token-budget-gate/SKILL.md +175 -0
- package/plugins/fh-meta/agents/fact-checker.md +121 -0
- package/plugins/fh-meta/agents/hub-persona-auditor.md +109 -0
- package/plugins/fh-meta/agents/persona-innovator.md +195 -0
- package/plugins/fh-meta/skills/agent-composer/SKILL.md +461 -0
- package/plugins/fh-meta/skills/agent-composer/SKILL_detail.md +464 -0
- package/plugins/fh-meta/skills/apex-review/SKILL.md +185 -0
- package/plugins/fh-meta/skills/asset-placement-gate/SKILL.md +135 -0
- package/plugins/fh-meta/skills/contention-layer/SKILL.md +127 -0
- package/plugins/fh-meta/skills/context-bridge-dispatch/SKILL.md +30 -0
- package/plugins/fh-meta/skills/context-bridge-dispatch/SKILL_detail.md +144 -0
- package/plugins/fh-meta/skills/context-doctor/SKILL.md +341 -0
- package/plugins/fh-meta/skills/cross-ecosystem-synergy-detection/SKILL.md +202 -0
- package/plugins/fh-meta/skills/deep-clarify/SKILL.md +144 -0
- package/plugins/fh-meta/skills/edit-manifest/SKILL.md +210 -0
- package/plugins/fh-meta/skills/field-harvest/SKILL.md +384 -0
- package/plugins/fh-meta/skills/frontier-digest/SKILL.md +272 -0
- package/plugins/fh-meta/skills/goal-quench/SKILL.md +509 -0
- package/plugins/fh-meta/skills/harness-doctor/SKILL.md +277 -0
- package/plugins/fh-meta/skills/harness-doctor/SKILL_detail.md +484 -0
- package/plugins/fh-meta/skills/harvest-loop/SKILL.md +231 -0
- package/plugins/fh-meta/skills/harvest-loop/SKILL_detail.md +201 -0
- package/plugins/fh-meta/skills/hub-cc-pr-reviewer/SKILL.md +129 -0
- package/plugins/fh-meta/skills/hub-cc-pr-reviewer/SKILL_detail.md +158 -0
- package/plugins/fh-meta/skills/install-doctor/SKILL.md +207 -0
- package/plugins/fh-meta/skills/install-wizard/SKILL.md +613 -0
- package/plugins/fh-meta/skills/marketplace-gate/SKILL.md +193 -0
- package/plugins/fh-meta/skills/memory-hygiene/SKILL.md +143 -0
- package/plugins/fh-meta/skills/meta-prompt-builder/SKILL.md +167 -0
- package/plugins/fh-meta/skills/meta-prompt-builder/SKILL_detail.md +37 -0
- package/plugins/fh-meta/skills/pipeline-conductor/SKILL.md +430 -0
- package/plugins/fh-meta/skills/plugin-recommender/SKILL.md +221 -0
- package/plugins/fh-meta/skills/plugin-recommender/SKILL_detail.md +220 -0
- package/plugins/fh-meta/skills/prompt-regression/SKILL.md +178 -0
- package/plugins/fh-meta/skills/public-surface-audit/SKILL.md +224 -0
- package/plugins/fh-meta/skills/return-path-gate/SKILL.md +257 -0
- package/plugins/fh-meta/skills/self-marketing-lint/SKILL.md +129 -0
- package/plugins/fh-meta/skills/sim-conductor/SKILL.md +364 -0
- package/plugins/fh-meta/skills/sim-conductor/SKILL_detail.md +337 -0
- package/plugins/fh-meta/skills/skill-splitter/SKILL.md +126 -0
- package/plugins/fh-meta/skills/skill-splitter/SKILL_detail.md +185 -0
- package/plugins/fh-meta/skills/source-grounding-audit/SKILL.md +230 -0
- package/plugins/fh-meta/skills/source-grounding-audit/SKILL_detail.md +182 -0
- package/plugins/fh-meta/skills/steel-quench/SKILL.md +226 -0
- package/plugins/fh-meta/skills/steel-quench/SKILL_detail.md +453 -0
- package/plugins/fh-meta/skills/verify-bidirectional/SKILL.md +238 -0
- package/scripts/fh-gate.sh +175 -40
- package/scripts/fh-goal.sh +182 -0
- package/scripts/fh-run.sh +269 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plugin-recommender-detail
|
|
3
|
+
description: Detail reference for plugin-recommender — bash discovery scripts, install procedures, recommendation examples. Load when executing specific steps.
|
|
4
|
+
load: on-demand
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# plugin-recommender — Detail Reference
|
|
8
|
+
|
|
9
|
+
## §Discovery-Bash
|
|
10
|
+
|
|
11
|
+
### Step 0 — GitHub Auth Check Commands
|
|
12
|
+
|
|
13
|
+
**Check command (run before Step 2 search):**
|
|
14
|
+
```bash
|
|
15
|
+
gh auth status
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Internal GHE unauthenticated — PAT setup:**
|
|
19
|
+
```bash
|
|
20
|
+
# 1. Generate PAT at https://<your-ghe-url>/settings/tokens
|
|
21
|
+
# Scopes: repo, read:org (minimum)
|
|
22
|
+
|
|
23
|
+
# 2. Save to gh CLI
|
|
24
|
+
gh auth login --hostname <your-ghe-url>
|
|
25
|
+
# Prompt: Select HTTPS → Paste an authentication token → enter token
|
|
26
|
+
|
|
27
|
+
# 3. Verify
|
|
28
|
+
GH_HOST=<your-ghe-url> gh api /user --jq '.login'
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**External GitHub unauthenticated — PAT setup:**
|
|
32
|
+
```bash
|
|
33
|
+
# 1. Generate PAT at https://github.com/settings/tokens
|
|
34
|
+
# Scopes: repo, read:org
|
|
35
|
+
|
|
36
|
+
# 2. Save to gh CLI
|
|
37
|
+
gh auth login --hostname github.com
|
|
38
|
+
# (or default: gh auth login)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Search call host branching:**
|
|
42
|
+
```bash
|
|
43
|
+
# Internal GHE search
|
|
44
|
+
GH_HOST=<your-ghe-url> gh api ...
|
|
45
|
+
# or
|
|
46
|
+
gh search repos --owner <your-ghe-org> --hostname <your-ghe-url> [keywords]
|
|
47
|
+
|
|
48
|
+
# External GitHub search
|
|
49
|
+
gh search repos [keywords] # default host
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**External user Step 0 skip branch:**
|
|
53
|
+
```bash
|
|
54
|
+
# External user Step 0 replacement (no internal GHE access)
|
|
55
|
+
gh auth status # default host (github.com) only
|
|
56
|
+
# Authenticated → proceed to Step 1 immediately
|
|
57
|
+
# Unauthenticated → guide github.com PAT generation above
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Claude Code marketplace search:**
|
|
61
|
+
```bash
|
|
62
|
+
claude mcp search [capability-keyword]
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Codex marketplace search:**
|
|
66
|
+
```bash
|
|
67
|
+
npx @openai/codex list-agents [capability-keyword]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**npm ecosystem search (scoped packages):**
|
|
71
|
+
```bash
|
|
72
|
+
npm search @chrono-meta [keyword]
|
|
73
|
+
npm search @anthropic [keyword]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## §Install-Procedure
|
|
79
|
+
|
|
80
|
+
### Step 5 — Full Install and Configuration Details
|
|
81
|
+
|
|
82
|
+
#### 5-0. Pre-install Duplicate Detection
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
claude plugin list
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Three things to verify:
|
|
89
|
+
- **Manual install status**: If target plugin name exists in output → reinstall unnecessary
|
|
90
|
+
- **Repo-level activation**: If plugin is in `.claude/settings.json` `enabledPlugins` → already active
|
|
91
|
+
- **Same-name different-function conflict**: Same name but different origin/function → conflict handling below
|
|
92
|
+
|
|
93
|
+
**Same-name Conflict Handling procedure:**
|
|
94
|
+
|
|
95
|
+
1. Compare existing skill description vs recommended skill description
|
|
96
|
+
2. **Feature match** → report "Equivalent feature already installed" + skip reinstall
|
|
97
|
+
3. **Feature mismatch** → issue conflict warning:
|
|
98
|
+
```
|
|
99
|
+
⚠️ Name conflict: `<skill-name>` is already installed but has different functionality.
|
|
100
|
+
|
|
101
|
+
Currently installed: <summary of existing skill description>
|
|
102
|
+
Recommendation target: <summary of new skill description>
|
|
103
|
+
|
|
104
|
+
Options:
|
|
105
|
+
A. Keep existing (skip install)
|
|
106
|
+
B. Install with namespace qualifier — e.g., `fh-<skill-name>`
|
|
107
|
+
C. Remove existing and install new (⚠️ existing skill will be removed)
|
|
108
|
+
```
|
|
109
|
+
4. If user selects Option B: guide adding prefix to `name` field in plugin.json + present modification path
|
|
110
|
+
|
|
111
|
+
If either duplicate condition met → skip install → report "Already active" → proceed to Step 5-3 config only.
|
|
112
|
+
|
|
113
|
+
#### 5-1 through 5-3. Install Steps
|
|
114
|
+
|
|
115
|
+
1. Confirm intent: "Would you like to install the `[plugin-name]` plugin?"
|
|
116
|
+
2. On agreement:
|
|
117
|
+
```bash
|
|
118
|
+
claude plugin marketplace add [plugin-name]
|
|
119
|
+
claude plugin install [plugin-name]
|
|
120
|
+
```
|
|
121
|
+
3. Post-install initial configuration guidance:
|
|
122
|
+
- **API token input**: Guide token generation path for external service APIs (Jira/Confluence/Slack — specify each service's token page URL + env var or plugin config storage location)
|
|
123
|
+
- **MCP connection**: If plugin uses MCP server, guide auto-update of `.mcp.json` or `claude mcp add` command
|
|
124
|
+
- **Verify**: `claude plugin list` or `/plugin` UI + recommend first-call dry-run
|
|
125
|
+
|
|
126
|
+
#### 5-B. External Asset Migration Path (when non-plugin asset is found)
|
|
127
|
+
|
|
128
|
+
Activation condition: Step 3 found a promising external asset lacking `plugin.json` or `claude plugin install` support — install not possible but pattern has value.
|
|
129
|
+
|
|
130
|
+
**5-B-1. Migration Suitability Assessment (quick 3-criteria check):**
|
|
131
|
+
|
|
132
|
+
| Criteria | OK | NG |
|
|
133
|
+
|---|---|---|
|
|
134
|
+
| **Single purpose** | Clearly performs 1 task | Complex framework/SDK level |
|
|
135
|
+
| **Dependency complexity** | Standard CLI tools only (bash, gh, grep etc.) | Requires custom runtime/database |
|
|
136
|
+
| **FH gap coverage** | No similar skill currently in FH | Existing skill covers 95%+ |
|
|
137
|
+
|
|
138
|
+
All 3 OK → recommend migration. Any NG → report "Recommend referencing rather than installing" then guide Step 2 [Priority 2.5] contribution path.
|
|
139
|
+
|
|
140
|
+
**5-B-2. SKILL.md Conversion Template:**
|
|
141
|
+
|
|
142
|
+
```markdown
|
|
143
|
+
---
|
|
144
|
+
name: {1-3 words for the external asset's core action}
|
|
145
|
+
description: {one sentence, plain text only — first line is the core spec}
|
|
146
|
+
user-invocable: true
|
|
147
|
+
allowed-tools: ["Read", "Bash", "Grep"] # only actually needed tools
|
|
148
|
+
model: sonnet
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
# {name} — {one-line description}
|
|
152
|
+
|
|
153
|
+
## Activation Triggers
|
|
154
|
+
- When user says "{core action}"
|
|
155
|
+
|
|
156
|
+
## Execution Steps
|
|
157
|
+
|
|
158
|
+
### Step 1. ...
|
|
159
|
+
### Step 2. ...
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Conversion checklist:
|
|
163
|
+
- [ ] description first line = core spec (no marketing language)
|
|
164
|
+
- [ ] allowed-tools = only actually called tools (no over-declaration)
|
|
165
|
+
- [ ] External asset original URL → explicitly stated in `## Source` section (license check mandatory)
|
|
166
|
+
|
|
167
|
+
**5-B-3. Migration Location Guidance:**
|
|
168
|
+
|
|
169
|
+
| Purpose | Path | Notes |
|
|
170
|
+
|---|---|---|
|
|
171
|
+
| FH official skill (org-wide distribution) | `plugins/fh-meta/skills/{name}/SKILL.md` | PR mandatory — must pass team review |
|
|
172
|
+
| Local experiment (own environment only) | `.claude/rules/{name}.md` | No plugin install needed |
|
|
173
|
+
| Mode D standalone deployment | `.claude/agents/{name}.md` | Only when operating as agent form |
|
|
174
|
+
|
|
175
|
+
> FH official skill inclusion criteria: recommend PR after confirming 2+ actual uses (simplification guard — immediate inclusion after 1 experiment is prohibited).
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## §Examples
|
|
180
|
+
|
|
181
|
+
### Recommendation Table — Output Example
|
|
182
|
+
|
|
183
|
+
Full format with Tier + Platform columns:
|
|
184
|
+
|
|
185
|
+
| Rank | Plugin Name | Tier | Platform | Recommendation Reason | Key Features | Synergy Effect |
|
|
186
|
+
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
|
|
187
|
+
| **1** | `jira-automator` | Tier 1 | CC marketplace | Fully satisfies Jira ticket create/modify/query. Production usage evidence (5k+ installs). | Ticket creation, status change, comment addition | ★★★ (auto-links docs when used with `confluence-linker`) |
|
|
188
|
+
| **2** | `agile-sprint-board` | Tier 2 | GHE | Specialized for Jira-integrated sprint board visualization. Marketplace-listed, no benchmark data. | Sprint visualization, burndown chart | ★ (standalone use) |
|
|
189
|
+
| **3** | `issue-tracker-cli` | Tier 3 | GitHub only | Repo-only tool, no marketplace listing. Covers edge case not in Tier 1/2 options. | Bulk status updates via CLI | ★ (standalone use) |
|
|
190
|
+
|
|
191
|
+
### Persona Discovery (sim-conductor chain) — Return Example
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
plugin-recommender result to sim-conductor:
|
|
195
|
+
Searched: CC marketplace, Codex marketplace, FH native
|
|
196
|
+
Found:
|
|
197
|
+
- deep-insight (Tier 1, CC marketplace) — adversarial reviewer persona
|
|
198
|
+
- persona-devil-advocate (Tier 1, FH native, already installed)
|
|
199
|
+
Installed: deep-insight
|
|
200
|
+
Available personas: [devil-advocate, innovator, deep-insight, conservative-critic]
|
|
201
|
+
→ Return control to sim-conductor
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Quality Tier Assignment — Walk-through Example
|
|
205
|
+
|
|
206
|
+
Candidate: `@anthropic/code-review-agent`
|
|
207
|
+
- Published benchmark: accuracy 94% on HumanEval — **High** signal present
|
|
208
|
+
- GitHub stars: 2,400 — **Medium** signal present
|
|
209
|
+
- CC marketplace listing confirmed — **Medium** signal present
|
|
210
|
+
- Not FH-reviewed — no High signal from community
|
|
211
|
+
|
|
212
|
+
Result: 1 High + 2 Medium → **Tier 1**
|
|
213
|
+
|
|
214
|
+
Candidate: `random-org/bash-linter-plugin`
|
|
215
|
+
- No benchmark data
|
|
216
|
+
- GitHub stars: 45 (below 100 threshold)
|
|
217
|
+
- Not on any marketplace
|
|
218
|
+
- Unknown author
|
|
219
|
+
|
|
220
|
+
Result: no signals → **Tier 3** (source-available, GitHub only)
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: prompt-regression
|
|
3
|
+
description: Detects harness regressions by running standard prompt probes after rule/skill changes and comparing outputs against saved baselines. Triggers on "prompt regression", "did my changes break anything", "regression check", "test harness changes".
|
|
4
|
+
user-invocable: true
|
|
5
|
+
allowed-tools: ["Read", "Bash", "Glob", "Grep"]
|
|
6
|
+
model: sonnet
|
|
7
|
+
complexity_routing:
|
|
8
|
+
base: sonnet
|
|
9
|
+
high: opus
|
|
10
|
+
escalate_when:
|
|
11
|
+
- full_suite
|
|
12
|
+
- cross_skill_impact
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# prompt-regression — Harness Regression Detection
|
|
16
|
+
|
|
17
|
+
After CLAUDE.md edits, rule changes, or new skill additions, harness behavior can silently regress. This skill runs a lightweight probe suite against the changed assets and compares outputs against saved baselines to surface regressions before they reach production.
|
|
18
|
+
|
|
19
|
+
> **Scope distinction**
|
|
20
|
+
> - harness-doctor: structural completeness (files, links, drift)
|
|
21
|
+
> - prompt-regression: **behavioral correctness** — did the change alter expected AI response patterns?
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Triggers
|
|
26
|
+
|
|
27
|
+
- `/prompt-regression`
|
|
28
|
+
- "prompt regression", "regression check", "regression test"
|
|
29
|
+
- "did my rule change break anything", "test harness changes", "verify harness behavior", "make sure my edit didn't change behavior"
|
|
30
|
+
- After significant CLAUDE.md edits or new skill commits
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Execution Steps
|
|
35
|
+
|
|
36
|
+
### Step 1. Identify Changed Assets
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# What changed since last commit (or last N commits)
|
|
40
|
+
git diff HEAD~1 --name-only -- CLAUDE.md .claude/ plugins/
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Classify each changed file:
|
|
44
|
+
- `CLAUDE.md` → **core behavior** (high impact)
|
|
45
|
+
- `.claude/rules/*.md` → **rule layer** (medium impact)
|
|
46
|
+
- `plugins/*/skills/*/SKILL.md` → **skill behavior** (scoped impact)
|
|
47
|
+
- `plugins/*/skills/*/SKILL.md` (trigger phrases changed) → **trigger routing** (high impact)
|
|
48
|
+
|
|
49
|
+
If no changes detected: report "No harness changes since last commit — regression check skipped."
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
### Step 2. Load Probe Suite
|
|
54
|
+
|
|
55
|
+
Check for custom probes:
|
|
56
|
+
```bash
|
|
57
|
+
ls .claude/regression/probes.md 2>/dev/null || echo "NO_CUSTOM_PROBES"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**If custom probes exist**: load and use them.
|
|
61
|
+
|
|
62
|
+
**If no custom probes**: use the default probe matrix below.
|
|
63
|
+
|
|
64
|
+
#### Default Probe Matrix
|
|
65
|
+
|
|
66
|
+
| Probe ID | Input Pattern | Expected Behavior | Scope |
|
|
67
|
+
|---|---|---|---|
|
|
68
|
+
| `P-GREET-01` | `hi` / `hello` | Active onboarding protocol triggered | CLAUDE.md §Onboarding |
|
|
69
|
+
| `P-TRIGGER-01` | `recommend a plugin` | plugin-recommender proposed | CLAUDE.md §Autonomous |
|
|
70
|
+
| `P-TRIGGER-02` | `context is getting long` | context-doctor proposed | CLAUDE.md §Autonomous |
|
|
71
|
+
| `P-TRIGGER-03` | `harness is complex` | harness-doctor proposed | CLAUDE.md §Autonomous |
|
|
72
|
+
| `P-CHAIN-01` | `/field-harvest` | harvest-loop close-chain referenced (wrap-up deferred to CLAUDE.md session-close chain — field-harvest has no inline sim-conductor gate) | field-harvest SKILL.md |
|
|
73
|
+
| `P-CHAIN-02` | `/apex-review` | Conditional verdict present (apex-review vocabulary: "Conditional" / "Conditionally passed") | apex-review SKILL.md |
|
|
74
|
+
| `P-GATE-01` | new skill commit | New Skill Pre-Commit Gate (5 items) invoked | CLAUDE.md §Gate |
|
|
75
|
+
| `P-CLOSE-01` | `wrap up` / `good work` | Session close chain (4-step) triggered | CLAUDE.md §Wrap-up |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
### Step 3. Map Changes → Affected Probes
|
|
80
|
+
|
|
81
|
+
| Changed File | Affected Probes |
|
|
82
|
+
|---|---|
|
|
83
|
+
| `CLAUDE.md` §Onboarding | P-GREET-01 |
|
|
84
|
+
| `CLAUDE.md` §Autonomous Initiative | P-TRIGGER-* |
|
|
85
|
+
| `CLAUDE.md` §Wrap-up | P-CLOSE-01 |
|
|
86
|
+
| `CLAUDE.md` §New Skill Gate | P-GATE-01 |
|
|
87
|
+
| `plugins/fh-meta/skills/*/SKILL.md` | P-CHAIN-* matching skill |
|
|
88
|
+
|
|
89
|
+
If change scope is `CLAUDE.md` core (10+ lines changed): run **full suite** (all probes).
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
### Step 4. Run Affected Probes
|
|
94
|
+
|
|
95
|
+
For each affected probe, evaluate:
|
|
96
|
+
|
|
97
|
+
**4-a. Trigger routing check** — Does the trigger phrase still map to the expected skill/behavior?
|
|
98
|
+
- Read the changed file
|
|
99
|
+
- Locate trigger section
|
|
100
|
+
- Confirm the probe's input pattern still appears in the trigger list
|
|
101
|
+
|
|
102
|
+
**4-b. Chain integrity check** — Are mandatory chains still present?
|
|
103
|
+
- For skill chains: confirm `→ chain:` or `Mandatory:` gate lines exist
|
|
104
|
+
- For session close chain: confirm all 4 steps in CLAUDE.md §Wrap-up
|
|
105
|
+
|
|
106
|
+
**4-c. Gate presence check** — Are gate conditions still enforced?
|
|
107
|
+
- Pre-commit gate: confirm all 5 items present in CLAUDE.md
|
|
108
|
+
- Conditional-pass gate: confirm `CONDITIONAL_PASS` logic in affected SKILL.md
|
|
109
|
+
|
|
110
|
+
Output per probe:
|
|
111
|
+
```
|
|
112
|
+
[PASS] P-TRIGGER-01 — plugin-recommender trigger phrase found in CLAUDE.md
|
|
113
|
+
[FAIL] P-CHAIN-01 — field-harvest SKILL.md no longer references the harvest-loop close chain after edit
|
|
114
|
+
[SKIP] P-GREET-01 — §Onboarding not in changed files
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
### Step 5. Regression Report
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
## Prompt-Regression Report — YYYY-MM-DD
|
|
123
|
+
|
|
124
|
+
### Changed Assets
|
|
125
|
+
- CLAUDE.md (§Autonomous Initiative — 3 trigger phrases modified)
|
|
126
|
+
- plugins/fh-meta/skills/field-harvest/SKILL.md
|
|
127
|
+
|
|
128
|
+
### Probes Run: 4 | Pass: 3 | Fail: 1 | Skip: 4
|
|
129
|
+
|
|
130
|
+
### FAIL Details
|
|
131
|
+
| Probe | Location | Finding | Fix |
|
|
132
|
+
|---|---|---|---|
|
|
133
|
+
| P-CHAIN-01 | field-harvest SKILL.md | harvest-loop close-chain reference removed by edit | Restore the harvest-loop chain reference |
|
|
134
|
+
|
|
135
|
+
### Verdict
|
|
136
|
+
⚠️ REGRESSION DETECTED — 1 probe failed. Fix required before merge.
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
If all probes pass:
|
|
140
|
+
```
|
|
141
|
+
✅ NO REGRESSION — All N probes passed. Safe to merge.
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### Step 6. Baseline Update (on explicit user approval)
|
|
147
|
+
|
|
148
|
+
After a deliberate behavior change (not a regression — an intentional improvement), update the baseline:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# Baseline stored as markdown in .claude/regression/
|
|
152
|
+
mkdir -p .claude/regression
|
|
153
|
+
# Write updated probe expectations
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Prompt user: *"Probe P-CHAIN-01 now expects the new gate format. Update baseline? (y/n)"*
|
|
157
|
+
|
|
158
|
+
Only update on explicit `y` — never auto-update.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Done When
|
|
163
|
+
|
|
164
|
+
- All affected probes are evaluated (PASS / FAIL / SKIP)
|
|
165
|
+
- Regression report is output with clear PASS/FAIL verdict
|
|
166
|
+
- If FAIL: specific file + line fix is recommended
|
|
167
|
+
- Baseline updated only on explicit user approval
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Chains
|
|
172
|
+
|
|
173
|
+
**Upstream** (runs before this skill):
|
|
174
|
+
- Automatically triggered after significant harness commits (Step 1 detects via git diff)
|
|
175
|
+
|
|
176
|
+
**Downstream** (runs after FAIL verdict):
|
|
177
|
+
- → `harness-doctor` for structural fixes if L1/L2 issues found
|
|
178
|
+
- → `verify-bidirectional` to confirm fix resolved the regression
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: public-surface-audit
|
|
3
|
+
description: >-
|
|
4
|
+
Scans git-tracked (public) files for operator-private tokens that should live only in gitignored files — real usernames, absolute home paths, companion-store names, company asset names. Reports file:line + matched token + severity, so a public/private split stays clean before publish. Triggered by "public surface audit", "did I leak anything", "check tracked files for private tokens", "private token scan", "public-surface-audit".
|
|
5
|
+
user-invocable: true
|
|
6
|
+
allowed-tools: ["Read", "Bash", "Grep", "Glob"]
|
|
7
|
+
model: sonnet
|
|
8
|
+
category: Composability Gate
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# public-surface-audit — Operator-Private Token Leak Scan
|
|
12
|
+
|
|
13
|
+
Scans the git-tracked file set (the public surface) for operator-private tokens that were supposed
|
|
14
|
+
to stay in gitignored files (e.g. `CLAUDE.local.md`, companion store). After a public/private split,
|
|
15
|
+
a front-door fix is not enough — a leaked username or absolute home path anywhere in the tracked set
|
|
16
|
+
breaks the "public repo = model-agnostic methodology only" invariant.
|
|
17
|
+
|
|
18
|
+
> While `marketplace-gate` Check 5 answers "is this repo broadly safe to publish?" (API keys, internal
|
|
19
|
+
> domains, license), `public-surface-audit` answers a narrower question: "did any operator-private
|
|
20
|
+
> token survive the public/private split into a tracked file?" It scans `git ls-files` only — gitignored
|
|
21
|
+
> files like `CLAUDE.local.md` are intentionally out of scope (they are the *correct* home for these tokens).
|
|
22
|
+
|
|
23
|
+
## Triggers
|
|
24
|
+
|
|
25
|
+
- `/public-surface-audit`
|
|
26
|
+
- `/public-surface-audit --target <repo path>`
|
|
27
|
+
- "Did I leak anything into the public repo?", "public surface audit", "private token scan"
|
|
28
|
+
- "Check tracked files for private tokens", "is my public/private split clean?"
|
|
29
|
+
- "Did any operator-private token survive into a tracked file?", "scan before publish"
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Scope — Tracked Files Only
|
|
34
|
+
|
|
35
|
+
This skill scans **only `git ls-files`** (committed/staged tracked files). Gitignored files are
|
|
36
|
+
deliberately excluded — `CLAUDE.local.md`, the companion store, and local session data are the
|
|
37
|
+
*correct* home for operator-private tokens, so finding them there is not a leak.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
REPO_PATH="${ARGUMENTS#--target }"
|
|
41
|
+
REPO_PATH="${REPO_PATH:-$(pwd)}"
|
|
42
|
+
git -C "$REPO_PATH" rev-parse --is-inside-work-tree >/dev/null 2>&1 \
|
|
43
|
+
|| { echo "Not a git repo — public-surface-audit scans git-tracked files only. Aborting."; exit 1; }
|
|
44
|
+
echo "Target: $REPO_PATH"
|
|
45
|
+
git -C "$REPO_PATH" ls-files | wc -l | xargs echo "Tracked files:"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Step 1. Pattern List (configurable)
|
|
51
|
+
|
|
52
|
+
The patterns **are themselves operator-private** — your real username and employer name must not be
|
|
53
|
+
hardcoded *here*, on the public surface, or this skill would leak exactly what it hunts. So the literal
|
|
54
|
+
values live in a **gitignored source you supply** (`.claude/rules/.public-surface-patterns`, or a
|
|
55
|
+
section of `CLAUDE.local.md`) — one `severity<TAB>regex` per line. This SKILL.md carries only
|
|
56
|
+
placeholders; the scan reads the gitignored file, never literals from this table. The skill dogfoods
|
|
57
|
+
its own rule.
|
|
58
|
+
|
|
59
|
+
| # | Token class | Severity | Placeholder (real value goes in the gitignored source) | Why private |
|
|
60
|
+
|:-:|---|:-:|---|---|
|
|
61
|
+
| 1 | Real username | HIGH | `<your-unix-username>` | Personal identity — must not appear on public surface |
|
|
62
|
+
| 2 | Company / employer asset name | HIGH | `<company-asset>` (alternation OK) | Company-confidential, leak-forbidden |
|
|
63
|
+
| 3 | Operator absolute home path | MED | `/Users/[a-z0-9_-]+/` (generic — carries no literal name) | Machine-bound, leaks username + local layout |
|
|
64
|
+
| 4 | Companion-store name | LOW | `<companion-store-name>` | Private companion store — methodology should not name it |
|
|
65
|
+
| 5 | Operator-private script / handoff name | LOW | `<private-script>`, `<private-dir>/` | Operator-specific wiring, belongs in `CLAUDE.local.md` |
|
|
66
|
+
|
|
67
|
+
**Severity meaning**:
|
|
68
|
+
- **HIGH** — real name or company asset. A leak is a confidentiality / identity exposure. Block publish.
|
|
69
|
+
- **MED** — absolute home path. Leaks username + local filesystem layout; also a portability bug.
|
|
70
|
+
- **LOW** — companion-store / private-wiring name. Methodology should be model-agnostic; naming a private
|
|
71
|
+
store is drift, not a confidentiality breach.
|
|
72
|
+
|
|
73
|
+
> **Setup**: put your real values in the gitignored pattern source (one `severity<TAB>regex` per line);
|
|
74
|
+
> the scan reads that file, never literals from this SKILL.md. If the source is **absent**, the scan
|
|
75
|
+
> reports **NOT CONFIGURED** — *not* CLEAN. A missing pattern file must never masquerade as a clean bill
|
|
76
|
+
> of health (that would be a silent failure: "nothing scanned" misread as "nothing leaked"). To declare
|
|
77
|
+
> "I genuinely have no private tokens", create the file **empty** — an empty file is an explicit CLEAN,
|
|
78
|
+
> an absent file is unconfigured.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Step 2. Allowlist (legitimate references)
|
|
83
|
+
|
|
84
|
+
Some tracked files legitimately reference otherwise-private tokens — the scan must not flag these as
|
|
85
|
+
leaks. Maintain an allowlist of `file path :: token` pairs. A match is suppressed only when **both**
|
|
86
|
+
the file and the token are on the allowlist row.
|
|
87
|
+
|
|
88
|
+
| Tracked file | Allowed tokens | Reason |
|
|
89
|
+
|---|---|---|
|
|
90
|
+
| `.gitignore` | companion-store name, sync-script name | Must name what it ignores |
|
|
91
|
+
| your sync script (e.g. `scripts/<sync-script>`) | companion-store name, operator-dir names, home path | The sync script's whole job is the companion store |
|
|
92
|
+
| an install-template rules file | home path, companion-store name | Install template — the install path is its content |
|
|
93
|
+
| a doc describing the companion-store *pattern* | the `*-be` pattern (no literal store name) | Documents the pattern generically |
|
|
94
|
+
|
|
95
|
+
**Allowlist rule**: a hit on file F matching token T is **suppressed** iff a row exists with file == F
|
|
96
|
+
and T in that row's allowed tokens. Everything else is reported. Keep the allowlist tight — when in
|
|
97
|
+
doubt, report and let the user confirm. Genuinely model-agnostic mentions (the `*-be` companion
|
|
98
|
+
*pattern* without the literal store name) should not require allowlisting because they do not match a
|
|
99
|
+
literal private token.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Step 3. Scan
|
|
104
|
+
|
|
105
|
+
For each pattern in Step 1, grep the tracked set, then drop allowlisted hits.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
cd "$REPO_PATH" || exit 1
|
|
109
|
+
# Build the tracked-file list once.
|
|
110
|
+
git ls-files > /tmp/_psa_tracked.txt
|
|
111
|
+
|
|
112
|
+
# Load your real patterns from the gitignored source (one "severity<TAB>regex" per line).
|
|
113
|
+
PATTERN_SRC="${PSA_PATTERNS:-.claude/rules/.public-surface-patterns}"
|
|
114
|
+
# Absent file ≠ CLEAN. An absent file is unconfigured (silent-failure risk); an EMPTY file is an
|
|
115
|
+
# explicit "no tokens to protect" → CLEAN. Distinguish the two.
|
|
116
|
+
[ -e "$PATTERN_SRC" ] || { echo "⚪ NOT CONFIGURED: no pattern source at $PATTERN_SRC. Create it (empty = explicit CLEAN) before trusting any verdict. Not scanning."; exit 2; }
|
|
117
|
+
|
|
118
|
+
# One grep pass per pattern row; the regex comes from the file, never hardcoded here.
|
|
119
|
+
while IFS=$'\t' read -r severity regex; do
|
|
120
|
+
[ -z "$regex" ] && continue
|
|
121
|
+
grep -nIE "$regex" $(cat /tmp/_psa_tracked.txt) 2>/dev/null | sed "s/^/[$severity] /"
|
|
122
|
+
done < "$PATTERN_SRC"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
For each pattern, run `grep -nIE "<regex>" $(git ls-files)`:
|
|
126
|
+
- `-n` → line numbers (required for `file:line` output)
|
|
127
|
+
- `-I` → skip binary files
|
|
128
|
+
- `-E` → extended regex (alternation in the pattern table)
|
|
129
|
+
|
|
130
|
+
Then remove any hit whose `file` + matched `token` is on the Step 2 allowlist. Do this for **every**
|
|
131
|
+
pattern row before producing the report — do not stop at the first HIT.
|
|
132
|
+
|
|
133
|
+
**Binary / generated carve-out**: `-I` already skips binaries. Additionally note (do not auto-suppress)
|
|
134
|
+
hits inside generated artifacts (e.g. `paper/*.html` exported from a private source) — these are real
|
|
135
|
+
leaks on the public surface and must be reported, but the fix is "regenerate from a sanitized source",
|
|
136
|
+
not "edit the HTML by hand". Flag them with a `(generated artifact)` note.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Step 4. Report
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
public-surface-audit — Operator-Private Token Scan
|
|
144
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
145
|
+
Target: {REPO_PATH} | Tracked files scanned: {N}
|
|
146
|
+
|
|
147
|
+
🔴 HIGH ({count})
|
|
148
|
+
{file}:{line} → {matched token} [class: username | company asset]
|
|
149
|
+
🟠 MED ({count})
|
|
150
|
+
{file}:{line} → {matched token} [class: absolute home path]
|
|
151
|
+
🟡 LOW ({count})
|
|
152
|
+
{file}:{line} → {matched token} [class: companion-store | private wiring]
|
|
153
|
+
|
|
154
|
+
Allowlist-suppressed: {count} hit(s) (legitimate references — not leaks)
|
|
155
|
+
|
|
156
|
+
Verdict:
|
|
157
|
+
⚪ NOT CONFIGURED — pattern source absent (nothing scanned — NOT a clean result; set up first)
|
|
158
|
+
🟢 CLEAN — pattern source present (incl. empty), 0 HIGH + 0 MED + 0 LOW (after allowlist)
|
|
159
|
+
🟡 REVIEW — 0 HIGH + 0 MED, LOW-only (drift, not a breach)
|
|
160
|
+
🔴 LEAK — 1+ HIGH or 1+ MED (block publish / fix before commit)
|
|
161
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Per HIGH/MED hit, append a one-line prescription:
|
|
165
|
+
- **HIGH (username/company)** — move the line to `CLAUDE.local.md` (or regenerate the artifact from a
|
|
166
|
+
sanitized source); never edit-in-place if it is a generated file.
|
|
167
|
+
- **MED (absolute path)** — replace with a relative path, a `~`-anchored path, or a `{project}`
|
|
168
|
+
placeholder; absolute home paths are also a portability bug for external clones.
|
|
169
|
+
- **LOW (companion-store/wiring)** — rephrase to the model-agnostic *pattern* (e.g. "a private companion
|
|
170
|
+
store" / "the `*-be` companion pattern") instead of the literal name, unless the file is the
|
|
171
|
+
`.gitignore` / sync script that must name it (allowlist those).
|
|
172
|
+
|
|
173
|
+
**Simplification guard**: 🟢 CLEAN → collapse the report to one line: "public surface clean — 0 private
|
|
174
|
+
tokens in {N} tracked files (X allowlist-suppressed)." Do not print empty severity buckets.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Connected Skills
|
|
179
|
+
|
|
180
|
+
| Situation | Connected skill |
|
|
181
|
+
|---|---|
|
|
182
|
+
| Broader pre-publish repo readiness (README, license, API keys) | `/marketplace-gate` (Check 5 Public Safety is the wide net; this skill is the private-token detail) |
|
|
183
|
+
| A leak is a recurring process gap, not a one-off | log via `field-harvest` → candidate `#rule-candidate` |
|
|
184
|
+
| Where should the leaked content actually live? | `/asset-placement-gate` (hub vs project vs CLAUDE.local.md) |
|
|
185
|
+
| Phantom refs / stale links on the same surface | `/source-grounding-audit` (forward axis — orthogonal to this leak axis) |
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## External User Environment Adaptation
|
|
190
|
+
|
|
191
|
+
Usable standalone — no hub clone required.
|
|
192
|
+
- **No companion store / no operator-private tokens** → create the pattern source **empty** to declare
|
|
193
|
+
this explicitly; the scan then reports CLEAN. Leaving the file *absent* instead yields NOT CONFIGURED
|
|
194
|
+
(a deliberate distinction — absence is "unknown", not "clean"). The skill is only useful once you have
|
|
195
|
+
a public/private split to protect.
|
|
196
|
+
- **No `.gitignore` allowlist needs** → Step 2 allowlist may be empty; every hit is then reported.
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Done When
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
Step 1 pattern list confirmed (defaults shown / user-adapted)
|
|
204
|
+
+ Step 2 allowlist applied
|
|
205
|
+
+ Step 3 scan run for every pattern over git ls-files (tracked only — gitignored excluded)
|
|
206
|
+
+ Step 4 report output: per-hit file:line + token + severity, plus overall verdict
|
|
207
|
+
+ "public-surface-audit Complete" declaration output
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Verdict: **CLEAN** (0 tokens after allowlist) | **REVIEW** (LOW-only — drift, prescriptions noted) |
|
|
211
|
+
**LEAK** (1+ HIGH or 1+ MED — block publish, prescriptions attached).
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Operating Notes
|
|
216
|
+
|
|
217
|
+
- **Tracked-only is the point**: never scan gitignored files. A token in `CLAUDE.local.md` is correct
|
|
218
|
+
placement, not a leak — scanning it would produce false LEAK verdicts and erode trust in the skill.
|
|
219
|
+
- **Patterns are data, not code**: the Step 1 table is the configurable surface. A user with a different
|
|
220
|
+
username/employer/companion-store edits the table; the scan logic is unchanged.
|
|
221
|
+
- **Generated artifacts are real leaks**: an exported HTML/PDF carrying a username is still a public-surface
|
|
222
|
+
leak even though hand-editing it is wrong — report it, prescribe "regenerate from sanitized source".
|
|
223
|
+
- **Allowlist tight, not loose**: when unsure whether a reference is legitimate, report it. A false LEAK
|
|
224
|
+
the user dismisses is cheaper than a real leak suppressed by an over-broad allowlist.
|