create-byan-agent 2.49.0 → 2.52.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/CHANGELOG.md +78 -0
- package/install/package.json +1 -1
- package/install/templates/.claude/hooks/agent-gate-check.js +14 -2
- package/install/templates/.claude/hooks/codex-delegate-guard.js +137 -0
- package/install/templates/.claude/hooks/inject-voice-anchor.js +25 -0
- package/install/templates/.claude/hooks/lib/agent-gate.js +95 -5
- package/install/templates/.claude/hooks/lib/autodelegate-decision.js +11 -13
- package/install/templates/.claude/hooks/lib/codex-delegate-gate.js +130 -0
- package/install/templates/.claude/hooks/lib/fact-check-core.js +34 -2
- package/install/templates/.claude/hooks/lib/voice-conformance.js +97 -0
- package/install/templates/.claude/hooks/strict-scope-guard.js +71 -14
- package/install/templates/.claude/hooks/voice-conformance-check.js +53 -0
- package/install/templates/.claude/rules/native-workflows.md +17 -7
- package/install/templates/.claude/settings.json +8 -0
- package/install/templates/.claude/skills/byan-byan/SKILL.md +16 -10
- package/install/templates/_byan/mcp/byan-mcp-server/bin/byan-armament-report.js +82 -0
- package/install/templates/_byan/mcp/byan-mcp-server/lib/armament-report.js +80 -0
- package/install/templates/_byan/mcp/byan-mcp-server/lib/dispatch-router.js +48 -30
- package/install/templates/_byan/mcp/byan-mcp-server/lib/native-tiers.js +25 -6
- package/install/templates/_byan/mcp/byan-mcp-server/lib/tier-script.js +8 -4
- package/install/templates/_byan/mcp/byan-mcp-server/lib/workflows-lint.js +6 -2
- package/install/templates/_byan/mcp/byan-mcp-server/skill-bundles-manifest.json +1 -1
- package/install/templates/dist/skill-bundles/byan-byan.zip +0 -0
- package/install/templates/docs/codex-auto-delegation.md +51 -25
- package/install/templates/docs/intelligent-dispatch.md +9 -5
- package/install/templates/docs/native-workflows-contract.md +9 -4
- package/package.json +1 -1
|
@@ -2,26 +2,27 @@
|
|
|
2
2
|
// given a task's NATURE and COMPLEXITY, decide which RUNTIME runs it (Codex or
|
|
3
3
|
// Claude), which MODEL, and (Codex only) which reasoning EFFORT.
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// needs — runtime selection and Codex reasoning effort — on top of it.
|
|
5
|
+
// The Claude-side model is a FOUR-rung complexity ladder (v3):
|
|
6
|
+
// haiku -> sonnet -> opus -> fable, fable being the last-resort top-reasoning
|
|
7
|
+
// model reserved for EXTREME complexity (~2x Opus price). See
|
|
8
|
+
// claudeModelForComplexity. This module adds the two NEW axes the intelligent
|
|
9
|
+
// dispatch needs — runtime selection and Codex reasoning effort — on top of it.
|
|
10
10
|
//
|
|
11
11
|
// Routing table is the cross-checked result (5 independent sources, see
|
|
12
12
|
// docs / CHANGELOG): Codex wins autonomous execution, shell/CI/DevOps, deploy,
|
|
13
13
|
// browser/computer use ; Claude wins architecture, refactor-at-repo-scale,
|
|
14
14
|
// quality, planning, and ALL verification. Two hard red lines are enforced here,
|
|
15
15
|
// not left to the caller:
|
|
16
|
-
// 1. Fable is NEVER
|
|
16
|
+
// 1. Fable is NEVER routed to CODEX (Codex runs the ChatGPT-subscription model,
|
|
17
|
+
// it cannot run a Claude model at all). On the CLAUDE side Fable IS allowed,
|
|
18
|
+
// but only at the extreme rung (v3 product reversal — the old blanket ban is
|
|
19
|
+
// lifted). assertNoFable therefore guards the Codex path only.
|
|
17
20
|
// 2. Verification is NEVER routed to Codex (a runtime must not grade its own
|
|
18
21
|
// work ; the reviewer stays on Claude).
|
|
19
22
|
//
|
|
20
23
|
// Pure: no I/O, no clock, deterministic. The Codex transport (F2) and the
|
|
21
24
|
// orchestrating loop (F4) consume this; they never re-decide routing.
|
|
22
25
|
|
|
23
|
-
import { TIER_MODEL } from './native-tiers.js';
|
|
24
|
-
|
|
25
26
|
export const RUNTIMES = Object.freeze({ CODEX: 'codex', CLAUDE: 'claude' });
|
|
26
27
|
|
|
27
28
|
// Codex runs on the ChatGPT-subscription entitled model. Kept as a named constant
|
|
@@ -30,8 +31,10 @@ export const CODEX_MODEL = 'gpt-5.4';
|
|
|
30
31
|
|
|
31
32
|
export const EFFORTS = Object.freeze({ LOW: 'low', MEDIUM: 'medium', HIGH: 'high' });
|
|
32
33
|
|
|
33
|
-
// Models we refuse to emit
|
|
34
|
-
//
|
|
34
|
+
// Models we refuse to emit on the CODEX path. Codex runs the ChatGPT-subscription
|
|
35
|
+
// model and cannot run a Claude model — Fable on Codex is a category error, so the
|
|
36
|
+
// guard makes that refusal mechanical. (On the CLAUDE path Fable is allowed at the
|
|
37
|
+
// extreme rung — see claudeModelForComplexity ; this list does not gate it.)
|
|
35
38
|
export const FORBIDDEN_MODELS = Object.freeze(['fable', 'claude-fable-5']);
|
|
36
39
|
|
|
37
40
|
// Task natures that route to Codex. Everything NOT here (and not a verification
|
|
@@ -58,12 +61,14 @@ function matchesAny(text, list) {
|
|
|
58
61
|
return list.some((kw) => text.includes(kw));
|
|
59
62
|
}
|
|
60
63
|
|
|
61
|
-
// assertNoFable(model) — mechanical enforcement of red line #1
|
|
62
|
-
// than silently substituting, so a Fable request is a loud
|
|
64
|
+
// assertNoFable(model) — mechanical enforcement of red line #1 on the CODEX path.
|
|
65
|
+
// Throws rather than silently substituting, so a Fable-on-Codex request is a loud
|
|
66
|
+
// failure at the source (Codex cannot run a Claude model). It does NOT gate the
|
|
67
|
+
// Claude path, which may legitimately emit Fable at the extreme rung.
|
|
63
68
|
export function assertNoFable(model) {
|
|
64
69
|
const m = normalize(model);
|
|
65
70
|
if (FORBIDDEN_MODELS.some((f) => m.includes(f))) {
|
|
66
|
-
throw new Error(`dispatch-router: forbidden model "${model}" (
|
|
71
|
+
throw new Error(`dispatch-router: forbidden model "${model}" on the Codex path (Codex cannot run a Claude model)`);
|
|
67
72
|
}
|
|
68
73
|
return model;
|
|
69
74
|
}
|
|
@@ -106,28 +111,41 @@ export function effortForComplexity(complexity) {
|
|
|
106
111
|
return complexityBucket(complexity);
|
|
107
112
|
}
|
|
108
113
|
|
|
109
|
-
// claudeModelForComplexity(complexity) ->
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
//
|
|
114
|
+
// claudeModelForComplexity(complexity) -> the Claude-side model RECOMMENDATION on
|
|
115
|
+
// a FOUR-rung complexity ladder (v3): haiku -> sonnet -> opus -> fable.
|
|
116
|
+
// - < 34 : haiku (trivial / low)
|
|
117
|
+
// - < 67 : sonnet (medium)
|
|
118
|
+
// - < 90 : opus (high — the default frontier)
|
|
119
|
+
// - >= 90 : fable (extreme complexity, LAST RESORT)
|
|
120
|
+
// Fable is the top-reasoning model : strongest on the intelligence index but
|
|
121
|
+
// ~2x the price of Opus, so it is reserved for the extreme rung only. This is a
|
|
122
|
+
// per-task RECOMMENDATION consumed by the dispatch orchestrator / skill — NOT a
|
|
123
|
+
// live switch of the running session model (Claude Code exposes no such switch).
|
|
124
|
+
// Labels map too (trivial/low/medium/high/extreme). The old blanket "never Fable"
|
|
125
|
+
// red line is lifted on the CLAUDE side (deliberate v3 product reversal); it still
|
|
126
|
+
// holds on the CODEX side (see dispatch() + assertNoFable + codex-bridge).
|
|
115
127
|
export function claudeModelForComplexity(complexity) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
128
|
+
if (typeof complexity === 'number' && Number.isFinite(complexity)) {
|
|
129
|
+
if (complexity < 34) return 'haiku';
|
|
130
|
+
if (complexity < 67) return 'sonnet';
|
|
131
|
+
if (complexity < 90) return 'opus';
|
|
132
|
+
return 'fable';
|
|
133
|
+
}
|
|
134
|
+
const c = normalize(complexity);
|
|
135
|
+
if (['trivial', 'low', 'simple', 'easy'].includes(c)) return 'haiku';
|
|
136
|
+
if (['medium', 'moderate'].includes(c)) return 'sonnet';
|
|
137
|
+
if (['extreme', 'frontier', 'max'].includes(c)) return 'fable';
|
|
138
|
+
if (['high', 'hard', 'complex'].includes(c)) return 'opus';
|
|
139
|
+
return 'sonnet'; // unknown -> a safe middle
|
|
123
140
|
}
|
|
124
141
|
|
|
125
142
|
// dispatch({ nature, complexity }) -> the full routing decision:
|
|
126
143
|
// { runtime, model, effort, reasoning }
|
|
127
144
|
// - Codex: model = CODEX_MODEL, effort = complexity bucket (the real knob).
|
|
128
|
-
// - Claude: model = haiku/sonnet/
|
|
129
|
-
// effort knob — its "effort" IS the model tier).
|
|
130
|
-
//
|
|
145
|
+
// - Claude: model = haiku/sonnet/opus/fable on the complexity ladder, effort =
|
|
146
|
+
// null (Claude has no effort knob — its "effort" IS the model tier).
|
|
147
|
+
// The red lines are enforced here regardless of caller input: Codex keeps its
|
|
148
|
+
// no-Fable guard ; verification stays on Claude.
|
|
131
149
|
export function dispatch({ nature, complexity } = {}) {
|
|
132
150
|
const runtime = routeRuntime(nature);
|
|
133
151
|
if (runtime === RUNTIMES.CODEX) {
|
|
@@ -140,7 +158,7 @@ export function dispatch({ nature, complexity } = {}) {
|
|
|
140
158
|
}
|
|
141
159
|
return {
|
|
142
160
|
runtime,
|
|
143
|
-
model: claudeModelForComplexity(complexity), //
|
|
161
|
+
model: claudeModelForComplexity(complexity), // haiku/sonnet/opus/fable by complexity
|
|
144
162
|
effort: null, // Claude effort = model tier, no separate knob
|
|
145
163
|
reasoning: isVerification(nature)
|
|
146
164
|
? 'verification stays on Claude (red line: a runtime never grades its own work)'
|
|
@@ -40,6 +40,17 @@ export const TIERS = Object.freeze({ CHEAP: 'cheap', BALANCED: 'balanced', DEEP:
|
|
|
40
40
|
// flags every script literal that drifts from it, so the fan-out stays bounded.
|
|
41
41
|
export const TIER_MODEL = Object.freeze({ cheap: 'haiku', balanced: 'sonnet', deep: null });
|
|
42
42
|
|
|
43
|
+
// UP-TIER models (v3). The auto-routing above never pins UP (the default stays
|
|
44
|
+
// cost-safe: deep = inherit the session model). But an author MAY deliberately
|
|
45
|
+
// raise a genuinely complex leaf ABOVE the inherited tier — 'opus' for a hard
|
|
46
|
+
// leaf, 'fable' as the last-resort top-reasoning model for extreme complexity
|
|
47
|
+
// (~2x Opus price). This is the workflow-leaf mirror of the dispatch-router
|
|
48
|
+
// complexity ladder (haiku -> sonnet -> opus -> fable). Up-tier pins are an
|
|
49
|
+
// explicit authoring choice: the anti-DOWNGRADE floor does not apply upward, so
|
|
50
|
+
// the linter ALLOWS them (they cost more, they never regress quality). The old
|
|
51
|
+
// blanket "never pin up / never Fable" ban on leaves is lifted here.
|
|
52
|
+
export const UP_TIER_MODELS = Object.freeze(['opus', 'fable']);
|
|
53
|
+
|
|
43
54
|
// Leaf task-type taxonomy. EXPLORATION (cheap) and MECHANICAL + ANALYSIS
|
|
44
55
|
// (balanced) are the downgrade classes; VERIFICATION and IMPLEMENTATION stay
|
|
45
56
|
// protected (deep, inherit the session model). MECHANICAL is verification whose
|
|
@@ -130,18 +141,26 @@ export function modelForLeaf(leaf) {
|
|
|
130
141
|
return TIER_MODEL[tierFor(classifyLeaf(leaf))];
|
|
131
142
|
}
|
|
132
143
|
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
|
|
144
|
+
// isUpTierModel(modelId) -> true if modelId pins a leaf ABOVE the inherited tier
|
|
145
|
+
// (opus or fable). An explicit, allowed authoring choice for a genuinely complex
|
|
146
|
+
// leaf (v3): the anti-downgrade floor does not apply upward.
|
|
147
|
+
export function isUpTierModel(modelId) {
|
|
148
|
+
return !!modelId && UP_TIER_MODELS.includes(modelId);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// isKnownTierModel(modelId) -> true if modelId is a recognised tier literal:
|
|
152
|
+
// a downgrade model (cheap/balanced = haiku/sonnet) OR an up-tier model
|
|
153
|
+
// (opus/fable). Used by the linter to reject an opts.model literal that is not in
|
|
154
|
+
// the vocabulary at all. null/'' are not "known" (deep = omission, not a literal).
|
|
137
155
|
export function isKnownTierModel(modelId) {
|
|
138
156
|
if (!modelId) return false;
|
|
139
|
-
return Object.values(TIER_MODEL).filter(Boolean).includes(modelId);
|
|
157
|
+
return Object.values(TIER_MODEL).filter(Boolean).includes(modelId) || isUpTierModel(modelId);
|
|
140
158
|
}
|
|
141
159
|
|
|
142
160
|
// isDowngradeModel(modelId) -> true if modelId pins a leaf BELOW the inherited
|
|
143
161
|
// tier (cheap or balanced). The linter's anti-downgrade rule uses this: a
|
|
144
|
-
// protected leaf must never carry a downgrade model.
|
|
162
|
+
// protected leaf must never carry a downgrade model. Up-tier models return false
|
|
163
|
+
// (they are not downgrades — see isUpTierModel).
|
|
145
164
|
export function isDowngradeModel(modelId) {
|
|
146
165
|
return modelId === TIER_MODEL.cheap || modelId === TIER_MODEL.balanced;
|
|
147
166
|
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
// passes — the gate forces a decision, it does not trap the turn.
|
|
16
16
|
|
|
17
17
|
import crypto from 'node:crypto';
|
|
18
|
-
import { classifyLeaf, tierFor, TIER_MODEL, TIERS, LEAF_TYPES } from './native-tiers.js';
|
|
18
|
+
import { classifyLeaf, tierFor, TIER_MODEL, TIERS, LEAF_TYPES, isUpTierModel } from './native-tiers.js';
|
|
19
19
|
import { stripComments, extractLabelledLeaves } from './workflows-lint.js';
|
|
20
20
|
|
|
21
21
|
// Acknowledgment marker, raw-text (comment form survives comment-stripping
|
|
@@ -26,15 +26,19 @@ export const ACK_RE = /BYAN-TIER:\s*reviewed\b/;
|
|
|
26
26
|
|
|
27
27
|
function verdictFor(cls, model) {
|
|
28
28
|
const expected = TIER_MODEL[tierFor(cls)]; // 'haiku' | 'sonnet' | null (inherit)
|
|
29
|
+
// Up-tier pins (opus/fable) are always allowed (v3): the author deliberately
|
|
30
|
+
// raises a complex leaf ABOVE the inherited tier. The anti-DOWNGRADE floor does
|
|
31
|
+
// not apply upward — it costs more but never regresses quality.
|
|
32
|
+
if (isUpTierModel(model)) return 'ok';
|
|
29
33
|
if (expected === null) {
|
|
30
|
-
// Protected class:
|
|
34
|
+
// Protected class: a downgrade pin is still wrong (up-tier handled above).
|
|
31
35
|
return model === null ? 'ok' : 'violation';
|
|
32
36
|
}
|
|
33
37
|
if (model === null) return 'missing-tier';
|
|
34
38
|
if (model === expected) return 'ok';
|
|
35
39
|
// Exploration may ride ABOVE its floor (sonnet on a cheap leaf wastes a
|
|
36
|
-
// little, breaks nothing). Anything else — haiku on mech
|
|
37
|
-
//
|
|
40
|
+
// little, breaks nothing). Anything else — haiku on mech- — is below a
|
|
41
|
+
// declared tier.
|
|
38
42
|
if (cls === LEAF_TYPES.EXPLORATION && model === TIER_MODEL[TIERS.BALANCED]) return 'ok';
|
|
39
43
|
return 'violation';
|
|
40
44
|
}
|
|
@@ -153,10 +153,15 @@ export function modelRoutingViolations(src) {
|
|
|
153
153
|
if (!isKnownTierModel(model)) {
|
|
154
154
|
out.push({
|
|
155
155
|
id: 'unknown-tier-model',
|
|
156
|
-
msg: `opts.model '${model}' is not a
|
|
156
|
+
msg: `opts.model '${model}' is not a recognised tier (downgrade: haiku/sonnet ; up-tier: opus/fable); omit opts.model to inherit the session model on deep leaves`,
|
|
157
157
|
});
|
|
158
158
|
continue;
|
|
159
159
|
}
|
|
160
|
+
// Up-tier pins (opus/fable) are an allowed explicit authoring choice: they
|
|
161
|
+
// raise a complex leaf ABOVE the inherited tier. The anti-downgrade floor does
|
|
162
|
+
// not apply upward, and no label is required (v3). Only DOWNGRADES are gated
|
|
163
|
+
// below.
|
|
164
|
+
if (!isDowngradeModel(model)) continue;
|
|
160
165
|
const label = nearestLabelBefore(code, m.index);
|
|
161
166
|
if (!label) {
|
|
162
167
|
out.push({
|
|
@@ -165,7 +170,6 @@ export function modelRoutingViolations(src) {
|
|
|
165
170
|
});
|
|
166
171
|
continue;
|
|
167
172
|
}
|
|
168
|
-
if (!isDowngradeModel(model)) continue;
|
|
169
173
|
// Per-class floor: exploration accepts any downgrade tier (haiku or sonnet,
|
|
170
174
|
// both at-or-above its cheap floor); a mech- leaf accepts exactly the
|
|
171
175
|
// balanced tier (haiku would sit BELOW the tier its label declares); every
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"name": "byan-byan",
|
|
95
95
|
"module": "core",
|
|
96
96
|
"tier": "connector-bound",
|
|
97
|
-
"sourceHash": "
|
|
97
|
+
"sourceHash": "fcea02854887283c8ff1d4b7d09778d62fc7ce52959a00577e87091e7c31f991"
|
|
98
98
|
},
|
|
99
99
|
"byan-byan-v2": {
|
|
100
100
|
"name": "byan-byan-v2",
|
|
Binary file
|
|
@@ -10,11 +10,23 @@ work crosses the line.
|
|
|
10
10
|
## What it does
|
|
11
11
|
|
|
12
12
|
Every turn, a `UserPromptSubmit` hook estimates how much of the Claude 5h window
|
|
13
|
-
you have burned
|
|
14
|
-
|
|
15
|
-
injects a one-line note directing you to hand it to Codex via
|
|
13
|
+
you have burned. When you are over the pressure threshold (default **75%**), BYAN
|
|
14
|
+
injects a one-line note directing you to hand the delegable work to Codex via
|
|
16
15
|
`codex:codex-rescue --model gpt-5.4`. You still verify Codex's output before commit.
|
|
17
16
|
|
|
17
|
+
**v3 — pressure-only, and the router decides Codex vs Claude.** Two deliberate
|
|
18
|
+
changes from v2:
|
|
19
|
+
|
|
20
|
+
- **Pressure is the only auto-trigger (F1).** A delegable-looking task no longer
|
|
21
|
+
proposes Codex on its own. Delegating to the subscription Codex (which trails
|
|
22
|
+
Claude on quality — see below) is worth it to SPARE the Claude budget, not per
|
|
23
|
+
coding task. So off-pressure, code runs on Claude with no nag.
|
|
24
|
+
- **The guard obeys the router (F2).** WHERE a task runs (Codex vs Claude) is the
|
|
25
|
+
`dispatch-router`'s call, by task nature: execution / shell / deploy / devops /
|
|
26
|
+
browser -> Codex ; architecture / refactor / quality / planning + all
|
|
27
|
+
verification -> Claude. The delegation guard only bites for a task the router
|
|
28
|
+
itself routes to Codex.
|
|
29
|
+
|
|
18
30
|
**Both engines must be present.** The lane only arms — and the note only fires —
|
|
19
31
|
when TWO conditions hold together: the yanstaller option wrote
|
|
20
32
|
`_byan/_config/autodelegate.json` with `enabled:true`, AND Codex is actually
|
|
@@ -23,25 +35,38 @@ linked on this machine (`~/.codex/auth.json` from `codex login`, or
|
|
|
23
35
|
This is the runtime `codexLinked()` gate in `codex-autodelegate.js`, the mirror of
|
|
24
36
|
the installer's arm-time `codexAuthState` check.
|
|
25
37
|
|
|
26
|
-
**Armed = directive,
|
|
27
|
-
armed (both engines present), it reads as a directive:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
**Armed = directive, enforced by a guard (option B + v3).** Because the note only
|
|
39
|
+
appears when the lane is armed (both engines present), it reads as a directive:
|
|
40
|
+
delegate the delegable part. And it is not just prose — the `codex-delegate-guard`
|
|
41
|
+
PreToolUse hook DENIES a **code** Write/Edit that skipped Codex, but ONLY when all
|
|
42
|
+
of these hold together (v3): the lane is armed, the ROUTER routes this task to
|
|
43
|
+
Codex, you are under budget PRESSURE, and Codex is available. Miss any one and it
|
|
44
|
+
allows. The two per-turn ways to stay on Claude are (1) Codex unavailable
|
|
45
|
+
(auto-detected via `codex --version`), or (2) the USER opted out — the
|
|
46
|
+
`.byan-codex-autodelegate/off` switch, or a phrase like "reste sur Claude" /
|
|
47
|
+
"sans codex" in the request. The "small script / latency / I verify anyway"
|
|
48
|
+
excuse is explicitly NOT valid: that was the self-dodge (a
|
|
49
|
+
`// BYAN-DELEGATE: reviewed` marker BYAN wrote itself) that option B removed. BYAN
|
|
50
|
+
can no longer self-grant a bypass; only the human can.
|
|
51
|
+
|
|
52
|
+
The deny is a wall against BYAN's silent self-dodge, not a trap for the user: the
|
|
53
|
+
human keeps the escape switch and the opt-out phrase, a doc/config write (not
|
|
54
|
+
code) does not trip it, and off-pressure OR router-to-Claude nothing bites at all.
|
|
55
|
+
Honest ceiling: Claude Code has no control point before a response is shown, so
|
|
56
|
+
the *choice* to delegate stays model-driven; the guard acts one step later, at the
|
|
57
|
+
Write, denying the skip.
|
|
58
|
+
|
|
59
|
+
The auto-trigger, plus one opt-in:
|
|
60
|
+
|
|
61
|
+
1. **Pressure (F1, the only auto-trigger)** — estimated Claude 5h usage
|
|
62
|
+
`>= threshold` (default **75%**) -> propose offloading **everything** delegable
|
|
63
|
+
this session. Needs a `budget` gauge; without one, pressure stays uncomputed
|
|
64
|
+
and nothing is proposed (documented, non-blocking).
|
|
65
|
+
2. **Perf** (opt-in, off by default) — a configurable forces table says Codex is
|
|
41
66
|
reputed stronger for this kind of task. See "Perf routing" below.
|
|
42
67
|
|
|
43
68
|
**The red line** (held): only delegable natures are proposed. Judgment,
|
|
44
|
-
analysis, soul and verification stay on Claude.
|
|
69
|
+
analysis, soul and verification stay on Claude — and the router keeps them there.
|
|
45
70
|
|
|
46
71
|
## Enable it
|
|
47
72
|
|
|
@@ -97,8 +122,8 @@ pins `--model gpt-5.4`. See `src/loadbalancer/providers/codex-provider.js`
|
|
|
97
122
|
| Key | Default | Meaning |
|
|
98
123
|
|-----|---------|---------|
|
|
99
124
|
| `enabled` | `true` (once written) | Master switch. Delete the file or set `false` to disarm. |
|
|
100
|
-
| `threshold` | `
|
|
101
|
-
| `budget` | `null` | Your plan's rough token ceiling for the 5h window. Without it, `pct` is null and
|
|
125
|
+
| `threshold` | `75` | Pressure percentage that flips to "offload everything delegable" (v3: aligned with the guard's pressure floor). |
|
|
126
|
+
| `budget` | `null` | Your plan's rough token ceiling for the 5h window. Without it, `pct` is null, pressure stays uncomputed, and nothing is auto-proposed (v3 pressure-only; see caveat). |
|
|
102
127
|
| `invocation` | `codex:codex-rescue --model gpt-5.4` | What the nudge tells BYAN to run. |
|
|
103
128
|
| `perfRouting` | `false` | Enable the perf trigger. |
|
|
104
129
|
| `perfForces` | `[]` | The forces table (see below). |
|
|
@@ -114,11 +139,12 @@ without editing the config; remove it to re-enable.
|
|
|
114
139
|
your local transcripts (`~/.claude/projects/*/*.jsonl`) over the rolling 5h
|
|
115
140
|
window, weighting cache reads at 0.1 (they are billed roughly a tenth and
|
|
116
141
|
repeat every turn). It is proportional, not exact — and `pct` is only computed
|
|
117
|
-
when you set a `budget`. Without a budget,
|
|
118
|
-
trigger
|
|
142
|
+
when you set a `budget`. Without a budget, pressure stays uncomputed and the
|
|
143
|
+
auto-trigger stays silent (v3 pressure-only).
|
|
119
144
|
- **`~/.claude` is a native accelerator, not a source of truth** (PORTABLE-3).
|
|
120
|
-
If it is absent the estimator degrades to `pct: null
|
|
121
|
-
|
|
145
|
+
If it is absent the estimator degrades to `pct: null`, so pressure cannot be
|
|
146
|
+
computed and the auto-trigger stays silent. Code still runs on Claude normally;
|
|
147
|
+
the feature keeps working, it just does not auto-propose Codex.
|
|
122
148
|
- **Perf routing is a heuristic below the L2 floor.** "Model X is better at task
|
|
123
149
|
Y" is a performance claim; BYAN's fact-check floor for performance is L2 (a
|
|
124
150
|
reproducible benchmark). A community arena such as designarena.ai is weaker
|
|
@@ -22,17 +22,21 @@ task-type signal is used, which is stable across sources.
|
|
|
22
22
|
|
|
23
23
|
## Model and effort by complexity
|
|
24
24
|
|
|
25
|
-
- **Claude side**: complexity picks the model
|
|
26
|
-
low -> haiku, medium -> sonnet, high ->
|
|
27
|
-
is no separate effort knob on Claude: the model tier IS
|
|
28
|
-
|
|
25
|
+
- **Claude side**: complexity picks the model on a four-rung ladder (v3) —
|
|
26
|
+
low -> haiku, medium -> sonnet, high -> opus, extreme -> fable (last resort,
|
|
27
|
+
~2x Opus price). There is no separate effort knob on Claude: the model tier IS
|
|
28
|
+
the effort. This is a per-task RECOMMENDATION, not a live switch of the running
|
|
29
|
+
session model (Claude Code exposes no such switch).
|
|
29
30
|
- **Codex side**: fixed model (`gpt-5.4`, the entitled subscription model) with a
|
|
30
31
|
real reasoning-effort knob — low / medium / high — scaled to complexity via
|
|
31
32
|
`codex exec -c model_reasoning_effort=...`.
|
|
32
33
|
|
|
33
34
|
## The three red lines (enforced in code, not left to the caller)
|
|
34
35
|
|
|
35
|
-
1. **No Fable.** `assertNoFable` throws rather than emit a Fable model
|
|
36
|
+
1. **No Fable on Codex.** `assertNoFable` throws rather than emit a Fable model on
|
|
37
|
+
the Codex path (Codex runs the ChatGPT-subscription model and cannot run a
|
|
38
|
+
Claude model). On the Claude path Fable IS allowed, but only at the extreme
|
|
39
|
+
complexity rung (v3 product reversal — the old blanket ban is lifted).
|
|
36
40
|
2. **Verification stays on Claude.** The router forces a verification nature to
|
|
37
41
|
Claude ; the orchestrator re-asserts it and throws if it ever regresses.
|
|
38
42
|
3. **Codex does not write.** Codex runs read-only and returns a unified diff ;
|
|
@@ -95,16 +95,21 @@ tier vocabulary, the leaf classifier, and the model map.
|
|
|
95
95
|
|
|
96
96
|
| Tier | `opts.model` | Used for |
|
|
97
97
|
|------|--------------|----------|
|
|
98
|
+
| `up-tier` | `opus` / `fable` | EXPLICIT authoring choice: raise a genuinely complex leaf above the inherited tier (opus for hard, fable for extreme, last resort) |
|
|
98
99
|
| `deep` | **omitted** (inherit the session model) | implement, verify, analysis — the default |
|
|
99
100
|
| `balanced` | `sonnet` | MECHANICAL verification, opt-in only via the `mech-` label prefix |
|
|
100
101
|
| `cheap` | `haiku` | a pure exploration leaf: read / load / parse / detect |
|
|
101
102
|
|
|
102
103
|
Three hard rules:
|
|
103
104
|
|
|
104
|
-
- **No pin-up
|
|
105
|
-
leaf
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
- **No AUTO pin-up, but an explicit up-tier is allowed (v3).** Auto-routing does
|
|
106
|
+
not raise a leaf above the inherited tier: `deep` is an omission, letting a leaf
|
|
107
|
+
inherit whatever the session runs (Opus by default, Sonnet if the user chose
|
|
108
|
+
Sonnet). An author MAY still deliberately pin `opus` or `fable` on a genuinely
|
|
109
|
+
complex leaf — the workflow-leaf mirror of the dispatch-router complexity ladder
|
|
110
|
+
(haiku -> sonnet -> opus -> fable). The anti-downgrade floor does not apply
|
|
111
|
+
upward, so the linter allows an up-tier pin; the old blanket "no pin-up / no
|
|
112
|
+
Fable" ban is lifted.
|
|
108
113
|
- **Only exploration and mech- downgrade.** A leaf is pinned to `cheap` only
|
|
109
114
|
when it is unambiguous read/extract work. `classifyLeaf` keys off the LABEL
|
|
110
115
|
(the prompt is too noisy — an exploration leaf often says "report what you
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-byan-agent",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.52.0",
|
|
4
4
|
"description": "BYAN v2.8 - Intelligent AI agent creator with ELO trust system + scientific fact-check + Hermes universal dispatcher + native Claude Code integration (hooks, skills, MCP server). Multi-platform (Claude Code, Codex). Merise Agile + TDD + 71 Mantras. ~54% LLM cost savings.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|