@chrono-meta/fh-gate 1.4.59 → 1.4.61
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-plugin/marketplace.json +3 -3
- package/CATALOG.md +83 -0
- package/CHEATSHEET.md +15 -2
- package/CLAUDE.md +143 -224
- package/README.ja.md +8 -7
- package/README.ko.md +7 -6
- package/README.md +36 -17
- package/README.zh.md +5 -5
- package/bin/fh-codex-doctor.js +34 -3
- package/bin/fh-gate.js +17 -5
- package/bin/fh-goal.js +13 -5
- package/bin/fh-run.js +13 -5
- package/knowledge/shared/harness-core/claude_md_gate_details.md +88 -1
- package/knowledge/shared/harness-core/fh_detail_protocols.md +2 -2
- package/knowledge/shared/harness-core/field_harness_diagnostic.md +48 -0
- package/knowledge/shared/harness-core/measurement-integrity-checklist.md +9 -2
- package/knowledge/shared/harness-core/multi_harness_evolution_loop.md +66 -0
- package/knowledge/shared/harness-core/onboarding_acceleration_autopilot.md +82 -0
- package/package.json +2 -1
- package/plugins/fh-commons/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/.claude-plugin/plugin.json +2 -2
- package/plugins/fh-meta/skills/fh/SKILL.md +71 -0
- package/plugins/fh-meta/skills/harness-doctor/SKILL.md +109 -10
- package/plugins/fh-meta/skills/salience-splitter/SKILL.md +1 -1
- package/plugins/fh-meta/skills/verify-bidirectional/SKILL.md +3 -3
- package/scripts/count_check.sh +8 -1
- package/scripts/fh-gate.sh +150 -13
- package/scripts/fh-goal.sh +46 -5
- package/scripts/fh-run.sh +11 -0
- package/scripts/selfcheck.sh +40 -10
- package/scripts/test_fh_gate_regressions.sh +208 -0
- package/templates/local_fh_context.md +1 -1
package/README.md
CHANGED
|
@@ -72,6 +72,18 @@ claude
|
|
|
72
72
|
> ✅ Claude reads `CLAUDE.md` and asks what project to connect or what task to start.
|
|
73
73
|
> Say **"Connect a project"** → hub scans `../`, finds `.git` directories, creates `tracks/{project}/`.
|
|
74
74
|
|
|
75
|
+
**Your first 15 minutes** — what success looks like, and what to do with it:
|
|
76
|
+
|
|
77
|
+
1. You'll know setup worked when a greeting ("hi") shows the 🐿️ door menu, and "Connect a project"
|
|
78
|
+
creates `tracks/{your-project}/`.
|
|
79
|
+
2. Then grab an immediate win in the same session: say **"accelerate this project"** (ranked plan of
|
|
80
|
+
skills/plugins worth wiring, install-gated) or **"run /context-doctor"** (token-waste scan).
|
|
81
|
+
3. One honest note: FH's core payoff is **compounding** — session records, harvested learnings,
|
|
82
|
+
cross-session memory. It shows from **session 2 onward**. Day one gives you the menu, the
|
|
83
|
+
acceleration plan, and governance gates; don't judge the compounding on day one.
|
|
84
|
+
|
|
85
|
+
Unfamiliar words on the way? → [`knowledge/shared/GLOSSARY.md`](knowledge/shared/GLOSSARY.md).
|
|
86
|
+
|
|
75
87
|
**Plugin only (no clone):**
|
|
76
88
|
```bash
|
|
77
89
|
claude plugin marketplace add https://github.com/chrono-meta/forge-harness.git # once
|
|
@@ -79,16 +91,20 @@ claude plugin install -s user fh-meta@forge-harness
|
|
|
79
91
|
cd ~/projects/{your-project} && claude
|
|
80
92
|
```
|
|
81
93
|
|
|
82
|
-
> ⚠️ **Plugin-only is partial synergy.** You get the skills and agents, but **not**
|
|
83
|
-
> `CLAUDE.md` governance (active onboarding, the 4-axis gate, mode branching
|
|
84
|
-
> context (`tracks/` memory accumulation, `harvest-loop`
|
|
85
|
-
>
|
|
86
|
-
>
|
|
94
|
+
> ⚠️ **Plugin-only is partial synergy.** You get the skills and agents, but **not** the hub-side
|
|
95
|
+
> orchestration — the `CLAUDE.md` governance (active onboarding, the 4-axis gate, mode branching;
|
|
96
|
+
> automation layer) and the compounding context (`tracks/` memory accumulation, `harvest-loop`
|
|
97
|
+
> learning; methodology layer).
|
|
98
|
+
> Each skill runs the same in isolation; what's missing is the orchestration that makes them compound
|
|
99
|
+
> across sessions. Clone the hub (above) when you want the full set, not just the tools.
|
|
87
100
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
101
|
+
**Which entry path is for you?**
|
|
102
|
+
|
|
103
|
+
| You are… | Start with |
|
|
104
|
+
|---|---|
|
|
105
|
+
| Solo dev, one project, just trying it | [`templates/starter_profile.md`](templates/starter_profile.md) — one command, curated first-five skills |
|
|
106
|
+
| Multiple projects, want the compounding hub | Clone the hub (quickstart above) |
|
|
107
|
+
| CI / non-Claude runtime, gates only | `npx @chrono-meta/fh-gate` (zero-install governance gate) |
|
|
92
108
|
|
|
93
109
|
---
|
|
94
110
|
|
|
@@ -131,12 +147,13 @@ attention is spent only where a change is irreversible.
|
|
|
131
147
|
|
|
132
148
|
Scale is the second point. A **skill, agent, or plugin** is a tool. A **harness** is a level up — a *star*:
|
|
133
149
|
one project's tools, rules, gates, and memory bound into a single working body. **forge-harness is the
|
|
134
|
-
galaxy those stars live in
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
150
|
+
galaxy those stars live in**: it binds many harnesses onto a shared floor to prevent drift, and lets
|
|
151
|
+
them evolve together instead of scattering.
|
|
152
|
+
|
|
153
|
+
This galaxy is more than a container. FH can run a field harness **in simulation inside its own
|
|
154
|
+
sandbox** — expensive per run, cheaper in total, because the trial-and-error pools in one place and
|
|
155
|
+
compounds — and when the simulation holds, it **emits** the project as an independent, specialized
|
|
156
|
+
harness. That is the goal it is built toward. In practice it works in four ways:
|
|
140
157
|
|
|
141
158
|
**① Assemble** — FH runs a *cluster* of harnesses at optimized token cost and hands you the right one for
|
|
142
159
|
the project. You don't wire up skills one by one; you get a **harness** — its plugins, skills, and agents
|
|
@@ -220,7 +237,7 @@ FH_BACKEND=codex npx --package @chrono-meta/fh-gate fh-goal --prompt "Implement
|
|
|
220
237
|
|
|
221
238
|
The broader FH automation layer still depends on Claude Code for sub-agents, hooks, and slash commands. The portable path is shared documents plus runtime adapters, not separate Codex and Claude forks.
|
|
222
239
|
|
|
223
|
-
**Recommended posture — Claude Code as orchestrator, others as sidecars.** FH's automation layer (auto-firing hooks, sub-agent dispatch, onboarding, memory) is Claude-Code-native, so the fullest experience runs **Claude Code as the main orchestrator with Gemini, Codex, or Antigravity (`agy`) as actively-used sidecars**. You can also run a **non-CC runtime as your main agent** — you keep the full methodology layer and M1 skills through `fh-gate`/`fh-run`, but you do **not** get the autopilot layer: hooks don't auto-fire, M2 agent-dispatch steps need the adapter (or interactive approval), and M3 skills are reference-only. This is a deliberate two-layer boundary, not a gap to be closed. Per-runtime detail: [`docs/codex-compat.md`](docs/codex-compat.md) (tier-by-tier) and [`multi_model_sidecar_strategy.md`](knowledge/shared/harness-core/multi_model_sidecar_strategy.md) (sidecar engines, including the Gemini→`agy` succession at the 2026-06-18 EOL).
|
|
240
|
+
**Recommended posture — Claude Code as orchestrator, others as sidecars.** FH's automation layer (auto-firing hooks, sub-agent dispatch, onboarding, memory) is Claude-Code-native, so the fullest experience runs **Claude Code as the main orchestrator with Gemini, Codex, or Antigravity (`agy`) as actively-used sidecars**. You can also run a **non-CC runtime as your main agent** — you keep the full methodology layer and M1 skills (M1 = runs on any runtime as written; M2 = needs agent dispatch; M3 = Claude-Code-native — the portability tiers detailed in [`docs/codex-compat.md`](docs/codex-compat.md)) through `fh-gate`/`fh-run`, but you do **not** get the autopilot layer: hooks don't auto-fire, M2 agent-dispatch steps need the adapter (or interactive approval), and M3 skills are reference-only. This is a deliberate two-layer boundary, not a gap to be closed. Per-runtime detail: [`docs/codex-compat.md`](docs/codex-compat.md) (tier-by-tier) and [`multi_model_sidecar_strategy.md`](knowledge/shared/harness-core/multi_model_sidecar_strategy.md) (sidecar engines, including the Gemini→`agy` succession at the 2026-06-18 EOL).
|
|
224
241
|
|
|
225
242
|
**Empirical result (2026-05-31)**: Applied to OpenCode's AI-generated `permission/arity.ts` (163 lines, CI green). Current gate semantics classify this as BLOCKED: 2 A-grade findings CI didn't catch (short-token overflow in allowlist, executor tools absent from arity table).
|
|
226
243
|
|
|
@@ -258,7 +275,9 @@ All four movements ship. Temper was named before it was built — deliberately (
|
|
|
258
275
|
two more signatures keep it running: `harvest-loop` (each session's lessons become permanent skills) and
|
|
259
276
|
`agent-composer` (orchestrate the dispatch). The other skills wait until you need them — full list below.
|
|
260
277
|
|
|
261
|
-
##
|
|
278
|
+
## 38 skills · 8 agents
|
|
279
|
+
|
|
280
|
+
> Count = non-deprecated skills (deprecated redirect stubs — kept only for old-name routing — excluded).
|
|
262
281
|
|
|
263
282
|
<details>
|
|
264
283
|
<summary>Full asset activation check</summary>
|
package/README.zh.md
CHANGED
|
@@ -127,11 +127,11 @@ Project B ──→ 在 CLAUDE.md 中连接中枢
|
|
|
127
127
|
|
|
128
128
|
规模是第二个重点。**技能、agent 或插件** 是一个工具。**框架** 高出一级 —— 是一颗 *星*:
|
|
129
129
|
一个项目的工具、规则、门禁与记忆,绑成一个运作的整体。**forge-harness 就是这些星所栖居的
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
130
|
+
星系**:它把众多框架绑定在共享的下限之上以防止漂移,并让它们一起演化而不是四散。
|
|
131
|
+
|
|
132
|
+
这个星系不只是容器。FH 可以在自己的沙箱里**以仿真方式跑一个现场框架** —— 单次昂贵,总体
|
|
133
|
+
更便宜,因为试错汇聚在一处并复利累积 —— 当仿真验证通过,它就把该项目**输出 (emit)** 为一个
|
|
134
|
+
独立的、特化的框架。这就是它所朝向的目标。实际上,它以四种方式运作:
|
|
135
135
|
|
|
136
136
|
**① 组装 (Assemble)** —— FH 以优化后的 token 成本运行一整 *簇* 框架,并把最合适的那个交到你手上。
|
|
137
137
|
你不是一个个去接线技能;你得到的是一个 **框架** —— 连同它的插件、技能与 agent —— 已按需组装好。
|
package/bin/fh-codex-doctor.js
CHANGED
|
@@ -117,15 +117,25 @@ function extractBacktickNames(line) {
|
|
|
117
117
|
return names;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
// The tier table IS this doctor's instrument. If it cannot be read or parsed, every skill
|
|
121
|
+
// comes back documentedTier=null, no M1 rule can ever fire, findings is empty, and the report
|
|
122
|
+
// says OK with --strict exiting 0 — a broken instrument reporting "no violations". An
|
|
123
|
+
// unreadable source (permissions, wrong root) and a parse yielding zero rows (the table's
|
|
124
|
+
// markdown drifted, e.g. bold dropped from `| **M1 |`) both land there, so both are reported
|
|
125
|
+
// as an instrument failure rather than a clean bill of health.
|
|
120
126
|
function documentedTiers(root) {
|
|
121
127
|
const sources = [
|
|
122
128
|
path.join(root, 'AGENTS.md'),
|
|
123
129
|
];
|
|
124
130
|
const tiers = new Map();
|
|
125
131
|
const evidence = [];
|
|
132
|
+
const sourceErrors = [];
|
|
126
133
|
for (const source of sources) {
|
|
127
134
|
const text = maybeReadText(source);
|
|
128
|
-
if (!text)
|
|
135
|
+
if (!text) {
|
|
136
|
+
sourceErrors.push(`${rel(root, source)}: missing or unreadable`);
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
129
139
|
const lines = text.split('\n');
|
|
130
140
|
lines.forEach((line, index) => {
|
|
131
141
|
const tierMatch = line.match(/\|\s*\*\*(M[123])\b/);
|
|
@@ -137,7 +147,12 @@ function documentedTiers(root) {
|
|
|
137
147
|
}
|
|
138
148
|
});
|
|
139
149
|
}
|
|
140
|
-
|
|
150
|
+
if (tiers.size === 0 && sourceErrors.length === 0) {
|
|
151
|
+
sourceErrors.push(
|
|
152
|
+
`${rel(root, sources[0])}: readable but yielded 0 tier rows — the tier table format drifted`
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
return { tiers, evidence, sourceErrors };
|
|
141
156
|
}
|
|
142
157
|
|
|
143
158
|
function compatDocTierMentions(root, skillNames) {
|
|
@@ -333,7 +348,13 @@ function buildReport(root) {
|
|
|
333
348
|
}
|
|
334
349
|
|
|
335
350
|
return {
|
|
336
|
-
|
|
351
|
+
// INSTRUMENT_ERROR outranks both: without a tier table this run measured nothing, and
|
|
352
|
+
// "measured nothing" must not be reported as OK (nor as DRIFT, which would claim a
|
|
353
|
+
// finding it never made).
|
|
354
|
+
status: docs.sourceErrors.length > 0
|
|
355
|
+
? 'INSTRUMENT_ERROR'
|
|
356
|
+
: findings.some((f) => f.severity === 'HIGH') ? 'DRIFT' : 'OK',
|
|
357
|
+
instrumentErrors: docs.sourceErrors,
|
|
337
358
|
root,
|
|
338
359
|
counts,
|
|
339
360
|
agentCards: loadAgentCards(root),
|
|
@@ -411,6 +432,16 @@ function main() {
|
|
|
411
432
|
} else {
|
|
412
433
|
printText(report);
|
|
413
434
|
}
|
|
435
|
+
// An instrument failure is not a passing run. It exits non-zero unconditionally — not only
|
|
436
|
+
// under --strict — because the failure mode it guards is precisely a caller reading exit 0
|
|
437
|
+
// as "no drift" when nothing was measured. 10 = harness error, distinct from 1 = drift found.
|
|
438
|
+
if (report.status === 'INSTRUMENT_ERROR') {
|
|
439
|
+
for (const err of report.instrumentErrors) {
|
|
440
|
+
process.stderr.write(`ERROR: tier source unusable — ${err}\n`);
|
|
441
|
+
}
|
|
442
|
+
process.stderr.write(' Nothing was classified, so no drift could be detected. Failing closed.\n');
|
|
443
|
+
process.exit(10);
|
|
444
|
+
}
|
|
414
445
|
if (args.strict && report.counts.findings.HIGH > 0) {
|
|
415
446
|
process.exit(1);
|
|
416
447
|
}
|
package/bin/fh-gate.js
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
|
+
// Thin wrapper — the exit code IS the contract (0 PASS / 1 PENDING / 2 BLOCKED /
|
|
4
|
+
// 3 ESCALATE / 10 harness-error / 11 arg-error / 12 dry-run). execFileSync throws on any
|
|
5
|
+
// non-zero exit, so an uncaught throw collapsed every one of them into node's own exit 1 —
|
|
6
|
+
// i.e. BLOCKED arrived at the caller as PENDING ("proceed with awareness"). Propagate the
|
|
7
|
+
// real status, and fail closed (10) when there is no status to propagate.
|
|
3
8
|
const { execFileSync } = require('child_process');
|
|
4
9
|
const path = require('path');
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
try {
|
|
11
|
+
execFileSync(
|
|
12
|
+
path.join(__dirname, '..', 'scripts', 'fh-gate.sh'),
|
|
13
|
+
process.argv.slice(2),
|
|
14
|
+
{ stdio: 'inherit' }
|
|
15
|
+
);
|
|
16
|
+
} catch (err) {
|
|
17
|
+
if (typeof err.status === 'number') process.exit(err.status);
|
|
18
|
+
// Killed by a signal, or the script could not be spawned at all: no verdict exists.
|
|
19
|
+
console.error(`fh-gate: could not run the gate (${err.signal || err.code || err.message}) — failing closed`);
|
|
20
|
+
process.exit(10);
|
|
21
|
+
}
|
package/bin/fh-goal.js
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
|
+
// Thin wrapper — propagate the script's real exit status. execFileSync throws on non-zero,
|
|
4
|
+
// so an uncaught throw collapsed every distinct status into node's own exit 1.
|
|
3
5
|
const { execFileSync } = require('child_process');
|
|
4
6
|
const path = require('path');
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
try {
|
|
8
|
+
execFileSync(
|
|
9
|
+
path.join(__dirname, '..', 'scripts', 'fh-goal.sh'),
|
|
10
|
+
process.argv.slice(2),
|
|
11
|
+
{ stdio: 'inherit' }
|
|
12
|
+
);
|
|
13
|
+
} catch (err) {
|
|
14
|
+
if (typeof err.status === 'number') process.exit(err.status);
|
|
15
|
+
console.error(`fh-goal: could not run (${err.signal || err.code || err.message}) — failing closed`);
|
|
16
|
+
process.exit(10);
|
|
17
|
+
}
|
package/bin/fh-run.js
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
|
+
// Thin wrapper — propagate the script's real exit status. execFileSync throws on non-zero,
|
|
4
|
+
// so an uncaught throw collapsed every distinct status into node's own exit 1.
|
|
3
5
|
const { execFileSync } = require('child_process');
|
|
4
6
|
const path = require('path');
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
try {
|
|
8
|
+
execFileSync(
|
|
9
|
+
path.join(__dirname, '..', 'scripts', 'fh-run.sh'),
|
|
10
|
+
process.argv.slice(2),
|
|
11
|
+
{ stdio: 'inherit' }
|
|
12
|
+
);
|
|
13
|
+
} catch (err) {
|
|
14
|
+
if (typeof err.status === 'number') process.exit(err.status);
|
|
15
|
+
console.error(`fh-run: could not run (${err.signal || err.code || err.message}) — failing closed`);
|
|
16
|
+
process.exit(10);
|
|
17
|
+
}
|
|
@@ -103,9 +103,79 @@ pass/block verdict* — e.g. `agent-composer`, `goal-quench`, `asset-placement-g
|
|
|
103
103
|
|
|
104
104
|
---
|
|
105
105
|
|
|
106
|
+
## §Cross-Family-Complement
|
|
107
|
+
|
|
108
|
+
Execution detail for CLAUDE.md §FH Improvement 4-Axis Auto-Gate → *Cross-family complement*. The rule
|
|
109
|
+
that a load-bearing change recruits ≥1 different-family auditor, that it is autonomous once consented,
|
|
110
|
+
and that the governor keeps the terminal verdict + source-grounds every finding — all stay in CLAUDE.md.
|
|
111
|
+
|
|
112
|
+
**Sidecar mapping (per the UAP)** — pick by task class, not by preference:
|
|
113
|
+
|
|
114
|
+
| Task class | Recruit | Why |
|
|
115
|
+
|---|---|---|
|
|
116
|
+
| Repo-grounded code / security audit | `codex` (`gpt-5.5`, xhigh) | reads the actual tree; strongest on verdict-code logic |
|
|
117
|
+
| Breadth / multimodal / frontier scan | `agy` (Gemini) | wide recall, video + image ingest |
|
|
118
|
+
| Batch / free-tier arm | local 4090 over Tailscale | no token cost; weaker judge — anchor it |
|
|
119
|
+
|
|
120
|
+
**Degrade**: when no different-family auditor is reachable, say so and fall back to single-session — but
|
|
121
|
+
note the exception in §Field-Harness Load-Bearing Change Gate, where an unreachable cross-family panel is
|
|
122
|
+
**NOT-CONVERGED** rather than a silent same-family pass (that surface is pre-merge and irreversible-adjacent).
|
|
123
|
+
|
|
124
|
+
**Dogfood evidence (2026-06-27)**: a cross-family pass caught a HIGH execution-side-effect blind spot that
|
|
125
|
+
the same-family reviewers **and** the target-tier sim all shared. That is the decorrelation value made
|
|
126
|
+
concrete: the miss was not a depth failure (the sim ran at the right tier) but a *correlation* failure —
|
|
127
|
+
every reviewer in the Claude family read the change the same optimistic way. Decorrelation is the only
|
|
128
|
+
lever that moves a correlated blind spot; more same-family review does not.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## §Destructive-Op-Hook-Coverage
|
|
133
|
+
|
|
134
|
+
Execution detail for CLAUDE.md §Destructive-Op Gate. The **order invariant** (enumerate → recover →
|
|
135
|
+
destroy), the **3 steps**, the `DESTRUCTIVE_OP_OK=1` override, and the **fail-closed degrade direction**
|
|
136
|
+
stay in CLAUDE.md — they are load-bearing every session. What follows is the mechanics + honest scope.
|
|
137
|
+
|
|
138
|
+
**Per-ref verdict (pre-push hook)**: the hook detects the destructive refspec on stdin — *delete* = local
|
|
139
|
+
SHA all-zeros; *force* = remote SHA not an ancestor of local — then judges each ref:
|
|
140
|
+
|
|
141
|
+
| Ref state | Verdict | Hook action |
|
|
142
|
+
|---|---|---|
|
|
143
|
+
| Branch delete, fully merged | SAFE | allowed |
|
|
144
|
+
| Branch delete, commits off base + 0 unique paths | CHECK | **blocked** — needs a judged content look |
|
|
145
|
+
| Branch delete, unique paths present | REVIEW | **blocked** — recovery mandatory |
|
|
146
|
+
| Force / non-ff push | — | **always blocked** |
|
|
147
|
+
| Tag / notes delete | — | **always blocked** |
|
|
148
|
+
|
|
149
|
+
The verdict is load-bearing, not decorative: a merged-branch cleanup passes, a silent-loss CHECK does not.
|
|
150
|
+
This is the enumerate step as a mechanical floor rather than prose.
|
|
151
|
+
|
|
152
|
+
**What it does and does NOT close (honest)**: it closes the **honest-weak-model** gap — an agent that
|
|
153
|
+
simply *forgot* the prose gate is now mechanically stopped. It does **not** close the
|
|
154
|
+
**injected/adversarial** gap: an agent under instruction can set the override or pass `--no-verify`, and a
|
|
155
|
+
client-side hook is readable and bypassable by design. The hard floor for the adversarial case is
|
|
156
|
+
**server-side branch protection** (GitHub *Restrict deletions* / *Restrict force pushes*) — this hook is
|
|
157
|
+
the honest-model floor, branch protection is the hard floor.
|
|
158
|
+
|
|
159
|
+
**Scope**: covers only git pushes *from a hook-installed repo*. `npm publish` is mechanized separately via
|
|
160
|
+
`prepublishOnly` (see §Pre-Publish-Hook-Coverage (c)); the remaining non-git surface — a separate-repo
|
|
161
|
+
`gh repo create --public` / visibility flip — is genuinely un-hookable and stays prose +
|
|
162
|
+
`PRE-PUBLISH-CHECKLIST.md`.
|
|
163
|
+
|
|
164
|
+
**Portability defect class**: the hook is bash-3.2 safe (macOS default `/bin/bash`). The original draft
|
|
165
|
+
used a bash-4 associative array that crashed **fail-OPEN** on 3.2 — caught in test. Worth naming: a
|
|
166
|
+
portability break in a gate degrades toward permissive unless the gate is written to fail closed on its
|
|
167
|
+
own errors.
|
|
168
|
+
|
|
169
|
+
**Origin (2026-06-10 branch cleanup)**: pre-deletion enumeration recovered a parallel session's card
|
|
170
|
+
(weekly-audit completion + #88 merge state) that existed **only on an unmerged branch** with zero unique
|
|
171
|
+
paths — exactly the CHECK class, and invisible to "is it merged?" intuition. Deletion without the gate
|
|
172
|
+
destroys live state without anyone noticing. This is why the loss class is called *silent*.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
106
176
|
## §Pre-Publish-Hook-Coverage
|
|
107
177
|
|
|
108
|
-
**Hook coverage —
|
|
178
|
+
**Hook coverage — three distinct actions** (refined 2026-06-17 for (a)/(b); (c) added 2026-06-27):
|
|
109
179
|
- **(a) repo-go-public** (`gh repo create --public` / a visibility flip) is irreversible and usually in a
|
|
110
180
|
**separate repo** — the FH pre-commit hook **cannot** catch it. That stays **AI-behavioral** (proactive
|
|
111
181
|
trigger) **+ a portable checklist** (`templates/PRE-PUBLISH-CHECKLIST.md`), run on any repo/machine.
|
|
@@ -126,6 +196,23 @@ pass/block verdict* — e.g. `agent-composer`, `goal-quench`, `asset-placement-g
|
|
|
126
196
|
plaintext only (encoded tokens out of scope); a line-split backstop catches a token wrapped across
|
|
127
197
|
lines; `PUBLIC_SURFACE_OK=1` overrides and is logged to a gitignored audit trail for the weekly audit.
|
|
128
198
|
Residuals (split-encoding, override-not-populated, override abuse) are documented, not silent.
|
|
199
|
+
- **(c) `npm publish`** — mechanically gated by `scripts/public_surface_scan_files.sh`, wired into
|
|
200
|
+
`prepublishOnly` (`npm run release` also runs it *outside* the lifecycle). Unlike (b) it scans the
|
|
201
|
+
**full content of the exact npm-published file set** (`npm pack --dry-run`), *not* a commit diff — so a
|
|
202
|
+
token committed **before the scan existed**, or carried in a `files[]` entry, is still caught at the
|
|
203
|
+
registry boundary. HIGH/MED block; `PUBLIC_SURFACE_OK=1` overrides + logs. **Fail-closed** when patterns
|
|
204
|
+
or the file set are unresolved, when the parse looks partial, **or when the gitignored operator override
|
|
205
|
+
is absent** — defaults-only would otherwise green-PASS a HIGH company literal on a fresh clone or CI runner.
|
|
206
|
+
|
|
207
|
+
**Named residuals for (c)** — it is a denylist **on the npm CLI path with scripts enabled**, not a
|
|
208
|
+
universal secret-scanner:
|
|
209
|
+
|
|
210
|
+
| # | Residual | Mitigation |
|
|
211
|
+
|---|---|---|
|
|
212
|
+
| i | `npm publish --ignore-scripts`, a CI `.npmrc` with `ignore-scripts=true`, or `pnpm`/`yarn publish` **skip the lifecycle hook entirely** | route publishes through `npm run release`, or add an explicit CI scan step |
|
|
213
|
+
| ii | scans only the **loaded patterns** — an **un-patterned secret shape** (an API key the patterns don't describe) still ships | pattern coverage is the limit; pair with a real secret-scanner if that shape matters |
|
|
214
|
+
| iii | on a runner without the gitignored override it is **defaults-only** unless populated | populate the override in each authoring env (esp. the company env) |
|
|
215
|
+
| iv | scans **working-tree content, not the final tarball bytes** | benign today (content-neutral lifecycle: prepare=chmod, no prepack) — **re-open if a content-generating publish lifecycle is added** (cross-family audit 2026-06-27) |
|
|
129
216
|
|
|
130
217
|
> Origin: 2026-06-05 `phantom-gate` shipped public, then needed a private→de-company-scrub→re-public
|
|
131
218
|
> round-trip (`fh_signal_2026-06-05_fh-direct`). PSA existed but nothing forced it pre-publish. 2026-06-17
|
|
@@ -96,13 +96,13 @@ Identity marker: every greeting response opens with **🐿️ then an identity-r
|
|
|
96
96
|
> 🐿️ **Welcome to FH.** *forge-harness is a tool hub for rapidly setting up Claude Code projects. It supports plugin recommendations, project setup, and harness diagnostics. What would you like to work on?*
|
|
97
97
|
|
|
98
98
|
**Returning user** (branch test above) — open with the fixed 4-door menu (the doors are stable; the contents are composed live). A summary copy lives in CLAUDE.md §Active Onboarding — keep branch tests and door labels in sync when editing:
|
|
99
|
-
> 🐿️ **Welcome back to FH.** *What would you like to start? ① Map a project · ② Create a new project · ③ Accelerate a mapped project (work · Full-Harness · skills/agents/plugins) — {field candidates} · ④ Cross-project synergy*
|
|
99
|
+
> 🐿️ **Welcome back to FH.** *What would you like to start? ① Map a project · ② Create a new project · ③ Accelerate **or diagnose** a mapped project (work · Full-Harness · skills/agents/plugins · 진단) — {field candidates} · ④ Cross-project synergy*
|
|
100
100
|
>
|
|
101
101
|
> (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.")
|
|
102
102
|
|
|
103
103
|
- **① Map a project** → routes to `auto_project_mapping.md`; after a successful mapping, offer the §6 Full-Harness promotion prompt
|
|
104
104
|
- **② Create a new project** → Step 3-0 (new project setup)
|
|
105
|
-
- **③ Accelerate a mapped project** → compose live from `CATALOG.md` / active tracks / the session card's **field-side** candidates — never hardcode a track name; read current state each time so the menu cannot go stale. **Acceleration levers** (offer per project state, each user-approved):
|
|
105
|
+
- **③ Accelerate or diagnose a mapped project** → compose live from `CATALOG.md` / active tracks / the session card's **field-side** candidates — never hardcode a track name; read current state each time so the menu cannot go stale. Picking ③ with a *fix/diagnose* intent ("고칠 거 있나", "점검") routes to the **Field-Harness Diagnostic** (CLAUDE.md §Field-Harness Diagnostic) rather than the install plan. **Acceleration levers** (offer per project state, each user-approved):
|
|
106
106
|
- **Full-Harness promotion** for projects still on light mapping (`auto_project_mapping.md` §6)
|
|
107
107
|
- **Skill-ification** of repeated patterns (`#skill-candidate` tag at 3+ recurrences → SKILL.md draft; FH skill gates — diet · Done When · triggers — apply to field skills too)
|
|
108
108
|
- **Sub-agent proposals** (`.claude/agents/*.md`, invocation rules in `operations.md`)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Field-Harness Diagnostic — compose → rank → HITL (detail)
|
|
2
|
+
|
|
3
|
+
> Always-loaded summary: `CLAUDE.md §Field-Harness Diagnostic`. This file is the detail home —
|
|
4
|
+
> the full lens table, dogfood examples, and guard rationale. Read when actually running the
|
|
5
|
+
> diagnostic on a mapped project.
|
|
6
|
+
|
|
7
|
+
The Load-Bearing Change Gate fires on a **specific field code change**. This diagnostic is its
|
|
8
|
+
**on-demand pull sibling**: when the operator, working in a mapped project, asks to *diagnose* or
|
|
9
|
+
*improve* the harness itself ("진단해줘", "개선해줘", "check this project"), don't hand-pick one
|
|
10
|
+
skill — **compose the checks FH already has into a single ranked diagnostic list and get per-item
|
|
11
|
+
approval.** The value is that the operator asks once and the harness surfaces *everything* worth
|
|
12
|
+
fixing, ranked, instead of the operator having to know which of a dozen skills to invoke. Every fix
|
|
13
|
+
is HITL — the diagnostic **proposes**, never auto-edits.
|
|
14
|
+
|
|
15
|
+
## Composition (no-reinvention — every row is an existing check; the diagnostic only *routes and ranks*)
|
|
16
|
+
|
|
17
|
+
| Lens | Existing check | Catches (real examples from 2026-07-08) |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| **Confidentiality / leak** | `/public-surface-audit` (incl. Step 3c ignore-verification) | a hardcoded internal API host literal in a SKILL body; a `local_*_context.md` that is **tracked** when it should be gitignored (the gitignore-mistake class) |
|
|
20
|
+
| **Split integrity** | `/phantom-quench` **Step 2.7** (bidirectional) | orphan detail sections + phantom pointers in a SKILL.md ↔ SKILL_detail.md pair |
|
|
21
|
+
| **Token / salience** | salience-split candidates (`/context-doctor` · `/salience-splitter` targets) | oversized always-loaded SKILL.md / CLAUDE.md — trim candidates |
|
|
22
|
+
| **Structure** | `/harness-doctor` (L1–L4) | orphaned/redundant/decorative units, missing Done-When, ≥70% overlap |
|
|
23
|
+
| **Verdict/gate degrade** | `scripts/degrade_direction_scan.sh` | a field verdict/gate helper that degrades toward permissive (advisory pre-screen) |
|
|
24
|
+
| **Loop-readiness** (황민호 loop-eng 5-question lens, 2026-07-10 — detail home: `loop_engineering.md`, incl. the FH loop inventory + design-time discipline) | *Loop-runtime axis — net-new vs Structure* (harness-doctor scans static form; this scans whether the path closes a loop). **Mechanical grep**: `/goal-quench`·`/loop` wiring present · check-class token declared. **Judged**: is the persisted state (card/handoff/memory) actually reloaded · is the declared check-class anchored, not judged-only · does the path halt. Done-When *presence* → see Structure row (no double-grep). **Adversarial pair** (for the judged sub-checks — decorrelated, behavior-vs-checklist): a target-tier blind sim that *runs* the path and observes whether it halts + persists, rather than re-checklisting it (the harness litmus shares this lens's axis, so it is a co-lens, not the adversary). | an agent path that *runs but doesn't loop*: no completion criterion (Done-When absent), judged-only validation with no anchor, no halt/budget guard (runaway/cost), or no state carried to the next run — the 5 questions (initiate · complete · validate · halt · persist) with 0 answers |
|
|
25
|
+
|
|
26
|
+
## Output
|
|
27
|
+
|
|
28
|
+
One ranked list, `M` (must-fix) / `S` (should-fix) / `R` (recommended) — same tiering as
|
|
29
|
+
harness-doctor — each item stating *lens · file:line · one-line fix*. **Then HITL**: the operator
|
|
30
|
+
approves per item (or a batch); an approved fix routes to the owning skill's normal path (and, if it
|
|
31
|
+
is itself a load-bearing field change, through the Load-Bearing Change Gate). **Nothing is
|
|
32
|
+
auto-fixed** — the diagnostic's job is the *intelligent list*, the human's job is the *go*.
|
|
33
|
+
|
|
34
|
+
## Guards
|
|
35
|
+
|
|
36
|
+
- **(a) Project-level ask only** — fires on a project-level "진단/개선" ask, not a single-file edit
|
|
37
|
+
request (those go straight to the relevant skill).
|
|
38
|
+
- **(b) Once per ask** — not a per-turn nag.
|
|
39
|
+
- **(c) Company residency** — run leak/confidentiality lenses locally, sanitize before any
|
|
40
|
+
cross-family dispatch, and *surface* company-sensitive findings (tracked company hosts,
|
|
41
|
+
git-history rewrites) for operator decision rather than auto-fixing them. Dogfood 2026-07-08: the
|
|
42
|
+
`local_pmh_context.md` tracked-company-hosts finding was surfaced, not auto-untracked — history
|
|
43
|
+
rewrite is the operator's call.
|
|
44
|
+
- **(d) Autonomy floor** — the compose/rank judgment is trusted at opus-tier+; below-floor, run the
|
|
45
|
+
individual checks and present raw rather than silently skipping a lens.
|
|
46
|
+
|
|
47
|
+
**Scale to the ask**: a quick "뭐 고칠 거 있어?" runs the cheap mechanical lenses (leak · split ·
|
|
48
|
+
token); "제대로 진단해줘" runs all six + harness-doctor depth.
|
|
@@ -17,6 +17,7 @@ becomes a gate other skills invoke, revisit the weight.
|
|
|
17
17
|
| 2 | **Non-deterministic borderline verdicts** — contested/borderline cases flip across runs (observed: haiku 4/4 flip; flagship models flip too — flipping is **not** a tier signal). A single draw is noise, not a measurement. | **reps ≥ 3 on any borderline/contested verdict.** A single run on a contested case is inadmissible. Report the flip pattern (STABLE vs FLIP), not just the modal verdict. |
|
|
18
18
|
| 3 | **Generic self-identity probe** — a probe any model passes ("are you working? → OK") proves nothing about *which* model answered. | **Use a discriminating probe** — one that two different models answer *differently*. A generic-pass probe is invalid. The probe is a **pattern, not a fixed string**: a probe that discriminates Opus 4.8 from Sonnet 4.6 today may both-pass a future model generation, so **re-validate the probe each model generation** (same staleness class `memory-hygiene` exists to catch). |
|
|
19
19
|
| 4 | **Serving-path / quantization variance** — the *same* display-name model served over two different backends (different quantization/infra) is a **different instrument** and yields materially different measurements. Observed: one GLM-5.2 model family gave effect-size delta **+0.21** when served via an internal NVFP4-quantized deployment vs **+0.08** via an OpenRouter relay — same model name, ~2.6× different effect (n=864, reps≥3). A correctly-pinned display name (item #1) is **necessary but not sufficient**. | **Pin *and record* the serving path** — backend host + quantization, not just the display name. Two runs are comparable only if the serving path matches; a name match across different infra is an implicit apples-to-oranges. When you cannot hold it fixed, **report the serving path as a measured variable**, not a constant. |
|
|
20
|
+
| 5 | **Injected-context contamination (blind-sim class)** — a subagent dispatched to evaluate a *modified* instruction file answers from the **auto-injected project context** (claudeMd/memory baked into its system prompt at spawn) instead of reading the target. Observed twice in one session (2026-07-17): a "blind sim" quoted section numbering that existed only in the pre-edit file, and a second sim cited trigger-table rows that had been **deleted** from the file it claimed to have read — tool-use count 0–1 in both. The measurement *looks* grounded (fluent, plausibly cited) but the instrument never touched the target. A prompt-line telling it to ignore injected context is **not sufficient** — both runs had one. | **Force mechanical grounding a stale answer cannot fake**: ① stage the target at a **neutral path** (tmp copy) the injection cannot cover; ② require **verbatim quotes** (or grep line-number output) from that path for every claim; ③ design the probe around a **content discriminator** — something present only in the new version, or *absent* from it (a deleted row cited = instant invalidation); ④ treat **tool-use count as a validity signal** — a sim that "read two files" with 0–1 tool calls is invalid regardless of answer quality. Re-run, don't argue with a contaminated result. |
|
|
20
21
|
|
|
21
22
|
## Why these are entangled (and why they matter beyond their own scope)
|
|
22
23
|
|
|
@@ -36,10 +37,16 @@ served over a different quantization/backend). The verified identity a measureme
|
|
|
36
37
|
sound once the serving path of each family is itself pinned, else "different family" silently smuggles
|
|
37
38
|
"different infra" ([[reference_measurement_serving_path_variance]]).
|
|
38
39
|
|
|
40
|
+
Item #5 (injected-context contamination) is item #3's sibling on the *input* side: #3 proves *who*
|
|
41
|
+
answered, #5 proves *what they actually read*. Both reduce to the same mechanical-anchor rule — never
|
|
42
|
+
accept a measurement's self-report (of identity or of grounding) when a discriminating mechanical
|
|
43
|
+
check is available. Its sharpest tool is the **deleted-content discriminator**: a probe target that no
|
|
44
|
+
longer contains X makes any answer citing X self-invalidating — certainty no prompt instruction buys.
|
|
45
|
+
|
|
39
46
|
## Done When
|
|
40
47
|
|
|
41
|
-
- The checklist enumerates all
|
|
42
|
-
*Check class: mandatory-pass (binary —
|
|
48
|
+
- The checklist enumerates all five failure modes, each with its countermeasure.
|
|
49
|
+
*Check class: mandatory-pass (binary — five items present, each with a countermeasure).*
|
|
43
50
|
- The probe item specifies a **discriminating** test and rejects generic probes.
|
|
44
51
|
*Check class: judged, pair: a probe that two different models both pass must FAIL this check; a
|
|
45
52
|
discriminating one must distinguish them.*
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Multi-Harness Evolution Loop — audit → persona → fix → devolution-check → settle
|
|
2
|
+
|
|
3
|
+
> Operator-forged pattern (2026-07-17). The operator ran this sequence once across three harnesses
|
|
4
|
+
> and named it afterward: *"오늘 내가 제시한 기법 자체가 fh·pmh를 진화시킬 수 있는 루프였을 거라고
|
|
5
|
+
> 생각해."* This doc is the harvest — the loop as a repeatable protocol, with its n=1 evidence and
|
|
6
|
+
> a promotion gate. It is a **composition of existing FH checks** (no-reinvention: every phase
|
|
7
|
+
> routes to an existing asset); what is net-new is the loop shape and its two doctrine points below.
|
|
8
|
+
|
|
9
|
+
## The loop (5 phases)
|
|
10
|
+
|
|
11
|
+
| Phase | What runs | Existing asset routed | Check class |
|
|
12
|
+
|---|---|---|---|
|
|
13
|
+
| **1. Structure audit** | harness-doctor lens per harness **+ a cluster lens across them** (registry freshness · track sync · cross-refs · skill-bus reachability · gate propagation · orchestration artifacts) | `/harness-doctor` · LOCAL_SKILL_REGISTRY · Field-Harness gates | mechanical + judged |
|
|
14
|
+
| **2. Persona usability audit** | beginner (cold-read, minutes-to-first-value) · main-player (daily intent-utterance test: do natural phrases reach the right skill?) · expert (frontier bar, external citations mandatory) — per harness | fh-meta persona agents (beginner / main-player / expert) | judged, adversarially paired by tier diversity |
|
|
15
|
+
| **3. Fix application** | fixer agents per repo, **verify-before-act on every claimed defect** (a false finding gets skipped with evidence, not applied); each repo's own gates honored, HITL-deferred items go to a ranked backlog instead of being forced | fixer dispatch + per-repo 4-axis / pre-commit gates | mechanical (grep-verify per fix) |
|
|
16
|
+
| **4. Devolution check** | adversarial regression audit of the fixes themselves — *"is anything now WORSE than before?"* — cross-family (codex) on public repos, same-family with an honest residency note on company repos; **iterate fix→re-verify until CONVERGED** | `auto-decorrelation` posture · codex headless · target-tier blind sim | cross-family + mechanical anchor |
|
|
17
|
+
| **5. Settle** | canonical wiki node + INDEX pointer (machine side) **+ operator-readable report pushed to where the operator actually reads** (Obsidian/iCloud mirror) + ranked M/S/R backlog of operator-decision items | wiki 규약 · sync-wiki-to-icloud | mandatory-pass (artifacts exist) |
|
|
18
|
+
|
|
19
|
+
## Two doctrine points (the net-new judgment content)
|
|
20
|
+
|
|
21
|
+
1. **Usability is a first-class diagnostic axis, not polish.** The loop's n=1 run found the same
|
|
22
|
+
root defect in all three harnesses — *the routing surface was narrower than the user's real
|
|
23
|
+
daily utterances* — and structure-only audits (phase 1 alone) had missed it for months. The
|
|
24
|
+
operator's framing is the axis: "성능이 좋아도 결국 사용하기 쉽고 직관적이어야" — a harness whose
|
|
25
|
+
speech doesn't reach is failing regardless of internal rigor. Phase 2 is therefore not optional
|
|
26
|
+
decoration on phase 1; it is the half of the diagnosis that structure scans cannot see.
|
|
27
|
+
2. **Improvement without a devolution check is half a loop.** Phase 4 exists because phase 3's
|
|
28
|
+
fixes are themselves AI-authored changes — the same optimistic-author blind spot the
|
|
29
|
+
cross-family gate guards. In the n=1 run, phase 4 caught a real regression that phases 1–3
|
|
30
|
+
produced (a README layer mis-attribution that made vague wording *wrong*), plus two S-tier
|
|
31
|
+
follow-ups in the field fixes. "다 하고 나서 기존보다 어떻게 개선되었는지, 오히려 퇴화한 부분은
|
|
32
|
+
없는지 점검" — the loop is not done at "fixes applied"; it is done at CONVERGED.
|
|
33
|
+
|
|
34
|
+
## Guards (inherited, restated for the loop)
|
|
35
|
+
|
|
36
|
+
- **Residency**: company-token repos never go to an external model family; their devolution check
|
|
37
|
+
runs same-family with the limitation recorded, not hidden.
|
|
38
|
+
- **Verify-before-act**: every audit finding is re-verified against disk before a fixer applies it
|
|
39
|
+
(n=1 run: one "typo" finding was in-house jargon — correctly skipped with source evidence).
|
|
40
|
+
- **HITL boundary**: judgment items (canonical-count decisions, dual-source direction, gate
|
|
41
|
+
loosening, architecture surgery) are never auto-applied — they land in the ranked backlog.
|
|
42
|
+
- **Autonomy floor**: compose/rank judgments at opus-tier+; the loop was designed to run
|
|
43
|
+
autonomously on an explicit operator go ("자체적으로 돌아줘"), not as a standing daemon.
|
|
44
|
+
|
|
45
|
+
## n=1 evidence (2026-07-17)
|
|
46
|
+
|
|
47
|
+
Three harnesses (FH hub + two mapped field harnesses), 21 agents total (12 audit · 2 fixer ·
|
|
48
|
+
7 verification). Outcomes: hub always-loaded footprint over-threshold closed (TARGET-rooted
|
|
49
|
+
95.8k → 79.9k chars); three repos' routing surfaces extended to cover the measured daily
|
|
50
|
+
utterances; ~10 phantom references replaced with disk-verified targets; registry brought to
|
|
51
|
+
parity (mirror-dedup for the fork, lockline for the irreversible-execution skill); one real
|
|
52
|
+
regression caught and fixed by the cross-family pass; final verdicts CONVERGED across all three
|
|
53
|
+
repos. Ranked residual backlog delivered for operator decisions.
|
|
54
|
+
|
|
55
|
+
## Promotion gate
|
|
56
|
+
|
|
57
|
+
This doc is the pattern's home at **n=1**. Per evidence-threshold build discipline, do NOT build a
|
|
58
|
+
skill or runner from it yet. Promotion path: a second full run (n=2, ideally on a different harness
|
|
59
|
+
set or triggered from a field cwd) → then decide skill-ification (`/harness-evolution-loop`
|
|
60
|
+
orchestrator skill, chamber-screened) vs staying a documented protocol. Cadence candidate
|
|
61
|
+
(quarterly, alongside the harness-doctor 30-day cadence) is also an n≥2 decision.
|
|
62
|
+
|
|
63
|
+
Related: `harness_6axis_framework.md` (axes 5–6) · `field_harness_diagnostic.md` (single-project
|
|
64
|
+
pull sibling) · `hub_compounding_loop.md` (the learning-return this loop feeds) ·
|
|
65
|
+
`measurement-integrity-checklist.md` (phase-4 instrument hygiene — the n=1 run also invalidated a
|
|
66
|
+
contaminated sim and re-ran it with a verbatim-quote protocol).
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Onboarding / Acceleration Autopilot — discover → compose → rank → install-HITL (detail)
|
|
2
|
+
|
|
3
|
+
> Always-loaded summary: `CLAUDE.md §Onboarding / Acceleration Autopilot`. This file is the detail
|
|
4
|
+
> home — the full Phase-0 branch logic (including the chamber / simulate-first honesty boundary),
|
|
5
|
+
> provenance, and guard evidence. Read when executing the autopilot on an onboarding or
|
|
6
|
+
> acceleration door.
|
|
7
|
+
|
|
8
|
+
The **install-direction twin of the Field-Harness Diagnostic**: same `compose → rank → HITL`
|
|
9
|
+
engine, but it decides *what to install/wire* instead of *what to fix*. When the operator enters an
|
|
10
|
+
onboarding / acceleration door (returning-menu ①②③: "새 프로젝트", "하네스 작성/작성해줘",
|
|
11
|
+
"이 프로젝트 가속화", "harness-ify", "accelerate this project"), don't hand-run one skill —
|
|
12
|
+
**auto-discover the local state, let the innovator center a recommend cascade, produce a ranked
|
|
13
|
+
install plan, and gate every install.**
|
|
14
|
+
|
|
15
|
+
## Flow
|
|
16
|
+
|
|
17
|
+
1. **Phase 0 — State Audit + branch (auto-discovery)**: read the target's existing
|
|
18
|
+
`.claude/agents|skills`, `CLAUDE.md`, mapped `tracks/`, **locally-connected sibling repos** (the
|
|
19
|
+
env-delta SessionStart hook already emits "N unmapped sibling repos"), and the
|
|
20
|
+
`LOCAL_SKILL_REGISTRY` + stack/language. Then **branch**: *new-build* (no prior harness) ·
|
|
21
|
+
*extend-existing* (harness present → found→extend, never fork) · *maintain* (mature harness →
|
|
22
|
+
route to the Field-Harness Diagnostic instead).
|
|
23
|
+
|
|
24
|
+
**New-build sub-branch — simulate-first (incubator doctrine)**: judge the project's character
|
|
25
|
+
before building. Clear · small · low failure-cost → build immediately (current flow). Uncertain ·
|
|
26
|
+
exploratory · failure-expensive → **flag simulate-first as an option**: doctrine says such a
|
|
27
|
+
project *should* be chamber-simulated before emit. The chamber **run orchestration is wired**
|
|
28
|
+
(`scripts/chamber_run.sh` — an intent-driven, resumable 7-step runner: budget-entry cap,
|
|
29
|
+
≥3-blind-persona gate, Emission Gate, G4 ledger auto-append; run #3 exercised it 2026-07-14).
|
|
30
|
+
But a **live one-command autonomous simulate→EMIT of a field harness is NOT yet a capability**:
|
|
31
|
+
step-4 persona dispatch is human/Claude-driven (bash cannot spawn the isolated Agents — the
|
|
32
|
+
honest muscle boundary), the EMIT terminus is HITL, and **EMIT has never fired — the ledger's
|
|
33
|
+
real runs are honest KILLs** (the chamber to date *screens*, it has not *birthed*). So today this
|
|
34
|
+
branch = a one-line HITL recommendation to run the chamber (`chamber_run.sh`), then fall back to
|
|
35
|
+
Full-Harness Mode §6 (`auto_project_mapping.md`) for the actual onboarding; the runner gates and
|
|
36
|
+
records a human-driven run — it must **not** be presented as a push-button autonomous emit. The
|
|
37
|
+
same branch applies to a **new capability of an existing harness** — the
|
|
38
|
+
incubate-in-chamber-then-transplant flow is likewise run-orchestrated but not autonomously
|
|
39
|
+
emitting today. Rationale + economics:
|
|
40
|
+
`knowledge/shared/harness-core/harness_incubator_doctrine.md §3`.
|
|
41
|
+
|
|
42
|
+
This audit-and-branch pre-step is imported from the revfactory/harness Phase-0 State Audit
|
|
43
|
+
(sister-audit 2026-07-07) — it tightens FH's found→extend reflex and is the "이미 로컬에 연결돼
|
|
44
|
+
있으면 자동 탐색" mechanism.
|
|
45
|
+
|
|
46
|
+
2. **Innovator-centered recommend**: `persona-innovator` centers the cascade (Mode I on
|
|
47
|
+
acceleration / Mode F on FH-dev), composing `plugin-recommender` (Tier 0 platform → Tier 1
|
|
48
|
+
official → Tier 2/3) + `cross-ecosystem-synergy-detection` (locally-connected skills worth
|
|
49
|
+
wiring) + inferred technical level (conversation-cue read, also imported from revfactory) to
|
|
50
|
+
shape *what* and *how much*.
|
|
51
|
+
|
|
52
|
+
3. **Ranked install plan**: one list, `M`/`S`/`R`, each item = *what · why · source (Tier 0
|
|
53
|
+
built-in / Tier 1 official / local sibling / FH scaffold) · exact install command*.
|
|
54
|
+
No-reinvention: an official/built-in that covers the need ranks above a net-new scaffold.
|
|
55
|
+
|
|
56
|
+
4. **Install — HITL, non-overwriting**: per-item approval; **never clobber an existing `.claude/`**
|
|
57
|
+
(propose merge/skip if present — this is FH's edge over revfactory's post-plan auto-write and
|
|
58
|
+
harness-100's raw `cp`). Any generated/installed FH asset runs the **4-axis gate**; a field
|
|
59
|
+
scaffold runs `asset-placement-gate` + `steel-quench`. **"끝까지 해줘 / 자율로 완주" →
|
|
60
|
+
full-autonomy**: run the whole plan under the `/goal-quench` budget+quality gate (token cost
|
|
61
|
+
accepted by the operator), still non-overwriting and still gated per asset — autonomy removes
|
|
62
|
+
the per-item *prompt*, never the *gate*.
|
|
63
|
+
|
|
64
|
+
## Guards
|
|
65
|
+
|
|
66
|
+
- **(a) Non-overwriting is inviolable** — the one thing both revfactory surfaces get wrong; FH
|
|
67
|
+
proposes merge, never clobbers.
|
|
68
|
+
- **(b) No-reinvention** — Tier 0/1 first, scaffold only what adds governance.
|
|
69
|
+
- **(c) Company residency** — discovery of a company sibling repo surfaces it, does not
|
|
70
|
+
auto-map/leak it; promoted to a machine field (`residency` on the skill registry,
|
|
71
|
+
`fh_detail_protocols.md §1-c`) so any derived recommendation naming a `company` /
|
|
72
|
+
`operator-private` entry lands only in gitignored `tracks/_meta/` or the private companion store,
|
|
73
|
+
never a tracked public file (chamber run #7, 2026-07-14 — the guard was prose-only and the field
|
|
74
|
+
didn't exist).
|
|
75
|
+
- **(d) Autonomy floor** — the discover/rank judgment is trusted at opus-tier+; below-floor,
|
|
76
|
+
present the raw recommend and ask.
|
|
77
|
+
- **(e) Once per door-entry** — not a per-turn nag.
|
|
78
|
+
|
|
79
|
+
This is the door ③ (accelerate; a *diagnose* intent on the same door routes to the Field-Harness
|
|
80
|
+
Diagnostic instead) engine and the new-project/harness-write path made autonomous —
|
|
81
|
+
the operator asks once and the harness discovers, ranks, and (on request) installs everything worth
|
|
82
|
+
wiring.
|