@chrono-meta/fh-gate 1.4.34 → 1.4.36
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.md +23 -6
- package/package.json +1 -1
- package/plugins/fh-meta/skills/frontier-digest/SKILL.md +5 -2
- package/plugins/fh-meta/skills/frontier-digest/SKILL_detail.md +9 -1
- package/plugins/fh-meta/skills/install-wizard/SKILL.md +4 -2
- package/plugins/fh-meta/skills/install-wizard/SKILL_detail.md +12 -0
- package/plugins/fh-meta/skills/public-surface-audit/SKILL.md +51 -1
- package/plugins/fh-meta/skills/sim-conductor/SKILL.md +70 -9
package/CLAUDE.md
CHANGED
|
@@ -103,17 +103,17 @@ Simplification guard: trivial denials with one obvious fix → state block + sin
|
|
|
103
103
|
|
|
104
104
|
**4-step summary**: ① Auto-read CLAUDE.md + CATALOG + session card + registry scan + UAP (`tracks/_meta/user_adaptation_profile.md`, if present — apply user-tuned defaults: preferred tier, suppressed proposals, muted nags; see §Operational Adaptation Loop) → ② One-line proposal (new user / exploratory / returning branches) → ③ 5-skill cascade (plugin-recommender → synergy → .claudeignore → model → verify) → ④ Approval + setup
|
|
105
105
|
|
|
106
|
-
**Greeting branch + door skeleton (summary-level — applies even if the detail file read is skipped)**: the branch test is **mechanical local state — session files under `tracks/`** — never git log / CATALOG residue (a fresh clone carries full history but zero session files: it is a NEW install — origin: a fresh-clone sonnet sim rendered the returning menu off commit messages, `fh_signal_2026-06-11` FP8). Every variant opens with **🐿️
|
|
106
|
+
**Greeting branch + door skeleton (summary-level — applies even if the detail file read is skipped)**: the branch test is **mechanical local state — session files under `tracks/`** — never git log / CATALOG residue (a fresh clone carries full history but zero session files: it is a NEW install — origin: a fresh-clone sonnet sim rendered the returning menu off commit messages, `fh_signal_2026-06-11` FP8). Every variant opens with **🐿️ then an identity-revealing welcome line on the SAME line** (🐿️ is no longer alone on its own line), followed by the menu — one salience unit, not a separate rule. (Put a space after 🐿️; the exact count is **not significant** — a markdown renderer collapses multiple mid-line spaces to one — so the verifiable invariant is *same-line*, NOT a space count.) Welcome line by branch: new / exploratory = "Welcome to FH." · returning = "Welcome back to FH." · operator (FH-dev state) = "The FH operator — good to see you." (rendered in the user's language; the lid/onboarding-smoothness matters even though it is not the substance).
|
|
107
107
|
|
|
108
108
|
- **New user** (no session files AND no mapped project tracks under `tracks/` — fresh clone/install; underscore meta dirs `_meta`/`_audit`/`_contrib` don't count): 2-door starter, never the returning menu —
|
|
109
109
|
|
|
110
|
-
> 🐿️
|
|
111
|
-
> *"Looks like you're new here! ① Create your first project (guided) · ② Map an existing project — and I can run `/install-wizard` to finish initial setup."*
|
|
110
|
+
> 🐿️ **Welcome to FH.** *Looks like you're new here! ① Create your first project (guided) · ② Map an existing project — and I can run `/install-wizard` to finish initial setup.*
|
|
112
111
|
|
|
113
112
|
- **Returning user** (session files OR mapped project tracks exist): fixed 4-door menu —
|
|
114
113
|
|
|
115
|
-
> 🐿️
|
|
116
|
-
>
|
|
114
|
+
> 🐿️ **Welcome back to FH.** *① Map a project · ② Create a new project · ③ Accelerate a mapped project (work · Full-Harness · skills/agents/plugins) — {field candidates} · ④ Cross-project synergy*
|
|
115
|
+
>
|
|
116
|
+
> (When **FH-dev state exists** — the operator — the welcome line is **"The FH operator — good to see you."** in place of "Welcome back to FH.")
|
|
117
117
|
|
|
118
118
|
Render conditions: ①②③ always (③'s candidates composed live) · ④ only when **2+ project tracks** exist (underscore meta dirs don't count) — synergy findings flow back into each project, and may *propose* an FH contribution (`/field-harvest` → `tracks/_contrib`) as an **outcome of findings, never a standing door**.
|
|
119
119
|
|
|
@@ -121,7 +121,7 @@ Simplification guard: trivial denials with one obvious fix → state block + sin
|
|
|
121
121
|
|
|
122
122
|
Compose session-card candidates **into door ③ (field) and the 🔧 door (FH-dev)**, never as a raw priority dump that replaces the menu. An urgent open item (time-windowed handoff · blocking external deadline) outranks the menu; an explicit task utterance skips it entirely (see Guards below); cadence reminders (§Cadence Rules) ride below it, they don't displace it. Canonical source: `fh_detail_protocols.md` Step 2 — keep branch tests and door labels in sync.
|
|
123
123
|
|
|
124
|
-
**Identity marker**: every greeting response (Step ②) opens with 🐿️ on
|
|
124
|
+
**Identity marker**: every greeting response (Step ②) opens with 🐿️ then an identity-revealing welcome line **on the same line** (a space after 🐿️; exact count not significant — the renderer collapses it — the invariant is *same-line*, not 🐿️ alone) — new / exploratory = "Welcome to FH." · returning = "Welcome back to FH." · operator (FH-dev state) = "The FH operator — good to see you." It is embedded in all skeletons above (do not strip it when composing doors); the exploratory branch template (`fh_detail_protocols.md` Step 2) uses the "Welcome to FH." line.
|
|
125
125
|
|
|
126
126
|
**Guards**: explicit task-entry utterance → skip onboarding · once per session · code/debug requests → start working directly · project routing is a suggestion, mention at most once
|
|
127
127
|
**Metadata-is-not-intent guard**: the trigger is the user's **typed message only**. Session metadata — branch name (auto-derived from the first message, e.g. `claude/korean-greeting-*`), repo name, file paths — is **never** a task spec and never suppresses or redirects the greeting trigger. A bare greeting fires onboarding even when the branch name looks like a feature request; if the only "task" signal lives in metadata and not in what the user typed, treat the message as a greeting and run the greeting branch + door skeleton above.
|
|
@@ -227,6 +227,23 @@ post-compaction 2026-06-12). 2026-06-15+: headless `claude -p` draws from the ha
|
|
|
227
227
|
subscription — prefer in-session Agent dispatch when the plan gate allows; take the headless fallback
|
|
228
228
|
knowingly. Record sim results in the Axes 2–3 marker + sub-agent invocation log.
|
|
229
229
|
|
|
230
|
+
**Floor-tier canary (optional pre-screen — token-free, *below* the Sonnet sim)**: a local model weaker
|
|
231
|
+
than or comparable to Sonnet (e.g. `ollama run qwen3:8b` on the local host today; a cross-family local
|
|
232
|
+
panel — qwen3.x:27b / gemma4:12b-qat / gpt-oss:20b / devstral — on a GPU host once its remote-exec path
|
|
233
|
+
is live) can pre-screen a salience-dependent edit *before* the Sonnet dispatch is spent: a rule that
|
|
234
|
+
fires correctly on the floor model is *evidence of* robustness below Sonnet (one floor sample, not proof
|
|
235
|
+
— hold the asymmetric-skepticism discipline). Blind probe — feed the verbatim rule text + a scenario,
|
|
236
|
+
demand a strict YES/NO + one-line reason, judge whether the rule fired (mechanism dogfood-verified
|
|
237
|
+
2026-06-20: a local `qwen3:8b` correctly gated the public install-wizard local-LLM-offload item in both
|
|
238
|
+
directions — a claim checkable against that skill — re-validating that day's salience-binding fix at a
|
|
239
|
+
sub-Sonnet tier). **Canary, NOT gate**: a PASS adds cheap floor confidence and you still run the Sonnet
|
|
240
|
+
sim; a FAIL never blocks alone — the opus orchestrator triages it as a *real salience gap* (fix the
|
|
241
|
+
rule) vs a *floor-model quirk* (small-model loop/hallucination, per the public "Local AI is not Opus"
|
|
242
|
+
finding + the cheap-oracle ceiling — a small model adds nothing where one grep already settles the
|
|
243
|
+
check). The terminal verdict stays with the frontier (Sonnet sim + opus judge) — no judge-only path, no
|
|
244
|
+
weak-local-judge regression of the judge-robustness principle (mechanical anchor over judge-only verdict).
|
|
245
|
+
The cross-family-panel upgrade spec lives in the private companion store's `handoff/` design note.
|
|
246
|
+
|
|
230
247
|
**Axis ownership** (each skill is already complete — orchestrator only coordinates):
|
|
231
248
|
|
|
232
249
|
| Axis | Skill | What it catches |
|
package/package.json
CHANGED
|
@@ -65,7 +65,7 @@ On **cadence-triggered** runs (7d), ask the operator one line before collecting:
|
|
|
65
65
|
|
|
66
66
|
## Step 1. Data Collection
|
|
67
67
|
|
|
68
|
-
Collect from
|
|
68
|
+
Collect from five sources (bash per source in §Collection-Bash):
|
|
69
69
|
|
|
70
70
|
| Source | Method | Cap |
|
|
71
71
|
|---|---|---|
|
|
@@ -73,11 +73,14 @@ Collect from four sources (bash per source in §Collection-Bash):
|
|
|
73
73
|
| arxiv | export API, latest by submittedDate | 6 items |
|
|
74
74
|
| TLDR AI | RSS, title + link | 5 items |
|
|
75
75
|
| The Batch (deeplearning.ai) | HTML scraping, title + issue slug | 5 items |
|
|
76
|
+
| GeekNews (news.hada.io) | Atom feed (`/rss/news` path), title + link, AI/agent/LLM-relevant | 5 items |
|
|
76
77
|
|
|
77
|
-
Report progress: `📡 HN 15 items · arxiv 5 items · TLDR 5 items · Batch 5 items collected`
|
|
78
|
+
Report progress: `📡 HN 15 items · arxiv 5 items · TLDR 5 items · Batch 5 items · GeekNews 5 items collected`
|
|
78
79
|
|
|
79
80
|
> **Detail**: See `SKILL_detail.md §Collection-Bash` — curl commands per source with parsing notes — read when executing Step 1.
|
|
80
81
|
|
|
82
|
+
**Knowledge-currency augment (on-demand, not weekly-scanned)**: distinct from the trend feeds above, these are fetched when a specific version/fact/spec needs confirming against the model's knowledge cutoff — `docs.anthropic.com` (official Claude/API docs · model IDs · pricing), arxiv (already a feed, also a currency target by ID), and Zenodo (research deposits incl. FH's own). Pull these into context for currency rather than scanning them for trends; in egress-restricted environments (e.g. a company network) route the fetch through the approved bridge (n8n), not a direct call.
|
|
83
|
+
|
|
81
84
|
---
|
|
82
85
|
|
|
83
86
|
## Step 2. Synthesis
|
|
@@ -50,7 +50,15 @@ curl -s --max-time 10 -L "https://www.deeplearning.ai/the-batch/"
|
|
|
50
50
|
|
|
51
51
|
Extract `"title":"..."` + `"slug":"issue-\d+"` pattern → URL: `https://www.deeplearning.ai/the-batch/{slug}/`. Max 5 items.
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
### GeekNews — news.hada.io (RSS)
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
curl -s --max-time 8 "https://news.hada.io/rss/news"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Korean dev-news aggregator (HN-equivalent), AI-heavy. **The `/rss/news` path serves an Atom feed** (`<feed>`/`<entry>`, NOT RSS `<item>` — verified 2026-06-20: 50 `<entry>` elements, 0 `<item>`). Parse `<entry>` → `<title>` + `<link href>`; keep AI/agent/LLM/harness-relevant items only. `/rss/news` is a *general* dev-news feed, so if 0 AI-relevant items remain after filtering, **drop GeekNews from this run's progress line rather than padding to 5**. Endpoint verified HTTP 200 (2026-06-20); `/rss/new` and `/rss/topics` 404 — use `/rss/news`. Max 5 items.
|
|
60
|
+
|
|
61
|
+
Report progress: `📡 HN 15 items · arxiv 5 items · TLDR 5 items · Batch 5 items · GeekNews 5 items collected`
|
|
54
62
|
|
|
55
63
|
---
|
|
56
64
|
|
|
@@ -102,7 +102,7 @@ Pasting tokens directly in chat exposes them in conversation history; environmen
|
|
|
102
102
|
|
|
103
103
|
*(Run after Step 0-A·B pre-checks. Output results as environment card, then continue to Step 0-C.)*
|
|
104
104
|
|
|
105
|
-
CC runs the detection bash automatically (injection pre-flight scan → FH_DIR/CC_HUB_DIR → cwd project info → plugins → MCP → zshrc hook → optional framework detection), then outputs the environment card.
|
|
105
|
+
CC runs the detection bash automatically (injection pre-flight scan → FH_DIR/CC_HUB_DIR → cwd project info → plugins → MCP → zshrc hook → optional framework detection → local LLM runtime, optional), then outputs the environment card.
|
|
106
106
|
|
|
107
107
|
**Stop rule (behavioral)**: if `FH_DIR` is not set, output the bootstrap guidance and **do not proceed to subsequent Steps** — install FH first, then rerun.
|
|
108
108
|
|
|
@@ -135,7 +135,9 @@ Y (add integration plan items to Step 1) / N (add-only, keep existing rules) / S
|
|
|
135
135
|
|
|
136
136
|
**[Prerequisite] install-doctor conflict diagnosis (only in environments without install history)**: if `~/.cc_sentinels/{project-name}_wizard_done` doesn't exist (first install), call `/install-doctor --plugin fh-meta` first. CONFLICT/WARNING items → add ❗ markers to Step 2 proposal list. Items the doctor already diagnosed (`FH plugin install` · `zshrc hook` · `.claudeignore`) → map results directly, skip re-diagnosis; all other items → check directly.
|
|
137
137
|
|
|
138
|
-
Auto-check each item as PASS / MISS / FAIL. Check items: `.claudeignore` · `local_fh_context.md` · `zshrc hook` · `weekly_audit` freshness · `sentinel` setup · FH plugin install · `.git/info/exclude` · MCP plugin · `deep-insight` plugin (optional) · `fh_env_context.jsonc` · `phantom-gate` (Python + AI-output projects only) · domain pattern pack (optional, none ship by default).
|
|
138
|
+
Auto-check each item as PASS / MISS / FAIL. Check items: `.claudeignore` · `local_fh_context.md` · `zshrc hook` · `weekly_audit` freshness · `sentinel` setup · FH plugin install · `.git/info/exclude` · MCP plugin · `deep-insight` plugin (optional) · `fh_env_context.jsonc` · `phantom-gate` (Python + AI-output projects only) · domain pattern pack (optional, none ship by default) · local-LLM offload (optional — surface ONLY if the Step 0 bash emitted the literal line `Local LLM runtime: detected`; absent that line, this item does not exist).
|
|
139
|
+
|
|
140
|
+
**Local-LLM offload (conditional, recommend-only)**: when Step 0 detected a local LLM runtime (Ollama / LM Studio), surface one optional item — route to `/plugin-recommender` for local-model offload tooling. FH recommends, never rebuilds (no-reinvention). Two complementary offload shapes the user picks per workload: **input-side context routing** (a small local model returns line ranges, so the cloud model receives only the dense slices instead of whole files) and **output-side generation delegation** (the local model generates and self-reviews code while the frontier model decomposes and validates). The benefit is tier-dependent — largest in headless/scripted pipelines and on weaker cloud tiers; an interactive session already triages via targeted reads. Local models suit **bounded, well-specified** work (triage, codebase explanation, instructed maintenance), not long-horizon autonomous tasks where small models loop or hallucinate — so the frontier model keeps decomposition and validation. Skip silently when no local runtime is present.
|
|
139
141
|
|
|
140
142
|
> **Detail**: See `SKILL_detail.md §Step1-Checks` — full check table with criteria and verification commands per item — read when executing Step 1.
|
|
141
143
|
|
|
@@ -128,6 +128,16 @@ FRAMEWORK=""
|
|
|
128
128
|
for fw in streamlit django fastapi flask; do
|
|
129
129
|
if grep -qi "$fw" requirements.txt pyproject.toml 2>/dev/null; then FRAMEWORK="$fw"; echo "Framework: $fw detected"; break; fi
|
|
130
130
|
done
|
|
131
|
+
|
|
132
|
+
# Local LLM runtime (optional) — gates the conditional local-offload recommendation in Step 1.
|
|
133
|
+
# Ollama default :11434, LM Studio default :1234. Absence is the normal state (no offload item surfaced).
|
|
134
|
+
# Confirm the RESPONSE SHAPE, not just any HTTP 200 — Ollama /api/tags returns {"models":...},
|
|
135
|
+
# LM Studio /v1/models returns {"data":...}; this avoids a non-LLM service squatting the port.
|
|
136
|
+
for url in http://localhost:11434/api/tags http://localhost:1234/v1/models; do
|
|
137
|
+
if curl -sf -m 1 "$url" 2>/dev/null | grep -q '"models"\|"data"'; then
|
|
138
|
+
echo "Local LLM runtime: detected ($url)"; break
|
|
139
|
+
fi
|
|
140
|
+
done
|
|
131
141
|
```
|
|
132
142
|
|
|
133
143
|
**Bootstrap guidance when FH_DIR is not set (stop immediately in Step 0):**
|
|
@@ -168,6 +178,7 @@ install-wizard — Environment Detection
|
|
|
168
178
|
CC Hub: {CC_HUB_DIR or not set}
|
|
169
179
|
Plugins: {installed plugin list}
|
|
170
180
|
zshrc hook: {present/absent}
|
|
181
|
+
Local LLM: {runtime + url if detected — omit this row when none}
|
|
171
182
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
172
183
|
```
|
|
173
184
|
|
|
@@ -251,6 +262,7 @@ Auto-check the following items based on detected environment. Each item classifi
|
|
|
251
262
|
| `fh_env_context.jsonc` | `.claude/rules/fh_env_context.jsonc` exists | `ls .claude/rules/fh_env_context.jsonc` |
|
|
252
263
|
| `phantom-gate` | **(Python + AI-output projects only)** `phantom-gate` present in `requirements.txt` / `pyproject.toml` | `grep "phantom.gate" requirements.txt pyproject.toml 2>/dev/null` |
|
|
253
264
|
| `Domain pattern pack applied` | (optional — only when a `{framework}_patterns.md` pack is present; none ship by default) framework-specific pattern checks | `knowledge/shared/{framework}_patterns.md` check (skip if file absent — the normal default) |
|
|
265
|
+
| `local-LLM offload` | (optional — only when Step 0 detected a local LLM runtime) recommend local-model offload tooling, recommend-only | route to `/plugin-recommender` (no install performed here; skip silently if no runtime detected) |
|
|
254
266
|
|
|
255
267
|
---
|
|
256
268
|
|
|
@@ -170,6 +170,56 @@ token only *contains* an example substring but is otherwise a real private value
|
|
|
170
170
|
|
|
171
171
|
---
|
|
172
172
|
|
|
173
|
+
## Step 3c. Ignore-Verification — the gitignore-mistake safeguard (root-cause, runs before Step 4)
|
|
174
|
+
|
|
175
|
+
Steps 3/3b scan what **is** tracked. This step checks the inverse and the upstream cause: a file you
|
|
176
|
+
*intend* to be private that is **not actually ignored** — the gitignore mistake that becomes tomorrow's
|
|
177
|
+
tracked leak. For each expected-private path, `git check-ignore -v` reports whether it is ignored **and
|
|
178
|
+
by which layer** (committed `.gitignore` · local `.git/info/exclude` · global `core.excludesFile`). A
|
|
179
|
+
path that resolves to no ignore rule is a MISS — surface it before it is ever `git add`ed.
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Expected-private set = conventional FH local-only files, EXTENDED with any `# private-path: <path>`
|
|
183
|
+
# lines the operator added to the gitignored pattern source (self-extends per repo — not a frozen
|
|
184
|
+
# operator snapshot). Built one-path-per-line + while-read so it is portable across bash AND zsh
|
|
185
|
+
# (zsh does not word-split an unquoted variable, so `for f in $VAR` would break). A non-existent file
|
|
186
|
+
# is skipped; an all-absent set emits n/a, never a silent pass.
|
|
187
|
+
present=$({ printf '%s\n' CLAUDE.local.md .claude/rules/.public-surface-patterns \
|
|
188
|
+
.claude/rules/local_fh_context.md tracks/_meta/user_adaptation_profile.md
|
|
189
|
+
grep -E '^# private-path:' .claude/rules/.public-surface-patterns 2>/dev/null \
|
|
190
|
+
| sed -E 's/^# private-path:[[:space:]]*//'; } \
|
|
191
|
+
| awk 'NF' | sort -u | while IFS= read -r f; do [ -e "$f" ] && printf '%s\n' "$f"; done)
|
|
192
|
+
[ -z "$present" ] && echo "n/a (no expected-private files present in this repo — add '# private-path:' lines to the pattern source if any exist)"
|
|
193
|
+
printf '%s\n' "$present" | while IFS= read -r f; do
|
|
194
|
+
[ -z "$f" ] && continue
|
|
195
|
+
# Tracked status is tested FIRST: a file can match an ignore rule yet still be force-added
|
|
196
|
+
# (`git add -f`) — the exact ignored-but-committed mechanism behind the PR #109 leak. Tracked wins,
|
|
197
|
+
# so an ignored-but-committed file reports TRACKED (not a false-clean OK).
|
|
198
|
+
if git ls-files --error-unmatch "$f" >/dev/null 2>&1; then
|
|
199
|
+
echo "TRACKED $f (already committed — Step 3 scans its contents; un-track if it must be private: git rm --cached)"
|
|
200
|
+
elif rule=$(git check-ignore -v "$f" 2>/dev/null); then
|
|
201
|
+
echo "OK $f → ignored by [$rule]"
|
|
202
|
+
else
|
|
203
|
+
echo "MISS $f (exists, NOT ignored, NOT tracked — one 'git add .' from a leak; add an ignore rule)"
|
|
204
|
+
fi
|
|
205
|
+
done
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
- **OK** — ignored; the report names which layer covers it (operator-private files should resolve to
|
|
209
|
+
`.git/info/exclude` or `.gitignore`, never end up tracked).
|
|
210
|
+
- **MISS** — exists but no ignore rule covers it → counts as **🟠 MED** in the Step 4 verdict (a latent
|
|
211
|
+
leak, not yet a breach).
|
|
212
|
+
- **TRACKED** — already committed: Step 3 scans its *contents*; this also flags it for un-tracking if it
|
|
213
|
+
was meant to be private.
|
|
214
|
+
|
|
215
|
+
Why this is the safeguard for **gitignore mistakes** (a wrong assumption about what is ignored):
|
|
216
|
+
`.gitignore` is committed/shared, `.git/info/exclude` is local/personal, and a global `core.excludesFile`
|
|
217
|
+
ignores across all repos — `git check-ignore -v` is the one command that says *which* rule (if any)
|
|
218
|
+
applies, so an "I thought it was ignored" error surfaces here instead of in a public PR (the PR #109
|
|
219
|
+
class of leak). Diagnostic-only: this step never writes — it reports, the operator adds the ignore rule.
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
173
223
|
## Step 4. Report
|
|
174
224
|
|
|
175
225
|
```
|
|
@@ -180,7 +230,7 @@ public-surface-audit — Operator-Private Token Scan
|
|
|
180
230
|
🔴 HIGH ({count})
|
|
181
231
|
{file}:{line} → {matched token} [class: username | company asset]
|
|
182
232
|
🟠 MED ({count})
|
|
183
|
-
{file}:{line} → {matched token} [class: absolute home path]
|
|
233
|
+
{file}:{line} → {matched token} [class: absolute home path | ignore-MISS (Step 3c)]
|
|
184
234
|
🟡 LOW ({count})
|
|
185
235
|
{file}:{line} → {matched token} [class: companion-store | private wiring]
|
|
186
236
|
|
|
@@ -9,7 +9,9 @@ model: opus
|
|
|
9
9
|
# sim-conductor — Meta-Simulation Automation Orchestrator
|
|
10
10
|
|
|
11
11
|
> Profiles target → derives personas → dispatches parallel agents → M/S/R triage → commit.
|
|
12
|
-
> Personas are sourced installed-first →
|
|
12
|
+
> Personas are sourced installed-first → **filled from the persona-container schema** (6 slots, not an
|
|
13
|
+
> ad-hoc directive) → external install. Scale: 3 to 16, extensible to a crowd behind the
|
|
14
|
+
> marginal-coverage stop (§Scale).
|
|
13
15
|
|
|
14
16
|
## Invocation Triggers
|
|
15
17
|
|
|
@@ -97,12 +99,20 @@ Recommendation:
|
|
|
97
99
|
|
|
98
100
|
#### Persona Discovery (after profile → before dispatch)
|
|
99
101
|
|
|
102
|
+
> **Schema**: `knowledge/shared/harness-core/persona_container_schema.md` — the 6-slot persona-definition
|
|
103
|
+
> container. ② below **fills** these slots (lens / internal-logic / external-grounding / output-protocol
|
|
104
|
+
> / cost-tier / lifecycle) instead of injecting a shapeless directive. The container is what makes a
|
|
105
|
+
> synthesized persona reproducible and cost-routable; the old "fallback palette" was undefined.
|
|
106
|
+
|
|
100
107
|
After profiling, sim-conductor determines the needed perspective types, then maps each to the best available agent:
|
|
101
108
|
|
|
102
109
|
```
|
|
103
110
|
For each needed perspective:
|
|
104
111
|
① Scan installed plugins + .claude/agents/ → exact match? → use it
|
|
105
|
-
②
|
|
112
|
+
② Fill the 6-slot persona container — lens · internal-logic · external-grounding · output-protocol
|
|
113
|
+
(= Step 1.5 parallax shape) · cost-tier · lifecycle → a defined, reproducible persona; the filled
|
|
114
|
+
container IS the dispatch prompt (replaces the old ad-hoc "fallback palette" directive). Assign
|
|
115
|
+
the cost-tier slot per §Scale cost-tier routing. [Schema: persona_container_schema.md]
|
|
106
116
|
③ GAP: no ①② match for a high-weight perspective
|
|
107
117
|
→ query /plugin-recommender: "find agents for [perspective] matching [artifact_type] context"
|
|
108
118
|
→ present: name · install command · estimated fit · token cost
|
|
@@ -113,8 +123,8 @@ Persona Discovery output:
|
|
|
113
123
|
|
|
114
124
|
```
|
|
115
125
|
Persona Map:
|
|
116
|
-
beginner → [installed agent: beginner] OR [
|
|
117
|
-
challenger → [installed agent: challenger] OR [
|
|
126
|
+
beginner → [installed agent: beginner] OR [filled 6-slot container]
|
|
127
|
+
challenger → [installed agent: challenger] OR [filled 6-slot container]
|
|
118
128
|
[profile-specific role] → ⚠️ GAP — plugin-recommender recommends: [X] (install? y/n)
|
|
119
129
|
```
|
|
120
130
|
|
|
@@ -203,7 +213,8 @@ sim-conductor does **not** run a fixed persona set. It derives needed perspectiv
|
|
|
203
213
|
|
|
204
214
|
```
|
|
205
215
|
① Installed first — scan installed plugins + .claude/agents/ for a matching persona/agent
|
|
206
|
-
②
|
|
216
|
+
② Container fill — fill the 6-slot persona container for the standpoint; the filled container IS the
|
|
217
|
+
dispatch prompt into a general-purpose Agent (Path B — replaces the old ad-hoc role directive)
|
|
207
218
|
③ External fetch — chain to /plugin-recommender when ①② insufficient for high-stakes tasks
|
|
208
219
|
```
|
|
209
220
|
|
|
@@ -220,7 +231,7 @@ FH ships a coherent **user-mastery spectrum** as real, reusable agents (not prom
|
|
|
220
231
|
|
|
221
232
|
> **Lineage**: `beginner` / `main-player` / `expert` are the FH-native frontier successors to the field deep-insight `user` group (newcomer / power-user) — re-derived to FH grade with embedded methodology + Done-When, not name-copied. `challenger` is the advanced form of the field `devil-advocate`. The former standalone skeptic standpoint is folded into `challenger` U1.
|
|
222
233
|
|
|
223
|
-
**Ad-hoc roles** (② tier —
|
|
234
|
+
**Ad-hoc roles** (② tier — container fill): when the profile demands a standpoint with no shipped agent (e.g. "security auditor", "non-native reader"), fill the 6-slot persona container for that standpoint — the filled container is the dispatch prompt. Prefer ① shipped agents; use ② only for genuinely task-specific one-offs.
|
|
224
235
|
|
|
225
236
|
#### Scale
|
|
226
237
|
|
|
@@ -229,8 +240,30 @@ FH ships a coherent **user-mastery spectrum** as real, reusable agents (not prom
|
|
|
229
240
|
| **Minimum** | 3 | Routine Area A — most task-relevant 3 perspectives |
|
|
230
241
|
| **Extended** | 4–8 | High-stakes publish / external release |
|
|
231
242
|
| **Full** | Up to 16 parallel | Pre-major-version / architecture review |
|
|
232
|
-
|
|
233
|
-
|
|
243
|
+
| **Crowd** | 16+ — **no fixed cap; bounded by the marginal-coverage stop** | Only when the marginal-coverage stop has demonstrably **not** fired at 16 — i.e. persona #17 is still decorrelated and finding-productive. **Not** chosen by artifact size or audience count (Full already covers those); the stop, not a headcount, opens this tier |
|
|
244
|
+
|
|
245
|
+
**Crowd is output-driven, never a target** (per the container schema): the 16-cap lifts only behind the
|
|
246
|
+
**marginal-coverage stop** — add a persona only if it is *decorrelated* (a distinct viewpoint, or — at
|
|
247
|
+
crowd scale — a different model family) from those already running; **stop when the marginal new-finding
|
|
248
|
+
rate → 0**. A crowd of identical-output personas is decorative (steel-quench Wave-1 angle #1). Do not
|
|
249
|
+
name a headcount goal; the count is whatever the stop allows.
|
|
250
|
+
|
|
251
|
+
**Cost-tier routing (the economy lever)** — each persona's `cost-tier` slot routes it to a model so
|
|
252
|
+
breadth is cheap and the verdict stays trustworthy:
|
|
253
|
+
- **floor-local / heavy-local** (e.g. a local Ollama sidecar) carry cheap *breadth* — extra decorrelated
|
|
254
|
+
standpoints at near-zero token cost. A heavier local (27–32B) is a stronger canary than a floor model,
|
|
255
|
+
but **on one probe, not a benchmark** (`[[persona-container-schema]]` §tier-distribution) — so a local
|
|
256
|
+
tier is a **canary, never the gate**.
|
|
257
|
+
- **frontier** carries the **terminal verdict** — the M/S/R triage and any auto-commit decision stay
|
|
258
|
+
frontier. This is the same anchor as Step 0.6: local breadth *decorrelates*, it does not *decide*.
|
|
259
|
+
- Cost-tier routing and the Step 0.6 cross-model gate are complementary, not duplicate: 0.6 *requires* a
|
|
260
|
+
non-session source for risk≥medium (blind-spot closure); cost-tier *distributes* breadth for economy.
|
|
261
|
+
A local-sidecar persona can satisfy both at once (cross-family **and** cheap), but only Step 0.6's
|
|
262
|
+
quoted-artifact rule lets it count as `external` coverage.
|
|
263
|
+
|
|
264
|
+
All personas run as **parallel Agents** — no sequential bottleneck. Use agent-composer Medium/Large
|
|
265
|
+
fan-out for Extended/Full; Crowd scale dispatches in decorrelated waves, re-checking the marginal-coverage
|
|
266
|
+
stop between waves rather than firing all at once.
|
|
234
267
|
|
|
235
268
|
**Simplification guard**: Routine internal audits → ② built-in fallback at Minimum scale. Chain to ③ only when a needed perspective has no ①② match, or stakes are high.
|
|
236
269
|
|
|
@@ -296,7 +329,7 @@ Persona composition adapts to `artifact_type` from Step 0.3 profile:
|
|
|
296
329
|
| Prompt / config | `beginner` | challenger | Interpretation errors, implicit assumptions |
|
|
297
330
|
| Auth / security-sensitive | challenger + Security-auditor† | `main-player` (Heavy) | Attack surface, privilege escalation |
|
|
298
331
|
|
|
299
|
-
† Security-auditor =
|
|
332
|
+
† Security-auditor = ② tier — the 6-slot persona container filled for a security-auditor standpoint.
|
|
300
333
|
|
|
301
334
|
All personas run in parallel. Findings = M/S/R → M-tier items fixed immediately.
|
|
302
335
|
|
|
@@ -356,6 +389,10 @@ positives erode reviewer trust.
|
|
|
356
389
|
- Priority labels verbatim — Critical/Important/Suggestion carried as the persona set them.
|
|
357
390
|
- No forced consensus or forced conflict — report Common opinions (2+ personas agree) and Conflicts
|
|
358
391
|
(position A vs B, each with rationale) as-is. Feeds Step 2 M/S/R triage (M ← Critical or 2+ personas).
|
|
392
|
+
- Cost-tier aware triage — a frontier-tier persona's verdict is terminal; a floor/heavy-local persona's
|
|
393
|
+
finding enters only as decorrelated **breadth** (it can raise a standpoint to `covered`, never solely
|
|
394
|
+
set an M-tier on its own). This enforces in the aggregator the §Scale "local breadth decorrelates, it
|
|
395
|
+
does not decide" lock — without it, a local canary's finding would drive triage identically to frontier.
|
|
359
396
|
|
|
360
397
|
**Zero-coverage map (mandatory synthesizer output)** — the synthesizer must emit, mechanically, the set
|
|
361
398
|
of standpoints that produced **no** finding, not only the ones that did (judge-robustness swarm,
|
|
@@ -441,6 +478,30 @@ as normal. (This withdraws one privilege, not the run — the report and fixes s
|
|
|
441
478
|
|
|
442
479
|
---
|
|
443
480
|
|
|
481
|
+
## Step 5 — Graduate a Proven Persona (optional, rare)
|
|
482
|
+
|
|
483
|
+
Most synthesized personas are **throwaway** — the run accelerated the work and the persona is discarded.
|
|
484
|
+
A persona earns a permanent home only by passing the container schema's **admission test** (the analogue
|
|
485
|
+
of "app-ification"; `[[persona-container-schema]]` §Lifecycle):
|
|
486
|
+
|
|
487
|
+
| Check | Criterion | Class |
|
|
488
|
+
|---|---|---|
|
|
489
|
+
| **Recurrence** | surfaced **≥1 unique S/M finding** (one no other persona in the run produced) across **≥2 distinct targets** — not a one-off lucky fire | measured |
|
|
490
|
+
| **Trust bar (skills only)** | if graduating into a *skill* rather than a project's persona set, additionally clears the **FH 6-item creation gate** | mandatory-pass |
|
|
491
|
+
|
|
492
|
+
- **Pass → into a project's static set**: route the write through `asset-placement-gate` (expected
|
|
493
|
+
verdict: project-local) before writing the filled container to the project's persona file (e.g.
|
|
494
|
+
the-bible `core/personas.json`) — sim-conductor proposes the target, the placement gate confirms it,
|
|
495
|
+
the operator approves. A project-local asset, not an FH change, but the cross-boundary write is still gated.
|
|
496
|
+
- **Pass → into a skill**: route through `asset-placement-gate` + the New-Skill creation gate (the
|
|
497
|
+
skill-foundry inversion — the trust bar is non-negotiable). This is **HITL**, never auto-graduated.
|
|
498
|
+
- **Fail the recurrence check** → stays ephemeral. Do not graduate on a single run.
|
|
499
|
+
|
|
500
|
+
Graduation is **never automatic** and is **out of scope for auto-commit** — it is a deliberate,
|
|
501
|
+
operator-approved promotion. A clean simulation that graduated nothing is a normal, complete run.
|
|
502
|
+
|
|
503
|
+
---
|
|
504
|
+
|
|
444
505
|
## Human Gate Principle
|
|
445
506
|
|
|
446
507
|
Convergence within an AI-AI loop is **provisional**. Elevated to final only after human gate.
|