@azure-id/orc 0.56.1 → 1.0.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 +2367 -2218
- package/README-id.md +49 -107
- package/README.md +45 -133
- package/bin/build-agents.js +18 -11
- package/bin/cli.js +33060 -29855
- package/bin/onboarding-content.js +0 -3
- package/bin/test-run.js +491 -0
- package/bin/verify-contracts.js +4256 -3277
- package/bin/verify-package.js +563 -498
- package/bin/webui/api.js +1186 -1163
- package/bin/webui/app.html +9 -0
- package/bin/webui/css/06-responsive.css +120 -108
- package/bin/webui/css/panels/extra.css +29 -0
- package/bin/webui/css/panels/lanes.css +134 -0
- package/bin/webui/css/panels/settings.css +79 -3
- package/bin/webui/fixtures/extra.js +2036 -1934
- package/bin/webui/fixtures/flow.js +2 -2
- package/bin/webui/fixtures/index.js +503 -486
- package/bin/webui/fixtures/lanes.js +218 -0
- package/bin/webui/fixtures/settings.js +261 -34
- package/bin/webui/fixtures/stats.js +3 -3
- package/bin/webui/i18n/TERMS.md +135 -134
- package/bin/webui/i18n/en/extra.json +345 -313
- package/bin/webui/i18n/en/lanes.json +29 -0
- package/bin/webui/i18n/en/nav.json +1 -0
- package/bin/webui/i18n/en/overview.json +2 -0
- package/bin/webui/i18n/en/settings.json +16 -5
- package/bin/webui/i18n/id/extra.json +345 -313
- package/bin/webui/i18n/id/lanes.json +29 -0
- package/bin/webui/i18n/id/nav.json +1 -0
- package/bin/webui/i18n/id/overview.json +2 -0
- package/bin/webui/i18n/id/settings.json +15 -4
- package/bin/webui/js/01-i18n.js +1 -0
- package/bin/webui/js/panels/extra.js +3199 -3011
- package/bin/webui/js/panels/lanes.js +259 -0
- package/bin/webui/js/panels/overview.js +10 -0
- package/bin/webui/js/panels/settings.js +149 -3
- package/package.json +39 -39
- package/templates/agents/MODEL-MAPPING.md +23 -35
- package/templates/agents/orc-executor-opus-4-7-high.md +1 -1
- package/templates/agents/orc-executor-opus-4-7-med.md +1 -1
- package/templates/agents/orc-executor-opus-4-8-high.md +1 -1
- package/templates/agents/orc-executor-opus-5-high.md +1 -1
- package/templates/agents/orc-executor-opus-5-low.md +1 -1
- package/templates/agents/orc-executor-opus-5-med.md +1 -1
- package/templates/agents/orc-retro-opus-5-med.md +73 -73
- package/templates/agents/orc-retro-sonnet-5-high.md +72 -72
- package/templates/agents/orc-trace-writer-haiku-4-5.md +107 -107
- package/templates/commands/orc-route.md +1 -1
- package/templates/commands/orc.md +1 -1
- package/templates/skills/_shared/README.md +7 -3
- package/templates/skills/_shared/config-precedence.md +198 -0
- package/templates/skills/_shared/drift-recovery.md +1 -1
- package/templates/skills/_shared/extra-dispatch.md +159 -7
- package/templates/skills/_shared/interview.md +1 -1
- package/templates/skills/_shared/opus5-only.md +9 -7
- package/templates/skills/_shared/phases/README.md +82 -0
- package/templates/skills/{orc/references → _shared/phases}/analyst-gates.md +15 -3
- package/templates/skills/_shared/phases/execution.md +143 -0
- package/templates/skills/{orc/references → _shared/phases}/house-rules.md +13 -1
- package/templates/skills/{orc/references → _shared/phases}/intake.md +15 -2
- package/templates/skills/_shared/phases/mock-example.md +56 -0
- package/templates/skills/{orc/references → _shared/phases}/plan-handoff.md +16 -3
- package/templates/skills/_shared/phases/planning.md +135 -0
- package/templates/skills/_shared/phases/preflight.md +76 -0
- package/templates/skills/_shared/phases/review.md +53 -0
- package/templates/skills/_shared/phases/scoring.md +65 -0
- package/templates/skills/{orc/references → _shared/phases}/security-checklist.md +12 -1
- package/templates/skills/_shared/phases/security.md +55 -0
- package/templates/skills/_shared/phases/ship.md +88 -0
- package/templates/skills/{orc/references/stop-and-resume.md → _shared/phases/stop-resume.md} +169 -160
- package/templates/skills/_shared/phases/summary.md +48 -0
- package/templates/skills/_shared/phases/testgen.md +51 -0
- package/templates/skills/{orc/references/trace-protocol.md → _shared/phases/trace.md} +49 -6
- package/templates/skills/_shared/phases/verify.md +70 -0
- package/templates/skills/{orc/references → _shared/phases}/wave-grouping.md +14 -2
- package/templates/skills/{orc/references → _shared/phases}/wiki-consult.md +13 -1
- package/templates/skills/_shared/read-ladder.md +48 -0
- package/templates/skills/context-combiner/SKILL.md +214 -187
- package/templates/skills/orc/README.md +148 -150
- package/templates/skills/orc/SKILL.md +70 -358
- package/templates/skills/orc/config.md +137 -389
- package/templates/skills/orc/examples/full-run-mock.md +1 -1
- package/templates/skills/orc/references/effort-and-mode.md +16 -18
- package/templates/skills/orc/references/phases/intake.md +47 -0
- package/templates/skills/orc/references/phases/integration.md +19 -0
- package/templates/skills/orc/references/preflight-report.md +4 -4
- package/templates/skills/orc/references/ultra-mode.md +117 -123
- package/templates/skills/orc/schemas/planning-output.md +279 -279
- package/templates/skills/orc/subskills/orc-planner/SKILL.md +260 -264
- package/templates/skills/orc/subskills/orc-pr/stack-gate.md +4 -1
- package/templates/skills/orc-aftermath/SKILL.md +153 -136
- package/templates/skills/orc-analyze/SKILL.md +247 -220
- package/templates/skills/orc-analyze/references/branching.md +51 -51
- package/templates/skills/orc-analyze/references/thin-input.md +1 -1
- package/templates/skills/orc-analyze-mini/SKILL.md +128 -112
- package/templates/skills/orc-boundary/SKILL.md +244 -208
- package/templates/skills/orc-brainstorm/SKILL.md +372 -339
- package/templates/skills/orc-budget/SKILL.md +243 -225
- package/templates/skills/orc-challenge/README.md +1 -1
- package/templates/skills/orc-challenge/SKILL.md +293 -255
- package/templates/skills/orc-challenge/examples/council-full-roster.md +1 -1
- package/templates/skills/orc-claude/SKILL.md +216 -199
- package/templates/skills/orc-diy/README.md +2 -1
- package/templates/skills/orc-diy/SKILL.md +129 -70
- package/templates/skills/orc-diy/references/blocks/analyze.md +1 -1
- package/templates/skills/orc-diy/references/compile.md +21 -7
- package/templates/skills/orc-diy/references/flow-schema.md +2 -2
- package/templates/skills/orc-doc/SKILL.md +44 -7
- package/templates/skills/orc-explain/SKILL.md +19 -0
- package/templates/skills/orc-export/SKILL.md +26 -5
- package/templates/skills/orc-fast/SKILL.md +215 -187
- package/templates/skills/orc-grill/SKILL.md +233 -207
- package/templates/skills/orc-handoff/SKILL.md +223 -204
- package/templates/skills/orc-learn/SKILL.md +176 -156
- package/templates/skills/orc-mini/SKILL.md +41 -23
- package/templates/skills/orc-pact/SKILL.md +250 -218
- package/templates/skills/orc-pattern/SKILL.md +149 -124
- package/templates/skills/orc-poly/SKILL.md +237 -216
- package/templates/skills/orc-poly/references/gather.md +1 -1
- package/templates/skills/orc-pr-driver/SKILL.md +196 -167
- package/templates/skills/orc-pr-driver/references/orc-run-split.md +1 -1
- package/templates/skills/orc-pr-setup/SKILL.md +212 -184
- package/templates/skills/orc-quick/README.md +2 -2
- package/templates/skills/orc-quick/SKILL.md +45 -12
- package/templates/skills/orc-quick/references/dispatch-gate.md +2 -3
- package/templates/skills/orc-retro/SKILL.md +244 -222
- package/templates/skills/orc-retro/examples/retro-mock.md +171 -171
- package/templates/skills/orc-route/SKILL.md +183 -165
- package/templates/skills/orc-verify/SKILL.md +100 -86
- package/templates/skills/orc-wiki/SKILL.md +55 -206
- package/templates/skills/orc-wiki/references/phases/phase-0.md +71 -0
- package/templates/skills/orc-wiki/references/phases/phase-1.md +35 -0
- package/templates/skills/orc-wiki/references/phases/phase-2.md +52 -0
- package/templates/skills/orc-wiki/references/phases/phase-3.md +57 -0
- package/templates/skills/orc-wiki/references/phases/phase-3c.md +36 -0
- package/templates/agents/orc-advisor-fable-5.md +0 -50
- package/templates/agents/orc-analyst-fable-5.md +0 -115
- package/templates/agents/orc-judge-fable-5.md +0 -79
- package/templates/agents/orc-planner-fable-5.md +0 -152
- package/templates/agents/orc-reviewer-fable-5.md +0 -57
- package/templates/skills/_shared/fable5-override.md +0 -56
- package/templates/skills/orc-diy/references/blocks/execution.md +0 -42
- package/templates/skills/orc-diy/references/blocks/mock-example.md +0 -22
- package/templates/skills/orc-diy/references/blocks/planning.md +0 -34
- package/templates/skills/orc-diy/references/blocks/review.md +0 -18
- package/templates/skills/orc-diy/references/blocks/scoring.md +0 -16
- package/templates/skills/orc-diy/references/blocks/security.md +0 -25
- package/templates/skills/orc-diy/references/blocks/ship.md +0 -25
- package/templates/skills/orc-diy/references/blocks/summary.md +0 -18
- package/templates/skills/orc-diy/references/blocks/testgen.md +0 -17
- package/templates/skills/orc-diy/references/blocks/trace.md +0 -28
- package/templates/skills/orc-diy/references/blocks/verify.md +0 -25
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* panels/lanes.js — orc ui client
|
|
3
|
+
The `orc lane` noun, rendered: which lanes exist, which SHARED phases each
|
|
4
|
+
one runs, and the whole call catalogue.
|
|
5
|
+
|
|
6
|
+
Loaded by app.html in the order its numeric prefix names. Classic
|
|
7
|
+
script, no import/export: an ES module import carries no query string,
|
|
8
|
+
and every static request here needs the per-launch session token. */
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/* =================================================================== LANES == */
|
|
12
|
+
|
|
13
|
+
// TWO TABS, on this panel's own precedent (Crosslink's two, Knowledge's five,
|
|
14
|
+
// Extra's six). Phases and Calls answer two different questions about the same
|
|
15
|
+
// noun — what a lane READS, in order, and what a lane RUNS — and stacking both
|
|
16
|
+
// down one column made the second one something you had to know was there.
|
|
17
|
+
//
|
|
18
|
+
// The tab survives a re-render, exactly as `KN_TAB` and `EX_TAB` do: losing
|
|
19
|
+
// your place because a fetch resolved is the small rudeness that makes a panel
|
|
20
|
+
// feel unreliable.
|
|
21
|
+
let LN_TAB = "phases";
|
|
22
|
+
// The selected lane likewise. A lane picker that snaps back to `orc` every time
|
|
23
|
+
// the panel repaints is a picker nobody uses twice.
|
|
24
|
+
let LN_LANE = "orc";
|
|
25
|
+
|
|
26
|
+
PANELS.lanes = function (host) {
|
|
27
|
+
head(host, t("lanes.title"), t("lanes.sub"));
|
|
28
|
+
section(
|
|
29
|
+
host,
|
|
30
|
+
() => read("/api/lanes").then((r) => r.data),
|
|
31
|
+
(d) => {
|
|
32
|
+
const out = frag();
|
|
33
|
+
const lanes = d.lanes || [];
|
|
34
|
+
if (!lanes.length) {
|
|
35
|
+
out.append(el("div", "empty", t("lanes.none")));
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
if (!lanes.some((l) => l.lane === LN_LANE)) LN_LANE = lanes[0].lane;
|
|
39
|
+
|
|
40
|
+
const body = el("div", "stack");
|
|
41
|
+
const paint = () => {
|
|
42
|
+
body.replaceChildren();
|
|
43
|
+
if (LN_TAB === "phases") phasesTab(body, lanes);
|
|
44
|
+
else callsTab(body);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// The panel's own `.tabs` convention: a flat strip driven by
|
|
48
|
+
// `aria-selected`, exactly as Knowledge and Runs build theirs. Keys are
|
|
49
|
+
// written out IN FULL rather than assembled from the tab id — a key built
|
|
50
|
+
// from a fragment is invisible to every check that looks for one.
|
|
51
|
+
const strip = el("div", "tabs");
|
|
52
|
+
const select = (which) => {
|
|
53
|
+
LN_TAB = which;
|
|
54
|
+
for (const b of strip.children) b.setAttribute("aria-selected", String(b.dataset.tab === which));
|
|
55
|
+
paint();
|
|
56
|
+
};
|
|
57
|
+
for (const [which, label] of [
|
|
58
|
+
["phases", t("lanes.tab.phases")],
|
|
59
|
+
["calls", t("lanes.tab.calls")],
|
|
60
|
+
]) {
|
|
61
|
+
const b = el("button", null, label);
|
|
62
|
+
b.type = "button";
|
|
63
|
+
b.dataset.tab = which;
|
|
64
|
+
b.setAttribute("aria-selected", String(which === LN_TAB));
|
|
65
|
+
b.addEventListener("click", () => select(which));
|
|
66
|
+
strip.append(b);
|
|
67
|
+
}
|
|
68
|
+
out.append(strip, body);
|
|
69
|
+
paint();
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/* ------------------------------------------------------------------ phases -- */
|
|
76
|
+
|
|
77
|
+
function phasesTab(host, lanes) {
|
|
78
|
+
const picker = card(t("lanes.picker.title"));
|
|
79
|
+
picker.append(el("div", "note", t("lanes.picker.note")));
|
|
80
|
+
|
|
81
|
+
const sel = el("select", "text-input");
|
|
82
|
+
sel.setAttribute("aria-label", t("lanes.picker.aria"));
|
|
83
|
+
for (const l of lanes) {
|
|
84
|
+
const o = el("option", null, l.lane + (l.command ? " " + l.command : ""));
|
|
85
|
+
o.value = l.lane;
|
|
86
|
+
if (l.lane === LN_LANE) o.selected = true;
|
|
87
|
+
sel.append(o);
|
|
88
|
+
}
|
|
89
|
+
picker.append(sel);
|
|
90
|
+
host.append(picker);
|
|
91
|
+
|
|
92
|
+
const slot = el("div", "stack");
|
|
93
|
+
host.append(slot);
|
|
94
|
+
|
|
95
|
+
const load = () => {
|
|
96
|
+
slot.replaceChildren(skeleton(3));
|
|
97
|
+
read("/api/lane/phases?lane=" + encodeURIComponent(LN_LANE))
|
|
98
|
+
.then((r) => slot.replaceChildren(phasesCard(r.data)))
|
|
99
|
+
.catch((e) => slot.replaceChildren(failBox(e)));
|
|
100
|
+
};
|
|
101
|
+
sel.addEventListener("change", () => {
|
|
102
|
+
LN_LANE = sel.value;
|
|
103
|
+
load();
|
|
104
|
+
});
|
|
105
|
+
load();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function phasesCard(d) {
|
|
109
|
+
const one = (d.lanes || [])[0];
|
|
110
|
+
const c = card(t("lanes.phases.title"));
|
|
111
|
+
if (!one) {
|
|
112
|
+
c.append(el("div", "empty", t("lanes.phases.unknown")));
|
|
113
|
+
return c;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// The trace tier and token are the CLI's words for how this lane narrates.
|
|
117
|
+
// They belong at the top because every phase below closes into one of them.
|
|
118
|
+
const meta = el("div", "lane-meta");
|
|
119
|
+
meta.append(el("span", "lane-meta-label", t("lanes.phases.trace")));
|
|
120
|
+
if (one.trace_tier) meta.append(chip(one.trace_tier));
|
|
121
|
+
if (one.trace_token) meta.append(chip("lane token " + one.trace_token, "lane"));
|
|
122
|
+
c.append(meta);
|
|
123
|
+
|
|
124
|
+
const phases = one.phases || [];
|
|
125
|
+
if (!phases.length) {
|
|
126
|
+
// AN EMPTY ANSWER IS AN ANSWER (v0.43.0). Five lanes keep their pipeline in
|
|
127
|
+
// their own spine on purpose, so "no shared phases" is a fact about this
|
|
128
|
+
// lane and not a fetch that failed. Saying nothing here would make the two
|
|
129
|
+
// look identical.
|
|
130
|
+
c.append(el("div", "empty", t("lanes.phases.inSpine")));
|
|
131
|
+
return c;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
for (const p of phases) {
|
|
135
|
+
const row = el("div", "phase-row");
|
|
136
|
+
row.append(el("span", "phase-ord", String(p.ord)));
|
|
137
|
+
|
|
138
|
+
const mid = el("div", "phase-mid");
|
|
139
|
+
mid.append(el("div", "phase-id", p.id));
|
|
140
|
+
// A row names a FILE or a HEADING, never both and never neither — the
|
|
141
|
+
// manifest rule the two-way lint enforces. Whichever it is, it is a CLI
|
|
142
|
+
// string and is printed verbatim.
|
|
143
|
+
if (p.file) mid.append(el("div", "phase-file", p.file));
|
|
144
|
+
if (p.heading) mid.append(el("div", "phase-file", p.heading));
|
|
145
|
+
if ((p.calls || []).length) {
|
|
146
|
+
const calls = el("div", "phase-calls");
|
|
147
|
+
calls.append(el("span", "phase-calls-label", t("lanes.phases.calls")));
|
|
148
|
+
for (const id of p.calls) calls.append(chip(id, "lane"));
|
|
149
|
+
mid.append(calls);
|
|
150
|
+
}
|
|
151
|
+
row.append(mid);
|
|
152
|
+
|
|
153
|
+
const right = el("div", "phase-right");
|
|
154
|
+
// `when` is one of the CLI's own words (`always`, `on-phase`,
|
|
155
|
+
// `compile-time`, …). It is never softened into "sometimes".
|
|
156
|
+
if (p.when) right.append(chip(p.when, p.when === "always" ? "ok" : null));
|
|
157
|
+
if (p.read) right.append(el("div", "phase-read", p.read));
|
|
158
|
+
if ((p.layers || []).length) right.append(el("div", "phase-layers", p.layers.join(" · ")));
|
|
159
|
+
row.append(right);
|
|
160
|
+
|
|
161
|
+
if (p.optional_when) row.append(el("div", "phase-why", p.optional_when));
|
|
162
|
+
c.append(row);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if ((d.phase_files || []).length || (d.layer_set || []).length) {
|
|
166
|
+
const foot = el("div", "note");
|
|
167
|
+
foot.append(document.createTextNode(t("lanes.phases.foot")));
|
|
168
|
+
c.append(foot);
|
|
169
|
+
}
|
|
170
|
+
return c;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* ------------------------------------------------------------------- calls -- */
|
|
174
|
+
|
|
175
|
+
function callsTab(host) {
|
|
176
|
+
const slot = el("div", "stack");
|
|
177
|
+
host.append(slot);
|
|
178
|
+
slot.replaceChildren(skeleton(4));
|
|
179
|
+
read("/api/lane/calls")
|
|
180
|
+
.then((r) => slot.replaceChildren(callsCard(r.data)))
|
|
181
|
+
.catch((e) => slot.replaceChildren(failBox(e)));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function callsCard(d) {
|
|
185
|
+
const calls = d.calls || [];
|
|
186
|
+
const c = card(t("lanes.calls.title", { n: calls.length }));
|
|
187
|
+
c.append(el("div", "note", t("lanes.calls.note")));
|
|
188
|
+
if (!calls.length) {
|
|
189
|
+
c.append(el("div", "empty", t("lanes.calls.none")));
|
|
190
|
+
return c;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
for (const call of calls) {
|
|
194
|
+
// EXPANDS IN PLACE, one row at a time — the Runs-row rule (v0.43.6). A
|
|
195
|
+
// detail box below a list means reading a row and then looking somewhere
|
|
196
|
+
// else for what it said.
|
|
197
|
+
const row = el("div", "call-row");
|
|
198
|
+
const h = el("button", "call-head");
|
|
199
|
+
h.type = "button";
|
|
200
|
+
h.setAttribute("aria-expanded", "false");
|
|
201
|
+
h.append(el("span", "call-caret", "▸"));
|
|
202
|
+
h.append(el("span", "call-cmd", call.cmd));
|
|
203
|
+
if (call.cost) h.append(chip(call.cost, call.cost === "free" ? "ok" : "warn"));
|
|
204
|
+
h.append(el("span", "call-lanes-n", tn((call.lanes || []).length, "lanes.calls.lanes")));
|
|
205
|
+
|
|
206
|
+
const detail = el("div", "call-detail");
|
|
207
|
+
detail.hidden = true;
|
|
208
|
+
// Every string below is the CLI's registry text and is never translated: it
|
|
209
|
+
// names commands, exit codes and reference files by their real ids.
|
|
210
|
+
const rows = [];
|
|
211
|
+
if (call.what) rows.push([t("lanes.calls.what"), call.what]);
|
|
212
|
+
if (call.when) rows.push([t("lanes.calls.when"), call.when]);
|
|
213
|
+
if (call.on_absent) rows.push([t("lanes.calls.onAbsent"), call.on_absent]);
|
|
214
|
+
if (call.never) rows.push([t("lanes.calls.never"), call.never]);
|
|
215
|
+
if (call.canonical) rows.push([t("lanes.calls.canonical"), call.canonical]);
|
|
216
|
+
detail.append(kvList(rows));
|
|
217
|
+
|
|
218
|
+
// The exit codes are a CONTRACT, so they are drawn as a table rather than
|
|
219
|
+
// folded into a sentence — a lane branches on these numbers.
|
|
220
|
+
const exits = call.exits || {};
|
|
221
|
+
const codes = Object.keys(exits);
|
|
222
|
+
if (codes.length) {
|
|
223
|
+
const ex = el("div", "call-exits");
|
|
224
|
+
ex.append(el("span", "call-exits-label", t("lanes.calls.exits")));
|
|
225
|
+
for (const code of codes) ex.append(el("span", "call-exit", code + " = " + exits[code]));
|
|
226
|
+
detail.append(ex);
|
|
227
|
+
}
|
|
228
|
+
if ((call.states || []).length) {
|
|
229
|
+
const st = el("div", "call-exits");
|
|
230
|
+
st.append(el("span", "call-exits-label", t("lanes.calls.states")));
|
|
231
|
+
for (const s of call.states) st.append(chip(s));
|
|
232
|
+
detail.append(st);
|
|
233
|
+
}
|
|
234
|
+
if ((call.lanes || []).length) {
|
|
235
|
+
const ls = el("div", "call-lane-chips");
|
|
236
|
+
ls.append(el("span", "call-exits-label", t("lanes.calls.calledBy")));
|
|
237
|
+
for (const l of call.lanes) ls.append(chip(l, "lane"));
|
|
238
|
+
detail.append(ls);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
h.addEventListener("click", () => {
|
|
242
|
+
const open = h.getAttribute("aria-expanded") === "true";
|
|
243
|
+
// ONE ROW OPEN AT A TIME, the Runs-row rule again: thirty open rows is
|
|
244
|
+
// the wall this panel replaced.
|
|
245
|
+
for (const other of c.querySelectorAll(".call-head[aria-expanded='true']")) {
|
|
246
|
+
other.setAttribute("aria-expanded", "false");
|
|
247
|
+
other.parentElement.querySelector(".call-detail").hidden = true;
|
|
248
|
+
}
|
|
249
|
+
if (!open) {
|
|
250
|
+
h.setAttribute("aria-expanded", "true");
|
|
251
|
+
detail.hidden = false;
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
row.append(h, detail);
|
|
256
|
+
c.append(row);
|
|
257
|
+
}
|
|
258
|
+
return c;
|
|
259
|
+
}
|
|
@@ -54,6 +54,16 @@ const FINDING_ROUTE = {
|
|
|
54
54
|
// evicts the old package first), and `upgrade` is an action row on
|
|
55
55
|
// MAINTENANCE — so that is genuinely the panel that can clear it.
|
|
56
56
|
"legacy-global-package": { panel: "maintenance", cta: "overview.item.legacyGlobalPackage.cta" },
|
|
57
|
+
// v1.0.0 W5. The rule again: a demoted run is cleared by `orc extra promote`,
|
|
58
|
+
// and Recovery is the Extra tab where every other journal-shaped state is
|
|
59
|
+
// already rendered — so that is genuinely the panel that can clear it.
|
|
60
|
+
"extra-demoted-run": { panel: "extra", cta: "overview.item.extraDemotedRun.cta" },
|
|
61
|
+
// v1.0.0 W16. An INSTALL-FOOTPRINT finding, so it takes the documented
|
|
62
|
+
// default rather than an interesting exception: the thing that clears it is
|
|
63
|
+
// `orc update`, which is an action row on MAINTENANCE. It is spelled out
|
|
64
|
+
// rather than left to DEFAULT_FINDING_ROUTE because the CTA is specific --
|
|
65
|
+
// a reader who sees "lane config drifted" should be told which button.
|
|
66
|
+
"lane-keys-drifted": { panel: "maintenance", cta: "overview.item.laneKeysDrifted.cta" },
|
|
57
67
|
};
|
|
58
68
|
const DEFAULT_FINDING_ROUTE = { panel: "maintenance", cta: "overview.item.doctor.cta" };
|
|
59
69
|
const findingRoute = (id) => FINDING_ROUTE[id] || DEFAULT_FINDING_ROUTE;
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
// keys stay GREPPABLE: a build of a string key from a fragment is a key no
|
|
18
18
|
// coverage check can see, and the check is the only thing standing between a
|
|
19
19
|
// renamed key and a raw dotted string on somebody's screen.
|
|
20
|
-
const TIER_LABEL_KEY = { common: "settings.tier.common",
|
|
21
|
-
const TIER_DESC_KEY = { common: "settings.tierDesc.common",
|
|
20
|
+
const TIER_LABEL_KEY = { common: "settings.tier.common", advanced: "settings.tier.advanced" };
|
|
21
|
+
const TIER_DESC_KEY = { common: "settings.tierDesc.common", advanced: "settings.tierDesc.advanced" };
|
|
22
22
|
const TIER_LABEL = (tier) => (TIER_LABEL_KEY[tier] ? t(TIER_LABEL_KEY[tier]) : tier);
|
|
23
23
|
const TIER_DESC = (tier) => (TIER_DESC_KEY[tier] ? t(TIER_DESC_KEY[tier]) : "");
|
|
24
24
|
|
|
@@ -162,6 +162,12 @@ async function renderSettings(body) {
|
|
|
162
162
|
// flips — which is how the precedence rule gets taught rather than described.
|
|
163
163
|
out.append(ladderCard(d.score_table));
|
|
164
164
|
|
|
165
|
+
// WHO DECIDES WHAT (v1.0.0 W16). The ladder above answers one family;
|
|
166
|
+
// this answers all of them, and it is the picture a flat key list cannot
|
|
167
|
+
// draw: a contested setting is not decided by the key you are looking at,
|
|
168
|
+
// it is decided by the highest rank that resolved.
|
|
169
|
+
out.append(ranksCard(d.families, d.families_resolved, d.rank_states));
|
|
170
|
+
|
|
165
171
|
// 36 keys in three flat lists is a wall, and the answer to "where is the one
|
|
166
172
|
// I want" was scrolling. Each tier is now its own collapsible card, and the
|
|
167
173
|
// toolbar filters across ALL of them at once — so finding a key never depends
|
|
@@ -169,7 +175,7 @@ async function renderSettings(body) {
|
|
|
169
175
|
const tiers = [];
|
|
170
176
|
out.append(settingsToolbar(d, tiers));
|
|
171
177
|
|
|
172
|
-
for (const tier of ["common", "
|
|
178
|
+
for (const tier of ["common", "advanced"]) {
|
|
173
179
|
const keys = d.keys.filter((k) => k.tier === tier);
|
|
174
180
|
if (!keys.length) continue;
|
|
175
181
|
|
|
@@ -234,6 +240,32 @@ async function renderSettings(body) {
|
|
|
234
240
|
out.append(c);
|
|
235
241
|
}
|
|
236
242
|
|
|
243
|
+
// A key ORC REMOVED, still sitting in the user's file. It is NOT an editable
|
|
244
|
+
// setting and it is NOT a hand-edited override, so it gets its own block —
|
|
245
|
+
// rendering it as either would tell the user a dead line still does
|
|
246
|
+
// something. The CLI computed the row; this only draws it.
|
|
247
|
+
if ((d.retired_keys || []).length) {
|
|
248
|
+
const c = card(t("settings.retired.title"));
|
|
249
|
+
c.append(el("div", "note", t("settings.retired.note")));
|
|
250
|
+
for (const r of d.retired_keys) {
|
|
251
|
+
const row = el("div", "setting shadowed");
|
|
252
|
+
const left = el("div");
|
|
253
|
+
const name = el("div", "setting-name");
|
|
254
|
+
name.append(document.createTextNode(r.key));
|
|
255
|
+
const lock = el("span", "lock");
|
|
256
|
+
lock.append(document.createTextNode("🔒 " + t("settings.retired.badge")));
|
|
257
|
+
name.append(lock);
|
|
258
|
+
left.append(name);
|
|
259
|
+
left.append(el("div", "setting-desc", t("settings.retired.readonly")));
|
|
260
|
+
left.append(el("div", "shadow-why", `${t("settings.retired.removedIn")} ${r.removed_in} — ${r.why}`));
|
|
261
|
+
const right = el("div", "setting-control");
|
|
262
|
+
right.append(el("div", "readonly-value", String(r.value)));
|
|
263
|
+
row.append(left, right);
|
|
264
|
+
c.append(row);
|
|
265
|
+
}
|
|
266
|
+
out.append(c);
|
|
267
|
+
}
|
|
268
|
+
|
|
237
269
|
// Last block on the panel, and it sticks to the bottom of the viewport once
|
|
238
270
|
// something is pending: with 36 keys across three tiers, an Apply you have to
|
|
239
271
|
// go looking for is an Apply that gets forgotten.
|
|
@@ -243,6 +275,99 @@ async function renderSettings(body) {
|
|
|
243
275
|
body.replaceChildren(out);
|
|
244
276
|
}
|
|
245
277
|
|
|
278
|
+
// WHO DECIDES WHAT (v1.0.0 W16) — the contested families, resolved.
|
|
279
|
+
//
|
|
280
|
+
// THE PANEL DECIDES NOTHING HERE. `families` is the CLI's static registry (which
|
|
281
|
+
// ranks exist, in which order, and the question each family answers) and
|
|
282
|
+
// `families_resolved` is what those ranks actually did against the config on
|
|
283
|
+
// disk right now. Re-deriving a precedence in the browser is the exact drift
|
|
284
|
+
// this panel exists to make impossible — the Flow-stepper rule, applied to
|
|
285
|
+
// config.
|
|
286
|
+
//
|
|
287
|
+
// Only CONTESTED families are drawn. A family with one rank has no precedence
|
|
288
|
+
// to teach, and a card that lists thirty uncontested rows to show two
|
|
289
|
+
// interesting ones is a card nobody reads to the bottom of.
|
|
290
|
+
//
|
|
291
|
+
// Every state word is the CLI's own, from the closed set it publishes as
|
|
292
|
+
// `rank_states` — never a friendlier synonym (`resolved`, `not-read`, `inert`,
|
|
293
|
+
// `demoted`, `absent`, `partly-resolved`). A `why` is CLI prose and is never
|
|
294
|
+
// translated: it names keys, runs, profiles and commands by their real ids.
|
|
295
|
+
const RANK_STATE_KIND = {
|
|
296
|
+
resolved: "ok",
|
|
297
|
+
"partly-resolved": "ok",
|
|
298
|
+
"not-read": null,
|
|
299
|
+
inert: "warn",
|
|
300
|
+
demoted: "warn",
|
|
301
|
+
absent: null,
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
function ranksCard(families, resolved, states) {
|
|
305
|
+
const c = card(t("settings.ranks.title"));
|
|
306
|
+
c.id = "ranks-card";
|
|
307
|
+
c.append(el("div", "note", t("settings.ranks.note")));
|
|
308
|
+
|
|
309
|
+
const names = Object.keys(families || {}).filter((n) => (families[n] || {}).contested);
|
|
310
|
+
if (!names.length) {
|
|
311
|
+
c.append(el("div", "empty", t("settings.ranks.none")));
|
|
312
|
+
return c;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
for (const name of names) {
|
|
316
|
+
const fam = families[name] || {};
|
|
317
|
+
const res = (resolved || {})[name] || {};
|
|
318
|
+
const block = el("div", "rank-family");
|
|
319
|
+
|
|
320
|
+
const h = el("div", "rank-family-head");
|
|
321
|
+
// The family id is a CLI id. The QUESTION beside it is the CLI's too —
|
|
322
|
+
// it is the whole reason the grouping means anything.
|
|
323
|
+
h.append(el("span", "rank-family-name", name));
|
|
324
|
+
h.append(el("span", "rank-family-q", fam.question || ""));
|
|
325
|
+
block.append(h);
|
|
326
|
+
|
|
327
|
+
// WHAT ANSWERED, stated before the ladder rather than left to be inferred
|
|
328
|
+
// from which row happens to be green. `resolved_by` is null on a terminal
|
|
329
|
+
// rank, which is not a gap: it means nothing above the floor resolved.
|
|
330
|
+
if (res.resolved_at) {
|
|
331
|
+
const by = el("div", "rank-answer");
|
|
332
|
+
by.append(
|
|
333
|
+
document.createTextNode(
|
|
334
|
+
res.resolved_by
|
|
335
|
+
? t("settings.ranks.answeredBy", { prio: res.resolved_at, key: res.resolved_by })
|
|
336
|
+
: t("settings.ranks.answeredByDefault", { prio: res.resolved_at })
|
|
337
|
+
)
|
|
338
|
+
);
|
|
339
|
+
block.append(by);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
for (const r of res.ranks || fam.ranks || []) {
|
|
343
|
+
const row = el("div", "rank-row" + (r.state === "resolved" ? " is-resolved" : ""));
|
|
344
|
+
row.append(el("span", "rank-prio", r.prio));
|
|
345
|
+
// A rank is either a KEY or the family's terminal floor. The floor has no
|
|
346
|
+
// key on purpose — it is "the thing that happens when nobody chose" — and
|
|
347
|
+
// rendering it as a key would invite somebody to look for it in the file.
|
|
348
|
+
row.append(el("span", "rank-key" + (r.key ? "" : " is-terminal"), r.key || r.terminal || ""));
|
|
349
|
+
const st = r.state || "absent";
|
|
350
|
+
// An unknown state is RENDERED, not swallowed: the CLI owns this set, and
|
|
351
|
+
// a panel that silently drops a word it does not recognise is a panel that
|
|
352
|
+
// hides the next state somebody adds.
|
|
353
|
+
row.append(chip(st, RANK_STATE_KIND[st] === undefined ? null : RANK_STATE_KIND[st]));
|
|
354
|
+
if (r.why) row.append(el("div", "rank-why", r.why));
|
|
355
|
+
block.append(row);
|
|
356
|
+
}
|
|
357
|
+
c.append(block);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// The closed set, once, at the bottom. It is what makes an unfamiliar chip
|
|
361
|
+
// above readable without leaving the page.
|
|
362
|
+
if ((states || []).length) {
|
|
363
|
+
const legend = el("div", "rank-legend");
|
|
364
|
+
legend.append(el("span", "rank-legend-label", t("settings.ranks.legend")));
|
|
365
|
+
for (const s of states) legend.append(chip(s, RANK_STATE_KIND[s] === undefined ? null : RANK_STATE_KIND[s]));
|
|
366
|
+
c.append(legend);
|
|
367
|
+
}
|
|
368
|
+
return c;
|
|
369
|
+
}
|
|
370
|
+
|
|
246
371
|
function ladderCard(table) {
|
|
247
372
|
const c = card(t("settings.ladder.title"));
|
|
248
373
|
c.id = "ladder-card"; // the FLIP morph finds it by id, never by a :has() query
|
|
@@ -324,6 +449,27 @@ function settingRow(k, panelBody, edits) {
|
|
|
324
449
|
// translated. They name keys, values and precedence rules by their real ids.
|
|
325
450
|
left.append(el("div", "setting-desc", k.desc));
|
|
326
451
|
if (k.shadow_reason) left.append(el("div", "shadow-why", k.shadow_reason));
|
|
452
|
+
// WHICH LANES READ THIS (v1.0.0 W16). `k.lanes[]` is the CLI's own
|
|
453
|
+
// `CONFIG_META[].lanes[]` — the same list `orc lane config` filters on, and
|
|
454
|
+
// the same list a two-way lint already refuses to let drift. It answers the
|
|
455
|
+
// question a settings screen otherwise leaves you guessing at: I changed
|
|
456
|
+
// this, so what did I just change? A lane name is a CLI id and is never
|
|
457
|
+
// translated.
|
|
458
|
+
//
|
|
459
|
+
// AN EMPTY LIST IS AN ANSWER AND KEEPS ITS ROW. Ten keys are permanently
|
|
460
|
+
// empty and the lint has an allowlist naming every one of them: they are
|
|
461
|
+
// OPERATING keys of the `orc extra` bridge — a lane calls `orc extra
|
|
462
|
+
// dispatch` and the CLI reads `extra_timeout_s`, so no lane ever names it.
|
|
463
|
+
// Skipping the line would make "no lane reads this" look identical to "we
|
|
464
|
+
// did not render it", which is the distinction this whole row exists to
|
|
465
|
+
// draw.
|
|
466
|
+
{
|
|
467
|
+
const lanes = el("div", "setting-lanes");
|
|
468
|
+
lanes.append(el("span", "setting-lanes-label", t("settings.lanes.label")));
|
|
469
|
+
if ((k.lanes || []).length) for (const lane of k.lanes) lanes.append(chip(lane, "lane"));
|
|
470
|
+
else lanes.append(el("span", "setting-lanes-none", t("settings.lanes.none")));
|
|
471
|
+
left.append(lanes);
|
|
472
|
+
}
|
|
327
473
|
|
|
328
474
|
const right = el("div", "setting-control");
|
|
329
475
|
right.append(controlFor(k, edits));
|
package/package.json
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@azure-id/orc",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "ORC — an orchestrator skill constellation for Claude Code: intake, planning, scored parallel subagents, code-pattern matching, review, verify, ship, plus a project knowledge-base wiki.",
|
|
5
|
-
"bin": {
|
|
6
|
-
"orc": "bin/cli.js"
|
|
7
|
-
},
|
|
8
|
-
"files": [
|
|
9
|
-
"README.md",
|
|
10
|
-
"README-id.md",
|
|
11
|
-
"CHANGELOG.md",
|
|
12
|
-
"bin/",
|
|
13
|
-
"mock-run/",
|
|
14
|
-
"templates/"
|
|
15
|
-
],
|
|
16
|
-
"scripts": {
|
|
17
|
-
"postinstall": "node -e \"try{require('fs').accessSync(require('path').join(__dirname,'bin','cli.js'));console.log('\\nORC installed. Run: orc init (or orc init --global)\\n')}catch(e){console.error('\\n[orc] WARNING: bin/cli.js missing from this install — the repo/publish was incomplete. Reinstall from a complete source.\\n')}\"",
|
|
18
|
-
"build:agents": "node bin/build-agents.js",
|
|
19
|
-
"test": "node
|
|
20
|
-
"verify": "node bin/build-agents.js --check && node bin/verify-package.js && node bin/verify-contracts.js",
|
|
21
|
-
"prepack": "node bin/build-agents.js --check && node bin/verify-package.js && node bin/verify-contracts.js && node
|
|
22
|
-
},
|
|
23
|
-
"keywords": [
|
|
24
|
-
"claude",
|
|
25
|
-
"claude-code",
|
|
26
|
-
"orchestrator",
|
|
27
|
-
"skills",
|
|
28
|
-
"agents",
|
|
29
|
-
"ai"
|
|
30
|
-
],
|
|
31
|
-
"license": "MIT",
|
|
32
|
-
"engines": {
|
|
33
|
-
"node": ">=18"
|
|
34
|
-
},
|
|
35
|
-
"repository": {
|
|
36
|
-
"type": "git",
|
|
37
|
-
"url": "github:azure-id/orc"
|
|
38
|
-
}
|
|
39
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@azure-id/orc",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "ORC — an orchestrator skill constellation for Claude Code: intake, planning, scored parallel subagents, code-pattern matching, review, verify, ship, plus a project knowledge-base wiki.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"orc": "bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"README.md",
|
|
10
|
+
"README-id.md",
|
|
11
|
+
"CHANGELOG.md",
|
|
12
|
+
"bin/",
|
|
13
|
+
"mock-run/",
|
|
14
|
+
"templates/"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"postinstall": "node -e \"try{require('fs').accessSync(require('path').join(__dirname,'bin','cli.js'));console.log('\\nORC installed. Run: orc init (or orc init --global)\\n')}catch(e){console.error('\\n[orc] WARNING: bin/cli.js missing from this install — the repo/publish was incomplete. Reinstall from a complete source.\\n')}\"",
|
|
18
|
+
"build:agents": "node bin/build-agents.js",
|
|
19
|
+
"test": "node bin/test-run.js",
|
|
20
|
+
"verify": "node bin/build-agents.js --check && node bin/verify-package.js && node bin/verify-contracts.js",
|
|
21
|
+
"prepack": "node bin/build-agents.js --check && node bin/verify-package.js && node bin/verify-contracts.js && node bin/test-run.js"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"claude",
|
|
25
|
+
"claude-code",
|
|
26
|
+
"orchestrator",
|
|
27
|
+
"skills",
|
|
28
|
+
"agents",
|
|
29
|
+
"ai"
|
|
30
|
+
],
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18"
|
|
34
|
+
},
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "github:azure-id/orc"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Single-role, model-specific agents. The orchestrator dispatches BY AGENT NAME —
|
|
4
4
|
model is pinned in frontmatter, not requested in prose. No agent is multi-role.
|
|
5
5
|
|
|
6
|
-
## Executors (score-mapped by the single
|
|
6
|
+
## Executors (score-mapped by the single 6-band table in config.md)
|
|
7
7
|
|
|
8
8
|
| Score band | Agent | Model | Effort |
|
|
9
9
|
|-----------|-------|-------|--------|
|
|
@@ -11,14 +11,20 @@ model is pinned in frontmatter, not requested in prose. No agent is multi-role.
|
|
|
11
11
|
| [30,40) | orc-executor-sonnet-4-6-med | claude-sonnet-4-6 | medium |
|
|
12
12
|
| [40,55) | orc-executor-sonnet-4-6-high | claude-sonnet-4-6 | high |
|
|
13
13
|
| [55,65) | orc-executor-sonnet-5-high | claude-sonnet-5 | high |
|
|
14
|
-
| [65,
|
|
15
|
-
| [
|
|
16
|
-
| [80,90) | orc-executor-opus-4-8-high | claude-opus-4-8 | high |
|
|
17
|
-
| [90,100] | orc-executor-opus-5-high | claude-opus-5 | high |
|
|
14
|
+
| [65,90) | orc-executor-opus-5-low | claude-opus-5 | low |
|
|
15
|
+
| [90,100] | orc-executor-opus-5-med | claude-opus-5 | medium |
|
|
18
16
|
|
|
19
|
-
Score→executor mapping lives in config.md (one canonical
|
|
17
|
+
Score→executor mapping lives in config.md (one canonical 6-band table;
|
|
20
18
|
`rubric_bands` is granularity only, not a preset selector).
|
|
21
19
|
|
|
20
|
+
**Executors no band names — they still ship.**
|
|
21
|
+
`orc-executor-opus-4-7-med`, `orc-executor-opus-4-7-high`,
|
|
22
|
+
`orc-executor-opus-4-8-high` and `orc-executor-opus-5-high` are still generated
|
|
23
|
+
and still installed. Since v1.0.0 they are reachable only when a user names one
|
|
24
|
+
explicitly: `rubric_bands_override`, `orc diy`'s `fixed_executor`, or
|
|
25
|
+
`extra_fallback_agent`. They are not deleted because a table change is not a
|
|
26
|
+
model change, and an agent's model change is always a RENAME.
|
|
27
|
+
|
|
22
28
|
## Fixed-role agents
|
|
23
29
|
|
|
24
30
|
| Agent | Model | Effort | Role |
|
|
@@ -36,8 +42,8 @@ Score→executor mapping lives in config.md (one canonical 8-band table;
|
|
|
36
42
|
| orc-retro-sonnet-5-high | claude-sonnet-5 | high | mine behavior traces → calibration report (/orc-retro; read-only) |
|
|
37
43
|
| orc-wiki-scanner-opus-4-8-high | claude-opus-4-8 | high | scan ONE wiki coverage area → evidence-anchored doc body + crosslink tags (/orc-wiki only; read-only against the project). The DEEP half of the v0.46.0 tier ladder: first scan · STRUCTURAL · wide delta · a new exported symbol |
|
|
38
44
|
| orc-wiki-scanner-sonnet-5-high | claude-sonnet-5 | high | the LIGHT half of the same ladder — an existing doc whose covered files moved by a small, no-new-surface delta. IDENTICAL return contract; it escalates with `needs_context` rather than under-delivering. Never used for a first scan |
|
|
39
|
-
| orc-executor-opus-5-med | claude-opus-5 | medium |
|
|
40
|
-
| orc-executor-opus-5-low | claude-opus-5 | low |
|
|
45
|
+
| orc-executor-opus-5-med | claude-opus-5 | medium | the `[90,100]` band in BOTH tables |
|
|
46
|
+
| orc-executor-opus-5-low | claude-opus-5 | low | the default table's `[65,90)`, `opus5_only`'s `[0,90)`, and the forced mini/fast executor |
|
|
41
47
|
| orc-advisor-opus-5-xhigh | claude-opus-5 | xhigh | ultra Phase U0 advisory brief + rubric + clarification questions (read-only; /orc-ultra only) |
|
|
42
48
|
| orc-judge-opus-5-xhigh | claude-opus-5 | xhigh | ultra judgment gates — analysis / plan / implementation (read-only; /orc-ultra only) |
|
|
43
49
|
| orc-learn-writer-opus-5-low | claude-opus-5 | low | deepen ONE feature → learning-docs/<slug>/ (/orc-learn only; git-ignored output) |
|
|
@@ -58,15 +64,14 @@ Score→executor mapping lives in config.md (one canonical 8-band table;
|
|
|
58
64
|
|
|
59
65
|
`opus5_only` FORCES every dispatched role onto `claude-opus-5`, with effort as
|
|
60
66
|
the only cost dial. Each agent below replaces its default with the same slice
|
|
61
|
-
and the same return contract. Effort is PINNED per role
|
|
62
|
-
|
|
67
|
+
and the same return contract. Effort is PINNED per role — no CLI rewrites
|
|
68
|
+
these. Full mapping + precedence:
|
|
63
69
|
`../skills/_shared/opus5-only.md`.
|
|
64
70
|
|
|
65
71
|
| Agent | Model | Effort | Replaces |
|
|
66
72
|
|-------|-------|--------|----------|
|
|
67
|
-
| orc-executor-opus-5-low | claude-opus-5 | low | the `[0,
|
|
68
|
-
| orc-executor-opus-5-med | claude-opus-5 | medium | the `[
|
|
69
|
-
| orc-executor-opus-5-high | claude-opus-5 | high | the `[80,100]` band |
|
|
73
|
+
| orc-executor-opus-5-low | claude-opus-5 | low | the `[0,90)` band · orc-mini's and orc-fast's fixed executor |
|
|
74
|
+
| orc-executor-opus-5-med | claude-opus-5 | medium | the `[90,100]` band |
|
|
70
75
|
| orc-analyze-mini-opus-5-med | claude-opus-5 | medium | orc-analyze-mini-sonnet-5-high |
|
|
71
76
|
| orc-planner-mini-opus-5-med | claude-opus-5 | medium | orc-planner-mini-sonnet-5-high |
|
|
72
77
|
| orc-scout-opus-5-low | claude-opus-5 | low | orc-scout-sonnet-4-6-high |
|
|
@@ -80,22 +85,6 @@ verifier, test-author, combiner, learn-writer, advisor, judge — dispatch
|
|
|
80
85
|
unchanged under this mode. **Never forced:** `orc-trace-writer-haiku-4-5` (it
|
|
81
86
|
transcribes a packet, no reasoning) and orc-diy (its table is compile-owned).
|
|
82
87
|
|
|
83
|
-
## Fable 5 role-override agents (hard-gated; dispatched only when configured)
|
|
84
|
-
|
|
85
|
-
*(Entirely INERT while `opus5_only: true` — that mode outranks this one.)*
|
|
86
|
-
|
|
87
|
-
Used ONLY when `fable5_enabled: true` and the role is in `fable5_roles` — each
|
|
88
|
-
replaces its default role agent with the same slice/contract. Effort defaults to
|
|
89
|
-
`medium` and is rewritten in-place by `orc config set fable5_effort <v>`.
|
|
90
|
-
|
|
91
|
-
| Agent | Model | Effort | Replaces |
|
|
92
|
-
|-------|-------|--------|----------|
|
|
93
|
-
| orc-analyst-fable-5 | claude-fable-5 | fable5_effort | orc-system-analyst-opus-5-high |
|
|
94
|
-
| orc-planner-fable-5 | claude-fable-5 | fable5_effort | orc-planner-opus-5-med |
|
|
95
|
-
| orc-advisor-fable-5 | claude-fable-5 | fable5_effort | orc-advisor-opus-5-xhigh (ultra) |
|
|
96
|
-
| orc-judge-fable-5 | claude-fable-5 | fable5_effort | orc-judge-opus-5-xhigh (ultra) |
|
|
97
|
-
| orc-reviewer-fable-5 | claude-fable-5 | fable5_effort | orc-reviewer-opus-5-med |
|
|
98
|
-
|
|
99
88
|
Mini execution reuses orc-executor-sonnet-5-high. Fast-lane (orc-fast)
|
|
100
89
|
execution reuses orc-executor-sonnet-4-6-high — no dedicated agent. Under
|
|
101
90
|
`opus5_only` both reuse orc-executor-opus-5-low.
|
|
@@ -114,8 +103,7 @@ agent to spawn before EVERY dispatch, and reuses shipped agents:
|
|
|
114
103
|
The only dispatch it does not re-ask is build-repair rounds 1–2, which reuse the
|
|
115
104
|
executor the user already chose for that entry; round 3 asks again.
|
|
116
105
|
|
|
117
|
-
**`opus5_only
|
|
118
|
-
all INERT in this lane** — they would silently collapse the user's choice. It is
|
|
106
|
+
**`opus5_only` and `rubric_bands_override` are both INERT in this lane** — they would silently collapse the user's choice. It is
|
|
119
107
|
the one exception to `opus5_only`'s otherwise flat precedence. See
|
|
120
108
|
`skills/_shared/opus5-only.md` and `skills/orc-quick/references/dispatch-gate.md`.
|
|
121
109
|
|
|
@@ -136,12 +124,12 @@ The orchestrator (main session) is NOT an agent file.
|
|
|
136
124
|
Model IDs use the Platform/API dateless format (confirmed at
|
|
137
125
|
platform.claude.com/docs/en/about-claude/models/model-ids-and-versions):
|
|
138
126
|
claude-haiku-4-5, claude-sonnet-4-6, claude-sonnet-5, claude-opus-4-7,
|
|
139
|
-
claude-opus-4-8
|
|
140
|
-
|
|
127
|
+
claude-opus-4-8 and claude-opus-5 (the top executor band + the core fixed
|
|
128
|
+
roles).
|
|
141
129
|
|
|
142
130
|
1. **Run `/agents`** to confirm Claude Code accepts these full IDs in agent
|
|
143
|
-
frontmatter — in particular `claude-haiku-4-5` and `claude-
|
|
144
|
-
|
|
131
|
+
frontmatter — in particular `claude-haiku-4-5` and `claude-opus-5`. If it
|
|
132
|
+
wants short aliases (opus/sonnet/haiku) or dated IDs, adjust
|
|
145
133
|
each `model:` field. The full IDs are valid at the API level but Claude Code
|
|
146
134
|
may normalize differently.
|
|
147
135
|
2. **Confirm `effort:` is a valid CLI frontmatter field.** If the CLI ignores
|